The Two-Flop Synchronizer
The standard fix for a single-bit crossing
The two-flop synchronizer is the workhorse of CDC. It is the correct, standard way to bring a single-bit signal safely into a new clock domain.
How it works
Place two flip-flops in series, both clocked by the destination clock. The first flop samples the asynchronous input and may go metastable. By the time the next destination edge arrives, that first flop has almost certainly settled, so the second flop captures a clean, stable value to hand to the rest of the logic.
// Two-flop synchronizer for a single-bit signal
module sync2 (
input wire clk_dst, // destination clock
input wire async_in, // signal from another domain
output reg sync_out
);
reg meta;
always @(posedge clk_dst) begin
meta <= async_in; // may go metastable
sync_out <= meta; // settled, safe to use
end
endmoduleThe rules that make it valid
- Both flops use the destination clock, and only the destination clock.
- Put no combinational logic between the two flops - the first flop needs the full cycle to settle.
- Use it only for a single bit, or for signals where each bit is independent.
Why two flops: the MTBF math
The reason two flops work comes down to probability. When the first flop samples an asynchronous input and goes metastable, it does not stay undecided forever, it resolves toward a valid 0 or 1 in a time that grows the longer you let it settle. The chance it is still undecided after a settling time t falls off exponentially, roughly as e raised to the power of minus t divided by tau, where tau is the flop metastability time constant.
A single flop gives the metastable output almost no time to settle before the next stage reads it, so failures are frequent. Adding a second flop hands the first flop a full destination clock period to resolve before the second flop samples it. Because the failure probability drops exponentially with that extra settling time, one extra cycle can turn a failure every few seconds into a failure every thousands of years.
This is captured as MTBF (mean time between failures), the average time between synchronization failures:
e^( t_settle / tau )
MTBF = ---------------------------------
T0 x f_clk x f_data
t_settle : time allowed to resolve (about one clock
period of margin per extra flop)
tau, T0 : the flop metastability constants (library)
f_clk : destination clock frequency
f_data : rate the asynchronous signal changesTwo things fall out of that formula. First, settling time helps exponentially, which is exactly what each extra flop buys, so a second flop raises MTBF enormously and a third raises it again (used at very high clock speeds or in safety-critical designs). Second, a faster destination clock and a faster-changing input both lower MTBF, which is why the fastest crossings sometimes need three flops. The target is simply an MTBF far longer than the product will ever be in service.
What it costs and what it needs
- Latency: the signal appears one to two destination cycles later.
- The input must stay stable long enough to be caught, so it suits slow-changing levels and control signals.
A two-flop synchronizer does not work for a short pulse that is narrower than the destination clock period. The destination clock may step right over it and miss it entirely. Narrow pulses need a pulse synchronizer or a handshake, covered later in this path.
Mark synchronizer flops clearly (a naming convention like _meta and _sync, or a dedicated module) so synthesis, place-and-route, and CDC tools recognize them and keep the two flops close together with no logic between.