aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--rtl/alu.sv47
-rw-r--r--rtl/montreal_pkg.sv28
-rw-r--r--tb/alu/alu_logic_tb.sv21
4 files changed, 24 insertions, 76 deletions
diff --git a/.gitignore b/.gitignore
index ad3001c..fe0d8c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,10 @@
.vscode
.claude/
+# iverilog build artifacts
+*.vvp
+obj_dir/
+
# SymbiYosys output
verif/formal/simple_alu/simple_alu/
verif/formal/simple_alu/simple_alu_bmc/
diff --git a/rtl/alu.sv b/rtl/alu.sv
index 30645c1..2966135 100644
--- a/rtl/alu.sv
+++ b/rtl/alu.sv
@@ -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,
@@ -27,48 +29,35 @@ module alu
/* Carry signals. */
logic carry, carry_d, carry_q;
- /* Adder width is SLICE_WIDTH + 1 to account for carry-out. */
- logic [SLICE_WIDTH:0] adder_a, adder_b, adder_result;
-
- /* For the first slice, carry-in must be driven to zero for addition
- * and one for subtraction or comparisons. All other slices use the
+ /* 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;
- 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;
- /* ADD, SUB, SLT, SLTU use the same adder to computer their results*/
-
assign adder_a = {1'b0, a_i};
assign adder_b = {1'b0, (b_i ^ {SLICE_WIDTH{negate_b}})};
+
+ /* 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_o = adder_result[SLICE_WIDTH];
assign carry_d = carry_o;
/* Combinational arithmetic/logic core. */
always_comb begin : alu_core
- result_o = '0;
-
unique casez (alu_op_i[2:0])
/* ADD, SUB, SLT, SLTU. */
- 3'b0??: begin
- result_o = adder_result[SLICE_WIDTH-1:0];
- end
+ 3'b0??: result_o = adder_result[SLICE_WIDTH-1:0];
/* XOR. */
- 3'b100: begin
- result_o = a_i ^ b_i;
- carry_d = 0;
- end
+ 3'b100: result_o = a_i ^ b_i;
/* OR. */
- 3'b110: begin
- result_o = a_i | b_i;
- carry_d = 0;
- end
+ 3'b110: result_o = a_i | b_i;
/* AND. */
- 3'b111: begin
- result_o = a_i & b_i;
- carry_d = 0;
- end
- default: begin end
+ 3'b111: result_o = a_i & b_i;
+ default: result_o = '0;
endcase
end : alu_core
diff --git a/rtl/montreal_pkg.sv b/rtl/montreal_pkg.sv
deleted file mode 100644
index 741a926..0000000
--- a/rtl/montreal_pkg.sv
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: CERN-OHL-P-2.0 */
-
-package montreal_pkg;
-
- typedef logic unsigned [config_pkg::XLEN-1:0] word_t;
- typedef logic unsigned [config_pkg::SLICE_WIDTH-1:0] slice_t;
-
- typedef enum logic [3:0] {
- /* Arithmetic operations. */
- ADD = 4'b0000,
- SUB = 4'b1000,
- /* Logical operations. */
- XOR = 4'b0100,
- OR = 4'b0110,
- AND = 4'b0111,
- /* Shift operations. */
- SLL = 4'b0001,
- SRL = 4'b0101,
- SRA = 4'b1101,
- /* Conditional set operations. */
- SLT = 4'b0010,
- SLTU = 4'b0011,
- /* Zicond operations. */
- CZERO_EQZ = 4'b1001,
- CZERO_NEZ = 4'b1011
- } fu_op_t;
-
-endpackage : montreal_pkg
diff --git a/tb/alu/alu_logic_tb.sv b/tb/alu/alu_logic_tb.sv
index 6533132..7d70bda 100644
--- a/tb/alu/alu_logic_tb.sv
+++ b/tb/alu/alu_logic_tb.sv
@@ -1,7 +1,8 @@
/* Testbench for ALU XOR, OR, AND operations.
*
* Logical operations are purely combinational per slice — no carry propagation.
- * carry_o MUST be 0 on every slice for all logical operations.
+ * carry_o is NOT valid for logical operations and MUST NOT be used by the
+ * caller. It is not checked in this testbench.
*/
module alu_logic_tb;
@@ -70,27 +71,11 @@ module alu_logic_tb;
end
endtask
- task automatic check_carry(
- input string name,
- input logic [31:0] a,
- input logic [31:0] b,
- input logic got
- );
- if (got === 1'b0) begin
- $display(" PASS %s carry: %h op %h -> carry_o = 0", name, a, b);
- pass_count++;
- end else begin
- $display(" FAIL %s carry: %h op %h -> carry_o = %b (expected 0)", name, a, b, got);
- fail_count++;
- end
- endtask
-
task automatic test_xor(input logic [31:0] a, input logic [31:0] b);
logic [31:0] result;
logic final_carry;
run_op(XOR, a, b, result, final_carry);
check("XOR", a, b, result, a ^ b);
- check_carry("XOR", a, b, final_carry);
endtask
task automatic test_or(input logic [31:0] a, input logic [31:0] b);
@@ -98,7 +83,6 @@ module alu_logic_tb;
logic final_carry;
run_op(OR, a, b, result, final_carry);
check("OR", a, b, result, a | b);
- check_carry("OR", a, b, final_carry);
endtask
task automatic test_and(input logic [31:0] a, input logic [31:0] b);
@@ -106,7 +90,6 @@ module alu_logic_tb;
logic final_carry;
run_op(AND, a, b, result, final_carry);
check("AND", a, b, result, a & b);
- check_carry("AND", a, b, final_carry);
endtask
initial begin