2026-05-22
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:
sync_rst_n fans out to every downstream flop's sensitivity list — mixing sync and async reset styles across the same clock domain is where trouble starts.set_false_path -from [raw_rst] -to [synchronizer_first_flop]) so STA doesn't try to time the async input, but still times recovery/removal on the synchronized output.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.
