Reset Synchronization
Asserting async, removing it synchronously
Resets cross clock domains too, and a badly handled reset is its own CDC bug. The standard answer is the reset synchronizer, and the principle behind it is worth knowing cold.
The problem is reset removal, not assertion
Asserting reset is safe: when reset goes active, all flops are forced to their reset value regardless of the clock. The danger is de-assertion. If reset is released too close to a clock edge, a flop can go metastable on the very first edge after reset, because the reset removal violated its recovery and removal timing.
Asynchronous assert, synchronous de-assert
The accepted technique is to assert reset asynchronously so the logic resets instantly even if the clock is stopped, but to remove reset synchronously so it lines up with the destination clock and never releases inside a flop timing window.
// Reset synchronizer: async assert, sync de-assert
module reset_sync (
input wire clk,
input wire arst_n, // raw async active-low reset
output reg rst_n // clean reset for this domain
);
reg meta;
always @(posedge clk or negedge arst_n) begin
if (!arst_n) begin
meta <= 1'b0; // assert immediately, async
rst_n <= 1'b0;
end else begin
meta <= 1'b1; // release lined up with the clock
rst_n <= meta;
end
end
endmoduleWhy two flops again
When reset releases, the first flop can be metastable on that edge, just like any synchronizer. The second flop gives it a cycle to settle, so the reset seen by the rest of the domain comes out clean and aligned to the clock.
Each clock domain gets its own reset synchronizer driven by that domain clock. Do not route one synchronized reset across domains, and do not release reset to different domains on the same raw edge expecting them to be aligned. Per-domain reset synchronizers keep each domain clean.
The reset assertion path is asynchronous and bypasses normal timing, so it still needs care in static timing analysis (recovery and removal checks on the de-assertion). Treat reset like any other signal that must be timed on its synchronous edge.