Advanced Python Traffic Generator API - 2023.2 English

Vitis Unified Software Platform Documentation: Application Acceleration Development (UG1393)

Document ID
UG1393
Release Date
2023-12-13
Version
2023.2 English

The following is the list of the advanced Python traffic generator API along with their usage.

Tip: A full system-level example using these API is available for external IO in Python in the External_IO_PY tutorial on GitHub.
Table 1. List of Advanced Python API used in external traffic generator
API Behavior
ipc_axis_master_util("<sender_io_name>") To instantiate the master traffic generator (TG)
ipc_axis_slave_util("<receiver_io_name>") To instantiate the slave TG
b_transport(packet) Blocking API to send the AXI4-Stream packets
sample_transaction() Blocking API to receive the AXI4-Stream packets. Data is received beat by beat (one sample_transaction() call gives one beat).
ipc_axis_master_nb_util("<sender_io_name>") To instantiate a non-blocking master TG
ipc_axis_slave_nb_util("<receiver_io_name>") To instantiate a non-blocking slave TG
nb_transport(packet) Non-blocking API call to send the AXI4-Stream packets
nb_sample_transaction() Non-blocking API call to receive the AXI4-Stream packets. Data is received beat by beat (one sample_transaction() call gives one beat).
no_of_available_txns() Used to get the number of transactions received for non-blocking TG
end_of_simulation()

End and exit the simulation using this API

Preferable use in external TG with sw_emu/hw_emu

disconnect()

To disconnect the socket connections (DataIn, DataOut etc)

Preferable for use in external TG with x86simulator or aiesimulator

ipc_axis_master_util (<sender_io_name>) 

Used to instantiate the sender port in the Python script.

API usage
Creates a user object using the API for sender:
sender_obj = ipc_axis_master_util (<sender_io_name>) 
Parameters
Name of the external port that sends data:
<sender_io_name>
Example
#Instantiating AXI Master Utilities 
data_in = ipc_axis_master_util("DataIn")
DataIn is the external port name and data_in is the user object.

ipc_axis_slave_util(<receiver_io_name>)

Used to instantiate the receiver port in the Python script.

API usage
Creates a user object using the API for the receiver:
receiver_obj = ipc_axis_slave_util (<receiver_io_name>)
Parameters
Name of the external port that receives the data:
receiver_io_name
Example
#Instantiating AXI Slave Utilities 
data_out = ipc_axis_slave_util("DataOut")
In the example, DataOut is the external port and data_out is the user object.

b_transport(packet)

The blocking API to send the AXI4-Stream.
API usage
Calls the API using the object created
sender_obj.b_transport(<packet>) 
Parameters
AXI4-Stream packet:
packet
This AXI4-Stream has the following attributes that need to be set.
The data that needs to be sent:
data
The TLAST value to mark the end of the packet. This is the user's choice based on the application.
tlast
If not specified, the default TLAST value is true so that every data beat is a transaction. If tlast=false no TLAST is driven. If tlast=true (specified by the user based on the application), the last data beat has tlast=true.
Some other optional AXI4-Stream packet fields are: tuser and tkeep
Example
#Create packet
data_packet = xtlm_ipc.axi_stream_packet() // API to generate the stream packet
data = generate_data() # custom user code to generate the data
data_packet.data = data 

data_packet.tlast = True #AXI Stream Fields
#Optional AXI Stream Parameters
data_packet.tuser = optional data
data_packet.tkeep = optional data 

#Send Transaction
data_in.b_transport(data_packet)

sample_transaction()

Blocking API to receive the AXI4-Stream packets.
API Usage
Calls the API using the receiver_obj created:
packet = receiver_obj.sample_transaction()
Example
#Sample the packets
data_packet = data_out.sample_transaction() # Will wait until data is received.
Here, data_out is the receiver object and data_packet is the received packet.

ipc_axis_master_nb_util (<sender_io_name>) 

Instantiates the sender port for non-blocking in the python script.
API Usage
Creates a user object using the API for sender:
sender_obj = ipc_axis_master_nb_util (<sender_io_name>) 
Parameters
Name of the external port that sends the data:
<sender_io_name>
Example
#Instantiating AXI Master Utilities 
data_in = ipc_axis_master_nb_util("DataIn")

ipc_axis_slave_nb_util(<receiver_io_name>)

Used to instantiate the receiver port for non-blocking in the Python script

API Usage
Creates a user object using the API for receiver
receiver_obj = ipc_axis_slave_util (<receiver_io_name>)
Parameters
Name of the external port that sends the data
receiver_io_name
Example
#Instantiating AXI Slave Utilities
data_out = ipc_axis_slave_nb_util("DataOut")

nb_transport(<packet>)

Non-blocking API used to send AXI4-Stream packets. Prior to transporting data you need to format it into data packets as described in Formatting Data with Traffic Generators in Python below.

API Usage
Calls the API using sender_obj:
sender_obj.nb_transport(<packet>) 
Parameters
AXI4-Stream packet:
packet
This AXI4-Stream packet is created by the user which has the following attributes:
The data that needs to be sent:
data
The TLAST value to mark the end of the packet. This is the user's choice based on the application.
tlast
If not specified, the default TLAST value is true so that every data beat is a transaction. If tlast=false no TLAST is driven. If tlast=true (specified by the user based on the application), the last data beat has tlast=true.
Some other optional AXI4-Stream packet fields are tuser and tkeep.
Example
#Create packet
data_packet = xtlm_ipc.axi_stream_packet()
data = generate_data() # custom user code to generate the desired data
data_packet.data_length = "DATA_LENGTH"
data_packet.data = data
data_packet.tlast = True #to mark end of packet. This is user's choice based on application
data_in.nb_transport(data_packet)

nb_sample_transaction()

A non-blocking API to receive the AXI stream packets.

API Usage
packet = receiver_obj.nb_sample_transaction() 
Example
#Sample the packets
# Will return data if it is available
# Will return empty list if nothing is available
# Will not wait or stop the execution until data is present to sample
data_packet = data_out.nb_sample_transaction()

Here, data_out is the receiver object and data_packet is the received packet.

no_of_available_txns

For non-blocking, this API is used to get to get number of transactions received.

API Usage
Calls the API using the user object for the receiver.
Example
data_out = ipc_axis_slave_nb_util("ReceiverName")
data = []

# Checks if any data is present to receive
if(slave.no_of_available_txns != 0) :
data = data_out.nb_sample_transaction() # fill data with respective received data

end_of_simulation()

Ends and exits the simulation.

API Usage
Call the API using the sender object
sender_obj.end_of_simulation()
Example
data_in.end_of_simulation()

Preferably used with with sw_emu/hw_emu.

disconnect()

To disconnect the socket connections (DataIn, DataOut etc)

API Usage
Calls the API using sender or receiver object:
sender_obj.disconect()
receiver_obj.disconnect()
Example
data_in.disconnect() 
data_out.disconnect()

Preferably used with x86simulator or aiesimulator.

Formatting Data with Traffic Generators in Python

Data formatting is not necessary when using the AI Engine API as described in Python API for AI Engine Graphs. However, to send or receive data using the advanced API, which expects data to be in the form of packets, you need to format the data prior to transport.

To emulate AXI4-Stream transactions AXI Traffic Generators require the payload data to be broken into appropriately sized bursts. For example, to send 128 bytes with a PLIO width of 32 bits (4 bytes) requires 128 bytes/4 bytes = 32 AXI4-Stream transactions. Converting between bytes arrays and AXI transactions can be handled in Python.

The Python struct library provides a mechanism to convert between Python and C data types. Specifically, the struct.pack and struct.unpack functions pack and unpack byte arrays according to a format string argument. The following table shows format strings for common C data types and PLIO widths.

For more information see: https://docs.python.org/3/library/struct.html

Table 2. Format Strings for C Data Types and PLIO Widths
Data Type PLIO Width Python Code Snippet
cfloat PLIO32 N/A
PLIO64 rVec = np.real(data)

iVec = np.imag(data)

out2column = np.zeros((L,2)).astype(np.single)

out2column.tobytes()

formatString = "<"+str(len(byte_arry)//4)+"f"

PLIO128
cint16 PLIO32 rVec = np.real(data).astype(np.int16)

iVec = np.imag(data).astype(np.int16)

formatString = "<"+str(len(byte_arry)//2)+"h"

PLIO64
PLIO128
int8 PLIO32 intvec = np.real(data).astype(np.int8)

formatString = "<"+str(len(byte_arry)//1)+"b"

PLIO64
PLIO128
int32 PLIO32 intvec = np.real(data).astype(np.int32)

formatString = "<"+str(len(byte_arry)//4)+"i"

PLIO64
PLIO128