Draft preview. Lessons are being written and reviewed.

Digital Design / Module 10: Clock domain crossing

58. Asynchronous FIFO

Design the standard solution for bulk crossing.

Lecture coming soon

See it move

The idea

An asynchronous lets streams of data pass between two unrelated clocks. The memory is dual-port and holds data steady. The only signals crossing domains are the read and write pointers, in .

The structure

  • The write side keeps a binary write pointer, and a registered Gray copy.
  • The read side does the same, with its read pointer.
  • Each Gray pointer goes through a two-flop into the other domain.
  • Full is computed in the write domain, and empty in the read domain.
// Write domain
assign wbin_next  = wbin + (wr && !full);
assign wgray_next = (wbin_next >> 1) ^ wbin_next;
assign full_next  = (wgray_next ==
    {~rgray_sync[AW:AW-1], rgray_sync[AW-2:0]});

always_ff @(posedge wclk or negedge wrst_n)
  if (!wrst_n) {wbin, wgray, full} <= '0;
  else         {wbin, wgray, full} <= {wbin_next, wgray_next, full_next};

// Read domain
assign rbin_next  = rbin + (rd && !empty);
assign rgray_next = (rbin_next >> 1) ^ rbin_next;
assign empty_next = (rgray_next == wgray_sync);

The full condition

With Gray pointers having one extra bit, the FIFO is empty when the pointers match. It's full when the top two bits differ and the rest match, rather than when just the MSB differs. That's a consequence of how Gray code mirrors its sequence.

Why the flags are safe

Each side sees the other's pointer a few cycles late.

  • The writer sees an old read pointer, so it thinks the FIFO has less space than it does. It may declare full early, but it can't overflow.
  • The reader sees an old write pointer, so it thinks the FIFO holds less data than it does. It may declare empty early, but it can't underflow.

Flags can be pessimistic, and they can never be dangerously wrong. The result is a small loss of usable , in exchange for complete safety.

Sizing

Extra depth covers the pointer synchronizer delay. The animation above uses a real two-clock simulation model: change the clock ratio and watch the contents move without losing a word.

Common mistake

Combining reset poorly. Each domain needs its own synchronized reset, and the pointers must not change during the release. Also, the depth must be a power of two for this Gray scheme to work without special handling.

Key ideas

  • Gray pointers cross domains through synchronizers.
  • Full is computed in the write domain and empty in the read domain.
  • Stale pointers make flags conservative, which is safe.

Lab: Clock crossing lab

Your exercise

Build a depth-16 async FIFO and test different clock ratios.

Find the bug

This code has one deliberate bug. Read the symptom, then click the line you think is wrong.

What goes wrong: The FIFO reports full at the wrong times, so data can be overwritten while other flags seem fine.

Interview questions

coreWhat is the full condition with Gray pointers?

basicIn an asynchronous FIFO, why is full computed in the write domain and empty in the read domain?

basicWhy do the pointers of a depth-16 async FIFO have 5 bits, and why does the depth need to be a power of two?

coreA depth-8 async FIFO uses 4-bit Gray pointers. The synchronized read pointer is binary 2. What write pointer, in binary and in Gray, makes the FIFO full?

coreEach side of an async FIFO only sees a delayed copy of the other side's pointer. Why can that never cause an overflow or an underflow?

coreThis full flag was written by copying the binary rule (invert only the MSB) into the Gray version. What happens?

assign full_next = (wgray_next == {~rgray_sync[AW], rgray_sync[AW-1:0]});

coreWhy is full computed from wgray_next and registered, rather than computed combinationally from the current wgray?

advancedA burst of 64 words is written at 200 MHz into an async FIFO, one word per cycle. The reader takes one word per cycle at 100 MHz. What depth would you choose?

advancedHow would you add an almost-full flag to an async FIFO, and why is it still safe?

Practise these 9 questions with animations