Hardware Engineering · HDL and Synthesis
Metastability: What a Two-Flop Synchronizer Buys and What It Cannot
Why a flip-flop that samples a changing asynchronous input can hover between logic levels, how the resolution failure rate falls exponentially with the time allowed, and why buses cannot be crossed one bit at a time.
A flip-flop samples its input in a narrow window around the clock edge, and a signal that changes inside that window leaves the internal latch with no defined value to resolve to. The latch’s cross-coupled inverters then amplify whatever difference exists between their outputs, and the time that takes is proportional to the logarithm of the initial difference. If that difference is arbitrarily small, the resolution time is arbitrarily long. The output can sit near the switching threshold past the end of the clock cycle, and downstream logic receiving it may decide it is a zero, or a one, or neither.
This is metastability, and it cannot be eliminated in a design where unrelated clocks exchange data or where an input has no timing relationship to the sampling clock. What can be done is to make the failure rate so low that it does not matter, and the way that is done, spending time in a register rather than logic, is the mechanism behind every synchronizer.
The aperture and the exponential
The window in which a transition causes trouble is the setup-plus-hold aperture of the sampling element, tens of picoseconds wide in current processes. When a transition lands inside it, the latch is pushed to a balance point between its two stable states, and the exponential recovery means the probability of still being undecided after a resolution time $t_r$ is proportional to $e^{-t_r/\tau}$. The constant $\tau$ is set by the latch’s own regeneration loop (its node capacitance divided by the transconductance of the transistors in the feedback path), and is also tens of picoseconds in a modern process.
The standard consequence is a mean time between failures, derived from that probability, the aperture window $T_w$, the sampling clock frequency $f_c$, and the rate at which the data input changes $f_d$:
$$\text{MTBF} \approx \frac{e^{t_r/\tau}}{T_w \cdot f_c \cdot f_d}$$
Every term is worth reading. The exponential says that doubling the resolution time allowed has a much larger effect than anything else in the formula. The clock frequency and the data rate are multipliers: a fast interface with a fast clock fails sooner for the same resolution time. The aperture width is the exposure per event. Design targets for this figure are stated in years, which is the reason the exponential matters: a design whose resolution time is one or two $\tau$ is hopeless, and one whose resolution time is ten $\tau$ has margin to spare.
Why the second flip-flop is a time budget, not a fix
The synchronizer for a single-bit signal is two registers in series, both clocked by the receiving domain’s clock.
/* Asynchronous single-bit input crossing into clk domain. */
reg sync_meta, sync_out;
always @(posedge clk) begin
sync_meta <= async_in; /* may go metastable; nothing reads it */
sync_out <= sync_meta; /* samples a full period later */
end
The first flip-flop is allowed to be metastable. Nothing but the second flip-flop reads its output, and the second one samples it a full clock period later. That period is the resolution time $t_r$ in the formula, so the failure probability now depends on $e^{T/\tau}$ where $T$ is the clock period. The second flip-flop can itself go metastable, but only if the first is still undecided when it is sampled, which is exactly the event whose probability the formula gives.
This is why the technique is a probability reduction and not a guarantee, and why the number of stages is chosen against a target: each additional stage multiplies the resolution time by another period and therefore multiplies the MTBF by $e^{T/\tau}$, which for typical values is many orders of magnitude. Two stages are the norm because one is not enough: with a single flip-flop, the metastable output drives combinational logic and several destinations. Different paths through that logic have different delays and different switching thresholds, so one consumer may resolve the value as a zero while another resolves it as a one, and each may see a different transition time. That incoherence, not the metastable level itself, is what breaks a single-flop crossing.
Two properties of the construction are easy to break. The synchronizer’s first stage must be the only load on the asynchronous signal, and the signal must come from a register in the source domain, not from combinational logic there; a glitchy source can produce more transitions than the formula’s $f_d$ assumes, and a source that is not registered can produce an arbitrarily short pulse that neither synchronizer stage ever samples. Synthesizers and place-and-route tools also happily optimize adjacent registers, whether by merging, retiming, or resizing the first stage, unless told not to, and tools provide attributes to mark synchronizer stages so that they survive optimization intact.
Buses cannot be synchronized bit by bit
The construction generalizes to a bus in exactly one way, and it is not the obvious one. Putting a two-flop synchronizer on each bit fails whenever more than one bit changes between source-domain edges. Each bit resolves independently, with its own propagation and its own metastable delay, so the destination can observe a mixture of old and new values: for a counter going from 7 to 8, a snapshot of some bits at the new value and others at the old produces a value that was never written, for example 15 or 0 depending on which bits lagged.
Three structures avoid this.
Gray coding. If only one bit changes per source-domain update, there is no mixture to observe: the destination sees either the old code or the new one. This is why asynchronous FIFOs carry their read and write pointers across the domain boundary in Gray code rather than binary, even though each side has to convert Gray to binary in order to increment and convert the result back. The property holds only if the code sequence really is single-bit-change, which for a binary counter incrementing by one is exactly the Gray sequence.
/* Gray-code pointer increment: one bit changes per increment. */
function [PTR_W-1:0] gray_next(input [PTR_W-1:0] bin);
reg [PTR_W-1:0] nxt;
begin
nxt = bin + 1'b1;
gray_next = (nxt >> 1) ^ nxt;
end
endfunction
Handshake. The source presents data, waits for a synchronized acknowledgement from the destination, and only then changes the data. The data lines are stable during the crossing by construction, so they need no synchronizer at all; only the request and acknowledge signals are synchronized. The cost is latency: a round trip of at least two destination clock periods plus two source clock periods.
Asynchronous FIFO. A dual-port memory with pointers in each domain, each pointer synchronized into the other domain for the full and empty comparisons. It allows continuous throughput, at the cost of memory and of the subtlety that the pointer comparison must use Gray-coded values and typically an extra bit to distinguish full from empty.
The important structural point is that in all three, the data path is not synchronized and the control path is. Synchronizing the data would not help, because the data is a multi-bit value whose bits have no individual meaning.
Resets cross domains too
An asynchronous reset asserted into a clocked domain has the same problem in a different form. The assertion is safe: driving a register into reset does not depend on the clock. The de-assertion is not, because if it happens near a clock edge, some registers leave reset on one edge and some on the next, and a state machine can start in an illegal state as a result. The standard remedy is to assert asynchronously and release synchronously, by passing the reset through the same two-stage structure clocked by the destination domain and driving the register’s asynchronous reset input from the synchronized version.
Detecting the problem before it is built
Because clock domain crossings are structural, they can be found statically. Tools and linters identify every signal that crosses a clock domain boundary in the netlist or in the RTL, and check that it passes through an approved synchronizer structure, that the synchronizer’s stages share one clock, and that no combinational logic sits between the two stages. The checks that matter most are the ones that report a crossing with no synchronizer at all, a synchronizer whose output feeds combinational logic that then re-enters a register in the same domain, and a multi-bit crossing with no Gray code or handshake.
The corresponding verification technique is to constrain the two clock domains differently in simulation, with random independent jitter on both clocks, and note that simulation cannot demonstrate the absence of metastability. The models available in RTL simulation represent a metastable value as an unknown, which the simulator propagates according to its own rules, and those rules are not the circuit’s behaviour. The unknown value travels through the same delta-cycle regions as any other value, which is why a testbench can appear to observe a coherent result from an incoherent crossing. A testbench that passes with an unknown propagating to an output has shown that the design’s behaviour depends on a value the hardware may not resolve. That is a signal to look at the crossing, not a proof that one exists.
Timing constraints and synchronizers interact: the paths into a synchronizer must be excluded from normal setup and hold analysis, because they are by definition not timing-related, and they must instead be checked for the maximum delay that the source-domain data rate allows. Getting that exclusion wrong is the subject of the timing report’s exception mechanism: a crossing left in the ordinary analysis either fails, because the two clocks have no fixed phase relationship, or is declared a false path without checking that the synchronizer justifies the declaration.
References
- Metastability and Synchronizers: A Tutorial — Ran Ginosar, IEEE Design & Test of Computers, 2011
- Clock Domain Crossing (CDC) Design & Verification Techniques Using SystemVerilog — Clifford E. Cummings, SNUG 2008
- Digital Systems Engineering — William J. Dally and John W. Poulton, Cambridge University Press