2-Flop Synchronizer vs Toggle vs Handshake vs Async FIFO: CDC

Between asynchronous clock domains there will always be moments when the receiving flip-flop cannot meet its setup or hold time, so signals are passed through circuits designed on the assumption that metastability will occur. The basic one is the synchronizer, which receives a 1-bit level signal through two flip-flops. A toggle synchronizer carries short pulses, a handshake carries occasional multi-bit data, and an asynchronous FIFO carries continuous, high-volume data. All of them share one idea: only a 1-bit signal, or a Gray code that changes by only one bit per step, is ever synchronized.

Aspect2-flop synchronizerToggle synchronizerHandshakeAsynchronous FIFO
What it can carryA 1-bit level signal (a slowly changing control signal)A 1-bit pulse (an event)Multi-bit data, one word at a time, occasionallyA stream of multi-bit data (continuous, high volume)
How it worksPasses the signal through two flip-flops on the receiving clock, giving any metastability in the first stage time to resolve before the second stage captures itTurns each pulse into a level that flips on the sending side, synchronizes it, and recovers the pulse on the receiving side by XORing it with a one-stage-delayed copyHolds the data, passes req through a synchronizer, and once the receiver has captured the data, returns ack through a synchronizerWrites into a dual-port memory and synchronizes Gray-coded pointers into the other domain to decide full and empty
Signals that are synchronizedThe signal itselfThe toggle signal (1 bit)req and ack (1 bit each); the data is not synchronizedGray-coded pointers (only 1 bit changes per step)
ThroughputThe signal must change much more slowly than the receiving clock periodPulses must be spaced by more than the few receiving cycles needed to detect each changeSlow: one 4-phase transfer takes 8 or more cycles across both domainsFast: one word can be written and read every cycle
Typical latency to the receiverAbout 2 receiving-clock cyclesAbout 2 to 3 receiving-clock cyclesAbout 2 cycles for req to arrive; sending the next word must also wait for ack to come backAbout 2 to 3 cycles until a written word is visible on the read side
Main pitfallsUsed on multi-bit data, bits can be captured in different cycles and an intermediate value appears; short pulses from a faster domain can be lostIf pulses come too close together, the toggle signal returns to its old value and two events are missedThe data must not change until ack returnsThe depth is set from the burst length and the read/write rate difference, plus margin for the synchronization delay
Circuit size2 flip-flops (sometimes 3 stages for fast clocks)A few flip-flops and an XORreq/ack synchronizers and state machines on both sidesMemory, pointers with Gray-code conversion, synchronizers and full/empty logic
Typical usesControl signals such as enables, asynchronous external inputsDone or interrupt notifications that last only one cycle in a fast domainPassing configuration register valuesData transfer between buses or interfaces running on different clocks

Figures are typical orders of magnitude and vary by process generation and product.

When to use which

2-flop synchronizer
For a 1-bit level signal that stays stable much longer than the receiving clock period. It is the building block of every other method; use 3 stages when the clock is fast or a longer MTBF is needed.
Toggle synchronizer
When a short pulse in a fast domain must reach a slower domain without being lost, provided that consecutive pulses are spaced by more than a few receiving cycles.
Handshake
When multi-bit data such as configuration values must be passed reliably from time to time. It is safe for any frequency ratio, but each transfer takes many cycles.
Asynchronous FIFO
When data must be passed continuously or at a high rate. It absorbs rate differences and bursts, but it is the largest circuit of the four.

FAQ

Why not put a 2-flop synchronizer on each bit of multi-bit data?

Because for each bit it is undetermined whether a change is captured at this edge or the next. For example, when the value changes from 0111 to 1000, the receiver can see 1111 or 0000 for one cycle, with only some bits updated. Instead, keep the data itself unsynchronized and stable and synchronize only a 1-bit control signal (a handshake), or use an asynchronous FIFO. For counter values, another option is to convert them to Gray code so that only one bit changes at a time.

What changes when a synchronizer goes from 2 to 3 stages?

The time available for metastability to resolve grows by about one clock period, and the mean time between failures (MTBF) grows exponentially. MTBF is roughly e^(t_r/τ) ÷ (T_0 × f_clk × f_data); with τ = 20 ps, adding 1 ns to t_r multiplies the MTBF by e^50 (more than 10 to the 21st power). The cost is one more cycle of latency.

Why are asynchronous FIFO pointers converted to Gray code?

Because a binary pointer can change several bits at once, as from 0111 to 1000, and synchronizing the bits separately can produce a completely unrelated value. In Gray code only one bit changes per step, so even if that bit goes metastable and resolves either way, the result is the value before or after the step. The receiver only sees a slightly old value, so the full and empty decisions err on the safe side.

How is the depth of an asynchronous FIFO chosen?

From the largest amount that piles up during a write burst because reading cannot keep up. With a 100 MHz write side and an 80 MHz read side, writing a 100-word burst one word per cycle and reading one word per cycle, the depth is 100 × (1 − 80/100) = 20 words. Real designs add margin for the pointer synchronization delay.

Check your understanding

How does the mean time between failures (MTBF) due to metastability change when a two-flip-flop synchronizer is extended to three stages?

  1. AThe time available for metastability to resolve increases by about one period, and MTBF grows exponentially
  2. BMTBF increases 1.5 times, in proportion to the number of stages
  3. CHow likely metastability is depends on the input side, so MTBF does not change
Show answer and explanation

Answer: A. The time available for metastability to resolve increases by about one period, and MTBF grows exponentially

Synchronizer MTBF is approximately MTBF = e^(t_r/τ) ÷ (T_0 × f_clk × f_data), where t_r is the time available for metastability to resolve and τ and T_0 are constants determined by the flip-flop's characteristics. Adding a stage extends t_r by about one period (precisely, one period minus the flip-flop's clock-to-output delay and setup time). For example, with τ = 20 ps, increasing t_r by 1 ns multiplies MTBF by e^50, more than 10^21 times. The probability of the first stage going metastable is unchanged, but the probability that it resolves before propagating further rises sharply.

Each bit of 4-bit data is passed to another clock domain through its own two-stage synchronizer. What problem can occur when the data changes from 0111 to 1000?

  1. AThe bits may be captured in different cycles, so an intermediate value such as 1111 or 0000 may be received
  2. BPassing through the synchronizers aligns all bits to the same cycle, so no problem occurs
  3. CAll four bits become metastable and never return to either 0 or 1
Show answer and explanation

Answer: A. The bits may be captured in different cycles, so an intermediate value such as 1111 or 0000 may be received

For each bit, a two-stage synchronizer does not determine whether a change is captured at the current edge or the next one. In a change from 0111 to 1000 all four bits change, so for one cycle the receiver may get a value in which only some bits have their new value, such as 1111, 0000 or 0100. If the receiver uses that value, it malfunctions. Metastability resolves to 0 or 1 over time. For counter values, convert to Gray code so that only one bit changes; for arbitrary data, use a handshake or an asynchronous FIFO.

In toggle synchronization (a scheme in which the sending side generates and passes a level signal that inverts each time a pulse arrives), how is the original pulse recovered on the receiving side?

  1. AUse the synchronized toggle signal directly as the pulse
  2. BAND the synchronized toggle signal with the receiving clock to make a one-cycle-wide pulse
  3. CXOR the synchronized toggle signal with a version of it delayed by one more stage
Show answer and explanation

Answer: C. XOR the synchronized toggle signal with a version of it delayed by one more stage

In toggle synchronization, the sending side inverts a flip-flop each time a pulse arrives, representing each event as a 0-to-1 or 1-to-0 transition. Being a level signal, it is not lost even if the pulse is shorter than the receiving period. On the receiving side, after two-stage synchronization, XORing with the value delayed by one more stage gives a one-cycle-wide pulse that is 1 only in the cycle where a change occurred. Using the toggle signal directly misses the second event, when it returns to 0. Logic operations with the clock cause glitches.

  1. Which is a drawback of transferring data between clock domains with a handshake?
  2. Why are the write and read pointers of an asynchronous FIFO converted to Gray code before being synchronized into the other domain?
  3. In an asynchronous FIFO with a 100 MHz write side and an 80 MHz read side, the write side writes a 100-word burst at one word per cycle and the read side reads one word per cycle. There is ample idle time between bursts. What is the minimum depth needed to avoid overflow (ignore synchronization delay)?

Practice Timing analysis and CDC questions

Key terms explained

Synchronizer
A circuit that aligns an asynchronous signal to the receiving clock. The basic form is two flip-flops in series, which raises the probability that metastability in the first stage resolves before the next edge.
Toggle synchronizer
A scheme that turns each pulse on the sending side into a toggle of a level signal, synchronizes it, and recovers a pulse on the receiving side by XORing it with its value one cycle earlier. Pulses shorter than the receiving clock period are not lost, but pulses must be spaced several receiving cycles apart.
Handshake
A scheme that transfers data reliably by exchanging a request (req) from the sender and an acknowledgment (ack) from the receiver. Across clock domains only req and ack are synchronized while the data is held stable, which is safe but takes several cycles or more per transfer.
Asynchronous FIFO
A FIFO written and read on separate clocks, used to pass multi-bit data between clock domains. Its pointers are converted to Gray code before being synchronized into the other domain to decide full and empty. The pointers have one more bit than the address to distinguish wrap-around.
Clock domain
A group of flip-flops driven by the same clock, or by clocks with a fixed frequency and phase relationship. Passing a signal between clock domains that are asynchronous to each other requires a synchronizer.
Metastability
A state in which a flip-flop's output stays between 0 and 1 for a while when setup or hold time is violated. Asynchronous signals are passed through two flip-flops (a synchronizer) to guard against it.
Gray code
A code in which successive values differ in only one bit. It prevents read errors in rotary encoders and when passing counter values between different clock domains.
MTBF (mean time between failures)
The average interval between failures. For a synchronizer it is the average time between metastable events that fail to resolve and propagate onward, given by MTBF = e^(t_r/τ) ÷ (T_0 × f_clk × f_data). Adding stages lengthens the resolution time t_r and increases it exponentially.

Related comparisons