Sync reset used as async reset

2026-05-22

Stack Overflow: View Question

Tags: verilog, fpga

Score: 0 | Views: 44

The asker sees code shaped like this:

always @(posedge clk or negedge sync_rst_n)
    if (!sync_rst_n) q <= 0;
    else             q <= d;

where sync_rst_n is the output of a two-flop synchronizer fed by an external asynchronous reset. Their intuition is that this looks wrong — you've gone to the trouble of synchronizing the reset, only to then expose it again as an asynchronous edge in the sensitivity list. Why bother synchronizing at all?

Why this is actually the canonical pattern. What's being described is the textbook reset synchronizer (sometimes called "asynchronous assertion, synchronous deassertion"). The motivation isn't to make the reset purely synchronous — it's to fix the one specific failure mode a fully async reset has: if the external reset is deasserted too close to a clock edge, individual flops in the design can come out of reset on different cycles, leading to metastability or inconsistent initial state. By passing reset deassertion through two flops clocked by clk, you guarantee that when downstream flops see sync_rst_n go high, it does so cleanly relative to clk, with enough recovery/removal margin.

Why the sensitivity list still lists negedge sync_rst_n. The assertion of reset should still be asynchronous: you want every flop in the design to drop into reset immediately, without waiting for a clock that may not be running (e.g., during power-up, PLL not locked, clock gated). Putting sync_rst_n in the sensitivity list preserves async assertion. The synchronizer only buys you clean deassertion.

Approach to verifying the pattern is correct:

Gotchas: per clock domain you need a separate synchronizer — a single sync_rst_n shared across domains defeats the purpose. Xilinx UG949 and Cliff Cummings' SNUG 2003 paper "Synthesis and Scripting Techniques for Designing Multi-Asynchronous Clock Designs" are the standard references; both explicitly recommend this exact construct.

The challenge: The code looks contradictory but is actually the industry-standard reset synchronizer — async assertion for safety, synchronous deassertion for clean recovery timing.

All newsletters