AMBA AXI · Module 14
AXI Across Clock Domains
The clock-domain-crossing (CDC) problem for AXI — metastability, why multi-bit buses can't be naively synchronized, why per-signal synchronizers fail for a handshaked bus, and why async FIFOs are the safe crossing for each AXI channel.
Real SoCs have multiple clock domains — a CPU at one frequency, peripherals at another, memory at a third — and AXI interfaces frequently cross between them. Crossing a clock-domain boundary safely is the CDC (clock-domain-crossing) problem, and AXI makes it harder than a single signal because it's a multi-signal, handshaked bus: VALID, READY, ADDR, DATA, and more must cross coherently. This chapter explains the underlying hazard (metastability), why multi-bit buses can't be naively synchronized, why synchronizing each AXI signal independently is wrong, and why the safe answer is an async FIFO per channel — the foundation for the async bridges of Chapter 14.2.
1. The Hazard — Metastability
When a signal generated in one clock domain is sampled by a flip-flop in another, the source signal can change arbitrarily close to the destination clock edge — violating the flop's setup/hold window. The flop can then enter a metastable state: its output hovers between 0 and 1 for an unpredictable time before resolving randomly. If that metastable value propagates into logic, it causes unpredictable, intermittent failures.
For a single-bit signal, the standard fix is a synchronizer — two (or more) back-to-back flops in the destination domain. The first flop may go metastable, but it has a full clock period to resolve before the second flop samples it, making the probability of metastability propagating vanishingly small (quantified by MTBF). This handles control bits safely. But a synchronizer only works for one bit at a time — and that's exactly where a multi-bit bus breaks.
2. Multi-Bit Buses Can't Be Naively Synchronized
The critical problem: you cannot safely synchronize a multi-bit bus (ADDR, DATA) by putting a synchronizer on each bit independently. The reason is bit skew — when the bus transitions, the bits don't all change at exactly the same instant (routing/timing differences), and each bit's synchronizer resolves its metastability independently and randomly. So on the destination side, some bits may resolve to the new value while others resolve to the old value in the same cycle — producing a garbage value that was never actually on the bus.
For example, a bus going from 0x0F to 0x10 (multiple bits changing) sampled mid-transition could resolve to 0x1F, 0x00, or any mix — a value the source never drove. Per-bit synchronizers make each bit metastability-safe but do nothing to keep the bits coherent as a word. So multi-bit data needs a fundamentally different crossing technique than control bits.
cdc-problem — multi-bit bus sampled mid-transition resolves to garbage
6 cycles3. Why Per-Signal AXI Synchronizers Fail
AXI compounds the problem because it's a handshaked, multi-signal protocol. Even setting aside multi-bit data skew, synchronizing each AXI signal (VALID, READY, ADDR, DATA) independently is wrong, because the synchronizers have different, independent latencies:
VALIDmight cross in 2 cycles whileDATA(if it could even cross — it can't naively) crosses in a different number — so the receiver could seeVALIDasserted before the correspondingDATAis stable, latching the wrong data.- The
VALID/READYhandshake timing is destroyed — the carefully-coupled relationship (data stable whileVALIDheld untilREADY) is broken ifVALIDand the payload cross with different, uncorrelated delays.
So the AXI signals must cross together, coherently — the payload (ADDR/DATA) must be guaranteed stable and associated with its VALID on the destination side. Independent per-signal synchronization gives no such guarantee. This is why a proper AXI CDC isn't "synchronize the signals" — it's a structured mechanism that crosses the data and its control as a coherent unit.
4. The Safe Crossing — Async FIFO per Channel
The standard, safe AXI CDC is an asynchronous FIFO on each channel. An async FIFO has a write port in the source domain and a read port in the destination domain, with a dual-clock memory between them:
- Data rides through memory. The payload (
ADDR/DATA/etc.) is written into the FIFO in the source domain and read out in the destination domain — it's only read when the FIFO indicates it's present and stable, so the destination never samples mid-transition. The multi-bit data never needs per-bit synchronizing because it's stored, not sampled-in-flight. - Pointers cross safely via Gray code. The FIFO's write and read pointers must cross domains (to compute full/empty), and they're Gray-coded — only one bit changes per increment — so a pointer can be synchronized bit-by-bit safely (a single-bit change can't produce a garbage multi-bit value; at worst the synchronized pointer lags by a cycle, which is safe/conservative for full/empty).
So the principle is: cross the control (pointers) as single-bit-safe Gray code through synchronizers, and let the data ride through the FIFO memory, read only when safe. Each AXI channel (AW, W, B, AR, R) gets its own async FIFO, preserving the per-channel handshake across the boundary. This is exactly what the interconnect's clock converter (Chapter 12.7) implements, and it's the structure the async bridges of Chapter 14.2 detail.
5. Common Misconceptions
6. Debugging Insight
7. Verification Insight
8. Interview Questions
9. Summary
Crossing an AXI interface between clock domains is the CDC problem, rooted in metastability: a signal sampled near the destination edge can hover undefined and cause intermittent failures. Single-bit control signals are crossed with synchronizers (2-FF, high MTBF), but multi-bit buses cannot be naively synchronized — per-bit synchronizers resolve independently, so bit skew produces garbage words never on the bus. AXI compounds this: synchronizing its signals independently breaks the VALID/payload association (wrong data latched) and the handshake timing (uncorrelated latencies), so the signals must cross coherently.
The safe crossing is an async FIFO per channel: the payload rides through dual-clock memory (written in the source domain, read in the destination domain only when present — never sampled mid-transition), while the Gray-coded pointers cross through synchronizers (one bit changes per increment → single-bit-safe, conservative full/empty). Control crosses as Gray pointers; data rides through memory. Each AXI channel gets its own FIFO, preserving the handshake — the interconnect's clock converter (12.7) and the async bridges (14.2). Critically, CDC needs static CDC analysis (functional sim doesn't model metastability), complemented by metastability injection — a structural proof that every crossing is safe. Next: the async bridge structure that implements this per-channel.
10. What Comes Next
You've got the CDC problem and principle; next, the bridge that implements it:
- 14.2 — Asynchronous AXI Bridges (coming next) — the async-FIFO bridge structure that crosses AXI between domains safely, channel by channel.
- 14.3 — Reset Sequencing (coming soon) —
ARESETnbehavior and synchronous-deassert reset discipline.
Previous: 13.6 — Identifying Performance Bottlenecks. Related: 12.7 — Clock & Reset in Interconnect for where clock converters sit in the fabric. For the broader protocol catalog, see the AMBA family overview doc.