14. Logical Shifter

Loading...

Testbench Code

`timescale 1ns/1ps

module tb_shift8;
    // Inputs
    reg  [7:0] A;
    reg  [2:0] shamt;

    // DUT outputs
    wire [7:0] SHL;
    wire [7:0] SHR;

    // Expected outputs
    reg  [7:0] expected_SHL;
    reg  [7:0] expected_SHR;

    // Mismatch signals
    wire mismatch_shl = (SHL !== expected_SHL);
    wire mismatch_shr = (SHR !== expected_SHR);
    wire mismatch     = mismatch_shl | mismatch_shr;

    integer TOTAL_TEST_CASES = 0;
    integer TOTAL_PASSED_TEST_CASES = 0;
    integer TOTAL_FAILED_TEST_CASES = 0;

    // Instantiate DUT
    shift8 dut (
        .A(A),
        .shamt(shamt),
        .SHL(SHL),
        .SHR(SHR)
    );

    // VCD dump (Inputs -> Outputs -> Expected -> mismatch)
    initial begin
        $dumpfile("tb_shift8.vcd");
        $dumpvars(0,
            tb_shift8.A, tb_shift8.shamt,             // inputs
            tb_shift8.SHL, tb_shift8.SHR,             // outputs
            tb_shift8.expected_SHL, tb_shift8.expected_SHR, // expected
            tb_shift8.mismatch                        // mismatch flag
        );
    end

    task run_one;
        input [7:0] tA;
        input [2:0] tShamt;
        begin
            A = tA; shamt = tShamt;

            // Golden model
            expected_SHL = tA << tShamt;
            expected_SHR = tA >> tShamt;

            #1;
            TOTAL_TEST_CASES = TOTAL_TEST_CASES + 1;
            if (!mismatch) begin
                TOTAL_PASSED_TEST_CASES = TOTAL_PASSED_TEST_CASES + 1;
            end else begin
                TOTAL_FAILED_TEST_CASES = TOTAL_FAILED_TEST_CASES + 1;
                $display("FAILED: A=%b shamt=%0d | SHL=%b exp_SHL=%b | SHR=%b exp_SHR=%b mismatch=%b",
                         A, shamt, SHL, expected_SHL, SHR, expected_SHR, mismatch);
            end
        end
    endtask

    integer i;
    initial begin
        // Directed edge/typical cases
        run_one(8'b1010_1100, 3'd0); // pass-through
        run_one(8'b1010_1100, 3'd1);
        run_one(8'b1010_1100, 3'd3);
        run_one(8'b1010_1100, 3'd7);
        run_one(8'hFF,        3'd4); // SHL=0xF0, SHR=0x0F
        run_one(8'h01,        3'd1); // SHR -> 0
        run_one(8'h80,        3'd7); // SHR -> 1

        // Limited randomized sweep
        for (i=0; i<20; i=i+1)
            run_one($random, $random);

        // 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");
        $display("======================================");
        $finish;
    end
endmodule