The ForSyDe-SystemC Tutorial for the Synchronous Data Flow MoC
This tutorial is a walk-through for modeling systems in the the Synchronous Data Flow (SDF) Model of Computation (MoC) using the ForSyDe-SystemC library. It assumes that the user has already installed the SystemC and the ForSyDe-SystemC libraries and knows how to build and run a model on her computer. Also, it is assumed that the user has gone through the tutorial for the SY MoC, thus we will focus only on the specific features of the SDF MoC.
In ForSyDe-SystemC, a system is modeled as a hierarchical process network where processes communicate only via signals, making it similar to a data-flow style of modeling. Although SystemC elements are present in this framework, the user is advised to adopt only the ForSyDe terminology in designing systems in order to fully exploit the advantages of formalism provided by the ForSyDe methodology.
This tutorial will present a toy example for understanding the concepts of designing an SDF system. As shown in the picture below, this system consists of an up-sampler, a running averager and a down-sampler.
The Synchronous Data Flow (SDF) MoC
Before proceeding with implementing the first system using the SDF MoC of ForSyDe-SystemC, a few basic assumptions derived from the SDF semantics need to be clarified:
- just as the SY MoC, the SDF MoC is untimed, thus there is no notion of physical time described in model.
- processes communicate via messages called tokens.
- each process has fixed production P and consumption C rates.
- a SDF process is triggered once it inputs C tokens (unlike a SY process which is triggered by a master event). Once it is triggered, it consumes the C tokens and produces P tokens.
To understand the usage of the SDF MoC, the user might consider that a main class of applications modelled as SDF systems are telecommunications applications where processes communicate in different clock domains through specific protocols. Also, streaming applications are targeted since their main target is the control of the data flow.
For more information about the concepts behind the SDF MoC, the user is encouraged to consult the world wide web. A good introduction may be found here.
Signal
As seen in the SY tutorial, signals are the only means with which the processes can communicate and synchronize. In the SDF MoC, signals are carriers for the data containers associated with tokens. A signal is typed and it is instantiated with the class ForSyDe::SDF::signal
using the template:
or the template.
Both instantiations are equivalent and create a signal my_sig
which carries tokens encapsulating data of type double
.
Processes
The processes in ForSyDe are described here, and have been presented in the SY tutorial. Their usage in the SDF MoC of ForSyDe-SystemC is similar to the one in SY MoC. The main differences will be presented in the following paragraphs.
Leaf processes
The process constructors for the leaf processes are found in the ForSyDe::SDF namespace. Also, as described in their API documentation, to instantiate a leaf process, apart from the process-specific parameters, the user must pass the number of tokens for each input port and for the output port. An example of process instantiation for the avg1
process in the figure above is:
The same result is obtain by using the make_comb2
helper function to reduce code verbosity (see the SY tutorial):
The helper function constructs a standard comb2
ForSyDe process which has only one output. The line avg1->oport1(din)
specifies that the same output port oport1
of avg1
is used as input for the signal din
. Also, as suggested in the picture above, the number of tokens are specified for avg1->oport1
(2), avg1->iport1
(3) and avg1->iport2
(2).
The function passed as a parameter for the avg1
process (of type avg1
) called avg_func
describes the desired functionality:
The ForSyDe-SystemC convention for passing the process ports as function parameters is still respected. The convention imposes that the list of parameters should start with the output port, followed by the input ports in ascending order of their indexes.
The process ports are passed to the function as vectors and, unlike in the SY MoC, decapsulation is not needed outside the #pragma
preprocessors. Each token is represented by one element of the vector, thus accessing the tokens is like accessing the vector elements (for example inp1[0]
).
Inside the preprocessors #pragma ForSyDe begin
and #pragma ForSyDe end
the user is advised to write standard C code, since most of the design flows associated with ForSyDe-SystemC directly map that code on C-based backends.
Composite processes
The composite processes are the same as in the SY tutorial. The only difference is that, since now the signals which pass through them are SDF signals, the input an output ports now derive from SDF::in_port
, respectively from SDF::out_port
. Below you can find an example for designing the compAvg1
composite process, as suggested in the picture.
Simulation
How to test a ForSyDe-SystemC design has been presented in the SY tutorial. The user needs to provide inputs and observe the outputs with the help of procuder/consumer processes specific to (in our case) the SDF MoC. For example, the top module for our toy example:
As shown in the SY tutorial, two new processes have been instantiated: a source process called stimuli1
which produces a stream of 10 tokens generated by the function stimuli_func
and a sink process called report1
which consumes the tokens generated by ds1
and prints them out through its function report_func
. The code for stimuli_func
and report_func
is:
To verify the design we have to compile the code in a set-up environment suggested in the installation instructions. Running the resulting binary, we get the following output:
SystemC 2.3.0-ASI --- Dec 11 2013 15:10:22
Copyright (c) 1996-2012 by all Contributors,
ALL RIGHTS RESERVED
output value: 0
output value: 0.333333
output value: 1.44444
output value: 2.33333
output value: 3.77778
output value: 4.2716
output value: 5.7572
output value: 6.75309
which is the expected output for our toy system since we know that the source has produced the stream [1 2 3 4 5 6 7 8 9 10]
.
The full code can be checked out from the ForSyDe-SystemC repository, and compiled and run from the user’s machine.
Introspection
The notion of Introspection has been presented in the SY tutorial. This feature can be activated by adding the following lines after declaring the processes inside the module that needs to be parsed (in our case the top module in top.hpp
):
Note that the library (and the above model) are enabled for introspection only when the FORSYDE_INTROSPECTION
macro is defined, either in the source code or as a compiler switch (-DFORSYDE_INTROSPECTION
). Assuming the existence of the gen/
sub-folder, the executable model writes to XML files named top.xml
and compAvg.xml
to this folder, each representing one level of hierarchy. The XML files synthesize the structural characteristics of the system which can be extracted by other tools in the design flow. For example, the tool [[f2dot]] is able to generate the following representation: