38. Safe MUX

Loading...

Testbench Code

`timescale 1ns/1ps

module tb_safe_mux2;
    // Inputs
    reg  [7:0] a, b;
    reg        sel;

    // DUT outputs
    wire [7:0] y;
    wire       sel_unknown;

    // Expected (as wires; prefix expected_)
    wire [7:0] expected_y;
    wire       expected_sel_unknown;

    // Mismatch signal (for VCD only)
    reg  mismatch;
    wire mismatch_w = (y !== expected_y) || (sel_unknown !== expected_sel_unknown);

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

    // VCD control
    integer VCD_MAX_CASES = 32;

    // DUT
    safe_mux2 dut(.a(a), .b(b), .sel(sel), .y(y), .sel_unknown(sel_unknown));

    // Reference model
    assign expected_y =
        (sel === 1'b0) ? a :
        (sel === 1'b1) ? b : 8'h00;

    assign expected_sel_unknown =
        (sel === 1'b0) ? 1'b0 :
        (sel === 1'b1) ? 1'b0 : 1'b1;

    // VCD setup
    initial begin
        $dumpfile("tb_safe_mux2.vcd");
        $dumpvars(0,
            tb_safe_mux2.a, tb_safe_mux2.b, tb_safe_mux2.sel,                 // Inputs
            tb_safe_mux2.y, tb_safe_mux2.sel_unknown,                         // Outputs
            tb_safe_mux2.expected_y, tb_safe_mux2.expected_sel_unknown,       // Expected
            tb_safe_mux2.mismatch                                            // Mismatch
        );
        $dumpon;
    end

    initial begin
        a = 8'h00; b = 8'h00; sel = 1'b0;
        mismatch = 1'b0;
        $display(" a     b    sel | DUT_y   DUT_sel_unknown || expected_y expected_sel_unknown | mismatch");
        $display("--------------------------------------------------------------------------------------");
    end

    // Apply vector, settle, log truth table, update counters
    task apply_and_check;
        input [7:0] ta, tb;
        input       tsel;
        begin
            a = ta; b = tb; sel = tsel;
            #1; // allow DUT + expected to settle

            mismatch = mismatch_w;

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

            // Print truth table row
            $display("0x%02h 0x%02h   %s  | 0x%02h        %b            ||   0x%02h           %b         |   %b",
                a, b,
                (sel===1'b0)?"0":(sel===1'b1)?"1":(sel===1'bx)?"x":"z",
                y, sel_unknown,
                expected_y, expected_sel_unknown,
                mismatch
            );

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

    // Stimulus
    initial begin
        // Clean select
        apply_and_check(8'h12,8'h34,1'b0);
        apply_and_check(8'h12,8'h34,1'b1);

        // X/Z select
        apply_and_check(8'hAA,8'h55,1'bx);
        apply_and_check(8'hAA,8'h55,1'bz);

        // Randomized clean (mask to 0/1)
        repeat (12) apply_and_check($random, $random, $random & 1);

        // Stress with unknown select
        apply_and_check(8'hF0,8'h0F,1'bx);
        apply_and_check(8'hFF,8'h00,1'bz);

        // 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