Skip to content

GLS · Chapter 1 · RTL vs Gate-Level Simulation

How Netlist Behaviour Diverges from RTL

RTL is an abstraction; the synthesized netlist is the real implementation, and the two diverge along four specific axes. Initialisation: an RTL register starts from a known value while real gate cells power up unknown. Structure: a behavioural block versus the real, optimised standard cells synthesis chose. Timing: RTL's zero-delta evaluation versus real cell and interconnect delays once an SDF is annotated. Construct fidelity: simulation-only constructs that have no gate equivalent and simply vanish. Naming these four axes turns a confusing pile of RTL-versus-gate-level mismatches into a clear split, since some divergences are expected consequences of the abstraction and some are real bugs. This lesson maps the four axes on the running D flip-flop and teaches how to tell an expected divergence from a genuine defect.

Foundation12 min readGLSRTL vs GatesNetlistDivergenceFoundations

Chapter 1 · Section 1.1 · RTL vs Gate-Level Simulation

Project thread — Chapter 0 met the D flip-flop and the idea that GLS catches what RTL hides; Chapter 1 now dissects how RTL and the netlist diverge, on the same flip-flop, building to the full RTL-to-gates walkthrough in 1.5.

1. Why Should I Learn This?

The single most common beginner reaction to a first gate-level simulation is "why doesn't this match my RTL?" — followed by hours of treating every difference as a bug. Most of those differences are expected: the abstraction you designed at (RTL) is deliberately simpler than the gates you ship. Knowing the four axes along which RTL and the netlist diverge lets you predict the expected differences and isolate the real ones — turning 'nothing matches' into 'these three differences are expected, and this one is the bug.'

This lesson is the map for the chapter: 1.2 (synthesis transformations), 1.3 (vanishing constructs), and 1.4 (four-state vs two-state) each detail one mechanism behind these axes, and 1.5 walks the whole thing on the D flip-flop.

2. Real Silicon Story — the engineer who fought every difference

A designer runs their first GLS and is alarmed: the gate-level waveforms look nothing like the RTL waveforms they know by heart. Signals are X at the start where RTL showed clean 0s; the internal signal names are gone, replaced by cell instances; some logic they wrote is missing and other logic appears combined. They file a stack of 'GLS mismatch' bugs and escalate that 'synthesis broke the design.'

Synthesis had broken nothing. Every difference fell on one of four expected axes: the X-at-start was initialisation (real cells power up unknown); the missing internal names and combined logic were structure (synthesis optimised and mapped to cells); the shifted event times (once SDF was on) were timing; and a value their RTL testbench relied on was gone because it came from an initial block that vanished (construct fidelity). None of these were defects — they were the abstraction meeting reality. The one genuine issue buried in the pile — a flop that reset did not reach — was an initialisation bug, and it was invisible until the engineer stopped treating expected divergences as bugs and asked which differences were not explained by the four axes. The post-mortem lesson: RTL and the netlist diverge along four structured axes — initialisation, structure, timing, and construct fidelity — and most RTL-vs-GLS differences are expected consequences of those axes, not bugs; the skill is to explain each difference by an axis and flag only the ones that remain as real defects.

3. Concept — the four axes of divergence

RTL is an abstraction; the netlist is the implementation. They diverge along four axes:

  • Initialisation. An RTL reg presents a known starting value (or the testbench sets it); real gate cells power up unknown (X) and rely on reset to reach a known state. Expected difference: X at power-up in GLS where RTL showed a clean value (Ch0, and 1.4/Ch7).
  • Structure. You wrote behavioural always_ff/always_comb; synthesis produced real standard cells, often optimised (Boolean simplification, constant propagation), restructured, and shared. Expected difference: internal RTL signals gone, logic combined/renamed (1.2).
  • Timing. RTL evaluates in zero-delta time (events at the edge); the netlist's cells have real delays once SDF is annotated, so events occur at real times (Ch0's full-timing mode, Ch3–4).
  • Construct fidelity. Simulation-only constructs — initial, force, # delays, $display, sim-only assigns — have no gate equivalent and vanish in synthesis. Expected difference: behaviour the RTL sim leaned on is gone in GLS (1.3).

The judgement this enables: an RTL-vs-GLS difference is either explained by an axis (expected) or it is a real bug. Here are the four axes, RTL side vs netlist side:

Four divergence axes RTL vs netlist: initialisation, structure, timing, construct fidelityINITIALISATIONRTL reg starts known · realgate cells start X (resetwashes it out)STRUCTUREbehavioural always_ff · vsreal optimised/shared cells(names gone)TIMINGRTL zero-delta · vs realcell/interconnect delays(SDF)CONSTRUCT FIDELITYsim-only constructs(initial, force, # delays)VANISHEXPECTED vs BUGexplained by an axis ->expected · not explained ->real bug12
Figure 1 — RTL and the netlist diverge along four structured axes, not randomly. INITIALISATION: RTL reg starts known/2-state-friendly; real gate cells power up X (reset must wash it out). STRUCTURE: behavioural always_ff vs real, optimised/restructured/shared standard cells (internal names gone). TIMING: RTL zero-delta (events at the edge) vs real cell/interconnect delays (with SDF). CONSTRUCT FIDELITY: sim-only constructs (initial, force, # delays) vanish — they have no gate equivalent. Most RTL-vs-GLS differences are EXPECTED consequences of these axes; a difference NOT explained by an axis is a real bug.

4. Mental Model — RTL is the blueprint, the netlist is the built house

5. Working Example — the D flip-flop, RTL vs netlist, axis by axis

Take the running D flip-flop and read the divergence on each axis.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// RTL (SystemVerilog): behavioural, idealised. One clean reg, a known reset value, zero-delta timing.
module dff (input logic clk, input logic rst_n, input logic d, output logic q);
  always_ff @(posedge clk or negedge rst_n)
    if (!rst_n) q <= 1'b0;   // known reset value
    else        q <= d;
endmodule

The same flip-flop in Verilog and VHDL — all three synthesize to the same cell and diverge from RTL identically (start-X, renamed structure, real clk-to-q):

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// RTL (Verilog-2001): same D flip-flop.
module dff (input clk, input rst_n, input d, output reg q);
  always @(posedge clk or negedge rst_n)
    if (!rst_n) q <= 1'b0;
    else        q <= d;
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- RTL (VHDL): same D flip-flop (async reset). std_logic can hold X, so gate-level X shows in VHDL GLS too.
process(clk, rst_n)
begin
  if rst_n = '0' then         q <= '0';
  elsif rising_edge(clk) then q <= d;
  end if;
end process;
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// NETLIST (representative): the SAME function as a real cell — but INITIALISATION and STRUCTURE differ.
module dff_netlist (input clk, input rst_n, input d, output q);
  DFFRX1 U0 (.D(d), .CK(clk), .RN(rst_n), .Q(q));   // real cell: Q starts X; internal names gone; +real delay w/ SDF
endmodule

The RTL-vs-GLS logs differ on expected axes — and that is the point:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
# RTL SIM (blueprint): known start, zero-delta timing, source signal names.
t=0  dff.q      = 0        <- INITIALISATION axis: RTL reg presents a known value
t=10 (posedge)  q = 1      <- zero-delta: captures instantly
 
# GLS (built house): X at start, real cell, (with SDF) a real clk-to-q.
t=0  U0.Q       = x        <- INITIALISATION axis: real cell powers up X (EXPECTED, not a bug)
t=7  (reset)    U0.Q = 0   <- reset washes out the X
t=10 (posedge)
t=10.3 U0.Q     = 1        <- TIMING axis: real ~0.3ns clk-to-q (with SDF); STRUCTURE: it is U0.Q, not dff.q

Every difference here is explained by an axis: the start-X is initialisation, the U0.Q name is structure, the 0.3 ns delay is timing. There is no unexplained difference — so this design is behaving correctly, just at a different level of reality. The debug skill is spotting the difference that an axis does not explain.

6. Debugging Session — an "RTL mismatch" that is an expected divergence (and the one that isn't)

1

A pile of RTL-vs-GLS differences is investigated as bugs, when three are expected divergences (init, structure, timing) and only one — a flop reset does not reach — is a real defect

EXPLAIN EACH DIFFERENCE BY AN AXIS; FLAG THE UNEXPLAINED
Symptom

A first GLS run 'does not match RTL': signals are X at the start, internal RTL names are gone (cell instances instead), some logic looks combined, and events land at slightly different times. It looks like synthesis corrupted the design, and every difference is filed as a mismatch bug.

Root Cause

Most of the differences are expected divergences, not defects — and the method is to explain each by an axis. The start-X is the initialisation axis (real cells power up unknown; reset is meant to wash it out). The missing internal names and combined logic are the structure axis (synthesis optimised, restructured, and mapped to library cells). The shifted event times are the timing axis (real cell delays under SDF). None of those are bugs — they are the abstraction meeting reality, and they would appear on any correct design. The real bug is the one difference that no axis explains: an X that persists on a specific flop after reset should have washed it out. Initialisation predicts X at power-up that reset clears; a flop whose X survives reset is not explained by the initialisation axis — it is a reset-coverage defect (that flop is off the reset net). By triaging each difference to an axis, the three expected divergences are set aside and the single unexplained one is exposed as the actual bug — in seconds, instead of debugging a stack of non-bugs.

Fix

Account for each RTL-vs-GLS difference with an axis; set aside the expected ones (init X that reset clears, optimised structure, real-delay timing); and investigate only the unexplained residue — here, the flop whose X survives reset — as the real bug (bring it onto the reset). The lesson: RTL and the netlist diverge along four structured axes (initialisation, structure, timing, construct fidelity), so most RTL-vs-GLS differences are expected; explain each difference by an axis and treat only the unexplained residue as a defect — do not fight the expected divergences, and do not miss the real bug hiding among them.

7. Common Mistakes

  • Treating every RTL-vs-GLS difference as a bug. Most are expected divergences (init, structure, timing, vanished constructs) — explain each by an axis before filing it.
  • "Fixing" the netlist to match the RTL waveform. The gate level is closer to silicon; an expected divergence means RTL was the idealisation, not the netlist the error.
  • Missing the real bug among expected ones. The defect is the difference no axis explains (e.g. X that survives reset) — do not let it hide in the pile.
  • Assuming optimised/renamed structure means synthesis broke the design. Restructuring and renaming are the structure axis — synthesis preserves function for defined values.
  • Blaming X-at-start on GLS. X at power-up is the initialisation axis — expected on real cells; only X that persists (past reset) is a bug.

8. Industry Best Practices

  • Triage RTL-vs-GLS differences by axis. Initialisation, structure, timing, construct fidelity — account for each difference, then flag the residue.
  • Expect X at power-up; investigate X that persists. The former is the initialisation axis; the latter is a reset/init bug.
  • Read the netlist as the implementation, not a corrupted RTL. Optimised, renamed, real-timed structure is expected.
  • Keep an axis checklist handy on first GLS. It converts 'nothing matches' into a short list of real candidates.
  • Confirm the residue is a bug before escalating "synthesis broke it". Synthesis preserves defined-value function; the residue is usually an init/reset or a real design issue, not a tool defect.

Senior Engineer Thinking

  • Beginner: "The gate sim doesn't match my RTL — synthesis broke the design."
  • Senior: "How doesn't it match? X at start is initialisation, renamed logic is structure, shifted edges are timing — all expected. Which difference is left unexplained by an axis? That is the bug."

The senior does not compare waveforms pixel-for-pixel; they attribute each difference to a known axis and hunt the one that has no attribution.

Silicon Impact

If you cannot separate expected divergence from real defect, two failures follow. Drown the real bug in a pile of 'mismatches' and the unexplained X — a flop reset never reaches — ships, causing intermittent power-up failures and field returns (Ch0's escape, now understood mechanically). Or waste days 'fixing' expected divergences — editing correct netlist behaviour to match an idealised RTL waveform — burning schedule and risking a new bug. Reading divergence correctly is what keeps both the escape and the wasted effort off the tape-out.

Engineering Checklist

  • Explained each RTL-vs-GLS difference by an axis (init / structure / timing / construct).
  • Set aside expected divergences (start-X that reset clears, optimised names, real-delay edges).
  • Flagged only the unexplained residue as a candidate bug.
  • Confirmed X at power-up is cleared by reset (initialisation), not persisting.
  • Did not edit correct netlist behaviour to match an idealised RTL waveform.

Try Yourself

  1. Simulate the D flip-flop above four-state — first the RTL, then the (representative) netlist cell — holding reset low for a few cycles, then releasing it.
  2. Observe: in the RTL, q starts at a known value; in the gate-level run, q starts X and only becomes known once reset asserts (the initialisation axis).
  3. Change: delay reset assertion by a couple of cycles and re-run the gate-level sim.
  4. Expect: the start-X now persists for those extra cycles before reset clears it — same axis, longer. That transient-vs-persistent read is the judgement you will reuse everywhere.

Any four-state Verilog/VHDL simulator works — open-source or commercial. No specific or paid tool is required.

Interview Perspective

  • Weak: "The gate sim doesn't match my RTL, so synthesis broke the design."
  • Good: "RTL and the netlist differ along known axes — initialisation, structure, timing, vanished constructs — so most differences are expected, not bugs."
  • Senior: "I attribute each difference to an axis and investigate only the unexplained residue. A start-X that reset clears is initialisation; an X that survives reset is a real reset gap — that is the bug."

Quick Revision

Four axes of divergence: initialisation (real cells start X), structure (optimised/renamed cells), timing (real delays, SDF), construct fidelity (sim-only constructs vanish). Most RTL-vs-GLS differences are expected — explain each by an axis; the unexplained residue is the bug. Next: 1.2 opens the "structure" axis — what synthesis actually changes.

9. Interview / Review Questions

10. Key Takeaways

  • RTL is an abstraction; the netlist is the implementation — they diverge along four structured axes, not randomly.
  • The axes: initialisation (real cells start X; reset washes it out), structure (behavioural source vs optimised/renamed library cells), timing (zero-delta vs real delays, SDF), and construct fidelity (sim-only constructs vanish).
  • Most RTL-vs-GLS differences are expected — the skill is to explain each difference by an axis and treat only the unexplained residue as a bug.
  • The signature discipline: X at power-up is expected (initialisation); X that persists past reset is a bug (reset coverage) — and a functional mismatch on defined inputs is real, because synthesis preserves defined-value function.
  • Do not fix the netlist to match the RTL waveform — the gate level is closer to silicon; fighting expected divergences wastes time and risks masking the real defect. 1.2–1.4 detail the mechanisms behind these axes; 1.5 walks them on the D flip-flop.