57. 4-bit Comparator

Compute the maximum and minimum among four unsigned 4-bit inputs.

Requirements

  • Module: maxmin4
  • Inputs: a[3:0], b[3:0], c[3:0], d[3:0]
  • Outputs: max[3:0], min[3:0]
  • Keep it fully combinational (no clocks, no delays).

Behavior

  • Inputs: a[3:0], b[3:0], c[3:0], d[3:0]
  • Outputs: max[3:0], min[3:0]
  • Unsigned comparison. Pairwise tree is recommended

Testbench Code

`timescale 1ns/1ps

module tb_maxmin4;
    // 1) Inputs
    reg  [3:0] a, b, c, d;

    // 2) DUT outputs
    wire [3:0] max, min;

    // 3) Expected (purely combinational helpers)
    function [3:0] fmax2;
        input [3:0] x, y; begin fmax2 = (x >= y) ? x : y; end
    endfunction
    function [3:0] fmin2;
        input [3:0] x, y; begin fmin2 = (x  <  y) ? x : y; end
    endfunction

    wire [3:0] exp_max = fmax2( fmax2(a,b), fmax2(c,d) );
    wire [3:0] exp_min = fmin2( fmin2(a,b), fmin2(c,d) );

    // 4) Single mismatch flag (case-inequality treats X/Z as mismatches)
    wire mismatch = ({max, min} !== {exp_max, exp_min});

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

    // Limits
    integer VCD_MAX_CASES   = 32; // normal rows printed
    integer ERROR_MAX_CASES = 32; // error rows printed
    integer printed_rows    = 0;
    integer printed_errors  = 0;

    // DUT
    maxmin4 dut(.a(a), .b(b), .c(c), .d(d), .max(max), .min(min));

    // VCD dump
    initial begin
        $dumpfile("tb_maxmin4.vcd");
        $dumpvars(0,
            tb_maxmin4.a, tb_maxmin4.b, tb_maxmin4.c, tb_maxmin4.d,
            tb_maxmin4.max, tb_maxmin4.min,
            tb_maxmin4.exp_max, tb_maxmin4.exp_min,
            tb_maxmin4.mismatch
        );
        $dumpon;
    end

    // Header + init
    initial begin
        a=0; b=0; c=0; d=0;
        $display("  a   b   c   d  | max min | exp_max exp_min | mismatch");
        $display("--");
    end

    // Apply + check (drive -> wait -> read combinational mismatch)
    task apply_and_check;
        input [3:0] ta, tb, tc, td;
        begin
            a = ta; b = tb; c = tc; d = td;
            #1; // settle

            TOTAL_TEST_CASES = TOTAL_TEST_CASES + 1;
            if (!mismatch) begin
                TOTAL_PASSED_TEST_CASES = TOTAL_PASSED_TEST_CASES + 1;
                if (printed_rows < VCD_MAX_CASES) begin
                    $display("0x%1h 0x%1h 0x%1h 0x%1h | 0x%1h 0x%1h |   0x%1h     0x%1h  |    %0d",
                             a,b,c,d, max,min, exp_max,exp_min, mismatch);
                    printed_rows = printed_rows + 1;
                end
            end else begin
                TOTAL_FAILED_TEST_CASES = TOTAL_FAILED_TEST_CASES + 1;
                if (printed_errors < ERROR_MAX_CASES) begin
                    $display("ERR: a=0x%1h b=0x%1h c=0x%1h d=0x%1h => max=0x%1h min=0x%1h (exp max=0x%1h min=0x%1h)",
                             a,b,c,d, max,min, exp_max,exp_min);
                    printed_errors = printed_errors + 1;
                end
            end

            // Optional: stop VCD after cap of total vectors
            if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff;
        end
    endtask

    integer ia, ib, ic, id;
    initial begin
        // Directed: ties, extremes, permutations
        apply_and_check(4'h0, 4'h0, 4'h0, 4'h0); // all equal
        apply_and_check(4'hF, 4'h0, 4'h1, 4'h8); // spread
        apply_and_check(4'h7, 4'h7, 4'h2, 4'h2); // two pairs
        apply_and_check(4'hA, 4'h5, 4'hA, 4'h3); // tie at max
        apply_and_check(4'h4, 4'h4, 4'h4, 4'hF); // three equal + one extreme
        apply_and_check(4'hF, 4'hE, 4'hD, 4'hC); // descending
        apply_and_check(4'h1, 4'h2, 4'h3, 4'h4); // ascending

        // full sweeps 
        for (ia = 0; ia < 16; ia = ia + 1)
          for (ib = 1; ib < 16; ib = ib + 1)
            for (ic = 2; ic < 16; ic = ic + 1)
              for (id = 3; id < 16; id = id + 1)
                apply_and_check(ia[3:0], ib[3:0], ic[3:0], id[3:0]);


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