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 13 to Rev 14
- ↔ Reverse comparison
Rev 13 → Rev 14
/verilog/MC6809_cpu.v
49,9 → 49,11
* Decoder outputs |
*/ |
wire [2:0] dec_o_p1_mode; // addressing mode |
wire [2:0] dec_o_p1_optype; // k_opcode type |
wire dec_o_use_s; // signals when S should be used instead of U |
wire dec_o_alu_size; /* size of the result of an alu opcode (destination to be written) */ |
wire op_SYNC, op_EXG, op_TFR, op_RTS, op_RTI, op_CWAI; |
wire op_MUL, op_SWI, op_PUSH, op_PULL, op_LEA, op_JMP, op_JSR; |
|
/* ea decoder */ |
wire dec_o_ea_ofs8, dec_o_ea_ofs16, dec_o_ea_wpost, dec_o_ea_ofs0, dec_o_ea_indirect; |
/* alu k_opcode decoder */ |
67,8 → 69,6
/* 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; |
183,7 → 183,19
.page2_valid(k_p2_valid), |
.page3_valid(k_p3_valid), |
.mode(dec_o_p1_mode), |
.optype(dec_o_p1_optype), |
.op_SYNC(op_SYNC), |
.op_EXG (op_EXG ), |
.op_TFR (op_TFR ), |
.op_RTS (op_RTS ), |
.op_RTI (op_RTI ), |
.op_CWAI(op_CWAI), |
.op_MUL (op_MUL ), |
.op_SWI (op_SWI ), |
.op_PUSH(op_PUSH), |
.op_PULL(op_PULL), |
.op_LEA (op_LEA ), |
.op_JSR (op_JSR ), |
.op_JMP (op_JMP ), |
.use_s(dec_o_use_s) |
); |
|
253,16 → 265,18
*/ |
always @(*) |
begin |
datamux_o_dest = alu_o_result; |
case (dec_o_p1_optype) |
`OP_PULL, `OP_RTS: // destination register |
datamux_o_dest = { k_memhi, k_memlo }; |
`OP_LEA: |
if (op_PULL | op_RTS | op_RTI) // destination register |
datamux_o_dest = { k_memhi, k_memlo }; |
else |
if (op_LEA) |
begin |
if (dec_o_ea_indirect)// & dec_o_alu_size) |
datamux_o_dest = { k_memhi, k_memlo }; |
else |
datamux_o_dest = regs_o_eamem_addr; |
endcase |
end |
else |
datamux_o_dest = alu_o_result; |
end |
|
/* ALU left input mux */ |
272,15 → 286,15
if (dec_lo_left_path_addr == `RN_MEM8) |
datamux_o_alu_in_left_path_data = { k_memhi, k_memlo }; |
else |
case (dec_o_p1_optype) |
`OP_LEA: |
if (dec_o_ea_indirect)// & dec_o_alu_size) |
datamux_o_alu_in_left_path_data = { k_memhi, k_memlo }; |
else |
datamux_o_alu_in_left_path_data = regs_o_eamem_addr; |
default: |
if (op_LEA) |
begin |
if (dec_o_ea_indirect)// & dec_o_alu_size) |
datamux_o_alu_in_left_path_data = { k_memhi, k_memlo }; |
else |
datamux_o_alu_in_left_path_data = regs_o_eamem_addr; |
end |
else |
datamux_o_alu_in_left_path_data = regs_o_left_path_data; |
endcase |
end |
/* PC as destination from jmp/bsr mux */ |
always @(*) |
334,7 → 348,7
end |
else |
begin |
/* Inrerrupt recognition and acknowledge */ |
/* Interrupt recognition and acknowledge */ |
if (!k_reg_nmi[2]) |
k_reg_nmi <= { k_reg_nmi[1:0], cpu_nmi_n }; |
if (!k_reg_irq[2]) |
528,32 → 542,20
case (dec_o_p1_mode) |
`NONE: // unknown opcode or push/pull... refetch ? |
begin |
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'b001101x0: // PUSH S&U |
if (op_SYNC) state <= `SEQ_SYNC; |
else if (op_PUSH) // PUSH S&U |
begin |
state <= `SEQ_PC_READ_L; |
next_state <= `SEQ_PREPUSH; |
next_push_state <= `SEQ_FETCH; |
end |
8'b001101x1: // PULL S&U |
else if (op_PULL) // PULL S&U |
begin |
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 |
else /* we ignore unknown opcodes */ |
state <= `SEQ_FETCH; |
end |
`IMMEDIATE: // 8 or 16 bits as result decides.. |
begin |
565,32 → 567,41
end |
`INHERENT: |
begin |
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 |
if (op_RTI) // RTI |
begin |
state <= `SEQ_PREPULL; |
k_pp_regs <= 8'hff; // all regs |
end |
else if (op_RTS) |
begin |
state <= `SEQ_PREPULL; |
k_pp_regs <= 8'h80; // Pull PC (RTS)all regs |
end |
else if (op_MUL) |
begin k_mul_cnt <= 1'h1; state <= `SEQ_GRAL_ALU; end // counter for mul |
else if (op_SWI) |
state <= `SEQ_SWI; |
else |
state <= `SEQ_GRAL_ALU; |
end |
`DIRECT: |
begin |
state <= `SEQ_PC_READ_L; // loads address |
case (dec_o_p1_optype) |
`OP_JSR: next_state <= `SEQ_JSR_PUSH; |
`OP_JMP: next_state <= `SEQ_JMP_LOAD_PC; |
default: |
begin |
k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi |
if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) || |
(dec_o_left_path_addr == `RN_MEM8)) |
begin |
next_state <= `SEQ_MEM_READ_H; |
next_mem_state <= `SEQ_GRAL_ALU; // read then alu |
end |
else |
next_state <= `SEQ_GRAL_ALU; // no read |
k_eahi <= regs_o_dp; |
end |
endcase |
if (op_JSR) next_state <= `SEQ_JSR_PUSH; |
else if (op_JMP) next_state <= `SEQ_JMP_LOAD_PC; |
else |
begin |
k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi |
if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) || |
(dec_o_left_path_addr == `RN_MEM8)) |
begin |
next_state <= `SEQ_MEM_READ_H; |
next_mem_state <= `SEQ_GRAL_ALU; // read then alu |
end |
else |
next_state <= `SEQ_GRAL_ALU; // no read |
k_eahi <= regs_o_dp; |
end |
end |
`INDEXED: |
state <= `SEQ_IND_READ_EA; |
597,27 → 608,25
`EXTENDED: |
begin |
state <= `SEQ_PC_READ_H; // loads address |
case (dec_o_p1_optype) |
`OP_JSR: next_state <= `SEQ_JSR_PUSH; |
`OP_JMP: next_state <= `SEQ_JMP_LOAD_PC; |
default: |
begin |
k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi |
if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) || |
(dec_o_left_path_addr == `RN_MEM8)) |
begin |
next_state <= `SEQ_MEM_READ_H; |
next_mem_state <= `SEQ_GRAL_ALU; // read then alu |
end |
else |
next_state <= `SEQ_GRAL_ALU; // no read |
end |
endcase |
if (op_JSR) next_state <= `SEQ_JSR_PUSH; |
else if (op_JMP) next_state <= `SEQ_JMP_LOAD_PC; |
else |
begin |
k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi |
if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) || |
(dec_o_left_path_addr == `RN_MEM8)) |
begin |
next_state <= `SEQ_MEM_READ_H; |
next_mem_state <= `SEQ_GRAL_ALU; // read then alu |
end |
else |
next_state <= `SEQ_GRAL_ALU; // no read |
end |
end |
`REL8: |
begin |
state <= `SEQ_PC_READ_L; // loads address |
if (dec_o_p1_optype == `OP_JSR) // bsr |
if (op_JSR) // bsr |
next_state <= `SEQ_JSR_PUSH; |
else |
next_state <= `SEQ_JMP_LOAD_PC; // offset loaded in this cycle, jump if needed |
625,7 → 634,7
`REL16: |
begin |
state <= `SEQ_PC_READ_H; // loads address |
if (dec_o_p1_optype == `OP_JSR) // lbsr |
if (op_JSR) // lbsr |
next_state <= `SEQ_JSR_PUSH; |
else |
next_state <= `SEQ_JMP_LOAD_PC; |
636,28 → 645,21
begin // has prefix 10 or 11 |
case (dec_o_p1_mode) |
`NONE: // unknown k_opcode... re-fetch ? |
state <= `SEQ_FETCH; |
if (op_EXG) begin k_write_exg <= 1; state <= `SEQ_TFREXG; end |
else if (op_TFR) begin k_write_tfr <= 1; state <= `SEQ_TFREXG; end |
else |
state <= `SEQ_FETCH; |
`IMMEDIATE: // 8 or 16 bits as result decides.. |
begin |
case (k_opcode) |
8'h1e: begin k_write_exg <= 1; state <= `SEQ_TFREXG; end |
8'h1f: begin k_write_tfr <= 1; state <= `SEQ_TFREXG; end |
default: |
begin |
next_state <= `SEQ_GRAL_ALU; |
if (dec_o_alu_size) |
state <= `SEQ_PC_READ_H; |
else |
state <= `SEQ_PC_READ_L; |
end |
endcase |
next_state <= `SEQ_GRAL_ALU; |
if (dec_o_alu_size) |
state <= `SEQ_PC_READ_H; |
else |
state <= `SEQ_PC_READ_L; |
end |
`INHERENT: |
case (k_opcode) |
8'h3f: if (k_p2_valid) state <= `SEQ_SWI2; |
else state <= `SEQ_SWI3; |
default: state <= `SEQ_GRAL_ALU; |
endcase |
if (op_SWI) state <= (k_p2_valid) ? `SEQ_SWI2:`SEQ_SWI3; |
else state <= `SEQ_GRAL_ALU; |
`DIRECT: |
begin |
state <= `SEQ_PC_READ_L; |
706,19 → 708,17
`SEQ_GRAL_WBACK: |
begin |
next_mem_state <= `SEQ_FETCH; |
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 & (dec_o_p1_mode == `INDEXED); |
end |
endcase |
endcase |
if (op_CWAI) state <= `SEQ_CWAI_STACK; // CWAI |
else |
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 & (dec_o_p1_mode == `INDEXED); |
end |
endcase |
end |
`SEQ_CWAI_STACK: |
begin |
832,10 → 832,8
next_state <= `SEQ_IND_DECODE_OFS; // has some offset, load arg |
end |
else |
if (dec_o_p1_optype == `OP_JSR) // jsr |
begin |
next_state <= `SEQ_JSR_PUSH; |
end |
if (op_JSR) // jsr |
next_state <= `SEQ_JSR_PUSH; |
else |
begin // no extra load... |
if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) || |
853,10 → 851,8
end |
`SEQ_IND_DECODE_OFS: // loads argument if needed |
begin |
if (dec_o_p1_optype == `OP_JSR) // jsr |
begin |
if (op_JSR) // jsr |
next_state <= `SEQ_JSR_PUSH; |
end |
else |
begin |
if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) || |
918,7 → 914,7
state <= `SEQ_FETCH; // end of sequence |
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_opcode == 8'h3B) && (!`FLAGE)) // not all registers have to be pulled |
if (op_RTI && (!`FLAGE)) // not all registers have to be pulled |
begin |
k_pp_active_reg <= `RN_PC; k_pp_regs <= 0; state <= `SEQ_MEM_READ_H; |
end |
1017,13 → 1013,19
`SEQ_MEM_READ_H: // reads high byte |
begin |
case (dec_o_p1_mode) |
`NONE: begin k_cpu_addr <= regs_o_su; k_inc_su <= 1; end // pull, rts, rti |
`INDEXED: |
if (k_indirect_loaded) |
k_cpu_addr <= { k_memhi, k_memlo }; |
else |
k_cpu_addr <= regs_o_eamem_addr; |
default: k_cpu_addr <= { k_eahi, k_ealo }; |
default: |
if (op_PULL | op_RTI | op_RTS) |
begin |
k_cpu_addr <= regs_o_su; |
k_inc_su <= 1; |
end |
else |
k_cpu_addr <= { k_eahi, k_ealo }; |
endcase |
if (k_forced_mem_size | dec_o_source_size | (k_pp_active_reg < `RN_ACCA)) |
state <= `SEQ_MEM_READ_H_1; |
1045,16 → 1047,17
endcase |
state <= `SEQ_MEM_READ_L_1; |
k_cpu_addr <= k_cpu_addr + 16'h1; |
case (dec_o_p1_mode) |
`NONE: begin k_inc_su <= 1; end // pull, rts, rti |
endcase |
if (op_PULL | op_RTI | op_RTS) |
k_inc_su <= 1; |
end |
`SEQ_MEM_READ_L: // reads low byte |
begin |
// falls through from READ_MEM_H with the right address |
case (dec_o_p1_mode) |
`NONE: begin k_cpu_addr <= regs_o_su; k_inc_su <= 1; end // pull, rts, rti |
endcase |
if (op_PULL | op_RTI | op_RTS) |
begin |
k_cpu_addr <= regs_o_su; |
k_inc_su <= 1; |
end |
state <= `SEQ_MEM_READ_L_1; |
end |
`SEQ_MEM_READ_L_1: |
1069,9 → 1072,8
`MEMDEST_MH: k_memlo <= cpu_data_i; |
`MEMDEST_AH: k_ealo <= cpu_data_i; |
endcase |
case (dec_o_p1_mode) |
`NONE, `INHERENT: k_write_dest <= 1; // pull, rts, rti |
endcase |
if (op_PULL | op_RTI | op_RTS) k_write_dest <= 1; // FIXME: which other opcode is inherent and needs write-back ? |
|
if (next_mem_state == `SEQ_LOADPC) |
k_write_pc <= 1; |
case (dec_o_p1_mode) |
/verilog/Changelog.txt
1,5 → 1,9
Changelong |
---------- |
16.07.14 |
-------- |
- decoders.v : decode of some opcodes modified to improve size & speed |
- MC6809_cpu.v : Removed dec_o_optype and added single wire signals for common opcodes |
|
06.07.14 |
-------- |
/verilog/defs.v
143,7 → 143,7
`define DSZ_0 2'h0 |
`define DSZ_8 2'h1 |
`define DSZ_16 2'h2 |
|
/* |
`define OP_NONE 3'h0 |
`define OP_PUSH 3'h1 |
`define OP_PULL 3'h2 |
150,8 → 150,9
`define OP_RTS 3'h3 |
`define OP_JSR 3'h4 |
`define OP_JMP 3'h5 |
`define OP_LD 3'h6 |
`define OP_LEA 3'h7 |
`define OP_LEA 3'h6 |
`define OP_X 3'h7 |
*/ |
|
/* alu decoder right path modifier */ |
`define MOD_DEFAULT 2'h0 |
/verilog/decoders.v
159,6 → 159,19
input wire page3_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded) |
output reg [2:0] mode, |
output reg [2:0] optype, |
output reg op_SYNC, |
output reg op_EXG, |
output reg op_TFR, |
output reg op_RTS, |
output reg op_RTI, |
output reg op_CWAI, |
output reg op_MUL, |
output reg op_SWI, |
output reg op_PUSH, |
output reg op_PULL, |
output reg op_LEA, |
output reg op_JMP, |
output reg op_JSR, |
output reg use_s |
); |
|
170,10 → 183,22
begin |
//dsize = `DSZ_8; // data operand size |
//msize = `MSZ_8; // memory operand size |
optype = `OP_NONE; |
use_s = 1; |
mode = `NONE; |
size = 0; |
op_SYNC = 0; |
op_EXG = 0; |
op_TFR = 0; |
op_RTS = 0; |
op_RTI = 0; |
op_CWAI = 0; |
op_MUL = 0; |
op_SWI = 0; |
op_PUSH = 0; |
op_PULL = 0; |
op_LEA = 0; |
op_JMP = 0; |
op_JSR = 0; |
// Addressing mode |
casex(opcode) |
8'h0x: begin mode = `DIRECT; end |
181,20 → 206,23
8'h12, 8'h13, 8'h19: mode = `INHERENT; |
8'h14, 8'h15, 8'h18, 8'h1b: mode = `NONE; // undefined opcodes |
8'h16: mode = `REL16; |
8'h17: begin mode = `REL16; optype = `OP_JSR; end |
8'h1a, 8'h1c, 8'h1d, 8'h1e, 8'h1f: mode = `IMMEDIATE; // handled in ALU ORCC, ANDCC, SEX |
|
8'h17: begin mode = `REL16; op_JSR = 1; end |
8'h1a, 8'h1c, 8'h1d: mode = `IMMEDIATE; // handled in ALU ORCC, ANDCC, SEX |
8'h1e: op_EXG = 1; |
8'h1f: op_TFR = 1; |
8'h2x: mode = `REL8; |
8'h30, 8'h31, 8'h32, 8'h33: begin mode = `INDEXED; optype = `OP_LEA; end |
8'h34: begin optype = `OP_PUSH; mode = `NONE; end |
8'h35: begin optype = `OP_PULL; mode = `NONE; end |
8'h36: begin optype = `OP_PUSH; mode = `NONE; use_s = 0; end |
8'h37: begin optype = `OP_PULL; mode = `NONE; use_s = 0; end |
8'h30, 8'h31, 8'h32, 8'h33: begin mode = `INDEXED; op_LEA = 1; end |
8'h34: op_PUSH = 1; |
8'h35: op_PULL = 1; |
8'h36: begin op_PUSH = 1; use_s = 0; end |
8'h37: begin op_PULL = 1; use_s = 0; end |
8'h38, 8'h3e: mode = `NONE; |
// don't change to inh because SEQ_MEM_READ_x would not use register S as address |
8'h39, 8'h3b: begin mode = `NONE; optype = `OP_RTS; end |
8'h3a, 8'h3c, 8'h3d, 8'h3f: mode = `INHERENT; |
|
8'h39: begin op_RTS = 1; mode = `INHERENT; end |
8'h3b: begin op_RTI = 1; mode = `INHERENT; end |
8'h3a, 8'h3c: mode = `INHERENT; |
8'h3d: begin op_MUL = 1; mode = `INHERENT; end |
8'h3f: begin op_SWI = 1; mode = `INHERENT; end |
8'h4x: begin mode = `INHERENT; end |
8'h5x: begin mode = `INHERENT; end |
8'h6x: begin mode = `INDEXED; end |
222,18 → 250,14
endcase |
// Opcode type |
casex(opcode) |
8'b1xxx0110: optype = `OP_LD; |
8'h0e, 8'h6e, 8'h7e: optype = `OP_JMP; |
8'b11xx1100: optype = `OP_LD; // LDD |
8'b10xx1101: begin optype = `OP_JSR; end// bsr & jsr |
8'b1xxx1110: optype = `OP_LD; // LDX, LDU |
//8'b1xxx1111, 8'b11xx1101: optype = `OP_ST; |
8'h0e, 8'h6e, 8'h7e: op_JMP = 1; |
8'b10xx1101: op_JSR = 1; // bsr & jsr |
endcase |
if (page2_valid == 1'b1) |
begin |
casex(postbyte0) |
8'h2x: mode = `REL16; |
8'h3f: mode = `INHERENT; |
8'h3f: op_SWI = 1; |
8'h83: begin mode = `IMMEDIATE; size = 1; end |
//8'h93, 8'ha3, 8'hb3: begin mem16 = 1; size = 1; end |
8'h8c: begin mode = `IMMEDIATE; size = 1; end |
250,15 → 274,11
8'hax, 8'hex: mode = `INDEXED; |
8'hbx, 8'hfx: mode = `EXTENDED; |
endcase |
casex( postbyte0) |
8'b1xxx1110: optype = `OP_LD; // LDY, LDS |
//8'b1xxx1111, 8'b1xxx1101: optype = `OP_ST; // STY, STS |
endcase |
end |
if (page3_valid == 1'b1) |
begin |
casex(postbyte0) |
8'h3f: mode = `INHERENT; |
8'h3f: op_SWI = 1; |
8'h83: begin mode = `IMMEDIATE; size = 1; end // CMPD |
//8'h93, 8'ha3, 8'hb3: begin mem16 = 1; size = 1; end // CMPD |
8'h8c: begin mode = `IMMEDIATE; size = 1; end |