Skip to main content...
S2 · Verilog RTL Design
35 min

Day 79: The async FIFO: gray-code pointers

The async FIFO is the safe way to move data between clock domains — and gray-coded pointers are the clever trick that makes it work.

The async FIFO: gray-code pointers

An asynchronous FIFO buffers data between a write clock and a read clock — the standard, safe multi-bit CDC structure. Its challenge: each side must compare its pointer against the *other* domain's pointer to compute full/empty, which means crossing a multi-bit pointer between domains. The solution is gray coding: encode the pointers so only one bit changes per increment, making them safe to synchronize.

Binary-to-gray and gray-to-binary conversion
// gray = binary XOR (binary >> 1)   -- only one bit flips per increment
function [W-1:0] bin2gray(input [W-1:0] b);
    bin2gray = b ^ (b >> 1);
endfunction

// binary = gray XOR (gray>>1) XOR (gray>>2) ...  (prefix-XOR)
function [W-1:0] gray2bin(input [W-1:0] g);
    integer i; reg [W-1:0] b;
    begin b = g; for (i=1;i<W;i=i+1) b = b ^ (g >> i); gray2bin = b; end
endfunction

// write side: increment binary wptr, convert to gray, SYNC into read domain
// read  side: increment binary rptr, convert to gray, SYNC into write domain

Why gray code is the key

This is the deep idea foreshadowed all the way back in Stage 0's K-maps (Day 20). Because a gray-coded pointer changes only one bit per step, synchronizing it can only ever be 'off by one count' at worst — never a wildly wrong value from multiple bits resolving differently. That single-bit-change property is what makes the multi-bit crossing safe.

Key terms

Asynchronous FIFO
A FIFO with independent write and read clocks; the standard safe multi-bit CDC structure.
Gray code
An encoding where consecutive values differ in exactly one bit — safe to synchronize across domains.
Pointer synchronization
Passing a gray-coded read/write pointer into the other clock domain via 2-FF synchronizers.
bin2gray / gray2bin
Conversions: gray = b ^ (b>>1); binary via prefix-XOR of the gray value.

Progress for Day 79

Why are async-FIFO pointers gray-coded before crossing clock domains?

We use cookies

We use cookies to enhance your browsing experience, serve personalized content, and analyze our traffic. By clicking "Accept All", you consent to our use of cookies. Learn more

    Day 79: The async FIFO: gray-code pointers | RBTechIconX