Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Mealy Lustre Produits Simple

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 7

Grenoble INP/Phelma — 2ème année SEOC — TP Lustre Mars 2024 - F.

Maraninchi

Temps réel, contraintes et implantation


TP Machines de Mealy, Lustre

1 Installation des outils

Voir git@gitlab.ensimag.fr:maraninf/trci.git.
Les exemples donnés en cours et ici sont suffisants pour le TP, mais vous avez aussi un tutoriel du
langage Lustre dans la distribution accessible ici :
https://www-verimag.imag.fr/~raymond/home/tools/lv4/

2 Premier programme Lustre

Voici un premier programme très simple :


node Counter (i : bool) returns (x : int ; y : int) ;
-- ceci est un commentaire.
let
x = (0->pre x) + (if i then 1 else 0) ;
y = (0->pre y) + (if i then 0 else 1) ;
tel.

node Toto (i : bool) returns (j : bool) ;


let
j = not i ;
tel.

▷ A faire 1 :
— Tapez ce programme dans votre éditeur préféré, nommez le fichier Counter.lus
— Pour le tester, tapez luciole Counter.lus Counter ou bien luciole Counter.lus Toto
Vous obtenez quelque part sur votre écran l’un des deux panneaux de contrôle de luciole :

Les entrées du noeud Lustre (ici boolénnes) donnent des boutons, et les sorties des affichages qui
dépendent du type. Il y a un bouton step pour faire un pas de calcul. Pour obtenir des chronogrammes,
activez l’option sim2chro gtk dans le menu Tools. Vous obtenez ça :

2023-2024 page: 1/7


Grenoble INP/Phelma — 2ème année SEOC — TP Lustre Mars 2024 - F. Maraninchi

▷ A faire 2 :
Inventer un noeud Lustre à deux entrées booléennes. Lancer luciole pour ce noeud. Comment faire
un pas en ayant fixé la valeur des deux entrées ? Dans le menu Clock, choisir compose. L’interface
change, et on peut choisir toutes les valeurs des entrées pour un pas, avant de lancer un step.
Familiarisez-vous avec ce fonctionnement.

3 Programmes Lustre pour la compréhension des modèles synchrones

3.1 Codage de machines de Mealy

▷ A faire 3 :
En utilisant le schéma de codage vu en cours, donner des nœuds Lustre N1, N2, N3 correspondant
aux automates (M1), (M2), (M3) de la figure 1.

−a
a
−a a/c AC −a
−a −a −b −b
a b BD BC
A B C D a
a/b b/c a
AD
M1 M2 −a

M3 = (M1 * M2)\ b

Figure 1: Un compteur 2 bits

2023-2024 page: 2/7


Grenoble INP/Phelma — 2ème année SEOC — TP Lustre Mars 2024 - F. Maraninchi

3.2 Parallélisme de machines et connexion flot de données

▷ A faire 4 :
— Ecrire un noeud Lustre N qui réutilise les nœuds N1, N2 précédemment écrits, et qui branche
la sortie b de N1 sur l’entrée b de N2 (cf. Figure 2-α).
— Ecrire un nouveau nœud Lustre P qui fait tourner en parallèle ce nœud N et le nœud N3 de
la question précédente, en leur donnant la même entrée, et en connectant les deux sorties à un
comparateur (cf. Figure 2-β). Que pensez-vous de la sortie de ce comparateur ?

N3 a
N
a b c
N1 N2 =
N3

α β

Figure 2: Connexion de nœuds

Indication : pour utiliser un nœud Lustre dans un autre, on peut écrire par exemple :

node Un (a, b : int) returns (c, d : bool) ;


let
c = (a=b); d = (a > b);
tel
node Deux (x, y, z : int) returns (t : int) ;
var alpha, beta : bool;
let
(alpha, beta) = Un (x+y, y+z) ;
t = 0 -> x + (if alpha then y else 0) + (if beta then z else 0) ;
tel.

4 2 Versions du double clic

4.1 Version 1 : codage direct de l’automate de Mealy

▷ A faire 5 :
— Reprenez le double clic comme vu en cours en machine de Mealy ; codez directement l’automate
du transparent 165 en Lustre ; exécutez avec Luciole.
— Vous pouvez décider de ne pas avoir d’entrée top, et donc de considérer que le temps est donné
par l’horloge de base du programme. Modifiez l’automate pour prendre en compte cette idée, recodez
en Lustre.
— Exécutez avec Luciole. Dans un menu vous trouverez la possibilité de “brancher” l’horloge de
base sur le temps “réel” de votre machine ; ça vous permet de tester le double clic en situation réelle.

2023-2024 page: 3/7


Grenoble INP/Phelma — 2ème année SEOC — TP Lustre Mars 2024 - F. Maraninchi

4.2 Version 2 : utilisation d’un noeud twostates et d’un compteur

On écrit maintenant une autre version Lustre du double clic, issue du schéma donné en cours (celle
qui utilise le noeud twostates du transparent 166). Complétez le programme ci-dessous en trouvant
les définitions correctes de reset, simple, double :

const D : int = 10 ;
-- double = 2 clicks in less than D tops=base clock
node doubleclick (button : bool) returns
(simple : bool ; double : bool) ;
var
idle, yaclick, reset : bool ;
count : int ;
let
(idle, yaclick) = twostates (button, reset) ;
count = if idle then 0 else pre(count) + 1 ;
reset = .... ;
simple = .... ;
double = .... ;
tel.

Pour débugger, on réalise le test suivant :


▷ A faire 6 :
— Ecrivez un programme Lustre qui permet d’exécuter les deux versions (codage direct de l’automate
avec horloge de base comme échelle de temps, version avec noeud twostates) sur les mêmes entrées
pour vérifier ensuite que les résultats sont toujours les mêmes.
— Utiliser ce programme de test pour trouver vos bugs éventuels dans la version 2

2023-2024 page: 4/7


Grenoble INP/Phelma — 2ème année SEOC — TP Lustre Mars 2024 - F. Maraninchi

5 Pour aller (beaucoup) plus loin : un exemple réaliste sur la détection


du sens de rotation

On étudie un mécanisme utilisé dans les souris informatiques pour déterminer un sens de rotation. Un
disque à zones noires et blanches (voir figure ci-dessous) tourne autour de son centre, et passe ainsi
devant un support fixe qui porte deux capteurs IE (internal eye) et EE (external eye). Quand le disque
tourne, ces deux capteurs voient se succéder des zones noires et des zones blanches.
Dans tout cet exercice on raisonne en synchrone, donc on suppose l’existence d’une horloge de base qui
découpe le temps en instants successifs. A chacun de ces instants, chaque capteur délivre un booléen,
vrai si la zone qui est en face du capteur à ce moment-là est noire, faux si elle est blanche (on suppose
que le capteur est suffisamment fin, et on ne considère donc pas les cas où le capteur est à cheval sur
une zone noire et une zone blanche).
On veut réaliser un programme synchrone qui reçoit en entrée les deux booléens en provenance des
capteurs, et qui émet deux booléens CK et antiCK: CK (resp. antiCK) est vrai quand on est sûr que le
cyclindre vient de tourner dans le sens horaire (resp. anti horaire).

Sens Sens
horaire anti horaire

IE

EE

Support fixe
portant les capteurs C, E

▷ A faire 7 :
— Expliquez informellement (sans écrire de programmes) comment utiliser les informations en prove-
nance des deux capteurs (valeurs et fronts montants ou descendants) pour déterminer le sens de ro-
tation. Etudiez bien tous les cas (il faut pouvoir émettre le sens de rotation le plus souvent possible)
et prêtez une attention particulière à l’état initial du système.
— Y a-t-il une contrainte à respecter entre la vitesse de rotation et la fréquence d’échantillonnage
des capteurs pour que le système fonctionne correctement ?
On donne un programme Lustre à compléter (à récupérer sur le git), qui contient :
• une partie de détection de sens de rotation (pour l’instant cela produit toujours faux pour les
sorties CK et antiCK, c’est à vous d’implémenter correctement cette partie);
• une partie de génération de valeurs produites par les capteurs IE et EE
• Des nœuds qui assemblent le générateur d’événements et vos détecteurs.

2023-2024 page: 5/7


Grenoble INP/Phelma — 2ème année SEOC — TP Lustre Mars 2024 - F. Maraninchi

-- Generating events as perceived by the EE (externaleye), and the IE


-- (internaleye), when the circle is turning. The
-- basic clock is used as the time scale.
-- Principle: each eye(IE, EE) sees a 1 half of the time, and a
-- 0 half of the time. At max speed, the pattern for 8 instants is:
-- 11 001100, or 10011001 depending on the phase. If we consider the
-- two eyes together, turning clockwise is a given superposition of
-- such patterns for the two eyes; turn anticlockwise is another. We
-- describe what happens for 4 ticks, because the
-- two halves are identical.
-- CK is the pattern $ [ <1, 0>, <1, 1>, <0, 1>, <0, 0> ] * $ for $<IE, EE> $
-- antiCK is $ [ <1, 1>, <1, 0>, <0, 0>, <0, 1> ] * $ for $<IE, EE>$

-- pattern1produces the pattern $ 1100 $


-- when count goes through $ [ 0, 4 - 1] $

node s_pattern1(count: int) returns( p: bool) ;


let p = (count mod 4) div 2 = 0 ; tel.

-- pattern2 produces the pattern $ 1001 $


-- when count goes through $ [ 0, 4 - 1] $
-- It’s a shift of pattern1
node s_pattern2 (count: int) returns( p: bool) ;
let p = s_pattern1 ( (count + 1) mod 4 ) ; tel.

node s_not_turning( inita : int) returns(IE, EE:bool) ;


let IE= false; EE= false; tel.

-- Turning anti-clockwise, the eyes see pattern1 and pattern2 superposed


node s_turning_antiCK(foo:bool ) returns( IE, EE: bool) ;
var
count : int;
let
IE = s_pattern1( count) ;
EE = s_pattern2( count) ;
count = counter(true);
tel.

-- Turning clockwise, the eyes see pattern1 and not pattern2 superposed
node s_turningCK(foo:bool ) returns( IE, EE: bool) ;
var
count : int;
let
IE = s_pattern1( count) ;
EE = not s_pattern2( count) ;
count = counter(true);
tel.

2023-2024 page: 6/7


Grenoble INP/Phelma — 2ème année SEOC — TP Lustre Mars 2024 - F. Maraninchi

------------------------------------------------------
-- Write your code here

-- formula for CK detection


node CKdetect( xIE, xEE: bool) returns( r: bool) ;
let
r= false;
-- write your code here to replace this definition
tel.

-- formula for antiCK detection


node antiCKdetect( xIE, xEE: bool) returns( r: bool) ;
let
r= false;
-- write your code here to replace this definition
tel.

--------------------------------------------------------
-- test the generator+ your detector
-- by looking at okCK or okantiCK in luciole

node counter (foo:bool) returns (cpt:int);


let
cpt = 0 -> pre(cpt)+1;
tel.

node okCK (foo:bool) returns (ok:bool);


let
ok = CKdetect (s_turningCK (foo));
tel.

node okantiCK (foo:bool) returns (ok:bool);


let
ok = antiCKdetect (s_turning_antiCK (foo));
tel.

2023-2024 page: 7/7

Vous aimerez peut-être aussi