Skip to content

UVM

Case Study — A Protocol Verification Project

Turn the reusable testbench into a shippable verification campaign — a risk-based verification plan, a regression run nightly with managed seeds and triage, a coverage-closure loop that drives new tests, and a multi-criteria sign-off — plus the flaky-regression bug that silently ships a real failure.

Industry Case Studies · Module 30 · Page 30.6

The Engineering Problem

You built reusable agents and composed them into an SoC environment. That is the machine. A verification project is the campaign you run with that machine to actually prove a design correct and ship it: a plan that says what to verify and where the risk is, a regression you run continuously with managed seeds and triage, a coverage-closure loop that turns "we ran a lot of tests" into "we exercised what matters," and a sign-off decision that says it is safe to tape out. The testbench is necessary but not sufficient — a perfect environment run without a plan, a regression, and closure proves nothing in particular.

This case study turns the methodology into a campaign. A verification plan enumerates the features and interfaces and ranks them by risk, deriving coverage goals and tests. The testbench is the SoC environment you already built. A regression runs the test suite nightly across many seeds, with stable pass/fail, seed management, and disciplined triage of every failure. Coverage closure is the loop: run, merge, analyze holes, write targeted stimulus, repeat until the meaningful coverage is closed. Sign-off is the multi-criteria judgment — coverage closed, checks clean, regression stable, bug rate flattened — with the courage to withhold it. The one campaign-level mistake that ships bugs: treating a flaky test as noise instead of an unsolved bug.

How do you turn a reusable testbench into a shippable verification campaign — a risk-based plan, a regression run continuously with managed seeds and triage, a coverage-closure loop that drives new tests, and a multi-criteria sign-off — so the project proves the design correct, not just exercises it?

Motivation — why the campaign, not the testbench, ships the chip

A great environment is wasted without the campaign around it:

  • A testbench proves nothing without a plan. Running tests at random exercises something, but the plan is what guarantees the high-risk features are verified to depth — without it, effort scatters and the dangerous blocks are under-verified.
  • Verification is continuous, not a one-shot. A design changes daily, so the regression is the standing safety net that catches every regression the moment it lands — a one-time run is stale by morning.
  • Coverage is what makes "done" measurable. Constrained-random finds bugs by volume, but coverage is what tells you what you actually reached and turns an open-ended run into a closable effort with a defensible end.
  • Sign-off is the decision the whole campaign exists to inform. The plan, regression, and closure all feed one judgment — is it safe to ship — and the campaign's value is making that call on evidence rather than hope.

The motivation, in one line: the testbench is the machine, but the project — plan, regression, coverage closure, sign-off — is what turns the machine into proof that the design is correct and safe to ship, which is the actual deliverable of verification.

Mental Model

Hold a verification project as certifying an aircraft through a planned flight-test campaign, not one demonstration flight:

You do not certify a new aircraft by flying it once and declaring it safe. You run a flight-test campaign, and the campaign is a discipline, not a stunt. First you write a test plan: the flight envelope is mapped, and every region — stalls, maximum speed, engine-out, icing, crosswind landings — is enumerated and ranked by risk, so the dangerous and novel regimes get the most flights and the routine ones get fewer. Then you fly continuously, the same core tests repeated as the aircraft is modified, because a change to fix one thing can break another, and you need to know the day it happens. Every flight is instrumented and logged, and crucially, when an anomaly appears — a vibration, an intermittent reading — you do not shrug it off as a quirk and fly again; you ground the aircraft and chase it to root cause, because an intermittent anomaly in test is an intermittent failure in service, and the ones that get waved away are the ones that come back as accidents. You track coverage of the envelope: which regions have been flown and which remain, so you can see the holes and fly them deliberately rather than assuming the envelope is covered. And finally there is certification: an authority signs off only when the evidence converges — the envelope flown, the anomalies resolved, the data clean — and a responsible authority withholds the signature when it does not, even under schedule pressure to deliver, because certifying an unsafe aircraft is the one mistake that cannot be undone. The aircraft is the machine; the certification campaign is what proves it is safe to fly. You do not certify an aircraft by flying it once. You run a flight-test campaign — a discipline, not a stunt. You write a test plan (the envelope mapped, regions ranked by risk). You fly continuously (the same tests repeated as the aircraft changes). Every anomaly — a vibration, an intermittent reading — you chase to root cause, not wave away, because an intermittent anomaly in test is an intermittent failure in service. You track coverage of the envelope (which regions flown, which holes remain). And certification signs off only when the evidence converges — withheld when it does not, even under schedule pressure.

So running a verification project is running the certification campaign: the testbench is the aircraft, the verification plan maps and ranks the envelope, the regression is the continuous flying, coverage closure is tracking and filling the envelope, and sign-off is certification on converged evidence. The accident you must prevent is the anomaly waved away — the flaky test suppressed instead of chased — because that intermittent failure ships.

The Verification Campaign in One Figure

A verification project is a loop, not a line: plan, build, run the regression, measure coverage, close holes, and sign off — iterating until the evidence converges.

The verification campaign loop: plan, regression, triage and coverage analysis, close holes, sign-offPlan → regression → triage + coverage → close holes → sign-offPlan → regression → triage + coverage → close holes → sign-off1Verification planenumerate features, rank by risk, derive coverage goals + tests.2Regressionrun the suite nightly across many seeds; stable pass/fail, managedseeds.3Triage + coverageroot-cause every failure; merge + analyze coverage for holes.4Close holesbias constraints / add directed tests at real holes; feed back intothe suite.5Sign-offcoverage closed + checks clean + stable regression + flat bug rate→ tape-out.
Figure 1 — the verification campaign. From the spec, the verification plan enumerates features and ranks them by risk, deriving coverage goals and tests. The testbench (the reusable SoC env) runs the test suite as a regression, nightly across many seeds. Results feed two tracks: failures go to triage (every one root-caused, never retried away), and coverage is merged and analyzed for holes. Holes drive new or adjusted stimulus, which feeds back into the suite. This loop repeats until coverage closes and the bug rate flattens, at which point sign-off — a convergence of evidence — gates tape-out. The campaign is iterative; the testbench is just one box in it.

The figure is the campaign as a loop. The plan (1) turns the spec into a ranked list of what to verify and the coverage and tests to do it. The regression (2) runs the suite — the reusable testbench is one box here, not the whole project. Results split (3): failures go to triage, where every one is root-caused, and coverage is merged and analyzed for holes. The holes (4) drive new or adjusted stimulus that feeds back into the suite. This repeats until sign-off (5), the convergence of evidence that gates tape-out. The campaign is the loop; the rest of this chapter is each box.

The Verification Plan

The plan turns the spec into a ranked list of what to verify, with coverage goals and tests, spending effort by risk.

The verification plan: risk-ranked features deriving coverage goals, checks, and testsFeature + interface list (from spec)every function and interface enumerated — the scope of what must be verifiedevery function and interface enumerated — the scope of what must be verifiedRisk rankingscore each by complexity, novelty, change, and cost-of-escape; effort follows riskscore each by complexity, novelty, change, and cost-of-escape; effort follows riskCoverage goalsthe covergroups that define what 'exercised' means for each featurethe covergroups that define what 'exercised' means for each featureChecksassertions for local protocol, scoreboards for end-to-end correctnessassertions for local protocol, scoreboards for end-to-end correctnessTestsdirected for specific corners, constrained-random for breadthdirected for specific corners, constrained-random for breadth
Figure 2 — the verification plan as a risk-ranked feature list. Each feature and interface from the spec is scored by risk — complexity, novelty, how much it changed from a proven design, and the cost of an escape — and the highest-risk items (a new coherence engine, a complex arbiter) get the deepest verification while low-risk reused blocks get a lighter pass. From the ranking come the coverage goals (the covergroups that define 'exercised'), the checks (assertions and scoreboards), and the tests (directed for corners, constrained-random for breadth). The plan is the contract for what 'verified' means and where the effort goes.

The plan is the campaign's contract. It starts from the feature and interface list — everything the design does, enumerated from the spec, so the scope is explicit. Each item is risk-ranked by complexity, novelty, how much it changed from a proven prior design, and the cost of a bug escaping there — and effort follows that ranking, the high-risk items verified to depth and the low-risk reused blocks given a lighter, documented pass. From the ranking the plan derives coverage goals (the covergroups that define "exercised" for each feature), checks (assertions for local protocol, scoreboards for end-to-end correctness), and tests (directed for specific corners, constrained-random for breadth). The plan is what makes "verified" mean something concrete and spends the finite budget where it buys down the most risk.

The Regression and Its Disciplines

The regression runs the suite continuously, and its value depends on three disciplines: stable pass/fail, managed seeds, and disciplined triage.

The regression runs the whole test suite — typically nightly and on every significant change — across many random seeds, because one seed exercises one path and the real coverage is the union across seeds. Three disciplines make it trustworthy rather than theater:

  • Stable pass/fail. A test that passes some nights and fails others is flaky, and a flaky test is an unsolved bug, not noise — either a real intermittent DUT bug or a testbench race. Flakes are root-caused, never suppressed, because a suppressed flake hides a real failure (the DebugLab).
  • Managed seeds. The regression records each run's seed and enough state to replay a failure deterministically; a failure you cannot reproduce you cannot debug, so seed capture is non-negotiable.
  • Disciplined triage. Every failure is root-caused and classified — real DUT bug, testbench bug, or environment issue — not retried until it passes. Triage is where the regression's signal is actually extracted; a regression nobody triages is just burned compute.

A regression with these disciplines is a standing safety net that catches every regression the day it lands; without them it is green theater that hides bugs.

Coverage Closure

Coverage closure is the loop that turns "we ran tests" into "we exercised what matters": run, merge, analyze holes, drive stimulus at the real ones, repeat.

The coverage closure loop: run, merge coverage, analyze holes, drive stimulus, repeat to closureRun → merge → analyze holes → drive stimulus → repeatRun → merge → analyze holes → drive stimulus → repeat1Run + mergerun the regression across seeds; merge all coverage into onedatabase (the union).2Analyze holestriage unhit bins: real reachable, unreachable (exclude), orrare-but-reachable.3Drive stimulusbias constraints at real holes; directed test for stubborn corners.4Repeat to closurererun + remerge until meaningful coverage closes, holes justified,bug rate flat.
Figure 3 — the coverage-closure loop. Run the regression and merge the coverage from all seeds and tests into one database — the union is the real picture. Analyze the merged result for holes (unhit bins) and triage them: real reachable holes are scenarios that matter; unreachable bins are excluded as ignore/illegal, refining the model; rare-but-reachable holes need targeted stimulus. For the real holes, drive stimulus — bias the constrained-random constraints toward the uncovered region, or write a directed test for a stubborn corner — then rerun and remerge. Repeat until meaningful coverage closes with remaining holes justified. Lean on random for breadth, reserve directed for what random cannot reach economically.

Closure is iterative. Run and merge (1): the real coverage is the union across all seeds and tests, so you merge every run into one database — a single seed's coverage is not the picture. Analyze holes (2): read the merged result for unhit bins and triage them — real reachable holes are scenarios that matter, unreachable bins are excluded as ignore/illegal (refining the model, not hiding the gap), and rare-but-reachable holes need targeted help. Drive stimulus (3): for the real holes, bias the constrained-random constraints toward the uncovered region, or write a directed test for a corner random will not reach economically. Repeat (4) until the meaningful coverage closes with remaining holes justified and the bug rate flat. The strategy is random for breadth, directed for the stubborn tail — and the discipline is that an excluded hole is justified as unreachable, never just ignored, because a reachable hole wrongly excluded is an untested scenario where a bug hides.

Sign-off

Sign-off is the campaign's purpose: the multi-criteria judgment that the evidence has converged, with the courage to withhold it when it has not.

Sign-off is not one number; it is a convergence of evidence: functional coverage closed with holes justified, assertions and lint and clock-domain-crossing checks clean, the regression green and stable across seeds, the bug-discovery rate flattened over time, and the design, testbench, and coverage reviews complete. No single criterion suffices — coverage at 100% with a daily bug means the design is unstable; a flat bug rate at 70% coverage means scenarios are untested; a clean run on one seed is not stable. The senior act is the courage to say not ready when the evidence does not converge, even under schedule pressure, because the asymmetry is brutal: shipping a bug into silicon costs a respin or a field return, while a slip costs days. Sign-off is where the whole campaign — plan, regression, closure — pays off as a defensible decision, and where verification's ownership of the outcome is tested most.

DebugLab — the green regression that shipped a bug

The regression was green for weeks, then the bug showed up in silicon — a flaky test had been suppressed

Symptom

The regression was green for weeks and the design was signed off. Then the bug appeared in silicon — an intermittent data-corruption under a specific back-pressure condition. Reviewing the history, the failure had been seen in simulation: a single test had failed intermittently months earlier, roughly one run in fifty, and had been marked "known flaky" and filtered out of the regression's pass/fail. The regression had been green only because that test's failures were being suppressed.

Root cause

A test that failed intermittently was suppressed as flaky instead of being root-caused — and the intermittent failure was a real DUT bug, not testbench noise:

how the bug got suppressed
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
observed:   one test fails ~1 run in 50, intermittently
action:     marked "known flaky" → filtered from regression pass/fail ✗
assumption: intermittent failure = testbench noise, safe to ignore
reality:    the failure was a real intermittent DUT bug (a back-pressure corner)
result:     regression green for weeks → signed off → bug escapes to silicon
fix:        treat every flake as an UNSOLVED BUG → capture the seed, reproduce,
            root-cause to DUT-vs-testbench before ever suppressing

The fatal step was the assumption that an intermittent failure is noise. A flaky test is, by definition, a failure that is not understood — and an un-understood failure can be a real intermittent DUT bug just as easily as a testbench race. Suppressing it without root cause did not make the bug go away; it hid the one signal that was catching it. The captured seed from one of those failures, replayed, would have reproduced the silicon bug in simulation months before tape-out. The regression's greenness was manufactured by filtering out the very test that worked.

Diagnosis

The tell is a "known flaky" test masking a real failure. Localize it in the regression's triage discipline:

  1. Audit every suppressed or "known flaky" test. Each one is an unsolved failure; confirm it was root-caused to a testbench cause before suppression, not assumed to be noise.
  2. Reproduce the flake from its seed. A captured seed replayed deterministically tells you whether the failure is in the DUT or the testbench — the question suppression skipped.
  3. Correlate the silicon bug to suppressed history. A silicon failure that matches an earlier intermittent simulation failure confirms the suppressed test was real.
Prevention

Treat the regression's stability as sacred:

  1. Root-cause every flake; never suppress on assumption. A flaky test is an unsolved bug until proven a testbench race; capture its seed, reproduce, and classify DUT-versus-testbench before any suppression.
  2. Make the regression's pass/fail honest. No test is filtered from sign-off without a documented root cause; a green regression must mean every test passed, not every test we did not mute.
  3. Track and gate on flake rate. A rising flake rate is an unsolved-bug backlog; treat it as a sign-off blocker, not a maintenance nuisance.

The one-sentence lesson: a flaky test is an unsolved bug, not noise — suppress it without root cause and you may be muting the one test catching a real intermittent DUT failure, manufacturing a green regression that ships the bug to silicon.

Common Mistakes

  • Suppressing a flaky test as noise. A flake is an unsolved bug; suppressing it without root cause can mute a real intermittent DUT failure — the DebugLab.
  • Running the testbench without a plan. Random tests with no risk-ranked plan under-verify the high-risk features; effort must follow risk.
  • Mistaking "tests ran" for "coverage closed." Volume is not closure; merge coverage and analyze holes, or you do not know what you exercised.
  • Excluding a reachable coverage hole. An ignored hole that is actually reachable is an untested scenario; exclusions must be justified as unreachable, not used to hit a number.
  • Signing off on one criterion. Coverage alone, or a green run on one seed, is not sign-off; it is the convergence of coverage, clean checks, a stable regression, and a flat bug rate.
  • Not capturing seeds. A failure you cannot reproduce you cannot debug; the regression must record seeds and replay state.

Senior Design Review Notes

Interview Insights

A verification project is the campaign run with the testbench — a risk-based plan, a continuous regression with triage, a coverage-closure loop, and a sign-off decision — whereas the testbench is just the machine those activities use. The testbench, however good, only exercises the design; it does not by itself prove anything in particular or decide when verification is done. The project wraps it in process. First a verification plan enumerates the features and interfaces and ranks them by risk, deriving the coverage goals, checks, and tests, so effort goes where bugs are most likely and most costly. Then the testbench runs as a regression, continuously and across many seeds, because the design changes daily and a single run is stale by morning. The regression's results feed triage, where every failure is root-caused, and coverage analysis, where holes are found. Coverage closure is the loop that drives new stimulus at the real holes until meaningful coverage closes. And sign-off is the decision the whole campaign exists to inform: a convergence of evidence that the design is safe to ship. So the difference is that the testbench is the machine and the project is the disciplined campaign — plan, regression, closure, sign-off — that turns exercising the design into proving it correct. The understanding to convey is testbench-as-machine versus project-as-campaign, and that the campaign's process is what produces the actual deliverable, a defensible decision that the design is verified.

You enumerate the design's features and interfaces from the spec, score each for risk by complexity, novelty, how much it changed from a proven design, and the cost of an escape, and allocate verification effort by that ranking, deriving coverage goals, checks, and tests for each. The plan starts as a complete list of what the design does, so the scope is explicit and nothing is silently skipped. Then each item is risk-ranked: a brand-new, complex block that has never been built at this scale and whose bug would be catastrophic scores high; a simple, well-understood block reused unchanged from a proven prior project scores low. Effort follows the ranking — the high-risk items get the deepest verification, the most directed corners and the tightest coverage, while the low-risk reused blocks get a lighter, documented pass. From each item the plan derives concrete deliverables: the coverage goals that define what exercised means, the assertions and scoreboards that check it, and the directed and constrained-random tests that drive it. The plan is the contract for what verified means and where the budget goes, and it is what guarantees the dangerous features are verified to depth rather than effort scattering evenly. Under schedule pressure, the plan is also the triage tool: when time runs short, you protect the high-risk items and take documented reductions on the low-risk ones. The understanding to convey is enumerate-rank-by-risk-derive-deliverables, and that risk-based allocation is what spends a finite budget where it buys down the most risk.

A flaky test is dangerous because it is a failure you do not understand, and an un-understood intermittent failure can be a real intermittent DUT bug just as easily as a testbench race — so suppressing it as noise can mute the one test catching a real bug, manufacturing a green regression that ships the failure. The temptation is to mark an occasionally-failing test as known flaky and filter it from the regression's pass/fail so the regression goes green. But that does not fix anything; it hides the signal. If the underlying failure is a real intermittent DUT bug — say a corruption under a rare back-pressure condition — suppressing the test removes the only thing detecting it, and the bug escapes to silicon while the regression looks clean. What you should do is treat every flake as an unsolved bug: capture the seed from a failing run, reproduce the failure deterministically, and root-cause it to either the DUT or the testbench before doing anything else. If it is a testbench race, fix the testbench. If it is a DUT bug, it is a real find. Only after root cause, and only if it is genuinely a benign testbench issue being fixed, is any suppression justified, and even then with documentation. The discipline is that a green regression must mean every test passed, not every test we did not mute. The understanding to convey is that a flake is an unsolved bug, the danger of suppressing a real failure, and the capture-reproduce-root-cause response — which is exactly the discipline that keeps a regression honest.

Coverage closure is an iterative loop: run the regression across many seeds, merge all the coverage into one database, analyze the merged result for holes, triage those holes, drive targeted stimulus at the real ones, and repeat until the meaningful coverage closes with remaining holes justified. The merge is essential because a single seed or test hits only some coverage; the real picture is the union across the whole regression, so you merge every run into one database. Then you analyze that merged database for holes — unhit bins — and triage them into three kinds: real reachable holes are scenarios that matter and must be hit; unreachable bins are excluded as ignore or illegal, which refines the model rather than hiding a gap; and rare-but-reachable holes need targeted help. For the real, reachable holes you drive stimulus: usually by biasing the constrained-random constraints toward the uncovered region, sometimes by adding seeds, and for a stubborn corner that random will not hit economically, by writing a directed test. Then you rerun, remerge, and check the holes closed and nothing regressed. The loop repeats until coverage reaches the target with the remaining holes justified as unreachable and the bug rate flat. The strategy throughout is constrained-random for breadth, directed for the stubborn tail. The crucial discipline is that an excluded hole must be justified as genuinely unreachable, never excluded just to hit a number, because a reachable hole wrongly excluded is an untested scenario where a bug hides. The understanding to convey is run-merge-analyze-drive-repeat with honest exclusion triage, which is how a campaign turns running tests into closing coverage.

Sign-off is a convergence of evidence rather than a single number: functional coverage closed with holes justified, assertions and lint and clock-domain-crossing checks clean, the regression green and stable across many seeds, the bug-discovery rate flattened over time, and the design, testbench, and coverage reviews complete — and the willingness to withhold the signature when these do not agree. No one criterion is sufficient. Coverage at a hundred percent with a bug found every day means the design is still unstable. A flat bug rate at seventy percent coverage means large parts were never exercised. A clean run on a single seed is not stable. So I look for the criteria converging: coverage reaching its target with the unhit bins triaged as genuinely unreachable and excluded; assertions passing, lint clean, CDC clean; the regression not just green but stable run after run across seeds, no unexplained flakes; the bug-discovery rate, tracked over the project, having flattened to near zero, which is the strongest empirical signal the design has stabilized; and the reviews done so a second set of eyes confirmed the plan was executed. The decision is that this evidence agrees, and the senior responsibility is the courage to say not ready when it does not, even under schedule pressure, because shipping a bug into silicon costs a respin or a field failure while slipping costs days. The understanding to convey is the multi-criteria convergence and the courage to withhold, which is the call the entire campaign exists to inform.

Exercises

  1. Rank the plan. For a chip with a new coherence engine and several reused peripheral blocks, sketch the risk ranking and how verification effort and coverage goals differ across them.
  2. Audit the regression. Given a green regression with three "known flaky" tests, describe what you would check before trusting the green, and why each flake is a potential masked bug.
  3. Close a hole. For a coverage hole in a high-risk feature, outline how you would decide whether it is real, unreachable, or rare, and how you would drive stimulus at it if real.
  4. Defend a sign-off. Write the evidence you would present to certify a block, and the specific conditions under which you would say not ready.
  5. Trace the escape. Explain how a suppressed flaky test could let an intermittent DUT bug reach silicon, and the discipline that prevents it.

Summary

  • A verification project is the campaign run with the testbench, not the testbench itself: a risk-based plan, a continuous regression, a coverage-closure loop, and a sign-off decision.
  • The plan enumerates features and ranks them by risk, deriving coverage goals, checks, and tests — so effort follows risk rather than scattering evenly.
  • The regression runs the suite continuously across many seeds, and its value rests on three disciplines: stable pass/fail (a flake is an unsolved bug), managed seeds (reproducible failures), and disciplined triage (every failure root-caused).
  • Coverage closure is the loop — run, merge, analyze holes, drive stimulus at the real ones, repeat — until meaningful coverage closes with exclusions justified as unreachable, leaning on random for breadth and directed for the tail.
  • Sign-off is a convergence of evidence — coverage closed, checks clean, regression stable, bug rate flat, reviews done — with the courage to withhold it; and the campaign-level bug that ships silicon is a flaky test suppressed instead of root-caused.
  • The durable rule of thumb: run verification as a campaign, not a testbench — plan by risk, regress continuously with honest triage, close coverage with justified exclusions, and sign off on converged evidence — because the deliverable is proof the design is correct, and the fastest way to ship a bug is a green regression manufactured by suppressing the test that was catching it.

Next — Architecture Checklist: the case studies built and ran the methodology; the final module condenses it into the sign-off checklists you actually run before a review. The first is the UVM architecture checklist — the concrete items to confirm in a testbench's structure, construction, configuration, and connectivity before you declare it sound.