The C++ API provides both blocking and non-blocking function support. The following table shows the usage:
API | Behavior |
---|---|
xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::BLOCKING>
socket_util("<sender_io_name>")
|
To instantiate the master for blocking API calls |
xtlm_ipc::axis_target_socket_util<xtlm_ipc::BLOCKING>
socket_util("<receiver_io_name>")
|
To instantiate the slave for blocking API calls |
xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::NON_BLOCKING>
socket_util("<sender_io_name>")
|
To instantiate the master for non-blocking API calls |
xtlm_ipc::axis_target_socket_util<xtlm_ipc::NON_BLOCKING>
socket_util("<receiver_io_name>")
|
To instantiate the slave for non-blocking API calls |
transport(data, size(),
tlast)
|
API to send data in the form of vector of char, specify the size of the data Optional argument TLAST if tlast = false, No TLAST is driven if tlast = true, last data beat has TLAST=true Default value of TLAST is true. |
transport(data,
tlast)
|
API to send data in the form of vector of char Optional argument TLAST if tlast = false, No TLAST is driven if tlast = true, last beat has TLAST=true Default value of TLAST is true. |
transport(packet)
|
API to send the AXI4-Stream packets |
sample_transaction(data)
|
API to receive data in the form of vector of char Receives data beat by beat (one
|
sample_transaction(data, tlast)
|
API to receive data in the form of vector of char Receives data beat by beat (onesample_transaction() call gives one beat of
data).This API returns the tlast value. |
sample_transaction(packet)
|
Receives data beat by beat (one
|
end_of_simulation()
|
End and exit the simulation using this API Preferably use in External TG with sw_emu/hw_emu |
disconnect()
|
To disconnect the socket connections (DataIn, DataOut etc) Preferably use in External TG with AI Engine sim/x86sim |
xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::BLOCKING>
Instantiates the sender in the C++ code for blocking send calls.
- API Usage
- Creates the user object using the API for blocking API calls:
- Parameters
- Name of the external port that sends the data:
- Example
-
Here,xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::BLOCKING> data_in("DataIn");
data_in
is the sender object andDataIn
is the external port name.
xtlm_ipc::axis_target_socket_util<xtlm_ipc::BLOCKING>
Instantiates the receiver in the C++ code for blocking API calls.
- API Usage
- Creates the user object for the receiver for blocking receive calls:
- Parameters
- Name of the external port that receives the data:
- Example
-
Here,xtlm_ipc::axis_target_socket_util<xtlm_ipc::BLOCKING> data_out("DataOut");
data_out
is the user object andDataOut
is the external port name.
xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::NON_BLOCKING>
Instantiates the sender in the C++ code for non-blocking API calls.
- API Usage
- Creates the user object for the sender:
- Parameters
- Name of the external port that receives the data:
- Example
-
Here,xtlm_ipc::axis_initiator_socket_util<xtlm_ipc::NON_BLOCKING> data_in("DataIn");
data_in
is the user object andDataIn
is the external port name.
xtlm_ipc::axis_target_socket_util<xtlm_ipc::NON_BLOCKING>
Instantiates the receiver in the C++ code for non-blocking API calls.
- API Usage
- Creates the user object using the API:
- Parameters
- Name of the external port that receives the data:
- Example
-
Here,xtlm_ipc::axis_target_socket_util<xtlm_ipc::NON_BLOCKING> data_out("DataOut");
data_out
is the user object andDataOut
is the external port name.
transport(std::vector<char> data, int size(), bool tlast=true)
Sends the data if you prefer not to have fine granular control (recommended).
- API Usage
- Calls the API using the sender object:
- Parameters
- The generated data in the form of vector of char:
- Example
-
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)
Sends the data if you prefer not to have fine granular control (recommended).
- API Usage
- Calls the API using the sender object:
- Parameters
- The generated data in the form of vector of char:
transport(xtlm_ipc::axis_payload packet)
Sends the stream packets if you need fine granular control.
- API Usage
- Calls the API using the sender object:
- Parameters
- AXI stream packet:
- Example
-
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)
Receives the data if you prefer not to have fine granular control (recommended).
- API Usage
- Calls the API using the receiver object.
- Parameters
- The empty vector of char to receive the data:
- Example
-
Receives data available on the interface up to TLAST. For example, if the master generates TLAST every 16 beats, then the vector<> will be populated with 16 beats. If the master does not drive TLAST, then every beat is considered a transaction by itself (i.e one beat per call of the API).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 }
sample_transaction(std::vector<char>& data, bool& tlast)
Receives data if you prefer not to have fine granular control (recommended).
Here bool tlast
is passed as an
argument to check if the current data is the last beat of transaction.
You can use this tlast
for further
processing.
- API Usage
- Calls the API using the receiver object
- Parameters
- The empty vector of char to receive the data:
- Example
-
Receives data available on the interface up to TLAST. For example, if the master generates TLAST every 16 beats, then the vector<> will be populated with 16 beats. If the master does not drive TLAST, then every beat is considered a transaction by itself (i.e one beat per call of the API).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 }
sample_transaction(xtlm_ipc::axis_payload& packet)
Receives AXI stream packets.
- API Usage
- Calls the API using the receiver object:
- Parameters
- Empty stream packet to be filled with samples:
- Example
-
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();
Ends and exits the simulation.
- API Usage
- Calls the API using the sender object:
- Example
-
Preferably used with sw_emu/hw_emu.//! 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();
barrier_wait()
For non-blocking, the API waits for all transactions to complete.
- API Usage
- Calls the API using the sender object.
- Example
-
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()
For non-blocking, the API is used to check if any transaction is available to receive.
This method is useful in the non-blocking version because sample_transaction
may not fill the vector/payload if
no transaction is available. It is recommended to check before calling sample_transaction
with NON_BLOCKING receiver.
- API Usage
- Calls the API using the sender object.
- Example
-
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); }