diff options
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | rtl/alu.sv | 47 | ||||
| -rw-r--r-- | rtl/montreal_pkg.sv | 28 | ||||
| -rw-r--r-- | tb/alu/alu_logic_tb.sv | 21 |
4 files changed, 24 insertions, 76 deletions
@@ -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/ @@ -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 |