The AXI4 Master interface has a
read/write address channel that can be used to read/write specific addresses. By default the
m_axi
interface starts all read and write operations
from the address 0x00000000
. For example, given the
following code, the design reads data from addresses 0x00000000
to 0x000000C7
(50 32-bit words,
gives 200 bytes), which represents 50 address values. The design then writes data back to
the same addresses.
#include <stdio.h>
#include <string.h>
void example(int *a){
#pragma HLS INTERFACE mode=m_axi port=a depth=50
int i;
int buff[50];
//The use of memcpy is discouraged because multiple calls of memcpy cannot be
//pipelined and will be scheduled sequentially. Use a dedicated for loop instead
//memcpy(buff,(const int*)a,50*sizeof(int));
//Burst read input
for(i=0; i<50; i++){
buff[i] = a[i];
}
// Compute value
for(i=0; i < 50; i++){
buff[i] = buff[i] + 100;
}
//Burst write output
for(i=0; i<50; i++){
a[i] = buff[i];
}
}
The HLS compiler provides the capability to let the base address be configured statically in the Vivado IP for instance, or dynamically by the software application or another IP during runtime.
The m_axi
interface can be both a master
initiating transactions, and also a slave interface that receives the data and sends
acknowledgment. Depending on the mode specified with the offset
option of the INTERFACE pragma, an HLS IP can use multiple approaches to
set the base address.
syn.interface.m_axi_offset
configuration command provides a
global setting for the offset, that can be overridden for specific
m_axi
interfaces using the INTERFACE pragma offset
option.-
Master Mode: When acting as a
master interface with different
offset
options, them_axi
interface start address can be either hard-coded or set at runtime.-
offset=off
: Sets the base address of them_axi
interface to 0x00000000 and it cannot be changed in the Vivado IP integrator. One disadvantage with this approach is that you cannot change the base address during runtime. See Customizing AXI4 Master Interfaces in IP Integrator for setting the base address.The following shows the INTERFACE pragma settingoffset=off
for the function.void example(int *a){ #pragma HLS INTERFACE m_axi depth=50 port=a offset=off ... }
-
offset=direct
: Vitis HLS generates a port on the IP for setting the address. Note the addition of thea
port as shown in the figure below. This lets you update the address at runtime, so you can have onem_axi
interface reading and writing different locations. For example, an HLS module that reads data from an ADC into RAM, and an HLS module that processes that data. Because you can change the address on the module, while one HLS module is processing the initial dataset the other module can be reading more data into different address.void example(int *a){ #pragma HLS INTERFACE m_axi depth=50 port=a offset=direct ... }
Figure 1. offset=direct -
-
Slave Mode: The slave mode for an
interface is set with
offset=slave
. In this mode the IP will be controlled by the host application, or the micro-controller through thes_axilite
interface. This is the default for both the Vitis kernel flow, and the Vivado IP flow. Here is the flow of operation:- initially, the Host/CPU will start the IP or kernel using the
block-level control protocol which is mapped to the
s_axilite
adapter. - The host will send address offsets for the
m_axi
interfaces through thes_axilite
adapter. - The
m_axi
adapter will read the start address from thes_axilite
adapter and store it in a queue. - The HLS design starts to read the data from the global memory.
- initially, the Host/CPU will start the IP or kernel using the
block-level control protocol which is mapped to the
As shown in the following figure, the HLS design will have both the
s_axilite
adapter for the base address, and the m_axi
to perform read and write transfer to the global
memory.
Offset Rules
The following are rules associated with the offset
option:
- Fully Specified Offset: When the user explicitly sets the offset value
the tool uses the specified settings. The user can also set different offset values for
different
m_axi
interfaces in the design, and the tool will use the specified offsets.#pragma HLS INTERFACE s_axilite port=return #pragma HLS INTERFACE mode=m_axi bundle=BUS_A port=out offset=direct #pragma HLS INTERFACE mode=m_axi bundle=BUS_B port=in1 offset=slave #pragma HLS INTERFACE mode=m_axi bundle=BUS_C port=in2 offset=off
- No Offset Specified: If there are no offsets specified in the INTERFACE
pragma, the tool will defer to the setting specified by
syn.interface.m_axi_offset
.Note: If the globalsyn.interface.m_axi_offset
setting is specified, and the design has ans_axilite
interface, the global setting is ignored andoffset=slave
is assumed.void top(int *a) { #pragma HLS interface mode=m_axi port=a #pragma HLS interface mode=s_axilite port=a }