UVM RAL · Chapter 10 · RAL Coverage
Coverage Analysis & Closure
Coverage closure is not a number to reach but a loop that drives verification: run the regression, measure coverage, analyze the holes, write targeted stimulus, and rerun until no real holes remain. The percentage is a byproduct of that loop, not the goal. The real skill is hole triage, because every unfilled bin is one of three things. A real hole means your stimulus never drove a reachable value, which you close with a targeted test. A legitimately unreachable value is one the design cannot produce, which you waive with justification. A measurement artifact is coverage never sampled or never enabled, which you fix in the collection, not the stimulus. The lesson ends with the most dangerous closure bug: forcing 100% by waiving a real, reachable hole as unreachable, so unverified functionality ships signed off as covered.
Foundation12 min readUVM RALcoverage closurehole triagewaiverexclusion
Chapter 10 · Section 10.5 · RAL Coverage
1. Why Should I Learn This?
Coverage only improves verification if you use it as a loop — measure, analyze holes, target stimulus, rerun — and if you triage holes honestly. The most damaging closure mistake is not a mechanism bug but an integrity one: waiving a real hole to hit 100%, which signs off unverified functionality behind a green number. Knowing the closure loop and how to classify every hole — real, unreachable, or measurement artifact — is what makes coverage closure mean 'verified' rather than 'the number says 100%.'
Learning coverage analysis and closure ties Chapter 10 together — enabling (10.1), interpreting (10.2), user-defined bins (10.3), and honest collection (10.4) all feed the loop and the triage that this closing section makes into a disciplined process.
2. Industry Story — 100% reached by waiving the bug
A team is one hole short of 100% coverage: a reserved-mode bin on a control field is unfilled, and the deadline is close. Someone reasons 'that value is probably not reachable in normal operation' and waives the bin as unreachable. Coverage hits 100%, the report is green, and the block is signed off.
The value was not unreachable — software could write that mode (it was reserved, not physically impossible), and the DUT had a bug in handling it. The waiver was a false claim: 'unreachable' was asserted to close the number, not because the value genuinely could not occur. So a reachable, unverified, buggy value was signed off as covered, and the green 100% report actively vouched for functionality that had never been tested. The bug shipped, behind a coverage number that said 'done.' Had the hole been triaged honestly — 'is this value truly unreachable, or just unhit?' — it would have been recognized as a real hole, closed with a targeted test, and the bug caught. The post-mortem lesson: a coverage waiver is a claim that a value is unreachable, and it must be true — waiving a reachable hole to force 100% signs off unverified functionality behind a green number and ships the bug it hides; every unfilled bin must be honestly triaged as a real hole (close it), a legitimately unreachable value (waive with justification), or a measurement artifact (fix collection), never waived merely to reach the number.
3. Concept — the closure loop and three-way hole triage
Coverage closure is a loop, and its core skill is classifying holes:
- The loop. Run regression -> measure coverage -> are there holes? -> if yes, write targeted stimulus for the real ones and rerun; if no, closed. The percentage is a byproduct of driving this loop, not the target.
- Hole triage — every unfilled bin is one of three things:
- (a) Real hole — stimulus never drove a reachable value. Action: write a targeted test to hit it. This is the productive loop.
- (b) Legitimately unreachable — a value the design cannot produce (illegal-by-construction, physically impossible). Action: waive/exclude with a justification that is true and auditable.
- (c) Measurement artifact — the bin is unfilled because coverage was never sampled (10.3), never enabled (10.1), or the number is inflated/misattributed (10.4). Action: fix the collection, not the stimulus.
- A waiver is an auditable claim. '(b) unreachable' asserts the value cannot occur. That claim must be true — reviewable against the spec/design. Waiving a real hole (a) as unreachable (b) to force 100% is the signature integrity failure: it signs off reachable, unverified functionality.
Here is the closure loop — the point is the feedback, not the percentage:
4. Mental Model — closure is a loop driven by honest triage, not a number to force
5. Working Example — triaging holes and closing the loop
Analyze each hole into its category and act accordingly — targeted test, justified waiver, or collection fix:
// Measure, then TRIAGE each unfilled bin into one of three categories. This is the analysis step.
// Hole 1: cp_mode.normal[3] unfilled -> is value 3 reachable? YES -> REAL HOLE -> targeted test.
// Hole 2: cp_mode.reserved unfilled -> is the reserved encoding reachable? (software CAN write it) -> REAL.
// Hole 3: cp_state.illegal unfilled -> can the FSM produce this state? NO (illegal by construction) -> WAIVE.
// Hole 4: ALL bins 0 -> not a stimulus issue -> MEASUREMENT ARTIFACT (never sampled, 10.3) -> fix wiring.// (a) REAL hole -> close it with TARGETED stimulus (the productive loop), then rerun:
class hit_reserved_mode_seq extends uvm_reg_sequence#(uvm_sequence#(uvm_reg_item));
virtual task body();
uvm_status_e s;
regs.ctrl.mode.set(3'b111); regs.ctrl.update(s); // drive the reserved value FUNCTIONALLY (10.4)
// ... and CHECK the DUT rejects it (coverage exercises; a check verifies, 10.2) ...
endtask
endclass// (b) LEGITIMATELY unreachable -> waive with a TRUE, auditable justification (reviewable against design):
// cp_state.illegal: the FSM encoding is illegal-by-construction (one-hot; this code cannot occur).
// -> excluded with justification 'FSM is one-hot; this multi-bit code is unreachable by construction'.
// A reviewer can CHECK this claim against the RTL. A waiver is only honest if the claim is TRUE.// (c) MEASUREMENT artifact -> fix the COLLECTION, not the stimulus:
// all-bins-0 -> sample() not wired (10.3) -> wire it;
// flat 0% -> coverage not enabled (10.1) -> include_coverage + set_coverage;
// inflated -> setup/backdoor filling bins (10.4) -> gate sampling to functional stimulus.Each hole is classified before it is acted on: real holes get tests, unreachable values get justified waivers, artifacts get collection fixes. The one thing you never do — waive a real hole to reach the number — is the bug of the next section.
6. Debugging Session — forcing 100% by waiving a real hole
Waiving a reachable coverage hole as 'unreachable' to force 100% signs off unverified functionality behind a green number, and ships the bug it hides
A WAIVER IS A CLAIM THAT MUST BE TRUE// One bin short of 100%: the reserved-mode value is unfilled. Instead of triaging it honestly,
// it is waived as 'unreachable' to hit the number:
// cp_mode.reserved: WAIVED as 'unreachable' -> coverage = 100% -> signed off.
// BUG: the reserved value IS reachable (software can write it); the waiver is a FALSE claim made to
// force the number. A real, unverified, BUGGY value is now signed off as 'covered'.Coverage reaches 100%, the report is green, and the block is signed off as fully covered. But a real bug — the DUT mishandles the reserved mode — escapes, because the value was waived rather than tested: no functional stimulus ever drove it and no check ever verified its handling. The green 100% actively vouches for the unverified functionality, so the escape is worse than a visible hole would have been — a hole would have flagged the gap, but the waiver certified it as done. The bug surfaces later (in silicon, when software writes the reserved mode), with the confounding cover story that coverage was 100% closed.
A coverage waiver is a claim — specifically the claim that a value is unreachable (category b), meaning the design cannot produce it. Here that claim was false: the reserved mode is reachable (software can write it; 'reserved' means should not, not cannot), so the unfilled bin was actually a real hole (category a) — stimulus simply never drove it. It was misclassified as unreachable and waived to force the number to 100%, rather than closed with a targeted test. So the process failed at the triage step: a real hole was relabeled unreachable because the goal had become the percentage instead of honest verification. The consequence is that reachable, unverified functionality — with a real bug behind it — was signed off as covered, and the green report certifies it, which is why the escape is especially dangerous: the coverage number, meant to reveal gaps, was made to conceal one. This is the closure-stage form of the wrongful-exclusion pattern (waiving a real bit-bash/map failure, 3.5/7.3) and the over-claim pattern (8.5): an exclusion or waiver is only honest if its underlying claim is true.
Reclassify the hole honestly: the reserved value is reachable, so it is a real hole — remove the waiver, write a targeted sequence to drive the reserved mode functionally (10.4), and add a check that the DUT handles/rejects it correctly (coverage exercises, a check verifies, 10.2), then rerun the loop. Reserve waivers strictly for values that are genuinely unreachable, with justifications that are true and auditable against the design. The rule the bug teaches: a coverage waiver is a claim that a value is unreachable, and it must be true; waiving a reachable hole to force 100% signs off unverified functionality behind a green number and ships the bug it hides — every hole must be honestly triaged (real -> test, unreachable -> justified waiver, artifact -> fix collection), never waived merely to reach the percentage. The tell in the wild: a waiver justified by 'probably not reachable' or 'needed to hit 100%' rather than a concrete design reason is a real hole in disguise — audit waivers as claims, because a forced 100% is more dangerous than an honest 95%.
7. Common Mistakes
- Chasing the percentage instead of running the loop. The number is a byproduct of measure-triage-target-rerun; making it the goal invites forcing it.
- Waiving a real hole as 'unreachable' to hit 100%. A waiver is a claim that must be true; a false one signs off unverified functionality (3.5, 7.3, 8.5).
- Not triaging holes into their three categories. A hole is real (test it), unreachable (justified waiver), or a measurement artifact (fix collection) — treating them alike misdirects the fix.
- Fixing stimulus for a measurement artifact. All-bins-0 or flat 0% is a collection problem (10.1/10.3), not a stimulus one — more tests will not help.
- Waivers without auditable justification. 'Probably not reachable' is not a justification; 'illegal by construction because …' is — and a reviewer must be able to check it.
8. Industry Best Practices
- Run coverage as a closure loop. Measure, triage holes, write targeted stimulus for real ones, rerun — let the percentage follow.
- Triage every hole into real / unreachable / artifact. Act per category: targeted test, justified waiver, or collection fix (10.1/10.3/10.4).
- Treat waivers as auditable claims. 'Unreachable' must be true and defensible against the design — review waivers as rigorously as code.
- Prefer an honest 95% to a forced 100%. A visible hole flags unverified work; a forced 100% certifies it as done — the honest lower number is safer.
- Pair covered values with checks. Closing a hole means the value is exercised and its behavior verified — coverage plus a check, not coverage alone (10.2).
9. Interview / Review Questions
10. Key Takeaways
- Coverage closure is a loop — run, measure, analyze holes, write targeted stimulus for the real ones, rerun — and the percentage is a byproduct of running it honestly, not the goal.
- Triage every hole into three categories: a real hole (stimulus never drove a reachable value -> write a targeted test), a legitimately unreachable value (design cannot produce it -> waive with a true, auditable justification), or a measurement artifact (not sampled 10.3 / not enabled 10.1 / inflated 10.4 -> fix the collection).
- A waiver is a claim that a value is unreachable — it must be true and reviewable against the design; 'probably not reachable' or 'needed to hit 100%' is a real hole in disguise.
- The signature closure bug is forcing 100% by waiving a real hole as 'unreachable' — it signs off reachable, unverified functionality behind a green number and ships the bug; a forced 100% is more dangerous than an honest 95% (3.5, 7.3, 8.5).
- Across Chapter 10, coverage means 'verified' only when it is enabled (10.1), read as reach not verification (10.2), has the critical bins required (10.3), is honestly attributed (10.4), and is closed by testing real holes, not waiving them (10.5) — and covered values are paired with checks.