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.
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
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.
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
avg1 is used as input for the signal
din. Also, as suggested in the picture above, the number of tokens are specified for
avg1->iport1 (3) and
The function passed as a parameter for the
avg1 process (of type
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
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.
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.
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
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.
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
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
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: