Production RTL is read more often than it is written. Stable naming, one process per state group, clean lint results, and narrow waivers keep reviews short.
3 lessons, about 13 min
Fix each root cause first, in the RTL. A waiver is only for behavior that is intentional and reviewed, with an owner and an expiry.
The whole topic on one page, taken from each lesson's Remember box. Read it before an interview, or print it.
Style conventions that reduce review friction
Direction, polarity and role live in the suffix: req_i, grant_o, rst_ni, state_q, state_d.
Use one always_ff per clock and reset domain.
In the always_comb block, give every output a default before the case so no input combination leaves one unassigned.
Rule of thumb: one process says what happens next, the other says when it is stored.
Lint, RDC, and waiver policy
Lint reads the RTL as written; RDC also reads clock and reset intent.
A source reset can change data under a live receiver. Coordinate resets, isolate before reset, or synchronise a single-bit level.
Fix first, then waive. A waiver without the fix hides the next instance.
Rule of thumb: a reset-release synchroniser alone is not RDC signoff.
Waiver rules that scale
A waiver records an intentional exception; a missing field means the entry is a guess.
Waive the site, never the rule: scope to the instance or signal, one entry per site.
A rising waiver count per rule means the style is drifting.
Rule of thumb: refuse a waiver when the RTL fix is cheap, the scope is wider than the site, or no expiry is given.
Mini project: a reusable FIFO IP with package, interface, assertions and a formal check
Practice question: Debugging metastability from asynchronous reset deassertion
Interview: run a mock interview on this topic
The benches here are finite digital checks, not lint/RDC or physical signoff results. Executed with Icarus Verilog 13.0 (2026-10-16): each prints PASS.