GLS · Chapter 1 · RTL vs Gate-Level Simulation
Four-State vs Two-State Simulation
A simulator can model each signal in four states, namely 0, 1, unknown, and high-impedance, or in two states, meaning 0 and 1 only. Two-state simulation is faster and common for RTL functional runs, but it cannot represent an unknown: it collapses that unknown to a definite value, either a fixed 0 or a chosen or random initial value. For gate-level simulation this is fatal, because the entire purpose of GLS is to expose unknowns at power-up and reset-coverage bugs, and a two-state run hides exactly those by forcing every unknown to a defined value. So GLS must run four-state to do its job, and high-impedance matters too for tri-state buses and bidirectional pins. This lesson explains the distinction, why a two-state GLS is nearly pointless for finding unknowns, and the trap where a two-state run looks clean while a four-state run reveals the real problem.
Foundation11 min readGLSFour-StateTwo-StateXZ
Chapter 1 · Section 1.4 · RTL vs Gate-Level Simulation
Project thread — Chapter 0's X-thinking and 1.3's vanished-initial X both assume the simulator can show X. This lesson checks that assumption: a two-state simulator would hide the D flip-flop's power-up X entirely.
1. Why Should I Learn This?
You can do everything else right — run GLS from a cold start, look for the first divergence, trace X to its source — and find nothing, simply because the simulator was in two-state mode and could not represent X. A two-state GLS that passes 'clean' is one of the most dangerous false greens in the flow, because it looks like a successful X check while being incapable of finding an X. Knowing the four-state/two-state distinction is what makes every other GLS lesson actually work — it is the precondition for seeing X at all.
This lesson is the precondition for Chapter 0's X-thinking and 1.3's masked-reset X: both only function if the simulator is four-state. It also introduces Z for the tri-state logic that appears later (Chapters 8–11).
2. Real Silicon Story — the clean GLS that could not see X
Under tape-out pressure, a team wants GLS to run faster, so they enable two-state mode for the gate-level run (it roughly halves runtime). The GLS is clean — no X, no mismatches — and they sign off, relieved. Silicon comes back and the block fails at power-up, intermittently, with the classic signature of an uninitialised register.
The two-state GLS was clean because it was structurally incapable of showing the failure. The netlist did have an uninitialised register (a real reset gap), which powers up X — but in two-state mode there is no X: the simulator collapsed that unknown to a definite 0, so the register came up at a clean, defined value in the run and nothing looked wrong. The 'clean GLS' was not evidence the netlist was X-free; it was evidence the simulator could not represent the X. A four-state run on the same netlist showed the register X at power-up immediately — the bug had been there all along, invisible to two-state. The post-mortem lesson: a two-state simulator cannot represent X — it collapses every unknown to a definite value — so a two-state GLS hides exactly the X-init/reset bugs GLS exists to find; a 'clean' two-state GLS proves nothing about X, and GLS must run four-state (0/1/X/Z) to do its job.
3. Concept — four states, two states, and why GLS needs four
The distinction is how many values a signal can hold:
- Four-state (0, 1, X, Z). The full model: 0 and 1 (logic levels), X (unknown — the value is indeterminate), and Z (high-impedance — nothing is driving the net). This is what lets a simulation represent an uninitialised flop (X) or an undriven tri-state bus (Z).
- Two-state (0, 1 only). A faster model with no X and no Z. Every signal is forced to
0or1— an unknown cannot exist, so it is collapsed to a definite value (a fixed0, or a chosen/random 2-state init). - Why GLS needs four-state. The purpose of GLS is to expose X at power-up and reset-coverage bugs (Ch0, 1.3, Ch7). A two-state run forces those X to defined values, so it cannot see them — a two-state GLS is nearly pointless for X. GLS must be four-state.
- Z matters too. Tri-state buses and bidirectional pins genuinely go high-impedance at the gate level; only four-state can represent Z (and bus contention,
Xfrom multiple drivers).
The consequence, per value: four-state shows the unknown; two-state collapses it and hides the bug:
4. Mental Model — two-state is a black-and-white photo that cannot show 'unknown'
5. Working Example — the same X, seen in four-state and hidden in two-state
An uninitialised register (no reset). Run the same netlist four-state and two-state.
// RTL (SystemVerilog): a register with NO reset -> real flops power up X. A tiny checker flags unknown.
module reg_no_reset (input logic clk, input logic [7:0] d, output logic [7:0] q);
always_ff @(posedge clk) q <= d; // no reset -> q is X until first captured
endmodule
// Checker IDEA: flag if q is unknown after reset should have happened.
initial #1 if ($isunknown(q)) $display("t=%0t X DETECTED on q = %b", $time, q);The state model is what decides whether the unknown is even representable — and this is a cross-language point, not a Verilog quirk:
// RTL (Verilog): 'reg' is FOUR-STATE (0/1/x/z) by default -> an unknown IS representable in 4-state runs.
module reg_no_reset (input clk, input [7:0] d, output reg [7:0] q);
always @(posedge clk) q <= d; // no reset -> q is x until first captured
endmodule-- RTL (VHDL): std_logic is a 9-value type incl 'U' (uninitialised) and 'X' -> unknown IS representable.
-- A 2-value type (VHDL `bit`, or a 2-state Verilog run) CANNOT hold unknown -> the X would disappear.
signal q : std_logic_vector(7 downto 0); -- starts 'U' (uninitialised) until first drivenThat register synthesizes to real flop cells with no reset pin — a representative gate-level view (cell names vary by library):
// NETLIST (representative): the register maps to real flops with NO reset input -> Q powers up X.
module reg_no_reset_netlist (input clk, input [7:0] d, output [7:0] q);
DFFX1 U0 (.D(d[0]), .CK(clk), .Q(q[0])); // no reset pin -> Q[0] starts X (four-state shows it; two-state hides it)
// ... bits [7:1] the same: all X at power-up ...
endmoduleThe same netlist gives opposite results depending on the simulator's state model:
# FOUR-STATE GLS: the uninitialised reg is X -> the checker fires -> bug VISIBLE.
t=0 q = xxxxxxxx
t=1 X DETECTED on q = xxxxxxxx <- four-state shows the unknown -> GLS did its job
# TWO-STATE GLS (same netlist): X is COLLAPSED to a definite value -> checker never fires -> bug HIDDEN.
t=0 q = 00000000 <- two-state repainted X as 0; q looks 'initialised'
(t=1: $isunknown(q) is FALSE -> no message) <- the run is 'clean' but proved nothing about XSame netlist, same bug, two verdicts. Four-state exposes the X; two-state manufactures a clean result by collapsing it. The clean two-state run is the dangerous one — it looks like a passing X check while being incapable of finding X. The next section is that exact false green.
6. Debugging Session — a clean two-state GLS that hid the X
A two-state GLS runs clean while a four-state GLS on the same netlist shows X at power-up — the two-state simulator collapsed the unknown and could not represent the real init bug
TWO-STATE CANNOT SEE X — RUN GLS FOUR-STATEA GLS run enabled in two-state mode (for speed) comes up clean — no X, no mismatches — and is signed off. Later (or in silicon), a power-up / reset bug appears that the 'clean' GLS never showed. Re-running the same netlist in four-state mode immediately shows X at power-up.
The two-state simulator cannot represent X — it has only 0 and 1 — so when the netlist's uninitialised register would be unknown, the two-state run collapsed it to a definite value (a fixed 0, or a chosen/random init). The register therefore came up at a clean, defined value in the run, and nothing looked wrong — but that cleanliness was manufactured by the state model, not by the design. The real netlist has an actual initialisation gap (a register with no reset, exactly the 1.3 class), which powers up X — and a four-state run, which can represent X, shows it immediately. So the two-state GLS was not a successful X check that happened to find nothing; it was structurally incapable of finding X, and its 'clean' result proved nothing about unknowns. The bug was present the whole time, hidden by the two-state simulator's inability to model X. The tell is the pattern: clean in two-state, X in four-state on the same netlist — the simulator's state model, not the design, changed the verdict.
Run GLS in four-state mode (0/1/X/Z) so it can actually represent X — then it exposes the power-up X, which you root-cause as a real init/reset bug (the register needs a reset, per 1.3) and fix. Reserve two-state mode for fast RTL functional runs where X is not the target, never for the GLS X check. The lesson: a two-state simulator collapses every unknown to a definite value, so it cannot find X — a 'clean' two-state GLS proves nothing about X and hides exactly the init/reset bugs GLS exists to catch; GLS must run four-state. This is the precondition for every X-related lesson: Chapter 0's X-thinking, 1.3's masked reset, and Chapter 7's reset debug all require a four-state simulator, or they find nothing while looking successful.
7. Common Mistakes
- Running the GLS X check in two-state mode. Two-state cannot represent X — the run is structurally incapable of finding the bugs GLS exists for; use four-state.
- Trusting a 'clean' two-state GLS. Its cleanliness is the state model collapsing X, not the netlist being X-free — it proves nothing about unknowns.
- Enabling two-state for GLS 'speed' near tape-out. It halves runtime by removing the ability to find X — the worst possible trade for the gate-level signoff run.
- Forgetting Z. Two-state also cannot represent high-impedance — tri-state buses and bidirectional pins need four-state (Ch8–11).
- Assuming RTL two-state runs carry over. Two-state is fine for fast RTL function; it is not acceptable for the GLS X/reset check.
8. Industry Best Practices
- Always run GLS four-state (0/1/X/Z). Representing X (and Z) is the entire point of the gate-level check.
- Reserve two-state for fast RTL functional runs. Use it where X is not the target; never for the GLS X/reset signoff.
- Treat a clean two-state GLS as unverified for X. Re-run four-state before believing the netlist is X-free.
- Confirm the simulator's state mode before trusting a GLS result. A 'clean' verdict is only meaningful if the simulator could represent X.
- Use four-state for tri-state/bus logic. Z and contention only appear in four-state — essential for bidirectional and bus designs.
Senior Engineer Thinking
- Beginner: "GLS is clean — no X, we're good."
- Senior: "Was it four-state? A clean two-state GLS cannot represent X — it collapsed every unknown to 0/1, so 'clean' means the camera couldn't show the problem, not that there isn't one. Re-run four-state before I believe it."
The senior checks the state model before trusting a clean X result — because a two-state 'clean' is a false green by construction.
Silicon Impact
If a two-state GLS is trusted, the init/reset bug it cannot show ships. Silicon powers up with the real X the two-state run collapsed — intermittent boot failures, field returns, and a debug that is doubly painful because 'GLS was clean' points the team away from the real cause. The schedule 'saving' from two-state (a faster run) is dwarfed by a respin for a bug a four-state GLS would have caught in the first cold-start. For tri-state designs, a missed Z (bus contention, undriven nets) similarly reaches silicon as marginal, driver-strength-dependent failures. The state model is not a performance knob on the signoff run — it is a correctness setting.
Engineering Checklist
- Ran the GLS X/reset check in four-state (0/1/X/Z) mode.
- Did not use two-state for the gate-level signoff run.
- Treated any 'clean' two-state GLS as unverified for X — re-ran four-state.
- Confirmed the simulator's state mode before trusting a clean verdict.
- Used four-state for tri-state / bus logic so Z and contention are visible.
Try Yourself
- Simulate
reg_no_resetin a four-state run — the$isunknowncheck fires (qis X at start). - Change: switch the simulator to two-state mode (most simulators expose a two-state option; or use 2-state types / VHDL
bit). - Observe: the X is gone —
qreads a defined value and the check does not fire. - Expect: the same design gives opposite verdicts. That proves a 'clean' two-state GLS says nothing about X — always run the GLS X check four-state.
Four-state is the default in standard Verilog/VHDL simulation, so no paid or specific tool is needed; two-state is an opt-in speed mode.
Interview Perspective
- Weak: "GLS is clean, so we're good on X."
- Good: "A clean GLS only means something if it ran four-state — two-state cannot represent X."
- Senior: "I confirm the state model before trusting a clean X result. A two-state 'clean' collapsed every unknown to 0/1; I re-run four-state before signing off on X/reset — and I keep two-state for fast RTL function only."
Quick Revision
Two-state (0/1) cannot represent X or Z — it collapses every unknown to a definite value, so a clean two-state GLS proves nothing about X. GLS must run four-state (0/1/X/Z) to see the init/reset bugs it exists for. A black-and-white camera cannot photograph grey. Next: 1.5 walks the D flip-flop from RTL to a clean four-state GLS run — the chapter's worked example.
9. Interview / Review Questions
10. Key Takeaways
- A simulator models signals in four states (0/1/X/Z) or two states (0/1 only) — two-state is faster but cannot represent X or Z.
- Two-state collapses every unknown to a definite value (a fixed 0, or a random init), so it hides exactly the X-init/reset bugs GLS exists to catch — a 'clean' two-state GLS proves nothing about X.
- GLS must run four-state — representing X (uninitialised flops, reset gaps) and Z (tri-state/bus) is the entire point of the gate-level check.
- The signature trap is a clean two-state GLS vs X in four-state on the same netlist — the state model, not the design, changed the verdict; the bug was there all along.
- The state model is a correctness setting, not a performance knob, for the signoff run: reserve two-state for fast RTL function, and confirm four-state before trusting any clean GLS X result. Next: 1.5 — the D flip-flop, RTL to a clean four-state GLS, tying Chapter 1 together.