GLS · Chapter 14 · Industry Case Studies
Case Study — DFF: From RTL to a Clean GLS Run
This is the first case study and the hello-world of gate-level simulation. It takes the simplest design, a D flip-flop, from RTL all the way to a clean gate-level run, shipping the full artifact set the way a real signoff does. It ships the RTL in three languages, a representative synthesized netlist using a reset flop cell, an adapted testbench, an expected log, and a debug walkthrough. The signature behavior is the one you will see over and over: the flop powers up with an unknown X, the X clears when reset asserts, and afterward Q follows D. The bar this case sets, carried through the rest of the chapter, is what clean GLS means, no unexplained X after reset. The design is deliberately minimal so the end-to-end flow and the clean-GLS bar are clear before the designs get bigger.
Foundation12 min readGLSCase StudyDFFClean GLSReset
Chapter 14 · Section 14.1 · Industry Case Studies
Project thread — this case begins the thread: a single D flip-flop. 14.2 adds SDF timing to a counter; 14.3 does X/reset signoff on the FSM; 14.4–14.6 scale to peripherals and the mini-SoC.
1. Why Should I Learn This?
Before scaling to a SoC, you need the end-to-end flow and the clean-GLS bar on the simplest possible design.
- The full artifact set (RTL → netlist → TB → log) in miniature.
- The canonical clean-GLS story: power-up
X→ reset →QfollowsD. - Clean GLS = no unexplained
X— the bar the whole chapter uses.
This is the template every later case follows.
2. Real Silicon Story — the "broken" flop that was textbook-correct
A new engineer ran GLS on a single flop, saw X at time 0, and reported the netlist as broken.
It was textbook-correct GLS. The flop powers up X (real flops do, 2.6); the testbench simply hadn't asserted reset yet. Once reset was applied, the X cleared and Q followed D — a clean run. The "bug" was an expectation mismatch: X at power-up is expected, and clean GLS means no X that reset doesn't explain.
Lesson: even the simplest GLS run shows power-up X — and that's correct. Clean GLS is no unexplained X: assert reset, and the flop behaves.
3. Concept — the DFF case, end to end
The design: a single D flip-flop with reset — the first project-thread element.
The end-to-end flow (the template):
- RTL — the flop in SV/Verilog/VHDL.
- Synthesis → netlist — mapped to a reset flop cell (
DFFRX1,D/CK/RN/Q). - Adapted testbench (Chapter 5) — reference ports /
bind, drive clear of the edge, strobe after settling, handleX, apply a proper reset. - Run zero-delay GLS (no SDF needed here; timing is 14.2).
- Compare to the expected log and confirm clean.
The signature behavior:
- Power-up:
Q = X(uninitialized, 2.6). - Reset asserted:
Q = 0(reset row of the flop's model, 2.3). - Reset released, clocking:
QfollowsD.
Clean GLS (the bar):
- No unexplained
X— the onlyXis the power-up one, explained and cleared by reset. - (Timing correctness — clk-to-Q, setup/hold — is 14.2, with SDF; this case is functional/
X/reset.)
Scope (accuracy):
- Clean-GLS here means no unexplained
X, not a timing proof (that's STA / the SDF run, 14.2); GLS stays dynamic (0.3).
4. Mental Model — the first brick, laid perfectly
The DFF case is the first brick of the SoC wall — and you lay it perfectly so the pattern is clear.
- One flop, the whole flow in miniature: RTL → netlist → adapted TB → clean run.
- Its only
Xis the power-up one — expected, and explained by reset. - Get this right — the flow, the artifact set, the clean-GLS bar — and every bigger case (timing, X-cleanup, peripherals, SoC) is the same pattern, more bricks.
Lay the first brick perfectly; the wall follows the pattern.
5. Working Example — the full DFF artifact set
The RTL (tri-HDL):
// SystemVerilog — D flip-flop with sync active-low reset
module dff (input logic clk, rst_n, d, output logic q);
always_ff @(posedge clk) if (!rst_n) q <= 1'b0; else q <= d;
endmodule// Verilog-2001 — same flop
module dff (clk, rst_n, d, q);
input clk, rst_n, d; output reg q;
always @(posedge clk) if (!rst_n) q <= 1'b0; else q <= d;
endmodule-- VHDL — same flop
library ieee; use ieee.std_logic_1164.all;
entity dff is port (clk, rst_n, d : in std_logic; q : out std_logic); end entity;
architecture rtl of dff is begin
process (clk) begin
if rising_edge(clk) then if rst_n = '0' then q <= '0'; else q <= d; end if; end if;
end process;
end architecture;The netlist, testbench, and expected log:
// Synthesized netlist — REPRESENTATIVE: a reset flop cell
module dff (clk, rst_n, d, q);
input clk, rst_n, d; output q;
DFFRX1 u_q (.D(d), .CK(clk), .RN(rst_n), .Q(q)); // Q powers up X until RN asserts (2.6/2.3)
endmodule// Adapted testbench — REPRESENTATIVE (Chapter 5): proper reset, strobe, X-aware
module tb_dff;
logic clk = 0, rst_n, d; logic q;
dff u_dut (.clk(clk), .rst_n(rst_n), .d(d), .q(q));
always #5 clk = ~clk;
default clocking cb @(posedge clk); input #3 q; endclocking // strobe after settle (5.4)
initial begin
rst_n = 0; d = 0; // hold reset (clears power-up X, 2.6)
repeat (2) @(posedge clk); #2 rst_n = 1; // release reset a skew after the edge (5.3)
#2 d = 1; @(cb); // drive clear of the edge; sample on strobe
if ($isunknown(cb.q)) $error("unexpected X after reset"); // X-aware (5.4)
end
endmodule# Expected log — REPRESENTATIVE (the clean-GLS signature):
# t=0 q = x (power-up X -- EXPECTED, 2.6)
# t=5 q = 0 (reset asserted -> Q=0)
# t=25 q = 0->1 (reset released, d=1 -> Q follows D)
# result: CLEAN -- no UNEXPLAINED X (the only X is the power-up one, cleared by reset)Practical context (representative, tool-neutral):
gls/case_dff/
rtl/dff.v netlist/dff.vg tb/tb_dff.v expected/dff.log
# Flow: synth(rtl) -> netlist -> compile(netlist + cells + tb) -> zero-delay GLS -> diff vs expected.log
# Clean-GLS bar: no UNEXPLAINED X (power-up X cleared by reset). Timing (SDF) is the NEXT case (14.2).The DFF's clean-GLS signature, as a real waveform:
DFF clean GLS: power-up X → reset clears to 0 → Q follows D (no unexplained X)
9 cycles6. Debugging Session — "the flop is broken" (it's textbook-clean)
A single-flop GLS run shows X at power-up and is reported as a broken netlist, but it is textbook-correct: the flop powers up X and clears on reset, and clean GLS means no unexplained X — assert reset and Q follows D
POWER-UP X IS EXPECTED; CLEAN GLS = NO UNEXPLAINED XA GLS run of a single flop shows X at time 0, reported as a broken netlist.
Textbook-correct GLS, an expectation mismatch. The flop powers up X — real flops (and their models, 2.3) do, 2.6 — and the testbench simply hasn't asserted reset yet at time 0. This X is expected, not a netlist defect. Once reset asserts, the flop's model clears Q to 0 (its reset row), and after reset release Q follows D — a clean run. The confusion is the clean-GLS bar: clean does not mean no X ever; it means no unexplained X — and the power-up X is explained (uninitialized state) and resolved (by reset). Reporting it as broken is reading an expected modelling behavior as a bug (the 12.6 catalog, family B).
Recognize the power-up X as expected, ensure the testbench asserts a proper reset before comparing (5.x/2.6), and confirm the run is clean by the bar: no unexplained X (the power-up X cleared by reset), with Q following D afterward — matching the expected log. Nothing in the netlist needs fixing. The lesson: even the simplest GLS run shows an expected power-up X that reset clears — clean GLS means no unexplained X, not no X ever; assert reset, and Q follows D. This case establishes the end-to-end flow (RTL → netlist → adapted TB → clean GLS) and the clean-GLS bar the rest of the chapter builds on. (Clean here is functional/X/reset — timing signoff is the SDF run of 14.2 and STA; GLS stays dynamic, 0.3.)
7. Common Mistakes
- Reporting power-up
Xas a broken netlist. It's expected (2.6). - Thinking clean means no
Xever. Clean = no unexplainedX. - Not asserting a proper reset before comparing (5.x).
- Using an un-adapted RTL testbench on the netlist (5.1) — ports/strobe/reset.
- Expecting timing correctness from this run — that's the SDF run (14.2).
8. Industry Best Practices
- Ship the full artifact set (RTL, netlist, TB, expected log) even for the simplest design.
- Adapt the testbench (ports/
bind, strobe, proper reset — Ch5). - Define clean GLS as no unexplained
Xand compare to the expected log. - Recognize expected power-up
X— explained by reset. - Add timing (SDF) as a separate run (14.2), not this one.
Senior Engineer Thinking
- Beginner: "
Xat time 0 — the netlist is broken." - Senior: "That's the flop powering up
X— expected. Did the TB assert reset? Clean GLS is no unexplainedX— the power-upXclears on reset andQfollowsD. Compare to the expected log."
The senior reads power-up X as expected and holds the clean-GLS bar at no unexplained X.
Silicon Impact
The DFF case looks trivial, but it establishes the two things every later case (and every real signoff) depends on: the end-to-end flow (RTL → synth → netlist → adapted TB → GLS → compare) and the clean-GLS bar (no unexplained X). Getting these clear on one flop prevents the two most common early mistakes at scale — reporting expected power-up X as bugs (wasting effort, 12.6-B) and mis-defining 'clean' (either chasing every X or, worse, waiving real ones). A team fluent in the DFF case reads a SoC's power-up X correctly, ships the full artifact set as a matter of course, and knows that functional/X/reset clean (this case) and timing clean (14.2/STA) are separate bars. The smallest case teaches the discipline the biggest one requires.
Engineering Checklist
- Shipped the full artifact set (RTL, netlist, TB, expected log).
- Adapted the testbench (ports/
bind, strobe, proper reset — Ch5). - Recognized power-up
Xas expected (2.6). - Confirmed clean = no unexplained
X(power-upXcleared by reset),QfollowsD. - Deferred timing to the SDF run (14.2) / STA.
Try Yourself
- Synthesize the DFF, write the adapted testbench, and run zero-delay GLS.
- Observe:
q = Xat power-up — expected (2.6). - Change: assert reset, then drive
dand sample on a strobe. - Expect:
qclears to 0 on reset, then followsd— a clean run (no unexplainedX) matching the expected log. Then remove the reset and watchqstayX— proving reset is what clears it.
Any free Verilog simulator runs the DFF case end-to-end. No paid tool required.
Interview Perspective
- Weak: "The flop is
Xat the start, so the netlist is wrong." - Good: "The flop powers up
Xand clears on reset; clean GLS meansQfollowsDafter reset." - Senior: "The DFF case is the end-to-end flow in miniature: RTL → netlist → adapted TB → clean GLS. Its only
Xis the expected power-up one, cleared by reset — so clean means no unexplainedX, not noXever. Timing (clk-to-Q, setup/hold) is a separate SDF run (14.2) and STA. Get this one right and every bigger case is the same pattern."
9. Interview / Review Questions
10. Key Takeaways
- The DFF case is the hello-world of GLS — the simplest design taken end-to-end (RTL → synth → netlist → adapted TB → zero-delay GLS → compare to expected log), shipping the full artifact set.
- The signature behavior: the flop powers up
X(2.6), reset clears it to 0, thenQfollowsD. - Clean GLS = no unexplained
X— the onlyXis the power-up one, explained and cleared by reset (not noXever). - The testbench must be adapted (ports/
bind, timing-aware,X-aware strobe, proper reset — Chapter 5), and power-upXmust be read as expected (not a broken netlist). - This case is functional/
X/reset (zero-delay) — timing (clk-to-Q, setup/hold) is the SDF run of 14.2 and STA; GLS stays dynamic (0.3). It sets the flow and clean-GLS bar the rest of the chapter builds on. Next: 14.2 — Counter: full-timing GLS with SDF.
Quick Revision
DFF case = hello-world GLS, end-to-end: RTL (tri-HDL) → netlist (
DFFRX1) → adapted TB (Ch5) → zero-delay GLS → compare expected log. Signature: power-upX(2.6) → reset0→QfollowsD. Clean GLS = no UNEXPLAINEDX(power-upXexplained/cleared by reset) — not noXever. Functional/X/reset here; timing = 14.2 (SDF) + STA. Sets the flow + clean-bar for the chapter. Next: 14.2 — Counter: full-timing GLS with SDF.