43. 8-to-3 Priority Encoder

module priority_encoder8 (
    input  [7:0] req,
    output reg [2:0] code
);
    always @* begin
        code = 3'b000; // default when no request

        casez (req)
            8'b1???????: code = 3'b111; // req[7]
            8'b01??????: code = 3'b110; // req[6]
            8'b001?????: code = 3'b101; // req[5]
            8'b0001????: code = 3'b100; // req[4]
            8'b00001???: code = 3'b011; // req[3]
            8'b000001??: code = 3'b010; // req[2]
            8'b0000001?: code = 3'b001; // req[1]
            8'b00000001: code = 3'b000; // req[0]
            default:       code = 3'b000;
        endcase
    end
endmodule

💡Remember

  • Priority comes from the order of casez items — first match wins.
  • casez with ? wildcards is concise for “MSB-first” priority patterns (? and z are equivalent).
  • Always set defaults at block entry (avoid latch inference).

Testbench Code

`timescale 1ns/1ps

module tb_priority_encoder8;
    // 1) Input
    reg  [7:0] req;

    // 2) DUT output
    wire [2:0] code;

    // 3) Expected (prefixed expected_)
    wire [2:0] expected_code;

    // 4) Mismatch (HIGH on fail)
    reg  mismatch;
    wire mismatch_w = (code !== expected_code);

    // Counters
    integer TOTAL_TEST_CASES=0, TOTAL_PASSED_TEST_CASES=0, TOTAL_FAILED_TEST_CASES=0;
    integer VCD_MAX_CASES = 32;

    // Seed for reproducible randomness (change to vary runs)
    integer seed;
    initial seed = 32'hCAFE_BABE ^ $time;

    // DUT (learner solution)
    priority_encoder8 dut(.req(req), .code(code));

    // ---- Golden model (clean 0/1 inputs assumed) ----
    function [2:0] f_code(input [7:0] r);
        begin
            if (r[7])      f_code = 3'b111;
            else if (r[6]) f_code = 3'b110;
            else if (r[5]) f_code = 3'b101;
            else if (r[4]) f_code = 3'b100;
            else if (r[3]) f_code = 3'b011;
            else if (r[2]) f_code = 3'b010;
            else if (r[1]) f_code = 3'b001;
            else if (r[0]) f_code = 3'b000;
            else           f_code = 3'b000;
        end
    endfunction
    assign expected_code = f_code(req);

    // ---- VCD dump (Inputs -> Outputs -> Expected -> Mismatch) ----
    initial begin
        $dumpfile("tb_priority_encoder8.vcd");
        $dumpvars(0,
            tb_priority_encoder8.req,                 // Inputs
            tb_priority_encoder8.code,                // Output
            tb_priority_encoder8.expected_code,       // Expected
            tb_priority_encoder8.mismatch             // Mismatch
        );
        $dumpon; // start at time 0
    end

    // Header + init
    initial begin
        req = 8'h00; mismatch = 1'b0;
        $display("   req     | code | exp_code | mismatch");
        $display("----------------------------------------");
    end

    // Apply + check one vector
    task apply_and_check;
        input [7:0] t_req;
        begin
            req = t_req;
            #1; // settle
            mismatch = mismatch_w;

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

            $display("0x%02h (%b) |  %03b |   %03b   |   %0d",
                     req, req, code, expected_code, mismatch);

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

    // Stimulus
    initial begin
        // No request
        apply_and_check(8'b0000_0000);

        // Single-bit requests (all 8)
        apply_and_check(8'b0000_0001); // [0]
        apply_and_check(8'b0000_0010); // [1]
        apply_and_check(8'b0000_0100); // [2]
        apply_and_check(8'b0000_1000); // [3]
        apply_and_check(8'b0001_0000); // [4]
        apply_and_check(8'b0010_0000); // [5]
        apply_and_check(8'b0100_0000); // [6]
        apply_and_check(8'b1000_0000); // [7]

        // Multiple requests (priority → highest bit)
        apply_and_check(8'b1111_1111);
        apply_and_check(8'b1001_0001);
        apply_and_check(8'b0111_0000);
        apply_and_check(8'b0100_0011);
        apply_and_check(8'b0011_1000);

        // 10 random cases (reseed seed to vary behavior across runs if desired)
        repeat (10) apply_and_check($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