summaryrefslogtreecommitdiff
path: root/rtl/core/cycles.sv
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-10-02 09:49:48 -0600
committerAlejandro Soto <alejandro@34project.org>2022-10-02 09:49:48 -0600
commite97d445908f39a3a1a215a824f52b283147e6195 (patch)
tree74baa4d5ee535c12dbbe400f8e6c2fda342b8e37 /rtl/core/cycles.sv
parent5e2f6be247018699d71d32887010830ba45b8349 (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.sv158
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