Offset and Modes of Operation - 2023.2 English

Vitis High-Level Synthesis User Guide (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 English
Important: In the Vitis kernel flow the default mode of operation is offset=slave and should not be changed. In the Vivado IP flow the default is also offset=slave, but can be changed.

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.

Tip: The 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, the m_axi interface start address can be either hard-coded or set at runtime.
    • offset=off: Sets the base address of the m_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 setting offset=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 the a port as shown in the figure below. This lets you update the address at runtime, so you can have one m_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 the s_axilite interface. This is the default for both the Vitis kernel flow, and the Vivado IP flow. Here is the flow of operation:
    1. initially, the Host/CPU will start the IP or kernel using the block-level control protocol which is mapped to the s_axilite adapter.
    2. The host will send address offsets for the m_axi interfaces through the s_axilite adapter.
    3. The m_axi adapter will read the start address from the s_axilite adapter and store it in a queue.
    4. The HLS design starts to read the data from the global memory.

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.

Figure 2. AXI Adapters in Slave Mode

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 global syn.interface.m_axi_offset setting is specified, and the design has an s_axilite interface, the global setting is ignored and offset=slave is assumed.
    void top(int *a) {
    #pragma HLS interface mode=m_axi port=a
    #pragma HLS interface mode=s_axilite port=a
    }