aboutsummaryrefslogtreecommitdiff
path: root/rtl/alu.sv
diff options
context:
space:
mode:
authorWarrick Lo <wlo@warricklo.net>2026-06-20 20:18:38 +0000
committerWarrick Lo <wlo@warricklo.net>2026-06-20 20:18:38 +0000
commit3b76fd6f9154b7c01414f8b3f57cf0378109d1a6 (patch)
treebb918db361f1ccfcaec9c36619cd3aea7b02ee99 /rtl/alu.sv
parentMinor refactor to regfile formal test module (diff)
downloadmontreal-3b76fd6f9154b7c01414f8b3f57cf0378109d1a6.tar.xz
montreal-3b76fd6f9154b7c01414f8b3f57cf0378109d1a6.zip
Add basic ALU skeleton
Signed-off-by: Warrick Lo <wlo@warricklo.net>
Diffstat (limited to '')
-rw-r--r--rtl/alu.sv61
1 files changed, 61 insertions, 0 deletions
diff --git a/rtl/alu.sv b/rtl/alu.sv
new file mode 100644
index 0000000..f5dde19
--- /dev/null
+++ b/rtl/alu.sv
@@ -0,0 +1,61 @@
+module alu
+ import montreal_pkg::*;
+#(
+ parameter int unsigned XLEN = config_pkg::XLEN,
+ parameter int unsigned SLICE_WIDTH = config_pkg::SLICE_WIDTH,
+
+ localparam int unsigned SLICE_ADDR_WIDTH = $clog2(XLEN / SLICE_WIDTH)
+) (
+ input logic clk_i,
+ input logic rst_ni,
+ input fu_op_t alu_op_i,
+
+ input logic [SLICE_ADDR_WIDTH-1:0] count_i,
+
+ input slice_t a_i,
+ input slice_t b_i,
+
+ output slice_t result_o,
+ output logic carry_o
+);
+
+ logic negate_b;
+
+ /* We used Karnaugh maps here. If the encoding for fu_op_t changes, this has to be updated. */
+ assign negate_b = alu_op_i[3] || (!alu_op_i[2] && alu_op_i[1]);
+
+ /* Adder width is SLICE_WIDTH + 1 to account for carry-out. */
+ logic [SLICE_WIDTH:0] adder_a, adder_b, adder_result;
+
+ assign adder_a = {1'b0, a_i};
+ assign adder_b = {1'b0, (b_i ^ {SLICE_WIDTH{negate_b}})};
+
+ /* Carry signals. */
+ logic carry, carry_d, carry_q;
+
+ assign carry = (count_i == '0) ? negate_b : carry_q;
+
+ /* Combinational arithmetic/logic core. */
+ always_comb begin : alu_core
+ unique casez (alu_op_i[2:0])
+ /* ADD, SUB, SLT, SLTU. */
+ 3'b0??: begin end
+ /* XOR. */
+ 3'b100: begin end
+ /* OR. */
+ 3'b110: begin end
+ /* AND. */
+ 3'b111: begin end
+ default: begin end
+ endcase
+ end : alu_core
+
+ always_ff @(posedge clk_i) begin : carry_ff
+ if (!rst_ni) begin
+ carry_q <= '0;
+ end else begin
+ carry_q <= carry_d;
+ end
+ end : carry_ff
+
+endmodule : alu