A synchronizer protects the logic in a new clock domain from the metastable state that the first flip-flop in that domain can enter when it samples a signal from another clock. The basic circuit is two flip-flops in series with nothing between them, which gives the first flop most of a clock period to settle before the second one samples it. On top of that basic circuit sit three kinds of synchronizer, level, edge-detecting and pulse, and choosing the right one depends on how long the signal stays valid and which clock is faster.
This is Part 1 of the series. The Introduction sets out the problem and Part 2 continues from here.
Key takeaways
- A two flip-flop synchronizer does not prevent metastability. It gives the first flop time to resolve, so the chance of a bad value reaching downstream logic becomes very small.
- No combinational logic is allowed between the source-domain flop and the first synchronizer flop, or between the two synchronizer flops.
- A synchronized signal costs one to two destination clock cycles of latency. Plan for two.
- Level synchronizers pass slow levels, edge-detecting synchronizers turn an edge into a one-cycle pulse, and pulse synchronizers carry a one-cycle pulse from a fast domain into a slow one.
- Every synchronizer has a rule about minimum pulse width or minimum spacing. Break it and events are merged or lost without any warning in simulation.
Why a synchronizer is needed
A flip-flop is only guaranteed to capture a clean 0 or 1 when its input is stable for the setup time before the clock edge and the hold time after it. A signal from an unrelated clock will, sooner or later, change inside that window. The flop can then sit at an intermediate voltage for an unpredictable time before falling to 0 or 1. If downstream logic reads that output while it is still undecided, different gates can see different values and the design fails. The Metastability post covers the physics in more detail.
The basic two flip-flop synchronizer
A simple synchronizer comprises two flip-flops in series without any combinational circuitry between them. This design ensures that the first flip-flop exits its metastable state and its output settles before the second flip-flop samples it. You also need to place the flip-flops close to each other, so that the wire between them is short and the clock skew between them is as small as possible. Every picosecond spent on the wire is a picosecond taken away from resolution time.
How safe is safe enough: MTBF
The quality of a synchronizer is measured as mean time between failures (MTBF). A widely used model is:
MTBF = e^(tr / tau) / (T0 x fclk x fdata)
Here tr is the time the first flop has to resolve (roughly one destination clock period minus the clock-to-Q delay of the first flop and the setup time of the second), tau and T0 are constants of the flip-flop that come from the library or from characterisation, fclk is the destination clock frequency and fdata is the rate at which the asynchronous input changes.
A worked example with illustrative values, not from any real library: tau = 50 ps, T0 = 100 ps, fclk = 500 MHz (2 ns period), fdata = 50 MHz.
| Synchronizer | Resolution time tr | tr / tau | MTBF |
|---|---|---|---|
| Two flops | 1.6 ns | 32 | about 3.2 x 10^7 s, roughly one year |
| Three flops | 3.6 ns | 72 | about 2.4 x 10^17 years |
One year is not acceptable for a product that ships in millions of units, since across the installed base failures would arrive every few minutes. Adding one more stage adds a full clock period to tr, and because tr sits in an exponent, MTBF jumps by many orders of magnitude. This is why very fast clocks, or very small tau budgets in advanced nodes, sometimes call for three-stage synchronizers.
Synchronizer cells from the foundry
Foundries and library vendors help with signal synchronization by providing synchronizer cells. One kind is a single flip-flop with very high gain. It uses more power and is larger than a standard flip-flop, but it resolves faster (a smaller tau), has reduced setup and hold requirements, and is resistant to oscillation when its input causes a metastable condition.
Another type of synchronizer cell contains two (or three) flip-flops in one cell. This eases your job: the flops are already placed close to each other and nobody can insert combinational logic between them. A dedicated cell also makes synchronizers easy for CDC tools and reviewers to find in the netlist.
No logic in front of the synchronizer
For synchronization to work properly, the signal crossing a clock domain should pass from a flip-flop in the original clock domain to the first flip-flop of the synchronizer without passing through any combinational logic between the two (see the figure below).
This requirement matters because the first stage of a synchronizer is sensitive to glitches that combinational logic produces. Logic driven by several source-domain flops can glitch whenever its inputs change at slightly different times. A long enough glitch that occurs at the wrong moment can meet the setup and hold requirements of the first synchronizer flop, and the synchronizer then passes a false valid indication to the rest of the logic in the new clock domain. The source domain clock does not filter the glitch, because the destination domain is not looking at it on source clock edges.
Latency through a synchronizer
A synchronized signal is valid in the new clock domain after two clock edges. Depending on where the input changes relative to the destination clock, the delay is between one and two clock periods of the new domain. A rule of thumb is that a synchronizer costs two clock cycles of delay in the new clock domain, and a designer needs to consider how that delay affects the timing of signals crossing clock domains, for example in handshakes, where each direction pays the cost.
The three kinds of synchronizer
Synchronizers fall into one of three basic categories: level, edge-detecting and pulse.
| Type | Input | Output | Rule the input must follow |
|---|---|---|---|
| Level | A level that stays valid for a long time | The same level, delayed | Stays high or low for more than two destination clock cycles, and returns to invalid between events |
| Edge-detecting | A level change | One destination clock-wide pulse per edge | Wider than one destination clock period plus the hold time of the first flop; two periods is safest |
| Pulse | A single source clock-wide pulse | A single destination clock-wide pulse | Pulses spaced at least two destination clock periods apart |
Level synchronizer
In a level synchronizer, the signal crossing a clock domain stays high and stays low for more than two clock cycles in the new clock domain. A requirement of this circuit is that the signal needs to change to its invalid state before it can become valid again. Each time the signal goes valid, the receiving logic considers it a single event, no matter how long the signal remains valid. This circuit is the heart of all the other synchronizers.
Edge-detecting synchronizer
The edge-detecting synchronizer adds a flip-flop to the output of the level synchronizer (see the figure below). The output of the additional flip-flop is inverted and ANDed with the output of the level synchronizer. The circuit detects the rising edge of the input and generates a one clock-wide, active-high pulse. Moving the inverter to the other AND gate input gives a synchronizer that detects the falling edge. Changing the AND gate to a NAND gate gives an active-low pulse.
The edge-detecting synchronizer works well for synchronizing a pulse going into a faster clock domain. One restriction is that the input pulse must be wider than the period of the synchronizer clock plus the hold time of the first synchronizer flip-flop, otherwise it can fall between two destination edges and never be seen. The safest pulse width is twice the synchronizer clock period. This synchronizer does not work if the input is a single clock-wide pulse entering a slower clock domain. The pulse synchronizer solves that problem.
Pulse synchronizer
The input to a pulse synchronizer is a single clock-wide pulse that triggers a toggle flip-flop in the originating clock domain (see the figure below). The toggle output changes from low to high or high to low each time it receives a pulse. Because it now holds each new value until the next pulse, it is a slow level that the level synchronizer can carry safely. In the destination domain the synchronized toggle goes to one input of an XOR gate and a one clock-cycle delayed copy goes to the other input. Each time the toggle changes state, the XOR output is high for exactly one destination clock cycle.
The job of a pulse synchronizer is to take a single clock-wide pulse in one clock domain and create a single clock-wide pulse in the new domain. Its restriction is that input pulses must be spaced at least two synchronizer clock periods apart. If they are closer, the output pulses in the new domain land next to each other and look like one pulse wider than a clock cycle. The problem is worse when the source clock is much faster than the destination clock, so that the synchronizer clock period is more than twice the source clock period. Then two source pulses can toggle the signal twice between destination samples, the toggle returns to its old value, and the synchronizer does not detect either pulse. If pulses can arrive that close together, use a handshake or an asynchronous FIFO instead (see FIFO depth calculation).
Verilog for all three synchronizers
The code below is a straightforward model of the three circuits described above. Asynchronous active-low reset is used throughout. In a real design the two flops in sync_level would usually be a library synchronizer cell, or would carry a constraint or attribute that keeps them together and marks them for CDC tools.
`timescale 1ns/1ps
// Level synchronizer: two flip-flops, nothing in between
module sync_level (
input wire clk_dst,
input wire rst_n,
input wire d_async, // must come straight from a flop in the source domain
output wire q_sync
);
reg meta, sync;
always @(posedge clk_dst or negedge rst_n)
if (!rst_n) begin
meta <= 1'b0;
sync <= 1'b0;
end else begin
meta <= d_async;
sync <= meta;
end
assign q_sync = sync;
endmodule
// Edge-detecting synchronizer: one-cycle pulse on each rising edge
module sync_edge (
input wire clk_dst,
input wire rst_n,
input wire d_async,
output wire rise_pulse
);
wire lvl;
reg lvl_d;
sync_level u_lvl (.clk_dst(clk_dst), .rst_n(rst_n), .d_async(d_async), .q_sync(lvl));
always @(posedge clk_dst or negedge rst_n)
if (!rst_n) lvl_d <= 1'b0;
else lvl_d <= lvl;
assign rise_pulse = lvl & ~lvl_d;
endmodule
// Pulse synchronizer: toggle in the source domain, XOR in the destination
module sync_pulse (
input wire clk_src,
input wire clk_dst,
input wire rst_n,
input wire pulse_src, // single clock-wide pulse in clk_src domain
output wire pulse_dst // single clock-wide pulse in clk_dst domain
);
reg tgl;
wire tgl_sync;
reg tgl_sync_d;
always @(posedge clk_src or negedge rst_n)
if (!rst_n) tgl <= 1'b0;
else if (pulse_src) tgl <= ~tgl;
sync_level u_lvl (.clk_dst(clk_dst), .rst_n(rst_n), .d_async(tgl), .q_sync(tgl_sync));
always @(posedge clk_dst or negedge rst_n)
if (!rst_n) tgl_sync_d <= 1'b0;
else tgl_sync_d <= tgl_sync;
assign pulse_dst = tgl_sync ^ tgl_sync_d;
endmodule
A simple testbench with a 100 MHz source clock and a roughly 42 MHz destination clock sends five single-cycle pulses, 90 ns apart, through sync_pulse and two slow rising edges through sync_edge. It counts five pulses out and two edge pulses out, as expected. Note that an RTL simulation never shows metastability; it only proves that the logic around the synchronizer is correct. Metastability is handled by design rules, MTBF analysis and CDC checks.
Common mistakes
- Logic before the first flop. Even a single AND gate in front of the synchronizer can let a glitch through. Register the signal in the source domain first.
- Synchronizing each bit of a bus separately. Bits can resolve on different destination cycles, so the bus can be read as a value that never existed. Use Gray code for counters (see Gray codes), a handshake with a stable data bus, or an asynchronous FIFO.
- Using an edge-detecting synchronizer for a fast-to-slow pulse. A one-cycle pulse from a fast clock can be missed entirely. Use the pulse synchronizer.
- Ignoring the latency. Two destination cycles in each direction adds up in a request and acknowledge handshake.
- Spreading the two flops apart in layout. Long wires and skew eat resolution time and reduce MTBF.
Frequently asked questions
Does a two flip-flop synchronizer remove metastability?
No. The first flop can still go metastable. The second flop gives it about one clock period to resolve, which makes the probability of a failure reaching downstream logic very low, as measured by MTBF.
When do I need three flip-flops instead of two?
When the MTBF with two stages is too low for the product, typically with very high destination clock frequencies, fast-changing inputs or flops with a large tau. The library or foundry data for the synchronizer cell is the place to start that calculation.
Can I synchronize a multi-bit bus with two flip-flops per bit?
Only if no more than one bit changes at a time, as with a Gray coded pointer. Otherwise use a handshake that holds the bus stable while a single control bit is synchronized, or an asynchronous FIFO.
What is the minimum spacing between pulses for a pulse synchronizer?
At least two destination clock periods between pulses. Closer pulses either merge into one wide pulse or cancel out and are lost.
Related reading
- Asynchronous in a synchronous world, Introduction
- Asynchronous in a synchronous world, Part 2
- Digital logic metastability definitions
- Diagnosing clock domain crossing errors in FPGAs
- The Semiconductor Hub glossary entries for metastability, clock domain crossing (CDC) and MTBF




Your comments will be moderated before it appears here.