No submissions yet

Submit your solution to display here.

Please login/signup to submit your solution.

Testbench Code

`timescale 1ns/1ps

module tb_alu4;
    // 1) Inputs
    reg  [3:0] a, b;
    reg  [2:0] op;

    // 2) DUT outputs
    wire [3:0] y;
    wire       cf;

    // 3) Expected (pure combinational, no functions)
    wire [4:0] exp_add5 = {1'b0, a} + {1'b0, b};                // ADD
    wire [4:0] exp_sub5 = {1'b0, a} + {1'b0, ~b} + 5'b00001;    // SUB (a + ~b + 1)

    wire [3:0] expected_y =
        (op==3'b000) ? exp_add5[3:0] :
        (op==3'b001) ? exp_sub5[3:0] :
        (op==3'b010) ? (a & b)       :
        (op==3'b011) ? (a | b)       :
        (op==3'b100) ? (a ^ b)       :
                        4'b0000;

    wire expected_cf =
        (op==3'b000) ? exp_add5[4]  :  // carry for ADD
        (op==3'b001) ? ~exp_sub5[4] :  // borrow for SUB = ~carry_out
                        1'b0;          // logic ops

    // 4) Single mismatch flag (treat X/Z as mismatches)
    wire mismatch = ({y, cf} !== {expected_y, expected_cf});

    // Accounting
    integer TOTAL_TEST_CASES        = 0;
    integer TOTAL_PASSED_TEST_CASES = 0;
    integer TOTAL_FAILED_TEST_CASES = 0;

    // Limits
    integer VCD_MAX_CASES   = 32; // normal printed rows
    integer ERROR_MAX_CASES = 32; // error printed rows
    integer printed_rows    = 0;
    integer printed_errors  = 0;

    // DUT
    alu4 dut(.a(a), .b(b), .op(op), .y(y), .cf(cf));

    // VCD dump
    initial begin
        $dumpfile("tb_alu4.vcd");
        $dumpvars(0,
            tb_alu4.a, tb_alu4.b, tb_alu4.op,
            tb_alu4.y, tb_alu4.cf,
            tb_alu4.expected_y, tb_alu4.expected_cf,
            tb_alu4.mismatch
        );
        $dumpon;
    end

    // Header + init
    initial begin
        a=0; b=0; op=3'b000;
        $display(" a  b   op |  y  cf | exp_y exp_cf | mismatch");
        $display("---------------------------------------------");
    end

    // Apply + check (drive -> wait -> read combinational mismatch)
    task apply_and_check;
        input [3:0] ta, tb_;
        input [2:0] top;
        begin
            a = ta; b = tb_; op = top;
            #1; // settle

            TOTAL_TEST_CASES = TOTAL_TEST_CASES + 1;
            if (!mismatch) begin
                TOTAL_PASSED_TEST_CASES = TOTAL_PASSED_TEST_CASES + 1;
                if (printed_rows < VCD_MAX_CASES) begin
                    $display("0x%1h 0x%1h %03b | 0x%1h  %0d | 0x%1h    %0d   |    %0d",
                             a, b, op, y, cf, expected_y, expected_cf, mismatch);
                    printed_rows = printed_rows + 1;
                end
            end else begin
                TOTAL_FAILED_TEST_CASES = TOTAL_FAILED_TEST_CASES + 1;
                if (printed_errors < ERROR_MAX_CASES) begin
                    $display("ERR: a=0x%1h b=0x%1h op=%03b => y=0x%1h cf=%0d (exp y=0x%1h cf=%0d)",
                             a, b, op, y, cf, expected_y, expected_cf);
                    printed_errors = printed_errors + 1;
                end
            end

            // Optional: stop VCD after cap of total vectors
            if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff;
        end
    endtask

    integer ia, ib, m;
    initial begin
        // Directed per op
        apply_and_check(4'h0,4'h0,3'b000); // ADD
        apply_and_check(4'hF,4'h1,3'b000); // ADD carry
        apply_and_check(4'h0,4'h1,3'b001); // SUB borrow
        apply_and_check(4'hA,4'h3,3'b001); // SUB
        apply_and_check(4'hA,4'h5,3'b010); // AND
        apply_and_check(4'hA,4'h5,3'b011); // OR
        apply_and_check(4'hA,4'h5,3'b100); // XOR

        // Compact sweeps (keep output readable)
        for (m = 0; m < 5; m = m + 1)
          for (ia = 0; ia < 16; ia = ia + 1)
            for (ib = 0; ib < 16; ib = ib + 1)
              apply_and_check(ia[3:0], ib[3:0], m[2:0]);

        // A few randoms
        repeat (24) apply_and_check($random, $random, {$random}%5);

        // Summary
        $display("---------------------------------------------");
        $display("TOTAL_TEST_CASES=%0d", TOTAL_TEST_CASES);
        $display("TOTAL_PASSED_TEST_CASES=%0d", TOTAL_PASSED_TEST_CASES);
        $display("TOTAL_FAILED_TEST_CASES=%0d", TOTAL_FAILED_TEST_CASES);
        $display("ALL_TEST_CASES_PASSED=%s", (TOTAL_FAILED_TEST_CASES==0) ? "true" : "false");
        #2 $finish;
    end
endmodule