Memory in FPGAs
Block RAM, distributed RAM, and FIFOs
Every useful digital system needs to store data. Processors have caches and registers. FPGAs have something better: built-in memory blocks that you can shape into exactly the structure your design needs.
Need a lookup table with 1,024 entries? A dual-port buffer so two modules can share data? A FIFO to safely pass data between clock domains? FPGAs give you dedicated, fast, on-chip memory, and lots of it. Let's see how it works.
Explore: RAM & FIFO
Switch between the RAM and FIFO tabs to explore two essential memory structures:
Types of FPGA Memory
Block RAM (BRAM) is dedicated memory hardware embedded throughout the FPGA. Each block is typically 18 Kbit or 36 Kbit and can be configured for different widths and depths (1024×18, 512×36, 2048×9, and so on). Block RAM is synchronous: reads and writes happen on clock edges, which makes timing predictable and fast. Most importantly, block RAM supports dual-port access, meaning two independent ports can read or write the same memory simultaneously, each with its own address, data, and clock.
Distributed RAM uses the LUTs inside CLBs as small memory elements. Since LUTs are already tiny memories (a 6-input LUT stores 64 bits), the FPGA tools can repurpose them as RAM. Distributed RAM is ideal for small, fast memories, typically 16 to 64 entries. It supports asynchronous reads (data appears immediately, no clock needed) and is sprinkled throughout the chip, so it's close to your logic. The trade-off: every LUT used as memory is a LUT that can't be used for logic.
When to use which? Use block RAM for anything over about 256 entries: data buffers, coefficient tables, instruction memories, FIFOs. Use distributed RAM for small register files, shallow FIFOs, and lookup tables that need instant reads. The synthesis tool will often make this choice for you based on size, but understanding the trade-off helps you write better HDL.
FIFOs (First-In, First-Out) are the workhorses of digital data flow. A FIFO has a write side and a read side: data goes in one end and comes out the other in the same order. Under the hood, a FIFO is a RAM with two pointers, one tracking where to write next and one tracking where to read next. FIFOs are essential when two modules produce and consume data at different rates, and they are critical for safely passing data across clock domain boundaries when built with gray-coded pointers.
Why This Matters
Memory is the glue that holds FPGA designs together:
- Data buffering: When a sensor produces samples faster than your processing pipeline can consume them, a FIFO absorbs the bursts without losing data.
- Clock domain crossing: When two parts of your design run on different clocks, an asynchronous FIFO with gray-coded pointers is the standard safe bridge between them.
- Video frame buffers: Storing an entire video frame (or even a few lines) requires large block RAM arrays. Dual-port RAM lets the camera write while the display reads simultaneously.
- Coefficient storage: FIR filter coefficients, sine lookup tables, and encryption keys all live in block RAM, ready for instant access every clock cycle.
Frequently Asked Questions
What is block RAM in an FPGA?
Block RAM (BRAM) is dedicated memory hardware embedded in the FPGA. Each BRAM block is typically 18 Kbit or 36 Kbit and can be configured as various widths and depths (e.g., 1024×18 or 512×36). BRAMs support synchronous read and write, dual-port access (two independent ports reading/writing simultaneously), and are the primary on-chip storage for data buffers, FIFOs, lookup tables, and register files.
How do FIFOs work?
A FIFO (First-In, First-Out) buffer stores data in the order it arrives and reads it out in the same order. It uses two pointers: a write pointer (where new data goes) and a read pointer (where data comes out). When write advances faster than read, the FIFO fills up. When read catches up, it empties. FIFOs are critical for clock domain crossings, rate matching, and buffering between modules that produce and consume data at different speeds.
What is the difference between block RAM and distributed RAM?
Block RAM uses dedicated memory hardware: large, efficient, but limited in quantity and location. Distributed RAM uses the LUTs in CLBs as small memories, which are flexible and available everywhere, but it consumes logic resources. Use block RAM for large memories (256+ entries) and distributed RAM for small, fast memories (16-64 entries) like register files or small lookup tables.
Quick Check
Test your understanding of the key concepts from this lesson.






