Project: Synchronous FIFO

A first-in first-out buffer with full and empty flags using the extra-pointer-bit trick.

A FIFO buffers data between a producer and a consumer that do not run in lockstep: a UART receiving bytes faster than software reads them, a video pipeline, a network interface. A synchronous FIFO uses one clock for both sides; it is a small RAM plus a write pointer and a read pointer.

The design

Writes store din at wptr and increment it, unless full.

Reads increment rptr, unless empty.

dout always shows the oldest word (first-word fall-through).

Variations

assign full = (wptr + 1 == rptr); // pointers without the extra bit

Use an extra pointer bit (or a count register) With plain pointers, 'equal' means both empty and full. The usual fix of sacrificing one slot works, but the extra-bit trick uses every slot and keeps the logic simple.

Why can't you build an asynchronous FIFO by synchronizing binary pointers?

A binary pointer can change several bits at once (e.g. 0111 -> 1000); synchronizing the bits independently can produce a completely wrong value. Gray-coded pointers change one bit per step, so a synchronized value is always either the old or the new pointer.

What is first-word fall-through?

The oldest word is visible on dout without a read cycle; rd_en acknowledges it and moves to the next. In standard mode, data appears one clock after rd_en.