summaryrefslogtreecommitdiff
path: root/rtl/core/alu/add.sv
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-11-08 15:59:12 -0600
committerAlejandro Soto <alejandro@34project.org>2022-11-08 15:59:12 -0600
commit13b112dcb8f67778c6a140cb5ce8f1ab21aa6fb9 (patch)
tree1c33528b0559a7b51f67a3c0df92202713e1a53b /rtl/core/alu/add.sv
parentf6929f9a4703e3eee9d7bd9752de055729cdd498 (diff)
Improve ALU performance
Diffstat (limited to 'rtl/core/alu/add.sv')
-rw-r--r--rtl/core/alu/add.sv37
1 files changed, 31 insertions, 6 deletions
diff --git a/rtl/core/alu/add.sv b/rtl/core/alu/add.sv
index 12bd237..a15a6b6 100644
--- a/rtl/core/alu/add.sv
+++ b/rtl/core/alu/add.sv
@@ -1,20 +1,45 @@
module core_alu_add
-#(parameter W=16)
+#
+(
+ parameter W=16,
+ parameter SUB=0
+)
(
input logic[W - 1:0] a,
b,
- c_in,
+ input logic c_in,
output logic[W - 1:0] q,
output logic c,
v
);
- logic sgn_a, sgn_b, sgn_q;
+ logic sgn_a, sgn_b, sgn_q, maybe_v;
+ logic[W:0] out;
+
+ /* Quartus infiere dos sumadores si se zero-extendea el cin
+ * para complacer a Verilator, lo cual es malo para Fmax.
+ */
+`ifdef VERILATOR
+ logic[W:0] ext_carry;
+ assign ext_carry = {{W{1'b0}}, c_in};
+`else
+ logic ext_carry;
+ assign ext_carry = c_in;
+`endif
+
+ assign v = maybe_v & (sgn_a ^ sgn_q);
+ assign {c, q} = out;
assign {sgn_a, sgn_b, sgn_q} = {a[W - 1], b[W - 1], q[W - 1]};
- //TODO: No sirve el carry
- assign {c, q} = {1'b0, a} + {1'b0, b} + {1'b0, c_in};
- assign v = (sgn_a ~^ sgn_b) & (sgn_a ^ sgn_q);
+ generate
+ if(SUB) begin
+ assign out = {1'b1, a} - {1'b0, b} - ext_carry;
+ assign maybe_v = sgn_a ^ sgn_b;
+ end else begin
+ assign out = {1'b0, a} + {1'b0, b} + ext_carry;
+ assign maybe_v = sgn_a ~^ sgn_b;
+ end
+ endgenerate
endmodule