Line 41... |
Line 41... |
reg [15:0] k_cpu_addr, k_new_pc;
|
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_write_pc, k_inc_su, k_dec_su, k_set_e, k_clear_e;
|
reg k_mul_cnt; // multiplier couner
|
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_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
|
reg k_force_read_word_from_mem; // used to force the size of a memory read to be 16 bits, used for vector fetch
|
|
reg k_exception_process; // asserted to force the use of k_eaxx during PC fetch from memory
|
/****
|
/****
|
* Decoder outputs
|
* Decoder outputs
|
*/
|
*/
|
wire [2:0] dec_o_p1_mode; // addressing mode
|
wire [2:0] dec_o_p1_mode; // addressing mode
|
wire dec_o_use_s; // signals when S should be used instead of U
|
wire dec_o_use_s; // signals when S should be used instead of U
|
Line 56... |
Line 57... |
/* ea decoder */
|
/* ea decoder */
|
wire dec_o_ea_ofs8, dec_o_ea_ofs16, dec_o_ea_wpost, dec_o_ea_ofs5, dec_o_ea_indirect;
|
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;
|
wire [3:0] dec_o_eabase, dec_o_eaidx;
|
/* alu k_opcode decoder */
|
/* alu k_opcode decoder */
|
wire [4:0] dec_o_alu_opcode;
|
wire [4:0] dec_o_alu_opcode;
|
wire [1:0] dec_o_right_path_mod; /* Modifier for alu's right path input */
|
|
/* register decoder */
|
/* register decoder */
|
wire dec_o_wdest, dec_o_source_size, dec_o_write_flags;
|
wire dec_o_wdest, dec_o_source_size, dec_o_write_flags;
|
wire [3:0] dec_o_left_path_addr, dec_o_right_path_addr, dec_o_dest_reg_addr;
|
|
// latched versions, used for muxes, regs and alu
|
// latched versions, used for muxes, regs and alu
|
wire [3:0] dec_lo_left_path_addr, dec_lo_right_path_addr, dec_lo_dest_reg_addr;
|
wire [3:0] dec_lo_left_path_addr, dec_lo_right_path_addr, dec_lo_dest_reg_addr;
|
wire [1:0] dec_o_left_path_memtype, dec_o_right_path_memtype, dec_o_dest_memtype;
|
wire [1:0] dec_o_left_path_memtype, dec_o_right_path_memtype, dec_o_dest_memtype;
|
wire [1:0] dec_lo_left_path_memtype, dec_lo_right_path_memtype, dec_lo_dest_memtype;
|
wire [1:0] dec_lo_left_path_memtype, dec_lo_right_path_memtype, dec_lo_dest_memtype;
|
wire dec_o_operand_read, dec_o_operand_write;
|
wire dec_o_operand_read, dec_o_operand_write;
|
Line 229... |
Line 230... |
assign cpu_oe_o = k_cpu_oe; // we latch on the rising edge
|
assign cpu_oe_o = k_cpu_oe; // we latch on the rising edge
|
assign cpu_we_o = k_cpu_we;
|
assign cpu_we_o = k_cpu_we;
|
assign cpu_addr_o = k_cpu_addr;
|
assign cpu_addr_o = k_cpu_addr;
|
assign cpu_data_o = k_cpu_data_o;
|
assign cpu_data_o = k_cpu_data_o;
|
assign k_reset = cpu_reset;
|
assign k_reset = cpu_reset;
|
assign cpu_state_o = state;
|
assign cpu_state_o = regs_o_CCR;
|
|
|
wire cpu_dtack_i = 1;
|
wire cpu_dtack_i = 1;
|
/* Left Register read mux
|
/* Left Register read mux
|
*/
|
*/
|
always @(*)
|
always @(*)
|
Line 313... |
Line 314... |
always @(*)
|
always @(*)
|
begin
|
begin
|
datamux_o_alu_in_right_path_data = { k_memhi, k_memlo };
|
datamux_o_alu_in_right_path_data = { k_memhi, k_memlo };
|
if ((dec_lo_right_path_memtype == `MT_NONE) &&
|
if ((dec_lo_right_path_memtype == `MT_NONE) &&
|
(dec_o_p1_mode != `IMMEDIATE))
|
(dec_o_p1_mode != `IMMEDIATE))
|
// datamux_o_alu_in_right_path_data = { k_memhi, k_memlo };
|
|
//else
|
|
datamux_o_alu_in_right_path_data = regs_o_right_path_data;
|
datamux_o_alu_in_right_path_data = regs_o_right_path_data;
|
// `MT_BYTE, `MT_WORD:
|
|
// datamux_o_alu_in_right_path_data = { k_memhi, k_memlo };
|
|
// endcase
|
|
end
|
end
|
|
|
always @(posedge cpu_clk or posedge k_reset)
|
always @(posedge cpu_clk or posedge k_reset)
|
begin
|
begin
|
if (k_reset == 1'b1)
|
if (k_reset == 1'b1)
|
Line 334... |
Line 330... |
end
|
end
|
else
|
else
|
begin
|
begin
|
/* Interrupt recognition and acknowledge */
|
/* Interrupt recognition and acknowledge */
|
if (!k_reg_nmi[2])
|
if (!k_reg_nmi[2])
|
k_reg_nmi <= { k_reg_nmi[1:0], cpu_nmi_n };
|
k_reg_nmi <= { k_reg_nmi[1:0], !cpu_nmi_n };
|
if (!k_reg_irq[2])
|
if (!k_reg_irq[2])
|
k_reg_irq <= { k_reg_irq[1:0], cpu_irq_n };
|
k_reg_irq <= { k_reg_irq[1:0], !cpu_irq_n };
|
if (!k_reg_firq[2])
|
if (!k_reg_firq[2])
|
k_reg_firq <= { k_reg_firq[1:0], cpu_firq_n };
|
k_reg_firq <= { k_reg_firq[1:0], !cpu_firq_n };
|
/* modifier registers */
|
/* modifier registers */
|
if (k_inc_pc)
|
if (k_inc_pc)
|
k_inc_pc <= 0;
|
k_inc_pc <= 0;
|
if (k_write_pc)
|
if (k_write_pc)
|
k_write_pc <= 0;
|
k_write_pc <= 0;
|
Line 367... |
Line 363... |
if (k_write_tfr)
|
if (k_write_tfr)
|
k_write_tfr <= 0;
|
k_write_tfr <= 0;
|
case (state)
|
case (state)
|
`SEQ_COLDRESET:
|
`SEQ_COLDRESET:
|
begin
|
begin
|
k_forced_mem_size <= 1;
|
k_exception_process <= 1;
|
state <= `SEQ_MEM_READ_H;
|
state <= `SEQ_MEM_READ_H;
|
k_eahi <= 8'hff;
|
k_eahi <= 8'hff;
|
k_ealo <= 8'hfe;
|
k_ealo <= 8'hfe;
|
next_mem_state <= `SEQ_LOADPC;
|
next_mem_state <= `SEQ_LOADPC;
|
k_opcode <= 8'h15; // force the decoder for NONE, used in memory access
|
k_opcode <= 8'h15; // force the decoder for NONE, used in memory access
|
end
|
end
|
`SEQ_NMI:
|
`SEQ_NMI:
|
begin
|
begin
|
k_forced_mem_size <= 1;
|
k_exception_process <= 1;
|
k_reg_nmi <= 3'h0;
|
k_reg_nmi <= 3'h0;
|
{ k_eahi, k_ealo } <= 16'hfffc;
|
{ k_eahi, k_ealo } <= 16'hfffc;
|
k_pp_regs <= 8'hff;
|
k_pp_regs <= 8'hff;
|
k_set_e <= 1;
|
k_set_e <= 1;
|
state <= `SEQ_PREPUSH; // first stack the registers
|
state <= `SEQ_PREPUSH; // first stack the registers
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
|
next_mem_state <= `SEQ_LOADPC; // than continue fetching instructions
|
end
|
end
|
`SEQ_SWI:
|
`SEQ_SWI:
|
begin
|
begin
|
k_forced_mem_size <= 1;
|
k_exception_process <= 1;
|
state <= `SEQ_MEM_READ_H;
|
|
{ k_eahi, k_ealo } <= 16'hfffa;
|
{ k_eahi, k_ealo } <= 16'hfffa;
|
k_pp_regs <= 8'hff;
|
k_pp_regs <= 8'hff;
|
state <= `SEQ_PREPUSH; // first stack the registers
|
state <= `SEQ_PREPUSH; // first stack the registers
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
|
next_mem_state <= `SEQ_LOADPC; // than continue fetching instructions
|
k_set_e <= 1;
|
k_set_e <= 1;
|
end
|
end
|
`SEQ_IRQ:
|
`SEQ_IRQ:
|
begin
|
begin
|
k_forced_mem_size <= 1;
|
k_exception_process <= 1;
|
k_reg_irq <= 3'h0;
|
k_reg_irq <= 3'h0;
|
state <= `SEQ_MEM_READ_H;
|
|
{ k_eahi, k_ealo } <= 16'hfff8;
|
{ k_eahi, k_ealo } <= 16'hfff8;
|
k_pp_regs <= 8'hff;
|
k_pp_regs <= 8'hff;
|
next_mem_state <= `SEQ_PREPUSH;
|
|
k_set_e <= 1;
|
k_set_e <= 1;
|
state <= `SEQ_PREPUSH; // first stack the registers
|
state <= `SEQ_PREPUSH; // first stack the registers
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
|
next_mem_state <= `SEQ_LOADPC; // than continue fetching instructions
|
end
|
end
|
`SEQ_FIRQ:
|
`SEQ_FIRQ:
|
begin
|
begin
|
k_forced_mem_size <= 1;
|
k_exception_process <= 1;
|
k_reg_firq <= 3'h0;
|
k_reg_firq <= 3'h0;
|
{ k_eahi, k_ealo } <= 16'hfff6;
|
{ k_eahi, k_ealo } <= 16'hfff6;
|
k_pp_regs <= 8'h81; // PC & CC
|
k_pp_regs <= 8'h81; // PC & CC
|
k_clear_e <= 1;
|
k_clear_e <= 1;
|
state <= `SEQ_PREPUSH; // first stack the registers
|
state <= `SEQ_PREPUSH; // first stack the registers
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
|
next_mem_state <= `SEQ_LOADPC; // than continue fetching instructions
|
end
|
end
|
`SEQ_SWI2:
|
`SEQ_SWI2:
|
begin
|
begin
|
k_forced_mem_size <= 1;
|
k_exception_process <= 1;
|
{ k_eahi, k_ealo } <= 16'hfff4;
|
{ k_eahi, k_ealo } <= 16'hfff4;
|
k_pp_regs <= 8'hff;
|
k_pp_regs <= 8'hff;
|
k_set_e <= 1;
|
k_set_e <= 1;
|
state <= `SEQ_PREPUSH; // first stack the registers
|
state <= `SEQ_PREPUSH; // first stack the registers
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
|
next_mem_state <= `SEQ_LOADPC; // than continue fetching instructions
|
end
|
end
|
`SEQ_SWI3:
|
`SEQ_SWI3:
|
begin
|
begin
|
k_forced_mem_size <= 1;
|
k_exception_process <= 1;
|
{ k_eahi, k_ealo } <= 16'hfff2;
|
{ k_eahi, k_ealo } <= 16'hfff2;
|
k_pp_regs <= 8'hff;
|
k_pp_regs <= 8'hff;
|
k_set_e <= 1;
|
k_set_e <= 1;
|
state <= `SEQ_PREPUSH; // first stack the registers
|
state <= `SEQ_PREPUSH; // first stack the registers
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
|
next_mem_state <= `SEQ_LOADPC; // than continue fetching instructions
|
end
|
end
|
`SEQ_UNDEF:
|
`SEQ_UNDEF:
|
begin
|
begin
|
k_forced_mem_size <= 1;
|
k_exception_process <= 1;
|
{ k_eahi, k_ealo } <= 16'hfff0;
|
{ k_eahi, k_ealo } <= 16'hfff0;
|
k_pp_regs <= 8'hff;
|
k_pp_regs <= 8'hff;
|
k_set_e <= 1;
|
k_set_e <= 1;
|
state <= `SEQ_PREPUSH; // first stack the registers
|
state <= `SEQ_PREPUSH; // first stack the registers
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_push_state <= `SEQ_MEM_READ_H; // than load new PC
|
next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
|
next_mem_state <= `SEQ_LOADPC; // than continue fetching instructions
|
end
|
end
|
`SEQ_LOADPC: /* loads the PC with the address taken from the reset vector */
|
`SEQ_LOADPC: /* loads the PC with the address taken from the reset vector */
|
begin
|
begin
|
$display("cpu_data_i %02x %t", cpu_data_i, $time);
|
$display("cpu_data_i %02x %t", cpu_data_i, $time);
|
state <= `SEQ_FETCH;
|
state <= `SEQ_FETCH;
|
Line 462... |
Line 455... |
case (k_mem_state)
|
case (k_mem_state)
|
3'h0: // start, output address
|
3'h0: // start, output address
|
begin
|
begin
|
k_p2_valid <= 0; // set when an k_opcode is page 2
|
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_p3_valid <= 0; // set when an k_opcode is page 3
|
|
k_opcode <= 8'h12; // clears all special opcode flags
|
k_pp_active_reg <= `RN_INV; // ensures that only push/pull control the left/dest muxes
|
k_pp_active_reg <= `RN_INV; // ensures that only push/pull control the left/dest muxes
|
if (k_nmi_req)
|
if (k_nmi_req)
|
state <= `SEQ_NMI;
|
state <= `SEQ_NMI;
|
else
|
else
|
if (k_firq_req & `FLAGF)
|
if (k_firq_req & (!`FLAGF)) // flag cleared means enabled
|
state <= `SEQ_FIRQ;
|
state <= `SEQ_FIRQ;
|
else
|
else
|
if (k_irq_req & `FLAGI)
|
if (k_irq_req & (!`FLAGI))
|
state <= `SEQ_IRQ;
|
state <= `SEQ_IRQ;
|
else
|
else
|
begin
|
begin
|
k_mem_state <= k_mem_state + 3'h1;
|
k_mem_state <= k_mem_state + 3'h1;
|
k_cpu_addr <= regs_o_pc;
|
k_cpu_addr <= regs_o_pc;
|
Line 670... |
Line 664... |
state <= `SEQ_PREPUSH; // first stack the registers
|
state <= `SEQ_PREPUSH; // first stack the registers
|
next_push_state <= `SEQ_CWAI_WAIT; // wait for interrupts
|
next_push_state <= `SEQ_CWAI_WAIT; // wait for interrupts
|
end
|
end
|
`SEQ_CWAI_WAIT: /* waits for an interrupt and process it */
|
`SEQ_CWAI_WAIT: /* waits for an interrupt and process it */
|
begin
|
begin
|
k_forced_mem_size <= 1;
|
k_exception_process <= 1;
|
next_mem_state <= `SEQ_FETCH; // then continue fetching instructions
|
next_mem_state <= `SEQ_FETCH; // then continue fetching instructions
|
k_eahi <= 8'hff;
|
k_eahi <= 8'hff;
|
k_ealo[7:4] <= 4'hf;
|
k_ealo[7:4] <= 4'hf;
|
if (k_nmi_req)
|
if (k_nmi_req)
|
begin
|
begin
|
k_reg_nmi <= 3'h0;
|
k_reg_nmi <= 3'h0;
|
k_ealo[3:0] <= 4'hc;
|
k_ealo[3:0] <= 4'hc;
|
state <= `SEQ_MEM_READ_H; // load new PC
|
state <= `SEQ_MEM_READ_H; // load new PC
|
end
|
end
|
else
|
else
|
if (k_firq_req & `FLAGF)
|
if (k_firq_req & (~`FLAGF))
|
begin
|
begin
|
k_reg_firq <= 3'h0;
|
k_reg_firq <= 3'h0;
|
k_ealo[3:0] <= 4'h6;
|
k_ealo[3:0] <= 4'h6;
|
state <= `SEQ_MEM_READ_H; // load new PC
|
state <= `SEQ_MEM_READ_H; // load new PC
|
end
|
end
|
else
|
else
|
if (k_irq_req & `FLAGI)
|
if (k_irq_req & (~`FLAGI))
|
begin
|
begin
|
k_reg_irq <= 3'h0;
|
k_reg_irq <= 3'h0;
|
k_ealo[3:0] <= 4'h8;
|
k_ealo[3:0] <= 4'h8;
|
state <= `SEQ_MEM_READ_H; // load new PC
|
state <= `SEQ_MEM_READ_H; // load new PC
|
end
|
end
|
Line 782... |
Line 776... |
if (dec_o_operand_read)
|
if (dec_o_operand_read)
|
begin
|
begin
|
next_mem_state <= `SEQ_GRAL_ALU;
|
next_mem_state <= `SEQ_GRAL_ALU;
|
state <= `SEQ_MEM_READ_H;
|
state <= `SEQ_MEM_READ_H;
|
if (dec_o_ea_indirect)
|
if (dec_o_ea_indirect)
|
k_forced_mem_size <= 1; // to load indirect address
|
k_force_read_word_from_mem <= 1; // to load indirect address
|
end
|
end
|
else
|
else
|
state <= `SEQ_GRAL_ALU; // no load, then store
|
state <= `SEQ_GRAL_ALU; // no load, then store
|
end
|
end
|
end
|
end
|
Line 799... |
Line 793... |
if (dec_o_operand_read)
|
if (dec_o_operand_read)
|
begin
|
begin
|
next_mem_state <= `SEQ_GRAL_ALU;
|
next_mem_state <= `SEQ_GRAL_ALU;
|
state <= `SEQ_MEM_READ_H;
|
state <= `SEQ_MEM_READ_H;
|
if (dec_o_ea_indirect)
|
if (dec_o_ea_indirect)
|
k_forced_mem_size <= 1; // to load indirect address
|
k_force_read_word_from_mem <= 1; // to load indirect address
|
end
|
end
|
else
|
else
|
state <= `SEQ_GRAL_ALU; // no load, then store
|
state <= `SEQ_GRAL_ALU; // no load, then store
|
end
|
end
|
end
|
end
|
Line 823... |
Line 817... |
`SEQ_JSR_PUSH:
|
`SEQ_JSR_PUSH:
|
begin
|
begin
|
k_pp_active_reg <= `RN_PC; // push PC
|
k_pp_active_reg <= `RN_PC; // push PC
|
state <= `SEQ_PUSH_WRITE_L;
|
state <= `SEQ_PUSH_WRITE_L;
|
next_state <= `SEQ_JMP_LOAD_PC;
|
next_state <= `SEQ_JMP_LOAD_PC;
|
|
k_cpu_addr <= regs_o_su - 16'h1;
|
end
|
end
|
`SEQ_PREPUSH:
|
`SEQ_PREPUSH:
|
begin
|
begin
|
next_state <= `SEQ_PREPUSH;
|
next_state <= `SEQ_PREPUSH;
|
if (k_pp_regs > 0)
|
if (k_pp_regs != 8'h0)
|
begin
|
begin
|
state <= `SEQ_PUSH_WRITE_L;
|
state <= `SEQ_PUSH_WRITE_L;
|
end
|
end
|
else
|
else
|
state <= next_push_state;
|
state <= next_push_state;
|
if (k_pp_regs[7]) begin k_pp_regs[7] <= 0; k_pp_active_reg <= `RN_PC; end
|
if (k_pp_regs[7]) begin k_pp_regs[7] <= 1'b0; k_pp_active_reg <= `RN_PC; end
|
else
|
else
|
if (k_pp_regs[6]) begin k_pp_regs[6] <= 0; k_pp_active_reg <= (dec_o_use_s) ? `RN_U:`RN_S; end
|
if (k_pp_regs[6]) begin k_pp_regs[6] <= 1'b0; k_pp_active_reg <= (dec_o_use_s) ? `RN_U:`RN_S; end
|
else
|
else
|
if (k_pp_regs[5]) begin k_pp_regs[5] <= 0; k_pp_active_reg <= `RN_IY; end
|
if (k_pp_regs[5]) begin k_pp_regs[5] <= 1'b0; k_pp_active_reg <= `RN_IY; end
|
else
|
else
|
if (k_pp_regs[4]) begin k_pp_regs[4] <= 0; k_pp_active_reg <= `RN_IX; end
|
if (k_pp_regs[4]) begin k_pp_regs[4] <= 1'b0; k_pp_active_reg <= `RN_IX; end
|
else
|
else
|
if (k_pp_regs[3]) begin k_pp_regs[3] <= 0; k_pp_active_reg <= `RN_DP; end
|
if (k_pp_regs[3]) begin k_pp_regs[3] <= 1'b0; k_pp_active_reg <= `RN_DP; end
|
else
|
else
|
if (k_pp_regs[2]) begin k_pp_regs[2] <= 0; k_pp_active_reg <= `RN_ACCB; end
|
if (k_pp_regs[2]) begin k_pp_regs[2] <= 1'b0; k_pp_active_reg <= `RN_ACCB; end
|
else
|
else
|
if (k_pp_regs[1]) begin k_pp_regs[1] <= 0; k_pp_active_reg <= `RN_ACCA; end
|
if (k_pp_regs[1]) begin k_pp_regs[1] <= 1'b0; k_pp_active_reg <= `RN_ACCA; end
|
else
|
else
|
if (k_pp_regs[0]) begin k_pp_regs[0] <= 0; k_pp_active_reg <= `RN_CC; end
|
if (k_pp_regs[0]) begin k_pp_regs[0] <= 1'b00; k_pp_active_reg <= `RN_CC; end
|
|
k_cpu_addr <= regs_o_su - 16'h1;
|
end
|
end
|
`SEQ_PREPULL:
|
`SEQ_PREPULL:
|
begin
|
begin
|
if (k_pp_regs != 8'h0)
|
if (k_pp_regs != 8'h0)
|
begin
|
begin
|
next_mem_state <= `SEQ_PREPULL;
|
next_mem_state <= `SEQ_PREPULL;
|
end
|
if (k_pp_regs[0]) begin k_pp_active_reg <= `RN_CC; k_pp_regs[0] <= 1'b0; state <= `SEQ_MEM_READ_L; 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
|
else
|
if (op_RTI && (!`FLAGE)) // not all registers have to be pulled
|
if (op_RTI && (!`FLAGE)) // not all registers have to be pulled
|
begin
|
begin
|
k_pp_active_reg <= `RN_PC; k_pp_regs <= 0; state <= `SEQ_MEM_READ_H;
|
k_pp_active_reg <= `RN_PC; k_pp_regs <= 0; state <= `SEQ_MEM_READ_H;
|
end
|
end
|
else
|
else
|
if (k_pp_regs[1]) begin k_pp_active_reg <= `RN_ACCA; 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] <= 1'b0; state <= `SEQ_MEM_READ_L; end
|
|
else
|
|
if (k_pp_regs[2]) begin k_pp_active_reg <= `RN_ACCB; k_pp_regs[2] <= 1'b0; state <= `SEQ_MEM_READ_L; end
|
else
|
else
|
if (k_pp_regs[2]) begin k_pp_active_reg <= `RN_ACCB; k_pp_regs[2] <= 0; state <= `SEQ_MEM_READ_L; end
|
if (k_pp_regs[3]) begin k_pp_active_reg <= `RN_DP; k_pp_regs[3] <= 1'b0; state <= `SEQ_MEM_READ_L; end
|
else
|
else
|
if (k_pp_regs[3]) begin k_pp_active_reg <= `RN_DP; k_pp_regs[3] <= 0; state <= `SEQ_MEM_READ_L; end
|
if (k_pp_regs[4]) begin k_pp_active_reg <= `RN_IX; k_pp_regs[4] <= 1'b0; state <= `SEQ_MEM_READ_H;end
|
else
|
else
|
if (k_pp_regs[4]) begin k_pp_active_reg <= `RN_IX; k_pp_regs[4] <= 0; state <= `SEQ_MEM_READ_H;end
|
if (k_pp_regs[5]) begin k_pp_active_reg <= `RN_IY; k_pp_regs[5] <= 1'b0; state <= `SEQ_MEM_READ_H;end
|
else
|
else
|
if (k_pp_regs[5]) begin k_pp_active_reg <= `RN_IY; k_pp_regs[5] <= 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] <= 1'b0; state <= `SEQ_MEM_READ_H; end
|
else
|
else
|
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
|
if (k_pp_regs[7]) begin k_pp_active_reg <= `RN_PC; k_pp_regs[7] <= 1'b0; state <= `SEQ_MEM_READ_H; end
|
|
end
|
else
|
else
|
if (k_pp_regs[7]) begin k_pp_active_reg <= `RN_PC; k_pp_regs[7] <= 0; state <= `SEQ_MEM_READ_H; end
|
state <= `SEQ_FETCH; // end of sequence
|
|
|
end
|
end
|
`SEQ_PUSH_WRITE_L: // first low byte push
|
`SEQ_PUSH_WRITE_L: // first low byte push
|
begin
|
begin
|
k_cpu_data_o <= regs_o_left_path_data[7:0];
|
k_cpu_data_o <= regs_o_left_path_data[7:0];
|
state <= `SEQ_PUSH_WRITE_L_1;
|
state <= `SEQ_PUSH_WRITE_L_1;
|
Line 957... |
Line 954... |
k_write_pc <= 1; // load PC in the next cycle, the mux output will have the right source
|
k_write_pc <= 1; // load PC in the next cycle, the mux output will have the right source
|
state <= next_state;
|
state <= next_state;
|
end
|
end
|
`SEQ_MEM_READ_H: // reads high byte
|
`SEQ_MEM_READ_H: // reads high byte
|
begin
|
begin
|
|
k_cpu_addr <= { k_eahi, k_ealo };
|
|
state <= `SEQ_MEM_READ_H_1;
|
|
if (!k_exception_process)
|
|
begin
|
case (dec_o_p1_mode)
|
case (dec_o_p1_mode)
|
`INDEXED:
|
`INDEXED:
|
if (k_indirect_loaded)
|
if (k_indirect_loaded)
|
k_cpu_addr <= { k_memhi, k_memlo };
|
k_cpu_addr <= { k_memhi, k_memlo };
|
else
|
else
|
k_cpu_addr <= regs_o_eamem_addr;
|
k_cpu_addr <= regs_o_eamem_addr;
|
default:
|
default:
|
if (op_PULL | op_RTI | op_RTS)
|
if (op_PULL | op_RTI | op_RTS)
|
begin
|
begin
|
k_cpu_addr <= regs_o_su;
|
k_cpu_addr <= regs_o_su;
|
k_inc_su <= 1;
|
k_inc_su <= 1'b1;
|
end
|
end
|
else
|
else
|
k_cpu_addr <= { k_eahi, k_ealo };
|
k_cpu_addr <= { k_eahi, k_ealo };
|
endcase
|
endcase
|
if (k_forced_mem_size | dec_o_source_size | (k_pp_active_reg < `RN_ACCA))
|
if (!(k_force_read_word_from_mem | 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_L_1;
|
k_forced_mem_size <= 0; // used for vector fetch
|
end
|
|
k_force_read_word_from_mem <= 1'b0; // used for vector fetch
|
|
k_exception_process <= 1'b0;
|
end
|
end
|
`SEQ_MEM_READ_H_1:
|
`SEQ_MEM_READ_H_1:
|
begin
|
begin
|
k_cpu_oe <= 1; // read
|
k_cpu_oe <= 1'b1; // read
|
state <= `SEQ_MEM_READ_H_2;
|
state <= `SEQ_MEM_READ_H_2;
|
end
|
end
|
`SEQ_MEM_READ_H_2:
|
`SEQ_MEM_READ_H_2:
|
begin
|
begin
|
k_memhi <= cpu_data_i;
|
k_memhi <= cpu_data_i;
|