URL
https://opencores.org/ocsvn/6809_6309_compatible_core/6809_6309_compatible_core/trunk
Subversion Repositories 6809_6309_compatible_core
Compare Revisions
- This comparison shows the changes necessary to convert path
/6809_6309_compatible_core/trunk/rtl
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/verilog/MC6809_cpu.v
22,11 → 22,10
); |
|
wire k_reset; |
wire k_clk; |
assign k_clk = cpu_clk; |
|
reg [7:0] k_opcode, k_postbyte, k_ind_ea; /* all bytes of an instruction */ |
reg [7:0] k_pp_regs, k_pp_active_reg; // push/pull mask |
reg [7:0] k_pp_regs; // push/pull registers to process |
reg [3:0] k_pp_active_reg; // push/pull active register |
reg [7:0] k_memhi, k_memlo, k_cpu_data_o; /* operand read from memory */ |
reg [7:0] k_ofslo, k_ofshi, k_eahi, k_ealo; |
reg [5:0] state, // state of the main state machine |
38,6 → 37,7
reg [15:0] k_cpu_addr, k_new_pc; |
reg k_write_pc, k_inc_su, k_dec_su, k_set_e, k_clear_e; |
reg [1:0] k_mem_dest; |
reg k_mul_cnt; // multiplier couner |
reg k_write_dest; // set for 1 clock when a register has to be written, dec_o_dest_reg_addr has the register source |
reg k_write_post_incdec; // asserted when in the last write cycle or in write back for loads |
reg k_forced_mem_size; // used to force the size of a memory read to be 16 bits, used for vector fetch |
61,6 → 61,8
/* ALU outputs */ |
wire [15:0] alu_o_result; |
wire [7:0] alu_o_CCR; |
wire [7:0] alu8_o_result; |
wire [7:0] alu8_o_CCR; |
/* Register Module outputs */ |
wire [15:0] regs_o_left_path_data, regs_o_right_path_data, regs_o_eamem_addr, regs_o_su; |
wire [7:0] regs_o_dp; |
83,19 → 85,20
assign k_firq_req = k_reg_firq[2] & k_reg_firq[1]; |
assign k_irq_req = k_reg_irq[2] & k_reg_irq[1]; |
|
alu16 alu( |
.clk(k_clk), |
alu alu( |
.clk_in(cpu_clk), |
.a_in(datamux_o_alu_in_left_path_data), |
.b_in(datamux_o_alu_in_right_path_data), |
.CCR(regs_o_CCR), /* flags */ |
.opcode_in(dec_o_alu_opcode), /* ALU k_opcode */ |
.sz_in(dec_o_alu_size), /* size, low 8 bit, high 16 bit */ |
.opcode_in(dec_o_alu_opcode), /* ALU k_opcode */ |
.sz_in(dec_o_alu_size), |
.q_out(alu_o_result), /* ALU result */ |
.CCRo(alu_o_CCR) |
); |
|
); |
|
|
regblock regs( |
.clk_in(k_clk), |
.clk_in(cpu_clk), |
.path_left_addr(datamux_o_alu_in_left_path_addr), |
.path_right_addr(dec_o_right_path_addr), |
.write_reg_addr(datamux_o_dest_reg_addr), |
192,8 → 195,13
/* Left Register read mux |
*/ |
always @(*) |
begin |
datamux_o_alu_in_left_path_addr = dec_o_left_path_addr; |
begin |
if (k_pp_active_reg != `RN_INV) |
datamux_o_alu_in_left_path_addr = k_pp_active_reg; |
else |
datamux_o_alu_in_left_path_addr = dec_o_left_path_addr; |
|
/* |
case (k_pp_active_reg) |
8'h80: datamux_o_alu_in_left_path_addr = `RN_PC; |
8'h40: datamux_o_alu_in_left_path_addr = (dec_o_use_s) ? `RN_U:`RN_S; |
202,15 → 210,21
8'h08: datamux_o_alu_in_left_path_addr = `RN_DP; |
8'h04: datamux_o_alu_in_left_path_addr = `RN_ACCB; |
8'h02: datamux_o_alu_in_left_path_addr = `RN_ACCA; |
8'h01: datamux_o_alu_in_left_path_addr = `RN_CC; |
endcase |
8'h01: datamux_o_alu_in_left_path_addr = `RN_CC; |
8'h00: datamux_o_alu_in_left_path_addr = dec_o_left_path_addr; |
endcase |
*/ |
end |
|
/* Destination register address MUX |
*/ |
always @(*) |
begin |
datamux_o_dest_reg_addr = dec_o_dest_reg_addr; |
begin |
if (k_pp_active_reg != `RN_INV) |
datamux_o_dest_reg_addr = k_pp_active_reg; |
else |
datamux_o_dest_reg_addr = dec_o_dest_reg_addr; |
/* |
case (k_pp_active_reg) |
8'h80: datamux_o_dest_reg_addr = `RN_PC; |
8'h40: datamux_o_dest_reg_addr = (dec_o_use_s) ? `RN_U:`RN_S; |
219,8 → 233,10
8'h08: datamux_o_dest_reg_addr = `RN_DP; |
8'h04: datamux_o_dest_reg_addr = `RN_ACCB; |
8'h02: datamux_o_dest_reg_addr = `RN_ACCA; |
8'h01: datamux_o_dest_reg_addr = `RN_CC; |
endcase |
8'h01: datamux_o_dest_reg_addr = `RN_CC; |
8'h00: datamux_o_dest_reg_addr = dec_o_dest_reg_addr; |
endcase |
*/ |
end |
|
/* Destination register data mux |
297,7 → 313,7
endcase |
end |
|
always @(posedge k_clk or posedge k_reset) |
always @(posedge cpu_clk or posedge k_reset) |
begin |
if (k_reset == 1'b1) |
begin |
449,8 → 465,11
`SEQ_FETCH_1: |
begin |
k_cpu_oe <= 1; |
state <= `SEQ_FETCH_2; |
k_inc_pc <= 1; |
k_inc_pc <= 1; |
k_p2_valid <= 0; // set when an k_opcode is page 2 |
k_p3_valid <= 0; // set when an k_opcode is page 3 |
k_pp_active_reg <= `RN_INV; // ensures that only push/pull control the left/dest muxes |
state <= `SEQ_FETCH_2; |
end |
`SEQ_FETCH_2: |
begin |
459,29 → 478,18
8'h10: |
begin |
k_p2_valid <= 1; |
k_p3_valid <= 0; |
state <= `SEQ_FETCH_3; |
end |
8'h11: |
begin |
k_p2_valid <= 0; |
begin |
k_p3_valid <= 1; |
state <= `SEQ_FETCH_3; |
end |
end |
8'h1e, 8'h1f: |
begin |
state <= `SEQ_FETCH_3; // tfr, exg, treated separately |
k_p2_valid <= 0; // set when an k_opcode is page 2 |
k_p3_valid <= 0; // set when an k_opcode is page 3 |
end |
state <= `SEQ_FETCH_3; // tfr, exg, treated separately |
default: |
begin |
state <= `SEQ_DECODE; |
k_p2_valid <= 0; // set when an k_opcode is page 2 |
k_p3_valid <= 0; // set when an k_opcode is page 3 |
end |
endcase |
k_pp_active_reg <= 8'h00; // prevents wrong register in left/dest data muxes |
end |
`SEQ_FETCH_3: |
begin |
508,17 → 516,13
case (dec_o_p1_mode) |
`NONE: // unknown k_opcode or push/pull... refetch ? |
begin |
casex (k_opcode) |
casex (k_opcode) |
8'h13: state <= `SEQ_SYNC; |
8'h39: // RTS |
begin |
state <= `SEQ_PREPULL; |
k_pp_regs <= 8'h80; // Pull PC (RTS)all regs |
end |
8'h3B: // RTI |
begin |
state <= `SEQ_PREPULL; |
k_pp_regs <= 8'hff; // all regs |
end |
8'b001101x0: // PUSH S&U |
begin |
state <= `SEQ_PC_READ_L; |
530,6 → 534,11
next_state <= `SEQ_PREPULL; |
state <= `SEQ_PC_READ_L; |
end |
8'h3B: // RTI |
begin |
state <= `SEQ_PREPULL; |
k_pp_regs <= 8'hff; // all regs |
end |
default: /* we ignore unknown opcodes */ |
state <= `SEQ_FETCH; |
endcase |
544,7 → 553,8
end |
`INHERENT: |
begin |
case (k_opcode) |
case (k_opcode) |
8'h3d: begin k_mul_cnt <= 1'h1; state <= `SEQ_GRAL_ALU; end // counter for mul |
8'h3f: state <= `SEQ_SWI; |
default: state <= `SEQ_GRAL_ALU; |
endcase |
659,25 → 669,66
endcase |
end |
`SEQ_GRAL_ALU: |
begin |
state <= `SEQ_GRAL_WBACK; |
k_write_dest <= 1; /* write destination on wback */ |
begin |
if (!k_mul_cnt) |
begin |
state <= `SEQ_GRAL_WBACK; |
k_write_dest <= 1; /* write destination on wback */ |
end |
else |
k_mul_cnt <= 1'h0; |
end |
`SEQ_GRAL_WBACK: |
begin |
next_mem_state <= `SEQ_FETCH; |
case (dec_o_dest_reg_addr) |
`RN_MEM8: state <= `SEQ_MEM_WRITE_L; |
`RN_MEM16: state <= `SEQ_MEM_WRITE_H; |
default: |
begin |
state <= `SEQ_FETCH; |
k_write_post_incdec <= dec_o_ea_wpost; |
end |
casex (k_opcode) |
8'h3C: state <= `SEQ_CWAI_STACK; // CWAI |
default: |
case (dec_o_dest_reg_addr) |
`RN_MEM8: state <= `SEQ_MEM_WRITE_L; |
`RN_MEM16: state <= `SEQ_MEM_WRITE_H; |
default: |
begin |
state <= `SEQ_FETCH; |
k_write_post_incdec <= dec_o_ea_wpost; |
end |
endcase |
endcase |
end |
`SEQ_INH_ALU: |
state <= `SEQ_GRAL_WBACK; |
`SEQ_CWAI_STACK: |
begin |
k_pp_regs <= 8'hff; |
k_set_e <= 1; |
state <= `SEQ_PREPUSH; // first stack the registers |
next_push_state <= `SEQ_CWAI_WAIT; // wait for interrupts |
end |
`SEQ_CWAI_WAIT: /* waits for an interrupt and process it */ |
begin |
k_forced_mem_size <= 1; |
next_mem_state <= `SEQ_FETCH; // then continue fetching instructions |
k_eahi <= 8'hff; |
k_ealo[7:4] <= 4'hf; |
if (k_nmi_req) |
begin |
k_reg_nmi <= 2'h0; |
k_ealo[3:0] <= 4'hc; |
state <= `SEQ_MEM_READ_H; // load new PC |
end |
else |
if (k_firq_req) |
begin |
k_reg_firq <= 2'h0; |
k_ealo[3:0] <= 4'h6; |
state <= `SEQ_MEM_READ_H; // load new PC |
end |
else |
if (k_irq_req) |
begin |
k_reg_irq <= 2'h0; |
k_ealo[3:0] <= 4'hf8; |
state <= `SEQ_MEM_READ_H; // load new PC |
end |
end |
`SEQ_TFREXG: |
state <= `SEQ_FETCH; |
`SEQ_IND_READ_EA: // reads EA byte |
751,25 → 802,24
if (k_pp_regs > 0) |
begin |
state <= `SEQ_PUSH_WRITE_L; |
//k_dec_su <= 1; |
end |
else |
state <= next_push_state; |
if (k_pp_regs[7]) begin k_pp_regs[7] <= 0; k_pp_active_reg <= 8'h80; end |
if (k_pp_regs[7]) begin k_pp_regs[7] <= 0; k_pp_active_reg <= `RN_PC; end |
else |
if (k_pp_regs[6]) begin k_pp_regs[6] <= 0; k_pp_active_reg <= 8'h40; end |
if (k_pp_regs[6]) begin k_pp_regs[6] <= 0; k_pp_active_reg <= (dec_o_use_s) ? `RN_U:`RN_S; end |
else |
if (k_pp_regs[5]) begin k_pp_regs[5] <= 0; k_pp_active_reg <= 8'h20; end |
if (k_pp_regs[5]) begin k_pp_regs[5] <= 0; k_pp_active_reg <= `RN_IY; end |
else |
if (k_pp_regs[4]) begin k_pp_regs[4] <= 0; k_pp_active_reg <= 8'h10; end |
if (k_pp_regs[4]) begin k_pp_regs[4] <= 0; k_pp_active_reg <= `RN_IX; end |
else |
if (k_pp_regs[3]) begin k_pp_regs[3] <= 0; k_pp_active_reg <= 8'h08; end |
if (k_pp_regs[3]) begin k_pp_regs[3] <= 0; k_pp_active_reg <= `RN_DP; end |
else |
if (k_pp_regs[2]) begin k_pp_regs[2] <= 0; k_pp_active_reg <= 8'h04; end |
if (k_pp_regs[2]) begin k_pp_regs[2] <= 0; k_pp_active_reg <= `RN_ACCB; end |
else |
if (k_pp_regs[1]) begin k_pp_regs[1] <= 0; k_pp_active_reg <= 8'h02; end |
if (k_pp_regs[1]) begin k_pp_regs[1] <= 0; k_pp_active_reg <= `RN_ACCA; end |
else |
if (k_pp_regs[0]) begin k_pp_regs[0] <= 0; k_pp_active_reg <= 8'h01; end |
if (k_pp_regs[0]) begin k_pp_regs[0] <= 0; k_pp_active_reg <= `RN_CC; end |
end |
`SEQ_PREPULL: |
begin |
780,21 → 830,21
end |
else |
state <= `SEQ_FETCH; // end of sequence |
if (k_pp_regs[0]) begin k_pp_active_reg <= 8'h01; k_pp_regs[0] <= 0; state <= `SEQ_MEM_READ_L; end |
if (k_pp_regs[0]) begin k_pp_active_reg <= `RN_CC; k_pp_regs[0] <= 0; state <= `SEQ_MEM_READ_L; end |
else |
if (k_pp_regs[1]) begin k_pp_active_reg <= 8'h02; k_pp_regs[1] <= 0; state <= `SEQ_MEM_READ_L; end |
if (k_pp_regs[1]) begin k_pp_active_reg <= `RN_ACCA; k_pp_regs[1] <= 0; state <= `SEQ_MEM_READ_L; end |
else |
if (k_pp_regs[2]) begin k_pp_active_reg <= 8'h04; k_pp_regs[2] <= 0; state <= `SEQ_MEM_READ_L; end |
if (k_pp_regs[2]) begin k_pp_active_reg <= `RN_ACCB; k_pp_regs[2] <= 0; state <= `SEQ_MEM_READ_L; end |
else |
if (k_pp_regs[3]) begin k_pp_active_reg <= 8'h08; k_pp_regs[3] <= 0; state <= `SEQ_MEM_READ_L; end |
if (k_pp_regs[3]) begin k_pp_active_reg <= `RN_DP; k_pp_regs[3] <= 0; state <= `SEQ_MEM_READ_L; end |
else |
if (k_pp_regs[4]) begin k_pp_active_reg <= 8'h10; k_pp_regs[4] <= 0; state <= `SEQ_MEM_READ_H;end |
if (k_pp_regs[4]) begin k_pp_active_reg <= `RN_IX; k_pp_regs[4] <= 0; state <= `SEQ_MEM_READ_H;end |
else |
if (k_pp_regs[5]) begin k_pp_active_reg <= 8'h20; k_pp_regs[5] <= 0; state <= `SEQ_MEM_READ_H;end |
if (k_pp_regs[5]) begin k_pp_active_reg <= `RN_IY; k_pp_regs[5] <= 0; state <= `SEQ_MEM_READ_H;end |
else |
if (k_pp_regs[6]) begin k_pp_active_reg <= 8'h40; k_pp_regs[6] <= 0; state <= `SEQ_MEM_READ_H; end |
if (k_pp_regs[6]) begin k_pp_active_reg <= (dec_o_use_s) ? `RN_U:`RN_S; k_pp_regs[6] <= 0; state <= `SEQ_MEM_READ_H; end |
else |
if (k_pp_regs[7]) begin k_pp_active_reg <= 8'h80; k_pp_regs[7] <= 0; state <= `SEQ_MEM_READ_H; end |
if (k_pp_regs[7]) begin k_pp_active_reg <= `RN_PC; k_pp_regs[7] <= 0; state <= `SEQ_MEM_READ_H; end |
end |
`SEQ_PUSH_WRITE_L: // first low byte push |
begin |
806,7 → 856,7
end |
`SEQ_PUSH_WRITE_L_1: |
begin |
if (k_pp_active_reg[7:4] > 0) |
if (k_pp_active_reg < `RN_ACCA) |
state <= `SEQ_PUSH_WRITE_H; |
else |
if (k_pp_regs[3:0] > 0) |
820,8 → 870,8
k_cpu_data_o <= regs_o_left_path_data[15:8]; |
state <= `SEQ_PUSH_WRITE_H_1; |
k_cpu_we <= 1; // write |
if (k_pp_active_reg[3:0] > 0) |
k_cpu_addr <= regs_o_su; |
if (k_pp_active_reg >= `RN_ACCA) |
k_cpu_addr <= regs_o_su; // address for 8 bit register |
k_dec_su <= 1; // decrement stack pointer |
end |
`SEQ_PUSH_WRITE_H_1: |
880,7 → 930,7
`INDEXED: k_cpu_addr <= regs_o_eamem_addr; |
default: k_cpu_addr <= { k_eahi, k_ealo }; |
endcase |
if (k_forced_mem_size | dec_o_source_size | (k_pp_active_reg[7:4] != 0)) |
if (k_forced_mem_size | dec_o_source_size | (k_pp_active_reg < `RN_ACCA)) |
state <= `SEQ_MEM_READ_H_1; |
else |
state <= `SEQ_MEM_READ_L_1; |
946,7 → 996,7
end |
`SEQ_MEM_WRITE_L: // reads high byte |
begin |
if (!dec_o_alu_size) // only if it is a n 8 bit write |
if (!dec_o_alu_size) // only if it is an 8 bit write |
case (dec_o_p1_mode) |
`INDEXED: k_cpu_addr <= regs_o_eamem_addr; |
default: k_cpu_addr <= { k_eahi, k_ealo }; |
972,6 → 1022,7
k_mem_dest = 0; |
k_new_pc = 16'hffff; |
k_write_tfr = 0; |
k_write_exg = 0; |
k_write_exg = 0; |
k_mul_cnt = 0; |
end |
endmodule |
/verilog/Changelog.txt
1,6 → 1,13
Changelong |
---------- |
|
01.01.14 |
-------- |
|
- alu16.v : the alu has been bronken in two units |
- MC6809_cpu.v : added CWAI states and decoding |
- decodres.v : added CWAI decoding |
|
31.12.13 |
-------- |
|
/verilog/defs.v
73,21 → 73,22
|
`define SEQ_GRAL_ALU 'h11 |
`define SEQ_GRAL_WBACK 'h12 |
`define SEQ_INH_ALU 'h13 |
`define SEQ_TFREXG 'h14 |
`define SEQ_CWAI_STACK 'h13 // stacks registers |
`define SEQ_CWAI_WAIT 'h14 // waits for an interrupt |
`define SEQ_TFREXG 'h15 |
|
`define SEQ_IND_READ_EA 'h15 // offset 8 or 16 bits |
`define SEQ_IND_READ_EA_1 'h16 |
`define SEQ_IND_READ_EA_2 'h17 // real operand from memory indirect |
`define SEQ_IND_DECODE 'h18 |
`define SEQ_IND_DECODE_OFS 'h19 // used to load 8 or 16 bits offset |
`define SEQ_JMP_LOAD_PC 'h1a |
`define SEQ_IND_READ_EA 'h16 // offset 8 or 16 bits |
`define SEQ_IND_READ_EA_1 'h17 |
`define SEQ_IND_READ_EA_2 'h18 // real operand from memory indirect |
`define SEQ_IND_DECODE 'h19 |
`define SEQ_IND_DECODE_OFS 'h1a // used to load 8 or 16 bits offset |
`define SEQ_JMP_LOAD_PC 'h1b |
|
|
`define SEQ_JSR_PUSH 'h1b |
`define SEQ_JSR_PUSH_L 'h1c |
`define SEQ_RTS_POP_L 'h1d |
`define SEQ_RTS_POP_H 'h1e |
`define SEQ_JSR_PUSH 'h1c |
`define SEQ_JSR_PUSH_L 'h1d |
`define SEQ_RTS_POP_L 'h1e |
`define SEQ_RTS_POP_H 'h1f |
|
`define SEQ_PREPUSH 'h20 |
`define SEQ_PREPULL 'h21 |
95,6 → 96,7
`define SEQ_PUSH_WRITE_L_1 'h23 |
`define SEQ_PUSH_WRITE_H 'h24 |
`define SEQ_PUSH_WRITE_H_1 'h25 |
`define SEQ_SYNC 'h26 |
|
`define SEQ_PC_READ_H 'h30 |
`define SEQ_PC_READ_H_1 'h31 |
/verilog/alu16.v
10,8 → 10,10
* |
*/ |
`include "defs.v" |
module alu16( |
input wire clk, |
|
|
module alu( |
input wire clk_in, |
input wire [15:0] a_in, |
input wire [15:0] b_in, |
input wire [7:0] CCR, /* condition code register */ |
21,186 → 23,429
output reg [7:0] CCRo |
); |
|
wire c_in, n_in, v_in, z_in, h_in; |
wire [7:0] ccr8_out, q8_out; |
wire [15:0] q16_out; |
wire [3:0] ccr16_out; |
|
reg [15:0] ra_in, rb_in; |
|
alu8 alu8(clk_in, ra_in[7:0], rb_in[7:0], CCR, opcode_in, q8_out, ccr8_out); |
alu16 alu16(clk_in, ra_in, rb_in, CCR, opcode_in, q16_out, ccr16_out); |
|
always @(posedge clk_in) |
begin |
ra_in <= a_in; |
rb_in <= b_in; |
end |
|
always @(*) |
begin |
if (sz_in) |
begin |
q_out = q16_out; |
CCRo = { CCR[7:4], ccr16_out }; |
end |
else |
begin |
q_out = { 8'h0, q8_out }; |
CCRo = ccr8_out; |
end |
end |
|
endmodule |
|
module alu8( |
input wire clk_in, |
input wire [15:0] a_in, |
input wire [15:0] b_in, |
input wire [7:0] CCR, /* condition code register */ |
input wire [4:0] opcode_in, /* ALU opcode */ |
output reg [7:0] q_out, /* ALU result */ |
output reg [7:0] CCRo |
); |
|
wire c_in, n_in, v_in, z_in, h_in; |
assign c_in = CCR[0]; /* carry flag */ |
assign n_in = CCR[3]; /* neg flag */ |
assign v_in = CCR[1]; /* overflow flag */ |
assign z_in = CCR[2]; /* zero flag */ |
assign h_in = CCR[5]; /* halb-carry flag */ |
|
|
wire [7:0] add8_r, adc8_r, sub8_r, sbc8_r, com8_r, neg8_r; |
wire [7:0] asr8_r, shr8_r, shl8_r, ror8_r, rol8_r, and8_r, or8_r, eor8_r; |
wire [3:0] daa8l_r, daa8h_r; |
wire daa_lnm9; |
|
wire [7:0] add8_w, adc8_w, com8_w, neg8_w, sub8_w, sbc8_w; |
wire [7:0] asr8_w, shr8_w, shl8_w, ror8_w, rol8_w, and8_w, or8_w, eor8_w; |
|
|
wire cadd8_w, cadc8_w, csub8_w, csbc8_w; |
wire cadd16_w, cadc16_w, csub16_w, csbc16_w; |
|
wire cadd8_r, cadc8_r, csub8_r, csbc8_r, ccom8_r, cneg8_r; |
wire casr8_r, cshr8_r, cshl8_r, cror8_r, crol8_r, cand8_r, cdaa8_r; |
|
wire vadd8_r, vadc8_r, vsub8_r, vsbc8_r, vcom8_r, vneg8_r; |
wire vasr8_r, vshr8_r, vshl8_r, vror8_r, vrol8_r, vand8_r; |
|
assign { cadd8_w, add8_w } = { 1'b0, a_in[7:0] } + { 1'b0, b_in[7:0] }; |
|
assign { cadc8_w, adc8_w } = { 1'b0, a_in[7:0] } + { 1'b0, b_in[7:0] } + { 8'h0, c_in }; |
|
|
assign { csub8_w, sub8_w } = { 1'b0, a_in[7:0] } - { 1'b0, b_in[7:0] }; |
|
assign { csbc8_w, sbc8_w } = { 1'b0, a_in[7:0] } - { 1'b0, b_in[7:0] } - { 8'h0, c_in }; |
|
|
assign com8_w = ~a_in[7:0]; |
|
assign neg8_w = 8'h0 - a_in[7:0]; |
|
|
assign asr8_w = { a_in[7], a_in[7:1] }; |
|
|
assign shr8_w = { 1'b0, a_in[7:1] }; |
|
|
assign shl8_w = { a_in[6:0], 1'b0 }; |
|
|
assign ror8_w = { c_in, a_in[7:1] }; |
|
|
assign rol8_w = { a_in[6:0], c_in }; |
|
|
assign and8_w = a_in[7:0] & b_in[7:0]; |
|
|
assign or8_w = a_in[7:0] | b_in[7:0]; |
|
|
assign eor8_w = a_in[7:0] ^ b_in[7:0]; |
|
|
// ADD, ADC |
assign { cadd8_r, add8_r } = { cadd8_w, add8_w }; |
assign vadd8_r = (a_in[7] & b_in[7] & (~add8_w[7])) | ((~a_in[7]) & (~b_in[7]) & add8_w[7]); |
assign { cadc8_r, adc8_r } = { cadd8_w, add8_w }; |
assign vadc8_r = (a_in[7] & b_in[7] & (~add8_w[7])) | ((~a_in[7]) & (~b_in[7]) & adc8_w[7]); |
// SUB, SUBC |
assign { csub8_r, sub8_r } = { csub8_w, sub8_w }; |
assign vsub8_r = (a_in[7] & (~b_in[7]) & (~sub8_w[7])) | ((~a_in[7]) & b_in[7] & sub8_w[7]); |
assign { csbc8_r, sbc8_r } = { csbc8_w, sbc8_w }; |
assign vsbc8_r = (a_in[7] & b_in[7] | (~sbc8_w[7])) | ((~a_in[7]) & b_in[7] & sbc8_w[7]); |
// COM |
assign com8_r = com8_w; |
assign ccom8_r = com8_w != 8'h0 ? 1'b1:1'b0; |
assign vcom8_r = 1'b0; |
// NEG |
assign neg8_r = neg8_w; |
assign cneg8_r = neg8_w[7] | neg8_w[6] | neg8_w[5] | neg8_w[4] | neg8_w[3] | neg8_w[2] | neg8_w[1] | neg8_w[0]; |
assign vneg8_r = neg8_w[7] & (~neg8_w[6]) & (~neg8_w[5]) & (~neg8_w[4]) & (~neg8_w[3]) & (~neg8_w[2]) & (~neg8_w[1]) & (~neg8_w[0]); |
// ASR |
assign asr8_r = asr8_w; |
assign casr8_r = a_in[0]; |
assign vasr8_r = a_in[0] ^ asr8_w[7]; |
// SHR |
assign shr8_r = shr8_w; |
assign cshr8_r = a_in[0]; |
assign vshr8_r = a_in[0] ^ shr8_w[7]; |
// SHL |
assign shl8_r = shl8_w; |
assign cshl8_r = a_in[7]; |
assign vshl8_r = a_in[7] ^ shl8_w[7]; |
// ROR |
assign ror8_r = ror8_w; |
assign cror8_r = a_in[0]; |
assign vror8_r = a_in[0] ^ shr8_w[7]; |
// ROL |
assign rol8_r = shl8_w; |
assign crol8_r = a_in[7]; |
assign vrol8_r = a_in[7] ^ rol8_w[7]; |
// AND |
assign and8_r = and8_w; |
assign cand8_r = c_in; |
assign vand8_r = 1'b0; |
// OR |
assign or8_r = or8_w; |
// EOR |
assign eor8_r = eor8_w; |
// DAA |
assign daa_lnm9 = (a_in[3:0] > 9); |
assign daa8l_r = (daa_lnm9 | h_in ) ? a_in[3:0] + 4'h6:a_in[3:0]; |
assign daa8h_r = ((a_in[7:4] > 9) || (c_in == 1'b1) || (a_in[7] & daa_lnm9)) ? a_in[7:4] + 4'h6:a_in[7:4]; |
assign cdaa8_r = daa8h_r < a_in[7:4]; |
|
reg c8, h8, n8, v8, z8; |
reg [7:0] q8; |
|
always @(*) |
begin |
q8 = 8'h0; |
c8 = c_in; |
h8 = h_in; |
v8 = v_in; |
case (opcode_in) |
`ADD: |
begin |
q8 = add8_r; |
c8 = cadd8_r; |
v8 = vadd8_r; |
end |
`ADC: |
begin |
q8 = adc8_r; |
c8 = cadc8_r; |
v8 = vadc8_r; |
end |
`CMP, `SUB: // for CMP no register result is written back |
begin |
q8 = sub8_r; |
c8 = csub8_r; |
v8 = vsub8_r; |
end |
`SBC: |
begin |
q8 = sbc8_r; |
c8 = csbc8_r; |
v8 = vsbc8_r; |
end |
`COM: |
begin |
q8 = com8_r; |
c8 = com8_r; |
v8 = vcom8_r; |
end |
`NEG: |
begin |
q8 = neg8_r; |
c8 = cneg8_r; |
v8 = vneg8_r; |
end |
`ASR: |
begin |
q8 = asr8_r; |
c8 = casr8_r; |
v8 = vasr8_r; |
end |
`LSR: |
begin |
q8 = shr8_r; |
c8 = cshr8_r; |
v8 = vshr8_r; |
end |
`LSL: |
begin |
q8 = shl8_r; |
c8 = cshl8_r; |
v8 = vshl8_r; |
end |
`ROR: |
begin |
q8 = ror8_r; |
c8 = cror8_r; |
v8 = vror8_r; |
end |
`ROL: |
begin |
q8 = rol8_r; |
c8 = crol8_r; |
v8 = vrol8_r; |
end |
`AND: |
begin |
q8 = and8_r; |
c8 = cand8_r; |
v8 = vand8_r; |
end |
`OR: |
begin |
q8 = or8_r; |
c8 = cand8_r; |
v8 = vand8_r; |
end |
`EOR: |
begin |
q8 = eor8_r; |
c8 = cand8_r; |
v8 = vand8_r; |
end |
`DAA: |
begin // V is undefined, so we don't touch it |
q8 = { daa8h_r, daa8l_r }; |
c8 = cdaa8_r; |
end |
`MUL: |
begin |
|
end |
`LD: |
begin |
v8 = 0; |
q8 = b_in[7:0]; |
end |
`ST: |
begin |
q8 = a_in[7:0]; |
end |
endcase |
end |
|
reg [7:0] regq8; |
/* register before second mux */ |
always @(posedge clk_in) |
begin |
regq8 <= q8; |
end |
|
always @(*) |
begin |
q_out[7:0] = q8; //regq8; |
case (opcode_in) |
`ORCC: |
CCRo = CCR | b_in[7:0]; |
`ANDCC: |
CCRo = CCR & b_in[7:0]; |
default: |
CCRo = { CCR[7:6], CCR[5], h8, q8[7], (q8 == 8'h0), v8, c8 }; |
endcase |
end |
|
initial |
begin |
end |
endmodule |
|
/* ALU for 16 bit operations */ |
module alu16( |
input wire clk_in, |
input wire [15:0] a_in, |
input wire [15:0] b_in, |
input wire [7:0] CCR, /* condition code register */ |
input wire [4:0] opcode_in, /* ALU opcode */ |
output reg [15:0] q_out, /* ALU result */ |
output reg [3:0] CCRo |
); |
|
wire c_in, n_in, v_in, z_in; |
assign c_in = CCR[0]; /* carry flag */ |
assign n_in = CCR[3]; /* neg flag */ |
assign v_in = CCR[1]; /* overflow flag */ |
assign z_in = CCR[2]; /* zero flag */ |
assign h_in = CCR[5]; /* halb-carry flag */ |
|
|
wire [7:0] add8_r, adc8_r, sub8_r, sbc8_r, com8_r, neg8_r; |
wire [7:0] asr8_r, shr8_r, shl8_r, ror8_r, rol8_r, and8_r, or8_r, eor8_r; |
wire [15:0] add16_r, adc16_r, sub16_r, sbc16_r, com16_r, neg16_r; |
wire [15:0] asr16_r, shr16_r, shl16_r, ror16_r, rol16_r, and16_r, or16_r, eor16_r, mul16_r; |
wire [3:0] daa8l_r, daa8h_r; |
wire daa_lnm9; |
|
wire [7:0] add8_w, adc8_w, com8_w, neg8_w, sub8_w, sbc8_w; |
wire [7:0] asr8_w, shr8_w, shl8_w, ror8_w, rol8_w, and8_w, or8_w, eor8_w; |
wire [15:0] add16_w, adc16_w, com16_w, neg16_w, sub16_w, sbc16_w; |
wire [15:0] asr16_w, shr16_w, shl16_w, ror16_w, rol16_w, and16_w, or16_w, eor16_w, mul16_w; |
wire [15:0] asr16_w, shr16_w, shl16_w, ror16_w, rol16_w, and16_w, or16_w, eor16_w; |
|
wire cadd8_w, cadc8_w, csub8_w, csbc8_w; |
wire cadd16_w, cadc16_w, csub16_w, csbc16_w; |
|
wire cadd8_r, cadc8_r, csub8_r, csbc8_r, ccom8_r, cneg8_r; |
wire casr8_r, cshr8_r, cshl8_r, cror8_r, crol8_r, cand8_r, cdaa8_r; |
wire cadd16_r, cadc16_r, csub16_r, csbc16_r, ccom16_r, cneg16_r; |
wire casr16_r, cshr16_r, cshl16_r, cror16_r, crol16_r, cand16_r, cmul16_r; |
wire vadd8_r, vadc8_r, vsub8_r, vsbc8_r, vcom8_r, vneg8_r; |
wire vasr8_r, vshr8_r, vshl8_r, vror8_r, vrol8_r, vand8_r; |
|
wire vadd16_r, vadc16_r, vsub16_r, vsbc16_r, vcom16_r, vneg16_r; |
wire vasr16_r, vshr16_r, vshl16_r, vror16_r, vrol16_r, vand16_r; |
|
assign { cadd8_w, add8_w } = { 1'b0, a_in[7:0] } + { 1'b0, b_in[7:0] }; |
|
assign { cadd16_w, add16_w } = { 1'b0, a_in[15:0] } + { 1'b0, b_in[15:0] }; |
assign { cadc8_w, adc8_w } = { 1'b0, a_in[7:0] } + { 1'b0, b_in[7:0] } + { 8'h0, c_in }; |
|
assign { cadc16_w, adc16_w } = { 1'b0, a_in[15:0] } + { 1'b0, b_in[15:0] } + { 16'h0, c_in }; |
|
assign { csub8_w, sub8_w } = { 1'b0, a_in[7:0] } - { 1'b0, b_in[7:0] }; |
|
assign { csub16_w, sub16_w } = { 1'b0, a_in[15:0] } - { 1'b0, b_in[15:0] }; |
assign { csbc8_w, sbc8_w } = { 1'b0, a_in[7:0] } - { 1'b0, b_in[7:0] } - { 8'h0, c_in }; |
|
assign { csbc16_w, sbc16_w } = { 1'b0, a_in[15:0] } - { 1'b0, b_in[15:0] } - { 16'h0, c_in }; |
|
assign com8_w = ~a_in[7:0]; |
|
assign com16_w = ~a_in[15:0]; |
assign neg8_w = 8'h0 - a_in[7:0]; |
|
assign neg16_w = 16'h0 - a_in[15:0]; |
|
assign asr8_w = { a_in[7], a_in[7:1] }; |
assign asr16_w = { a_in[15], a_in[15:1] }; |
|
assign shr8_w = { 1'b0, a_in[7:1] }; |
assign shr16_w = { 1'b0, a_in[15:1] }; |
|
assign shl8_w = { a_in[6:0], 1'b0 }; |
assign shl16_w = { a_in[14:0], 1'b0 }; |
|
assign ror8_w = { c_in, a_in[7:1] }; |
assign ror16_w = { c_in, a_in[15:1] }; |
|
assign rol8_w = { a_in[6:0], c_in }; |
assign rol16_w = { a_in[14:0], c_in }; |
|
assign and8_w = a_in[7:0] & b_in[7:0]; |
assign and16_w = a_in[15:0] & b_in[15:0]; |
|
assign or8_w = a_in[7:0] | b_in[7:0]; |
assign or16_w = a_in[15:0] | b_in[15:0]; |
|
assign eor8_w = a_in[7:0] ^ b_in[7:0]; |
assign eor16_w = a_in[15:0] ^ b_in[15:0]; |
assign mul16_w = a_in[7:0] * b_in[7:0]; |
|
// ADD, ADC |
assign { cadd8_r, add8_r } = { cadd8_w, add8_w }; |
assign vadd8_r = (a_in[7] & b_in[7] & (~add8_w[7])) | ((~a_in[7]) & (~b_in[7]) & add8_w[7]); |
assign { cadd16_r, add16_r } = { cadd16_w, add16_w }; |
assign vadd16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & (~b_in[15]) & add16_w[15]); |
assign { cadc8_r, adc8_r } = { cadd8_w, add8_w }; |
assign vadc8_r = (a_in[7] & b_in[7] & (~add8_w[7])) | ((~a_in[7]) & (~b_in[7]) & adc8_w[7]); |
assign { cadc16_r, adc16_r } = { cadd16_w, add16_w }; |
assign vadc16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & (~b_in[15]) & adc16_w[15]); |
// SUB, SUBC |
assign { csub8_r, sub8_r } = { csub8_w, sub8_w }; |
assign vsub8_r = (a_in[7] & (~b_in[7]) & (~sub8_w[7])) | ((~a_in[7]) & b_in[7] & sub8_w[7]); |
assign { csub16_r, sub16_r } = { csub16_w, sub16_w }; |
assign vsub16_r = (a_in[15] & b_in[15] & (~add16_w[15])) | ((~a_in[15]) & b_in[15] & sub16_w[15]); |
assign { csbc8_r, sbc8_r } = { csbc8_w, sbc8_w }; |
assign vsbc8_r = (a_in[7] & b_in[7] | (~sbc8_w[7])) | ((~a_in[7]) & b_in[7] & sbc8_w[7]); |
assign { csbc16_r, sbc16_r } = { csbc16_w, sbc16_w }; |
assign vsbc16_r = (a_in[15] & b_in[15] & (~sbc16_w[15])) | ((~a_in[15]) & b_in[15] & sbc16_w[15]); |
// COM |
assign com8_r = com8_w; |
assign ccom8_r = com8_w != 8'h0 ? 1'b1:1'b0; |
assign vcom8_r = 1'b0; |
assign com16_r = com16_w; |
assign ccom16_r = com16_w != 16'h0 ? 1'b1:1'b0; |
assign vcom16_r = 1'b0; |
// NEG |
assign neg8_r = neg8_w; |
assign cneg8_r = neg8_w[7] | neg8_w[6] | neg8_w[5] | neg8_w[4] | neg8_w[3] | neg8_w[2] | neg8_w[1] | neg8_w[0]; |
assign vneg8_r = neg8_w[7] & (~neg8_w[6]) & (~neg8_w[5]) & (~neg8_w[4]) & (~neg8_w[3]) & (~neg8_w[2]) & (~neg8_w[1]) & (~neg8_w[0]); |
assign neg16_r = neg16_w; |
assign vneg16_r = neg16_w[15] & (~neg16_w[14]) & (~neg16_w[13]) & (~neg16_w[12]) & (~neg16_w[11]) & (~neg16_w[10]) & (~neg16_w[9]) & (~neg16_w[8]) & (~neg16_w[7]) & (~neg16_w[6]) & (~neg16_w[5]) & (~neg16_w[4]) & (~neg16_w[3]) & (~neg16_w[2]) & (~neg16_w[1]) & (~neg16_w[0]); |
assign cneg16_r = neg16_w[15] | neg16_w[14] | neg16_w[13] | neg16_w[12] | neg16_w[11] | neg16_w[10] | neg16_w[9] & neg16_w[8] | neg16_w[7] | neg16_w[6] | neg16_w[5] | neg16_w[4] | neg16_w[3] | neg16_w[2] | neg16_w[1] | neg16_w[0]; |
// ASR |
assign asr8_r = asr8_w; |
assign casr8_r = a_in[0]; |
assign vasr8_r = a_in[0] ^ asr8_w[7]; |
assign asr16_r = asr16_w; |
assign casr16_r = a_in[0]; |
assign vasr16_r = a_in[0] ^ asr16_w[15]; |
// SHR |
assign shr8_r = shr8_w; |
assign cshr8_r = a_in[0]; |
assign vshr8_r = a_in[0] ^ shr8_w[7]; |
assign shr16_r = shr16_w; |
assign cshr16_r = a_in[0]; |
assign vshr16_r = a_in[0] ^ shr16_w[15]; |
// SHL |
assign shl8_r = shl8_w; |
assign cshl8_r = a_in[7]; |
assign vshl8_r = a_in[7] ^ shl8_w[7]; |
assign shl16_r = shl16_w; |
assign cshl16_r = a_in[15]; |
assign vshl16_r = a_in[15] ^ shl16_w[15]; |
// ROR |
assign ror8_r = ror8_w; |
assign cror8_r = a_in[0]; |
assign vror8_r = a_in[0] ^ shr8_w[7]; |
assign ror16_r = ror16_w; |
assign cror16_r = a_in[0]; |
assign vror16_r = a_in[0] ^ ror16_w[15]; |
// ROL |
assign rol8_r = shl8_w; |
assign crol8_r = a_in[7]; |
assign vrol8_r = a_in[7] ^ rol8_w[7]; |
assign rol16_r = rol16_w; |
assign crol16_r = a_in[15]; |
assign vrol16_r = a_in[15] ^ rol16_w[15]; |
// AND |
assign and8_r = and8_w; |
assign cand8_r = c_in; |
assign vand8_r = 1'b0; |
assign and16_r = and16_w; |
assign cand16_r = c_in; |
assign vand16_r = 1'b0; |
// OR |
assign or8_r = or8_w; |
assign or16_r = or16_w; |
// EOR |
assign eor8_r = eor8_w; |
assign eor16_r = eor16_w; |
// MUL |
assign mul16_r = mul16_w; |
assign cmul16_r = mul16_w[7]; |
// DAA |
assign daa_lnm9 = (a_in[3:0] > 9); |
assign daa8l_r = (daa_lnm9 | h_in ) ? a_in[3:0] + 4'h6:a_in[3:0]; |
assign daa8h_r = ((a_in[7:4] > 9) || (c_in == 1'b1) || (a_in[7] & daa_lnm9)) ? a_in[7:4] + 4'h6:a_in[7:4]; |
assign cdaa8_r = daa8h_r < a_in[7:4]; |
|
wire [15:0] q16_mul; |
|
mul8x8 mulu(clk_in, a_in[7:0], b_in[7:0], mul16_r); |
assign cmul16_r = mul16_r[7]; |
|
reg c8, h8, n8, v8, z8, c16, n16, v16, z16; |
reg [7:0] q8; |
reg c16, n16, v16, z16; |
reg [15:0] q16; |
|
always @(*) |
begin |
q8 = 8'h0; |
q16 = 16'h0; |
c8 = c_in; |
h8 = h_in; |
v8 = v_in; |
c16 = c_in; |
v16 = v_in; |
case (opcode_in) |
`ADD: |
begin |
q8 = add8_r; |
c8 = cadd8_r; |
v8 = vadd8_r; |
q16 = add16_r; |
c16 = cadd16_r; |
v16 = vadd16_r; |
207,9 → 452,6
end |
`ADC: |
begin |
q8 = adc8_r; |
c8 = cadc8_r; |
v8 = vadc8_r; |
q16 = adc16_r; |
c16 = cadc16_r; |
v16 = vadc16_r; |
216,9 → 458,6
end |
`CMP, `SUB: // for CMP no register result is written back |
begin |
q8 = sub8_r; |
c8 = csub8_r; |
v8 = vsub8_r; |
q16 = sub16_r; |
c16 = csub16_r; |
v16 = vsub16_r; |
225,18 → 464,13
end |
`SBC: |
begin |
q8 = sbc8_r; |
c8 = csbc8_r; |
v8 = vsbc8_r; |
q16 = sbc16_r; |
c16 = csbc16_r; |
v16 = vsbc16_r; |
end |
end |
`ifdef HD6309 |
`COM: |
begin |
q8 = com8_r; |
c8 = com8_r; |
v8 = vcom8_r; |
q16 = com16_r; |
c16 = ccom16_r; |
v16 = vcom16_r; |
243,9 → 477,6
end |
`NEG: |
begin |
q8 = neg8_r; |
c8 = cneg8_r; |
v8 = vneg8_r; |
q16 = neg16_r; |
c16 = cneg16_r; |
v16 = vneg16_r; |
252,9 → 483,6
end |
`ASR: |
begin |
q8 = asr8_r; |
c8 = casr8_r; |
v8 = vasr8_r; |
q16 = asr16_r; |
c16 = casr16_r; |
v16 = vasr16_r; |
261,9 → 489,6
end |
`LSR: |
begin |
q8 = shr8_r; |
c8 = cshr8_r; |
v8 = vshr8_r; |
q16 = shr16_r; |
c16 = cshr16_r; |
v16 = vshr16_r; |
270,9 → 495,6
end |
`LSL: |
begin |
q8 = shl8_r; |
c8 = cshl8_r; |
v8 = vshl8_r; |
q16 = shl16_r; |
c16 = cshl16_r; |
v16 = vshl16_r; |
279,9 → 501,6
end |
`ROR: |
begin |
q8 = ror8_r; |
c8 = cror8_r; |
v8 = vror8_r; |
q16 = ror16_r; |
c16 = cror16_r; |
v16 = vror16_r; |
288,9 → 507,6
end |
`ROL: |
begin |
q8 = rol8_r; |
c8 = crol8_r; |
v8 = vrol8_r; |
q16 = rol16_r; |
c16 = crol16_r; |
v16 = vrol16_r; |
297,42 → 513,23
end |
`AND: |
begin |
q8 = and8_r; |
c8 = cand8_r; |
v8 = vand8_r; |
`ifdef HD6309 |
q16 = and16_r; |
c16 = cand16_r; |
v16 = vand16_r; |
`endif |
end |
`OR: |
begin |
q8 = or8_r; |
c8 = cand8_r; |
v8 = vand8_r; |
`ifdef HD6309 |
q16 = or16_r; |
c16 = cand16_r; |
v16 = vand16_r; |
`endif |
end |
`EOR: |
begin |
q8 = eor8_r; |
c8 = cand8_r; |
v8 = vand8_r; |
`ifdef HD6309 |
q16 = eor16_r; |
c16 = cand16_r; |
v16 = vand16_r; |
`endif |
end |
`DAA: |
begin // V is undefined, so we don't touch it |
q8 = { daa8h_r, daa8l_r }; |
c8 = cdaa8_r; |
end |
`endif |
`MUL: |
begin |
q16 = mul16_r; |
340,28 → 537,13
end |
`LD: |
begin |
v8 = 0; |
v16 = 0; |
q8 = b_in[7:0]; |
q16 = b_in[15:0]; |
end |
`ST: |
begin |
q8 = a_in[7:0]; |
q16 = a_in[15:0]; |
end |
`T816: // zero extend 8 -> 16 |
begin |
q16 = { 8'h0, b_in[7:0] }; |
end |
`T168L: // 16L -> 8 |
begin |
q8 = b_in[7:0]; |
end |
`T168H: // 16L -> 8 |
begin |
q8 = b_in[15:8]; |
end |
`SEXT: // sign extend |
begin |
q16 = { b_in[7] ? 8'hff:8'h00, b_in[7:0] }; |
373,13 → 555,11
endcase |
end |
|
reg [7:0] regq8; |
reg [15:0] regq16; |
reg reg_n_in, reg_z_in; |
/* register before second mux */ |
always @(posedge clk) |
always @(posedge clk_in) |
begin |
regq8 <= q8; |
regq16 <= q16; |
reg_n_in <= n_in; |
reg_z_in <= z_in; |
388,10 → 568,8
/* Negative & zero flags */ |
always @(*) |
begin |
n8 = regq8[7]; |
z8 = regq8 == 8'h0; |
n16 = regq16[15]; |
z16 = regq16 == 16'h0; |
n16 = q16[15]; |
z16 = q16 == 16'h0; |
case (opcode_in) |
`ADD: |
begin |
435,13 → 613,9
`EOR: |
begin |
end |
`DAA: |
begin // V is undefined, so we don't touch it |
end |
`MUL: |
begin |
n16 = reg_n_in; |
z16 = reg_z_in; |
end |
`LD: |
begin |
449,21 → 623,6
`ST: |
begin |
end |
`T816: // zero extend 8 -> 16 |
begin |
n16 = reg_n_in; |
z16 = reg_z_in; |
end |
`T168L: // 16L -> 8 |
begin |
n8 = reg_n_in; |
z8 = reg_z_in; |
end |
`T168H: // 16L -> 8 |
begin |
n8 = reg_n_in; |
z8 = reg_z_in; |
end |
`SEXT: // sign extend |
begin |
n16 = reg_n_in; |
479,22 → 638,8
|
always @(*) |
begin |
q_out[15:8] = regq16[15:8]; |
if (sz_in) |
q_out[7:0] = regq16[7:0]; |
else |
q_out[7:0] = regq8; |
case (opcode_in) |
`ORCC: |
CCRo = CCR | b_in[7:0]; |
`ANDCC: |
CCRo = CCR & b_in[7:0]; |
default: |
if (sz_in) // 16 bit |
CCRo = { CCR[7:4], n16, z16, v16, c16 }; |
else |
CCRo = { CCR[7:6], CCR[5], h8, n8, z8, v8, c8 }; |
endcase |
q_out = q16; |
CCRo = { n16, z16, v16, c16 }; |
end |
|
initial |
503,15 → 648,27
endmodule |
|
module mul8x8( |
input wire clk, |
input wire clk_in, |
input wire [7:0] a, |
input wire [7:0] b, |
output wire [15:0] q |
); |
|
always @(posedge clk) |
|
reg [15:0] pipe0, pipe1;//, pipe2, pipe3; |
assign q = pipe1; |
|
always @(posedge clk_in) |
begin |
|
ebd |
pipe0 <= (a[0] ? {8'h0, b}:16'h0) + (a[1] ? { 7'h0, b, 1'h0}:16'h0) + |
(a[2] ? {6'h0, b, 2'h0}:16'h0) + (a[3] ? { 5'h0, b, 3'h0}:16'h0); |
pipe1 <= (a[4] ? {4'h0, b, 4'h0}:16'h0) + (a[5] ? { 3'h0, b, 5'h0}:16'h0) + |
(a[6] ? {2'h0, b, 6'h0}:16'h0) + (a[7] ? { 1'h0, b, 7'h0}:16'h0) + pipe0; |
/* |
pipe0 <= (a[0] ? {8'h0, b}:16'h0) + (a[1] ? { 7'h0, b, 1'h0}:16'h0); |
pipe1 <= (a[2] ? {6'h0, b, 2'h0}:16'h0) + (a[3] ? { 5'h0, b, 3'h0}:16'h0) + pipe0; |
pipe2 <= (a[4] ? {4'h0, b, 4'h0}:16'h0) + (a[5] ? { 3'h0, b, 5'h0}:16'h0) + pipe1; |
pipe3 <= (a[6] ? {2'h0, b, 6'h0}:16'h0) + (a[7] ? { 1'h0, b, 7'h0}:16'h0) + pipe2; |
*/ |
end |
|
endmodule |
/verilog/decoders.v
331,7 → 331,7
|
8'h19: alu_opcode = `DAA; |
8'h1a: alu_opcode = `ORCC; |
8'h1c: alu_opcode = `ANDCC; |
8'h1c, 8'h3c: alu_opcode = `ANDCC; |
8'h1d: alu_opcode = `SEXT; |
8'h1e: alu_opcode = `EXG; |
8'b0011_000x: alu_opcode = `LEA; |
/verilog/regblock.v
21,9 → 21,9
input wire inc_su, /* increments S or U */ |
input wire dec_su, /* decrements s or u */ |
input wire use_s, /* increments S or U */ |
input wire [15:0] data_w, |
input wire [15:0] data_w, |
input wire [15:0] new_pc, |
input wire [7:0] CCR_in, |
input wire [7:0] CCR_in, |
input wire write_flags, |
input wire set_e, |
input wire clear_e, |
174,10 → 174,10
|
assign left = (write_tfr | write_exg) ? path_left_data:data_w; |
|
wire [15:0] new_su, old_su; |
//wire [15:0] new_su, old_su; |
|
assign old_su = (use_s) ? SS:SU; |
assign new_su = (inc_su) ? old_su + 16'h1:(dec_su) ? old_su - 16'h1:old_su; |
//assign old_su = (use_s) ? SS:SU; |
//assign new_su = (inc_su) ? old_su + 16'h1:(dec_su) ? old_su - 16'h1:old_su; |
|
always @(posedge clk_in) |
begin |
224,13 → 224,13
if (clear_e) eflag <= 0; |
if (write_pc) PC <= new_pc; |
if (inc_pc) PC <= PC + 16'h1; |
|
/* |
if (inc_su | dec_su) |
begin |
if (use_s) SS <= new_su; |
else SU <= new_su; |
end |
/* |
*/ |
if (inc_su) |
if (use_s) SS <= SS + 16'h1; |
else SU <= SU + 16'h1; |
237,7 → 237,6
if (dec_su) |
if (use_s) SS <= SS - 16'h1; |
else SU <= SU - 16'h1; |
*/ |
end |
|
`ifdef SIMULATION |
/verilog/BUGS.txt
1,5 → 1,11
Known bugs are described here |
|
01.01.14 |
-------- |
- SYNC doesn't work as expected |
- The E flag is not read back when RTI is processed. This means that FIRQ will not return |
correctly. |
|
31.12.13 |
-------- |
- CWAI, SYNC don't work as expected |