void cnn( int *pixel, // Input pixel int *weights, // Input Weight Matrix int *out, // Output pixel ... // Other input or Output ports
In the example above, the kernel function has three pointer parameters:
out. By default the Vitis compiler will map these three parameters to the same AXI4 interface (
The default interface mapping inferred by the compiler is equivalent to the following INTERFACE pragmas:
#pragma HLS INTERFACE m_axi port=pixel offset=slave bundle=gmem #pragma HLS INTERFACE m_axi port=weights offset=slave bundle=gmem #pragma HLS INTERFACE m_axi port=out offset=slave bundle=gmem
bundle keyword on the INTERFACE pragma
defines the name of the port. The system compiler will create a port for each unique bundle
name, resulting in a compiled kernel object (XO) file that has a single AXI interface,
m_axi_gmem. When the same
name is used for different interfaces, this results in these interfaces being mapped to same
gmemname is short for global memory; however, it is not a keyword and is just used for consistency. You can assign your own names for the bundles.
Sharing ports helps save FPGA resources by eliminating AXI interfaces, but it
can limit the performance of the kernel because all the memory transfers have to go through a
single port. The
m_axi port has independent READ and WRITE
channels, so with a single
m_axi port, you can do reads and
writes simultaneously. However, the bandwidth and throughput of the kernel can be increased by
creating multiple ports, using different bundle names, to connect to multiple memory banks.
There are many options for configuring the INTERFACE, as described in
reasons to manually define an INTERFACE pragma in your code could include:
- Specifying the bundle for the INTERFACE pragma to separate AXI signals into separate bundles.
- Specifying the interface width to deviate from default int = 64 bytes (512-bits).
- Specifying AXI properties for burst transactions.
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
In the example above, two
create two distinct ports:
gmem1. The kernel will
gmem port, while
weights data will be accessed through the
port. As a result, the kernel will be able to make parallel accesses to
improving the throughput of the kernel.
bundle=names using all lowercase characters, so you can assign it to a specific memory bank using the connectivity.sp option.
The INTERFACE pragma is used during
compilation, resulting in a compiled kernel object (XO) file with two separate AXI interfaces,
m_axi_gmem1, that can be connected to global memory as needed. During system
compiler linking, the separate interfaces can be mapped to different global memory banks using
the connectivity.sp option in a configuration file, as
described in Mapping Kernel Ports to Memory.