Initializing and Resetting Arrays - 2022.2 English

Vitis High-Level Synthesis User Guide (UG1399)

Document ID
UG1399
Release Date
2022-12-07
Version
2022.2 English

In the following code, an array is initialized with a set of values. Each time the function is executed, array coeff is assigned these values. After synthesis, each time the design executes the RAM that implements coeff is loaded with these values. For a single-port RAM this would take eight clock cycles. For an array of 1024, it would of course take 1024 clock cycles, during which time no operations depending on coeff could occur.


int coeff[8] = {-2, 8, -4, 10, 14, 10, -4, 8, -2};

The following code uses the static qualifier to define array coeff. The array is initialized with the specified values at start of execution. Each time the function is executed, array coeff remembers its values from the previous execution. A static array behaves in C/C++ code as a memory does in RTL.


static int coeff[8] = {-2, 8, -4, 10, 14, 10, -4, 8, -2};

In addition, if the variable has the static qualifier, Vitis HLS initializes the variable in the RTL design and in the FPGA bitstream. This removes the need for multiple clock cycles to initialize the memory and ensures that initializing large memories is not an operational overhead. Refer to the initialization_and_reset example available on GitHub for examples.

The RTL configuration command config_rtl -reset can specify if static variables return to their initial state after a reset is applied. This is not the default. When reset state or all are used, it forces all arrays implemented as block RAM to be returned to their initialized state after reset. This can result in two very undesirable conditions in the RTL design:

  • Unlike a power-up initialization (or power-on reset), an explicit reset requires the RTL design to iterate through each address in the block RAM to set the value: this can take many clock cycles if N is large, and requires more area resources to implement the reset.
  • A reset is added to every array in the design.

To prevent adding reset logic onto every such block RAM, and incurring the cycle overhead to reset all elements in the RAM, specify the default control reset mode and use the RESET pragma or directive to identify individual static or global variables to be reset.

Alternatively, you can use the state reset mode, and use the RESET directive off option to select which individual static or global variables to not reset.

Finally, depending on the hardware device or platform of your choice (UltraScale+ or Versal, etc), there can be differences in how BRAMs and URAMs are initialized and/or reset. In general, Vitis HLS supports two types of reset: one is when the device is powered on (and also termed as power-up initialization or power-on reset), and the second is when a hardware RESET signal is asserted during device execution. The following shows the differences in behavior for the different memory resources:

  • Initialization Behavior: Applies to all BRAMs on all platforms and only to Versal URAMs. This is the behavior during power-on initialization (or power-on reset).
  • Maintaining an “initial value array” and “run time array” if the array is read/written. This applies to both BRAMs and URAMs and this corresponds to the hardware “RESET” signal during device execution.