61. 7-Segment Display Decoder

Decode a 4-bit hex value into seven segment control lines.

Requirements

  • Module: sevenseg_hex
  • Inputs: hex[3:0]
  • Outputs: seg[6:0] (active-high)
  • Keep it fully combinational (no clocks, no delays)

7-Segment ASCII Diagram (segment labels)

       a
     ────
  f |    | b
     ────   ← g
  e |    | c
     ────
       d

seg[6]=a, seg[5]=b, seg[4]=c, seg[3]=d, seg[2]=e, seg[1]=f, seg[0]=g

Expected Behavior

hexseg[6:0]Lit segments
07'b1111110a b c d e f
17'b0110000b c
27'b1101101a b d e g
37'b1111001a b c d g
47'b0110011b c f g
57'b1011011a c d f g
67'b1011111a c d e f g
77'b1110000a b c
87'b1111111a b c d e f g
97'b1111011a b c d f g
A7'b1110111a b c e f g
B7'b0011111c d e f g (styled ‘b’)
C7'b1001110a d e f
D7'b0111101b c d e g (styled ‘d’)
E7'b1001111a d e f g
F7'b1000111a e f g

Testbench Code

`timescale 1ns/1ps

module tb_sevenseg_hex;
    // 1) Inputs
    reg  [3:0] hex;

    // 2) DUT outputs
    wire [6:0] seg;      // ACTIVE-HIGH, {a,b,c,d,e,f,g}

    // 3) Expected (compute with a mirrored case here in TB)
    reg  [6:0] expected_seg;  // ACTIVE-HIGH expected

    // 4) Single mismatch flag (case-inequality catches X/Z)
    wire mismatch = (seg !== expected_seg);

    // 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 printed rows
    integer ERROR_MAX_CASES = 32; // error printed rows
    integer printed_rows    = 0;
    integer printed_errors  = 0;

    // DUT
    sevenseg_hex dut(.hex(hex), .seg(seg));

    // VCD dump
    initial begin
        $dumpfile("tb_sevenseg_hex.vcd");
        $dumpvars(0,
            tb_sevenseg_hex.hex,
            tb_sevenseg_hex.seg,
            tb_sevenseg_hex.expected_seg,
            tb_sevenseg_hex.mismatch
        );
        $dumpon;
    end

    // Golden computation (ACTIVE-HIGH) – matches the DUT table
    always @* begin
        case (hex)
            4'h0: expected_seg = 7'b1111110;
            4'h1: expected_seg = 7'b0110000;
            4'h2: expected_seg = 7'b1101101;
            4'h3: expected_seg = 7'b1111001;
            4'h4: expected_seg = 7'b0110011;
            4'h5: expected_seg = 7'b1011011;
            4'h6: expected_seg = 7'b1011111;
            4'h7: expected_seg = 7'b1110000;
            4'h8: expected_seg = 7'b1111111;
            4'h9: expected_seg = 7'b1111011;
            4'hA: expected_seg = 7'b1110111;
            4'hB: expected_seg = 7'b0011111;
            4'hC: expected_seg = 7'b1001110;
            4'hD: expected_seg = 7'b0111101;
            4'hE: expected_seg = 7'b1001111;
            4'hF: expected_seg = 7'b1000111;
            default: expected_seg = 7'b0000000;
        endcase
    end

    // Header + init
    initial begin
        hex = 4'h0;
        $display(" hex |  seg   | expected | mismatch   (seg bit order {a,b,c,d,e,f,g})");
        $display("---------------------------------------------------------------------");
    end

    // Apply + check (drive -> wait -> read combinational mismatch)
    task apply_and_check;
        input [3:0] th;
        begin
            hex = th;
            #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("  %1x  | %07b |  %07b |    %0d",
                             hex, seg, expected_seg, 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: hex=%1x => seg=%07b (expected %07b)",
                             hex, seg, expected_seg);
                    printed_errors = printed_errors + 1;
                end
            end

            if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff; // optional VCD cap
        end
    endtask

    integer i;
    initial begin
        // Exhaustive 0..F
        for (i = 0; i < 16; i = i + 1) apply_and_check(i[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