• Aucun résultat trouvé

Après l’extraction des interfaces des composants, nous présenterons dans cette section com-ment transformer le comportecom-ment de chaque composant en comportecom-ment formelle SIGNAL. Pour cela, nous avons utilisé le compilateur GCC de SYSTEMC et son format intermédiaire SSA. L’idée est de transformer les constructions SYSTEMC en code SSA, et ensuite de transformer ce code SSA en code SIGNAL. Le choix est motivé par le fait que la structure de contrôle d’un code SSA est beaucoup plus simple que celle d’un code SYSTEMC.

7.4.1 Transformation des types de données

Le modèle résultant de la compilation ne doit faire référence qu’à des objets proche du for-malisme synchrone de SIGNAL, de taille finie et ayant une sémantique précise. SYSTEMC est un langage fortement typé, impératif et orienté objet, donc il est important de conserver toutes les in-formations concernant les types. Néanmoins seuls les types utilisables en vérification et notamment ceux définis par la norme IEEE 1666TM-2005 [?] doivent être considérés.

Les types spécifiés par la norme ont aussi été définis en vue de la simulation et certains d’entre eux comportent des valeurs qui n’ont aucune signification, ni en terme de formalisme synchrone, ni en terme de vérification formelle [?]. La figure ?? donne un exemple de transformation de type.

SystemC SIGNAL

Les structures modulaires

SC_MODULE (<module_name>) Processsus <module_name >

Les ports de communication sc_in <type> sc_out <type> ? <type> ! <type> Les types de données sc_bit sc_int sc_float sc_bv <size> boolean integer real [size] boolean

// Le fichier du programme principal de simulation

#include"systemc.h" #include"ram.h" #include"cpu.h" #include<stdlib.h>

int sc_main (int argc, char *argv[]) {

memoire RAM ("memoire"); cpu CPU ("processeur"); //cpu avec ram

sc_signal <bool> cpuram_sigrd; sc_signal <bool> cpuram sig_wr; sc_signal <bool> cpuram sigout; sc_signal <short int> cpuram_sigin; sc_signal <short int> cpuram_sig_in;

( |

X := f(ZX)+1 | ZX := X$1

|)

FIGURE7.6 – Règles de transformation des types standards

7.4.2 Transformation des opérateurs et des fonctions standards

Les opérateurs et les fonctions standards, comme ceux définis par la norme IEEE 1666TM-2005 [?], sont bien sûr connus au niveau du langage SIGNAL, et il existe donc une correspondance entre leur utilisation et une famille d’opérateurs synchrones du noyau de base de SIGNAL.

La transformation d’un type complexe comme le type entier en un type élémentaire impose une transposition de toutes les fonctions et de tous les opérateurs associés à ce type. Les opérateurs

complexes tels que les opérateurs arithmétiques peuvent être représentés différemment suivant les propriétés à prouver au niveau formel. Cependant, la tâche de la compilation n’est pas de choisir une représentation précise pour ces opérateurs et ces fonctions, mais beaucoup plus de préserver l’équivalence sémantiques de ces opérateurs.

La compilation doit simplement préserver toutes les informations qui sont susceptibles d’être utilisées par la phase de génération et donc en particulier, elle ne doit pas chercher à expanser les opérateurs et les fonctions standards.

7.4.3 Transformation des blocs SSA

Il existe trois types de blocs en SSA : les blocs de base (BASIC BLOCKS), les blocs de test (TEST BLOCKS) et les blocs de branchement (JOINT BLOCKS). Chacun de ces blocs contient une instruction élémentaire, chaque variable contenue dans les blocs de base et de branchement contient exactement une seule expression d’affectation. Il est donc possible d’exécuter toutes les instruc-tions élémentaires ainsi que les expressions conditionnelles par un signal de condition booléenne (figure ??) et l’instruction de ce bloc est par la suite sélectionnée pour être exécutée uniquement dans le cas où ce signal est présent et sa valeur est vraie.

XN+1 = φ(X1, X2, …XN)

X2 = <Expression_2> XN = <Expression_N> X1 = <Expression_1>

Bloc B1 Bloc B2 Bloc B

N XN+1 := X1 when B1 default X2 when B2 default  XN-1 when BN-1 default XN when BN Bloc Jk <Expression> Boolean Bk Bloc BK

FIGURE 7.7 – Encodage des blocs de base SSA en SIGNAL

7.4.4 Transformation de la fonction PHI

Convertir du code ordinaire dans une représentation SSA est essentiellement un problème simple. Il suffit de remplacer chaque assignation d’une variable par une nouvelle variable "ver-sionnée" (la variable x se décompose en x1, x2, x3 . . . lors des assignations successives). Une fonction PHI du bloc de branchement (jointure) Jkdans SSA fonctionne comme un multiplexeur, elle sélectionne la bonne valeur (versions des variables) parmi ses entrées et la retourne sans la modifier (voir figure ??). La sélection dépend du chemin suivi dans le graphe du programme au moment du calcul de la fonction.

En langage SIGNAL, cette fonction est représentée par une équation d’échantillonnage. La figure ?? montre comment coder l’expression du bloc jk en SIGNAL.

7.4.5 Transformation des expressions conditionnelles

Pour chaque bloc de test SSA, une instruction de branchement conditionnelle est associée. Par exemple, l’exécution des deux successeurs (les blocs Bj et Bk) du bloc de test Tm dépend de la

7.4 Phase d’extraction comportementale 103

XN+1 = φ(X1, X2, …XN)

X2 = <Expression_2> XN = <Expression_N> X1 = <Expression_1>

Bloc B1 Bloc B2 Bloc B

N XN+1 := X1 when B1 default X2 when B2 default  XN-1 when BN-1 default XN when BN Bloc Jk

FIGURE 7.8 – Encodage de la fonction φ en SIGNAL valeur de sa condition (voir figure ??).

Modèle TLM (SystemC) Software (C/C++) Testbench (SystemC) Modèle RTL (HDL / SystemC) Synthèse Modèle Portes Soc

IF(Y1>X1) GOTO Bi ELSE GOTO Bj X1 = … <Expression_2> <Expression_1> Bloc B1 Bloc B2 Bloc BK Bloc Tm

Bi := true when (Y1>X1) default false

Bj := true when not( Y1>X1) default false

FIGURE7.9 – Encodage d’expressions conditionnelles en SIGNAL

7.4.6 Transformation des expressions d’affectation

Une expression d’affectation en forme SSA ne contient jamais plus de trois opérandes (à l’ex-ception des appels de fonctions) et elle a des effets secondaires implicites sur le déroulement d’exé-cution [?]. Les équations d’affectation des signaux en langages SIGNAL, ont la même forme que celle des expressions d’affectation de la forme SSA, ce qui rend facile le processus de passage SSA vers SIGNAL(voir figure ??) sur le plan sémantique [?].

XN+1 = φ(X1, X2, …XN)

X2 = <Expression_2> XN = <Expression_N> X1 = <Expression_1>

Bloc B1 Bloc B2 Bloc BN

XN+1 := X1 when B1 default X2 when B2 default  XN-1 when BN-1 default XN when BN Bloc Jk <….> Boolean Bk Bloc BK Xk = <Expression> Boolean Bk Xk := <Expression> when Bk Bloc BK

FIGURE7.10 – Encodage d’expressions d’affectation en SIGNAL

en SIGNAL par un signal booléen qui correspond au bloc de la forme SSA après traduction, à l’exception des blocs de jointure.

7.4.7 Transformation des boucles

La figure ?? montre un exemple de boucle for en SYSTEMC :

{...

for(i=1 ; i<10 ; i++) {

... } ...}

FIGURE 7.11 – Exemple de boucle for

Dans le graphe (voire figure ??) représentant la forme SSA de la boucle de la figure ??, le bloc Bj est défini avant l’expression conditionelle (i2 < 10), et son exécution dépend de la valeur de l’expression conditionnelle.

IF(i2 < 10) GOTO Bj ELSE GOTO Bk i1 = <Expression_2> Bloc B1 Bloc BK Bloc T i3 := i2$ +1 when Bj

Bj := true when (i2$ < 10) when pre_Bj default false

Bk := true when (i2 < 10) when Bj default false

where,

pre_Bj := Bj$ init true

i2= φ(i1, i3)

Bloc J

i3= i2 + 1

Bloc Bj

FIGURE7.12 – Encodage des boucles en SIGNAL

7.4.8 Transformation des modules

Un module est l’élément de base de la conception SYSTEMC, qui contient des ports, des constructeurs, des données membres, des fonctions membres ainsi que des variables et des fonc-tions locales. Un module SYSTEMC modélise un processus logiciel ou un composant matériel. La figure ?? montre un exemple d’un module SYSTEMC.

FIGURE7.13 – Exemple d’un module SYSTEMC

1#include "systemc.h"

3SC_MODULE(module_example)

{

5 sc_in<int> input1;

sc_in<int> input2;

7 sc_in<bool> select;

sc_out<int> output;

9

void module_process()

11 {

output = input1 + input2;

13 }

15 SC_CTOR(module_example) //constructor

{

17 SC_METHOD(module_process);

Sensitive << select ;

19 };

};

La transformation du code SYSTEMC de la figure ?? donne le code SIGNALsuivant :

process module_example =

2 ( ? integer input1, input2 ;

? Boolean select ;

4 ! integer output ;

)

6 (

| output := input1 + input2 when B1

8 | B1 := true when select default false

)

10 where Boolean B1;

end

L’idée consiste à remplacer le processus constructeur de module, dont la liste de sensibilité contient dans cet exemple le signal select, par un nouveau processus SIGNAL qui s’active sur la présence du signal booléen associé au bloc Bk.

Afin de résoudre le problème posé par le compilateur SIGNALpour le calcul d’horloges, Kalla et Talpin [?] ont proposé une solution basée sur la synchronisation globale de toutes les variables et les processus C++. Cependant, l’inconvénient majeur de cette solution est que le

comporte-ment SYSTEMC est totalement différent de celui des processus SIGNALgénérés. Ce qui implique un passage d’une sémantique d’exécution multi-horloge (SYSTEMC) vers une sémantique d’exé-cution séquentielle mono-horloge (SIGNAL). Nous proposons une solution originale basée sur les processus et les modules SYSTEMC, ce qui permet l’identification des relations de synchronisation entre les évènements des modules SYSTEMC et donc de synchroniser uniquement les évènements dépendants de chaque module. Elle détermine un ordre partiel entre les Blocks SSA d’un module sous la forme d’un arbre.