GLS · Chapter 6 · X-Propagation
Why RTL Hides Bugs the Netlist Exposes
One of the strongest reasons gate-level simulation exists is that RTL can hide bugs the netlist reveals. RTL is X-optimistic: a behavioral if or case handed an unknown select quietly picks a branch and produces a definite value, masking an uninitialized control. The synthesized netlist has no such behavior, so its mux propagates the unknown and exposes the same signal. The key fact underneath is that synthesis does not preserve X semantics. The gate-level netlist is logically equivalent for defined inputs, but it behaves differently on unknowns, so a bug that is invisible in RTL simulation can appear in GLS. This is not a synthesis defect; it is why GLS is a distinct, valuable check. This lesson shows the mechanism with a simple mux in three languages.
Foundation12 min readGLSX-OptimismRTLSynthesisUninitialized
Chapter 6 · Section 6.4 · X-Propagation
Project thread — the FSM's power-up X (5.5) is exactly this: RTL's behavioural reset/optimism can hide an uninitialized state the netlist exposes. 6.6 root-causes it end to end.
1. Why Should I Learn This?
"It passes RTL simulation" is not the same as "it's correct" — and this lesson explains the gap.
- RTL optimism resolves unknowns to a branch, hiding uninitialized control.
- The netlist propagates
X, exposing the same bug. - Synthesis doesn't preserve
Xsemantics — so GLS is a distinct check, not a redundant one.
This is the why behind gate-level X debugging and the FSM X of 6.6.
2. Real Silicon Story — the "verified" block that came up wrong in silicon
A control block passed extensive RTL simulation — no X, all tests green. In silicon it occasionally powered up in the wrong mode.
The mode select was driven by a register that lacked a proper reset. In RTL, the mode case was X-optimistic: with the select X, it fell through to a default branch and produced a definite, plausible mode — so RTL never showed a problem. The netlist mux propagated X, and a gate-level run would have flagged it — but GLS had been skipped as "redundant with RTL." Silicon, of course, powered up at some real value — sometimes the wrong mode.
Lesson: RTL optimism can make an uninitialized-control bug invisible. GLS (which propagates X) is the check that catches it — it is not redundant with RTL.
3. Concept — how RTL hides, how the netlist exposes
RTL is X-optimistic (hides):
if (sel) a; else b;withsel = X→ takeselse→ definiteb. The unknown is gone.case (sel) … default: … endcasewithsel = X→ often the default → definite. Unknown hidden.- Behavioural initial values / resets that model state the gates don't have.
The netlist exposes:
- Synthesis maps the conditional to a mux, which propagates
Xon an unknown select (differing data, 6.3). - Gate flops power up
X(noinitial, 2.6) — no behavioural init to hide it. - The
Xsurfaces at outputs, flagging the uninitialized source.
The key fact (accuracy):
- Synthesis does not preserve
Xsemantics. It preserves logic for defined inputs; behaviour on unknowns legitimately differs between RTL and gates. - So an RTL "pass" on unknowns is not authoritative — GLS is the distinct check.
- Neither is silicon truth (6.2) — but the gate
Xflags a real uninitialized source RTL hid.
4. Mental Model — RTL rounds off uncertainty; the netlist keeps it
RTL behavioural code rounds off uncertainty to a clean answer; the netlist keeps the uncertainty as X.
- Ask RTL "which branch if the select is unknown?" and it picks one — a confident (possibly wrong) answer.
- Ask the netlist mux the same and it says "unknown" (
X) — honest, if noisier. - Silicon picks a real branch — but not guaranteed to be RTL's guess.
RTL's rounding is convenient but hides the unknown; the netlist's honesty is why GLS catches the bug. Synthesis changing this behaviour is expected, not a defect.
5. Working Example — the same mux in three languages
The behavioural mux (X-optimistic), in three languages:
// SystemVerilog — behavioural mux: X-OPTIMISTIC on an unknown select
assign y = sel ? a : b; // sel = X -> resolves to b -> DEFINITE (hides uninitialized sel)// Verilog — same behaviour (case form also optimistic via default)
always @* case (sel) 1'b1: y = a; default: y = b; endcase // sel = X -> default -> DEFINITE-- VHDL — same behaviour
y <= a when sel = '1' else b; -- sel = 'X'/'U' -> else branch -> DEFINITE (hides it)After synthesis, this becomes a mux cell whose UDP propagates X on an unknown select (6.3) — so GLS shows X where RTL showed a definite value.
Practical context (representative, tool-neutral):
# Why GLS is NOT redundant with RTL (tool-neutral):
# synthesis preserves logic for DEFINED inputs; it does NOT preserve X semantics
# RTL if/case: unknown select -> branch/default -> DEFINITE (hides)
# netlist mux: unknown select -> X (exposes)
# => a bug invisible in RTL can appear in GLS. Run GLS; don't assume RTL covers it.
# (xprop, 6.5, can reproduce some of this in RTL to shift-left.)RTL hides, netlist exposes — as a real waveform:
Same uninitialized select: RTL outputs a definite value (hidden bug); GLS shows X (exposed bug)
8 cycles6. Debugging Session — RTL green, GLS shows X
A block passes RTL simulation cleanly but GLS shows X on an output, and GLS is doubted as over-pessimistic — but RTL's X-optimism hid an uninitialized control that the netlist mux correctly exposes; synthesis does not preserve X semantics
RTL PASS != CORRECT; GLS IS A DISTINCT CHECKA block is green in RTL simulation but shows X on an output in GLS. The team suspects GLS is being "over-pessimistic" and considers ignoring it.
RTL's X-optimism hid a real bug the netlist exposes. The output depends on a control (a select or mode register) that is genuinely uninitialized (no proper reset, 2.6). In RTL, the behavioural if/case handling that control is X-optimistic — an unknown select resolves to a branch/default, producing a definite value, so RTL never shows a problem. Synthesis maps the conditional to a mux that propagates X on an unknown select (6.3), so GLS exposes the uninitialized control. Crucially, synthesis does not preserve X semantics — the RTL and gate behaviours on unknowns legitimately differ, so the RTL "pass" was not authoritative. The gate X is the honest result, flagging a real uninitialized source.
Treat the GLS X as a real lead: trace it to its source (6.1) — here an uninitialized control — and fix the source (proper reset/initialization). Do not dismiss it because "RTL passed"; RTL optimism is exactly the mechanism that hides this class of bug. To catch it earlier, enable xprop in RTL (6.5) to reproduce the gate-like X behaviour and shift the find left. The lesson: RTL is X-optimistic and hides uninitialized-control bugs by resolving unknowns to a branch; the netlist propagates X and exposes them — synthesis does not preserve X semantics, so GLS is a distinct check, and a GLS-only X is a real bug to root-cause, not pessimism to ignore. (X is a modelling value; GLS stays dynamic — STA signs off, 0.3.)
7. Common Mistakes
- Assuming an RTL pass means correct. RTL optimism hides uninitialized-control bugs.
- Believing synthesis preserves
Xbehaviour. It preserves defined-input logic, notXsemantics. - Treating GLS as redundant with RTL. It is a distinct check for exactly this class of bug.
- Dismissing a GLS-only
Xas pessimism without tracing the source (6.2/6.1). - Not shifting left with xprop. RTL xprop (6.5) can catch some of these earlier.
8. Industry Best Practices
- Run GLS as a distinct check — do not assume RTL covers unknowns.
- Treat a GLS-only
Xas a real lead — trace to source (6.1). - Enable RTL xprop (6.5) to shift-left the catch.
- Fix uninitialized sources (reset/init), not the symptom.
- Educate that synthesis doesn't preserve
Xsemantics — set expectations.
Senior Engineer Thinking
- Beginner: "It's clean in RTL, so GLS
Xmust be pessimism." - Senior: "RTL is optimistic — it resolves unknown selects to a branch and hides them. Synthesis doesn't preserve
Xsemantics, so the gateXis a real finding. Where's the uninitialized source?"
The senior knows RTL optimism hides these bugs and treats a GLS-only X as a real lead to root-cause.
Silicon Impact
This is a first-order reason GLS earns its cost. A class of bugs — uninitialized control, missing reset, unhandled case — is systematically hidden by RTL's X-optimism and systematically exposed by the netlist's X-propagation. Skip GLS (or waive its Xs as pessimism), and these bugs sail through RTL green and surface in silicon as power-up-dependent, mode-wrong, intermittent failures (the reset-gap class, 0.3) — expensive and hard to reproduce. Running GLS and treating its Xs as real leads is precisely how teams catch what RTL cannot. Synthesis not preserving X semantics isn't a flaw to fear — it's the property that makes GLS a distinct, protective check.
Engineering Checklist
- Ran GLS as a distinct check, not assumed redundant with RTL.
- Treated each GLS-only
Xas a real lead → traced to source (6.1). - Fixed uninitialized sources (reset/init), not the symptom.
- Enabled RTL xprop (6.5) to shift-left where possible.
- Communicated that synthesis doesn't preserve
Xsemantics.
Try Yourself
- Simulate the behavioural mux (
sel ? a : b) in RTL withseluninitialized — output is a definite value (RTL passes). - Observe: RTL hides the bad select.
- Change: synthesize and run the netlist mux with the same uninitialized
sel. - Expect: GLS shows
X(bug exposed). Then enable xprop in the RTL run (6.5) and watch theXappear in RTL too — proving the shift-left.
Any free Verilog simulator shows the RTL-vs-GLS divergence; many support an xprop mode. No paid tool required.
Interview Perspective
- Weak: "If RTL passes, the design is correct."
- Good: "RTL is X-optimistic — an
if/casepicks a branch on an unknown select, hiding it; the netlist mux propagatesXand exposes it." - Senior: "Synthesis preserves defined-input logic but not
Xsemantics, so a bug hidden by RTL optimism appears in GLS — which is why GLS is a distinct check. A GLS-onlyXis a real lead to root-cause (uninitialized control), and I use RTL xprop to catch it earlier. Neither model is silicon truth, but the gateXflags the real uninitialized source."
9. Interview / Review Questions
10. Key Takeaways
- RTL is X-optimistic: a behavioural
if/casehanded an unknown select picks a branch/default and outputs a definite value — hiding an uninitialized control. - The synthesized netlist mux propagates
X(6.3) and exposes the same uninitialized source in GLS. - Synthesis does not preserve
Xsemantics — it preserves defined-input logic; behaviour on unknowns differs — so an RTL pass is not authoritative and GLS is a distinct check. - A GLS-only
Xis a real lead (uninitialized control/reset), not pessimism to dismiss — trace to source (6.1) and fix it; xprop (6.5) can shift the catch left into RTL. - Neither model is silicon truth — but the gate
Xflags a real source; GLS stays dynamic (STA signs off, 0.3). Next: 6.5 — controlling X-propagation (xprop modes).
Quick Revision
RTL X-optimism HIDES uninitialized-control bugs (
if/casepicks a branch on unknownsel→ definite). Netlist mux propagatesX→ EXPOSES them. Synthesis does NOT preserveXsemantics (defined-input logic yes,Xno) → a bug invisible in RTL appears in GLS → GLS is a distinct check. A GLS-onlyX= real lead (trace to source, 6.1), not pessimism. xprop (6.5) shifts the catch left. Next: 6.5 — controlling X-propagation.