Part 4 · Assertions (SVA) · Intermediate
Assertion Debug & Methodology
Hub — debugging failures and false passes, vacuity audits, performance and noise control, assertion placement, and the senior review checklist.
Writing assertions is half the job
The other half is living with them: decoding a failure message into a root cause, noticing that a green assertion suite is actually checking nothing, keeping ten thousand assertions from drowning a regression in noise, and deciding where assertions belong so they survive the next project. This topic is the methodology layer — the difference between someone who can write an assertion in an interview and someone a team trusts to own the assertion strategy for a block.
The recurring villain throughout is preponed sampling : assertions evaluate values captured just before the clock edge, while your waveform cursor shows values after it. Nearly every "the assertion is wrong, the waveform proves it" debug session ends with this one fact. The second villain is vacuity : an implication whose antecedent never fired passes forever while verifying nothing. Both have systematic cures, covered here.
Sub-topics
Debugging Assertion Failures — reading failure messages, attempt start vs fail time, the waveform off-by-one, $sampled in action blocks.
When Passing Is the Bug — vacuity audits, cover-first methodology, assertion density review.
Assertion Performance & Noise Control — attempt explosion, unbounded ranges, severity discipline, readable regressions.
Where Assertions Live — inline RTL vs interface vs bind, ownership, synthesis guards, formal/sim reuse.
The Assertion Review Checklist — the consolidated senior checklist plus a worked review of a flawed module.
Legend: [FAIL] [PASS] [PERF] [ARCH] [REVIEW]
┌────────────────────────────────────────────────────────────────────────┐
│ ASSERTION DEBUG & METHODOLOGY — topic map │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ assertion FIRED ──────────────► 1. DEBUGGING FAILURES [FAIL] │
│ "is the RTL wrong attempt start vs fail time │
│ or my assertion?" preponed vs waveform off-by-one │
│ $sampled printing │ thread views │
│ │
│ assertion SILENT ─────────────► 2. VACUITY & COVERAGE [PASS] │
│ "is it passing or vacuous pass audit │ cover-first │
│ just never trying?" cover on antecedents │ density review │
│ │
│ regression SLOW/NOISY ────────► 3. PERFORMANCE & NOISE [PERF] │
│ attempt explosion │ $assertoff phases │
│ $error vs $fatal │ rate limiting │
│ │
│ where do they GO? ────────────► 4. PLACEMENT [ARCH] │
│ RTL vs interface vs bind │ ownership │
│ synthesis guards │ formal reuse │
│ │
│ sign-off ─────────────────────► 5. REVIEW CHECKLIST [REVIEW] │
│ 6-point checklist │ worked bad-module │
│ review (find the 6 problems) │
│ │
└────────────────────────────────────────────────────────────────────────┘Key takeaways
Assertion debug starts from two timestamps: attempt start time and fail time — the protocol window lives between them.
The waveform shows post-edge values; the assertion saw pre-edge (preponed) values — expect a one-cycle disagreement.
A passing assertion suite proves nothing until vacuity and cover data say the checks actually attempted.
Placement (RTL vs interface vs bind) is an ownership and reuse decision, not a style preference.
Senior engineers review assertions with a checklist — every assert needs a cover, a reset gate, and a precise antecedent.