50. Vector Min/Max Pair

Given four 8-bit unsigned inputs, produce both the minimum and the maximum values.

Requirements

  • Module: minmax4_task
  • Inputs: v0[7:0], v1[7:0], v2[7:0], v3[7:0]
  • Outputs: min_val[7:0], max_val[7:0]

Behavior

  • Inputs: v0, v1, v2, v3 (all 8-bit unsigned)
  • Outputs: min_val = minimum of the four, max_val = maximum of the four

Testbench Code

`timescale 1ns/1ps

module tb_minmax4_task;
    // 1) Inputs
    reg  [7:0] v0, v1, v2, v3;

    // 2) DUT outputs
    wire [7:0] min_val;
    wire [7:0] max_val;

    // 3) Expected (prefixed expected_)
    reg  [7:0] expected_min_val;
    reg  [7:0] expected_max_val;

    // 4) Mismatch (HIGH on fail)
    reg  mismatch;
    wire mismatch_w = (min_val !== expected_min_val) ||
                      (max_val !== expected_max_val);

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

    // DUT
    minmax4_task dut(
        .v0(v0), .v1(v1), .v2(v2), .v3(v3),
        .min_val(min_val), .max_val(max_val)
    );

    // ---------- Golden model (TB-only) ----------
    function [7:0] f_max2; input [7:0] a,b; begin f_max2 = (a > b) ? a : b; end endfunction
    function [7:0] f_min2; input [7:0] a,b; begin f_min2 = (a < b) ? a : b; end endfunction

    task compute_expected;
        input [7:0] a,b,c,d;
        reg   [7:0] max01, max23, min01, min23;
        begin
            max01 = f_max2(a,b);  min01 = f_min2(a,b);
            max23 = f_max2(c,d);  min23 = f_min2(c,d);
            expected_max_val = f_max2(max01, max23);
            expected_min_val = f_min2(min01, min23);
        end
    endtask

    // ---- VCD dump (Inputs -> Outputs -> Expected -> Mismatch) ----
    initial begin
        $dumpfile("tb_minmax4_task.vcd");
        $dumpvars(0,
            tb_minmax4_task.v0, tb_minmax4_task.v1, tb_minmax4_task.v2, tb_minmax4_task.v3, // Inputs
            tb_minmax4_task.min_val, tb_minmax4_task.max_val,                                // Outputs
            tb_minmax4_task.expected_min_val, tb_minmax4_task.expected_max_val,              // Expected
            tb_minmax4_task.mismatch                                                         // Mismatch
        );
        $dumpon; // start at #0
    end

    // Header + init
    initial begin
        v0=0; v1=0; v2=0; v3=0; mismatch=0;
        expected_min_val=0; expected_max_val=0;
        $display("    v0    v1    v2    v3  | min  max | exp_min exp_max | mismatch");
        $display("-----------------------------------------------------------------");
    end

    // Apply + check (EXPECTED FIRST -> WAIT -> COMPARE)
    task apply_and_check;
        input [7:0] a, b, c, d;
        begin
            v0 = a; v1 = b; v2 = c; v3 = d;

            compute_expected(a,b,c,d); // expected first
            #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 0x%02h | 0x%02h 0x%02h |  0x%02h   0x%02h |    %0d",
                     v0, v1, v2, v3,
                     min_val, max_val,
                     expected_min_val, expected_max_val,
                     mismatch);

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

    integer i;
    integer seed;
    initial begin
        seed = 32'hC0DE_FEED ^ $time;

        // Directed (≤ ~16 rows printed)
        apply_and_check(8'h00, 8'h00, 8'h00, 8'h00);
        apply_and_check(8'hFF, 8'hFF, 8'hFF, 8'hFF);
        apply_and_check(8'h01, 8'h02, 8'h03, 8'h04);
        apply_and_check(8'h04, 8'h03, 8'h02, 8'h01);
        apply_and_check(8'hAA, 8'h55, 8'hC3, 8'h3C);
        apply_and_check(8'h10, 8'h10, 8'hF0, 8'h0F);
        apply_and_check(8'h7F, 8'h80, 8'h00, 8'hFF);
        apply_and_check(8'h11, 8'h22, 8'h11, 8'h22);

        // Small patterned sweep (still printed; keep under 20 total)
        for (i = 0; i < 6; i = i + 1)
            apply_and_check(i, i+8, 8'hF0+i, 8'h0F+i);

        // A few randoms (ensure total cases ≤ 32)
        repeat (6) apply_and_check($random(seed), $random(seed), $random(seed), $random(seed));

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