Increasing Local Memory Bandwidth

This section shows several ways provided by Vivado HLS to increase local memory bandwidth, which can be used together with loop pipelining and loop unrolling to improve system performance.

Arrays are intuitive and useful constructs in C/C++ programs. They allow the algorithm be easily captured and understood. In Vivado HLS, each array is by default implemented with a single port memory resource. However, such memory implementation may not be the most ideal memory architecture for performance oriented programs. At the end ofLoop Pipelining and Loop Unrolling, an example of resource contention caused by limited memory ports is shown.

Array Partitioning

Arrays can be partitioned into smaller arrays. Physical implementation of memories have only a limited number of read ports and write ports, which can limit the throughput of a load/store intensive algorithm. The memory bandwidth can sometimes be improved by splitting up the original array (implemented as a single memory resource) into multiple smaller arrays (implemented as multiple memories), effectively increasing the number of load/store ports.

Vivado HLS provides three types of array partitioning, as shown in the following figure.
  1. block: The original array is split into equally sized blocks of consecutive elements of the original array.
  2. cyclic: The original array is split into equally sized blocks interleaving the elements of the original array.
  3. complete: The default operation is to split the array into its individual elements. This corresponds to implementing an array as a collection of registers rather than as a memory.

Figure:Array Partitioning



To partition an array in Vivado HLS, insert this in the hardware function source code:
#pragma HLS array_partition variable=  factor= dim=
For blockand cyclicpartitioning, the factoroption can be used to specify the number of arrays which are created. In the figure above, a factor of two is used, dividing the array into two smaller arrays. If the number of elements in the array is not an integer multiple of the factor, the last array will have fewer than average elements.
When partitioning multi-dimensional arrays, the dimoption can be used to specify which dimension is partitioned. The following figure shows an example of partitioning different dimensions of a multi-dimensional array.

Figure:Multi-dimension Array Partitioning



Array Reshaping

Arrays can also be reshaped to increase the memory bandwidth. Reshaping takes different elements from a dimension in the original array, and combines them into a single wider element. Array reshaping is similar to array partitioning, but instead of partitioning into multiple arrays, it widens array elements. The following figure illustrates the concept of array reshaping.

Figure:Array Reshaping



To use array reshaping in Vivado HLS, insert this in the hardware function source code:
#pragma HLS array_reshape variable=  factor= dim=
The options have the same meaning as the array partition pragma.