diff options
Diffstat (limited to 'rtl/core/cycles.sv')
| -rw-r--r-- | rtl/core/cycles.sv | 158 |
1 files changed, 97 insertions, 61 deletions
diff --git a/rtl/core/cycles.sv b/rtl/core/cycles.sv index 8945bc2..c32bff0 100644 --- a/rtl/core/cycles.sv +++ b/rtl/core/cycles.sv @@ -2,77 +2,102 @@ module core_cycles ( - input logic clk, - dec_execute, - dec_branch, - dec_writeback, - dec_update_flags, - input ptr dec_branch_offset, - input alu_decode dec_alu, - input ptr fetch_insn_pc, - input word rd_value_b, - - output logic stall, - branch, - writeback, - update_flags, - output reg_num rd, - ra, - rb, - output ptr branch_target, - pc, - pc_visible, - output psr_mode reg_mode, - output alu_control alu, - output word alu_base, - output logic[7:0] alu_shift + input logic clk, + dec_execute, + dec_branch, + dec_writeback, + dec_update_flags, + input ptr dec_branch_offset, + input data_decode dec_data, + input ptr fetch_insn_pc, + input psr_flags next_flags, + input word rd_value_b, + q_alu, + q_shifter, + input logic c_shifter, + + output logic stall, + branch, + writeback, + update_flags, + c_in, + output reg_num rd, + ra, + rb, + output ptr branch_target, + pc_visible, + output psr_mode reg_mode, + output alu_op alu, + output word alu_b, + wr_value, + output shifter_control shifter, + output logic[7:0] shifter_shift ); enum { EXECUTE, - RD_SHIFT + RD_INDIRECT_SHIFT, + WITH_SHIFT } cycle, next_cycle; - logic final_writeback, data_snd_is_imm, data_snd_shift_by_reg; + logic bubble, final_writeback, data_snd_is_imm, data_snd_shift_by_reg, trivial_shift; logic[5:0] data_shift_imm; logic[7:0] data_imm; - logic bubble; word saved_base; - reg_num r_shift; + reg_num r_shift, final_rd; + ptr pc; assign stall = (next_cycle != EXECUTE) | bubble; assign pc_visible = pc + 2; assign reg_mode = `MODE_SVC; //TODO always_comb begin + unique case(cycle) + RD_INDIRECT_SHIFT: shifter_shift = rd_value_b[7:0]; + default: shifter_shift = {2'b00, data_shift_imm}; + endcase + + trivial_shift = 1; + if(final_writeback & (shifter.shl | shifter.shr | shifter.ror)) + trivial_shift = shifter_shift == 0; + next_cycle = EXECUTE; - if((cycle == EXECUTE) & data_snd_shift_by_reg) - next_cycle = RD_SHIFT; + + unique case(cycle) + EXECUTE: + if(data_snd_shift_by_reg) + next_cycle = RD_INDIRECT_SHIFT; + else if(~trivial_shift) + next_cycle = WITH_SHIFT; + + RD_INDIRECT_SHIFT: + if(~trivial_shift) + next_cycle = WITH_SHIFT; + + default: ; + endcase if(bubble) next_cycle = EXECUTE; unique case(cycle) - RD_SHIFT: - alu_base = saved_base; - - default: + EXECUTE: if(data_snd_is_imm) - alu_base = {{24{1'b0}}, data_imm}; + alu_b = {{24{1'b0}}, data_imm}; else - alu_base = rd_value_b; - endcase + alu_b = rd_value_b; - unique case(cycle) - RD_SHIFT: alu_shift = rd_value_b[7:0]; - default: alu_shift = {2'b00, data_shift_imm}; + RD_INDIRECT_SHIFT, WITH_SHIFT: + alu_b = saved_base; endcase end always_ff @(posedge clk) begin cycle <= next_cycle; bubble <= 0; + writeback <= 0; + wr_value <= q_alu; unique case(next_cycle) EXECUTE: begin @@ -84,40 +109,47 @@ module core_cycles if(dec_execute & ~bubble) begin bubble <= (dec_update_flags & update_flags) - | (final_writeback & ((rd == dec_alu.rn) | (rd == dec_alu.r_snd))); + | (final_writeback & ((rd == dec_data.rn) | (rd == dec_data.r_snd))); branch <= dec_branch; - final_writeback <= dec_writeback; update_flags <= dec_update_flags; branch_target <= pc_visible + dec_branch_offset; - data_snd_is_imm <= dec_alu.snd_is_imm; - data_snd_shift_by_reg <= dec_alu.snd_shift_by_reg; - data_imm <= dec_alu.imm; - data_shift_imm <= dec_alu.shift_imm; - - alu.op <= dec_alu.op; - alu.shl <= dec_alu.shl; - alu.shr <= dec_alu.shr; - alu.ror <= dec_alu.ror; - alu.put_carry <= dec_alu.put_carry; - alu.sign_extend <= dec_alu.sign_extend; - - rd <= dec_alu.rd; - ra <= dec_alu.rn; - rb <= dec_alu.r_snd; - r_shift <= dec_alu.r_shift; + data_snd_is_imm <= dec_data.snd_is_imm; + data_snd_shift_by_reg <= dec_data.snd_shift_by_reg; + data_imm <= dec_data.imm; + data_shift_imm <= dec_data.shift_imm; + + alu <= dec_data.op; + shifter.shl <= dec_data.shl; + shifter.shr <= dec_data.shr; + shifter.ror <= dec_data.ror; + shifter.put_carry <= dec_data.put_carry; + shifter.sign_extend <= dec_data.sign_extend; + + ra <= dec_data.rn; + rb <= dec_data.r_snd; + r_shift <= dec_data.r_shift; + c_in <= next_flags.c; + + final_rd <= dec_data.rd; + final_writeback <= dec_writeback; end writeback <= final_writeback; + rd <= final_rd; pc <= fetch_insn_pc; end - RD_SHIFT: begin + RD_INDIRECT_SHIFT: begin rb <= r_shift; data_snd_shift_by_reg <= 0; saved_base <= rd_value_b; - writeback <= 0; + end + + WITH_SHIFT: begin + c_in <= c_shifter; + saved_base <= q_shifter; end endcase end @@ -127,10 +159,14 @@ module core_cycles bubble = 0; pc = 0; + c_in = 0; branch = 1; writeback = 0; - data_snd_shift_by_reg = 0; branch_target = 30'd0; + data_snd_shift_by_reg = 0; + + final_rd = 0; + final_writeback = 0; end endmodule |
