Classroom Glossary Public page

Lab 2: Boolean Arithmetic — 32-bit ALU

274 words

Week: 2
Points: 20
Time: ~5 hours
Deliverable: verilog/alu/ directory + diary/week-02.md


What you ship

  • verilog/alu/full_adder.v — full adder
  • verilog/alu/adder32.v — 32-bit ripple-carry adder
  • verilog/alu/alu.v — 32-bit ALU (ADD/SUB/AND/OR/XOR/SLT)
  • lab2_testbench_output.txt — all tests pass
  • diary/week-02.md

Lab 2.1: Full adder

Extend the half adder from Lab 1.4 to a full adder. The full adder accepts carry_in and produces sum and carry_out:

module full_adder(
    input  a, b, carry_in,
    output sum, carry_out
);
    wire sum1, carry1, carry2;
    half_adder ha1(.a(a), .b(b), .sum(sum1), .carry(carry1));
    half_adder ha2(.a(sum1), .b(carry_in), .sum(sum), .carry(carry2));
    or_gate or1(.a(carry1), .b(carry2), .out(carry_out));
endmodule

Test all 8 input combinations. Verify 1+1+1 = 1 with carry_out = 1.


Lab 2.2: 32-bit ripple-carry adder

Wire 32 full_adder instances. Bit 0 has carry_in = 0 (or a sub control signal for subtraction):

module adder32(
    input  [31:0] a, b,
    input         sub,        // 1 = subtract (inverts b, carry_in=1)
    output [31:0] result,
    output        carry_out
);
    wire [31:0] b_in = sub ? ~b : b;
    wire [32:0] carry;
    assign carry[0] = sub;    // two's complement: flip + add 1
    // wire 32 full_adder instances using generate or explicit instantiation
    ...
endmodule

Verify with the testbench: 20 test cases including at least:

  • 0 + 0 = 0
  • 1 + 1 = 2
  • 0xFFFFFFFF + 1 = 0 with carry_out = 1 (overflow)
  • 10 - 3 = 7 with sub = 1
  • 0 - 1 = 0xFFFFFFFF (unsigned underflow)

Lab 2.3: ALU

Write alu.v with ADD, SUB, AND, OR, XOR, SLT operations selected by op[2:0]:

op Operation
3'b000 ADD
3'b001 SUB
3'b010 AND
3'b011 OR
3'b100 XOR
3'b101 SLT (set less than: signed comparison)

Also output zero = (result == 0) which the CPU uses for BEQ/BNE.

Run lab2_alu_tb.v: at least 10 test cases per operation (60 cases total). All must pass.


Lab 2.4: IEEE-754 hand encoding

This is a hand exercise, not a Verilog lab. Encode these three values in IEEE-754 single precision (32-bit):

Value Sign Biased exponent Mantissa (fraction) Hex
1.5
-0.75
0.1

Verify with Python:

import struct
for v in [1.5, -0.75, 0.1]:
    print(f"{v}: {struct.pack('>f', v).hex()}")

Note: 0.1 does not have an exact binary representation. Record the rounding in your diary.


Toolchain Diary

Record in diary/week-02.md:

  • Gate depth of your adder32.v: count the longest propagation path from any primary input to any output
  • Whether you used generate or explicit instantiation for the 32 full adders and why
  • IEEE-754 encoding results for all three values

Grading

Component Points
full_adder.v and adder32.v pass 20 testbench cases 6
alu.v passes 60-case testbench 10
IEEE-754 hand encoding correct for all 3 values 2
Toolchain Diary entry (gate depth + design choice noted) 2