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

Day 82: Memory inference: BRAM patterns the tools recognize

The tools recognize certain RTL patterns as memory and map them to dense on-chip RAM blocks. Write the pattern the tool wants.

Memory inference: BRAM patterns

On an FPGA, dedicated block RAM (BRAM) is far denser than building memory from flip-flops. Synthesis infers BRAM when your RTL matches a recognized pattern: a 2-D reg array with a synchronous (clocked) read and/or write. Deviating — an asynchronous read, or reading and writing weirdly — forces the tool to use flip-flops or LUT-RAM instead, wasting area. Write the pattern the tool wants.

A BRAM-inferring simple dual-port RAM (synchronous read)
module bram #(parameter W=32, DEPTH=1024, AW=10) (
    input               clk,
    input               we,
    input  [AW-1:0]     waddr, raddr,
    input  [W-1:0]      wdata,
    output reg [W-1:0]  rdata          // registered read -> infers BRAM
);
    reg [W-1:0] mem [0:DEPTH-1];
    always @(posedge clk) begin
        if (we) mem[waddr] <= wdata;
        rdata <= mem[raddr];           // SYNCHRONOUS read is the key
    end
endmodule

Async read breaks BRAM inference

The single most common reason a memory *doesn't* map to BRAM is an asynchronous read (assign rdata = mem[raddr];). BRAMs have a registered output, so the read must be clocked. If you need async-read behavior (like a register file), the tool uses distributed LUT-RAM or flip-flops instead — fine for 32 entries, ruinous for a cache. Match the pattern to the resource.

Before moving on, you should be able to

What RTL feature is essential for a memory array to be inferred as FPGA block RAM (BRAM)?

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 82: Memory inference: BRAM patterns the tools recognize | RBTechIconX