Skip to main content

The CDV Loop

Every generator, driver, monitor, and scoreboard built across Testbench and UVM exists to run one specific, named methodology: coverage-driven verification (CDV). This page names the loop directly — not how to randomize (already covered) or how to write a covergroup (already covered), but the iterative process those tools serve, and the question every real verification effort eventually has to answer: when do you stop?

The loop itself​

Randomize and Simulate leads to Measure Coverage leads to Analyze Holes leads to Refine, which loops back to Randomize and Simulate; repeat until signoff targets met

  • Randomize & simulate — a test suite, typically a mix of directed and constrained-random tests, runs against the current RTL. Random tests run with multiple seeds deliberately, since different seeds explore different corners of the input space — a single seed is one sample from a much larger distribution. There's no fixed universal number, but block-level regressions commonly run somewhere in the range of 10–50 seeds per test to get reasonable coverage of that distribution without an unbounded compute bill.
  • Measure — every run feeds a shared coverage database, tracked across three primary metrics: code coverage and FSM coverage (both covered next, structural and tool-generated) and functional coverage (already covered in SystemVerilog, user-defined and semantic).
  • Analyze — even after heavy random testing, real gaps remain, for reasons worth distinguishing rather than assuming they're all the same problem: a feature genuinely unimplemented or disabled in this configuration, a scenario the verification plan simply forgot to name, or a scenario that's legal but statistically rare enough that random stimulus alone rarely lands on it. Coverage data can also reveal a fourth, distinct cause worth naming separately: randomization bias — the generator's own constraints skew its output distribution (e.g. a dist weight or a subtle ordering in a constraint block that quietly favors certain legal values over others), so a bin sits empty not because the scenario is rare by nature, but because the generator itself was never really going to produce it in reasonable volume. The fix for this is different from the fix for genuine rarity: rebalancing the generator's distribution, not just running more seeds.
  • Refine — once a gap's cause is understood, the preferred fix is tightening constraint distributions so random stimulus is more likely to land there — a directed test that hits the exact scenario once is a much more brittle fix than a constraint change that keeps hitting it (and its neighbors) on every future regression run.

Why this loop, not a one-shot checklist​

A directed test suite is written once and, beyond bug fixes, mostly stays fixed. The CDV loop is different in kind: coverage results from this iteration directly decide what gets generated in the next one. That feedback loop — not constrained-random generation alone, not functional coverage alone — is what "coverage-driven" actually names. Randomizing stimulus without measuring what it covers is just random testing; measuring coverage without feeding gaps back into stimulus generation is just a report nobody acts on.

What's next​

The next two pages go deep on the "measure" step's structural half — code coverage, the metric a tool generates automatically with no test-writer input at all — before the following two pages return to functional coverage's judgment calls and the closure question this loop's "repeat until signoff targets met" line has been quietly deferring.