GLS · Chapter 0 · Foundation
Why Gate-Level Simulation Exists
Before a chip reaches silicon it is guarded by three very different checks, and understanding why there are three is the whole reason gate-level simulation exists. RTL functional simulation is fast and finds most bugs, but it runs an idealized design with no real gates and, by default, no timing. Static timing analysis proves every path meets setup and hold at every corner, but it runs no functional stimulus and never asks what value a flop captures. Between them sits a gap: the actual synthesized netlist, running real stimulus with real cell behavior and, once delays are annotated, real timing. Only gate-level simulation covers that gap, so it alone catches unknown values at power-up, resets that never release the design, uninitialized flops, and bugs the synthesis and place-and-route tools introduce. This opening lesson builds that intuition with a simple D flip-flop.
Foundation11 min readGLSGate-Level SimulationFoundationsRTL vs GatesSignoff
Chapter 0 · Section 0.1 · GLS Foundations
Project thread — Chapter 0 follows one running design, the D flip-flop: why GLS needs it (here), through what it catches (0.2), the flow (0.3), the timing modes (0.4), and reading its waveforms (0.5). We meet it now.
1. Why Should I Learn This?
If you only ever run RTL simulation and trust STA, you will ship a design that passed every test you ran and still hangs at power-on in silicon — because the bug lived in the gap neither check covers. GLS is the last functional check before tape-out, and knowing why it exists — what it uniquely sees — is what turns it from a slow box you tick into the tool that catches the most expensive, most embarrassing class of bugs: the ones that only appear once the design is real gates with real startup and real timing.
Learning why GLS exists is the foundation of the whole track. Everything after this — netlists, SDF, X-propagation, reset debug, timing violations — is how GLS does its job; this lesson is why the job needs doing at all.
2. Industry Story — the chip that passed everything and hung anyway
A team ships a block after a green regression: thousands of RTL functional tests passing, and a clean STA report — zero setup violations, zero hold violations, signed off at every corner. Confidence is high; the chip tapes out. First silicon comes back and the block hangs at power-on — it never leaves its reset state, or comes up in a nonsensical one, intermittently across parts.
The RTL sim never caught it because in RTL a reg conveniently starts at a defined value (or the testbench nudged it), so the design looked initialised. STA never caught it because STA checks timing, not values — it had no opinion about what the flops contained at time zero. The real design, made of actual flip-flop cells, powers up with its state unknown (X) and depends on the reset sequence to wash that X out — and a flop on the critical startup path was not on the reset, so its X never cleared and poisoned the logic downstream. The one check that would have shown this — the netlist simulated from an unknown state — was the check they skipped: gate-level simulation. The post-mortem lesson: RTL sim proves function on an idealised design and STA proves timing without function; the class of bug that is function on the real gates from a real startup state is invisible to both, and only GLS simulates that — which is exactly why GLS exists as a separate, mandatory check.
3. Concept — three checks, and the gap only GLS covers
A design is guarded by three checks, each blind to something:
- RTL functional simulation — runs stimulus against the idealised RTL. Catches functional bugs; misses real-gate behaviour, real startup/X, and (by default) timing. It answers "is the logic right?" on a design that is not yet gates.
- Static timing analysis (STA) — checks timing across all paths and corners, without simulating function. Catches timing problems exhaustively; misses everything about values — it never runs a test, so it cannot see an X, a wrong reset, or a functional mismatch.
- Gate-level simulation (GLS) — runs stimulus against the actual synthesized netlist, with real cell behaviour and (with SDF) real timing. It is the only check that simulates the thing you tape out, so it covers the gap: function-on-real-gates, X at power-up, reset release, and tool-flow correctness.
The mental picture is three overlapping guards with a seam between RTL-sim (function, ideal) and STA (timing, no function). GLS is the guard that covers the seam:
4. Mental Model — GLS is a dress rehearsal on the real actors
5. Working Example — a D flip-flop that passes RTL sim and shows X in GLS
Take the simplest sequential design, a D flip-flop — the first design in this track's project thread.
// RTL: a D flip-flop with an active-low async reset. In RTL SIMULATION this is well-behaved.
module dff (input logic clk, input logic rst_n, input logic d, output logic q);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) q <= 1'b0; // reset defines q
else q <= d;
end
endmoduleAfter synthesis, that always_ff becomes a real standard-cell flip-flop — a representative (conceptual) gate-level view. Note it has no notion of a defined initial value: at time zero, before reset asserts, its output is X.
// Representative GATE-LEVEL view (conceptual — real names vary by library):
// q starts UNKNOWN (X) at t=0; only an asserted reset (RN) drives it to a known value.
module dff_netlist (input clk, input rst_n, input d, output q);
DFFRX1 U0 (.D(d), .CK(clk), .RN(rst_n), .Q(q)); // a library D-FF cell with async reset RN
endmoduleA tiny GLS-adapted testbench idea: pulse the clock, and — deliberately — observe q before asserting reset, so you can see the difference between RTL and gates.
// Testbench IDEA (Chapter 0 — conceptual): clock the DUT and watch q around reset.
initial begin
clk = 0; rst_n = 0; d = 1;
#7 rst_n = 1; // release reset a bit AFTER the first clock edges
#50 $finish;
end
always #5 clk = ~clk; // 100 MHz clock
initial $monitor("t=%0t rst_n=%b d=%b q=%b", $time, rst_n, d, q);The expected logs differ between RTL sim and GLS — and that difference is the whole point:
# RTL SIM (idealised): q is a well-behaved reg — starts at its reset value, tracks d cleanly.
t=0 rst_n=0 d=1 q=0 <- RTL 'reg' conveniently sits at a known value
t=7 rst_n=1 d=1 q=0
t=10 rst_n=1 d=1 q=1 <- captures d on the clock edge, looks perfect
# GLS (real gate): q is UNKNOWN until reset actually asserts and washes the X out.
t=0 rst_n=0 d=1 q=x <- the real flop powers up UNKNOWN
t=7 rst_n=1 d=1 q=0 <- reset finally drove it to a known 0
t=10 rst_n=1 d=1 q=1 <- now it behavesThe same design is clean in RTL sim and shows an X at time zero in GLS. Here the reset cleans it up in time — but on a real design, a flop left off the reset would keep that X, and it would spread. That is the bug of the next section, and the reason GLS exists.
6. Debugging Session — clean RTL sim, but GLS shows a stuck X
A design passes RTL simulation but GLS shows X at the output that never clears — an uninitialised flop that reset does not reach, invisible to RTL sim and STA
ONLY GLS SEES X FROM A COLD STARTRTL functional simulation is green, and STA is clean (no setup/hold violations at any corner). But the first GLS run shows the block's output stuck at X — it never resolves to a real value, or resolves intermittently — from time zero onward, poisoning the logic it feeds. Nothing in the RTL sim log or the STA report hints at it, which is exactly what makes it alarming: two checks passed, and the third contradicts them.
The netlist is made of real flip-flop cells that power up in an unknown (X) state, and the design relies on the reset to drive every state element to a known value at startup. RTL simulation hid this: an RTL reg (or the testbench) presented the flops as already-initialised, so the design looked fine from a defined state it would never actually have in silicon. STA ignored it: STA checks timing, never values, so a flop sitting at X is simply outside what STA examines. The real cause is a state element that reset does not reach (a flop left off the reset network, or a reset that releases before the flop is driven) — so from the cold, unknown startup that only GLS models, its X never clears and propagates. It is not a timing bug and not an RTL logic bug in the idealised sense; it is a startup/initialisation bug that is only visible when you simulate real gates from an unknown state — the one thing GLS does and the other two checks do not.
Bring the offending flop into the reset (or fix the reset sequencing so every startup-critical flop is driven to a known value before it is used) so the design washes out its X deterministically — then re-run GLS and confirm the output resolves from time zero. The lesson the failure teaches, and the reason for this whole track: GLS is the only check that simulates the real netlist from a real (unknown) startup, so X-at-power-up and reset-coverage bugs are invisible to RTL sim (which starts from an idealised known state) and to STA (which never simulates values) — you find them, and can only find them, in gate-level simulation. A design is not signed off because RTL sim and STA are green; it is signed off when GLS is clean too, because GLS covers the seam the other two leave open.
7. Common Mistakes
- Trusting "green RTL sim + clean STA" as sign-off. They cover function-on-ideal-RTL and timing — not function on real gates from a cold start. GLS covers that seam; skipping it ships the seam bugs.
- Assuming X in GLS is a "simulation problem." An X at power-up is usually a real uninitialised-flop / reset-coverage bug that would misbehave in silicon — not a nuisance to suppress.
- Thinking STA replaces GLS because "timing is checked." STA never runs stimulus — it cannot see a wrong value, a reset bug, or a functional mismatch; it is complementary to GLS, not a substitute.
- Thinking RTL sim replaces GLS because "the logic is verified." RTL sim runs the idealised design, not the synthesized one — it misses real-gate startup and tool-flow effects.
- Treating GLS as optional because it is slow. It is slow because it is realistic; the bugs it catches are the most expensive to find later.
8. Industry Best Practices
- Treat GLS as a mandatory, separate signoff check. RTL sim, STA, and GLS each cover a different failure class — all three are required before tape-out.
- Run GLS from an unknown state early. Simulating from X (not a forced-known start) is what exposes reset-coverage and initialisation bugs while they are cheap to fix.
- Read an X in GLS as a real bug first. Assume an unknown value reflects a genuine startup/reset problem until proven otherwise.
- Keep RTL sim and STA green and GLS clean. Sign off on all three; a chip is not verified by any two of them alone.
- Understand what each check cannot see. RTL sim: real gates/startup/timing. STA: values/function. GLS: (its cost is speed) — knowing the blind spots is what makes the three-check strategy work.
9. Interview / Review Questions
10. Key Takeaways
- A chip is guarded by three complementary checks: RTL functional sim (stimulus on the ideal RTL — function only), STA (exhaustive timing, but no stimulus/values), and GLS (stimulus on the actual synthesized netlist with real cell behaviour and, with SDF, real timing).
- GLS is the only check that simulates what you tape out — so it covers the seam between RTL sim and STA: function on real gates, from a real (unknown) startup, run for real.
- The bug class GLS uniquely catches: X at power-up, reset-coverage / uninitialised-flop bugs, timing-dependent behaviour, and tool-flow (synthesis/P&R) bugs — all invisible to RTL sim (idealised start) and STA (no values).
- The signature symptom is a design that is green in RTL sim and clean in STA but shows X (or a mismatch) in GLS — usually a real startup/reset bug, not a simulation nuisance.
- A design is not signed off on any two checks alone — GLS is a mandatory, separate signoff because it verifies the real design from the real starting condition, which is precisely the failure class the other two cannot see.
Senior Engineer Thinking
- Beginner: "RTL passed and STA is clean, so the design is fine."
- Senior: "What did RTL simulation assume that silicon will not? RTL started my flops from a known value; real gates start at X, and STA ran no test at all. So 'green' means function on an idealised start plus legal timing — not function on real gates from a cold start. Which flop's X does reset not reach?"
The shift is from "which tests passed?" to "what did each check refuse to look at?" — and then running the one check (GLS) that looks there.
Silicon Impact
If this escapes to silicon, the chip can fail power-up: a flop reset never reaches keeps its X, and the block comes up in a nonsensical state or hangs at boot. Because real startup is non-deterministic, it shows as intermittent failures across parts — passes on the bench, fails in the field, drives customer returns, and can slip past production test (which does not hit the exact startup corner). A five-minute GLS catch becomes a multi-week post-silicon debug.
Engineering Checklist
- Ran GLS as a separate signoff check — not just RTL sim + STA.
- Simulated from an unknown (X) start, not a forced-known one.
- Confirmed reset drives every startup-critical flop to a known value.
- Treated any X at t=0 as a real bug until proven otherwise.
- Signed off only when RTL sim, STA, and GLS are all clean.
Quick Revision
Three checks, three blind spots. RTL sim = function on ideal RTL (no gates / no X / no timing). STA = timing only, no values. GLS = function on the real netlist from a real start — it covers the seam (X at power-up, reset, tool-flow). Green RTL + clean STA ≠ signed off. Next: 0.2 shows an X the netlist exposes that RTL hides.