- 对于 C++,API 可从以下位置获取:
$XILINX_VIVADO/data/emulation/ip_utils/xtlm_ipc/xtlm_ipc_v1_0/cpp/inc/axis
C++ API 可提供阻塞和非阻塞函数支持。以下片段显示了其用法。
提示: 此外还提供了一个 Makefile 样本用于生成可执行文件。 - 阻塞发送: 如果您倾向于不使用细粒度控制(建议),则可使用一个简单的 API:
#include "xtlm_ipc.h" //Include file void send_data() { //! Instantiate IPC socket with name matching in IPI diagram... xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::BLOCKING> socket_util("gt_master"); 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; i++) { data = generate_data(); print(data); socket_util.transport(data.data(), data.size()); } }
对于需要对 AXI4-Stream 进行细粒度控制的高级用户,可使用:
#include "xtlm_ipc.h" //Include file void send_packets() { //! Instantiate IPC socket with name matching in IPI diagram... xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::BLOCKING> socket_util("gt_master"); const unsigned int NUM_TRANSACTIONS = 8; xtlm_ipc::axi_stream_packet packet; std::cout << "Sending " << NUM_TRANSACTIONS << " Packets..." <<std::endl; for(int i = 0; i < NUM_TRANSACTIONS; i++) { xtlm_ipc::axi_stream_packet packet; // generate_data() is your custom code to generate traffic std::vector<char> data = generate_data(); //! Set packet attributes... packet.set_data(data.data(), data.size()); packet.set_data_length(data.size()); packet.set_tlast(1); //Additional AXIS attributes can be set if required socket_util.transport(packet); //Blocking transport API to send the transaction } }
- 阻塞接收: 如果您倾向于不使用细粒度控制(建议),则可使用一个简单的 API:
#include "xtlm_ipc.h" //Include file void receive_data() { //! Instantiate IPC socket with name matching in IPI diagram... xtlm_ipc::axis_target_socket_util<xtlm_ipc::BLOCKING> socket_util("gt_slave"); const unsigned int NUM_TRANSACTIONS = 100; unsigned int num_received = 0; std::vector<char> data; std::cout << "Receiving " << NUM_TRANSACTIONS << " data transactions..." <<std::endl; while(num_received < NUM_TRANSACTIONS) { socket_util.sample_transaction(data); print(data); num_received += 1; } }
对于需要对 AXI4-Stream 进行细粒度控制的高级用户,可使用:
#include "xtlm_ipc.h" void receive_packets() { //! Instantiate IPC socket with name matching in IPI diagram... xtlm_ipc::axis_target_socket_util<xtlm_ipc::BLOCKING> socket_util("gt_slave"); const unsigned int NUM_TRANSACTIONS = 8; unsigned int num_received = 0; xtlm_ipc::axi_stream_packet packet; std::cout << "Receiving " << NUM_TRANSACTIONS << " packets..." <<std::endl; while(num_received < NUM_TRANSACTIONS) { socket_util.sample_transaction(packet); //API to sample the transaction //Process the packet as per requirement. num_received += 1; } }
- 非阻塞发送:
#include <algorithm> // std::generate #include "xtlm_ipc.h" //A sample implementation of generating random data. xtlm_ipc::axi_stream_packet generate_packet() { xtlm_ipc::axi_stream_packet packet; // generate_data() is your custom code to generate traffic std::vector<char> data = generate_data(); //! Set packet attributes... packet.set_data(data.data(), data.size()); packet.set_data_length(data.size()); packet.set_tlast(1); //packet.set_tlast(std::rand()%2); //! Option to set tuser tkeep optional attributes... return packet; } //Simple Usage void send_data() { //! Instantiate IPC socket with name matching in IPI diagram... xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::NON_BLOCKING> socket_util("gt_master"); 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); socket_util.transport(data.data(), data.size()); } std::cout<< "Adding Barrier to complete all outstanding transactions..." << std::endl; socket_util.barrier_wait(); for(int i = NUM_TRANSACTIONS/2; i < NUM_TRANSACTIONS; i++) { data = generate_data(); print(data); socket_util.transport(data.data(), data.size()); } } void send_packets() { //! Instantiate IPC socket with name matching in IPI diagram... xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::NON_BLOCKING> socket_util("gt_master"); // Instantiate Non Blocking specialization const unsigned int NUM_TRANSACTIONS = 8; xtlm_ipc::axi_stream_packet packet; std::cout << "Sending " << NUM_TRANSACTIONS << " Packets..." <<std::endl; for(int i = 0; i < NUM_TRANSACTIONS; i++) { packet = generate_packet(); // Or user's test patter / live data etc. socket_util.transport(packet); } }
- 非阻塞接收:
#include <unistd.h> #include "xtlm_ipc.h" //Simple Usage void receive_data() { //! Instantiate IPC socket with name matching in IPI diagram... xtlm_ipc::axis_target_socket_util<xtlm_ipc::NON_BLOCKING> socket_util("gt_slave"); const unsigned int NUM_TRANSACTIONS = 8; unsigned int num_received = 0, num_outstanding = 0; std::vector<char> data; std::cout << "Receiving " << NUM_TRANSACTIONS << " data transactions..." <<std::endl; while(num_received < NUM_TRANSACTIONS) { num_outstanding = socket_util.get_num_transactions(); num_received += num_outstanding; if(num_outstanding != 0) { std::cout << "Outstanding data transactions = "<< num_outstanding <<std::endl; for(int i = 0; i < num_outstanding; i++) { socket_util.sample_transaction(data); print(data); } } usleep(100000); } } void receive_packets() { //! Instantiate IPC socket with name matching in IPI diagram... xtlm_ipc::axis_target_socket_util<xtlm_ipc::NON_BLOCKING> socket_util("gt_slave"); const unsigned int NUM_TRANSACTIONS = 8; unsigned int num_received = 0, num_outstanding = 0; xtlm_ipc::axi_stream_packet packet; std::cout << "Receiving " << NUM_TRANSACTIONS << " packets..." <<std::endl; while(num_received < NUM_TRANSACTIONS) { num_outstanding = socket_util.get_num_transactions(); num_received += num_outstanding; if(num_outstanding != 0) { std::cout << "Outstanding packets = "<< num_outstanding <<std::endl; for(int i = 0; i < num_outstanding; i++) { socket_util.sample_transaction(packet); print(packet); } } usleep(100000); //As transaction is non-blocking we would like to give some delay between consecutive samplings } }
- 以下是用于上述阻塞接收的 Makefile 示例:
GCC=/usr/bin/g++ IPC_XTLM=$(XILINX_VIVADO)/data/emulation/ip_utils/xtlm_ipc/xtlm_ipc_v1_0/cpp/ PROTO_PATH=$(XILINX_VIVADO)/data/simmodels/xsim/2022.1/lnx64/6.2.0/ext/protobuf/ SRC_FILE=b_receive.cpp .PHONY: run all default: all all : b_receive b_receive: $(SRC_FILE) $(GCC) $(SRC_FILE) $(IPC_XTLM)/src/common/*.cpp -I$(IPC_XTLM)/inc/ -I$(PROTO_PATH)/include/ -L$(PROTO_PATH) -lprotobuf -L$IPC_XTLM/lib/ -lxtlm_ipc -o $@ -lpthread -I$(BOOST)/
- 对于 C API,可从以下位置获取此文件:
可基于以下位置的预编译库来链接此文件:$XILINX_VIVADO/data/emulation/ip_utils/xtlm_ipc/xtlm_ipc_v1_0/C/inc/axis/c_axis_socket.h
$XILINX_VIVADO/data/emulation/ip_utils/xtlm_ipc/xtlm_ipc_v1_0/C/lib/
在以下位置可找到完整的系统级示例:https://github.com/Xilinx/Vitis_Accel_Examples/tree/master/emulation。