Menu Général

Le LANGAGE VHDL et les CPLD



SOMMAIRE
Page 3 Introduction
Page 4 Logique combinatoire
Page 15 Logique séquentielle
Page 22 Graphe d’états
          Références du langage VHDL    - Le Langage VHDL
          Lexique
          Abel et VHDL en BTS elect
          Intelliflow et VIEWlogic    -     Les PLDs   - Génération image vidéo Par PLD
          ISP Lattice
          BTS-VHDL.pdf       CoursVHDL.pdf     du VHDL au composant.pdf


INTRODUCTION 

Le langage VHDL a été créé pour décrire des systèmes numérisés destinés à une implantation dans des circuits logiques programmables (PLD, FPGA, ASIC). Il remplace la saisie de schéma traditionnelle. La plupart des outils de développement autorise les 2 types de saisie.

Le langage VHDL est en principe standardisé. Chaque outil de développement dispose cependant de bibliothèques spécifiques.

Les exemples fournis dans ce cours ont été testés et simulés avec l’outil ALTERA MaxPlus+2.

Pour développer une application de logique programmable, il faudra suivre la démarche ci-dessous :
 
 

- L’étape de vérification permet de valider la syntaxe du programme. La " netlist " est un fichier contenant la description de l’application sous forme d’équations logiques.
 
 

- Lors de l’étape de simulation fonctionnelle, on valide l’application, indépendamment de l’architecture et des temps de propagation du futur circuit cible.
 
 

- L’étape de routage génère les informations permettant d’intégrer l’application dans le circuit choisi. Une " rétro annotation " est effectuée dans la " netlist " : les temps de propagation du composant cible y sont pris en compte.
 
 

- Lors de la simulation temporelle, on peut évaluer les performances de l’application générée.

LOGIQUE COMBINATOIRE







1- Un exemple simple

Le texte ci-dessous décrit un circuit nommé " ex1 ", dont le schéma est le suivant :


 
 

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY ex1 IS -- commentaires

PORT ( -- déclaration des entrées/sorties physiques

a, b, c : IN STD_LOGIC ;

s1, s2 : OUT STD_LOGIC -- pas de point virgule

) ;

END ex1 ;

ARCHITECTURE numero1 OF ex1 IS -- description de l’application

BEGIN

s1 <= a AND b ;

s2 <= (NOT a) OR (a AND b AND c) ;

END numero1 ;
 
 

Conclusion:

- Les 2 instructions s1 <= … et s2 <= ….. sont " concurrentes " : l’ordre dans lequel elles sont écrites n’a pas d’importance, puisqu’au final, il s’agit d’associer des portes logiques. On dit que VHDL est un langage à exécution parallèle. Le terme " exécution " n’est d’ailleurs pas très bien choisi : ici, contrairement à un programme écrit en PASCAL ou en C, rien ne sera jamais exécuté. Il faudra toujours garder ceci à l’esprit chaque fois qu’on écrira un texte VHDL.

- VHDL ne distingue pas les majuscules des minuscules. Dans ce cours, les mots réservés du langage seront écrits en majuscules.

- Les bibliothèques déclarées au départ permettent d’utiliser les types " STD-LOGIC " définis depuis 1993.

- " l’ENTITY " est la boîte avec ses entrées et ses sorties physiques. " L’architecture " contient la description du fonctionnement de la boîte et possède son propre nom.

- Il existe une priorité entre opérateurs. Le plus simple est d’utiliser des parenthèses.

- Les autres opérateurs sont : XOR (ou exclusif), NAND, NOR, & (concaténation), + (addition), - (soustraction), * (multiplication), / (division).
 
 

2- Description structurelle ou comportementale

On pourrait décrire l’exemple précédent sous la forme suivante :

ARCHITECTURE numero2 OF ex1 IS

BEGIN

s1 <= ‘1’ WHEN (a=’1’ AND b=’1’ ) ELSE ‘0’ ;

s2 <= ‘1’ WHEN (( a=’0’) OR (a=’1’ AND b=’1’ AND c=’1’)) ELSE ‘0’ ;

END numero2 ;

Conclusion:

- numéro1 est une description structurelle :elle est très proche d’une saisie de schéma.

- numéro2 est une description comportementale. Le schéma logique équivalent ne se déduit pas immédiatement.

- En logique combinatoire, il faut TOUJOURS prévoir toutes les lignes de la table de vérité (ici, il ne faut pas omettre ELSE). Sinon, le compilateur VHDL génèrera une fonction séquentielle de mémorisation (on peut le vérifier en omettant le " ELSE " de l’exemple précédent).
 
 

Exemple: multiplexeur:
 
LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY ex1 IS 

PORT (

e0, e1, c :IN STD_LOGIC ;

s : OUT STD_LOGIC

) ;

END ex2 ;

ARCHITECTURE archi OF ex2 IS

BEGIN

s <= e0 WHEN c = ‘0’ ELSE e1;

END archi;


 

Les parenthèses sont inutiles ici, le compilateur repère les mots réservés.
 
 

3- Notion de signal

Un signal est un STD_LOGIC ou un bus interne, permettant un calcul intermédiaire.

On reprend ici le premier exemple :
 
ARCHITECTURE numero3 OF ex1 IS 

SIGNAL x : STD_LOGIC ; 

BEGIN

s1 <= a AND b ;

x <= a AND b AND c ;

s2 <= (NOT a) OR x ;

END numero3 ;


 

4- Bus et nombres, opérateurs de test, opérateurs arithmétiques
 
 

Exemple:

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY combi1 IS

PORT (

a :IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- bus 4 fils

b :IN STD_LOGIC_VECTOR(3 DOWNTO 0);

S : OUT STD_LOGIC_VECTOR(11 DOWNTO 0); -- bus 12 fils

T : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) -- bus 8 fils

);

END combi1;

ARCHITECTURE archi OF combi1 IS

ALIAS op1:STD_LOGIC_VECTOR (3 DOWNTO 0) IS S(3 DOWNTO 0);

ALIAS op2:STD_LOGIC_VECTOR (3 DOWNTO 0) IS S(7 DOWNTO 4);

BEGIN

op1 <= a AND b;

op2 <= a OR "1010";

T <= a & b; -- concatenation

S(8) <= '1' WHEN a > b ELSE '0';

S(9) <= '1' WHEN a = "0000" ELSE '0';

S(10) <= '1' WHEN a = "0011" ELSE '0';

S(11) <='1' WHEN a<= "1001" ELSE '0';

END archi;

Conclusion:

- Les types " STD_LOGIC " et " STD_LOGIC_VECTOR " sont utilisés pour effectuer des opérations logiques.

- Via la déclaration " ALIAS ", on effectue des calculs sur une partie des bus.

- On peut accéder aux bus bit par bit.

- L’opérateur " DIFFERENT DE " s’écrit /=

- 3 DOWNTO 0 peut être remplacé par 0 TO 3.

Exemple:

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY combi2 IS

PORT (

a :IN INTEGER RANGE 0 TO 15; -- bus 4 fils

b :IN INTEGER RANGE 0 TO 15;

U : OUT INTEGER RANGE 0 TO 15;

Y : OUT STD_LOGIC_VECTOR(2 DOWNTO 0); -- bus 3 fils

T : OUT INTEGER RANGE 0 TO 31 -- bus 5 fils

);

END combi2;

ARCHITECTURE archi OF combi2 IS

BEGIN

U <= a - 4;

T<= a + b;

Y(2) <= '1' WHEN a<=12 ELSE '0'; -- a exprimé en base 10

Y(1) <= '1' WHEN a > b ELSE '0';

Y(0)<= '1' WHEN a = 16#a# ELSE '0'; -- a exprimé en base 16

END archi;

Conclusion:

- Les entiers sont utilisés pour effectuer des opérations arithmétiques.

- Chez ALTERA, seules les multiplications ou divisions par une puissance de 2 sont autorisées.

- Les tests possibles sont les mêmes qu’avec les " STD_LOGIC " et les " STD_LOGIC_VECTOR ".
 
 

5- IF … ELSE - Notion de process

Exemple: multiplexeur 1 voie parmi 4:
 
LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY combi3 IS

PORT ( 

c :IN INTEGER RANGE 0 TO 3; 

e : IN STD_LOGIC_VECTOR(3 DOWNTO 0); 

s : OUT STD_LOGIC

);

ARCHITECTURE archi OF combi3 IS

BEGIN

PROCESS(c)

BEGIN

IF (c = 0) THEN s<= e(0);

ELSIF (c = 1) THEN s<= e(1);

ELSIF (c = 2) THEN s<= e(2);

ELSE s<= e(3);

END IF;

END PROCESS;

END archi;

Conclusion:

- La notion de PROCESS sera précisée un peu plus tard.

- Plusieurs instructions peuvent être écrites entre THEN et ELSE ou ELSIF.

- Comme vu précédemment, il faut envisager tous les cas possibles, sinon il y aura génération d’une fonction registre.

- La liste de signaux inscrits entre parenthèses après le mot PROCESS se nomme la liste des sensibilités. Elle contient tous les signaux dont un changement d’état influe sur les signaux calculés dans le PROCESS.

- On peut effectuer un test sur plusieurs conditions :

PROCESS ( a, b)

BEGIN

IF (a = ‘1’ AND b = ‘0’) THEN ………

- Les signaux testés peuvent être

- des INTEGER par exemple IF a = 3

- des STD_LOGIC par exemple IF a = ‘0’

- des STD_LOGIC_VECTOR par exemple IF a = " 00100001 "

- On peut ajouter, dans le test, autant de parenthèses que nécessaire à la compréhension et à la lisibilité.

6- CASE

Le même exemple:

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY combi4 IS

PORT (

c :IN INTEGER RANGE 0 TO 3;

e : IN STD_LOGIC_VECTOR(3 DOWNTO 0);

S : OUT STD_LOGIC

);

END combi4;

ARCHITECTURE archi OF combi4 IS

BEGIN

PROCESS(c)

BEGIN

CASE c IS

WHEN 0 => s<= e(0);

WHEN 1 => s<= e(1);

WHEN 2 => s<= e(2);

WHEN 3 => s<= e(3);

END CASE;

END PROCESS;

END archi;

Conclusion:

- Comme vu précédemment, il faut envisager tous les cas possibles, sinon il y aura génération d’une fonction registre.

- Si un cas n’est pas listé, on utilise WHEN OTHERS => ……

- Les tests possibles sont les mêmes qu’avec IF

- On peut écrire autant d’instructions que nécessaires entre => et WHEN.

- On peut au sein d’un CASE introduire un IF ou inversement :

Exemple: multiplexeur une voie parmi 4 avec entrée de validation:
 
LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY combi5 IS

PORT (

val : IN STD_LOGIC; 

c :IN INTEGER RANGE 0 TO 3; 

e : IN STD_LOGIC_VECTOR(3 DOWNTO 0); 

s : OUT STD_LOGIC

);

END combi5;

ARCHITECTURE archi OF combi5 IS

BEGIN

PROCESS(c, val)

BEGIN

IF ( val = '0' ) THEN s<='0';

ELSE

CASE c IS

WHEN 0 => s<= e(0);

WHEN 1 => s<= e(1);

WHEN 2 => s<= e(2);

WHEN 3 => s<= e(3);

END CASE;

END IF;

END PROCESS;

END archi;

7- Boucle et variable de boucle

On peut effectuer une itération via une instruction de boucle et un compteur de boucle. La variable de boucle est purement virtuelle, elle ne correspond à rien de physique dans le futur circuit et ne doit pas être déclarée.

Exemple: codage de données:

Le cahier des charges est le suivant :

s0 = a0

pour i>0 Si = ai . ai-1 + /ai . /ai-1
 

 
 

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY combi6 IS

PORT (

a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); 

s : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)

);

END combi6;

ARCHITECTURE archi OF combi6 IS

BEGIN

PROCESS

BEGIN

s(0) <= a(0);

FOR i IN 1 TO 3 LOOP

S(i)<= (a(i) AND a(i-1)) OR ( NOT a(i) AND NOT a(i-1));

END LOOP;

END PROCESS;

END archi;


 
 
 

8- Notion de variable

On peut utiliser une variable (en générale entière), pour effectuer des calculs intermédiaires. Cette variable ne correspond à rien de physique. Elle est utilisée par le compilateur pour synthétiser la logique de l’application.

Exemple: un autre codage de données:

Le cahier des charges est le suivant : le nombre S en sortie indique, en binaire, le nombre de signaux d’entrée à 1.

Si a = 1001 alors S = 010

Si a = 1100 alors S = 010

Si a = 1111 alors S = 100
 

 
 
 
 

 

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY combi7 IS

PORT (

a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); 

S : OUT INTEGER RANGE 0 TO 4

);

END combi7;

ARCHITECTURE archi OF combi7 IS

BEGIN

PROCESS (a)

VARIABLE resultat : INTEGER;

BEGIN

resultat := 0;

FOR i IN 0 TO 3 LOOP

IF (a (i) = '1') THEN 

resultat := resultat + 1; 

END IF;

END LOOP;

s <= resultat;

END PROCESS;

END archi;


 

Conclusion:

- Cet exemple pourrait aussi être décrit via une table de vérité grâce à l’instruction CASE.

- On peut ici préciser la notion de PROCESS: le compilateur prend en compte la totalité du PROCESS, et génère la logique correspondante. On peut faire cohabiter plusieurs PROCESS dans un même programme VHDL. Ils deviennent " concurrents ": les logiques correspondantes sont générées indépendamment l’une de l’autre.

Exemple:

On cherche à intégrer dans un circuit logique programmable deux des exemples précédents :

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY combi8 IS

PORT (

a: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

t : OUT INTEGER RANGE 0 TO 4;

c :IN INTEGER RANGE 0 TO 3;

e : IN STD_LOGIC_VECTOR(3 DOWNTO 0);

s : OUT STD_LOGIC

);

END combi8;

ARCHITECTURE archi OF combi8 IS

BEGIN

PROCESS (a)

VARIABLE resultat : INTEGER;

BEGIN

resultat := 0;

FOR i IN 0 TO 3 LOOP

IF (a (i) = '1') THEN resultat := resultat + 1; END IF;

END LOOP;

t <= resultat;

END PROCESS;

PROCESS(c)

BEGIN

CASE c IS

WHEN 0 => s<= e(0);

WHEN 1 => s<= e(1);

WHEN 2 => s<= e(2);

WHEN 3 => s<= e(3);

END CASE;

END PROCESS;

END archi;

9 – Le problème des " glitches "

Il s’agit d’impulsions parasites générées lorsque des portes situées sur le même étage de logique ont des temps de propagation différents, et lorsque plusieurs entrées changent d’état en même temps.

On peut observer ces impulsions sur les résultats de simulation des 2 exemples précédents.

Exemple:


 
 

Remède :

On ne cherche en général pas à supprimer ces impulsions parasites. La tendance actuelle est de synchroniser toutes les sorties via des bascules D, à une fréquence d’horloge suffisamment faible pour rendre les " glitches " " invisibles ", et suffisamment rapide pour satisfaire aux exigences temporelles de l’application.
 
 

LOGIQUE SEQUENTIELLE






1- Bascule D LATCH
 
 
 

 
 


 
 

Si ena = 0, la sortie q est figée.

Si ena = 1, la sortie q recopie l’entrée d.

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY seq1 IS

PORT (

d,ena : IN STD_LOGIC; 

q: OUT STD_LOGIC

);

END seq1;

ARCHITECTURE archi OF seq1 IS

SIGNAL test: STD_LOGIC ; 

BEGIN

PROCESS (ena,d)

BEGIN

IF ena = '1' THEN test <= d;

ELSE test <= test;

END IF;

END PROCESS;

q <= test;

END archi;


 

Remarque:

On ne peut pas effectuer le traitement directement avec le signal q. Le passage par le signal interne test est nécessaire.
 
 

2- Bascule D " Edge Triggered "
 
 
 
 
 

 
 


 
 

Au front d’horloge, la sortie q recopie l’entrée d.

Entre 2 fronts d’horloge, la sortie q est figée.

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY seq2 IS

PORT (

d, h: IN STD_LOGIC; 

q: OUT STD_LOGIC

);

END seq2;

ARCHITECTURE archi OF seq2 IS

SIGNAL test: STD_LOGIC ; 

BEGIN

PROCESS 

BEGIN

WAIT UNTIL h='1';

test <= d;

END PROCESS;

q <= test;

END archi;


 
 
 
 
 
 
 

Conclusion:

Ici, l’exécution du PROCESS est suspendue jusqu’au passage de 0 à 1 du signal d’horloge.

Le PROCESS ne comporte pas de liste de sensibilités.
 
 

Bascule D avec entrées de prépositionnement asynchrones :
 
 
 
 
 

 
 

Si prn = cln = 1, la bascule fonctionne comme précédemment.

Si cln = 0, la sortie q est mise à 0, indépendamment des autres entrées.

Si cln = 1 et prn = 0, la sortie q 

est mise à 1, indépendamment 

des autres entrées.

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY seq3 IS

PORT (

d, h: IN STD_LOGIC;

Prn, Cln : IN STD_LOGIC; 

q: OUT STD_LOGIC

);

END seq3;

ARCHITECTURE archi OF seq3 IS

SIGNAL test: STD_LOGIC ; 

BEGIN

PROCESS ( Prn, Cln, h)

BEGIN

IF Cln = '0' THEN test <= '0'; -- Clear prioritaire

ELSIF Prn = '0' THEN test <= '1';

ELSIF h'EVENT AND h = '1' THEN test <= d;

ELSE test <= test;

END IF;

END PROCESS;

q <= test;

END archi;


 
 
 
 
 

Conclusion:

- Ici, pour pouvoir définir une liste de sensibilités, on n’a pas utilisé l’instruction WAIT.

- L’instruction IF h’EVENT AND h = ‘1’ permet de détecter un front d’horloge. Il est nécessaire de préciser s’il s’agit d’un front montant ou descendant.

3- Registre parallèle

C’est une extension directe des applications précédentes.
 

 
 


 
 

Au front d’horloge, le bus de

sortie q recopie le bus d’entrée d.

Entre 2 fronts d’horloge, le bus

de sortie q est figé.

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY seq4 IS

PORT (

h: IN STD_LOGIC; 

d : IN STD_LOGIC_VECTOR (7 DOWNTO 0);

q: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)

);

END seq4;

ARCHITECTURE archi OF seq4 IS

SIGNAL test: STD_LOGIC_VECTOR (7 DOWNTO 0) ; 

BEGIN

PROCESS 

BEGIN

WAIT UNTIL h='1';

test <= d;

END PROCESS;

q <= test;

END archi;

Conclusion:

On pourra, sur le modèle des différentes bascules D, définir un registre de type LATCH, ou bien des entrées de prépositionnement asynchrones.
 
 

Suppresion des " glitches " générés par de la logique combinatoire, par synchronisation des sorties sur un signal d’horloge:

On reprend l’exemple COMBI7 :

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY seq5 IS

PORT (

a: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

h: IN STD_LOGIC;

S : OUT INTEGER RANGE 0 TO 4

);

END seq5;

ARCHITECTURE archi OF seq5 IS

SIGNAL tampon : INTEGER RANGE 0 TO 4;

BEGIN

PROCESS (a) -- description conforme à l’exemple COMBI7

VARIABLE resultat : INTEGER;

BEGIN

resultat := 0;

FOR i IN 0 TO 3 LOOP

IF (a (i) = '1') THEN resultat := resultat + 1; END IF;

END LOOP;

tampon <= resultat;

END PROCESS;

PROCESS -- synchronisation

BEGIN

WAIT UNTIL h = '1';

s <= tampon;

END PROCESS;

END archi;

Conclusion :

Les " glitches " ont disparu !

Les sorties changent d’état au front d’horloge.

4- Compteur

Les compteurs décrits ci-dessous reposent sur le principe suivant :

- La sortie du compteur est prise à la sortie d’un registre parallèle.

- L’entrée de ce registre est commandée par le résultat d’une addition : la sortie du registre +1.

Un premier compteur 3 bits simple, sans remise à 0, construit sur le modèle de SEQ2 :
 
 
 

 
 

 

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY seq6 IS

PORT (

h: IN STD_LOGIC; 

q: OUT INTEGER RANGE 0 TO 7 

);

END seq6;

ARCHITECTURE archi OF seq6 IS

SIGNAL test: INTEGER RANGE 0 TO 7; 

BEGIN

PROCESS 

BEGIN

WAIT UNTIL h='1';

test <= test+ 1;

END PROCESS;

q <= test;

END archi;

Un deuxième compteur 3 bits, avec remise à 0 asynchrone, construit sur le modèle de SEQ3 :
 
 
 
ENTITY seq7 IS

PORT (

h, Cln: IN STD_LOGIC; 

q: OUT INTEGER RANGE 0 TO 7 );

END seq7;

ARCHITECTURE archi OF seq7 IS

SIGNAL test: INTEGER RANGE 0 TO 7; 

BEGIN

PROCESS (Cln, h)

BEGIN

IF Cln = '0' THEN test <= 0; 

ELSIF h'EVENT AND h = '1' 

THEN test <= test + 1;

ELSE test <= test;

END IF;

END PROCESS;

q <= test;

END archi;


 
 
 

Conclusion :

A partir de ces 2 modèles et des outils combinatoires, on pourra multiplier les options : compteur/décompteur, compteur prépositionnable, compteur DCBN, signalisation de fin de comptage etc …

GRAPHE D’ETATS


Le modèle choisi est celui de Machine de MOORE : Les états sont codés en binaire (bits d’état). Ce code est matérialisé par les sorties d’un registre.

Les sorties du système sont des fonctions combinatoires des bits d’état.

L’état futur du système est calculé par une fonction combinatoire dépendant de l’état actuel et des entrées.

Une entrée de remise à 0 asynchrone est prévue, permettant le retour à l’état initial à tout moment.

Si nécessaire, les sorties du système peuvent être resynchronisées sur l’horloge, via un registre.

Exemple :

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY seq8 IS -- machine d'états

PORT ( h, x, y, z, init : IN STD_LOGIC;

a, b, c : OUT STD_LOGIC);


END seq8;






ARCHITECTURE archi OF seq8 IS

SIGNAL etat: STD_LOGIC_VECTOR (2 DOWNTO 0);


BEGIN


PROCESS

BEGIN

WAIT UNTIL h = '1';

CASE etat IS

WHEN "000" => IF init = '1' OR x = '0' THEN etat <= "000";

ELSE etat <= "001";

END IF;

WHEN "001" => IF init ='1' THEN etat <= "000";

ELSIF y = '1' THEN etat <= "011";

ELSE etat <= "010";

END IF;

WHEN "010" => IF init ='1' THEN etat <= "000";

ELSIF z = '1' THEN etat <= "100";

ELSE etat <= "010";

END IF;

WHEN "011" => IF init ='1' THEN etat <= "000";

ELSIF z = '1' THEN etat <= "100";

ELSE etat <= "011";

END IF;

WHEN "100" => IF init ='1' THEN etat <= "000";

ELSE etat <= "100";

END IF;

WHEN OTHERS => etat <="000"; -- pour envisager les etats non décrits

END CASE;

END PROCESS;

a <= '1' WHEN etat = "010" OR etat = "011" ELSE '0'; -- Equation des sorties

b <= '1' WHEN etat = "001" OR etat = "100" ELSE '0';

c <= '1' WHEN etat = "001" OR etat = "011" OR etat = "100" ELSE '0';

END archi;
 
 

Le même exemple en définissant un " type état " :

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY seq9 IS -- machine d'états

PORT ( -- autrement

h, x, y, z, init : IN STD_LOGIC;

a, b, c : OUT STD_LOGIC

);

END seq9;

ARCHITECTURE archi OF seq9 IS

TYPE STATE_TYPE IS (s0,s1,s2,s3,s4);

SIGNAL etat : STATE_TYPE;

BEGIN

PROCESS

BEGIN

WAIT UNTIL h = '1';

CASE etat IS

WHEN s0 => IF init = '1' OR x = '0' THEN etat <= s0;

ELSE etat <= s1;

END IF;

WHEN s1 => IF init ='1' THEN etat <= s0;

ELSIF y = '1' THEN etat <= s3;

ELSE etat <= s2;

END IF;

WHEN s2 => IF init ='1' THEN etat <= s0;

ELSIF z = '1' THEN etat <= s4;

ELSE etat <= s2;

END IF;

WHEN s3 => IF init ='1' THEN etat <= s0;

ELSIF z = '1' THEN etat <= s4;

ELSE etat <= s3;

END IF;

WHEN s4 => IF init ='1' THEN etat <= s0;

ELSE etat <= s4;

END IF;

WHEN OTHERS => etat <=s0; -- pour envisager les etats non décrits

END CASE;

END PROCESS;

-- Equation des sorties

a <= '1' WHEN etat = s2 OR etat = s3 ELSE '0';

b <= '1' WHEN etat = s1 OR etat = s4 ELSE '0';

c <= '1' WHEN etat = s1 OR etat = s3 OR etat = s4 ELSE '0';

END archi;
 
 

Il serait plus prudent, dans l’exemple précédent de traiter l’entrée d’initialisation init de manière asynchrone, en prévoyant un signal reset sur les bascules :

Le graphe d’états se simplifie comme ci-dessous :

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

ENTITY seq10 IS -- machine d'états

PORT ( -- avec reset asynchrone

h, x, y, z, init : IN STD_LOGIC;

a, b, c : OUT STD_LOGIC

);

END seq10;

ARCHITECTURE archi OF seq10 IS

TYPE STATE_TYPE IS (s0,s1,s2,s3,s4);

SIGNAL etat : STATE_TYPE;

BEGIN

PROCESS (h,init,x,y,z,etat)

BEGIN

IF init ='1' THEN etat<=S0; --Reset asynchrone

ELSIF h'EVENT AND h='1' THEN

CASE etat IS

WHEN s0 => IF x = '0' THEN etat <= s0;

ELSE etat <= s1;

END IF;

WHEN s1 => IF y = '1' THEN etat <= s3;

ELSE etat <= s2;

END IF;

WHEN s2 => IF z = '1' THEN etat <= s4;

ELSE etat <= s2;

END IF;

WHEN s3 => IF z = '1' THEN etat <= s4;

ELSE etat <= s3;

END IF;

WHEN s4 => etat <= s4;

WHEN OTHERS => etat <=s0; -- pour envisager les etats non décrits

END CASE;

ELSE etat<=etat;

END IF;

END PROCESS;

-- Equation des sorties

a <= '1' WHEN etat = s2 OR etat = s3 ELSE '0';

b <= '1' WHEN etat = s1 OR etat = s4 ELSE '0';

c <= '1' WHEN etat = s1 OR etat = s3 OR etat = s4 ELSE '0';

END archi;

LIGNE 3 ETATS







La ligne S1 ci-dessous, peut-être utilisée

1- Comme une entrée , on a alors S2 = S1 + c. Le buffer 3 états doit être placé en haute impédance via la commande CS (à 0).

2- Comme une sortie , on a alors S1 = a.b, et S2 = a.b + c. Le buffer 3 états doit être placé en basse impédance via la commande CS (à 1).
 
 
 
 
 

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

LIBRARY altera;

USE altera.maxplus2.all; -- contient la primitive TRI

ENTITY trivhd IS

PORT (

a,b,c,CS :IN STD_LOGIC;

S2 : OUT STD_LOGIC;

S1: INOUT STD_LOGIC

);

END trivhd;

ARCHITECTURE archi OF trivhd IS

SIGNAL X: STD_LOGIC;

BEGIN

S2 <= S1 OR c ;

X <= a AND b;

Mon_buffer : TRI PORT MAP (x, cs, S1); -- utilisation de la primitive TRI

END archi; -- on passe les paramètres spécifiés dans la doc

-- on peut retrouver la déclaration de la primitive dans

-- c:\maxplus2\vhdl93\altera\maxplus2.vhd


 
 
 


 

Menu Général