summaryrefslogtreecommitdiff
path: root/rtl/core/alu
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/alu
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/alu')
-rw-r--r--rtl/core/alu/alu.sv32
-rw-r--r--rtl/core/alu/shifter.sv42
2 files changed, 11 insertions, 63 deletions
diff --git a/rtl/core/alu/alu.sv b/rtl/core/alu/alu.sv
index 6ded727..d999164 100644
--- a/rtl/core/alu/alu.sv
+++ b/rtl/core/alu/alu.sv
@@ -3,10 +3,9 @@
module core_alu
#(parameter W=16)
(
- input alu_control ctrl,
+ input alu_op op,
input logic[W - 1:0] a,
- base,
- input logic[7:0] shift,
+ b,
input logic c_in,
output logic[W - 1:0] q,
@@ -14,22 +13,13 @@ module core_alu
output logic v_valid
);
- logic c, v, swap, sub, and_not, c_shifter, c_add, v_add;
- logic[W - 1:0] b, swap_a, swap_b, not_b, c_in_add, q_add, q_and, q_orr, q_xor;
+ logic c, v, swap, sub, and_not, c_add, v_add;
+ logic[W - 1:0] swap_a, swap_b, not_b, c_in_add, q_add, q_and, q_orr, q_xor;
assign swap_a = swap ? b : a;
assign swap_b = swap ? a : b;
assign not_b = ~b;
- core_alu_shifter #(.W(W)) shifter
- (
- .base(base),
- .shift(shift),
- .b(b),
- .c(c_shifter),
- .*
- );
-
core_alu_add #(.W(W)) op_add
(
.a(swap_a),
@@ -61,7 +51,7 @@ module core_alu
);
always_comb begin
- unique case(ctrl.op)
+ unique case(op)
`ALU_ADD, `ALU_ADC, `ALU_CMN, `ALU_CMP, `ALU_SUB, `ALU_SBC:
swap = 0;
@@ -72,7 +62,7 @@ module core_alu
swap = 1'bx;
endcase
- unique case(ctrl.op)
+ unique case(op)
`ALU_ADD, `ALU_CMN, `ALU_ADC:
sub = 0;
@@ -83,7 +73,7 @@ module core_alu
sub = 1'bx;
endcase
- unique case(ctrl.op)
+ unique case(op)
`ALU_ADD, `ALU_CMN, `ALU_CMP, `ALU_SUB, `ALU_RSB:
c_in_add = 0;
@@ -97,7 +87,7 @@ module core_alu
c_in_add = {W{1'bx}};
endcase
- unique case(ctrl.op)
+ unique case(op)
`ALU_AND, `ALU_TST:
and_not = 0;
@@ -108,7 +98,7 @@ module core_alu
and_not = 1'bx;
endcase
- unique case(ctrl.op)
+ unique case(op)
`ALU_SUB, `ALU_RSB, `ALU_ADD, `ALU_ADC, `ALU_SBC, `ALU_RSC, `ALU_CMP, `ALU_CMN:
q = q_add;
@@ -128,9 +118,9 @@ module core_alu
q = not_b;
endcase
- unique case(ctrl.op)
+ unique case(op)
`ALU_AND, `ALU_EOR, `ALU_TST, `ALU_TEQ, `ALU_ORR, `ALU_MOV, `ALU_BIC, `ALU_MVN: begin
- c = c_shifter;
+ c = c_in;
v = 1'bx;
v_valid = 0;
end
diff --git a/rtl/core/alu/shifter.sv b/rtl/core/alu/shifter.sv
deleted file mode 100644
index 1f99e99..0000000
--- a/rtl/core/alu/shifter.sv
+++ /dev/null
@@ -1,42 +0,0 @@
-`include "core/uarch.sv"
-
-module core_alu_shifter
-#(parameter W=16)
-(
- input alu_control ctrl,
- input logic[W - 1:0] base,
- input logic[7:0] shift,
- input logic c_in,
-
- output logic[W - 1:0] b,
- output logic c
-);
-
- localparam LOG = $clog2(W);
-
- logic[W - 1:0] b_no_c, b_shl, b_shr, b_ror;
- logic[W:0] sign_mask;
- logic c_shl, c_shr, c_ror;
-
- assign sign_mask = {(W + 1){ctrl.sign_extend & base[W - 1]}};
- assign {c_shl, b_shl} = {c_in, base} << shift;
- assign {b_shr, c_shr} = {base, c_in} >> shift | ~(sign_mask >> shift);
-
- logic ror_cycle;
- logic[LOG - 1:0] ror_shift;
- logic[2 * W:0] ror_out;
-
- assign ror_shift = shift[LOG - 1:0];
- assign ror_cycle = |shift[7:LOG] & ~|ror_shift;
- assign ror_out = {base, base, c_in} >> {ror_cycle, ror_shift};
- assign {b_ror, c_ror} = ror_out[W:0];
-
- always_comb
- if(ctrl.ror)
- {c, b} = {c_ror, b_ror};
- else if(ctrl.shr)
- {c, b} = {c_shr, b_shr[W - 1] | (ctrl.put_carry & c_in), b_shr[W - 2:0]};
- else
- {c, b} = {c_shl, b_shl};
-
-endmodule