30. Bus Error Checker

Loading...

Testbench Code

`timescale 1ns/1ps

module tb_error_checker_xz;
    // Input
    reg  [7:0] bus;

    // DUT outputs
    wire       all_known;
    wire       has_unknown;
    wire [7:0] bus_if_known;

    // Expected (golden)
    reg        expected_all_known;
    reg        expected_has_unknown;
    reg  [7:0] expected_bus_if_known;

    // Mismatch flags + consolidated one for waveform
    wire mm_known   = (all_known    !== expected_all_known);
    wire mm_has     = (has_unknown  !== expected_has_unknown);
    wire mm_bus     = (bus_if_known !== expected_bus_if_known);
    wire mismatch   = mm_known | mm_has | mm_bus;

    integer TOTAL, PASS, FAIL;

    // DUT
    error_checker_xz dut (
        .bus(bus),
        .all_known(all_known),
        .has_unknown(has_unknown),
        .bus_if_known(bus_if_known)
    );

    // VCD: only input, outputs, expected, mismatch
    initial begin
        $dumpfile("tb_error_checker_xz.vcd");
        $dumpvars(0,
            tb_error_checker_xz.bus,
            tb_error_checker_xz.all_known, tb_error_checker_xz.has_unknown, tb_error_checker_xz.bus_if_known,
            tb_error_checker_xz.expected_all_known, tb_error_checker_xz.expected_has_unknown, tb_error_checker_xz.expected_bus_if_known,
            tb_error_checker_xz.mismatch
        );
    end

    // Golden model (same X/Z detection as DUT; NOT a self-compare)
    task compute_expected;
        input [7:0] t_bus;
        reg   any_xz_g;
        begin
            any_xz_g              = (^(t_bus ^ t_bus)) === 1'bx;
            expected_has_unknown  = any_xz_g;
            expected_all_known    = ~any_xz_g;
            expected_bus_if_known = expected_all_known ? t_bus : 8'h00;
        end
    endtask

    task run_test;
        input [7:0] t_bus;
        begin
            bus = t_bus;
            compute_expected(t_bus);
            #1;
            TOTAL = TOTAL + 1;
            if (!mismatch) PASS = PASS + 1; else begin
                FAIL = FAIL + 1;
                $display("FAILED: bus=%b | known=%b has=%b out=%h | exp_known=%b exp_has=%b exp_out=%h",
                         bus, all_known, has_unknown, bus_if_known,
                         expected_all_known, expected_has_unknown, expected_bus_if_known);
            end
        end
    endtask

    integer i;
    initial begin
        TOTAL=0; PASS=0; FAIL=0;

        // Directed 8-bit cases (with X/Z)
        run_test(8'h00);              // known
        run_test(8'hFF);              // known
        run_test(8'b0000_010x);       // one X
        run_test(8'b0000_z001);       // one Z
        run_test(8'bzzzz_zzzz);       // all Z
        run_test(8'bxxxx_1010);       // leading Xs
        run_test(8'hA5);              // known
        run_test(8'h5A);              // known

        // Random known values (truncate $random to 8 bits -> still 0/1 only)
        for (i=0; i<6; i=i+1)
            run_test($random);

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