Day 69: Self-checking testbenches: no waveform-staring sign-off
Self-checking testbenches for every block
You've built an ALU, register file, FIFO, LFSR, and arbiter. Before moving to peripherals, ensure each ships with a self-checking testbench — a reference model, randomized + directed stimulus, and an automatic PASS/FAIL verdict. This isn't busywork: these blocks go into ChipX, and a bug caught here is a bug you don't chase inside the integrated core later.
// FIFO reference model in the testbench (a queue) vs the DUT
integer errors = 0;
reg [7:0] model_q [$]; // SystemVerilog queue as golden model
always @(posedge clk) begin
if (wr_en && !full) model_q.push_back(wdata);
if (rd_en && !empty) begin
automatic reg [7:0] exp = model_q.pop_front();
if (rdata !== exp) begin
$display("FIFO MISMATCH: got %h exp %h", rdata, exp);
errors = errors + 1;
end
end
end
// drive thousands of random wr/rd events, then assert errors == 0This is the on-ramp to Stage 3
The reference-model-vs-DUT pattern here *is* the essence of a scoreboard — the central checker in UVM (Stage 3). Building tiny ones now means the verification stage is a scale-up of a habit you already have, not a foreign discipline. Every block with a passing self-check is one less unknown in the integrated core.
Ship for Day 69
Why should a testbench’s reference model be independent of the DUT’s logic?