A waiver records an intentional exception, not an ignored bug. Every entry carries the same five fields.
Field | What it records |
|---|---|
Rule ID | The exact rule being waived, so the waiver dies if the rule is renamed |
Scope | The narrowest site: one line, signal, or instance |
Rationale | Why the behavior is intentional and safe |
Owner | Who defends the waiver at review |
Expiry | When it is revisited: a date or a design change |
An entry missing any field is a guess. Review sends it back for the missing fact.
Waive the site, never the rule. A file-level waiver silences the rule for future edits too.
Scope to the instance or signal, so new violations still fail.
One entry per site, so each rationale is checked on its own facts.
Prefer inline waivers next to the code over central files when the tool allows both.
# Illustrative waiver file (not tool output). One entry per intentional site.
# rule | scope | rationale | owner | expiry
ASYNC-RST | rst_sync assert path | Reset must take effect without a running clock; release is synchronized | team-rtl | revisit if the reset tree changesWaiver changes ride the same review as functional changes. A new waiver needs the same evidence as new logic.
Track the count per rule over time. A rising count means the style is drifting, not that the tool is noisy.
Scope: the waiver covers more code than reviewed, so later violations hide inside it. Expiry rots next: nobody revisits it.
The team is waiving a style habit instead of fixing it. The fix belongs in the shared template or the style rule.
The reset synchronizer behind the waiver above, plus a check of async assert and two-cycle release.
module rst_sync (
input logic clk_i,
input logic rst_n_i,
output logic rst_n_o
);
logic meta_q, sync_q;
// Intent: assert without a clock, release over two flops. A rule that
// requires fully synchronous resets is waived here; see the waiver file.
always_ff @(posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
meta_q <= 1'b0;
sync_q <= 1'b0;
end else begin
meta_q <= 1'b1;
sync_q <= meta_q;
end
end
assign rst_n_o = sync_q;
endmodule
Reset synchroniser bench run with Icarus Verilog 13.0 (2026-10-16): prints PASS. It is a finite digital check of asynchronous assert and two-cycle release. It does not model metastability or establish RDC signoff for data from independently reset sources.