The link phase is when the memory ports of the kernels are connected to
memory resources which include DDR, HBM, and PLRAM. By default, when the
xclbin file is produced during the
v++ linking process, all kernel memory interfaces are connected to the same global
memory bank (or
gmem). As a result, only one kernel
interface can transfer data to/from the memory bank at one time, limiting the performance of
the application due to memory access.
While the Vitis compiler can automatically connect CU to global memory resources, you can also manually specify which global memory bank each kernel argument (or interface) is connected to. Proper configuration of kernel to memory connectivity is important to maximize bandwidth, optimize data transfers, and improve overall performance. Even if there is only one compute unit in the device, mapping its input and output arguments to different global memory banks can improve performance by enabling simultaneous accesses to input and output data.
The following block diagram shows the Global Memory Two Banks example in Vitis Examples on GitHub. This example connects the input pointer interface of the kernel to DDR bank 0, and the output pointer interface to DDR bank 1.
--conectivity.spoption to distribute connections across different memory banks.
Start by assigning the kernel arguments to separate bundles to increase the available interface ports, then assign the arguments to separate memory banks. The following example uses the interfaces described at HW Interfaces.
- In the C/C++ kernel code assign arguments to separate bundles using the
INTERFACE pragma prior to compiling them:
void cnn( int *pixel, // Input pixel int *weights, // Input Weight Matrix int *out, // Output pixel ... // Other input or Output ports #pragma HLS INTERFACE m_axi port=pixel offset=slave bundle=gmem #pragma HLS INTERFACE m_axi port=weights offset=slave bundle=gmem1 #pragma HLS INTERFACE m_axi port=out offset=slave bundle=gmem
Note that the memory interface inputs
weightsare assigned different bundle names in the example above, while
outis bundled with
pixel. This creates two separate interface ports:
gmem1.Important: You must specify
bundle=names using all lowercase characters to be able to assign it to a specific memory bank using the
- Use the
--connectivity.spoption, or include it in a config file, as described in --connectivity Options.For example, for the
cnnkernel shown above, the
connectivity.spoption in the config file would be as follows:
[connectivity] #sp=<compute_unit_name>.<argument>:<bank name> sp=cnn_1.pixel:DDR sp=cnn_1.weights:DDR sp=cnn_1.out:DDR
<compute_unit_name>is an instance name of the CU as determined by the
connectivity.nkoption, described in Creating Multiple Instances of a Kernel, or is simply
<kernel_name>_1if multiple CUs are not specified.
<argument>is the name of the kernel argument. Alternatively, you can specify the name of the kernel interface as defined by the HLS INTERFACE pragma for C/C++ kernels, including
bundlename. In the
cnnkernel above, the ports would be
m_axi_gmem1.Tip: For RTL kernels, the interface is specified by the interface name defined in the kernel.xml file.
<bank_name>is denoted as
DDRfor a platform with four DDR banks. You can also specify the memory as a contiguous range of banks, such as DDR[0:2], in which case XRT will assign the memory bank at run time.
Some platforms also provide support for PLRAM, HBM, HP or MIG memory, in which case you would use PLRAM, HBM, HP or MIG. You can use the
platforminfoutility to get information on the global memory banks available in a specified platform. Refer to platforminfo Utility for more information.
In platforms that include both DDR and HBM memory banks, kernels must use separate AXI interfaces to access the different memories. DDR and PLRAM access can be shared from a single port.Tip: Assigning kernel interfaces to specific memory banks may also require you to specify the SLR to place the kernel into. For more information see Assigning Compute Units to SLRs on Alveo Accelerator Cards.
You can use the Device Hardware Transaction view in Vitis Analyzer to observe the actual DDR Bank communication, and to analyze DDR usage.