Home VLSI Digital Electronics STA RTL Design About Contact
VLSI · Reset Design

Reset Synchronization

Reset is the most safety-critical signal in a synchronous design — yet it is often the most poorly designed. A reset that de-asserts at the wrong moment puts the entire design into a random, unpredictable state. The ARSR pattern solves this with one elegant principle: assert fast, release slow and synchronized.

1. The Reset-Release Problem

Reset ensures every flip-flop in the design starts from a known, deterministic state at power-on and after any fault condition. The assertion of reset is straightforward — when the reset signal goes active, all downstream flip-flops immediately latch their reset value regardless of the clock. The danger is entirely in the release: when reset is removed, every flip-flop in the chip must exit reset on the same clock edge. If even one flip-flop exits a cycle earlier or later than the others, the FSM controlling the entire data path will be in an inconsistent state — and that inconsistency can propagate into data corruption, bus protocol violations, or a deadlocked system.

The root cause is metastability. When any signal — including reset — transitions within the setup or hold window of a flip-flop's clock edge, the flip-flop may enter a metastable state and resolve to either 0 or 1 non-deterministically. For synchronous signals, the solution is simply to register them before use. But reset is special: it is often driven from an asynchronous source (a power-on circuit, an external pin, or a watchdog timer) that has no timing relationship with the chip's clock. A purely synchronous reset cannot work here because it requires the clock to already be running — which defeats the purpose of power-on reset. A purely asynchronous reset can assert correctly but cannot release safely. The ARSR pattern solves both halves of this contradiction.

✕ Purely Async Reset — dangerous release
// Both assert AND de-assert asynchronous always_ff @(posedge clk or negedge rst_n) if (!rst_n) q <= 1'b0; else q <= d; // Problem: if rst_n goes 1 near a clk edge, // different FFs exit reset on different cycles
✓ ARSR — async assert, sync de-assert
// rst_sync is driven by the synchronizer below always_ff @(posedge clk or negedge rst_sync_n) if (!rst_sync_n) q <= 1'b0; else q <= d; // All FFs now exit reset on same clock edge

If a purely asynchronous reset de-asserts within the setup/hold window of a clock edge, some flip-flops in the chip see the de-assertion before the edge and others after — they exit reset on different clock cycles, creating a brief window of random FSM state.

2. The ARSR Reset Synchronizer

The Async-Assert Synchronous-De-assert (ARSR) pattern uses two flip-flops whose asynchronous reset inputs are tied to the raw reset signal. The D inputs are tied to logic 1 (VCC). This creates a 2-stage shift register that shifts in '1's on clock edges when reset is de-asserted.

// Standard 2-FF reset synchronizer — industry-standard pattern module rst_sync ( input logic clk, input logic async_rst_n, // raw async reset (active-low) output logic sync_rst_n // synchronized reset (active-low) ); logic [1:0] sync_chain; always_ff @(posedge clk or negedge async_rst_n) begin if (!async_rst_n) sync_chain <= 2'b00; // async assert: both FFs reset immediately else sync_chain <= {sync_chain[0], 1'b1}; // shift 1's in on clk end assign sync_rst_n = sync_chain[1]; // two cycles after de-assert endmodule

How It Works Step by Step

EventFF1 (Q1)FF2 (Q2 = sync_rst_n)What Happens
async_rst_n = 0 (assert)00Both FFs reset immediately, no clock needed. Reset propagates to all downstream FFs via sync_rst_n.
async_rst_n = 1 (de-assert)00Nothing yet — waiting for clock edge.
First posedge clk after de-assert10FF1 captures '1'. sync_rst_n still 0. All design FFs still in reset.
Second posedge clk11FF2 captures '1'. sync_rst_n goes to 1. All design FFs exit reset simultaneously.

Key insight: The two-cycle delay gives the de-assertion signal time to propagate through one FF before reaching the output. If FF1's de-assertion causes metastability, FF2 has a full clock period to resolve it before sync_rst_n is sampled by the design's flip-flops.

3. Reset Strategy Comparison

Three reset strategies are commonly discussed in VLSI design: purely synchronous, purely asynchronous, and ARSR (the hybrid). Each has a specific failure mode that disqualifies it from being the universal answer. The table below captures the trade-offs. In practice, ARSR is the standard for any design that must work at power-on with an asynchronous reset source — which covers the vast majority of ASIC and FPGA designs. The 3-FF variant is used when MTBF (Mean Time Between Failures from metastability) requirements are extreme, such as in high-frequency designs or safety-critical automotive applications where a longer resolution time is budgeted into the FMEA analysis.

StrategyAssertDe-assertWorks if clock absent?Metastability-safe?
Purely SyncOn next clock edgeOn next clock edgeNo — never assertsYes
Purely AsyncImmediatelyImmediatelyYesNo — de-assert unsafe
ARSR (2-FF sync)ImmediatelySynchronized (2 cycles)Yes (assert), Yes (clock needed for release)Yes
ARSR (3-FF sync)ImmediatelySynchronized (3 cycles)YesHigher MTBF than 2-FF

4. Multi-Clock-Domain Reset Distribution

A real SoC has many clock domains — CPU, DSP, memory controller, USB PHY, PCIe, each running at different frequencies and phases. Each domain needs its own reset synchronizer, because the 2-FF synchronizer is clocked by the domain's local clock and can only guarantee synchronous de-assertion relative to that clock. Sharing a single, un-synchronized reset signal across multiple clock domains is a common and dangerous mistake: the single shared reset has no timing guarantee with respect to most of the domains it feeds.

When each domain gets its own synchronizer, they will exit reset at slightly different absolute times — the CPU domain exits reset 2 CPU cycles after de-assertion, the USB domain exits 2 USB cycles later. The domain that exits reset last must set a global "all-domains-ready" signal before any inter-domain transactions are allowed. Tools like Mentor Questa RDC, Synopsys SpyGlass RDC, and Cadence JasperGold RDC perform formal verification of reset domain crossings to catch cases where inter-domain logic is driven before all domains have properly exited reset.

// Each clock domain gets its own rst_sync instance module top ( input logic raw_rst_n, input logic clk_cpu, clk_dsp, clk_usb ); logic rst_cpu_n, rst_dsp_n, rst_usb_n; // Separate synchronizer per domain — critical! rst_sync u_rst_cpu (.clk(clk_cpu), .async_rst_n(raw_rst_n), .sync_rst_n(rst_cpu_n)); rst_sync u_rst_dsp (.clk(clk_dsp), .async_rst_n(raw_rst_n), .sync_rst_n(rst_dsp_n)); rst_sync u_rst_usb (.clk(clk_usb), .async_rst_n(raw_rst_n), .sync_rst_n(rst_usb_n)); // Each subsystem uses its domain-local reset cpu_core u_cpu (.clk(clk_cpu), .rst_n(rst_cpu_n), ...); dsp_core u_dsp (.clk(clk_dsp), .rst_n(rst_dsp_n), ...); usb_phy u_usb (.clk(clk_usb), .rst_n(rst_usb_n), ...); endmodule

Reset domain crossing (RDC): When signals flow between two domains that exit reset at different absolute times, handshaking logic must account for the ordering. The domain that de-asserts reset last sets the "system ready" signal. Tools like Mentor Questa RDC verify reset domain crossing correctness.

5. Power-On Reset (POR)

Power-on reset generates the initial reset pulse when VDD first ramps up from zero. On many ASIC platforms, the POR circuit is implemented in analog cells in the standard cell library — it uses a voltage comparator or RC filter to detect when the supply has crossed a safe threshold and the PLL has locked. The POR output feeds the async_rst_n input of every domain's ARSR synchronizer, ensuring that reset stays asserted through the entire supply ramp until digital logic can operate correctly. The POR circuit must keep the chip in reset until all of the following conditions are met:

VDD Stable

Supply must exceed a minimum threshold (e.g., 0.9×VDD_nom) before digital logic behaves correctly. POR monitors the supply ramp.

PLL Locked

The system clock must be stable before reset releases. A PLL-locked signal gates the reset de-assertion in most SoC designs.

Brown-out

If VDD drops below a threshold during operation (brown-out), the POR circuit re-asserts reset to prevent data corruption.

6. RTL Coding Rules and Common Mistakes

Following consistent coding conventions for reset prevents whole categories of bugs. The most important rule: every synchronous module should have exactly one reset input, and that reset should be the synchronized output of an ARSR synchronizer, never the raw asynchronous reset wire. Propagating the raw async_rst_n directly into flip-flops that also have a synchronous clock connection bypasses the synchronizer entirely — a common error in systems where the synchronizer lives at the top level but sub-module engineers connect the wrong net.

A second common mistake is using if (!rst_n) ... else if (rst_n) ... with both async and sync branches in the same always_ff block, which some synthesis tools interpret as a hybrid reset — asserting asynchronously but only releasing on a clock edge driven by the conditional. This creates synthesis-versus-simulation mismatches and should be avoided. Use separate always_ff blocks for async-assert and synchronous logic, or use the ARSR synchronizer to create a clean synchronous reset and use always_ff @(posedge clk) with a simple if (!rst_sync_n) throughout the design.

A third mistake is using reset inside combinational always_comb blocks. Reset is a state-initialization mechanism and belongs only in sequential always blocks. Checking reset in combinational logic creates a level-sensitive behavior that will not be synthesized correctly and cannot be properly analyzed by STA tools.

Interactive: ARSR Reset Simulator

Assert and release the async reset, pulse the clock, and watch the 2-FF synchronizer shift reset de-assertion through to the output.

Controls

Release Status:
SAFE
Assert reset, then release it close to a clock edge to see METASTABLE RISK trigger.
CLK RST_IN FF1 (Q1) SYNC_OUT

FAQ

ARSR (Async-assert Sync-de-assert) asserts reset immediately without waiting for a clock edge — so the chip enters reset instantly even if the clock is absent. De-assertion is synchronized to the clock by passing the de-assert signal through two flip-flops that are themselves asynchronously reset. This ensures all downstream flip-flops exit reset on exactly the same clock edge.
A synchronous reset requires the clock to be running during reset assertion — which may not be guaranteed at power-on if the PLL hasn't locked yet. If the clock is absent or glitching, a synchronous reset never asserts, leaving the design in an unknown state. ARSR solves this by asserting asynchronously even without a clock.
A purely asynchronous reset (both assert and de-assert asynchronous) can cause different flip-flops to exit reset on different clock cycles if the de-assertion edge falls near a clock edge. Some FFs see the de-assertion before the edge and others after — this creates a brief period of random FSM states, which causes immediate functional failures.
Each clock domain needs its own reset synchronizer — the raw reset signal passes through a 2-FF synchronizer clocked by each domain's clock. This ensures each domain exits reset synchronously with respect to its own clock. The domain that exits reset last sets the global ready signal. Never share an un-synchronized reset across multiple clock domains.