Streaming Approach¶
To connect the external SystemC component to FERAL, it is necessary to create a C-fcapi-client that includes the FERAL Gateway library described in the FCAPI component. Further, the external SystemC code must include the SystemC FERAL library, and the control of the simulation needs to be done in a Java class.
The following is an example, where the user SystemC code basically receives data from FERAL and sends back to FERAL.
To start, you need to create a directory that contains your external SystemC component and a cpp file containing the C-fcapi-client configuration. The name of this cpp file is used to find the counterpart in FERAL. In this illustrative example, the name is {"ExampleSendReceive.cpp"}, and the fcapi-client is configured to have two ports, a receiver and a sender.
External SystemC component¶
The external SystemC Module must include the systemc library and the socket headers. For this send/receive application, the external SystemC code can be written as:
#include <systemc.h>
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
SC_MODULE(SystemCModule) {
public:
// Declare communication sockets
tlm_utils::simple_initiator_socket<SystemCModule> iSocket;
tlm_utils::simple_target_socket<SystemCModule> tSocket;
SC_CTOR(SystemCModule):iSocket("iSocket"), tSocket("tSocket") {
tSocket.register_b_transport(this, &SystemCModule::b_transport);
}
~SystemCModule() {
}
// In this function you can include or call data processes functions!
void b_transport(tlm::tlm_generic_payload& trans, sc_time& delay){
delay = delay + sc_time(0, SC_US);
iSocket->b_transport(trans, delay);
}
FCAPI-C Client¶
The following cpp file contains the FERAL connection setup.
#include <systemc.h>
#include "systemcferal.h"
#include "feralcapi.h"
#include "SystemCModule.h" // This is the user specific SystemC code
int sc_main(int __attribute__((unused)) argc, char __attribute__((unused)) *argv[])
{
fcapi_init();
fcapi_logAllToStdOut();
{
// Setup FERAL Connection:
Connection_t conn;
fcapi_connectionInit(&conn, UDP, NULL, 44444, NULL, 0);
sc_time stepSize = sc_time(10, SC_US); // Define the time step for the events
FERALControl ctrl("Sync", &conn, stepSize); //
// Setup SystemC Side:
SystemCModule module("module");
Connection_t txConn; // Send port
fcapi_connectionInit(&txConn, UDP, NULL, 44444, NULL, 0);
Connection_t rxConn; // Receive port
fcapi_connectionInit(&rxConn, UDP, NULL, 44444, NULL, 0);
uint32_t dataInputSize = stoi(argv[1]);
uint32_t dataOutputSize = stoi(argv[2]);
LTDataPortInitiator dpIni("dataportIni", &rxConn, "apple", dataInputSize);
LTDataPortTarget dpTgt("dataportTgt", &txConn, "banana", dataOutputSize);
// Connect all components:
dpIni.iSocket.bind(module.tSocket);
module.iSocket.bind(dpTgt.tSocket);
ctrl.syncPort.bind(dpTgt);
ctrl.syncPort.bind(dpIni);
sc_start();
}
fcapi_terminate();
return 0;
}
Simulation scenario¶
Ones defines the SystemC part, the simulation scenario must be created in a java class. The scenario is based on the Gateway implementation, and it is included as a nested class of our example class. Thus:
class ExampleSendReceive {
static class ScenarioWithGateway extends GatewayExampleBaseScript implements Runnable {
public ScenarioWithGateway() {
// Simulation setup
// - create scenario
scenario = new SimulationScenario();
// - create root
director = new DiscreteEventMOCC(scenario);
// Gateway setup
// - Create FERAL gateway for a given backend message protocol
createGatewayFERAL(director, TransmissionBackend.UDP, 1, 44444);
// - create ports for TX, RX, and synchronization
createFERALGatewayPorts(gateway, "banana", "apple", "Sync");
// - Create sender
ByteArrayProvider provider = new ByteArrayProvider(director);
// - Create receiver
ByteArrayReceiver receiver = new ByteArrayReceiver(director);
// - Setup links from/to C modul
new Link(provider.getOutputPort("output"), gateway.getInputPort("apple"));
new Link(gateway.getOutputPort("banana"), receiver.getInputPort("input"));
}
// Initialize simulation scenario
@Override
public void run() {
scenario.startSimulation(SimulationDuration.us (100));
}
}
public static void main{
ScenarioWithGateway scenario = new ScenarioWithGateway();
new Thread(scenario).start();
inputSize = "2";
List<String> inputs = new ArrayList<>(Arrays.asList(inputSize,inputSize));
// launch system c
List<String> stdOut = new ArrayList<>();
final int exitCode = ExecutableRunner.runExecutableSync
("target/path_to_the_compiled/C-fcapi-client_file/ExampleSendReceive", inputs, stdOut, false);
}
}
Note
The ByteArrayProvider and ByteArrayReceiver are defined as is indicated in the Create a Simulation section.