- C++ の場合、API は次に含まれます。
C++ API は、ブロッキング関数とノンブロッキング関数の両方をサポートします。次のコード部分は、その使用方法を示しています。$XILINX_VIVADO/data/emulation/ip_utils/xtlm_ipc/xtlm_ipc_v1_0/cpp/inc/axis
ヒント: 実行ファイルを生成するサンプル 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/2021.1/lnx64/6.2.0/ext/protobuf/ BOOST=$(XILINX_VIVADO)/tps/boost_1_64_0/ SRC_FILE=b_receive.cpp .PHONY: run all default: all all : b_receive b_receive: $(SRC_FILE) $(GCC) $(SRC_FILE) $(IPC_XTLM)/src/common/xtlm_ipc.pb.cc $(IPC_XTLM)/src/axis/*.cpp $(IPC_XTLM)/src/common/*.cpp -I$(IPC_XTLM)/inc/ -I$(PROTO_PATH)/include/ -L$(PROTO_PATH) -lprotobuf -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を参照してください。