GLS · Chapter 7 · Reset & Initialization Debug
Uninitialised Flops & the Startup Problem
Every gate-level flip-flop powers up in an unknown state, but not every flop needs a reset, and knowing which do is the heart of the startup problem. Control and state flops such as FSM state, counters, mode bits, and enables must be reset, or the design powers up in an unknown state and does the wrong thing. Datapath flops such as pipeline registers and data buffers are often intentionally left unreset to save area and timing, relying on being loaded with valid data before their value is ever used. An unknown in an unreset flop is therefore benign if it is overwritten before it affects anything, but a real bug if it feeds a control path or is read before being loaded. This lesson draws that line so you neither reset everything blindly nor ignore a dangerous unknown.
Foundation12 min readGLSResetUninitializedDatapathStartup
Chapter 7 · Section 7.2 · Reset & Initialization Debug
Project thread — the counter's state flops and the FSM's state are control flops that must reset (2.6/6.6); a data buffer feeding them might not. This lesson is how you decide which is which.
1. Why Should I Learn This?
"Reset everything" is wrong, and "ignore unreset X" is dangerous — the startup problem lives between them.
- Control/state flops must reset (known startup).
- Datapath flops may start
Xif loaded before use (area/timing savings). - The question for any unreset
X: is it used before it's loaded?
This is the judgement that makes reset debugging precise (and it refines the "reset the FSM" fix of 6.6).
2. Real Silicon Story — the pipeline X that was fine, and the enable X that wasn't
A gate-level run showed X on several flops. The team's first instinct was to reset them all.
Most were pipeline datapath registers — their X was overwritten by valid data a few cycles later, before any consumer used it. Resetting them would have added area and timing for no functional benefit. But one X was on an enable flop feeding control — it was used (gating a write) before being loaded, corrupting behaviour. Only that one needed a reset.
Lesson: an unreset X is only a bug if it is used before it's loaded. Reset control/state flops; let datapath flops start X where they're safely loaded first — don't blanket-reset, don't blanket-ignore.
3. Concept — which flops must reset, and when an X is a bug
Two categories of flop:
- Control / state flops (must reset): FSM state, counters, mode/config, enables, valid bits. An
Xhere immediately affects behaviour — reset is required (2.6/6.6). - Datapath flops (often unreset): pipeline registers, data buffers. Left unreset to save area/timing, relying on a valid load before use.
The startup question for any unreset X:
- Is it used before it's loaded?
- No (overwritten by valid data before any consumer reads it) → benign startup
X. - Yes (feeds control, or read before load) → real bug — reset it or guarantee a load.
- No (overwritten by valid data before any consumer reads it) → benign startup
Two forms of "initialised":
- Reset domain — forced to a known value by reset (control/state).
- Functionally initialised — made valid by the first valid load (datapath), guarded so the
Xwindow is never used.
The nuance (accuracy):
- Not every flop must be reset — blanket reset costs area/timing.
- Not every unreset
Xis safe — one that reaches control is a real bug. - Judge each unreset
Xby use-before-load, not by a blanket rule.
4. Mental Model — a blank notepad is fine until someone reads it
An unreset flop is a blank (garbled) notepad at power-up.
- If you write valid data on it before anyone reads it → the garble never mattered (benign datapath
X). - If someone reads it before you write — or it's a control note that steers decisions — the garble corrupts the outcome (real bug).
- Control/state notes are always read early → keep them pre-cleared (reset).
- Datapath scratchpads → fine to leave blank if you always write before reading.
The question is never "is it blank?" — it's "is it read before it's written?"
5. Working Example — a benign datapath X and a dangerous control X
Two unreset flops, two outcomes:
// DATAPATH flop — unreset, but LOADED before use -> benign X
DFFX1 u_pipe (.D(data_in), .CK(clk), .Q(pipe_q)); // X at power-up
// ... pipe_q is only consumed after 'valid' asserts, by which time it holds real data:
assign result = valid ? pipe_q : '0; // X window never used -> benign
// CONTROL flop — unreset AND used immediately -> real bug
DFFX1 u_en (.D(en_next), .CK(clk), .Q(en)); // X at power-up
assign wr = en & req; // 'en' = X gates a write NOW -> corrupts -> BUGPractical context (representative, tool-neutral):
# Classify an unreset X (tool-neutral):
# control/state flop (FSM, counter, enable, mode)? ....... MUST reset (2.6)
# datapath flop overwritten by valid data before use? .... benign (intentional, area/timing)
# datapath X read/used BEFORE its first valid load? ...... BUG -> reset or guard the load
# Rule: judge by USE-BEFORE-LOAD. Don't blanket-reset (area) or blanket-ignore (missed bug).Benign datapath X vs dangerous control X, as a real waveform:
Datapath X overwritten before use (benign) vs control X used immediately (bug)
8 cycles6. Debugging Session — reset-everything vs the one X that matters
Several flops show X at startup and the reflex is to reset them all, but most are datapath flops safely loaded before use (benign) while one is a control enable used before it is loaded (a real bug) — only that one needs a reset
JUDGE UNRESET X BY USE-BEFORE-LOADMultiple flops are X at power-up. The team proposes resetting all of them to "make the X go away."
A blanket reset misreads the startup problem. Most of the Xs are on datapath flops (pipeline registers, buffers) that are intentionally unreset for area/timing and are overwritten by valid data before any consumer uses them — their X is benign, and resetting them adds cost for no benefit. But one X is on a control flop — an enable that gates a write immediately, before it is ever loaded — so that X corrupts behaviour: a real bug. The correct model is use-before-load: an unreset X matters only if it is used before a valid load. Blanket-resetting hides the distinction (and wastes area); blanket-ignoring would miss the real control X.
Classify each unreset X by use-before-load: reset the control/state flops (FSM state, counters, enables, mode) — their X is used immediately (2.6); leave the datapath flops unreset where a valid load precedes any use (verify the load actually gates the consumer). For the dangerous control X, add a reset (or guarantee a valid load before use). The lesson: not every flop must be reset — control/state flops must, datapath flops often needn't (area/timing) if loaded before use; an unreset X is benign when overwritten before use and a bug when it feeds control or is read before load, so judge by use-before-load, not a blanket rule. (GLS surfaces these Xs; it stays dynamic — STA signs off timing, 0.3.)
7. Common Mistakes
- Blanket-resetting every flop. Wastes area/timing on datapath flops safely loaded before use.
- Blanket-ignoring unreset
X. Misses a controlXused before load. - Not tracing where an unreset
Xis used. Use-before-load is the whole question. - Assuming datapath flops are always safe. Only if the load truly precedes any use.
- Forgetting control/state flops. These always need reset (2.6).
8. Industry Best Practices
- Reset control/state flops; leave datapath flops unreset where loaded-before-use holds.
- Verify the load actually gates the consumer (valid/enable guarding the
Xwindow). - Trace each unreset
Xto its first use — bug only if used before load. - Justify unreset flops (area/timing) — a deliberate choice, documented.
- Don't blanket-reset to silence
X— it hides the real one and costs area.
Senior Engineer Thinking
- Beginner: "Flops are
Xat startup — reset them all." - Senior: "Which are control/state (must reset) and which are datapath (loaded before use)? For each unreset
X: is it used before it's loaded? That's the only one I reset."
The senior classifies by use-before-load, resetting control/state and justifying unreset datapath flops.
Silicon Impact
The startup problem is where area/timing and correctness meet. Reset everything and you burn area and can hurt timing on wide datapaths for no functional gain — a real cost at scale. Ignore all unreset X and a control X used before load (an enable, a mode bit) reaches silicon and causes power-up-dependent misbehaviour (0.3). The engineering answer is neither extreme: reset what's used-before-loaded (control/state), leave what's loaded-before-used (datapath), and verify the guard. That precise judgement — enabled by GLS surfacing every startup X — is what keeps both the die area and the power-up behaviour correct.
Engineering Checklist
- Reset all control/state flops (FSM, counters, enables, mode) (2.6).
- Left datapath flops unreset only where loaded-before-use holds.
- Traced each unreset
Xto its first use (bug only if used before load). - Verified the load guards the consumer (valid/enable).
- Avoided blanket reset (area) and blanket ignore (missed bug).
Try Yourself
- Build an unreset datapath flop consumed only after a
validgate, and an unreset control enable used immediately. - Observe: the datapath
Xis overwritten before use (benign); the controlXcorrupts a gated write (bug). - Change: reset only the control flop.
- Expect: the control
Xclears; the datapath flop still startsXbut never matters. Prove that use-before-load, not blanket reset, is the right rule.
Any free Verilog simulator demonstrates the benign-vs-dangerous unreset X. No paid tool required.
Interview Perspective
- Weak: "Every flop must be reset or you get
X." - Good: "Control/state flops must be reset; datapath flops can start
Xif they're loaded before use." - Senior: "The startup question is use-before-load. Control/state flops are used immediately, so they must reset. Datapath flops are often intentionally unreset for area/timing, safe if a valid load precedes any use. An unreset
Xis benign when overwritten before use and a bug when it feeds control — so I classify each, not blanket-reset or blanket-ignore."
9. Interview / Review Questions
10. Key Takeaways
- Gate-level flops power up
X, but not every flop needs a reset: control/state flops must reset; datapath flops are often intentionally unreset (area/timing). - Datapath flops are safe unreset only if loaded with valid data before their value is used — functionally initialised by the first valid load.
- An unreset
Xis benign if overwritten before use, a real bug if it feeds control or is read before load. - Judge each unreset
Xby use-before-load — don't blanket-reset (wastes area/timing) and don't blanket-ignore (misses a controlX). - GLS surfaces every startup
X; the classification is yours — it stays dynamic (STA signs off, 0.3). Next: 7.3 — asynchronous reset assertion & release.
Quick Revision
Not every flop needs reset. Control/state (FSM, counters, enables) → must reset (used immediately). Datapath (pipelines, buffers) → often unreset (area/timing), safe if loaded before use. An unreset
Xis benign if overwritten before use, a bug if it feeds control / read before load. Judge by use-before-load — no blanket reset, no blanket ignore. Next: 7.3 — async reset assertion & release.