GLS · Chapter 5 · GLS Testbench Adaptation
Timing-Aware Stimulus & Clock Generation
On a zero-delay RTL model, when you change an input barely matters, because the model reacts instantly. On a timed netlist it matters a great deal. If your testbench changes an input right at the active clock edge, that transition can land inside the flops' setup or hold window and fire a timing check, producing an unknown that the testbench caused rather than a real design bug. It can also race clock-to-output and make behaviour order-dependent. This lesson shows how to drive stimulus relative to the clock but clear of the timing window, typically a defined skew after the active edge, and how to generate a clean, glitch-free clock. It distinguishes a testbench-induced violation from a real timing bug and reaffirms that timing-aware stimulus does not turn gate-level simulation into a timing signoff.
Foundation11 min readGLSStimulusClockSetup/HoldTestbench
Chapter 5 · Section 5.3 · GLS Testbench Adaptation
Project thread — the FSM needs inputs (start, mode) driven cleanly relative to its clock. This lesson keeps the testbench from creating violations; 5.4 keeps the checker from mis-reading outputs.
1. Why Should I Learn This?
A timed netlist punishes sloppy stimulus timing that RTL forgave.
- Driving at the edge can violate the DUT's setup/hold → a testbench-induced
X. - It can race clk-to-Q → order-dependent, flaky behaviour.
- A glitchy clock injects false edges/pulses (3.5).
Getting stimulus timing right removes self-inflicted failures so real ones stand out — assumption (2) of 5.1, on the drive side.
2. Real Silicon Story — the "hold violation" the testbench created
A timed FSM run reported hold violations and X on capture. The team suspected a real hold problem and considered an ECO.
The testbench was changing the FSM's inputs exactly at the active clock edge — so from the DUT flops' view, data was moving inside the hold window, firing the $hold check (notifier → X). It was a testbench-induced violation, not a DUT timing bug. Driving the inputs a defined skew after the edge (clear of the window) removed every one of them; STA showed the actual hold paths were fine.
Lesson: stimulus that changes at the active edge can create setup/hold violations in a timed netlist. Drive clear of the timing window, then judge real timing with STA.
3. Concept — driving clear of the window, and a clean clock
The problem with edge-aligned drive:
- Inputs changing at the active edge sit inside the DUT flops' setup/hold window → timing checks fire (
X, 3.2). - Combinational stimulus at the edge can race clk-to-Q → order-dependent results.
Timing-aware stimulus:
- Drive inputs at a defined skew after the active edge — clear of the next edge's setup and this edge's hold.
- Use non-blocking / clocking-block drive skews so all inputs move together, off the edge.
- Keep the input stable across the DUT's timing window.
Clean clock generation:
- Generate a glitch-free clock with a stable period; avoid mid-cycle hazards.
- Keep clock and stimulus decoupled (stimulus references the clock; it doesn't perturb it).
Distinction (critical):
- Testbench-induced violation = the TB moved data into the window. Fix the TB.
- Real DUT violation = a genuine timing path. STA finds it; fix the design.
- Timing-aware stimulus removes the former so the latter is trustworthy — GLS stays dynamic (STA signs off, 0.3).
4. Mental Model — hand the baton between strides, not mid-step
Driving stimulus is like passing a baton to a runner (the DUT flop) who grabs it at the clock edge.
- Hand it over at the exact moment of the grab (the edge) and you fumble — the runner can't tell if they have it (setup/hold violation).
- Hand it over just after the grab, held steady until well before the next — a clean pass every time.
- The clock is the runner's stride; keep it even (glitch-free), and hand off between strides.
Time the hand-off to the window, not on top of it.
5. Working Example — edge-aligned vs timing-aware stimulus
Bad and good stimulus timing:
// BAD — drives inputs AT the active edge (inside the DUT's timing window on a timed netlist)
always @(posedge clk) begin
start <= new_start; // changes right at the edge -> may violate setup/hold -> notifier X
mode <= new_mode;
end// GOOD — clean clock + drive a defined skew AFTER the edge, clear of the window
logic clk = 0;
always #5 clk = ~clk; // clean, glitch-free clock (period 10)
task automatic drive(input logic s, input logic [1:0] m);
@(posedge clk); // sync to the edge
#2; // skew AFTER the edge -> clear of setup/hold window
start = s; mode = m; // inputs move off the edge, held stable to next window
endtaskPractical context (representative, tool-neutral):
# Rules of thumb for GLS stimulus (tool-neutral):
# - generate a clean clock (stable period, no glitches)
# - drive inputs a fixed skew AFTER the active edge (clear of setup/hold)
# - hold inputs stable across the DUT's timing window
# - reference the clock; never let stimulus perturb it
# Goal: remove TB-INDUCED violations so REAL timing (judged by STA) shows correctly.Edge-aligned vs after-edge drive, as a real waveform:
Driving at the edge (data in the hold window → X) vs driving after the edge (clean capture)
8 cycles6. Debugging Session — a testbench-induced hold violation
A timed run reports hold violations and X on capture, and a real hold bug is suspected — but the testbench changes inputs at the active clock edge, placing data inside the DUT flops' hold window; driving a skew after the edge removes every violation
STIMULUS AT THE EDGE = TB-INDUCED VIOLATIONA timed netlist run reports $hold violations and X on captured inputs. A real hold timing problem is suspected (possible ECO).
The testbench drives inputs at the active clock edge, so from the DUT flops' perspective the data is transitioning inside the hold window — firing the $hold check, toggling the notifier, and driving the capture to X (3.2/2.5). This is a testbench-induced violation: the stimulus timing, not a DUT timing path, created it. On zero-delay RTL the same code was harmless (no window); on the timed netlist it is not. The DUT's real hold paths may be perfectly fine — the violation is an artifact of when the testbench moved the data.
Drive inputs a defined skew after the active edge (clear of the hold window and the next setup window), keep them stable across the DUT's timing window, and generate a clean clock. This removes the testbench-induced violations. Then judge real timing where it belongs: STA across corners (0.3/3.4) — a genuine hold path is a design fix, not a stimulus one. The lesson: stimulus that changes at the active edge can create setup/hold violations in a timed netlist; drive clear of the timing window so testbench-induced violations disappear and real DUT timing (judged by STA) shows correctly. (Timing-aware stimulus does not close timing — GLS stays dynamic.)
7. Common Mistakes
- Driving inputs at the active edge. Lands in the setup/hold window → TB-induced
X(3.2). - Assuming RTL-safe stimulus is netlist-safe. Zero delay hid the window.
- Generating a glitchy clock. Injects false edges/pulses (3.5).
- Letting stimulus perturb the clock. Keep them decoupled.
- Reading a TB-induced violation as a real DUT bug. Judge real timing with STA (0.3).
8. Industry Best Practices
- Drive inputs a fixed skew after the active edge, clear of the window.
- Generate a clean, glitch-free clock with a stable period.
- Hold inputs stable across the DUT's timing window.
- Distinguish TB-induced vs real violations — fix TB vs fix design.
- Defer real timing judgement to STA (all corners).
Senior Engineer Thinking
- Beginner: "Hold violations on the netlist — we have a timing bug."
- Senior: "Is the testbench changing inputs at the edge? That creates hold violations from the flops' view. I'll drive a skew after the edge; if violations remain, then STA tells me about real paths."
The senior first removes testbench-induced violations, then judges real timing with STA.
Silicon Impact
Testbench-induced violations are pure noise that can trigger real harm: chasing a phantom hold problem can waste an ECO cycle, or — worse — teams may relax or waive timing checks to silence the noise, blunting GLS's ability to flag a genuine violation before tape-out (0.3). Clean, timing-aware stimulus keeps the signal-to-noise high: the only setup/hold firings left are ones worth investigating, and real timing is judged by STA across corners. Driving clear of the window is a small discipline that protects both schedule and signoff integrity.
Engineering Checklist
- Drove inputs a defined skew after the active edge (clear of the window).
- Generated a clean, glitch-free clock with a stable period.
- Held inputs stable across the DUT's timing window.
- Distinguished testbench-induced from real violations.
- Deferred real-timing judgement to STA (all corners).
Try Yourself
- Drive a flop's
dinat the activeposedge clkon a timed netlist — observe$holdfirings andXonq. - Observe: the violations are created by when the stimulus changes.
- Change: drive
dinwith a#2skew after the edge and hold it stable. - Expect: the violations and
Xdisappear — a clean capture. Confirm with STA that the DUT's real hold paths were fine all along.
Any free Verilog simulator with SDF timing checks reproduces this. No paid tool required.
Interview Perspective
- Weak: "Timing of stimulus doesn't matter — the DUT just reacts."
- Good: "On a timed netlist, changing inputs at the edge can violate the DUT's setup/hold; drive after the edge, clear of the window."
- Senior: "Edge-aligned stimulus creates testbench-induced setup/hold violations and races clk-to-Q. I drive a skew after the edge with a clean clock so those disappear, then judge real timing with STA. Timing-aware stimulus reveals real behaviour; it doesn't close timing."
9. Interview / Review Questions
10. Key Takeaways
- On a timed netlist, changing an input at the active clock edge can place data inside the DUT flops' setup/hold window, firing a timing check (
X, 3.2) and racing clk-to-Q — harmless on zero-delay RTL, not here. - Timing-aware stimulus: drive inputs a defined skew after the active edge, clear of the window, and hold them stable across it.
- Generate a clean, glitch-free clock, and keep stimulus decoupled from it.
- Distinguish a testbench-induced violation (fix the TB) from a real DUT timing bug (fix the design; STA finds it).
- Timing-aware stimulus removes self-inflicted violations so real behaviour shows correctly — it does not close timing; GLS stays dynamic (STA signs off, 0.3). Next: 5.4 — writing GLS-friendly checkers & strobes.
Quick Revision
Don't drive inputs AT the clock edge on a timed netlist — data lands in the setup/hold window → timing check fires (
X) and races clk-to-Q. Drive a skew AFTER the edge, clear of the window, hold stable; use a clean clock. Distinguish TB-induced (fix TB) vs real (STA finds it) violations. Removes self-inflicted noise; doesn't close timing. Next: 5.4 — GLS-friendly checkers & strobes.