GLS · Chapter 5 · GLS Testbench Adaptation
Writing GLS-Friendly Checkers & Strobes
A checker that samples an output exactly at the clock edge is fine on zero-delay RTL but misfires on a timed netlist, because real clock-to-output delay means the output has not updated yet, so the checker reads the previous value and reports a false mismatch. Three habits make a checker gate-level friendly. First, sample outputs on a strobe a defined delay after the active edge, once the delays have settled, rather than at the edge. Second, handle unknowns explicitly so an unknown is always treated as a failure to investigate and never accidentally matches. Third, avoid glitch-sensitive combinational checks that fire on transient glitches which settle correctly. The theme is that a checker artifact is not a design failure, and strobing reveals real values but does not turn GLS into a timing signoff.
Foundation12 min readGLSCheckerStrobeX-handlingSampling
Chapter 5 · Section 5.4 · GLS Testbench Adaptation
Project thread — the FSM's outputs must be checked after they settle and with X treated honestly. This lesson makes the checker trustworthy; 5.5 puts the whole adapted FSM testbench together.
1. Why Should I Learn This?
A checker that mis-samples turns a correct netlist into a wall of false failures.
- Sampling at the edge reads the pre-clk-to-Q value → false mismatch.
- Sloppy
==can let anXslip through as a match → a realXmissed. - Combinational immediate checks fire on glitches that settle fine (3.5).
Getting the checker right is assumption (2) of 5.1 on the sample side — and it decides whether GLS failures are trustworthy.
2. Real Silicon Story — the checker that failed a correct output
A timed FSM run drowned in output mismatches. The DUT looked broken; a rollback was discussed.
The checker sampled at the clock edge, before the output's clk-to-Q delay had settled — so it compared the previous cycle's value against the new expected value and failed every cycle. The netlist was correct. Moving the sample to a strobe after settling cleared every false mismatch; the few remaining differences were real and worth fixing.
Lesson: on a timed netlist, sample outputs after they settle. An edge-aligned checker reports false mismatches on a correct design.
3. Concept — three habits of a GLS-friendly checker
(1) Strobe after settling.
- Sample outputs a defined delay after the active edge — after clk-to-Q + path delays settle.
- Prefer a clocking-block output skew (a systematic "sample at edge + skew") over ad-hoc
#delay. - Never compare at the edge on a timed netlist.
(2) Handle X explicitly.
- Netlist outputs can be
X(power-up, timing-check firings). - A compare must treat
Xas a failure to investigate — never an accidental match. - Beware logical
==withX(yieldsx, which is not true but is easy to mis-handle); use explicitXchecks / case-equality where you mean it.
(3) Avoid glitch-sensitive combinational checks.
- Immediate checks on combinational outputs can fire on transient glitches (3.5) that settle to the right value.
- Check registered outputs, or sample on the strobe — judge the settled value.
Distinction: a checker artifact (mis-sample, X mishandling, glitch catch) is not a DUT failure. Fix the checker; a real mismatch after strobing is a genuine issue. Strobing reveals values; it doesn't close timing (STA signs off, 0.3).
4. Mental Model — read the scoreboard after the play, not during it
A checker is a referee reading the scoreboard.
- Read it during the play (at the edge) and the number hasn't updated — you call the wrong score (false mismatch).
- Read it just after the play settles (the strobe) and you get the real result.
- If the board shows
X(garbled), that's not a valid score — flag it, don't pretend it matches. - Ignore the flicker mid-update (glitches) — judge the settled number.
Read after settling, treat garbled as garbled, ignore the flicker.
5. Working Example — an edge checker vs a strobed, X-aware checker
Bad and good checkers:
// BAD — samples AT the edge; ignores X via loose compare
always @(posedge clk)
if (out == golden) ok++; // reads pre-clk-to-Q value -> false mismatch;
// '==' with X yields x (not a clean pass/fail) -> X can slip// GOOD — strobe after settling + explicit X handling
default clocking cb @(posedge clk); output #1step; input #3 out; endclocking // sample skew AFTER edge
task automatic check(input logic [3:0] golden);
@(cb); // strobe after the edge (input skew)
if ($isunknown(cb.out)) // X is a FAILURE to investigate, never a match
$error("X on out at strobe");
else if (cb.out !== golden) // case-inequality: exact, X-aware compare
$error("mismatch: got %0d exp %0d", cb.out, golden);
endtaskPractical context (representative, tool-neutral):
# GLS-friendly checker rules (tool-neutral):
# - sample outputs on a STROBE after clk-to-Q settles (clocking-block input skew)
# - use case-inequality (!==) and $isunknown() so X is caught, never matched
# - check REGISTERED outputs / settled values, not transient combinational glitches
# - a mismatch AFTER strobing is real; before strobing it is a checker artifactEdge-sample vs strobe-sample, as a real waveform:
Edge sampling reads the old value; strobe sampling reads the settled value
8 cycles6. Debugging Session — a correct netlist failing every cycle
A checker reports a mismatch nearly every cycle on a correct netlist because it samples the output at the clock edge, before clk-to-Q settles, comparing the previous value against the new expected — moving the sample to a strobe after settling clears the false failures
SAMPLE AFTER SETTLING, NOT AT THE EDGEA timed netlist run produces output mismatches nearly every cycle. The DUT appears broken; a rollback is considered.
The checker samples at the clock edge, before the output's clk-to-Q delay has settled. So it compares the previous cycle's (still-present) output against the new expected value — a mismatch every cycle, on a correct netlist. On zero-delay RTL this was fine (the output updated at the edge); on the timed netlist it is a checker artifact. A related trap: a loose == compare can let an X produce an ambiguous result and slip through, hiding a real X. Neither is a DUT failure.
Sample outputs on a strobe a defined delay after the active edge (a clocking-block input skew), so the checker reads the settled value; use case-inequality (!==) and $isunknown() so an X is caught as a failure, never matched. Check registered/settled values, not transient combinational glitches (3.5). The lesson: on a timed netlist, sample outputs after they settle (a strobe), and handle X explicitly — an edge-aligned or X-loose checker fabricates failures (or hides real X) on a correct design. A mismatch that remains after strobing is real. (Strobing reveals values; it doesn't close timing — STA signs off, 0.3.)
7. Common Mistakes
- Sampling outputs at the clock edge. Reads pre-clk-to-Q value → false mismatch.
- Loose
==withX. Ambiguous result can hide a realX; use!==/$isunknown(). - Immediate checks on combinational outputs. Fire on glitches that settle fine (3.5).
- Treating checker artifacts as DUT failures. Fix the checker first.
- Assuming strobing proves timing. It reveals values; STA signs off (0.3).
8. Industry Best Practices
- Strobe after settling (clocking-block input skew), never at the edge.
- Handle
Xexplicitly ($isunknown, case-inequality) —Xis a failure to investigate. - Check settled/registered values, not transient glitches.
- Separate checker artifacts from real failures before doubting the DUT.
- Judge real timing with STA, not the checker.
Senior Engineer Thinking
- Beginner: "Every cycle mismatches — the netlist is wrong."
- Senior: "Am I sampling at the edge? Then I'm reading the pre-clk-to-Q value. Strobe after settle, handle
Xwith!==/$isunknown, and then see which mismatches are real."
The senior fixes sampling and X handling before trusting a mismatch, and defers real timing to STA.
Silicon Impact
A checker that fabricates failures is worse than useless — it buries real gate-level issues (a genuine X, a real functional mismatch) under false ones, and the noise pushes teams to disable or loosen checks, blunting GLS right before tape-out (0.3). Conversely, a checker that mishandles X (letting it match) produces false passes, letting real uninitialized/timing-driven X escape. A strobed, X-aware checker keeps the mismatch log trustworthy: every remaining failure is worth investigating, so GLS actually protects the tape-out.
Engineering Checklist
- Sampled outputs on a strobe after settling (input skew), not at the edge.
- Handled
Xexplicitly ($isunknown,!==) — never an accidental match. - Checked settled/registered values, not transient glitches.
- Separated checker artifacts from real DUT failures.
- Deferred real timing judgement to STA (0.3).
Try Yourself
- Write a checker that samples
outatposedge clkon a timed netlist — watch it mismatch nearly every cycle on a correct DUT. - Observe: it is reading the pre-clk-to-Q value.
- Change: sample on a strobe (
#3after the edge or a clocking-block input skew) and use!==with$isunknown(). - Expect: false mismatches clear; any remaining mismatch is real. Then force an
Xonoutand confirm the checker flags it rather than passing.
Any free Verilog simulator supports clocking blocks, $isunknown, and case-inequality. No paid tool required.
Interview Perspective
- Weak: "The checker compares the output to the expected value each clock."
- Good: "It should sample after clk-to-Q settles — on a strobe — not at the edge, and treat
Xas a failure." - Senior: "On a timed netlist I sample outputs on a strobe (clocking-block input skew) after settling, compare with
!==and$isunknown()soXis caught not matched, and judge settled values not glitches. That keeps the mismatch log trustworthy — and real timing is STA's job, not the checker's."
9. Interview / Review Questions
10. Key Takeaways
- A checker that samples at the clock edge reads the pre-clk-to-Q value on a timed netlist → false mismatch; sample on a strobe a defined delay after the edge (clocking-block input skew), after settling.
- Handle
Xexplicitly — netlist outputs can beX(power-up, timing checks); treatXas a failure to investigate using$isunknown()/ case-inequality (!==), never an accidental match. - Avoid glitch-sensitive combinational checks — judge settled/registered values, not transient glitches (3.5).
- A checker artifact (mis-sample,
Xmishandling, glitch catch) is not a DUT failure — fix the checker; a mismatch that remains after strobing is real. - Strobing reveals values, not timing closure — STA signs off (0.3). Next: 5.5 — adapting an FSM testbench, end to end.
Quick Revision
Sample outputs on a STROBE after clk-to-Q settles (clocking-block input skew), never at the edge (reads old value → false mismatch). Handle
Xexplicitly ($isunknown,!==) —Xis a failure, never a match. Judge settled values, not glitches. Checker artifact ≠ DUT bug; a mismatch after strobing is real. Reveals values; STA signs off timing. Next: 5.5 — adapting an FSM testbench.