Bind_storage - Bind_storage - 2026.1 English - UG1399

Vitis High-Level Synthesis User Guide (UG1399)

Document_ID
UG1399
Release_Date
2026-09-11
Version
2026.1 English

Description

The BIND_STORAGE pragma assigns a variable (array, or function argument) in the code to a specific memory type ( type ) in the RTL. If the pragma is not specified, the Vitis HLS tool determines the memory type to assign. The HLS tool implements the memory using specified implementations ( impl ) in the hardware.

For example, you can use the pragma to specify which memory type to use to implement an array. This lets you control whether the array is implemented as a single or a dual-port RAM for example.

Important: This feature is important for arrays on the top-level function interface, because the memory type associated with the array determines the number and type of ports needed in the RTL, as discussed in Arrays on the Interface . However, for variables assigned to top-level function arguments you must assign the memory type and implementation using the -storage_type and -storage_impl options of the INTERFACE pragma or directive.

You can also specify the latency of the implementation. For block RAMs on the interface, the latency option lets you model off-chip, non-standard SRAMs at the interface, for example supporting an SRAM with a latency of 2 or 3. For internal operations, the latency option allows the memory to be implemented using more pipelined stages. These additional pipeline stages can help resolve timing issues during RTL synthesis.

Important: To use the latency option, the operation must have an available multi-stage implementation. The HLS tool provides a multi-stage implementation for all block RAMs.

Syntax

Form Syntax
Pragma #pragma HLS bind_storage variable=<v> type=<type> impl=<value> latency=<int>
Config File syn.directive.bind_storage=[OPTIONS] <loc> <var> type=<val> impl=<val> latency=<int>
Tcl set_directive_bind_storage [OPTIONS] <loc> <var> -type <val> -impl <val> -latency <int>

Place the pragma in the C/C++ source within the body of the function where the variable is defined.

#pragma HLS bind_storage variable=<variable> type=<type>\
[ impl=<value> latency=<int> ]

Options

variable=<variable>
Defines the variable to assign the BIND_STORAGE pragma to. This is required when specifying the pragma.
Tip: If the variable is an argument of a top-level function, then use the -storage_type and -storage_impl options of the INTERFACE pragma or directive.
type=<type>
Defines the type of memory to bind to the specified variable.
Supported types include: fifo , ram_1p , ram_1wnr , ram_2p , ram_s2p , ram_t2p , rom_1p , rom_2p , rom_np .
Table 1. Storage Types
Type Description
FIFO A FIFO. Vitis HLS determines how to implement this in the RTL, unless the -impl option is specified.
RAM_1P A single-port RAM. Vitis HLS determines how to implement this in the RTL, unless the -impl option is specified.
RAM_1WNR A RAM with 1 write port and N read ports, using N banks internally.
RAM_2P A dual-port RAM that allows read operations on one port and both read and write operations on the other port.
RAM_S2P A dual-port RAM that allows read operations on one port and write operations on the other port.
RAM_T2P A true dual-port RAM with support for both read and write on both ports.
ROM_1P A single-port ROM. Vitis HLS determines how to implement this in the RTL, unless the -impl option is specified.
ROM_2P A dual-port ROM.
ROM_NP A multi-port ROM.
Tip: If you specify a single port RAM for a PIPO, then the binder will typically allocate a merged-PIPO, with only one bank, and reader and writer accessing different halves of the bank. The info message reported by the HLS compiler says "Implementing PIPO using a single memory for all blocks." This is often cheaper for small PIPOs, where all banks can share a single RAM block. However, if you specify a dual-port RAM for a PIPO to get higher bandwidth and the scheduler uses both ports either in the producer or in the consumer, then the binder will typically allocate a split-PIPO, where the producer will use 1 port and the consumer 2 ports of different banks. The info message reported by the HLS compiler in this case says "Implementing PIPO using a separate memory for each block."
impl=<value>
Defines the implementation for the specified memory type. Supported implementations include: bram , bram_ecc , lutram , uram , uram_ecc , srl , memory , and auto as described below.
Table 2. Supported Implementation
Name Description
MEMORY Generic memory lets the AMD Vivado™ tool choose the implementation.
URAM UltraRAM resource
URAM_ECC UltraRAM with ECC
SRL Shift Register Logic resource
LUTRAM Distributed RAM resource
BRAM Block RAM resource
BRAM_ECC Block RAM with ECC
AUTO Vitis HLS automatically determine the implementation of the variable.
Table 3. Supported Implementations by FIFO/RAM/ROM
Type Command/Pragma Scope Supported Implementations
FIFO bind_storage 1 local AUTO , BRAM, BRAM_ECC, LUTRAM, URAM, URAM_ECC, MEMORY, SRL
FIFO config_storage global AUTO , BRAM, BRAM_ECC, LUTRAM, URAM, URAM_ECC, MEMORY, SRL
RAM* | ROM* bind_storage local AUTO BRAM, BRAM_ECC, LUTRAM, URAM, URAM_ECC
RAM* | ROM* config_storage 2 global N/A
RAM_1P set_directive_interface s_axilite -storage_impl local

AUTO , BRAM, URAM

  config_interface -m_axi_buffer_impl global

AUTO, BRAM , LUTRAM, URAM

  1. When no implementation is specified the directive uses AUTOSRL behavior as a default. However, this value cannot be specified.
  2. config_storage only supports FIFO types.
latency=<int>
Defines the default latency for the binding of the type. As shown in the following table, the valid latency varies according to the specified type and impl . The default is -1, that lets Vitis HLS choose the latency.
ce_reg=<1|0>

Default is 0, a value of 1 with a latency set to 2 or more inserts a register on the memory input CE to improve timing. Works for LUTRAM/BRAM/URAM.

Table 4. Supported Combinations of Memory Type, Implementation, and Latency
Type Implementation Min Latency Max Latency
FIFO BRAM 0 0
FIFO LUTRAM 0 0
FIFO MEMORY 0 0
FIFO SRL 0 0
FIFO URAM 0 0
RAM_1P AUTO 1 5
RAM_1P BRAM 1 5
RAM_1P LUTRAM 1 5
RAM_1P URAM 1 5
RAM_1WNR AUTO 1 5
RAM_1WNR BRAM 1 5
RAM_1WNR LUTRAM 1 5
RAM_1WNR URAM 1 5
RAM_2P AUTO 1 5
RAM_2P BRAM 1 5
RAM_2P LUTRAM 1 5
RAM_2P URAM 1 5
RAM_S2P BRAM 1 5
RAM_S2P BRAM_ECC 1 5
RAM_S2P LUTRAM 1 5
RAM_S2P URAM 1 5
RAM_S2P URAM_ECC 1 5
RAM_T2P BRAM 1 5
RAM_T2P URAM 1 5
ROM_1P AUTO 1 5
ROM_1P BRAM 1 5
ROM_1P LUTRAM 1 5
ROM_2P AUTO 1 5
ROM_2P BRAM 1 5
ROM_2P LUTRAM 1 5
ROM_NP BRAM 1 5
ROM_NP LUTRAM 1 5
Note: BRAM_ECC and URAM_ECC are supported for all types except for ROM.
Tip: For FIFOs with 0 latency means that the following:
  • read data is available on the FIFO output in the same cycle in which the read input is active.
  • write data is accepted by the FIFO input in the same cycle in which the write input is active.

The read-after-write latency, for example, the number of cycles after which data that has been written can be read from the FIFO can be configured only globally: config_storage fifo -read_after_write_latency N

Important: Any combinations of memory type and implementation that are not listed in the prior table are not supported by set_directive_bind_storage .

Example

The pragma specifies that the variable coeffs uses a single port RAM implemented on a BRAM core from the library.

#pragma HLS bind_storage variable=coeffs type=RAM_1P impl=bram
Tip: The ports created in the RTL to access the values of coeffs are defined in the RAM_1P.