OpenCores
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 16 to Rev 17
    Reverse comparison

Rev 16 → Rev 17

/verilog/MC6809_cpu.v
5,7 → 5,7
* distributed under the terms of the Lesser GPL, see LICENSE.TXT
*
*/
 
`include "defs.v"
module MC6809_cpu(
input wire cpu_clk,
18,16 → 18,16
output wire cpu_oe_o,
output wire [15:0] cpu_addr_o,
input wire [7:0] cpu_data_i,
output wire [7:0] cpu_data_o,
input wire debug_clk,
output wire [7:0] cpu_data_o,
input wire debug_clk,
output wire debug_data_o // serial debug info, 64 bit shift register
);
 
wire k_reset;
 
reg [7:0] k_opcode, k_postbyte, k_ind_ea; /* all bytes of an instruction */
reg [7:0] k_pp_regs; // push/pull registers to process
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;
34,15 → 34,15
reg [5:0] state, // state of the main state machine
next_state, // next state to exit to from the read from [PC] state machine
next_mem_state, // next state to exit to from the read from memory state machine
next_push_state; // next state to exit to from push multiple state machine
next_push_state; // next state to exit to from push multiple state machine
reg k_write_tfr, k_write_exg;
reg k_cpu_oe, k_cpu_we, k_inc_pc;
reg k_indirect_loaded; // set when in indirect indexed and the address has been loaded
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 k_mul_cnt; // multiplier couner
reg k_write_pc, k_inc_su, k_dec_su, k_set_e, k_clear_e;
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_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
/****
* Decoder outputs
52,7 → 52,7
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_ofs5, dec_o_ea_indirect;
wire [3:0] dec_o_eabase, dec_o_eaidx;
80,46 → 80,46
/* Data Muxes */
reg [3:0] datamux_o_dest_reg_addr, datamux_o_alu_in_left_path_addr;
reg [15:0] datamux_o_alu_in_left_path_data, datamux_o_alu_in_right_path_data, datamux_o_dest;
 
reg k_p2_valid, k_p3_valid; /* 1 when k_postbyte has been loaded for page 2 or page 3 */
 
reg [2:0] k_mem_state; /* Memory mini-state machine */
 
- * Interrupt sync registers + +/* + * Interrupt sync registers */ - + reg [2:0] k_reg_nmi, k_reg_irq, k_reg_firq; wire k_nmi_req, k_firq_req, k_irq_req; - + assign k_nmi_req = k_reg_nmi[2] & k_reg_nmi[1]; assign k_firq_req = k_reg_firq[2] & k_reg_firq[1]; assign k_irq_req = k_reg_irq[2] & k_reg_irq[1]; - -/* Debug */ -`ifdef SERIAL_DEBUG -reg [63:0] debug_r; - -always @(posedge debug_clk) - begin - if (cpu_clk) - begin - debug_r[15:0] <= regs_o_pc; - debug_r[23:16] <= k_opcode; - debug_r[27:24] <= datamux_o_alu_in_left_path_addr; - debug_r[31:28] <= dec_o_right_path_addr; - debug_r[35:32] <= datamux_o_dest_reg_addr; - debug_r[39:36] <= { 3'b0, k_write_pc }; //regs_o_CCR[3:0]; - debug_r[55:40] <= { k_memhi,k_memlo };//k_new_pc; - debug_r[63:56] <= cpu_data_i; - end - else - debug_r <= debug_r << 1; // shift out - end - -assign debug_data_o = debug_r[63]; -`else -assign debug_data_o = 1'b0; + +/* Debug */ +`ifdef SERIAL_DEBUG +reg [63:0] debug_r; + +always @(posedge debug_clk) + begin + if (cpu_clk) + begin + debug_r[15:0] <= regs_o_pc; + debug_r[23:16] <= k_opcode; + debug_r[27:24] <= datamux_o_alu_in_left_path_addr; + debug_r[31:28] <= dec_lo_right_path_addr; + debug_r[35:32] <= datamux_o_dest_reg_addr; + debug_r[39:36] <= { 3'b0, k_write_pc }; //regs_o_CCR[3:0]; + debug_r[55:40] <= { k_memhi,k_memlo };//k_new_pc; + debug_r[63:56] <= cpu_data_i; + end + else + debug_r <= debug_r << 1; // shift out + end + +assign debug_data_o = debug_r[63]; +`else +assign debug_data_o = 1'b0; `endif alu alu( .clk_in(cpu_clk), @@ -126,18 +126,18 @@ .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 */ + .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(cpu_clk), .path_left_addr(datamux_o_alu_in_left_path_addr), .path_right_addr(dec_lo_right_path_addr), - .write_reg_addr(datamux_o_dest_reg_addr), + .write_reg_addr(datamux_o_dest_reg_addr), .exg_dest_r(k_postbyte[7:4]), .eapostbyte( k_ind_ea ), .offset16({ k_ofshi, k_ofslo }), @@ -170,10 +170,6 @@ .postbyte0(k_postbyte), .page2_valid(k_p2_valid), .page3_valid(k_p3_valid), - - .path_left_addr_o(dec_o_left_path_addr), - .path_right_addr_o(dec_o_right_path_addr), - .dest_reg_o(dec_o_dest_reg_addr), .path_left_addr_lo(dec_lo_left_path_addr), .path_right_addr_lo(dec_lo_right_path_addr), .dest_reg_lo(dec_lo_dest_reg_addr), @@ -206,7 +202,7 @@ .alu_opcode(dec_o_alu_opcode), .dest_flags_o(dec_o_write_flags) ); - + decode_ea dec_ea( .eapostbyte( k_ind_ea ), .eabase_o(dec_o_eabase), // base register @@ -217,8 +213,8 @@ .ea_is_indirect_o(dec_o_ea_indirect), .ea_write_back_o(dec_o_ea_wpost) ); - - + + /* Condition decoder */ test_condition test_cond( .opcode(k_opcode), @@ -227,9 +223,9 @@ .CCR(regs_o_CCR), .cond_taken(dec_o_cond_taken) ); - + /* Module IO */ - + assign cpu_oe_o = k_cpu_oe; // we latch on the rising edge assign cpu_we_o = k_cpu_we; assign cpu_addr_o = k_cpu_addr; @@ -236,28 +232,28 @@ assign cpu_data_o = k_cpu_data_o; assign k_reset = cpu_reset; assign cpu_state_o = state; - + wire cpu_dtack_i = 1; /* Left Register read mux */ always @(*) - begin + 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_lo_left_path_addr; end - + /* Destination register address MUX */ always @(*) - begin - if (k_pp_active_reg != `RN_INV) - datamux_o_dest_reg_addr = k_pp_active_reg; - else - datamux_o_dest_reg_addr = dec_lo_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_lo_dest_reg_addr; end - + /* Destination register data mux * selects the source to write to register. 16 bit registers have to be written at once after reading the low byte * @@ -277,9 +273,9 @@ else datamux_o_dest = alu_o_result; end - + /* ALU left input mux */ - + always @(*) begin if (dec_lo_left_path_memtype == `MT_BYTE) @@ -294,17 +290,17 @@ end else datamux_o_alu_in_left_path_data = regs_o_left_path_data; - end + end /* PC as destination from jmp/bsr mux */ -always @(*) - begin - k_new_pc = { k_memhi,k_memlo }; // used to fetch reset vector +always @(*) + begin + k_new_pc = { k_memhi,k_memlo }; // used to fetch reset vector case (dec_o_p1_mode) `REL16: k_new_pc = regs_o_pc + { k_memhi,k_memlo }; `REL8: k_new_pc = regs_o_pc + { {8{k_memlo[7]}}, k_memlo }; `EXTENDED: k_new_pc = { k_eahi,k_ealo }; `DIRECT: k_new_pc = { regs_o_dp, k_ealo }; - `INDEXED: + `INDEXED: if (dec_o_ea_indirect) k_new_pc = { k_memhi,k_memlo }; else @@ -311,7 +307,7 @@ k_new_pc = regs_o_eamem_addr; default: k_new_pc = { k_memhi,k_memlo }; // used to fetch reset vector - endcase + endcase end /* ALU right input mux */ always @(*) @@ -326,7 +322,7 @@ // datamux_o_alu_in_right_path_data = { k_memhi, k_memlo }; // endcase end - + always @(posedge cpu_clk or posedge k_reset) begin if (k_reset == 1'b1) @@ -363,16 +359,16 @@ if (k_set_e) k_set_e <= 0; if (k_clear_e) - k_clear_e <= 0; - if (k_write_dest) - k_write_dest <= 0; - if (k_write_exg) - k_write_exg <= 0; + k_clear_e <= 0; + if (k_write_dest) + k_write_dest <= 0; + if (k_write_exg) + k_write_exg <= 0; if (k_write_tfr) k_write_tfr <= 0; case (state) `SEQ_COLDRESET: - begin + begin k_forced_mem_size <= 1; state <= `SEQ_MEM_READ_H; k_eahi <= 8'hff; @@ -607,13 +603,13 @@ end else next_state <= `SEQ_GRAL_ALU; // no read - k_eahi <= regs_o_dp; + k_eahi <= regs_o_dp; end end `INDEXED: state <= `SEQ_IND_READ_EA; `EXTENDED: - begin + begin state <= `SEQ_PC_READ_H; // loads address if (op_JSR) next_state <= `SEQ_JSR_PUSH; else if (op_JMP) next_state <= `SEQ_JMP_LOAD_PC; @@ -625,7 +621,7 @@ next_mem_state <= `SEQ_GRAL_ALU; // read then alu end else - next_state <= `SEQ_GRAL_ALU; // no read + next_state <= `SEQ_GRAL_ALU; // no read end end `REL8: @@ -646,18 +642,18 @@ end endcase end - `SEQ_GRAL_ALU: - begin - if (!k_mul_cnt) + `SEQ_GRAL_ALU: + begin + if (!k_mul_cnt) begin - state <= `SEQ_GRAL_WBACK; - k_write_dest <= 1; /* write destination on wback */ - end + state <= `SEQ_GRAL_WBACK; + k_write_dest <= 1; /* write destination on wback */ + end k_mul_cnt <= 1'h0; end `SEQ_GRAL_WBACK: begin - next_mem_state <= `SEQ_FETCH; + next_mem_state <= `SEQ_FETCH; if (op_CWAI) state <= `SEQ_CWAI_STACK; // CWAI else if (dec_o_dest_memtype == `MT_BYTE) state <= `SEQ_MEM_WRITE_L; else if (dec_o_dest_memtype == `MT_WORD) state <= `SEQ_MEM_WRITE_H; @@ -665,26 +661,26 @@ begin state <= `SEQ_FETCH; k_write_post_incdec <= dec_o_ea_wpost & (dec_o_p1_mode == `INDEXED); - end + end end `SEQ_CWAI_STACK: - begin + 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 + 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; + next_mem_state <= `SEQ_FETCH; // then continue fetching instructions + k_eahi <= 8'hff; k_ealo[7:4] <= 4'hf; - if (k_nmi_req) + if (k_nmi_req) begin k_reg_nmi <= 3'h0; k_ealo[3:0] <= 4'hc; - state <= `SEQ_MEM_READ_H; // load new PC + state <= `SEQ_MEM_READ_H; // load new PC end else if (k_firq_req & `FLAGF) @@ -700,26 +696,26 @@ k_ealo[3:0] <= 4'h8; state <= `SEQ_MEM_READ_H; // load new PC end - end - `SEQ_SYNC: /* sync works like this: - * waits for an interrupt request - * we recognize an interrupt if the level was kept for 2 cycles - * then we don't call the service routine - * if it was 3 or more cycles, then we call the service routine - */ - begin - if (k_nmi_req) - begin + end + `SEQ_SYNC: /* sync works like this: + * waits for an interrupt request + * we recognize an interrupt if the level was kept for 2 cycles + * then we don't call the service routine + * if it was 3 or more cycles, then we call the service routine + */ + begin + if (k_nmi_req) + begin if (k_reg_nmi == 3'b111) // at least 3 cycles long - state <= `SEQ_NMI; - else - begin - state <= `SEQ_FETCH; - k_reg_nmi <= 3'h0; - end + state <= `SEQ_NMI; + else + begin + state <= `SEQ_FETCH; + k_reg_nmi <= 3'h0; + end end else - if (k_firq_req & `FLAGF) + if (k_firq_req & `FLAGF) begin if (k_reg_firq == 3'b111) // at least 3 cycles long state <= `SEQ_FIRQ; @@ -727,10 +723,10 @@ begin state <= `SEQ_FETCH; k_reg_firq <= 3'h0; - end + end end else - if (k_irq_req & `FLAGI) + if (k_irq_req & `FLAGI) begin if (k_reg_irq == 3'b111) // at least 3 cycles long state <= `SEQ_IRQ; @@ -744,9 +740,9 @@ begin state <= `SEQ_FETCH_1; k_cpu_addr <= regs_o_pc; - end + end end - `SEQ_TFREXG: + `SEQ_TFREXG: state <= `SEQ_FETCH; `SEQ_IND_READ_EA: // reads EA byte begin @@ -795,7 +791,7 @@ end end `SEQ_IND_DECODE_OFS: // loads argument if needed - begin + begin if (op_JSR) // jsr next_state <= `SEQ_JSR_PUSH; else @@ -808,12 +804,21 @@ k_forced_mem_size <= 1; // to load indirect address end else - state <= `SEQ_GRAL_ALU; // no load, then store + state <= `SEQ_GRAL_ALU; // no load, then store end end `SEQ_JMP_LOAD_PC: begin state <= `SEQ_FETCH; +`ifdef CODE_ANALYSIS + if (op_JSR) + $display("J JSR [%x]", k_new_pc); + else + if (op_JMP) + $display("J JUMP[%x]", k_new_pc); + else + $display("R JUMP[%x]", k_new_pc); +`endif end `SEQ_JSR_PUSH: begin @@ -824,9 +829,9 @@ `SEQ_PREPUSH: begin next_state <= `SEQ_PREPUSH; - if (k_pp_regs > 0) + if (k_pp_regs > 0) begin - state <= `SEQ_PUSH_WRITE_L; + state <= `SEQ_PUSH_WRITE_L; end else state <= next_push_state; @@ -847,20 +852,20 @@ if (k_pp_regs[0]) begin k_pp_regs[0] <= 0; k_pp_active_reg <= `RN_CC; end end `SEQ_PREPULL: - begin - if (k_pp_regs != 8'h0) + begin + if (k_pp_regs != 8'h0) begin - next_mem_state <= `SEQ_PREPULL; - end - else + next_mem_state <= `SEQ_PREPULL; + end + else 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 (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 else + 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 + else 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 <= `RN_ACCB; k_pp_regs[2] <= 0; state <= `SEQ_MEM_READ_L; end @@ -880,7 +885,7 @@ k_cpu_data_o <= regs_o_left_path_data[7:0]; state <= `SEQ_PUSH_WRITE_L_1; k_cpu_we <= 1; // write - k_cpu_addr <= regs_o_su - 16'h1; + k_cpu_addr <= regs_o_su - 16'h1; k_dec_su <= 1; end `SEQ_PUSH_WRITE_L_1: @@ -891,7 +896,7 @@ if (k_pp_regs[3:0] > 0) state <= `SEQ_PREPUSH; else - state <= next_push_state; + state <= next_push_state; k_cpu_addr <= k_cpu_addr - 16'h1; // when pushing 16 bits the second decrement comes too late end `SEQ_PUSH_WRITE_H: // reads high byte @@ -898,13 +903,13 @@ begin k_cpu_data_o <= regs_o_left_path_data[15:8]; state <= `SEQ_PUSH_WRITE_H_1; - k_cpu_we <= 1; // write + k_cpu_we <= 1; // write 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: - begin + begin if (next_state == `SEQ_JMP_LOAD_PC) k_write_pc <= 1; // load PC in the next cycle, the mux output will have the right source state <= next_state; @@ -947,8 +952,8 @@ `REL8, `REL16, `IMMEDIATE: k_memlo <= cpu_data_i; `DIRECT, `EXTENDED: k_ealo <= cpu_data_i; `INDEXED: k_ofslo <= cpu_data_i; - endcase - if ((next_state == `SEQ_JMP_LOAD_PC) & (dec_o_cond_taken)) + endcase + if ((next_state == `SEQ_JMP_LOAD_PC) & (dec_o_cond_taken)) k_write_pc <= 1; // load PC in the next cycle, the mux output will have the right source state <= next_state; end @@ -968,11 +973,11 @@ end else k_cpu_addr <= { k_eahi, k_ealo }; - endcase + endcase 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; + state <= `SEQ_MEM_READ_H_1; + else + state <= `SEQ_MEM_READ_L_1; k_forced_mem_size <= 0; // used for vector fetch end `SEQ_MEM_READ_H_1: @@ -984,13 +989,13 @@ begin k_memhi <= cpu_data_i; state <= `SEQ_MEM_READ_L_1; - k_cpu_addr <= k_cpu_addr + 16'h1; + k_cpu_addr <= k_cpu_addr + 16'h1; 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 + // falls through from READ_MEM_H with the right address if (op_PULL | op_RTI | op_RTS) begin k_cpu_addr <= regs_o_su; @@ -1006,8 +1011,8 @@ `SEQ_MEM_READ_L_2: begin k_memlo <= cpu_data_i; - 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) // used by cold-reset + 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) // used by cold-reset k_write_pc <= 1; case (dec_o_p1_mode) `INDEXED: // address loaded, load argument @@ -1050,25 +1055,25 @@ end `SEQ_MEM_WRITE_L_1: begin - k_write_post_incdec <= dec_o_ea_wpost; + k_write_post_incdec <= dec_o_ea_wpost & (dec_o_p1_mode == `INDEXED); state <= next_mem_state; end - + endcase end end - + initial begin k_mem_state = 0; k_cpu_oe = 0; k_cpu_we = 0; - k_new_pc = 16'hffff; - k_write_tfr = 0; - k_write_exg = 0; + k_new_pc = 16'hffff; + k_write_tfr = 0; + k_write_exg = 0; k_mul_cnt = 0; k_write_dest = 0; k_indirect_loaded = 0; end endmodule - + \ No newline at end of file
/verilog/Changelog.txt
1,6 → 1,15
Changelong
----------
 
25.10.14
--------
- decoders.v : removed unused signals
- MC6809_cpu.v : Removed unused signals
 
20.10.14
---------
- MC6809_cpu.v : fixed wrong postincrement/predecrement write-back after memory access
 
25.07.14
---------
- decoders.v : new decoder: fix decoding of ABX, TST
/verilog/alu16.v
151,8 → 151,8
always @(*)
begin
case (opcode_in)
2'b00, 2'b10: overflow_out = (a_in[15] & b_in[15] & (~q_out[15])) | ((~a_in[15]) & (~b_in[15]) & q_out[7]);
2'b01, 2'b11: overflow_out = (a_in[15] & (~b_in[15]) & (~q_out[15])) | ((~a_in[15]) & b_in[15] & q_out[7]);
2'b00, 2'b10: overflow_out = (a_in[15] & b_in[15] & (~q_out[15])) | ((~a_in[15]) & (~b_in[15]) & q_out[15]);
2'b01, 2'b11: overflow_out = (a_in[15] & (~b_in[15]) & (~q_out[15])) | ((~a_in[15]) & b_in[15] & q_out[15]);
endcase
end
 
/verilog/decoders.v
1,12 → 1,11
 
/*
* Signals which registers have to be read/written for the current opcode
* Decodes an opcode
*
* All decoders in one module
*
*
*/
`include "defs.v"
 
module decoders(
input wire clk_in,
input wire [7:0] opcode,
13,10 → 12,7
input wire [7:0] postbyte0,
input wire page2_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded)
input wire page3_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded)
output wire [3:0] path_left_addr_o,
output wire [3:0] path_right_addr_o,
output wire [3:0] dest_reg_o,
output reg [3:0] path_left_addr_lo,
output reg [3:0] path_right_addr_lo,
output reg [3:0] dest_reg_lo,
31,7 → 27,7
output reg [1:0] dest_memtype_lo,
output wire operand_read_o, // reads 1 operand from memory
output wire operand_write_o, // writes result to memory
output wire [2:0] mode,
output reg op_SYNC,
output reg op_EXG,
47,17 → 43,17
output reg op_JMP,
output reg op_JSR,
output wire use_s,
output wire [4:0] alu_opcode,
output wire dest_flags_o
 
);
reg [3:0] lr, rr, dr;
reg [1:0] lm, rm, dm;
reg ss, sz, p2, p3;
reg [2:0] mo;
reg [4:0] aop;
reg [3:0] lr, rr, dr; // left, right and destination register addresses
reg [1:0] lm, rm, dm; // left, right and destination memory sizes
reg ss, sz, p2, p3; // S or *U, 16 or *8, page 2, page 3
reg [2:0] mo; // Addressing Mode
reg [4:0] aop; // ALU opcode
assign write_dest = (dr != `RN_INV);
assign source_size = (lr < `RN_ACCA) | sz | (rm == `MT_WORD);
// result size is used to determine the size of the argument
65,13 → 61,9
// why do we need the result size ?... because of tfr&exg
assign result_size = (dr == `RN_INV) ? (lr < `RN_ACCA):
(dr < `RN_ACCA) ? 1:0;
 
assign path_right_addr_o = rr;
assign path_left_addr_o = lr;
assign dest_reg_o = dr;
// for registers, memory writes are handled differently
 
assign operand_read_o = (lm != `MT_NONE) | (rm != `MT_NONE);
assign operand_write_o = dm != `MT_NONE;
assign path_left_memtype_o = lm;
81,7 → 73,7
assign use_s = ss;
assign mode = mo;
assign alu_opcode = aop;
always @(*)
begin
lr = `RN_INV;
417,7 → 409,7
4'he: begin rm = `MT_WORD; dr = `RN_U; aop = `LD; end
4'hf: begin lr = `RN_U; dm = `MT_WORD; aop = `ST; end
endcase
 
end
4'he:
begin
440,7 → 432,7
4'he: begin rm = `MT_WORD; dr = `RN_U; aop = `LD; end
4'hf: begin lr = `RN_U; dm = `MT_WORD; aop = `ST; end
endcase
 
end
4'hf:
begin
729,7 → 721,7
endcase
end
endcase
end
always @(posedge clk_in)
begin
740,9 → 732,9
path_left_memtype_lo <= lm;
dest_memtype_lo <= dm;
end
endmodule
 
module decode_ea(
input wire [7:0] eapostbyte,
output reg [3:0] eabase_o, // base register
753,9 → 745,9
output wire ea_is_indirect_o,
output reg ea_write_back_o
);
assign ea_is_indirect_o = eapostbyte[7] & eapostbyte[4];
 
always @(*)
begin
eabase_o = `RN_PC;
769,7 → 761,7
8'bx11_x_xxxx: eabase_o = `RN_S;
endcase
end
always @(*)
begin
ea_ofs5_o = 1'b0;
803,8 → 795,8
endcase
end
endmodule
 
 
/* decodes the condition and checks the flags to see if it is met */
module test_condition(
input wire [7:0] opcode,
813,14 → 805,14
input wire [7:0] CCR,
output reg cond_taken
);
 
wire [7:0] op = page2_valid ? postbyte0:opcode;
always @(*)
begin
cond_taken = 1'b0;
if ((op == 8'h16) || (op == 8'h17) || (op == 8'h8D) ||
(op == 8'h0e) || (op == 8'h6e) || (op == 8'h7e)) // jmp
if ((opcode == 8'h16) || (opcode == 8'h17) || (opcode == 8'h8D) ||
(opcode == 8'h0e) || (opcode == 8'h6e) || (opcode == 8'h7e)) // jmp
cond_taken = 1'b1; // LBRA/LBSR, BSR
if (op[7:4] == 4'h2)
case (op[3:0])
842,5 → 834,5
4'hf: cond_taken = (`DFLAGN != `DFLAGV) | (`DFLAGZ); // BLE
endcase
end
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.