Communication Example
This file is intended for giving a full example of how the communication between the different modules works. It will mainly focus on the SystemC components. To have more details about the communication of GvSoC with SystemC, please refer to the timing documentation.
The whole system works by means of requests, that can be of two types:
- Read: the core wants to read data from a sensor
- Write: the core wants to write data to a sensor
When a request is made, the text need to set the corrected values to its output signals, to instruct the functional bus how to handle the request. The following code snippet shows how the core handles the request.
void Core::handle_req(MessyRequest *req)
{
// ... other code
if (req->read_req)
{
// setting the correct signals to the functional bus for a read request
}
else
{
// // setting the correct signals to the functional bus for a write request
}
// ... other code
}
handle_req
please refer to the core.cpp file.
The middle main component of the system is the functional bus.
Write Request
When a write request is made, the core sets the following signals:
- request_address: is set to the address of the sensor memory that is being accessed
- request_data: is set to the pointer to the data that is being written to the sensor memory
- request_size: is set to the number of bytes that are being written to the sensor memory
- functional_bus_flag: is set to false, to indicate that the request is a write
- request_ready: is set to true, to indicate that the request is ready to be processed by the functional bus
Then the core stops on a wait()
statement, waiting for a change on the request_go
signal. A visual representation of the sequence of events of this first part is shown in the following diagram.
sequenceDiagram
participant Core
participant Functional_bus
Functional_bus->>Functional_bus: wait(request_ready, go_sensors)
Core->>Functional_bus: request_address = address
Core->>Functional_bus: request_data = data
Core->>Functional_bus: request_size = size
Core->>Functional_bus: functional_bus_flag = false
Core->>Functional_bus: request_ready = true
Core->>Core: wait(request_go)
The context is then passed to the functional bus, which is waiting on the hilighted wait()
statement in the following code.
void Functional_bus::processing_data(){
// ..... other code
while (true){
if (request_ready.read() == true) {
// ... other code
}
// Wait for the next event
wait();
if(selected_sensor>=0){
// ... other code
}
}
}
Since the request_ready
signal, which was initially set to false, is now set to true, the functional bus wakes up and starts processing the request.
The first thing that the functional bus does is to set the request_go
signal to 0, to indicate that the request is being processed. Then it continues by setting all the necessary signals to instruct the sensor how to handle the request. Specifically, it sets the following signals:
- address_out_sensor: is set to the address of the sensor memory that is being accessed
- data_out_sensor: is set to the pointer to the data that is being written to the sensor memory
- size_out_sensor: is set to the number of bytes that are being written to the sensor memory
- flag_out_sensor: is set to false, to indicate that the request is a write
- ready_sensor: is set to true, to indicate that the sensor can start processing the request
After that, the functional bus stops again on the same wait()
statement as before, waiting for the sensor to complete the request.
sequenceDiagram
participant Core
participant Functional_bus
participant Sensor
Sensor->>Sensor: wait(ready_sensor)
Functional_bus->>Functional_bus: wait(request_ready, go_sensors)
Core->>Functional_bus: request_address = address
Core->>Functional_bus: request_data = data
Core->>Functional_bus: request_size = size
Core->>Functional_bus: functional_bus_flag = false
Core->>Functional_bus: request_ready = true
Core->>Core: wait(request_go)
Note over Functional_bus: Functional bus wakes up
Functional_bus->>Sensor: address_out_sensor = address
Functional_bus->>Sensor: data_out_sensor = data
Functional_bus->>Sensor: size_out_sensor = size
Functional_bus->>Sensor: flag_out_sensor = false
Functional_bus->>Sensor: ready_sensor = true
Functional_bus->>Functional_bus: wait(request_ready, go_sensors)
sequenceDiagram
participant Core
participant Functional_bus
participant Sensor
Sensor->>Sensor: wait(ready_sensor)
Functional_bus->>Functional_bus: wait(request_ready, go_sensors)
Core->>Functional_bus: request_address = address
Core->>Functional_bus: request_data = data
Core->>Functional_bus: request_size = size
Core->>Functional_bus: functional_bus_flag = false
Core->>Functional_bus: request_ready = true
Core->>Core: wait(request_go)
Note over Functional_bus: Functional bus wakes up
Functional_bus->>Sensor: address_out_sensor = address
Functional_bus->>Sensor: data_out_sensor = data
Functional_bus->>Sensor: size_out_sensor = size
Functional_bus->>Sensor: flag_out_sensor = false
Functional_bus->>Sensor: ready_sensor = true
Functional_bus->>Functional_bus: wait(request_ready, go_sensors)
Note over Sensor: Sensor wakes up