=====Equivalences===== MAE: machine à états pour compiler la doc sudo apt-get install xml-twig-tools le mieux est d'utiliser le parser java comme ca pas de dépendances supplémentaires. -> appelle le même executable jar mais en lui donnant le nom du fichier txt.... sans même parser, il suffit d'analyser le fichier et quand on tombe sur un < génération des noms des fichiers a partir du nom lu depuis le txt autoriser des commentaires des liens inter et intra doc =====Documentation de FsmProcess===== FsmProcess est un utils pour la modélisation et l'implémentation simultanée des machines à états évoluées. A partir d'une description textuelle d'un modèle de MAE, cet outils génère: -code VHDL (composant, package, code d'instantiation etc...) -code DOT pour la visualisation -code C pour le test -à terme Verilog ou ce que l'on veut. Donner un exemple simple de .fsm ====Organisation de la documentation==== Présentation des éléments du langage de manière progressive. ====Description de l'outils==== Outils écrit en Java pour portabilité. Executable sur n'importe quelle machine équipée d'une machine virtuelle Java >...? Pourquoi un nouvel outil? FsmProcess a été créé dans le but de répondre au besoin de développer et utiliser des composants ayant un comportement de type machine à état (plus quelques subtilités supplémentaires détaillées plus loin). Un outils pour traiter des modèles décrit dans un language adapté au modèle: language FSM compact et souple correspondant directement au modèle. Inspiré de la syntaxe de dot possibilité de générer le code du composant implémentant le modèle mais également le code permettant d'inclure ce composant (package en VHDL, fichier header en C), le code permettant d'instancier le composant (intanciation avec port map en VHDL) et de le tester (testbench en VHDL). language relativement indépendant de la cible (FPGA, uP...) Permet de se concentrer sur le modèle, utile en enseignement. Coût des itérations sur le modèle réduit car il n'y a pas besoin de modifier l'implémentation. Erreurs modelisation <-> codage . Lors des allers retours nombreuses erreurs possibles. Utile en enseignements. Mais inconvénient c'est qu'on pratique moins le langage cible (par exemple le VHDL). Permet de valider que le modèle est implémentable. Si l'on peut le décrire dans le langage FSM, et après quelques vérifications automatiques réalisée par l'outils, l'utilisateur est informé. Permet d'inférer automatiquement l'interface (ce via quoi il communique) du composant machine à état d'après la description du modèle. dessin à la main ou en WYSIWYG de machine à états, jamais la place... Ici le choix est de laisser dot positionner et router automatiquement, en le guidant pour que le graphe produit soit facilement interprétable. Des options permettent d'adapter le rendu (compacité, taille des noeuds, orientation générale etc...) possibilité de commenter le modèle (et pas le code d'implémentation), donc les commentaires s'applique à l'emplacement où ils sont définits (par exemple c'est sur cette transition que tel composant va faire cela) Possibilité de générer automatiquement la documentation sous forme d'un graphe DOT, que l'on peut inclure dans une documentation d'un projet. La documentation est ainsi générée toujours à jour par rapport au modèle. Possibilité d'intégrer le codes de differentes machines à état utilisée dans un système dans un système de build automatisée Possibilité d'utiliser des outils de gestion de version tels que SVN, CVS ou Git pour suivre l'évolution du modèle au fûr et à mesure des mises à jours. Possibilité de générer le code décrivant le modèle à partir d'un programme. Possibilité d'inclure du code du langage cible directement dans le fichier décrivant le modèle. ===Les différents fichiers générés=== .log pour les infos,etc ... vhd ... ===Nommage des fichiers d'entrée=== ne pas utiliser de majuscule dans les noms de fichier (vhdl case insensitive, donc on pourrait avoir 2 composants avec des noms de fichiers différents mais vus comme le même composant) mais surtout ghdl génère un fichier executable avec un nom uniquement en minuscule donc il faut être cohérent ===Pour rendre à Caesar ce qui lui appartient=== Outils utilisant -Ant LR pour la lecture des fichiers d'entrée (lien) -Dot de Graphviz pour la génération des graphiques (lien) inspiré de mon expérience avec les langages SHDL et MAC (...) http://diabeto.enseeiht.fr/buisson/ Utilise le modèle de A. Nketsa. référence à l'outils de Clément pour WYSIWYG: http://sourceforge.net/projects/states/ =====Le langage FSM===== voir ce qui est interdit (====Mots réservés====) instruction terminée par ; espace, retour à la ligne et tabulation sont transparents; commentaires comme en C: // pour un commentaire sur une ligne /* */ pour un bloc de commentaires, éventuellement sur plusieurs lignes ====Machine à états==== Système séquentiel synchrone utilisable pour la commande ====Utilisation Basique==== ===Commentaires=== Les commentaires sont définis comme en langage C. Il peuvent être définis sur une ligne avec // ou sur plusieurs lignes avec /* en début et */ en fin. Syntaxe: // Ceci est un commentaire Syntaxe: ceci est du code utile /* à partir d'ici c'est du commentaire fin du commentaire */ L'utilisation de commentaire est vivement conseillée et le langage FSM permet d'inclure des commentaires à des endroits significatifs du modèle, il faut donc en profiter! ===Définition des états=== Le premier état définit est l'état initial par défaut de la machine à état. Syntaxe: nom_etat; Noms valides pour un état: ==Exemples== <> //définition de 4 états pas très soigneuse 2; etat0;state1; e4; <> Bien qu'étant correcte, ce code n'est pas très lisible, la version suivante sera donc préférée: <> //définition de 3 états etat_0; //dans cet état, le système fait... etat_1; //dans cet état, le système fait... etat_2; //dans cet état, le système fait... <> Pour que le modèle de cette MAE puisse être implémenté, il faudra utiliser l'option>> car le modèle ne répond pas à différentes contraintes détaillées dans ===Contraintes sur le modèle===, notament il ne décrit aucune sorties et les états etat_1 et etat_2 sont orphelins, le système n'ayant aucun moyen d'arriver dans ces états. Deux états différents ne peuvent bien sûr pas avoir le même nom, et dans la description suivante, un seul état etat_1 est donc créé. <> //définition de 3 états avec un état décrit deux fois etat_0; //dans cet état, le système fait... etat_1; //dans cet état, le système fait... etat_2; //dans cet état, le système fait... etat_1; //dans cet état, le système fait aussi... <> La taille des cercles représentant les états s'adapte au nom d'état le plus long. ===Définition des transitions entre états=== La définition de transition entre états se fait de la manière suivante: Syntaxe: nom_etat_initial -> nom_etat_destination; <> //définition de 3 transitions etat_0; //dans cet état, le système fait... etat_1; //dans cet état, le système fait... etat_2; //dans cet état, le système fait... etat_0->etat_1; etat_1->etat_2; etat_2->etat_1; <> Il est possible de décrire des transitions utilisant des états avant que ceux ci ne soit eux même définit, voir même sans définir les états si le modèle ne nécessite pas d'action sur ces états. Ainsi le modèle suivant est valide: <> //définition de 3 transitions etat_1->etat_2; etat_0->etat_1; etat_2; //dans cet état, le système fait... etat_2->etat_0; <> On pourra noter dans cet exemple que le premier état rencontré dans la lecture du code est l'état etat_1 apparaissant dans la première transition, et c'est donc lui qui sera l'état initial par défaut de la machine à état. ===Définition des conditions de transition=== La définition d'une condition pour une transition est optionnelle est se fait ainsi: Syntaxe: nom_etat_initial -> nom_etat_destination?condition; condition valide= combinaison d'entrées et d'opérateurs les entrées sont automatiquement détectées. <> //définition de 3 transitions etat_1->etat_2?IN1; etat_0->etat_1?NOT IN1; etat_2; //dans cet état, le système fait... etat_2->etat_0?IN2; <> Les conditions de sorties d'un état doivent être mutuellement exclusives Le modèle suivant est donc ambigue: dans l'état 1, que se passe-t il si IN1 et IN2 sont tous les deux vrais? <> etat_1->etat_2?IN1; etat_1->etat_0?IN2; etat_0->etat_1?NOT IN1; etat_2; etat_2->etat_0?IN2; <> Pour pallier à ce problème, il est possible de rendre non ambigu à la main le modèle, en ajoutant une priorité. Si l'on souhaite rendre la transition de etat_1 vers etat_2 plus prioritaire, il suffit d'inhiber la transition de etat_1 vers etat_0 de la façon suivante: <> etat_1->etat_2?IN1; //cette transition depuis l'état 1 est plus prioritaire etat_1->etat_0?IN2 AND NOT IN1; //que celle-ci etat_0->etat_1?NOT IN1; etat_2; //dans cet état, le système fait... etat_2->etat_0?IN2; <> === Priorités entre transitions=== Ce mécanisme est automatisé par l'outils grâce à la syntaxe suivante, Syntaxe: nom_etat_initial -> nom_etat_destination*priorite?condition; Un niveau de priorité est un entier non signé. Une valeur faible est plus prioritaire qu'une valeur forte. Dans le cas ou la valeur de priorité n'est pas spécifiée, elle vaut 1000 par défaut. La définition de la priorité permet d'alléger la description du modèle. Ainsi, ce modèle aura le même comportement que le modèle précédent: <> etat_1->etat_2*1?IN1; //cette transition depuis l'état 1 est plus prioritaire (niveau 1) etat_1->etat_0*2?IN2; //que celle-ci (niveau 2) etat_0->etat_1?NOT IN1; etat_2; etat_2->etat_0?IN2; <> ===Définition des actions=== ===Actions sur état=== ==Actions non memorisées== actions non mémorisées et non conditionnées syntaxe :NOM_ACTION permet d'indiquer que dans un état une action est active (valeur 1 par défaut) Une action non mémorisée est inactive partout ou elle n'est pas définie comme étant active. Plusieurs actions peuvent être effectuées sur un même état en les séparant par : <> //définition de 3 états et des actions correspondantes etat_0:ACTION_1; //dans cet état, ACTION_1 est active etat_1; //dans cet état, rien etat_2:ACTION_2:ACTION_1; //dans cet état, ACTION_1 et ACTION_2 sont actives etat_0->etat_1; etat_1->etat_2; etat_2->etat_0; <> ==actions conditionnées== syntaxe :NOM_ACTION=CONDITION permet d'indiquer que dans un état une action est active (valeur 1 par défaut) si la condition est vérifiée <> //définition de 3 états et des actions correspondantes etat_0:ACTION_1=ENTREE_1 AND ENTREE_2; //dans cet état, ACTION_1 est active si (ENTREE_1 AND ENTREE_2)=1. ACTION_2 est inactive. etat_1; //dans cet état, rien: ACTION_1 et ACTION_2 sont inactives etat_2:ACTION_2=ENTREE2:I,ACTION_1; //dans cet état, ACTION_2 recopie ENTREE2 et ACTION_1 est active. etat_0->etat_1; etat_1->etat_2; etat_2->etat_0; <> Pour bien différencier les actions non mémorisées des actions mémorisées présentées dans la suite, utilisation d'un I (optionnel) devant le nom de l'action, suivi d'une virgule: syntaxe :I,NOM_ACTION=CONDITION ==Actions mémorisées== Action pouvant être mise à 1 (SET), à 0 (RESET), ou à la valeur d'une expression (MEMORISATION) Reset inconditionnel d'une action mémorisée: syntaxe :R,NOM_ACTION Reset conditionné d'une action mémorisée: syntaxe :R,NOM_ACTION=CONDITION Set inconditionnel d'une action mémorisée: syntaxe :S,NOM_ACTION Set conditionné d'une action mémorisée: syntaxe :S,NOM_ACTION=CONDITION Mémorisation d'une action mémorisée: syntaxe :M,NOM_ACTION=EXPRESSION_A_MEMORISER Il est bien sûr possible d'intégrer des actions mémorisées et des actions non mémorisées dans la même machine à état, mais une action doit toujours être utilisée de la même manière (soit mémorisée soit non mémorisée). <> etat_0:R_ACTION_1=ENTREE_1 AND ENTREE_2; // ACTION_1 mis à 0 si (ENTREE_1 AND ENTREE_2)==1 etat_1:M,ACTION_2=ENTREE3 OR ENTREE4; // ACTION_2 mémorise la valeur de (ENTREE3 OR ENTREE4) etat_2:ACTION_NON_MEMORISEE=ENTREE2:S,ACTION_1; // ACTION_NON_MEMORISEE recopie la valeur de l'entrée 2 et vaudra 0 hors de cet état // ACTION_1 est mis à 1 etat_3:R,ACTION_1=ENTREE_1; // ACTION_1 est mis à 0 si ENTREE_1==1 etat_4; // rien... les actions mémorisées ne change pas et les actions non mémorisée sont à 0 par défaut etat_5:S,ACTION_1=ENTREE2:R,ACTION_2=ENTREE_2; // ACTION_1 est mis à 1 si ENTREE_2==1 // ACTION_2 est mis à 0 si ENTREE_2==1 etat_0->etat_1; etat_1->etat_2; etat_2->etat_3; etat_3->etat_4; etat_4->etat_5; etat_5->etat_0; <> La valeur par défaut au démarrage d'une action mémorisée est 0 mais celle-ci peut être réglée par un état transitoire d'initialisation ou reset synchrone ou asynchrone (décrits plus loin). ===Actions sur transition=== Les différentes actions peuvent aussi être effectuées sur transition, ainsi le modèle précédent peut être complété: <> etat_0; etat_1:M,ACTION_2=ENTREE3 OR ENTREE4; // ACTION_2 mémorise la valeur de (ENTREE3 OR ENTREE4) etat_2:ACTION_NON_MEMORISEE=ENTREE2:S,ACTION_1; // ACTION_NON_MEMORISEE recopie la valeur de l'entrée 2 et vaudra 0 hors de cet etat_3:R,ACTION_1=ENTREE_1; // ACTION_1 est mis à 0 si ENTREE_1==1 etat_4; // rien... les actions mémorisées ne change pas et les actions non mémorisée sont à 0 par défaut etat_5; etat_0->etat_1; //transition inconditionnelle etat_1->etat_2?IN2 AND NOT IN1:R_ACTION_1=ENTREE_1 AND ENTREE_2; //transition si (IN2 AND NOT IN1)==1, alors ACTION_1 mis à 0 si (ENTREE_1 AND ENTREE_2)==1 etat_2->etat_3; etat_3->etat_4:S,ACTION_1=ENTREE2; // ACTION_1 est mis à 1 si ENTREE_2==1; etat_4->etat_5; etat_5->etat_0; <> ===NOTABENE sur les actions=== Mauvaise façon de faire: action sur transition -> warning <> 1->1?INPUT:OUTPUT; <> Bonne facon <> 1:OUTPUT=INPUT; <> ====Utilisation Avancée==== ==Remise à zéro synchrone ou transition indifférenciée== Cette fonctionnalité permet d'imposer l'activation d'un certain état sans condition sur l'état précédemment actif de la machine à état. La présence d'un condition est obligatoire pour une telle transition, elle peut être basée sur une entrée ou une expression logique d'entrées syntaxe : -> nom_etat_destination?condition; Il est bien sûr possible d'attacher des actions sur une telle transition: syntaxe : -> nom_etat_destination?condition: ACTION; Il peut y avoir plusieurs de ces transitions, éventuellement vers un même état. Dans le cas de plusieurs de ces transitions vers un même état, la priorité peut être définie comme pour les transitions standard. Ceci peut être mis à profit pour effectuer des actions différentes en fonction de différentes conditions. syntaxe : -> nom_etat_destination*priorite?condition: ACTION; <> //définition de 3 états et des actions correspondantes etat_0; etat_1; etat_2; etat_0->etat_1; etat_1->etat_2; etat_2->etat_3; ->etat_0?SRESET_1; //Retour à etat_0 dès lors que SRESET_1 est active, pas d'action ->etat_2*1?SRESET_2 XNOR ENTREE_1:ACTION_1; //Retour à etat_2 dès lors que SRESET2=ENTREE_1, en réalisant l'action ACTION_1 ->etat_2*2?SRESET_3:M,ACTION_2=ENTREE_2; //Retour à etat_2 dès lors que SRESET3, en mémorisant sur l'action ACTION_2 la valeur de ENTREE_2 UNIQUEMENT SI SRESET2 différent de ENTREE_1 <> Attention, impact potentiellement important sur la synthèse: kdiff3 multiplier32bits.fsm multiplier32bitsnosreset.fsm kdiff3 multiplier32bits_ise_synthesis.txt multiplier32bitsnosreset_ise_synthesis.txt ==Notion de priorité sur les transitions standard== Les transitions indifférenciées sont TOUJOURS plus prioritaire que les transitions standard (même si des niveaux de priorités indiquant le contraires sont spécifiés dans le modèle, raison pour laquelle les couleurs utilisées pour indiquer les niveaux de priorité sont différentes). Donc non seulement, à inhibe les actions sur état et sur transition quand la condition de reset est valide A CLARIFIER!!!!!! <> 0:TOTO=TATA; 0->1?COND:TOTO=TITI; ->0?CONDRESET:TOTO=TUTU; <> que faire, dans ce cas la: <> 0:M,TOTO=TATA; 0->1?COND:S,TOTO=TITI; ->0?CONDRESET:R,TOTO=TUTU; <> idéalement inhiber le M de toto dans l'état 0 si on fait le S de TOTO sur la transition de 0 à 1, mais pas encore géré ===Réinitialisation asynchrone=== Par défaut, l'entrée de réinitialisation asynchrone est ARAZB active à 0. L'état initial par défaut de la machine à état peut être redefinit ainsi:. Syntaxe: =>etat?ENTREE,VAL; avec ENTREE le nom d'une entrée et VAL la valeur de l'entrée pour déclencher la remise à 0 asynchrone (ne pas utiliser d'expression complexe mais uniquement 0 ou 1). Il doit n'y avoir qu'une seule condition de réinitialisation asynchrone vers un unique état. Il est possible de définir la valeur des sorties mémorisées lors d'une réinitialisation asynchrone en utilisant la syntaxe suivante Syntaxe: =>etat?ENTREE,VAL: NOM_SORTIE1=VAL_1...; <> etat_0; etat_1; etat_2; etat_0->etat_1; etat_1->etat_2; etat_2->etat_0; =>etat_1?CLR,1: sortie4=1:sortie1=IN3; //redéfinit l'entree de réinitialisation asynchrone à CLR, active à 1, qui ramène la machine à état dans l'état_1 //sortie4 prend la valeur 1 lors de la réinitialisation asynchrone //sortie1 prend la valeur de l'entrée IN3 lors de la réinitialisation asynchrone (peut poser problème sur certaines architecture de FPGA, vérifier le résultat de la synthèse) <> ===Redéfinition de l'horloge=== Le nom du signal d'horloge utilisé pour cadencer la machine à états peut être redéfini avec la syntaxe Syntaxe: /NOM_SIGNAL; <> etat_0->etat_1; /HORLOGE; //redéfinit le nom du signal d'horloge à HORLOGE <> Si l'on souhaite horloge active sur front descendant sur FPGA, il faudra connecter l'entrée d'horloge du composant machine à état à un signal déphasé de 180° issus d'un bloc générateur d'horloge. Ce paramètre n'est donc pas pris en compte dans le modèle de machine à état lui même. ===Actions toujours vraies=== Il est possible en plus des actions sur état et sur transition de définir des actions toujours vraies Syntaxe: %ACTION...; attention si action également utilisé dans des états ou des conditions TODO: non il y a un probleme avec la sortie 7/// <> etat_0; %I,sortie7=entree2; // sortie7 active si entree2 vrai etat_1: sortie7; // mais sortie 7 active aussi dans etat_1 sans avoir besoin d'entree2 etat_2; etat_0->etat_1; etat_1->etat_2: R, sortie8; // mise à 0 de sortie8 sur cette transition etat_2->etat_3; %I,sortie6; // sortie6 active toujours %S,sortie8=entree3; // Mise à 1 de la sortie 8 conditionnée par entree3 (voir plus bas les règles de priorité du set sur le reset) %M,sortie5=entree4; // sortie5 recopie la valeur d'entree4 en permanence (induisant un cycle d'horloge de retard) <> ===Machine à état sans état=== Il est possible de définir un modèle sans aucun état, uniquement composée d'actions toujours vraies: <> %I,sortie6; // sortie6 active toujours %I,sortie2=entree1; // sortie 2 recopie entree1 %S,sortie5=entree2; // Mise à 1 de la sortie 5 conditionnée par entree2 (voir plus bas les règles de priorité du set sur le reset) %R,sortie5=entree3; // Sinon mise à 0 de la sortie 5 conditionnée par entree3 (voir plus bas les règles de priorité du set sur la mémorisation) %M,sortie5=entree4; // Sinon mémorisation de la valeur de entree4 sur la sortie 5 <> ===Sortie STATE_NUMBER=== Une sortie STATE_NUMBER est automatiquement générée afin de permettre le débogage de la machine à état. Cette sortie reflette à chaque instant l'état courant de la machine à état. La sortie est représentée sur une taille de bus adaptée au codage en code binaire naturel des différents états (dans l'ordre alphanumérique de leurs noms) TODO: définir une taille de bus fixe ===Ordre de priorités pour les actions=== priority= regularly > reset transition > transition > state pour les actions mémorisées, ordre de priorité plus fort que le classement précédent (qui reste valide pour un même type d'opération) asychrone > set > reset > mémorisation ===Même actions dans plusieurs états=== <> (1 to 5):COMPUTE; (2 to 8):COMPUTE2=TATA: COMPUTE3=TITI; 0: RES; <> ===Multiples transitions succéssives définies simultanément=== <> #etat(2 to 6)?CONDA; #etat(6 to 2)?CONDB; #(1 to 3)?COND; #e(1 to 3)*2?CONDI; #state(8 to 2)*3?CONDI2; <> <> #(0 to 19)?CONDA; #(19 to 0)?CONDB; 5->17*3?CONDC; 2->3?CONDA:TOTO; 6:TITI; 19->0*1?RETOUR; <> ===Multiples transitions vers un même état définies simultanément=== <> #(1 to 3)->org; #(5 to 2)->org?CONDI2; #(1 to 3)->org*2?CONDI2; #state(8 to 2)->org*3?CONDI2; <> Pour voir l'intérêt, comparer filteredge2.fsm et filteredge3.fsm qui font la même chose. ===Actions sur de multiples transitions=== <> 0->1?COND:OUT1=IN1 AND IN2: OUT2; #(0 to 3)?COND:OUT1=IN1 AND IN2: OUT2; #etat(5 to 2)?COND AND COND2:OUT1=IN1 AND IN2: OUT2; #(1 to 3)->org?COND AND COND2:OUT1=IN1 AND IN2: OUT2; <> ===Spécifications via Pragma=== ==Indiquer taille du bus pour la visualisation du numéro de l'état en cours== Par défaut la taille du buspour la sortie codant le numéro de l'état en cours est réglée automatiquement mais il est possible d'imposer une valeur fixe, par exemple pour contrôler un afficheur prenant des mots de 4 bits pour afficher en hexadécimal. Ceci est réalisé à l'aide de la commande pragma: Syntaxe: #pragma_vhdl_set_bit_size_for_output_state_number{ NOMBRE_DE_BITS }#pragma avec NOMBRE_DE_BITS une valeur entre 0 et 1000 En cas de valeur trop faible pour représenter toutes les valeurs nécessaires, un warning sera généré. <> 2->3:OUT1; 3->1?OUT2; 1->2:OUT3; #pragma_vhdl_set_bit_size_for_output_state_number{ 8 }#pragma <> ==Promotion automatique d'une sortie en buffer== Il est possible d'autoriser globalement le fait que dès qu'un terme apparaît en tant qu'entrée et sortie, il puisse être automatiquement combiné en une sortie dite bufferisée, dont la valeur peut être réutilisée en interne. Ce mécanisme permet par exemple d'autoriser l'utilisation de sorties dans les conditions. L'autorisation se fait à l'aide de la commande pragma: #pragma_vhdl_allow_automatic_buffering Seulement Les sorties mémorisées peuvent être promue de la sorte. <> 2->3:S,BUFFER1=ENTREE2; 3->1?BUFFER1 :OUT2; 1->2:R,BUFFER1=ENTREE1; #pragma_vhdl_allow_automatic_buffering <> Ceci peut être utilisé pour simplifier un modèle en mémorisant un évenement. Ainsi le modèle suivant évoluant en fonction des entrees ENTREE1 et ENTREE2: <> 1:S,BUFFER1=ENTREE2; 1->2?ENTREE1; 2->3?BUFFER1; 2->1?NOT BUFFER1; #pragma_vhdl_allow_automatic_buffering <> Il est possible d'utiliser ce mécanisme pour décrire des comportements plus complexes. Dans cet exemple, la transition des états 2 à 3 se base sur une condition dépendant de la valeur de BUFFER 1 avant la mémorisation de la valeur de BUFFER1 XOR ENTREE3: <> 1:S,BUFFER1=ENTREE2; 1->2?ENTREE1: R,BUFFER1=ENTREE4; 2->3?BUFFER1; 2->1?NOT BUFFER1; 2:M,BUFFER1=BUFFER1 XOR ENTREE3; #pragma_vhdl_allow_automatic_buffering <> ==Promotion manuelle d'une sortie en buffer== ordre: le pragma doit être fait après que l'entrée ou la sortie ait été utilisée par le modèle. <> 1 :OUT2; #pragma_vhdl_promote_to_buffer{ OUT2 , OUT3}#pragma //the OUT3 won't be demoted because the signal has not yet been defined in the model 2 : OUT3; 1->2; <> ==Destitution manuelle d'une sortie ou d'une entrée en signal interne== ordre: le pragma doit être fait après que l'entrée ou la sortie ait été utilisée par le modèle. <> 1 :OUT2:OUT4; #pragma_vhdl_demote_to_signal{ OUT4,OUT3}#pragma //the OUT3 won't be demoted because the signal has not yet been defined in the model 2 : OUT3; 1->2?IN1; #pragma_vhdl_demote_to_signal{ IN1}#pragma <> ===Inclusions de code via Pragma=== à l'intérieur des balises, on peut utiliser les mots réservés <> 0:encpt; #pragma_vhdl_pre_entity{ -- this a a pragma inserted before entity -- for instance to add libraries -- //comments inside pragma are inserted in the vhdl file without modifications -- void function() -- { -- tata=3; -- } }#pragma // this a a pragma inserted inside entity // for instance to add inputs /outputs // do no insert comments inside this pragmas #pragma_vhdl_entity{ A : in std_logic; added_output: out std_logic; }#pragma #pragma_vhdl_architecture_pre_begin{ -- this a a pragma inserted inside architecture before the begin statement -- for instance to declare signals or types signal signal_added_output: std_logic; }#pragma #pragma_vhdl_architecture_post_begin{ -- this a a pragma inserted inside architecture after the begin statement -- for instance to do anything signal_added_output <= '1'; added_output<=signal_added_output; }#pragma //add some signal for the simulation #pragma_vhdl_testbench_pre_begin{ signal A : std_logic_vector ( 64-1 downto 0 ) ; }#pragma #pragma_vhdl_init_testbench{ SRESET<='0'; DATA<=x"12345678"; --value to receive E_prediv<="00001001"; IR<='1'; }#pragma #pragma_vhdl_testbench{ -- code ajouté pour le testbench: --------------------------------------- wait until (ck'event and ck='0' ); BaudRATE_SELECTOR<="00"; D<="01010101"; WRB<='1'; wait for ck_period; WRB<='0'; wait for ck_period*20; --------------------------------------- wait until (ck'event and ck='0' ); BaudRATE_SELECTOR<="01"; D<="01010101"; WRB<='1'; wait for ck_period; WRB<='0'; wait for ck_period*40; --------------------------------------- wait until (ck'event and ck='0' ); BaudRATE_SELECTOR<="10"; D<="11100101"; WRB<='1'; wait for ck_period; WRB<='0'; wait for ck_period*80; --------------------------------------- }#pragma <> ===Gestion des composants génériques=== <> #pragma_vhdl_generic_directive{ par1:integer:=3; par2:integer:=9; m:positive:=7; o:natural:=7; r:real:=-4.23; }#pragma #pragma_vhdl_generic_directive{ n:integer:=2;}#pragma #pragma_vhdl_generic_directive{ m:integer:=3; G:integer:=10; F:integer:=5; }#pragma #pragma_vhdl_entity{ A : in std_logic_vector(N - 1 downto G- 4);}#pragma #pragma_vhdl_entity{ B : in std_logic_vector(N -1 downto M+2);}#pragma #pragma_vhdl_entity{ C : in std_logic_vector(N +1 downto F-1);}#pragma #pragma_vhdl_entity{ D : in std_logic_vector(N + 1 downto 0);}#pragma #pragma_vhdl_entity{ G : in std_logic_vector(3 downto M-2);}#pragma #pragma_vhdl_entity{ H : in std_logic_vector( 0 to M+12);}#pragma <> ===Gestion des bus=== TODO.... pas encore de gestion des sorties définies par pragmas dans le modèle. On peut indiquer pour l'affichage mais il n'y aura pas de code généré, il faut le faire à la main avec un autre pragma <> //définition des E/S et du code associé, doit être fait avant la définition du modèle pour que les E/S ne soient pas traitées par le modèle #pragma_vhdl_generic_directive{ n:integer:=4; }#pragma #pragma_vhdl_entity{ A : in std_logic_vector(N - 1 downto 0);}#pragma #pragma_vhdl_entity{ B : in std_logic_vector(N - 1 downto 0);}#pragma #pragma_vhdl_entity{ C : out std_logic_vector(N - 1 downto 0);}#pragma //définition du modèle 0:C=A; 1:C=B; 0->1?EN; 1->0?EN; //définition de l'affectation #pragma_vhdl_architecture_post_begin{ C<=A when (current_state=state_0) else B when (current_state=state_1) else (others=>'0'); }#pragma <> ===Casse=== <> 1 :i,OUT2:OUT4; 2 : OUT3:S,OUT5:r,out6= in1 anD totO2 XnOR TATA; 1->2?IN1; <> ===Composants génériques=== expliquer diff par rapport à param generic en vhdl dire qu'un parametre peut être définit soit dans le fichier #pragma_fsm_generic{N=1;}#pragma soit dans la ligne de commande -g n=1 insensible à la casse uniquement des valeurs d'entier opérateurs + - * / % log(x,y) calculs intermédiaires fait sur des entiers 64 bits comportement préprocesseur: affectation et remplacement par évaluation. visualisation du fichier en sortie du post_preprocesseur dans la gui +génération de fichier .fsm en sortie en fonction des paramètres (triés par nom) LES #pragma_fsm_generic{ ne peuvent pas être commentés. Si il contient affectation, elle est effective. Si il contient une valeur à remplacer, c'est cette valeur effective qui apparaitra en commentaire Bon exemple filteredge_generic.fsm en N= 4 ou 8 filteredge_generic_N_4.fsm et filteredge_generic_N_8.fsm <> #(1 to #pragma_fsm_generic{M=(N%7)+1;M+1}#pragma); (1 to #pragma_fsm_generic{3*M+1}#pragma):COMPUTE; #pragma_fsm_generic{N}#pragma:RESULT_AVAILABLE; #pragma_vhdl_entity{ C : out std_logic_vector(#pragma_fsm_generic{M*2}#pragma - 1 downto 0);}#pragma <> Pour débugger, utiliser un nom d'état par exemple pour afficher le résultat. Ici calcul du nombre de digits en base 10 pour afficher N bits. Ici il faut 10 digits pour afficher un entier sur 32 bits: <> #pragma_fsm_generic{ N=32;log(2^N,10)+1 }#pragma ; --état vide juste pour l'affichage <> ===Directives pour inclure des fichiers=== supporte plusieurs degrés d'inclusions (un fichier qui inclue plusieurs autres fichiers, eux même incluant plusieurs fichiers etc...) dans le cas où un fichier a déjà été inclus, pour éviter un nouvelle inclusion, l'ordre d'inclusion est ignoré (warning) //option en ligne de commande pour indiquer des dossiers d'inclusion //TODO: faire bon exemple et gérer le dossier de la doc pour que le fichier inclus soit trouvé lors de la compilation de la doc peut être utiliser pour ajouter des instructions de testbenches différentes peut être utiliser pour préciser la valeur de fsm_generics ce qu'on veut.... <> #pragma_include{ex_transition_priority1.fsm}#pragma #pragma_vhdl_testbench{ --------------------------------------- A<=(others=>'0'); B<=(others=>'0'); for i in 0 to 1000 loop for j in 0 to 10 loop wait until (ck'event and ck='0' ); START<='1'; wait for ck_period; START<='0'; wait for ck_period*40; B<=B+1; END LOOP; A<=A+1; B<=(others=>'0'); END LOOP; --------------------------------------- }#pragma <> ===Directives pour configurer le rendu=== valeurs par défaut: rankdir=LR; ranksep=0.5; // separation between different ranks nodesep=0.1; // separation between nodes in same rank (state and corresponding action) between 3 and 0.1 <> 1 :i,OUT2:OUT4; 2 : OUT3:S,OUT5:r,out6= in1 anD totO2 XnOR TATA; 1->2?IN1; #pragma_dot_global_directive{ rankdir=TB; ranksep=0.009; nodesep=0.01; ranksep=equally; }#pragma <> ===Génération de modèle par programme=== ====Exemples d'applications==== tiré de exam_AS: <> 0:encpt; 2:encpt:udcpt; 0->1?entree1; 1->0?entree2; 1->2?not entree2:sloadcpt:ecpt3:ecpt2:ecpt1:ecpt0; 2->0?(NOT QCPT3) AND (NOT QCPT2) AND (NOT QCPT1) AND (NOT QCPT0):FIN; <> <> 0:encpt; 2:encpt:udcpt; 0->1?entree1; 1->0?entree2; 1->2?not entree2:sloadcpt:ECPT_EGAL_F; 2->0?QCPT_EGAL_0:FIN; #pragma_vhdl_entity{ QCPT, ECPT: buffer std_logic_vector (3 downto 0); }#pragma #pragma_vhdl_allow_automatic_buffering #pragma_vhdl_demote_to_signal{sloadcpt,encpt,udcpt,ECPT_EGAL_F,QCPT_EGAL_0}#pragma #pragma_vhdl_architecture_post_begin{ process(ck, arazb) begin if arazb = '0' then QCPT<=(others=>'0'); elsif ck'event and ck = '1' then if (sloadcpt='1') then QCPT<=ECPT; elsif (encpt='1') then if (udcpt='1') then QCPT<=QCPT-1; else QCPT<=QCPT+1; end if; end if; end if; end process ; ECPT <="1111" when ECPT_EGAL_F='1' else "0000"; QCPT_EGAL_0<='1' when QCPT="0000" else '0'; }#pragma #pragma_vhdl_testbench{ --------------------------------------- wait until (ck'event and ck='0' ); entree1<='0'; entree2<='0'; wait for ck_period*20; entree1<='1'; entree2<='1'; wait for ck_period*5; entree2<='0'; wait for ck_period*5; entree1<='1'; entree2<='1'; wait for ck_period*30; --------------------------------------- }#pragma <> ====Mots réservés==== récupérer des listes dans le fichier FsmProcesss.java.... ====Les messages Info, Warning et Error==== ===Contraintes sur le modèle=== récupérer de toutes les vérifications que je fais dans le code. ====génération des différents fichiers==== ====Paramètres de l'exécutable==== System.out.println("usage: java -jar FsmProcess.jar -i -c -d -r -f fichier.fsm"); System.out.println(" -i: ignore error in the model and try to continue"); System.out.println(" -c: create output gif image file from the dot file"); System.out.println(" -f filename.fsm: provide the input file name to process"); System.out.println(" -g fsm_generic_parameter=value: provide generic parameter values"); System.out .println(" -r: realtime process, regenerate the files when the input file content changes and display the output gif image"); -i : ignore les erreurs critiques liées à la compilation du modèle et continue la génération des fichiers -f nom_fichier : indique le nom du fichier d'entrée -d -c -g fsm_generic_parameter=value TODO: choix compacité du graphe ->pragma dot TODO: choix des simplifications de modele par le checker =====vrac===== ===utilisation des sorties mémorisées comme entrées=== TODO: réalisation de registre à décalage? %M,sortie5=entree4; // sortie5 recopie la valeur d'entree4 en permanence (induisant un cycle d'horloge de retard) %M,sortie6=entree5; // sortie5 recopie la valeur d'entree4 en permanence (induisant un cycle d'horloge de retard) /// ===génération fichier vectoriel avec graphviz=== dot -Tpdf $dotfile -o $pdffile evince $pdffile & ===TODO=== Ajouter signature dans les fichiers générés +numéro de version FsmProcess + date et heure + citation du papier si utilisation