Sign in on the Premium hub to save lesson progress. This lesson is open to read so the page is a complete article, not an empty login wall.
Lesson 1.2

Sync FIFO vs async FIFO

Same queue idea. Different physics. A sync FIFO has one clock: pointers are ordinary registers you can compare combinationally. An async FIFO has two clocks: you must not compare a live binary counter from the other domain.

1

Side-by-side

Sync FIFOAsync FIFO
ClocksOne clkwr_clk and rd_clk, unrelated
Memory1-port or simple dual-port RAMTrue dual-port RAM (write on wr_clk, read on rd_clk)
PointersBinary, same domainBinary locally, Gray across the CDC
Full flagWrite domain (same as read)Generated in write domain from synced read pointer
Empty flagSame clockGenerated in read domain from synced write pointer
ResetOne reset (sync or async-assert)Per-domain reset; deassert synchronized on each clock
2

What you are allowed to compare

Sync β€” legal wptr, rptr, both on clk empty = (wptr == rptr) + extra MSB or count to tell full Async β€” illegal compare wptr_bin @ wr_clk with rptr_bin @ rd_clk multi-bit CDC / metastability

Never sample a multi-bit binary counter with a foreign clock. That is the whole reason for Gray pointers.

3

Waveform β€” two unrelated clocks

An async FIFO does not use a divided copy of one clock. wr_clk and rd_clk come from different PLLs / pads. There is no common rising edge, no integer period ratio you may assume, and no legal combinational path between domains. The diagram below uses WaveDrom period and phase so the clocks are not the same grid β€” that is the picture you should keep in your head.

If two clocks look identical in a slide, treat it as a drawing bug β€” silicon will not line those edges up. Dual-port RAM is written on wr_clk and read on rd_clk. full is a write-domain signal; empty is a read-domain signal. Never AND them in one always block.

Interview

β€œCan I 2FF-synchronize an 8-bit data bus?” β€” No. Each bit can resolve to a different sample. Use a FIFO (or handshake + captured data, or Gray if the bus is a counter). Data in an async FIFO does not cross; only Gray pointers do.

4

Metastability is why the 2FF exists

When a Gray bit is sampled near its transition by rd_clk, the first synchronizer flop can sit at an illegal voltage for a while. The second flop is far less likely to see a mid-level. That is all the 2FF buys you: a clean bit, not a fresh pointer. The pointer is still one or two read clocks stale. Flags computed from it must stay conservative so a stale β€œnot full” never licenses a write into a truly full RAM.

Three-flop synchronizers appear in very high reliability flows. They add latency and reduce apparent FIFO depth further. This course uses 2FF as the industry default for internal chip CDC of Gray pointers with a constrained MTBF.

5

Port list you should memorize

Write side: wr_clk, wr_rst_n, wr_en, wdata, full (and optional almost_full). Read side: rd_clk, rd_rst_n, rd_en, rdata, empty (and optional almost_empty, data_valid for FWFT). There is no shared clk. There is no combinational path from write-domain flops to read-domain flops except the intended Gray nets into synchronizer D-pins.

FPGA hard FIFO primitives (Xilinx FIFO Generator, Intel DCFIFO) implement this partition for you. You still need to know it: interviews and custom ASIC FIFOs will ask you to draw it from scratch.

Q

Frequently asked questions

What is the difference between a sync FIFO and an async FIFO?

A sync FIFO uses one clock; pointers are binary and compared in the same domain. An async FIFO uses two unrelated clocks, dual-port RAM for data, Gray-coded pointers through 2FF synchronizers, full in the write domain, and empty in the read domain.

Do wr_clk and rd_clk have to be related?

No. They may come from different PLLs or pads. You must not assume a common edge or an integer period ratio. Waveforms that show identical clocks are a drawing error.

Why not 2FF-synchronize the data bus?

Each bit can resolve on a different sample. The captured word can be a value that was never driven. Keep payload in RAM and cross only a unit-distance Gray pointer.

Where is the full flag generated?

In the write clock domain, from the local write Gray pointer compared with a 2FF-synchronized copy of the read Gray pointer. Empty is the mirror on the read clock.

Key takeaways

  • Sync FIFO: one clock, binary pointers, compare locally.
  • Async FIFO: two clocks, dual-port RAM, Gray pointer CDC, conservative flags.
  • Data stays in RAM. Only control (pointers) crosses domains.