diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-10-02 09:49:48 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-10-02 09:49:48 -0600 |
| commit | e97d445908f39a3a1a215a824f52b283147e6195 (patch) | |
| tree | 74baa4d5ee535c12dbbe400f8e6c2fda342b8e37 /rtl/core/cycles.sv | |
| parent | 5e2f6be247018699d71d32887010830ba45b8349 (diff) | |
Major shifter-ALU redesign
The shifter unit now works in parallel with the ALU and is no longer
part of it. Instructions that use the shifter as input to the ALU will
now take an additional cycle, unless the control unit can detect a
"trivial shift" situation where the shifter's output will be the same as
its input. This change improves Fmax substantially.
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 |
