Skip to content

AMBA AXI · Module 14

CDC Handshake Safety

The rules that keep the AXI VALID/READY handshake safe across clock domains — hold data stable until acknowledged, cross control via synchronizers and data via FIFO/held-stable, no combinational paths across the boundary, and the req/ack vs async-FIFO trade-off.

This chapter closes Module 14 by consolidating the rules that keep AXI's VALID/READY handshake safe across a clock-domain boundary. We've seen why naive crossing fails (Chapter 14.1) and the async-FIFO bridge that solves it at high throughput (Chapter 14.2); here we state the underlying safety rules explicitly — the principles any correct CDC handshake follows, whether implemented as a FIFO (high-throughput) or a req/ack handshake (low-throughput single-item). The four rules: hold data stable until acknowledged, cross control via synchronizers / data via FIFO-or-held-stable, no combinational paths across the boundary, and Gray-code multi-bit control. These are the checklist for any AXI CDC.

1. The Core Rules

A safe CDC handshake follows four rules:

  • Hold data stable until acknowledged. The source must keep the payload stable until the destination has captured it — so the data is never changing when the destination samples it. (AXI's VALID-held-until-READY already provides this within a domain; across domains the crossing must preserve it.)
  • Cross control via synchronizers; data via FIFO or held-stable. Single-bit control signals (VALID/ack, pointers) cross through synchronizers (or Gray-coded, Rule 4); multi-bit data crosses through a FIFO (read only when present) or is held stable long enough to be captured safely — never per-bit synchronized (bit skew, Chapter 14.1).
  • No combinational paths across the boundary. Every signal crossing the boundary must be registered — no combinational logic spanning the two domains. In particular, VALID must not combinationally depend on a synchronized READY (that would create a metastable combinational loop across the boundary).
  • Gray-code multi-bit control. Any multi-bit control that crosses (FIFO pointers, counters) must be Gray-coded so only one bit changes per increment, making it safely synchronizable (Chapter 14.1).

These rules are the invariant behind every correct AXI CDC — the async FIFO (14.2) is one implementation that satisfies them all; a req/ack handshake is another. Violate any one and you get metastability, garbage data, or a broken/deadlocked handshake.

Four rules: hold data stable, control via sync and data via FIFO, no combinational boundary paths, Gray-code multi-bit control.Hold data stableuntil acknowledged/capturedControl via sync, data viaFIFOnever per-bit sync dataNo combinational boundarypathsregister everythingGray-code multi-bitcontrol1-bit-change safe sync12
Figure 1 — the four CDC handshake safety rules. (1) Hold data stable until acknowledged. (2) Cross control via synchronizers, data via FIFO/held-stable (never per-bit sync). (3) No combinational paths across the boundary — register everything, no VALID-on-synced-READY loop. (4) Gray-code multi-bit control. These are the invariant any correct AXI CDC satisfies.

2. The Req/Ack Handshake (Single-Item Crossing)

The simplest CDC handshake that satisfies the rules is a four-phase req/ack crossing for one item at a time. VALID/READY maps to req/ack (VALID ≈ req, the acknowledge ≈ ack):

  1. Source asserts req + drives stable data. The payload is held stable for the whole exchange.
  2. Destination synchronizes req (2-FF), then — because the data has been stable — safely captures the data and asserts ack.
  3. Source synchronizes ack, sees the item was captured, and deasserts req (and may change the data).
  4. Destination sees req deassert and deasserts ack — ready for the next item.

This crosses one item safely but is slow: each item costs multiple synchronizer latencies (req across + ack back), so the throughput is one item every several cycles. It's used for low-throughput crossings (an occasional control event, a single register update) where a full async FIFO is overkill. The data is safe because it's held stable the whole time (Rule 1), and only the single-bit req/ack cross via synchronizers (Rule 2).

cdc-handshake — four-phase req/ack, data held stable across the crossing

8 cycles
Source asserts req with stable data; destination asserts ack after synchronizing and capturing; source deasserts req after synchronizing ack; one item crosses over several cycles.data held stable; req → ack → deassertreq + stable datareq + stable dataack (dest captured the stable data)ack (dest captured the…clkreqdataXDDDDXXXackt0t1t2t3t4t5t6t7
Figure 2 — cdc-handshake: a four-phase req/ack crossing. The source asserts req and holds the data stable; the destination (after synchronizing req) captures the stable data and asserts ack; the source (after synchronizing ack) deasserts req; the destination deasserts ack. One item crosses safely — data held stable throughout, only single-bit req/ack synchronized — but it costs several cycles per item (low throughput).

3. Req/Ack vs Async FIFO

The two implementations satisfy the same rules at different throughput points:

  • Req/ack handshake: simple, small (a couple of synchronizers + the held-data register), but low-throughput — one item every several cycles (the round-trip synchronizer latency per item). Good for occasional, single-item crossings (a config event, a status flag, a low-rate control word).
  • Async FIFO: more logic (dual-clock memory + Gray-coded pointers), but high-throughput — it pipelines many items, sustaining up to one item per cycle (limited by the slower clock), because the pointers cross continuously rather than a full round-trip per item. Good for streaming/high-rate crossings — which is exactly the AXI channel traffic, hence the async-FIFO bridge (14.2).

So the choice mirrors the throughput need: an AXI data path (high beat rate) needs the async FIFO (the bridge); a rare single control event crossing a domain can use the simpler req/ack. Both obey the four rules — they differ only in how much they pipeline. Most full AXI CDC uses async FIFOs per channel; req/ack appears for auxiliary single-bit/single-event crossings around the interface.

Req/ack is simple and low-throughput for single items; async FIFO is more logic and high-throughput for streaming; both follow the rules.Req/acksimple, low-throughputSingle-item / occasionalcontrol eventsAsync FIFOmore logic, high-throughputStreaming / AXI channelsthe bridge (14.2)12
Figure 3 — req/ack vs async FIFO. Req/ack: simple/small, low-throughput (one item per several-cycle round trip) — for occasional single-item crossings. Async FIFO: more logic, high-throughput (pipelined, up to one item per cycle of the slower clock) — for streaming AXI channel traffic. Both satisfy the four rules; they differ in pipelining/throughput. AXI channels use async FIFOs (the bridge).

4. The No-Combinational-Path Rule and VALID/READY

The most AXI-specific rule deserves emphasis: no combinational path may cross the clock-domain boundary, and in particular VALID must not combinationally depend on a synchronized READY (nor vice versa). Why this matters:

  • Synchronizers introduce metastability resolution; if a synchronized READY fed combinationally into the VALID logic (which then crosses back), you'd create a path where metastability propagates through combinational logic and potentially loops across the boundary — undefined, dangerous behavior.
  • Recall (Chapter 11.2) that even within a domain, VALID must not combinationally depend on READY (deadlock avoidance). Across domains the rule is stronger: everything crossing must be registered, so the metastability is contained in synchronizer flops and resolved before use.

So at a CDC boundary, the VALID/READY handshake is reconstructed from registered/synchronized signals on each side (as the async-FIFO bridge does with full/empty flags, 14.2) — never wired combinationally across. This is why a CDC AXI crossing is always a structured component (FIFO or req/ack), not just synchronizers sprinkled on the existing combinational handshake. Getting this wrong produces the metastability-propagation and combinational-loop bugs that static CDC analysis exists to catch.

No combinational path across the boundary; register everything; reconstruct the handshake from registered signals, not combinational VALID-on-synced-READY.No combinationalpath acrossboundaryRegister everycrossing signalReconstructhandshake fromregistered/syncedsignalsMetastabilitycontained, noloop → safe
Figure 4 — the no-combinational-path rule. Every boundary-crossing signal must be registered; VALID must not combinationally depend on a synchronized READY (would propagate metastability through logic / loop across the boundary). The handshake is reconstructed from registered/synchronized signals on each side (FIFO flags or req/ack), never wired combinationally across — which is why a CDC crossing is a structured component, not synchronizers on the existing handshake.

5. Common Misconceptions

6. Debugging Insight

7. Verification Insight

8. Interview Questions

9. Summary

CDC handshake safety reduces to four rules that any correct cross-domain AXI handshake satisfies: (1) hold data stable until acknowledged/captured; (2) cross control via synchronizers and data via a FIFO (or held-stable) — never per-bit synchronize multi-bit data; (3) no combinational path across the boundary — register everything, and never let VALID combinationally depend on a synchronized READY; (4) Gray-code multi-bit control (pointers). These are implemented two ways at different throughputs: a req/ack four-phase handshake (simple, low-throughput, one item per several-cycle round trip — for occasional single-item crossings) or an async FIFO (more logic, high-throughput, pipelined — for AXI channel traffic, the bridge of 14.2). VALID/READY maps to req/ack, and the handshake is always reconstructed from registered signals on each side, never wired combinationally across.

The async-FIFO bridge satisfies all four rules (data stored-stable in memory, Gray-coded pointers synchronized, handshake reconstructed from registered full/empty flags, no combinational crossing) — which is why it's the standard. Because the rules are structural and metastability is sim-invisible, CDC handshake safety is verified by static CDC analysis (the rule-checker), complemented by metastability injection and functional integrity across clock ratios. This completes Module 14 — the discipline for crossing AXI between clock domains: the hazard (14.1), the bridge (14.2), reset (14.3–14.4), and these unifying rules (14.5), all verified structurally. Next, Module 15 turns hands-on: building a simple AXI4-Lite slave from scratch.

10. What Comes Next

You've completed the clock-domain module; Module 15 turns to building real AXI hardware:

Previous: 14.4 — Avoiding Partial Transactions. Related: 14.1 — AXI Across Clock Domains for the metastability foundation, and 14.2 — Asynchronous AXI Bridges for the FIFO implementation of these rules. For the broader protocol catalog, see the AMBA family overview doc.