# Metastability and synchronizers

*What happens when an input misses the setup window*

Metastability is the unstable in-between state a flip-flop can enter when its data input changes too close to the clock edge (a setup or hold violation), where the output hovers at an invalid voltage and resolves to a clean 0 or 1 only after an unpredictable extra delay; the probability it is still undecided decays exponentially with waiting time, and a two-flip-flop synchronizer keeps that resolving state away from the rest of the circuit.

Group: Memory
URL: https://digiwleea.wleeaf.dev/learn/metastability/

The [timing](https://digiwleea.wleeaf.dev/learn/timing/) lesson gave a [flip-flop](https://digiwleea.wleeaf.dev/learn/dff/) a setup-and-hold window: for a clean capture, its `D` input must be steady for a moment before the clock edge and a moment after. The whole synchronous discipline is about making sure the logic settles in time so that window is always respected. But some inputs you simply **cannot** control that way: a button a human presses, a sensor, or a signal arriving from another part of the chip running on a *different* clock. Such a **truly asynchronous** input can change at any instant, including right inside the setup/hold window. When it does, the flip-flop can go **metastable**, and this lesson is about what that means and how to survive it.

> **WARN:** **Like hazards, this is invisible in our simulator, which is the point.** The lab settles every flip-flop to a clean `0` or `1` with zero delay, so it never shows the in-between state. Metastability is an *analog, timing* phenomenon, not a logic one, so you reason about it on paper. A design that ignores it passes every zero-delay simulation and then fails at random in real hardware.

## An analogy: a ball on a knife edge

Balance a ball exactly on the edge of a knife. There are two stable resting places, one on each side, and the knife edge is a single unstable point between them. A firm push sends the ball cleanly to one side. But a push that leaves it almost perfectly balanced lets it teeter on the edge, and you cannot predict *which* way it will eventually fall or *how long* it will hover first. A flip-flop is exactly this kind of system: two stable states (`0` and `1`) with one unstable balance point between them.

## The metastable state

A flip-flop stores its bit in a feedback loop, the same cross-coupled idea as the [SR latch](https://digiwleea.wleeaf.dev/learn/srlatch/): two inverters driving each other. That loop has two stable states (a solid `0` and a solid `1`) and, in between, one **unstable** balance point where both nodes sit at an invalid mid-supply voltage. A capture that respects setup/hold slams the loop firmly to one side. A capture that violates it can leave the loop near that balance point. From there the feedback slowly **regenerates** it toward a real `0` or `1`, but during that regeneration the output is neither: it is a metastable level that can linger far longer than the flip-flop's normal delay.

The crucial fact is **how** it resolves: exponentially. The probability that the flop is *still* metastable after waiting a time `t` falls off as a decaying exponential, set by the loop's regeneration time constant `tau`:

```
P(still metastable after t)  is approximately  e^(-t / tau)
```

So you can never *guarantee* it has settled, but every extra moment of waiting makes it dramatically more likely it has. Give it a nanosecond and it is probably resolved; give it a full clock period and the odds of it still being undecided are astronomically small. That trade between **resolution time allowed** and **reliability** is the whole game, and it is captured by a **mean time between failures** (MTBF): the average time between two events where a sampled async signal is still metastable when the circuit uses it.

```
MTBF  is approximately  e^(t_r / tau) / (T0 * f_clk * f_data)
```

Here `t_r` is the resolution time you allow the flop before anything reads it, `f_clk` is the clock rate, `f_data` is how often the async input changes, and `T0` and `tau` are properties of the flip-flop. The exponential `e^(t_r / tau)` on top is the key lever: a little more settling time multiplies the MTBF enormously, turning a failure-every-few-seconds design into one expected to fail once in centuries.

## The two-flip-flop synchronizer

How do you *buy* that resolution time? Put a flip-flop right at the asynchronous boundary, then feed its output into a **second** flip-flop on the same clock before any logic touches it. The first flop samples the async input and may go metastable. By the next clock edge, a full period later, it has (almost certainly) resolved to a clean `0` or `1`, and the second flop captures that clean value. The synchronized signal coming out of the second flop is safe for the rest of the circuit to use.

_Circuit diagram: A two-flip-flop synchronizer: the asynchronous input ASYNC is sampled by the first flip-flop (its output Q1), which feeds the second flip-flop, whose output SYNC is the safe, synchronized signal. Both flops share CLK. The first flop absorbs any metastability and gets a whole clock period to resolve before the second flop, and the downstream logic, ever sees it. Open it in the lab and pulse CLK to watch a value walk from ASYNC to Q1 to SYNC._

**Why is one flip-flop not enough?** If downstream gates read the first flop's output directly while it is still metastable, disaster follows: an intermediate voltage is not a defined logic value, so one gate may interpret it as `0` while another reads it as `1`. The circuit's state forks and becomes inconsistent. The second flop fixes this by **isolating** the metastable node: only that one flop's input sees the bad level, nothing else reads `Q1` for real work, and it has a full period to settle before `SYNC` is produced. Two stages do not *eliminate* metastability (nothing can), they push its probability down to the vanishing MTBF above.

## Multi-bit crossings need more than a synchronizer

A synchronizer protects **one** bit. You cannot just drop one on each wire of a multi-bit bus and call it done, because the bits can resolve on **different** clock edges. Imagine a [counter](https://digiwleea.wleeaf.dev/learn/counter/) crossing from `0111` to `1000`: four bits flip at once. If three of them synchronize this cycle and one the next, the receiver momentarily sees a combined value, like `1111` or `0000`, that the counter **never actually held**. The bus must cross as a coherent whole, which needs one of:

- **A handshake:** the sender raises a single `request` line (itself synchronized) only after its data bus is stable, and the receiver replies with an `acknowledge`. The multi-bit data is sampled only when the one-bit request says it is safe, so only that single control bit ever risks metastability.
- **An asynchronous FIFO:** a small dual-clock queue that the sender writes and the receiver reads, decoupling the two clock domains entirely.
- **Gray-coded pointers:** in that FIFO, the read and write pointers that *do* cross between clocks are encoded in [Gray code](https://digiwleea.wleeaf.dev/learn/gray-code/), where consecutive values differ in exactly **one** bit. Then at most one bit is ever mid-transition, so the worst a receiver can sample is the old value or the new one, never a bogus in-between count.

> **WARN:** **Common mistakes.** A single flip-flop on an asynchronous input is **not** a synchronizer; you need at least two in series. Never let an async or still-metastable signal **fan out** to several gates before it is synchronized, or different gates will latch different values. You cannot remove metastability with combinational logic, because it is an analog timing effect, not a logic bug. Do not synchronize a multi-bit value bit-by-bit; cross it with a handshake, a FIFO, or Gray-coded pointers. And remember a synchronizer only makes failure *improbable*: it never reaches zero, it only pushes the MTBF out to years.

**Q (Try it):** An asynchronous push-button feeds logic in a clocked circuit, and the design occasionally misbehaves with no logical explanation, never reproducing in simulation. What is likely happening, what is the standard fix, and why is putting a single flip-flop on the button input not enough?

**A:** The button can change inside the flip-flop's setup/hold window, so the flop goes **metastable** and resolves late and unpredictably, an analog timing effect that a zero-delay simulation never shows. The fix is a **two-flip-flop synchronizer**: sample the button with one flop, then pass it through a second flop on the same clock before any logic uses it. A single flop is not enough because its output can still be metastable when the surrounding gates read it, and an in-between voltage can be seen as `0` by one gate and `1` by another, splitting the circuit's state. The second flop gives the first a full clock period to resolve and keeps the metastable node away from everything else.

> **KEY:** Metastability is the price of touching the real, asynchronous world from inside a synchronous chip, and synchronizers are the universal toll you pay. Every clock-domain boundary, every external button or sensor, and even the release of an asynchronous reset gets this treatment. The [processor](https://digiwleea.wleeaf.dev/learn/buses/) you build in the next group runs on a single shared clock, so it needs no synchronizers internally, which is exactly what keeps it simple; but the moment a real system-on-chip talks to anything outside its own clock, the two-flip-flop synchronizer is the first circuit it reaches for.

### FAQ

**Q:** What is metastability in a flip-flop?

**A:** Metastability is an unstable in-between state a flip-flop can enter when its input changes too close to the clock edge. Its output hangs at an invalid mid-supply voltage and resolves to a clean `0` or `1` only after an unpredictable extra delay, because the flip-flop's feedback loop has been left near its balance point instead of pushed firmly to one side.

**Q:** What causes metastability?

**A:** A setup or hold time violation: the data input changes during the small window around the clock edge when it must stay steady. This is unavoidable for truly asynchronous inputs (buttons, sensors, signals from another clock domain) because they can change at any instant, independent of the receiving clock.

**Q:** What is a two-flip-flop synchronizer?

**A:** Two flip-flops in series on the same clock, placed at an asynchronous input. The first samples the async signal and may go metastable; by the next clock edge it has almost certainly resolved, and the second flip-flop captures a clean value. It gives the metastable state a full clock period to settle and isolates it from the rest of the logic.

**Q:** Can metastability be eliminated completely?

**A:** No. The probability that a flip-flop is still metastable decays exponentially with waiting time but never reaches zero, so the best you can do is make failure astronomically unlikely. A synchronizer pushes the mean time between failures (MTBF) out to years or centuries by giving the flop more time to resolve, but it cannot guarantee resolution.

**Q:** How do you safely cross a multi-bit bus between clock domains?

**A:** Not with a per-bit synchronizer, because different bits can resolve on different cycles and the receiver could sample a value that never existed. Use a handshake (synchronize a single request/acknowledge bit and move the data only when it is stable), an asynchronous FIFO, or Gray-coded pointers, where consecutive values differ in only one bit so at most one bit is ever in transition.
