高级 C++ 流量生成器 API - 2023.2 简体中文

Vitis 统一软件平台文档 应用加速开发 (UG1393)

Document ID
UG1393
Release Date
2023-12-13
Version
2023.2 简体中文

C++ API 可提供阻塞和非阻塞函数支持。下表显示了其用法:

表 1. 外部流量生成器中使用的高级 C++ API 列表
API 行为
xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::BLOCKING> socket_util("<sender_io_name>") 用于为阻塞 API 调用例化主接口
xtlm_ipc::axis_target_socket_util<xtlm_ipc::BLOCKING> socket_util("<receiver_io_name>") 用于为阻塞 API 调用例化从接口
xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::NON_BLOCKING> socket_util("<sender_io_name>") 用于为非阻塞 API 调用例化主接口
xtlm_ipc::axis_target_socket_util<xtlm_ipc::NON_BLOCKING> socket_util("<receiver_io_name>") 用于为非阻塞 API 调用例化从接口
transport(data, size(), tlast)

以字符矢量形式发送数据的 API,指定数据大小

可选实参 TLAST

如 tlast = false,则部驱动 TLAST

如 tlast = true,最后一个数据节拍的 TLAST=true

TLAST 默认值为 true。

transport(data, tlast)

以字符矢量形式发送数据的 API

可选实参 TLAST

如 tlast = false,则部驱动 TLAST

如 tlast = true,最后一个节拍的 TLAST=true

TLAST 默认值为 true。

transport(packet) 用于发送 AXI4‑Stream 包的 API
sample_transaction(data)

以字符矢量形式接收数据的 API

按节拍来接收数据节拍,每次 sample_transaction() 调用提供一拍数据。

sample_transaction(data, tlast)

以字符矢量形式接收数据的 API

按节拍来接收数据节拍,每次 sample_transaction() 调用提供一拍数据。

此 API 会返回 tlast 的值。

sample_transaction(packet)

按节拍来接收数据节拍,每次 sample_transaction() 调用提供一拍数据。

end_of_simulation()

使用此 API 即可结束并退出仿真

首选在含 sw_emu/hw_emu 的外部流量生成器内使用

disconnect()

用于断开套接字的连接(DataIn、DataOut 等)

建议在含 AI 引擎仿真器或 x86 仿真器的外部流量生成器内使用

xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::BLOCKING>

在 C++ 代码中例化发送器用于阻塞发送调用。

API 用法
使用 API 创建用户对象用于阻塞 API 调用:
xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::BLOCKING> sender_obj("<sender_io_name>")
参数
发送数据的外部端口的名称:
sender_io_name
示例
xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::BLOCKING> data_in("DataIn");
此处,data_in 是发送器对象,DataIn 是外部端口名称。 

xtlm_ipc::axis_target_socket_util<xtlm_ipc::BLOCKING>

在 C++ 代码中例化接收器用于阻塞发送调用。

API 用法
为接收器创建用户对象用于阻塞接收调用:
xtlm_ipc::axis_target_socket_util<xtlm_ipc::BLOCKING> receiver_obj("<receiver_io_name>")
参数
接收数据的外部端口的名称:
receiver_io_name
示例
xtlm_ipc::axis_target_socket_util<xtlm_ipc::BLOCKING> data_out("DataOut");
此处,data_out 是用户对象,DataOut 是外部端口名称。

xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::NON_BLOCKING>

在 C++ 代码中例化发送器用于非阻塞 API 调用。

API 用法
为发送器创建用户对象:
xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::NON_BLOCKING> sender_obj("<sender_io_name>")
参数
接收数据的外部端口的名称:
sender_io_name
示例
xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::NON_BLOCKING> data_in("DataIn");
此处,data_in 是用户对象,DataIn 是外部端口名称。

xtlm_ipc::axis_target_socket_util<xtlm_ipc::NON_BLOCKING>

在 C++ 代码中例化接收器用于非阻塞 API 调用。

API 用法
使用 API 创建用户对象:
xtlm_ipc::axis_target_socket_util<xtlm_ipc::NON_BLOCKING> receiver_obj("<receiver_io_name>")
参数
接收数据的外部端口的名称:
receiver_io_name
示例
xtlm_ipc::axis_target_socket_util<xtlm_ipc::NON_BLOCKING> data_out("DataOut");
此处,data_out 是用户对象,DataOut 是外部端口名称。

transport(std::vector<char> data, int size(), bool tlast=true)

如果您倾向于不使用细粒度控制(建议),则发送数据。

API 用法
使用发送器对象调用 API:
data_in.transport(data, size(), tlast)
参数
以字符矢量形式生成的数据:
data
数据大小:
size()
TLAST 为 True/False(由用户根据应用进行选择)。如不指定该值,则默认值为 true(即,每个数据节拍均为一项传输事务)。如果 tlast = false,则不驱动任何 TLAST。如果 tlast = true(由用户根据应用来指定),那么最后一个数据节拍的 TLAST=true。
tlast
示例
const unsigned int NUM_TRANSACTIONS = 8;
bool tlast;
std::vector<char> data; // Prepare data in the form of vector of char
for(int i = 0; i < NUM_TRANSACTIONS; i++) {

data = generate_data(); // user custom code to generate the data

// print(data); // user code to print the data
if (i==NUM_TRANSACTIONS-1){
  tlast = true;
}
else{
  tlast = false;
}
data_in.transport(data.data(), data.size(), tlast); 
}

transport(std::vector<char> data, bool tlast=true)

如果您倾向于不使用细粒度控制(建议),则发送数据。

API 用法
使用发送器对象调用 API:
data_in.transport(data, tlast)
参数
以字符矢量形式生成的数据:
data
TLAST 为 True/False(由用户根据应用进行选择)。如不指定该值,则默认值为 true(即,每个数据节拍均为一项传输事务)。如果 tlast = false,则不驱动任何 TLAST。如果 tlast = true(由用户根据应用来指定),那么最后一个数据节拍的 TLAST=true
tlast

transport(xtlm_ipc::axis_payload packet)

如果需要细粒度控制,则发送串流包。

API 用法
使用发送器对象调用 API:
sender_obj.transport(packet)
参数
AXI 串流包:
packet
此 AXI 串流包含下列需要设置的属性。
需发送的数据:
data
用于标记包结束的 TLAST 值。该值由用户根据应用进行选择和设置。
tlast
部分其他可选 AXI 串流包属性包括:
tuser
tkeep
示例
const unsigned int NUM_TRANSACTIONS = 8; 

xtlm_ipc::axis_payload& packet; 

for(int i = 0; i < NUM_TRANSACTIONS; i++) {
//generate_data() is your custom code to generate traffic

std::vector<char> data = generate_data(); 

//! Set packet attributes...
packet.data = data;
packet.tlast = 1; //Additional AXIS attributes can be set if required
//Blocking transport API to send the transaction
data_in.transport(packet); 
}

sample_transaction(std::vector<char>& data)

如果您倾向于不使用细粒度控制(建议),则接收数据。

API 用法
使用接收器对象调用 API。
参数
用于接收数据的空字符矢量:
data
示例
const unsigned int NUM_TRANSACTIONS = 100;
unsigned int num_received = 0;
std::vector<char> data; // Empty vector for receiving transactions

while(num_received < NUM_TRANSACTIONS) {
  data_out.sample_transaction(data); // sample_transaction fills the data vector
  // print(data); user code to print the data
  num_received += 1; // user logic to process data further
}
接收接口上可用的数据,直至 TLAST 为止。例如,如果主接口每 16 拍生成 TLAST,那么将在 vector<> 中填充 16 拍。如果主接口不驱动 TLAST,则将每个节拍本身视为一件传输事务(即,每次调用 API 为一拍)。

sample_transaction(std::vector<char>& data, bool& tlast)

如果您倾向于不使用细粒度控制(建议),则接收数据。

此处,bool tlast 会作为实参进行传递,以便检查当前数据是否是传输事务的最后一拍。

您可将此 tlast 用于进一步处理。

API 用法
使用接收器对象调用 API
参数
用于接收数据的空字符矢量:
data
这是接收的 tlast 值,由 API 返回:
tlast
示例
const unsigned int NUM_TRANSACTIONS = 100;
unsigned int num_received = 0;
std::vector<char> data; // Empty vector of char
bool recv_tlast;

while(num_received < NUM_TRANSACTIONS) {
  data_out.sample_transaction(data, recv_tlast); // data vector will be filled

  // If the current sample has tlast as true, recv_tlast will be set to true
  if (recv_tlast) {
    // do relevent logic if tlast is true
  }
  num_received += 1; // user logic to process data further
}
接收接口上可用的数据,直至 TLAST 为止。例如,如果主接口每 16 拍生成 TLAST,那么将在 vector<> 中填充 16 拍。如果主接口不驱动 TLAST,则将每个节拍本身视为一件传输事务(即,每次调用 API 为一拍)。

sample_transaction(xtlm_ipc::axis_payload& packet)

接收 AXI 串流包。

API 用法
使用接收器对象调用 API:
receiver_obj.sample_transaction(packet)
参数
要在其中填充样本的空串流包:
packet
示例
unsigned int num_received = 0; 
xtlm_ipc::axis_payload packet;

data_out.sample_transaction(packet); //API to sample the transaction which fills the empty packet of type xtlm_ipc::axis_payload

//Process the packet as per requirement.
num_received += 1;

end_of_simulation();

结束并退出仿真。

API 用法
使用发送器对象调用 API:
sender_obj.end_of_simulation()
示例
//! Instantiate IPC socket with name matching in IPI diagram...
  xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::BLOCKING> data_in("DataIn");

  const unsigned int NUM_TRANSACTIONS = 100;
  xtlm_ipc::axis_payload packet;

  std::cout << "Sending " << NUM_TRANSACTIONS << " Packets..." << std::endl;
  for (int i = 0; i < NUM_TRANSACTIONS; i++) {
    packet = generate_packet();
    print(packet);
    socket_util.transport(packet);
  }
  file.close();
  usleep(10000);
  data_in.end_of_simulation();
建议搭配 sw_emu/hw_emu 使用。

barrier_wait()

对于非阻塞调用,API 会等待所有传输事务完成。

API 用法
使用发送器对象调用 API。
示例
const unsigned int NUM_TRANSACTIONS = 8;
std::vector<char> data;
std::cout << "Sending " << NUM_TRANSACTIONS << " data transactions..."
<<std::endl;

for(int i = 0; i < NUM_TRANSACTIONS/2; i++) {
  data = generate_data();
  print(data);
  data_in.transport(data.data(), data.size());
}

 // "Adding Barrier to complete all outstanding transactions..." <<
std::endl;
data_in.barrier_wait();

for(int i = NUM_TRANSACTIONS/2; i < NUM_TRANSACTIONS; i++) {
  data = generate_data(); // user code to generate the data
  print(data); // user code to print the data
  data_in.transport(data.data(), data.size());
}

get_num_transactions()

对于非阻塞调用,API 用于检查是否有任何传输事务可供接收。

此方法适用于非阻塞版本,因为如无传输事务可用,那么 sample_transaction 就不会填充矢量/有效载荷。建议在使用 NON_BLOCKING 接收器调用 sample_transaction 前执行检查。

API 用法
使用发送器对象调用 API。
示例
xtlm_ipc::axis_target_socket_util<xtlm_ipc::NON_BLOCKING> receiverObj("Receiver");
xtlm_ipc::axis_payload receiverPayload;
// std::vector<char> receiveData;
if ( receiverObj.get_num_transactions() != 0 ) { // Checks if transaction is available
receiverObj.sample_transaction(receiverPayload); // Fills the receiverPayload

// One can use with vector<char> as parameter also
// such as receiverObj.sample_transaction(receiveData);
}