SynDEx v7 Tutorial

Nicolas Dos Santos, Christophe Gensoul, Kim-Hwa Khoo
Christophe Macabiau, Quentin Quadrat, Daniel de Rauglaudre,
Yves Sorel, Cécile Stentzel

Contents

Introduction

This tutorial respects some writing conventions:

To create an application workspace, launch SynDEx with option -libs libs. See the SynDEx v7 User Manual for more information.

The examples presented in this tutorial are located in the sub-folder examples/tutorial. Each example is located in its sub-folder. The example 7 is located in the examples/tutorial/example7, examples/tutorial/example7_mono, and examples/tutorial/example7_bi folders.


Example 1

Algorithm, architecture, and adequation:

Example 2

Hierarchy in algorithm:

Example 3

Delay in algorithm:

Example 4

Repetition and library in algorithm:

Example 5

Condition and nested condition in algorithm:

Example 6

Algorithm, architecture, adequation, and code generation:

Example 7

Definition of the source code into the code editor window:

Definition of the source code in separate C files:

Example 8

A complete realistic application from adequation to execution:

Example 9

A multiperiodic application:

Chapter 1  Example 1: algorithm, architecture, and adequation

1.1  The main algorithm


Figure 1.1: Algorithm / New Algorithm Window

From the principal window, choose the File / Save as option and save your first application under a new folder (e.g. my_tutorial) with the name example1.

Choose Algorithm / New Algorithm Window (cf. figure 1.1). It opens the edition window for algorithm definitions.

1.1.1  Definition of a sensor


Figure 1.2: Define Sensor


Figure 1.3: Name of the new sensor


Figure 1.4: Sensor definition window


Figure 1.5: Contextual menu → Add port


Figure 1.6: Create Port


Figure 1.7: Sensor definition window after output port created

To create an input sensor definition:

1.1.2  Definition of an actuator

To create an output actuator definition:

1.1.3  Definition of a function

To create a computation function definition:

1.1.4  Definition of the main algorithm


Figure 1.8: Contextual menu → Set As Main Definition


Figure 1.9: Drag and drop input definition


Figure 1.10: Create References to input


Figure 1.11: Main algorithm after references to sensor created


Figure 1.12: Main algorithm of the Example 1

To create an AlgorithmMain function definition:

1.2  An architecture with one operator

1.2.1  Definition of an operator


Figure 1.13: Operator definition window

To create an Uinout operator definition:

1.2.2  Definition of the main architecture


Figure 1.14: Architecture / Define Architecture


Figure 1.15: Edit / Reference Operator


Figure 1.16: Architecture with one operator

To create an ArchiOneOperator architecture definition:

The architecture looks like the figure 1.16.

1.3  An architecture with a SAM point-to-point comunication medium

1.3.1  Definition of operators

To create Uin and Uout definitions:

1.3.2  Definition of a medium


Figure 1.17: Type of a communication medium

To create a MediumSamPointToPoint medium definition:

1.3.3  Definition of the main architecture

To create an ArchiSamPointToPoint architecture definition:

1.3.4  Connections between the operators and the medium


Figure 1.18: Architecture with two operators and a SAM point-to-point communication medium

In the main architecture window, to create a connection between the u1 operator and the medium_sampp medium, point the cursor on the port x of the operator, middle click, and drag it to the communication medium. It draws an edge between the operator and the communication medium. After creating the other connection, the main architecture looks like the figure 1.18.

1.4  An architecture with a SAM multipoint medium

To create an ArchiSamMultiPoint architecture definition:

The architecture looks like the figure 1.19


Figure 1.19: Architecture with three operators and a SAM multipoint communication medium

1.5  An architecture with a RAM medium

To create the ArchiRam architecture definition:


Figure 1.20: Architecture with three operators and a RAM comunication medium

The architecture looks like the figure 1.20.

1.6  The adequation

1.6.1  Without constraint

Define the architecture with three operators and a medium of type SAM MultiPoint (cf. 1.4) as main architecture (Edit / Set As Main Architecture).

From the principal window, choose Adequation / Launch Adequation, then choose Adequation / Display schedule.

It opens the schedule window (cf. figure 1.21) in which you can see the schedule of the algorithm on the architecture and the schedule of the different inter-operator communications on the medium.


Figure 1.21: Schedule

1.6.2  With constraints

To contraint the ArchiSamMultiPoint architecture:

From the principal window, choose File / Close. In the dialog window, click on the Save button.

Chapter 2  Example 2: parameters and hierarchy in algorithm

From the principal window, choose File / Save as and save your second application under your tutorial folder with the name example2.

2.1  Definition of the function A

To create the A function definition:

The function A looks like the figure 2.2.


Figure 2.2: Function A

2.2  Definition of the function B

To create the B function definition:

The function B looks like the figure 2.3.


Figure 2.3: Function B

2.3  Definition of the algorithm with hierarchy

To create the Main algorithm:

The algorithm looks like the figure 2.4.


Figure 2.4: Algorithm of the Example 2

From the principal window, choose File / Close. In the dialog window, click on the Save button.

Chapter 3  Example 3: delay in algorithm

From the principal window, choose File / Save as and save your third application under your tutorial folder with the name example3.

3.1  Definition of the operations input, output, and calc

Create a sensor input, an actuator output, and the function calc, like in the Examples 1 and 2. (cf. 1.1.3 and calcul1 in 2.1)

3.2  Definition of the delay

To create the calcPrec delay:

3.3  Definition of the algorithm with delay

Create an algorithm algorithmMain. Create a reference in1 to the definition input, a reference calc to the definition calc, a reference out1 to the definition output, and a reference calcPrec<0;1> to the definition calcPrec. Create dependences between the references.

The algorithm looks like the figure 3.1.


Figure 3.1: Algorithm of the Example 3

From the principal window, choose File / Close. In the dialog window, click on the Save button.

Chapter 4  Example 4: repetition and library in algorithm

From the principal window, choose File / Save as and save your fourth application under your tutorial folder with the name example4.

4.1  An algorithm with repetition without any library

In this section, we create a multiplication function of a N elements vector by a scalar by repeating N times a multiplication function on scalars.

4.1.1  Definition of the scalar ins and the function mul on scalars

In a new algorithm window:

4.1.2  Definition of the vectors inv and outv

To create the vectors:

4.1.3  Definition of the algorithm AlgorithmMain1

To create the AlgorithmMain1 algorithm:

The repetition consists in multiplying each of the 3 elements of the v_input vector with the s_input scalar and placing the result in the 3 elements v_output vector.

The parameter N is here the repetition factor of the mul function.


Figure 4.2: AlgorithmMain1 of the Example 4

4.2  An algorithm with repetition with the int library

In this section, we create a multiplication function of a vector by a scalar by using the int library.

4.2.1  Inclusion of the library int

From the principal window choose File / Specify Library Directories and add the SYNDEXPATH/libs where SYNDEXPATH is the absolute path of the SynDEx distribution.

From the principal window, choose File / Included Libraries / int (cf. figure 4.3).


Figure 4.3: File / Included Libraries / int

4.2.2  Definition of the algorithm AlgorithmMain2

Notice that this library contains input, mul, and output definitions parameterized with length.

We will need to set it to 1 for the scalar and the multiplication function, and to N for the vectors:

Notice the difference of the mul reference when it is seen from the AlgorithmMain2 definition mode or from the main mode (Main button).


Figure 4.5: AlgorithmMain2 of the Example 4

4.3  An algorithm with repetition with the float library

In this section, we create a multiplication function of a N*M matrix by a M elements vector by repeating N times a multiplication function on vectors.

4.3.1  Inclusion of the library float

Include the library float (File / Included Libraries / Float).

4.3.2  Definition of the function dpacc

This function is a multiplication function on scalars with an accumulator:

Notice that acc is an input port and an output port of the function. It will be used as an accumulator to store the partial sum.


Figure 4.6: Algorithm of the function dpacc

4.3.3  Definition of the function dp

This function is a multiplication function on vectors with an accumulator:

The repetition consists in multiplying two dpaccn elements vectors by calling dpaccn times the dpacc multiplication function on scalars with accumulator. The initial value of its accumulator is given by the zero constant and the following are given by the accumulator itself.

4.3.4  Definition of the function prodmatvec

This function is a multiplication function of a matrix by a vector:

The repetition consists in multiplying a a*b matrix by a b elements vector by calling a times the dp multiplication function on vectors.

4.3.5  Definition of the algorithm AlgorithmMain3

To create the AlgorithmMain3 algorithm:

From the principal window, choose File / Close. In the dialog window, click on the Save button.

Chapter 5  Example 5: condition and nested condition in algorithm

From the principal window, choose File / Save as and save your fifth application under your tutorial folder with the name example5.

5.1  An algorithm with condition

5.1.1  Sensors x and i, actuator o

To create the sensors and the actuator:

5.1.2  Function switch1

To create the switch1 function:

5.1.3  Algorithm AlgorithmMain1

The algorithm looks like the figure 5.6.


Figure 5.6: AlgorithmMain1 of the Example 5

5.2  An algorithm with nested condition

5.2.1  Sensors x and i, actuator o

Use previous definitions (cf. 5.1.1).

5.2.2  Function switch2

To create the switch2 function:

5.2.3  Algorithm AlgorithmMain2

The algorithm looks like the figure 5.9.


Figure 5.9: AlgorithmMain2 of the Example 5

From the principal window, choose File / Close. In the dialog window, click on the Save button.

Chapter 6  Example 6: algorithm, architecture, adequation, and code generation

From the principal window, choose File / Save as and save your sixth application under a new folder of your tutorial folder (e.g. my_example6) with the name example6.

6.1  The main algorithm

Create the main algorithm algo (cf. figure 6.1) using the library int for the operations In<1> (input), cste2<{2}> (cst), add<1> (Arit_add), mul<1> (Arit_mul), visuadd<1>, and visumul<1> (output). For the operation conv, create a function definition conv, create a reference to this definition, and give it a duration. Create the dependences between the references. Set it as main.


Figure 6.1: Main algorithm of the Example 6

Warning: it is necessary that the sensor “in” should be distributed onto the processor “root”, i.e. on the local machine, in order that it operates properly.

6.2  The main architecture

To define and constraint the main architecture:

6.3  The adequation and the code generation

To perform the adequation and to generate the code:

where SYNDEXPATH is the absolute path of the SynDEx distribution.
Warning: in the previous makefile the statements $(RM) $(A).mk and $(M4) $< >$@ must begin with a tab character.
The folder of the Example 6 must contain the following files:

To launch the execution, type the command make in the folder of the Example 6. To delete the file created during the compilation, type the command gmake clean.

From the principal window, choose File / Close. In the dialog window, click on the Save button.

Chapter 7  Example 7: source code associated with an operation

7.1  Definition of the source code into the code editor window

In the previous Example 6, we have learnt that a m4 file, called with the name of the application plus the m4x extension, must be manually written. It contains all the source code associated with all operations present in a SynDEx application. For example, in the example6 application, the conv function increments of one the value of the input and stores the result in the output. Thus example6.m4x file contains:

  
    define(‘conv’,‘ifelse(
    MGC,‘INIT’,‘dnl’,
    MGC,‘LOOP’,‘$2[0] = $1[0] + 1;’,
    MGC,‘END’,‘dnl’)’)
  

where $1 and $2 correspond respectively to the input port named i and the output port named o of the conv function.

You may read the comments written in the example6.m4x.

Handwriting this kind of code is not very easy, for several reasons:

It should be more convenient to write @OUT(o)[0] = @IN(i)[0] + @PARAM(P) and let SynDEx interpret it and generate the associated m4x file than to write the specification with the m4 syntax. SynDEx (version ≥ 7.0.0) is able to do that thanks the code editor which is a tool integrated in the graphical user interface (GUI). In the following example, we will show how to use this tool.

7.1.1  To add parameters to an already defined operation

In this example, we show how to modify some functions by adding parameters in order to expand parameters into m4 arguments.

Open the example6.sdx application:

Add parameters to the conv function:

Verify that the parameters have been stored in the function

We have two solutions:

7.1.2  To edit the code associated with an operation

In the case of a generic processor

In the case of an architecture with heterogeneous processors

Sometimes it is interesting for an operation to have different source codes depending on the type of processor. For example, a given processor type X may only offer assembly language as a programming interface. In such case, we must be able to provide (for example) C code for processors that support it, and assembly language for the X processor type. To support heterogeneous architecture, the code editor associates code to a triplet (phase, processor, operation). A special processor type Default is provided for processors that have not been associated with dedicated code. Its use allows to share a code between different processor types.

Learn the macros of the code editor

The code editor comes with a set of predefined macros that alleviate the user from knowing the black magic of m4 processing.

The more useful ones are names translation macros. These macros translate port and parameter names to their internal representation as m4 parameters. We have already encountered such macros in what we have just done: @IN, @OUT and @INOUT are port name translation macros, and @PARAM is the parameter name translation macro. As a rule of thumb, you should use @PARAM(x) when you want to refer to a parameter x and @IN(i) (resp. @OUT(o) / @INOUT(io)) when you refer to an input port i (resp. output port o / input-output port io).

The code editor recognizes three more macros: @NAME, @QUOTE and @TEXT. These advanced macros are not used in this tutorial and the reader is refered to SynDEx user manual to learn more about it.

7.1.3  To generate m4x files

Before performing the code generation we have to perform the adequation:

Two cases are possible:

These two files constitute the Applicative kernel:

The example7_sdc.m4x file contains the following code:

  
    divert(-1)
    # (c)INRIA 2001-2009
    divert(0)

    define(‘example7_bar’,‘bar’)
    define(‘bar’,‘ifelse(
    processorType_,‘C40’,‘ifelse(
    MGC,‘INIT’, “/* Hi, I am $0 function, in init phase for C40 processor */”,
    MGC,‘LOOP’,“$2[0] = $1[0]; /* Hi, I am $0 function, in loop phase for C40 processor */”,
    MGC,‘END’, “/* Bye, I am $0 function, in end phase for C40 processor */”)’)’)
    processorType_,‘U’,‘ifelse(
    MGC,‘INIT’,“/* Hi, I am $0 function, in init phase for U processor */”,
    MGC,‘LOOP’,“$2[0] = $1[0] * 42; /* Hi, I am $0 function, in loop phase for U processor */”,
    MGC,‘END’, “/* Bye, I am $0 function, in end phase for U processor */”)’,

    define(‘example7_conv’,‘conv’)
    define(‘conv’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“printf("Init phase of function $0 for default processor.\n");”,
    MGC,‘LOOP’,“$5[0]=$3[0]*$2+$1;
     printf("Loop phase of function $0 for default processor =%i.\n", $4[0]);”,
    MGC,‘END’,“printf("End phase of function $0 for default processor.\n");”)’)’)
  

If the example7.m4x file did not exist at code generation time then it will contain the following code:

  
    divert(-1)
    # (c)INRIA 2001-2009
    divert(0)

    define(‘dnldnl’,“// ”)
    define(‘NOTRACEDEF’)
    define(‘NBITERATIONS’,“5”)

    include(‘example7_sdc.m4x’)

    divert
    #include <stdio.h> /* for printf */
    divert(-1)
    divert‘’dnl
  

Deeper insights about the m4 macro language can be found in SynDEx user manual and GNU M4 manual.

Notice that:

From the principal window, choose File / Close. In the dialog window, click on the Save button.


1
Macros of the code editor as @IN, @OUT, @PARAM, … are explained in the User Manual.

Chapter 8  Example 8: a complete realistic application from adequation to execution

From the principal window, choose File / Save as and save your eighth application under a new folder of yout tutorial folder (e.g. my_example8) with the name example8.

8.1  The aim of the example

In the seven previous examples we have learnt how to use SynDEx’s GUI to create architectures, algorithms, launch adequation, obtain executive files... Now, we have sufficient knowledge to perform a simple automatic control application that will be executed on a multiprocessor architecture.

First the application is described and the system is defined in Scicos (the block diagram editor of the Scilab software1). Second the corresponding SynDEx application is created (using the Example 1 to 3 of the tutorial). This needs the generation of some C code following the method discussed in Example 7. Finally, we compile the application to obtain executable for several processors as it has been shown in Examples 6 and 7. SynDEx generates the code necessary to the communication between the processors.

8.2  The model

We consider a system of two cars. The second car C2 follows the car C1 trying to maintain the distance l while the acceleration and the deceleration of C1. We call: x1(t) the position of the first car; x2(t) the position of the second car plus l; x_1(t) and x_2(t) the speeds of two cars. We denote k1 and k2 the inverse of the car masses. We call r(t) the reference speed chosen by the first driver. We suppose that we are able to observe the speed of the first car and the distance between the cars.

We have the following fourth order (four degrees of liberty) system:

x1k1 u1    x2k2 u2    y1= x_1     y2x1 − x2     (1)

We will decompose the system into mono-input mono-output system S1 (u1,y1) and S2 (u2,y2). Denoting by uppercase letter the Laplace transform of the variables, we have Y1=k1 U1/s and Y2=(k1 U1k2 U2)/s2 where U1 is seen as a perturbation that we want reject in the second system.

A first proportional feedback U11(RY1) will insure the first car to follow the reference speed. The second controller will be proportional derivative U22 Y23 s Y2 (in fact we will suppose in the following diagram that the derivative of y2 is also observed). The coefficient ρ1 is obtained by placing the pole of the first loop:

Y11k1R/(s1k1).

The coefficient ρ2 and ρ3 are obtained by placing the pole of the transfer from U1 to Y2 in the closed loop system which is given by:

Y2=U1k1/(s2+k2ρ3s +k2ρ2).

8.3  The controllers

The purpose of the controller of the C1 car is to follow the reference in speed given the first driver. It stabilizes the C1 speed around its reference speed by using pole placement. For example, gains are respectively: (0, -5, 0, 0, -5). The controller of second car stabilizes the distance between the two cars. It stabilizes y2 around 0 by pole placement. For example, gains are respectively: (4, 4,-4,-4).

The controler of C2 knows these informations and sends them electronically to C1. This remark is available for C1.

8.3.1  Block diagrams of controllers


Figure 8.1: Scicos controller of the first car


Figure 8.2: SynDEx controller of the first car


Figure 8.3: Scicos controller of the second car


Figure 8.4: SynDEx controller of the second car

Our controllers are simple. They are represented in figures 8.1 and 8.3 in Scicos and figures 8.2 and 8.4 in SynDEx:

8.3.2  Source code associated with the functions

We associate C source code to each function definition: gain and nary-sums. The code is inserted for the default processor.

Gain

A gain is a function that multiplies its input by a coefficient given as a parameter, named GAIN. After adding this parameter, open the code editor of the gain definition and write the following code in the loop phase of the default processor:

  
    @OUT(out_1)[0] = @IN(in_1)[0] * @PARAM(GAIN);
  

Sum

We have three different forms of sum depending of its arity: two, four or five input ports:

8.4  The complete model

In a real application, our job stops with the SynDEx’s adequation of the two controllers on their associated architectures. Nevertheless, for pedagogic reasons, we will simulate the whole system (with the dynamics of the cars) in the aim to verify that our application does the same job that Scicos.

8.4.1  The car dynamics

SynDEx is only used in discrete time model (not continuous time) and is not able to manage implicit algebraic loop. That is, in SynDEx, any loop contains at least a delay 1/z. Therefore, our application which is a continuous time dynamic system described in Scicos, must be discretized in time to be used in SynDEx.

The differential equation ẋ=u is discretized using the simplest way: the Euler scheme. Let us denote by h the step of the discretization and x0 an arbitrary initial value, the discretized system can be written as:

xn+1 − xnuh     (2)

Finally, the system is given in Scicos in the figure 8.5 and 2 is given in SynDEx in the figure 8.6. Notice that the variable h is stored in the Scicos context, and used in the input of the gain and the clock definition. In SynDEx, h is defined as parameter in the definition of a gain and the clock definition is directly used in the source code associated with operations.


Figure 8.5: An integral discretized in Scicos


Figure 8.6: An integral discretized in SynDEx

Create the integrale_discrete_sup algorithm (cf. figure 8.6). Notice that pas is of type gain_def with parameter GAIN equal to 0.001, sommateur is of type sommateur2_def, and retard is of type float/delay<{0};1>.

The car dynamics are given with Scicos block diagrams in the figure 8.7 and with SynDEx operations in the figure 8.8, where the input 1 (ref) is the acceleration of the car. The first integral gives the speed of the car and the second its position.


Figure 8.7: Car dynamics with Scicos block diagrams (continous time)


Figure 8.8: Car dynamics with SynDEx operations

Create the mecanique_sup algorithm (cf. figure 8.8). Notice that puissancemoteur is of type gain_def with parameter GAIN equal to 1 whereas integrale1 and integrale2 are of type integrale_discrete_sup.

8.4.2  The cars and their controllers

In the following diagrams (from 8.9 to 8.12), the blocks (operations) denoted by meca are the car dynamics. Let us get the controllers of the two cars.


Figure 8.9: Scicos C1 car dynamics and its controller


Figure 8.10: SynDEx voiture1_sup car dynamics and its controller


Figure 8.11: Scicos C2 car dynamics and its controller


Figure 8.12: SynDEx voiture2_sup car dynamics and its controller

Create the voiture1_sup and voiture2_sup algorithms (cf. figures 8.10 and 8.12). Notice that meca1 and meca2 are references to mecanique_sup whereas control1 (resp. control2) is a reference to controleur1_sup (resp. controleur2_sup).

8.4.3  The main algorithm

Create the following definitions (definitionName<PARAM>):

Then create algomain. Create the reference speed ref_vit of definition senseur_def<0>, the reference vitesse x_1 of definition vitesse_def<1>, the reference distance between the two cars of definition scope_def<2>, the reference vehicule1 of definition voiture1_sup and the reference vehicule2 of definition voiture2_sup, connect them according to the figure 8.13.


Figure 8.13: Main algorithm

8.4.4  Source code associated with the sensor and the actuator

We associate C source code to each function definition: input and two kinds of output.

Input

In our Scicos application an input is a square wave generator. As a rule, we will simulate a square wave generator by reading values in a text file (named ref_vitesse.txt). We will use the fopen, the fclose and the fscanf functions (stdio.h library). We will also use assertions (assert.h library) to ensure that the opening of a file has been successful.

For the moment, let suppose that it exists an array of FILE* (the structure returned by the fopen function) called fd_array and a variable called timer to simulate a pseudo-timer. Our sensor has a parameter called POSI_ARRAY to remember the position of the FILE* structure in the array.

Now, open the code editor of the senseur_def sensor and write the following code in the init phase of the default processor:

  
    timer = 0;
    fd_array[@PARAM(POSI_ARRAY)] = fopen("ref_vitesse.txt", "r");
    assert(fd_array[@PARAM(POSI_ARRAY)] != NULL);
  

In the Scicos application, we have defined the clock period of the square wave generator to the value 5 and the step of discretization h to the value 0.001. Thus we need, in the SynDEx application, to send 5000 times the same value. To count, we use the variable timer. All the 5000-th times, we read a new value in the file.

Write the following code in the loop phase of the default processor:

  
    timer = (timer + 1) % 5000;
    if (timer == 1)
    fscanf(fd_array[@PARAM(POSI_ARRAY)], "%f\n", &data);
    @OUT(out_1)[0] = data;
  

We need to free memory by closing the file. Write the following code in the end phase of the default processor:

  
    fclose(fd_array[@PARAM(POSI_ARRAY)]);
  

Speed output

An output saves in a file the values of the system states. Thus, an output has a parameter called POSI_ARRAY to remember the position of the array where the stream has been saved. Open the code editor of the vitesse_def actuator and write the following code in the init phase of the default processor:

  
    fd_array[@PARAM(POSI_ARRAY)] = fopen("actuator_@TEXT(@PARAM(POSI_ARRAY))", "w");
    assert(fd_array[@PARAM(POSI_ARRAY)] != NULL);
  

The loop phase, allows to save the values:

  
    fprintf(fd_array[@PARAM(POSI_ARRAY)], "%E\n", @IN(in_1)[0]);
  

We need to free the memory by closing the file. Write the following code in the end phase:

  
    fclose(fd_array[@PARAM(POSI_ARRAY)]);
  

Distance output

Contrary to the first type of output, this output has two input ports but the init and end source codes are identical. The loop phase differs. Open the code editor of the scope_def actuator and write the following code in the init phase of the default processor:

  
    fprintf(fd_array[@PARAM(POSI_ARRAY)], "%E\n", (@IN(in_1)[0] - @IN(in_2)[0]));
  

8.4.5  The example8_sdc.m4x

SynDEx’s code generation will create the example8_sdc.m4x file (as explained in Example 7):

  
    define(‘example8_algomain’,‘algomain’)
    define(‘algomain’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_controleur1_sup’,‘controleur1_sup’)
    define(‘controleur1_sup’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_controleur2_sup’,‘controleur2_sup’)
    define(‘controleur2_sup’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_gain_def’,‘gain_def’)
    define(‘gain_def’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_integrale_discrete_sup’,‘integrale_discrete_sup’)
    define(‘integrale_discrete_sup’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_scope_def’,‘scope_def’)
    define(‘scope_def’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_senseur_def’,‘senseur_def’)
    define(‘senseur_def’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_sommateur2_def’,‘sommateur2_def’)
    define(‘sommateur2_def’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_sommateur4_def’,‘sommateur4_def’)
    define(‘sommateur4_def’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_sommateur5_def’,‘sommateur5_def’)
    define(‘sommateur5_def’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_vitesse_def’,‘vitesse_def’)
    define(‘vitesse_def’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_voiture1_sup’,‘voiture1_sup’)
    define(‘voiture1_sup’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)

    define(‘example8_voiture2_sup’,‘voiture2_sup’)
    define(‘voiture2_sup’,‘ifelse(
    processorType_,processorType_,‘ifelse(
    MGC,‘INIT’,“”,
    MGC,‘LOOP’,“WARNING: empty code for macro $0 in loop phase”,
    MGC,‘END’,“”)’)’)
  

8.4.6  To handwrite the example8.m4x file

You will not can use directly the SynDEx’s generated example8.m4x generic file because both the creation of local variable and the call of libraries is missing. After the code generation, you will must handwrite it to obtain the following code:

  
    define(‘dnldnl’,“// ”)
    define(‘NOTRACEDEF’)
    define(‘NBITERATIONS’,“20000”)

    define(‘BINPWD’, ‘pwd’)
    define(‘RSHELL’, ‘ssh’)

    define(‘proc_init_’,‘
    FILE *fd_array[10];
    float data;
    int timer;’)

    include(‘example8_sdc.m4x’)

    divert
    divert(-1)
    divert‘’dnl
  

Where the macro proc_init_ allows the local variable declaration to be declared because it inserts its source code between the main function and the operations initialization. Notice that the main loop of the program is defined generically with a loop of NBITERATIONS where NBITERATIONS is initialized with the size of the input file (ref_vitesse.txt). Finally, the call of libraries is inserted after the include of the example8_sdc.m4x file.

8.5  Scicos simulation

Scicos software allows to simulate models in a window (cf. figure 8.14), where the values of three states are plotted (ordinate axle) according to the time (abscissa axle). We have:

Thanks the diagram, the system is stable (plots do not grow exponentially) and so it works. We do not continue to ameliorate the controllers job.


Figure 8.14: Scope window obtained with the values 0; -5; 0; 0; -5 for gains of the C1 controller and 4; 4; -4; -4 for the C2 controller.

8.6  SynDEx simulation

8.6.1  In the case of a mono-processor architecture

The architecture

In this subsection, we suppose that the architecture is constituted of an only operator named root:

The adequation and the code generation

First, launch the adequation. It modifies example8.sdc and example8.sdx files.

Then, generate the executive and applicative files (setting Code / Generate m4x Files). It creates example8.m4, example8.m4x, example8_sdc.m4x, and root.m4 files.

Finally, handwrite the example8.m4x file as explained in 8.4.6.

The compilation

First, generate manually a GNUmakefile containing:

  
    A  = example8
    M4 = gm4

    export ArchiMacros_Path = ../../../macros/archi_libraries
    export AlgoMacros_Path = ../../../macros/algo_libraries
    export M4PATH = $(ArchiMacros_Path):$(AlgoMacros_Path)

    CFLAGS = -DDEBUG
    VPATH = $(M4PATH)

    .PHONY: all clean
    all : $(A).mk $(A).run
    clean ::
    $(RM) $(A).mk *~ *.o *.a *.c actuator_*

    $(A).mk : $(A).m4 syndex.m4m U.m4m
    $(M4) $< >$@

    root.libs =
    P1.libs =

    include $(A).mk
  

Where:

Then, copy-paste the ref_vitesse.txt file from the Example 8 folder to yours.

Then, type the command gmake in a shell commands interpreter. It creates actuator_1, actuator_2, example8.mk, root, root.c, and root.root.o files:

8.6.2  In the case of a bi-processor architecture

The architecture

In this subsection, we suppose that the architecture is constituted of two operators named root and pc1, of type U and linked with a medium tcp1 of type TCP:

The adequation and the code generation

First, launch the adequation. It modifies example8.sdc and example8.sdx files.

Then, generate the executive and applicative files (setting Code / Generate m4x Files). It creates example8.m4, example8.m4x, example8_sdc.m4x, root.m4, and pc1.m4 files.

Finally, handwrite the example8.m4x file as explained in 8.4.6.

The compilation

First, generate manually the GNUmakefile, the example8.m4m, and the root.m4x files:

Then, copy-paste the ref_vitesse.txt file from the Example 8 folder to yours.

Then, type the command gmake in a shell commands interpreter. It creates actuator_1, actuator_2, example8.mk, root, root.c, root.root.o, pc1, pc1.c, and pc1.pc1.o files:

8.6.3  In the case of a multi-processor architecture

The architecture


Figure 8.15: The architecture with 5 operators.

In this subsection, we suppose that the architecture is constituted of five operators named root,cont1, cont2, dyna1, and dyna2, of type U and linked with a medium bus of type TCP:

The adequation and the code generation

First, launch the adequation. It modifies example8.sdc and example8.sdx files.

Then, generate the executive and applicative files (setting Code / Generate m4x Files). It creates example8.m4, example8.m4x, example8_sdc.m4x, root.m4, cont1.m4, cont2.m4, dyna1.m4, and dyna2.m4 files.

Finally, handwrite the example8.m4x file as explained in 8.4.6.

The compilation

First, generate manually the Makefile.ocaml, the example8.m4m, the root.m4x, the cont1.m4x, the cont2.m4x, the dyna1.m4x, and the dyna2.m4x files:

Then, copy-paste some files from the Example 8 folder to yours:

You will probably need to install camlp5 (see at http://pauillac.inria.fr/ ddr/camlp5/).

Then, type the command make -f Makefile.ocaml in a shell commands interpreter. It creates example8.cmi, example8.o, pa_example8.cmi, and <processor>.cmi, <processor>.cmx, <processor>.o, <processor>.opt for each processor.

Finally, launch separatly the five script files. At the end of their execution, the actuator_1 and actuator_2 files are created:

From the principal window, choose File / Close. In the dialog window, click on the Save button.


1
http://www.scilab.org

Chapter 9  Example 9: a multiperiodic application

From the principal window, choose File / Save as and save your ninth application under a new folder of yout tutorial folder (e.g. my_example9) with the name example9.

9.1  The main algorithm


Figure 9.1: Main algorithm of the Example 9

Create the main algorithm basicAlgorithm (cf. figure 9.1) using the library int for the operations input<1> (int/input) and output<1> (int/output). For the operation compute, create a function definition compute and create a reference to this definition. Create the dependences between the references. Set the periods to 4 for input, 8 for compute, and 8 for output by selecting each reference and filling the Period field.

9.2  The main architecture

Open the architecture monoProc from the library u. Define it as main. The durations for the U operator are by default:

  
    int/input = 3
    Implode_int = 1
    compute = 1
    int/output = 3
  

Implode_int is an internal operation automatically generated by SynDEx to collect the different data produced by the different occurences of the int/input operation.
In this case, the system is not schedulable.

9.3  A mono-phase schedule

9.3.1  Durations

Modify the durations for the U operator:

  
    int/input = 1
    Implode_int = 1
    compute = 1
    int/output = 1
  

9.3.2  Adequation


Figure 9.2: A mono-phase schedule

Launch the adequation (Adequation / Launch Adequation). Display the schedule (Adequation / Display Schedule) (cf. figure 9.2).

Wait operation

Notice the new operation added by SynDEx (Wait) to respect the period of the input operations.

Multiple occurrences

Notice that because of the periods, during a cycle two input operations are executed (input#1 and input#2) whereas only one compute and one output operations are executed.

Implode operation

Notice the new operation added by SynDEx (Implode_compute) to provide the data from the input operations to the compute one.

9.4  A multi-phase schedule

9.4.1  Durations

Modify the durations for the U operator:

  
    int/input = 1
    Implode_int = 1
    compute = 2
    int/output = 1
  

9.4.2  Adequation


Figure 9.3: A multi-phase schedule

Launch the adequation (Adequation / Launch Adequation). Display the schedule (Adequation / Display Schedule). The computed schedule has two phases: a transitory phase (red) and a permanent phase (green) (cf. figure 9.3).

Transitory phase

The transitory phase is executed only once. It contains the first occurrence of the input#1 operation, the first occurrence of the input#2 operation, the first occurrence of the Implode_compute operation, and the first occurrence of the compute operation. The compute operation provide data consumed by the output operation schedule at time 9 in the permanent phase.

Permanent phase

The permanent phase is the one that is executed infinitely. It contains the second occurrence of the input#1 operation (and its following occurrences). It contains the first occurrence of the output operation (and its following occurrences).


This document was translated from LATEX by HEVEA.