For a small combinational block the truth table is the specification. It lists what the output must be for every input.
That makes it the best debug anchor available. A failing test reporting “input 101 gave 0, expected 1” points straight at the missing minterm.
Inputs | Test vectors | Verdict |
|---|---|---|
3 | 8 | Usually instant. |
8 | 256 | Usually instant. |
16 | 65,536 | Often well under a second. |
24 | 16.7 million | Often seconds to minutes; fine for many nightly runs. |
32 | 4.3 billion | Too many for exhaustive simulation: use random + directed tests, or formal equivalence. |
Feasibility depends on the DUT, the simulator and logging. Time a small sample before extrapolating to the full run.
The pattern is a reference function in the testbench plus a loop that drives every input.
Here the majority function from the first lesson is checked against a counting-based reference. The reference is deliberately written differently from the design.
module majority3 (input logic a, b, c, output logic y);
assign y = (a & b) | (b & c) | (a & c);
endmodule
module tb_majority;
logic a, b, c, y;
majority3 dut (.*);
// Independent reference: count the ones. Different structure from the DUT.
function automatic logic ref_majority(logic ia, ib, ic);
int ones;
ones = (ia ? 1 : 0) + (ib ? 1 : 0) + (ic ? 1 : 0);
return (ones >= 2);
endfunction
int errors = 0;
initial begin
for (int i = 0; i < 8; i++) begin
{a, b, c} = i[2:0];
#1;
if (y !== ref_majority(a, b, c)) begin
$display("FAIL: abc=%b%b%b y=%b expected=%b", a, b, c, y, ref_majority(a, b, c));
errors++;
end
end
if (errors == 0) $display("PASS: all 8 vectors match");
$finish;
end
endmoduleSuppose someone “simplifies” the equation incorrectly to y = ab + bc, forgetting the ac term.
The exhaustive test reports exactly one failing vector. The truth table names the missing piece:
FAIL: abc=101 y=0 expected=1Input 101 is the minterm a·b′·c. No remaining term covers it, so the fix is to restore ac.
One failing row identified the bug without opening a waveform viewer.
Some inputs never occur in a real system. Examples are the unused codes of a BCD digit (10 to 15).
Their outputs are don't-cares: they may be chosen to simplify the logic. In simulation this is expressed as x:
// snippet: BCD "is even" with don't-care for invalid codes
always_comb begin
unique case (digit)
4'd0, 4'd2, 4'd4, 4'd6, 4'd8: is_even = 1'b1;
4'd1, 4'd3, 4'd5, 4'd7, 4'd9: is_even = 1'b0;
default: is_even = 1'bx; // 10..15 never happen
endcase
end2²⁰ is about one million vectors, so it is usually feasible and worth trying after timing a small sample. At roughly 32 inputs exhaustive simulation becomes impractical (4.3 billion). There you combine directed corner cases, constrained-random tests, and a formal equivalence check against the reference.