Skip to content

GLS · Chapter 7 · Reset & Initialization Debug

Asynchronous Reset Assertion & Release

An asynchronous reset has an easy half and a dangerous half. Asserting it is easy, because it acts immediately and independent of the clock, so forcing flops into reset is inherently safe. Releasing it is where designs break. If reset deasserts too close to a clock edge, the flop is caught between still resetting and now capturing, and it can go metastable. Gate-level simulation models this as two timing checks, recovery and removal, and violating either injects an unknown X value. The standard fix is a reset synchronizer that asserts asynchronously but deasserts synchronously to the clock, so release always lands clear of the edge. This lesson explains recovery and removal checks and the synchronizer, and notes that these checks are dynamic and stimulus-limited, with static timing analysis doing the exhaustive reset-timing check.

Foundation12 min readGLSAsync ResetRecoveryRemovalSynchronizer

Chapter 7 · Section 7.3 · Reset & Initialization Debug

Project thread — the FSM and counter use async reset (2.6/6.6). Asserting it was easy; this lesson is about releasing it safely so the design doesn't go metastable at reset deassertion.

1. Why Should I Learn This?

The bug isn't asserting reset — it's letting go of it near a clock edge.

  • Assertion is safe (immediate); release near an edge risks metastability.
  • GLS models it as $recovery/$removal violations → notifier X (2.5).
  • The fix is a reset synchronizer (async assert, sync deassert).

This is the timing dimension of reset, bridging reset debug (Ch7) to timing-violation debug (Ch8).

2. Real Silicon Story — the reset release that injected X

A design asserted reset cleanly, but on deassertion a flop showed X for a cycle, with a $recovery message in the log.

Reset was released asynchronously, and its edge happened to land just before a clock edge — inside the flop's recovery window. The flop couldn't cleanly decide "resetting" vs "capturing," so GLS flagged a recovery violation and injected X (the metastability risk). Adding a reset synchronizer — deasserting reset synchronously to the clock — moved release clear of the edge and the X disappeared.

Lesson: async reset release is the hazard, not assertion. Deasserting near a clock edge causes recovery/removal violations; synchronize the release.

3. Concept — recovery, removal, and the synchronizer

Assertion (safe):

  • Async reset asserts immediately, independent of the clock (7.1). No timing risk.

Release (dangerous):

  • Deasserting reset too close to a clock edge can leave the flop metastable (caught between reset and capture).
  • Two timing checks model the safe window:
    • $recovery — reset must be released a safe time before the active clock edge.
    • $removal — reset must stay asserted a safe time after the active clock edge.
  • Violate either → notifier fires → X (2.5) — the simulator flagging the metastability risk.

The fix — reset synchronizer:

  • Assert asynchronously (immediate, so reset is guaranteed even without a clock).
  • Deassert synchronously to the clock (release aligned clear of the edge).
  • A small 2-flop synchronizer on the reset-release path does this.

Scope (accuracy):

  • GLS recovery/removal checks are dynamic and stimulus-limited — they fire only if the stimulus deasserts reset in the window (like all timing checks, 2.5).
  • STA does the exhaustive reset-timing check across all paths/corners — GLS does not prove reset timing (0.3).
Async reset: assertion immediate/safe; release near clock edge risks recovery/removal violation and X; synchronizer deasserts synchronouslythen releasetoo closesynchronizeAssert async →immediate (SAFE)Release nearclock edge?Inrecovery/removalwindow →notifier XReset synchronizer:deassert SYNC toclockRelease clear ofedge → clean
Figure 1 — async reset assertion vs release (representative). ASSERTION is immediate and clock-independent -> safe. RELEASE (deassertion) near a clock edge is dangerous: the flop can go metastable. Two checks guard the safe window -- $recovery (reset released a safe time BEFORE the edge) and $removal (reset held a safe time AFTER the edge). A violation fires a notifier -> X (2.5). Fix: a reset synchronizer -- assert async (immediate), deassert SYNC to the clock so release lands clear of the edge.

4. Mental Model — assert like a fire alarm, release like a scheduled all-clear

Reset is a building fire alarm.

  • Assertion = pulling the alarm: you want it to go off instantly, no matter what (async, immediate — safe).
  • Release = the all-clear: if you shout "all clear" at the exact moment people are deciding whether to move (the clock edge), some freeze in confusion (metastability).
  • The synchronizer is announcing the all-clear at a scheduled, safe moment (synchronous deassertion) — everyone hears it cleanly, clear of the decision point.

Pull the alarm anytime; give the all-clear on schedule.

5. Working Example — a reset synchronizer and the recovery window

A representative reset synchronizer (async assert, sync deassert):

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Reset synchronizer — REPRESENTATIVE. Assert ASYNC (immediate), deassert SYNC to clk.
logic rff1, rff2;
always_ff @(posedge clk or negedge async_rst_n)
  if (!async_rst_n) begin rff1 <= 0; rff2 <= 0; end   // ASSERT: immediate (async)
  else              begin rff1 <= 1; rff2 <= rff1; end // DEASSERT: synchronous, 2 flops
assign rst_n = rff2;   // synchronized reset: asserts immediately, releases clear of the edge

The timing-check declarations that guard release (in the flop model):

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Reset-release timing checks in the flop's specify block — REPRESENTATIVE (2.5)
$recovery (posedge RN, posedge CK, 0, notify);   // reset released a safe time BEFORE the edge
$removal  (posedge RN, posedge CK, 0, notify);   // reset held a safe time AFTER the edge
// Deassert inside this window -> notifier toggles -> Q = X (metastability risk)

Practical context (representative, tool-neutral):

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
# Reset-release checklist (tool-neutral):
#   assert:   async, immediate -> safe (no timing)
#   release:  must land CLEAR of the clock edge (outside recovery/removal)
#   symptom:  X at deassertion + $recovery/$removal message -> release too near the edge
#   fix:      reset synchronizer (async assert, SYNC deassert)
#   signoff:  STA checks reset recovery/removal EXHAUSTIVELY -> GLS is dynamic, not the proof

Async release near the edge (violation) vs synchronized release (clean), as a real waveform:

Async reset release near the clock edge (recovery violation → X) vs synchronized release (clean)

8 cycles
An async reset deasserting just before a clock edge causes a recovery violation and X; a synchronized release lands clear of the edge and is cleanasync release → recovery Xasync release → recove…sync release → cleansync release → cleanclkrst_async (release near edge)q_asyncXrst_sync (synchronized)q_synct0t1t2t3t4t5t6t7
Representative. rst_async releases just before a clock edge — inside the recovery window — so the flop q_async goes X (recovery violation, notifier). rst_sync (through a synchronizer) releases clear of the edge, so q_sync captures cleanly. Assertion was safe in both; only the release timing differed.

6. Debugging Session — X at reset deassertion (a recovery violation)

1

A flop goes X at reset deassertion with a recovery message, and the reset logic is suspected — but the async reset released too close to a clock edge, inside the recovery window, and the fix is a reset synchronizer that deasserts synchronously

ASYNC RELEASE NEAR THE EDGE = RECOVERY/REMOVAL X
Symptom

Reset asserts fine, but on deassertion a flop shows X for a cycle, with a $recovery (or $removal) message in the log.

Root Cause

The async reset released too close to a clock edge, inside the flop's recovery/removal window. At deassertion the flop is caught between "still in reset" and "now capturing," a metastability risk that GLS models as a $recovery/$removal violation — the check fires a notifier and injects X (2.5). Note the asymmetry from 7.1: assertion was safe (immediate, clock-independent), but the release has timing, because deassertion competes with the clock edge. It is not a reset-logic error per se — it is an unsynchronized reset release landing in the danger window.

Fix

Add a reset synchronizer: assert asynchronously (immediate, so reset is guaranteed even without a clock) but deassert synchronously to the clock, so release always lands clear of the edge (outside recovery/removal). A small 2-flop synchronizer on the release path does it. The lesson: async reset assertion is safe, but release near a clock edge causes $recovery/$removal violations (notifier X, the metastability risk) — deassert reset synchronously via a reset synchronizer. Two scope notes: GLS recovery/removal checks are dynamic and stimulus-limited (they fire only if your stimulus deasserts in the window, 2.5); the exhaustive reset-timing check is STA across paths/corners — GLS does not prove reset timing (0.3).

7. Common Mistakes

  • Treating reset release like assertion (timing-free). Release near an edge has recovery/removal timing.
  • Deasserting reset asynchronously. Use a synchronizer (async assert, sync deassert).
  • Ignoring a $recovery/$removal message. It's the reset-release metastability flag.
  • Assuming GLS proves reset timing. Its checks are dynamic/stimulus-limited; STA is exhaustive (0.3).
  • Confusing recovery and removal. Recovery = released before the edge; removal = held after it.

8. Industry Best Practices

  • Assert async, deassert sync — the reset-synchronizer pattern.
  • Keep reset release clear of the clock edge (outside recovery/removal).
  • Read $recovery/$removal messages as reset-release metastability flags.
  • Sign off reset timing with STA (exhaustive), use GLS to confirm dynamically.
  • Synchronize per clock domain — each domain's reset release to its own clock.

Senior Engineer Thinking

  • Beginner: "Reset works when I assert it, but I get X when I release — reset is flaky."
  • Senior: "Assertion is safe; the release landed in the recovery window. I'll deassert reset synchronously with a synchronizer — and remember STA, not GLS, proves reset timing exhaustively."

The senior treats reset release as a timing event and synchronizes deassertion, deferring reset-timing signoff to STA.

Silicon Impact

Reset-release metastability is a real, classic silicon failure: an unsynchronized async reset deasserting near a clock edge can leave flops metastable at bring-up, causing intermittent, unreproducible power-up failures — some flops resolving one way, some another. GLS's recovery/removal X is the simulation flag for exactly this hazard, and the reset synchronizer is the standard, cheap fix. But because GLS checks are stimulus-limited, STA's exhaustive recovery/removal analysis is the signoff — GLS confirms the synchronizer works dynamically; STA proves the release timing across all paths and corners. Together they keep reset-release metastability off the tape-out.

Engineering Checklist

  • Asserted async, deasserted sync (reset synchronizer).
  • Kept reset release clear of the clock edge (outside recovery/removal).
  • Read $recovery/$removal messages as release metastability flags.
  • Deferred exhaustive reset-timing to STA (0.3).
  • Synchronized reset release per clock domain.

Try Yourself

  1. Deassert an async reset one step before a clock edge (inside the recovery window) — observe X and a $recovery message.
  2. Observe: the release timing, not assertion, caused it.
  3. Change: route reset through a 2-flop synchronizer (async assert, sync deassert).
  4. Expect: release now lands clear of the edge — clean, no X. Then recall: STA checks this exhaustively; GLS only where your stimulus exercised it.

Any free Verilog simulator with $recovery/$removal checks reproduces this. No paid tool required.

Interview Perspective

  • Weak: "Async reset is simple — just assert and deassert it."
  • Good: "Assertion is immediate/safe; deasserting near a clock edge causes recovery/removal violations, so you synchronize the release."
  • Senior: "Async reset assertion is clock-independent and safe; the release competes with the clock edge, so a deassertion in the recovery/removal window flags metastability as notifier X. I use a reset synchronizer — async assert, sync deassert — per clock domain. And GLS's checks are dynamic/stimulus-limited; STA does the exhaustive reset-timing signoff."

9. Interview / Review Questions

10. Key Takeaways

  • Async reset assertion is safe (immediate, clock-independent, 7.1); the release (deassertion) is the hazard.
  • Deasserting reset too close to a clock edge risks metastability, modelled in GLS as $recovery (released before the edge) and $removal (held after the edge) violations → notifier X (2.5).
  • The fix is a reset synchronizer: assert asynchronously (immediate) but deassert synchronously to the clock, so release lands clear of the edge.
  • GLS recovery/removal checks are dynamic and stimulus-limitedSTA does the exhaustive reset-timing check; GLS does not prove reset timing (0.3).
  • Synchronize reset release per clock domain. Next: 7.4 — reset sequencing across a design.

Quick Revision

Async reset: assert = safe (immediate); RELEASE = danger. Deassert near a clock edge → metastability → $recovery (release before edge) / $removal (hold after edge) violation → notifier X (2.5). Fix: reset synchronizer (async assert, sync deassert), per clock domain. GLS checks are dynamic/stimulus-limited; STA is the exhaustive reset-timing signoff. Next: 7.4 — reset sequencing.