Customizing AXI4-Stream Interfaces - 2024.1 English

Vitis High-Level Synthesis User Guide (UG1399)

Document ID
UG1399
Release Date
2024-07-03
Version
2024.1 English

An instance of an AXI4-Stream without side channels (for example hls::stream<ap_axiu<32, 0, 0, 0>>) can result in the following RTL signals on the interface:

  • TVALID
  • TREADY
  • TDATA[ ]
  • TLAST[ ]
  • TKEEP[ ]
  • TSTRB[ ]

Some of these signals (TLAST, TKEEP, and TSTRB) can be unnecessary or unwanted in your design. In addition, there are use cases where TDATA is not required as the modeler uses TUSER to move data. To support these additional use cases the hls::axis<T> definition supports the following options:

template <typename T,
          std::size_t WUser = 0,
          std::size_t WId = 0,
          std::size_t WDest = 0,
          uint8_t EnableSignals = (AXIS_ENABLE_KEEP |
                                   AXIS_ENABLE_LAST |
                                   AXIS_ENABLE_STRB),
          bool StrictEnablement = false>
struct axis {
  // members
  T data;
  ap_uint<bytesof<T>> strb;
  ap_uint<bytesof<T>> keep;
  ap_uint<WUser>      user;
  ap_uint<WId>        id;
  ap_uint<WDest>      dest;
  ap_uint<1>          last;
  
  // get_* methods
  …
  // set_* methods
  …
};

The EnableSignals and StrictEnablement fields let you specify which of the three signals (TKEEP, TLAST, and TSTRB) should appear in your design using the specification of special macros. The complete list of macros is shown below:

// Enablement for axis signals
#define AXIS_ENABLE_DATA 0b00000001
#define AXIS_ENABLE_DEST 0b00000010
#define AXIS_ENABLE_ID   0b00000100
#define AXIS_ENABLE_KEEP 0b00001000
#define AXIS_ENABLE_LAST 0b00010000
#define AXIS_ENABLE_STRB 0b00100000
#define AXIS_ENABLE_USER 0b01000000
  
// Disablement mask for DATA axis signals
#define AXIS_DISABLE_DATA (0b11111111 ^ AXIS_ENABLE_DATA) & \
                          (0b11111111 ^ AXIS_ENABLE_KEEP) & \
                          (0b11111111 ^ AXIS_ENABLE_STRB)
  
// Enablement/disablement of all axis signals
#define AXIS_ENABLE_ALL  0b01111111
#define AXIS_DISABLE_ALL 0b00000000
Tip: These macros also enable some error checking to identify cases where your specification is incomplete.

In addition to letting you enable or disable specific side-channel signals, the set of macros was expanded to allow the specification of all or none of the signals. This allowed for the definition of the special hls::axis_data<> and hls::axis_user<> helper classes that make it easier to pick and choose the exact signal specification. The definitions of these special helper classes are shown below:

// Struct: axis_data (alternative to axis)
//   DATA signal always enabled
//   All other signals are optional, disabled by default
template <typename TData,
          uint8_t EnableSignals = AXIS_ENABLE_DATA,
          std::size_t WUser = 0,
          std::size_t WId = 0,
          std::size_t WDest = 0,
          bool StrictEnablement = true>
using axis_data = axis<TData, WUser, WId, WDest,
                       (EnableSignals | AXIS_ENABLE_DATA),
                       StrictEnablement>;
// Struct: axis_user (alternative to axis)
//   USER signal always enabled
//   DATA signal always disabled
//   All other signals are optional, disabled by default
template <std::size_t WUser,
          uint8_t EnableSignals = AXIS_ENABLE_USER,
          std::size_t WId = 0,
          std::size_t WDest = 0,
          bool StrictEnablement = true>
using axis_user = axis<void, WUser, WId, WDest,
                       (EnableSignals & AXIS_DISABLE_DATA),
                       StrictEnablement>;

The following use cases illustrate the various options letting you customize the signals associated with the AXI4-Stream interface:

// Allow user to control existence of TKEEP, TSTRB and TLAST by template parameter `EnableSideChannels`
 
// Enable only TKEEP
using data_t = hls::axis<int, 0, 0, 0, AXIS_ENABLE_KEEP>; Or using data_t = hls::axis_data<int, AXIS_ENABLE_KEEP>
  
// Enable two channels TKEEP and TLAST
using data_t = hls::axis_data<int, AXIS_ENABLE_KEEP|AXIS_ENABLE_LAST>;
  
// Disable all side-channels
using data_t = hls::axis_data<int, AXIS_DISABLE_ALL>;
  
// Enable all side-channels
using data_t = hls::axis_data<int, AXIS_ENABLE_ALL, 4, 2, 3>;
 
// Error case: All signals enabled but zero size specified for WUser/WId/WDest
using data_t = hls::axis_data<int, AXIS_ENABLE_ALL>;
 
// Allow user to control existence of TDATA by specifying template parameter `T` with `void` type
// and only use TUSER channel
using data_t = hls::axis<void, 5, 0, 0, AXIS_DISABLE_ALL>; Or using data_t = hls::axis_user<5>
 
// Use default enabling of TDATA, TKEEP, TSTRB and TLAST
using data_t = hls::axis<int>;