Line 23... |
Line 23... |
|
|
wire k_reset;
|
wire k_reset;
|
wire k_clk;
|
wire k_clk;
|
assign k_clk = cpu_clk;
|
assign k_clk = cpu_clk;
|
|
|
reg [7:0] k_opcode, k_postbyte0, k_ind_ea; /* all bytes of an instruction */
|
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, k_pp_active_reg; // push/pull mask
|
reg [7:0] k_memhi, k_memlo, k_cpu_data_o; /* operand read from memory */
|
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 [7:0] k_ofslo, k_ofshi, k_eahi, k_ealo;
|
reg [5:0] state, // state of the main state machine
|
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_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_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_cpu_oe, k_cpu_we, k_inc_pc;
|
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 [1:0] k_mem_dest;
|
reg [1:0] k_mem_dest;
|
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
|
Line 67... |
Line 68... |
wire [7:0] regs_o_CCR;
|
wire [7:0] regs_o_CCR;
|
/* Data Muxes */
|
/* Data Muxes */
|
reg [3:0] datamux_o_dest_reg_addr, datamux_o_alu_in_left_path_addr;
|
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 [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_postbyte0 has been loaded for page 2 or page 3 */
|
reg k_p2_valid, k_p3_valid; /* 1 when k_postbyte has been loaded for page 2 or page 3 */
|
|
|
/*
|
/*
|
* Interrupt sync registers
|
* Interrupt sync registers
|
*/
|
*/
|
|
|
Line 96... |
Line 97... |
regblock regs(
|
regblock regs(
|
.clk_in(k_clk),
|
.clk_in(k_clk),
|
.path_left_addr(datamux_o_alu_in_left_path_addr),
|
.path_left_addr(datamux_o_alu_in_left_path_addr),
|
.path_right_addr(dec_o_right_path_addr),
|
.path_right_addr(dec_o_right_path_addr),
|
.write_reg_addr(datamux_o_dest_reg_addr),
|
.write_reg_addr(datamux_o_dest_reg_addr),
|
|
.exg_dest_r(k_postbyte[3:0]),
|
.eapostbyte( k_ind_ea ),
|
.eapostbyte( k_ind_ea ),
|
.offset16({ k_ofshi, k_ofslo }),
|
.offset16({ k_ofshi, k_ofslo }),
|
.write_reg(k_write_dest),
|
.write_reg(k_write_dest),
|
//.write_reg_16(dec_o_wdest_16 & (state == `SEQ_GRAL_WBACK)),
|
.write_tfr(k_write_tfr),
|
//.write_pull_reg(k_pull_reg_write),
|
.write_exg(k_write_exg),
|
.write_post(k_write_post_incdec),
|
.write_post(k_write_post_incdec),
|
.write_pc(k_write_pc),
|
.write_pc(k_write_pc),
|
.inc_pc(k_inc_pc),
|
.inc_pc(k_inc_pc),
|
.inc_su(k_inc_su),
|
.inc_su(k_inc_su),
|
.dec_su(k_dec_su),
|
.dec_su(k_dec_su),
|
Line 124... |
Line 126... |
.reg_su(regs_o_su)
|
.reg_su(regs_o_su)
|
);
|
);
|
|
|
decode_regs dec_regs(
|
decode_regs dec_regs(
|
.opcode(k_opcode),
|
.opcode(k_opcode),
|
.postbyte0(k_postbyte0),
|
.postbyte0(k_postbyte),
|
.page2_valid(k_p2_valid),
|
.page2_valid(k_p2_valid),
|
.page3_valid(k_p3_valid),
|
.page3_valid(k_p3_valid),
|
.path_left_addr(dec_o_left_path_addr),
|
.path_left_addr(dec_o_left_path_addr),
|
.path_right_addr(dec_o_right_path_addr),
|
.path_right_addr(dec_o_right_path_addr),
|
.dest_reg(dec_o_dest_reg_addr),
|
.dest_reg(dec_o_dest_reg_addr),
|
Line 137... |
Line 139... |
.result_size(dec_o_alu_size)
|
.result_size(dec_o_alu_size)
|
);
|
);
|
|
|
decode_op dec_op(
|
decode_op dec_op(
|
.opcode(k_opcode),
|
.opcode(k_opcode),
|
.postbyte0(k_postbyte0),
|
.postbyte0(k_postbyte),
|
.page2_valid(k_p2_valid),
|
.page2_valid(k_p2_valid),
|
.page3_valid(k_p3_valid),
|
.page3_valid(k_p3_valid),
|
.mode(dec_o_p1_mode),
|
.mode(dec_o_p1_mode),
|
.optype(dec_o_p1_optype),
|
.optype(dec_o_p1_optype),
|
.use_s(dec_o_use_s)
|
.use_s(dec_o_use_s)
|
Line 159... |
Line 161... |
/* Opcodes for the ALU are decoded here
|
/* Opcodes for the ALU are decoded here
|
* Write Flags are also decoded here
|
* Write Flags are also decoded here
|
*/
|
*/
|
decode_alu dec_alu(
|
decode_alu dec_alu(
|
.opcode(k_opcode),
|
.opcode(k_opcode),
|
.postbyte0(k_postbyte0),
|
.postbyte0(k_postbyte),
|
.page2_valid(k_p2_valid),
|
.page2_valid(k_p2_valid),
|
.page3_valid(k_p3_valid),
|
.page3_valid(k_p3_valid),
|
.alu_opcode(dec_o_alu_opcode),
|
.alu_opcode(dec_o_alu_opcode),
|
.dec_alu_right_path_mod(dec_o_right_path_mod),
|
.dec_alu_right_path_mod(dec_o_right_path_mod),
|
.dest_flags(dec_o_write_flags)
|
.dest_flags(dec_o_write_flags)
|
);
|
);
|
/* Condition decoder */
|
/* Condition decoder */
|
test_condition test_cond(
|
test_condition test_cond(
|
.opcode(k_opcode),
|
.opcode(k_opcode),
|
.postbyte0(k_postbyte0),
|
.postbyte0(k_postbyte),
|
.page2_valid(k_p2_valid),
|
.page2_valid(k_p2_valid),
|
.CCR(regs_o_CCR),
|
.CCR(regs_o_CCR),
|
.cond_taken(dec_o_cond_taken)
|
.cond_taken(dec_o_cond_taken)
|
);
|
);
|
|
|
Line 326... |
Line 328... |
k_write_post_incdec <= 0;
|
k_write_post_incdec <= 0;
|
if (k_dec_su)
|
if (k_dec_su)
|
k_dec_su <= 0;
|
k_dec_su <= 0;
|
if (k_inc_su)
|
if (k_inc_su)
|
k_inc_su <= 0;
|
k_inc_su <= 0;
|
//if (k_pull_reg_write)
|
|
// k_pull_reg_write <= 0;
|
|
if (k_set_e)
|
if (k_set_e)
|
k_set_e <= 0;
|
k_set_e <= 0;
|
if (k_clear_e)
|
if (k_clear_e)
|
k_clear_e <= 0;
|
k_clear_e <= 0;
|
if (k_write_dest)
|
if (k_write_dest)
|
k_write_dest <= 0;
|
k_write_dest <= 0;
|
|
if (k_write_exg)
|
|
k_write_exg <= 0;
|
|
if (k_write_tfr)
|
|
k_write_tfr <= 0;
|
case (state)
|
case (state)
|
`SEQ_COLDRESET:
|
`SEQ_COLDRESET:
|
begin
|
begin
|
k_forced_mem_size <= 1;
|
k_forced_mem_size <= 1;
|
state <= `SEQ_MEM_READ_H;
|
state <= `SEQ_MEM_READ_H;
|
Line 462... |
Line 466... |
begin
|
begin
|
k_p2_valid <= 0;
|
k_p2_valid <= 0;
|
k_p3_valid <= 1;
|
k_p3_valid <= 1;
|
state <= `SEQ_FETCH_3;
|
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
|
default:
|
default:
|
begin
|
begin
|
state <= `SEQ_DECODE;
|
state <= `SEQ_DECODE;
|
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
|
Line 483... |
Line 493... |
k_cpu_oe <= 1;
|
k_cpu_oe <= 1;
|
state <= `SEQ_FETCH_5;
|
state <= `SEQ_FETCH_5;
|
end
|
end
|
`SEQ_FETCH_5: /* fetches a page 2 or 3 opcode */
|
`SEQ_FETCH_5: /* fetches a page 2 or 3 opcode */
|
begin
|
begin
|
k_postbyte0 <= cpu_data_i;
|
k_postbyte <= cpu_data_i;
|
k_inc_pc <= 1;
|
k_inc_pc <= 1;
|
state <= `SEQ_DECODE_P23;
|
state <= `SEQ_DECODE_P23;
|
end
|
end
|
`SEQ_DECODE:
|
`SEQ_DECODE:
|
begin
|
begin
|
Line 586... |
Line 596... |
end
|
end
|
endcase
|
endcase
|
end
|
end
|
`SEQ_DECODE_P23:
|
`SEQ_DECODE_P23:
|
begin // has prefix 10 or 11
|
begin // has prefix 10 or 11
|
k_inc_pc <= 0;
|
|
case (dec_o_p1_mode)
|
case (dec_o_p1_mode)
|
`NONE: // unknown k_opcode... re-fetch ?
|
`NONE: // unknown k_opcode... re-fetch ?
|
state <= `SEQ_FETCH;
|
state <= `SEQ_FETCH;
|
`IMMEDIATE: // 8 or 16 bits as result decides..
|
`IMMEDIATE: // 8 or 16 bits as result decides..
|
begin
|
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)
|
if (dec_o_alu_size)
|
state <= `SEQ_PC_READ_H;
|
state <= `SEQ_PC_READ_H;
|
else
|
else
|
state <= `SEQ_PC_READ_L;
|
state <= `SEQ_PC_READ_L;
|
next_state <= `SEQ_GRAL_ALU;
|
end
|
|
endcase
|
end
|
end
|
`INHERENT:
|
`INHERENT:
|
case (k_opcode)
|
case (k_opcode)
|
8'h3f: if (k_p2_valid) state <= `SEQ_SWI2;
|
8'h3f: if (k_p2_valid) state <= `SEQ_SWI2;
|
else state <= `SEQ_SWI3;
|
else state <= `SEQ_SWI3;
|
Line 660... |
Line 676... |
end
|
end
|
endcase
|
endcase
|
end
|
end
|
`SEQ_INH_ALU:
|
`SEQ_INH_ALU:
|
state <= `SEQ_GRAL_WBACK;
|
state <= `SEQ_GRAL_WBACK;
|
|
`SEQ_TFREXG:
|
|
state <= `SEQ_FETCH;
|
`SEQ_IND_READ_EA: // reads EA byte
|
`SEQ_IND_READ_EA: // reads EA byte
|
begin
|
begin
|
k_cpu_addr <= regs_o_pc;
|
k_cpu_addr <= regs_o_pc;
|
state <= `SEQ_IND_READ_EA_1;
|
state <= `SEQ_IND_READ_EA_1;
|
k_inc_pc <= 1;
|
k_inc_pc <= 1;
|
Line 951... |
Line 969... |
begin
|
begin
|
k_cpu_oe = 0;
|
k_cpu_oe = 0;
|
k_cpu_we = 0;
|
k_cpu_we = 0;
|
k_mem_dest = 0;
|
k_mem_dest = 0;
|
k_new_pc = 16'hffff;
|
k_new_pc = 16'hffff;
|
|
k_write_tfr = 0;
|
|
k_write_exg = 0;
|
end
|
end
|
endmodule
|
endmodule
|
No newline at end of file
|
No newline at end of file
|