49. Using Task

Loading...

Testbench Code

`timescale 1ns/1ps

module tb_sat_add8_wrap;
    // 1) Inputs
    reg  [7:0] a, b;

    // 2) DUT outputs
    wire [7:0] sum;
    wire       carry;

    // 3) Expected (prefixed expected_)
    reg  [7:0] expected_sum;
    reg        expected_carry;

    // 4) Mismatch (HIGH on fail)
    reg  mismatch;
    wire mismatch_w = (sum !== expected_sum) || (carry !== expected_carry);

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

    // VCD limit
    integer VCD_MAX_CASES = 32;

    // Seed for reproducible randomness (change to vary)
    integer seed;
    initial seed = 32'h5ADD_CAFE ^ $time;

    // DUT
    sat_add8_wrap dut(.a(a), .b(b), .sum(sum), .carry(carry));

    // ---------- Golden model (TB-only) ----------
    reg [8:0] raw;
    task compute_expected;
        input [7:0] ta, tb;
        begin
            raw            = ta + tb;                   // 9-bit add
            expected_carry = raw[8];                    // unsigned carry
            expected_sum   = expected_carry ? 8'hFF     // saturation
                                            : raw[7:0];
        end
    endtask

    // VCD dump (Inputs -> Outputs -> Expected -> Mismatch)
    initial begin
        $dumpfile("tb_sat_add8_wrap.vcd");
        $dumpvars(0,
            tb_sat_add8_wrap.a, tb_sat_add8_wrap.b,          // Inputs
            tb_sat_add8_wrap.sum, tb_sat_add8_wrap.carry,    // Outputs
            tb_sat_add8_wrap.expected_sum,                   // Expected
            tb_sat_add8_wrap.expected_carry,                 // Expected
            tb_sat_add8_wrap.mismatch                        // Mismatch
        );
        $dumpon; // start at #0
    end

    // Header + init
    initial begin
        a=0; b=0; mismatch=0; expected_sum=0; expected_carry=0;
        $display("   a     b   |  sum  c | expected_sum expected_carry | mismatch");
        $display("----------------------------------------------------------------");
    end

    // Apply + check (EXPECTED FIRST -> WAIT -> COMPARE)
    task apply_and_check;
        input [7:0] ta, tb;
        begin
            a = ta; b = tb;

            compute_expected(ta, tb); // compute expected before waiting
            #1;                       // let DUT settle

            mismatch = mismatch_w;

            TOTAL_TEST_CASES++;
            if (!mismatch) TOTAL_PASSED_TEST_CASES++;
            else           TOTAL_FAILED_TEST_CASES++;

            $display("0x%02h 0x%02h | 0x%02h  %0d |     0x%02h           %0d        |   %0d",
                     a, b, sum, carry, expected_sum, expected_carry, mismatch);

            if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff;
        end
    endtask

    integer i;
    initial begin
        // Directed (compact table, < 20 lines printed)
        apply_and_check(8'h00, 8'h00); // 0 + 0
        apply_and_check(8'h01, 8'h02); // no carry
        apply_and_check(8'h7F, 8'h01); // boundary (no carry, sum=0x80)
        apply_and_check(8'h80, 8'h80); // carry -> saturate
        apply_and_check(8'hFF, 8'h01); // carry -> saturate
        apply_and_check(8'hF0, 8'h20); // carry -> saturate
        apply_and_check(8'h10, 8'h10); // no carry
        apply_and_check(8'hAA, 8'h55); // no carry

        // Small sweep near carry boundary
        for (i = 0; i < 8; i = i + 1)
            apply_and_check(8'hF8 + i, 8'h07);

        // A few randoms (keep total ≤ 32)
        repeat (8) apply_and_check($random(seed), $random(seed));

        // Summary logs
        $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