UVM
Design vs Verification
The two engineering mindsets a chip needs — the builder who makes behaviour happen and the breaker who proves it cannot go wrong — and why a strong team needs both.
Verification Foundations · Module 1 · Page 1.2
The Engineering Problem
In the previous lesson we established why verification exists: silicon cannot be patched, and a design's behaviour cannot be checked by inspection. That raises an immediate, uncomfortable question:
Who should do the checking?
The tempting answer — "the engineer who wrote the RTL, of course; they understand it best" — is exactly wrong, and understanding why it is wrong is the foundation of the entire discipline. A designer testing their own block tests what they intended to build. But the bugs that reach silicon live in the gap between what they intended and what they actually built — and that gap is invisible from inside the designer's own head, because the same mental model produced both the RTL and the test.
The real problem, then, is not "write some tests." It is: how do we check a design against the specification independently of the person and the assumptions that created it? Answering that question turns testing into verification, and makes it a distinct engineering discipline with its own mindset, its own role, and often its own team.
Motivation — why "the designer will test it" fails
A designer building a block holds a mental model of how it should behave. They write the RTL from that model. When they then write a test, they write it from the same model. So the test asks: "does the design do what I think it should?" — and, unsurprisingly, it usually does. The model and the implementation agree because the same person produced both from the same assumptions.
The catastrophe is the bug that lives outside that mental model — a case the designer never considered. They did not handle it in the RTL because they never thought of it, and they did not test it for exactly the same reason. The blind spot is shared. This is confirmation bias expressed in silicon: you cannot find a bug you were not capable of imagining, and the person who wrote the bug is, by definition, the person who could not imagine it.
The fix is independence. A second engineer, deriving expected behaviour from the specification rather than from the RTL, will interpret the spec differently, will think of cases the designer did not, and will build a checker that does not share the design's blind spots. Verification is not "the designer being more careful." It is a structurally different, independent perspective on the same specification.
Mental Model
Hold two complementary pictures:
Design is the prosecution; verification is the defence. The designer builds the case that the block works. The verifier's job is not to agree — it is to attack, to find the one input the designer's case cannot survive.
And, more precisely:
Design proves existence; verification proves absence. Design shows the block can do the right thing (here is an input, here is the correct output). Verification must show the block cannot do a wrong thing — across a space far too large to enumerate. Proving absence is a fundamentally harder, different kind of work, which is why it is a different discipline.
The builder is optimistic and asks "does it work?". The breaker is adversarial and asks "how do I make it fail?". A strong project needs both, and crucially needs them to be independent.
Visual Explanation — one specification, two independent interpretations
The specification is the shared contract. The designer implements one interpretation of it as RTL; the verifier independently re-derives the expected behaviour from the same spec and compares. Correctness is the agreement between two independent readings of one contract — not the design checking itself.
The two mindsets that walk those two paths are deliberately opposite:
RTL Perspective — where intent and implementation quietly diverge
Consider a 4-bit saturating counter. The specification is one sentence: count up but saturate at 15; count down but saturate at 0. The designer, focused on the word "saturate," writes this:
// Spec: 4-bit saturating counter.
// inc & !dec → count up, but SATURATE at 15 (stay at 15).
// dec & !inc → count down, but SATURATE at 0 (stay at 0).
module sat_counter (
input logic clk,
input logic rst_n,
input logic inc,
input logic dec,
output logic [3:0] count
);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
count <= 4'd0;
end else if (inc && !dec) begin
if (count != 4'd15) // up path: carefully saturates ✓
count <= count + 4'd1;
end else if (dec && !inc) begin
count <= count - 4'd1; // down path: NO floor guard → underflow wraps 0 → 15
end
end
endmoduleRead it as the designer would. The up path is handled with visible care — the count != 15 guard is exactly the "saturate at 15" the designer was thinking about. The down path looks symmetric and fine. But it is missing the mirror guard: decrementing at count == 0 underflows and wraps to 15. The spec said "saturate at 0"; the implementation does not. The bug is not carelessness — it is a gap between the designer's attention and the specification's full meaning.
Simulation Perspective — two tests, asking two different questions
Here are the two tests that get written. They look similar and are profoundly different.
// Built from the designer's mental model: "I saturate at 15."
foreach (i) pulse(inc); // climb to 15
repeat (3) pulse(inc); // keep incrementing
assert (count == 4'd15) // it stays at 15 → PASS, every time
else $error("up-saturation broke");
$display("DESIGNER SELF-TEST PASSED");// Built from the SPEC, by someone who did not write the RTL:
// model[t] = saturate(model[t-1] ± 1, 0, 15)
drive_random(inc, dec); // includes dec while count == 0
assert (count == spec_model.expected()) // catches the underflow wrap
else $error("spec mismatch: got %0d expected %0d", count, spec_model.expected());The self-test exercises the one behaviour the designer implemented carefully, and it passes forever. The independent check derives expected from the spec — including the dec-at-zero case the designer never imagined — and it fails the instant that corner appears. Same block, same spec, opposite outcomes — because of who wrote the checker and what they derived it from.
Waveform Perspective — the moment intent and spec part ways
Watch the actual counter against the spec-derived expectation as the FIFO is driven down past zero.
Saturating counter — actual RTL vs spec-expected, decrementing through zero
10 cyclesThe count lane is what the design does; the spec lane is what the contract demands. They are identical right up to the corner the designer did not think about — and then they diverge. The entire value of an independent verifier is the spec lane: a second interpretation of the contract that the design cannot quietly bend to match itself.
Verification Perspective — independence is the discipline
Everything above reduces to one principle: verification only has value to the extent that it is independent of the design. Independence is engineered along several axes, and a real methodology (UVM) exists to make each one reusable:
- Independent person — a verifier who did not write the RTL and does not share its blind spots.
- Independent interpretation — expected behaviour derived from the specification, not read back from the design (a reference model or scoreboard, never "whatever the RTL does").
- Independent stimulus — adversarial, constrained-random traffic that reaches corners no author would politely create (the previous lesson's theme).
- Independent measurement — coverage that reports what was actually exercised, so "it passed" is backed by "and here is how much we attacked it."
When those four are in place, the design can no longer grade its own homework. The verifier's reference model says 0, the silicon says 15, and the contradiction is surfaced before tape-out. That is verification — and it is why, on a real project, design and verification are different jobs done by different people, often in different teams.
Industry Usage — two roles, by design
This separation is not a preference; it is how the industry is organised. Design engineers and design-verification (DV) engineers are distinct career tracks with distinct skill sets, distinct tools, and distinct review gates. On most SoC programmes the DV team is the larger of the two, and the question that gates tape-out — "is it verified?" — is owned by verification, not design. IP vendors ship verification IP (VIP) built by independent verification teams precisely so an integrator gets an adversary for the design, not a second copy of the designer's assumptions. The independence is structural, all the way up to the org chart.
A blunt industry heuristic: never let a block be signed off solely by the person who designed it. The reviewer, the verifier, and the designer are separated for the same reason auditors do not audit their own accounts — not because anyone is untrustworthy, but because self-checking cannot, even in principle, find the errors baked into one's own assumptions.
Design Review Notes — what a senior engineer will press you on
Debugging Guide — "it passed the designer's tests, then failed in the lab"
The counter that passed self-test and underflowed in silicon
The sat_counter passed the designer's full directed self-test and shipped inside a credit-tracking block. In the lab, under sustained back-pressure (long runs of dec with the count already drained), the credit counter occasionally jumped to its maximum, briefly unblocking traffic that should have stayed blocked — a rare, throughput-dependent glitch that never appeared in simulation.
The down path has no floor guard:
end else if (dec && !inc) begin
count <= count - 4'd1; // BUG: at count==0 this underflows 0 → 15
end // spec: "saturate at 0"; should guard with `if (count != 0)`The designer implemented the up saturation they were focused on and assumed the down path was symmetric. The self-test, written from the same focus, only ever checked up-saturation — so the dec-at-zero behaviour was never exercised, and the gap between "saturate at 0" (spec) and "wrap to 15" (RTL) never surfaced.
Bring in an independent check derived from the spec, then look at coverage:
ref_model (from spec): … 1, 0, 0, 0, … // saturates at 0
dut (from RTL): … 1, 0, 15, 14, … // underflows
^ first mismatch — flagged at the exact cycle
covergroup cnt_cg
cross dec x (count == 0)
bin {dec=1, count=0} : 0 hits // dec-at-zero NEVER exercised by the self-testThe diagnosis is methodological, not micro-architectural: the design was checked against itself, so a whole legal behaviour (dec at 0) was never tested and a zero-hit coverage bin marked the hole. The mismatch is obvious the instant an independent model says what the spec wants.
Build the independence in from the start:
- Separate verifier, spec-derived expected. A reference model written from the specification — by someone other than the designer — would have computed
0and contradicted the15. - Constrained-random stimulus that freely drives
decwhilecount == 0, reaching the corner a focused author skips. - A spec assertion stating the contract directly:
assert property (@(posedge clk) disable iff (!rst_n) (dec && !inc && count == 0) |=> count == 0);— it fires the moment the RTL bends the spec, independent of any test the designer wrote.
The lesson of the lab failure is the lesson of this module: a design checked only by its author is unchecked. Verification is the discipline of checking it from the outside.
Interview Insights — what strong answers sound like
Because they are opposite cognitive stances applied to the same artifact. Design builds behaviour and asks "does it work?"; verification proves behaviour cannot go wrong and asks "how do I make it fail?" More importantly, they must be independent: the RTL and a self-test share one mental model and therefore one set of blind spots, so a designer cannot, even in principle, find the bugs rooted in their own assumptions. Splitting the roles keeps an adversarial, spec-derived perspective alive that self-checking structurally cannot provide.
Exercises — build the judgment, not the recall
- Find the shared blind spot. You are handed an RTL block and the designer's self-test, both written by the same engineer. Without running anything, explain why the test passing tells you very little — and state the single change to where expected values come from that would make the test meaningful.
- Re-derive from the spec. For the saturating counter in this lesson, write (in words or pseudocode) the reference model a verifier would build from the specification alone. Show how it produces
0where the RTL produces15, and why it would have caught the bug regardless of which directed cases were chosen. - Spot the non-independent scoreboard. A teammate's scoreboard stores
expected = dut.countat each cycle and later comparesdut.count == expected. Explain in one sentence why this scoreboard can never fail on a real design bug, and what it must do instead. - Mindset audit. List three concrete habits that distinguish a "breaker" verification engineer from a "builder" who is reluctantly testing — and for each, name the kind of bug it is designed to catch.
Summary
- The question "who checks the design?" has one correct answer: someone, and something, independent of it. A designer checking their own block tests their intent, not the specification — and the escaping bugs live in the gap between the two.
- Design and verification are opposite disciplines: the builder makes behaviour happen and proves a capability exists; the breaker proves misbehaviour is absent, adversarially and from the spec. One mind cannot reliably hold both, which is why the roles — and often the teams — are separate.
- Verification's value is independence, engineered along four axes: independent person, independent (spec-derived) interpretation, independent stimulus, and independent measurement. The cardinal sin is sourcing "expected" from the design itself.
- The durable rule of thumb: a design checked only by its author is unchecked. Confidence comes from a failed attempt to break it, never from a passed attempt to confirm it.
- UVM is the machinery that makes the independent side reusable — the drivers, monitors, scoreboards, and coverage that build a powerful adversary once and reuse it everywhere. You now understand the discipline it serves.
Next — The Cost of Verification: independence is not free. We quantify what verification actually costs — in engineers, schedule, and compute — and why, despite that cost, skipping it is the most expensive choice a chip project can make.