diff options
| author | Warrick Lo <wlo@warricklo.net> | 2026-06-25 05:28:07 +0000 |
|---|---|---|
| committer | Warrick Lo <wlo@warricklo.net> | 2026-06-25 05:28:07 +0000 |
| commit | 513ac84dbaaffd9b79330b24be089716d3c2dbc9 (patch) | |
| tree | 60ae88f956c3028ea3c9f48c55ed42609431eab5 /rtl/alu.sv | |
| parent | Add basic ALU skeleton (diff) | |
| parent | Clean up ALU before merge (diff) | |
| download | montreal-513ac84dbaaffd9b79330b24be089716d3c2dbc9.tar.xz montreal-513ac84dbaaffd9b79330b24be089716d3c2dbc9.zip | |
Merge branch 'feature/fu' from MyDariell
Implements arithmetic and bitwise logic in the ALU.
* feature/fu:
Clean up ALU before merge
Implement XOR, OR, AND logical operations in sliced ALU
Implement ADD and SUB operations in sliced ALU
Closes: #16
Reviewed-by: Warrick Lo <wlo@warricklo.net>
Diffstat (limited to '')
| -rw-r--r-- | rtl/alu.sv | 33 |
1 files changed, 22 insertions, 11 deletions
@@ -1,6 +1,8 @@ -module alu - import montreal_pkg::*; -#( +/* SPDX-License-Identifier: CERN-OHL-P-2.0 */ + +`include "types.svh" + +module alu #( parameter int unsigned XLEN = config_pkg::XLEN, parameter int unsigned SLICE_WIDTH = config_pkg::SLICE_WIDTH, @@ -24,29 +26,38 @@ module alu /* 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]); + /* Carry signals. */ + logic carry, carry_d, carry_q; + + /* For the first slice, carry-in must be driven to zero for addition + * and one for subtraction or comparisons. All other slices use the + * carry-out from the previous slice */ + assign carry = (count_i == '0) ? negate_b : carry_q; + /* 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; + /* ADD, SUB, SLT, SLTU use the same adder to computer their results*/ + assign adder_result = adder_a + adder_b + (SLICE_WIDTH + 1)'(carry); - assign carry = (count_i == '0) ? negate_b : carry_q; + assign carry_o = adder_result[SLICE_WIDTH]; + assign carry_d = carry_o; /* Combinational arithmetic/logic core. */ always_comb begin : alu_core unique casez (alu_op_i[2:0]) /* ADD, SUB, SLT, SLTU. */ - 3'b0??: begin end + 3'b0??: result_o = adder_result[SLICE_WIDTH-1:0]; /* XOR. */ - 3'b100: begin end + 3'b100: result_o = a_i ^ b_i; /* OR. */ - 3'b110: begin end + 3'b110: result_o = a_i | b_i; /* AND. */ - 3'b111: begin end - default: begin end + 3'b111: result_o = a_i & b_i; + default: result_o = '0; endcase end : alu_core |