AXI4 memory-mapped (m_axi
) interfaces allow kernels to read and write data in global
memory (DDR, HBM, PLRAM). Memory-mapped interfaces are a convenient way of
sharing data across different elements of the accelerated application, such as between the
host and kernel, or between kernels on the accelerator card. Refer to Vitis-HLS-Introductory-Examples/Interface/Memory on
GitHub for examples of some of these concepts.
The main advantages for m_axi
interfaces
are listed below:
- The interface has a separate and independent read and write channels
- It supports burst-based accesses with potential performance of ~17 GBps
- It provides support for outstanding transactions
- It can include cache to improve performance as indicated by the CACHE pragma or directive.
In the Vitis Kernel flow the m_axi
interface is assigned by default to pointer and array
arguments. In this flow it supports the following default features:
- Pointer and array arguments are automatically mapped to the
m_axi
interface - The default mode of operation is
offset=slave
in the Vitis flow and should not be changed - All pointer and array arguments are mapped to a single interface bundle to conserve device resources, and ports share read and write access across the time it is active
- The default alignment in the Vitis flow is set to 64 bytes
- The maximum read/write burst length is set to 16 by default
While not used by default in the Vivado
IP flow, when the m_axi
interface is specified it has the
following default features:
- The default operation mode is offset=off but you can change it as described in Offset and Modes of Operation
- Assigned pointer and array arguments are mapped to a single interface bundle to conserve device resources, and share the interface across the time it is active
- The default alignment in Vivado IP flow is set to 1 byte
- The maximum read/write burst length is set to 16 by default
In both the Vivado IP flow and Vitis kernel flow, global default values for the m_axi
interface are defined by the syn.interface.xxx
commands as described in Interface Configuration. The INTERFACE pragma or
directive can be used to modify default values as needed for specific interfaces. Some
customization can help improve design performance as described in Optimizing AXI System Performance. You can also specify the CACHE pragma or directive as described
in pragma HLS cache to improve performance of the m_axi
interface.
You can use an AXI4 master interface on array or pointer/reference arguments, which Vitis HLS implements in one of the following modes:
- Individual data transfers
- Burst mode data transfers
With individual data transfers, Vitis HLS reads or writes a single element of data for each address. The following example shows a single read and single write operation. In this example, Vitis HLS generates an address on the AXI interface to read a single data value and an address to write a single data value. The interface transfers one data value per address.
void bus (int *d) {
static int acc = 0;
acc += *d;
*d = acc;
}
With burst mode transfers, Vitis HLS reads
or writes data using a single base address followed by multiple sequential data samples, which
makes this mode capable of higher data throughput. Burst mode of operation is possible when
using a pipelined for
loop. Refer to AXI Burst Transfers for more information.
memcpy
is discouraged because it can not be inlined or pipelined. Its use can also
be problematic because it changes the type of the argument into char
, which can lead to errors if array_partition
, array_reshape
, or struct
disaggregate
is used. Instead you are recommended to write
your own version of memcpy
with explicit arrays and loops to
provide better control.When the prior example is synthesized, it results in the interfaces shown in the following figure.
When using a for
loop to implement burst
reads or writes, follow these requirements:
- Pipeline the loop
- Access addresses in increasing order
- Do not place accesses inside a conditional statement
- For nested loops, do not manually flatten loops (using LOOP_FLATTEN pragma or directive), because this inhibits the burst operation
for
loop unless the ports are bundled in different AXI
ports.