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 4.1

Dual-clock architecture

An async FIFO is two pointer engines plus a dual-port RAM. Data never crosses. Gray pointers cross through 2FF synchronizers. Full lives with the writer. Empty lives with the reader.

1

Block diagram

wr_clk domain wbin / wgray increment wr_fire = wr_en & ~full 2FF sync rgray โ†’ wq2_rgray then FULL compare Write port of RAM addr = wbin[ADDR_W-1:0] full (to producer) rd_clk domain rbin / rgray increment rd_fire = rd_en & ~empty 2FF sync wgray โ†’ rq2_wgray then EMPTY compare Read port of RAM addr = rbin[ADDR_W-1:0] empty (to consumer)

Dual-port RAM sits on the boundary: write-side sequential, read-side sequential, no combinational path between clocks.

2

What crosses the CDC

NetDirectionEncodingSynchronizer
wgraywr โ†’ rdregistered Gray2FF on rd_clk โ†’ rq2_wgray
rgrayrd โ†’ wrregistered Gray2FF on wr_clk โ†’ wq2_rgray
wdata / rdatanoneRAMnot synchronized

Because a 2FF chain delays the pointer by two destination clocks, flags are slightly pessimistic: you may see full a little early and empty a little early. That can cost a few entries of apparent depth. It must never allow overflow/underflow.

3

Power-of-two depth

Gray pointer wrap only stays unit-distance for a binary count that uses all 2^n states. Classic async FIFO depth must be a power of two. For a 10-deep FIFO you either waste 6 locations (use 16) or use a different (harder) style: dual n-bit Gray plus converted occupancy, or a vendor hard FIFO.

4

2FF vs 3FF and reported MTBF

MTBF of a synchronizer grows exponentially with extra flops and with a faster receiving clock (more time to resolve before the next sample โ€” actually faster clocks hurt resolution time). Datasheets for FPGA synchronizer hardness assume you used the dedicated ASYNC_REG pair. Custom ASIC 2FF cells are characterized. Do not roll your own three latches. For this course, 2FF is the answer unless a safety spec mandates 3FF.

5

When to instance a vendor FIFO

Use a hard/generated FIFO when you need ECC, FWFT, non-power-of-two, very deep BRAM cascade, or built-in almost-full calibrated in the GUI. Still draw the same boxes in a review: two clocks, RAM, Gray (or vendor-secret) pointers. Never mix two vendor FIFOsโ€™ almost-full encodings without reading the data sheet โ€” some count in words, some in cycles of lag.

Q

Frequently asked questions

What crosses the clock boundary in an async FIFO?

Only the registered Gray write pointer into the read domain and the registered Gray read pointer into the write domain, each through a 2FF. Data stays in dual-port RAM.

Why must DEPTH be a power of two?

The extra-MSB Gray scheme assumes a binary pointer that uses all 2^n states so wrap remains unit-distance. A 10-deep FIFO uses 16 locations or a different (harder) coding.

Why are flags conservative?

Each 2FF hides the last two destination clocks of opposite-side traffic. You may stall with a free slot or wait with data already in RAM. You must not overwrite or read garbage.

Where does dual-port RAM sit?

Write port sequential on wr_clk, read port sequential on rd_clk. No combinational path between the two clocks through the RAM.

Key takeaways

  • Two domains, two pointers, one dual-port RAM.
  • Only Gray pointers cross, each through a 2FF.
  • Flags are conservative because of synchronizer latency.