set_directive_bind_storage - 2023.2 English

Vitis High-Level Synthesis User Guide (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 English

Description

The set_directive_bind_storage command assigns a variable (array, or function argument) in the code to a specific memory type (type) in the RTL. If the command 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 set_directive_bind_storage command to specify which type of memory, and which implementation to use for an array variable. Also, this allows you to control whether the array is implemented as a single or a dual-port RAM.

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 use the -latency option to specify the latency of the implementation. For block RAMs on the interface, the -latency option allows you to 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 operation 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.

For best results, AMD recommends that you use -std=c99 for C and -fno-builtin for C and C++. To specify the C compile options, such as -std=c99, use the Tcl command add_files with the -cflags option. Alternatively, select the Edit CFLAGs button in the Project Settings dialog box as described in Creating an HLS Component.

Syntax

set_directive_bind_storage [OPTIONS] <location> <variable>
  • <location> is the location (in the format function[/label]) which contains the variable.
  • <variable> is the variable to be assigned.
    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.

Options

-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, and 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 for FIFO, lets the 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.
Tip: URAMs do not support a read-first output write_mode (unlike BRAMs) when a read and a write to the same address is mapped to the same memory port. BRAM supports the following write-modes: write thru, read first, no change. URAM only supports no change. Vitis HLS will issue the following warning message when it cannot schedule memory operations in the same cycle on a URAM port:
Usage of URAM can potentially cause worse II as Vitis HLS does not exploit 
read-first mode for URAMs. Consider using BRAMs instead.
Table 3. Supported Implementations by FIFO/RAM/ROM
Type Command/Pragma Scope Supported Implementations
FIFO bind_storage 1 local AUTO, BRAM, LUTRAM, URAM, MEMORY, SRL
FIFO config_storage global AUTO, BRAM, LUTRAM, URAM, 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 storage type to the implementation. The valid latency varies according to the specified type and impl. The default is -1, which lets Vitis HLS choose the latency.
Table 4. Supported Combinations of Memory Type, Implementation, and Latency
Type Implementation Min Latency Max Latency
FIFO BRAM 1 4
FIFO LUTRAM 1 4
FIFO MEMORY 1 4
FIFO SRL 1 4
FIFO URAM 1 4
RAM_1P AUTO 1 3
RAM_1P BRAM 1 3
RAM_1P LUTRAM 1 3
RAM_1P URAM 1 3
RAM_1WNR AUTO 1 3
RAM_1WNR BRAM 1 3
RAM_1WNR LUTRAM 1 3
RAM_1WNR URAM 1 3
RAM_2P AUTO 1 3
RAM_2P BRAM 1 3
RAM_2P LUTRAM 1 3
RAM_2P URAM 1 3
RAM_S2P BRAM 1 3
RAM_S2P BRAM_ECC 1 3
RAM_S2P LUTRAM 1 3
RAM_S2P URAM 1 3
RAM_S2P URAM_ECC 1 3
RAM_T2P BRAM 1 3
RAM_T2P URAM 1 3
ROM_1P AUTO 1 3
ROM_1P BRAM 1 3
ROM_1P LUTRAM 1 3
ROM_2P AUTO 1 3
ROM_2P BRAM 1 3
ROM_2P LUTRAM 1 3
ROM_NP BRAM 1 3
ROM_NP LUTRAM 1 3
Important: Any combinations of memory type and implementation that are not listed in the prior table are not supported by set_directive_bind_storage.

Examples

In the following example, the coeffs[128] variable is an argument to the function func1. The directive specifies that coeffs uses a single port RAM implemented on a BRAM core from the library.

set_directive_bind_storage -impl bram "func1" coeffs RAM_1P
Tip: The ports created in the RTL to access the values of coeffs are defined in the RAM_1P core.