FIFO (First-In-First-Out)
First-In-First-Out queue with independent read and write clocks. Buffers data between asynchronous streams. Features programmable full/empty thresholds, overflow/underrun detection, and status flags (FULL, EMPTY, PROG_FULL, PROG_EMPTY). Xilinx FPGA implementation.
Introduction
This block implements a FIFO buffer for data transfer between asynchronous clock domains. Write and read operations use independent clocks (CLK_WR, CLK_RD) and can occur at different rates.
Key features:
- Asynchronous read/write clocks
- FULL and EMPTY status flags
- Programmable almost-full/almost-empty thresholds
- Overflow and underrun detection
Read “After RESET” below before connecting WR: the FIFO is unable to accept a word for tens of clocks after reset, it says so on FULL, and a write issued in that window is discarded.
Pin Description
Properties
Set the amount of memory in number of words
FIFO depth in words. Allowed: 64-65536. Total storage = FIFO depth × Bit Width.Default: 1024
Options: 64 128 256 512 1024 2048 4096 8192 16384 32756 65536
Set the size in bits of the data
Bit width per word. Range: 1-1024.Default: 16
Range: 1 – 1024
PROG_EMPTY threshold in words. Must be between 3 and (FIFO depth - 3): outside that range the Xilinx XPM FIFO stops the simulation immediately. The upper bound depends on FIFO depth, so it is checked when you confirm this window.
Programmable empty threshold (3 to FIFO size-3). PROG_EMPTY asserts when count ≤ this value.Default: 3
Range: 3 – 65535
PROG_FULL threshold in words. Must be between 5 and (FIFO depth - 3): outside that range the Xilinx XPM FIFO stops the simulation immediately. The upper bound depends on FIFO depth, so it is checked when you confirm this window.
Programmable full threshold (5 to FIFO size-3; outside that range the Xilinx FIFO stops the simulation immediately and the compiler refuses the design). PROG_FULL asserts when count ≥ this value, and during the reset window.Default: 1021
Range: 5 – 65535
Functional description
FIFO maintains read and write pointers:
- Write: When WR=1 and not FULL, data is written on CLK_WR edge
- Read: When RD=1 and not EMPTY, data is read on CLK_RD edge
Status flags
- EMPTY: No data available to read
- FULL: No space available to write
- PROG_EMPTY: Data count below Prog Empty threshold
- PROG_FULL: Data count above Prog Full threshold
- OVERFLOW: Write attempted when FULL
- UNDERRUN: Read attempted when EMPTY
Timing
Read latency: 1 clock cycle (data appears 1 CLK_RD cycle after RD=1).
After RESET: wait for FULL to fall before writing
A dual-clock FIFO cannot accept a word until its internal reset handshake has crossed both clock domains, and that takes tens of clock cycles after RESET goes low - about 28 on the measured configuration, and more if CLK_WR and CLK_RD are far apart in frequency.
FULL (and PROG_FULL) stay HIGH for the whole of that window. Gate WR with
FULL - WR = my_request AND NOT FULL - and the design is simply held off
until the queue is ready: nothing is written, nothing is lost, and the word
stays in the producer’s hands. This is the same back-pressure that protects
you when the queue is genuinely full, so there is nothing special to write
for the reset case.
A write issued while FULL is high is DISCARDED, not queued. OVERFLOW reports it, but only after the fact - and a design that drives WR unconditionally right after reset therefore loses its first words silently. That is by far the most common way to lose data with this block.
EMPTY and PROG_EMPTY are likewise high through the window, so a reader that waits for EMPTY to fall is safe without any extra logic.
Typical use cases
- Clock domain crossing
- Rate matching between fast producer and slow consumer
- Data buffering in streaming systems