Université Abdelmalek
Essaâdi Année universitaire
Faculté des Sciences 2022-2032
Tétouan
Rapport De VHDL
Master Mécatronique
Année universitaire 2022/2023
Réalisée par
Ben Abdeluahab Ahmed
Le 2 janvier 2023
Sommaire
1 Additionneur complet à 4 bits: 2
1.1 Comment créer un nouveau projet ? . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Additionneur complet sur un bit: . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3 Additionneur complet à 4 bits: . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.1 Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3.2 Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3.3 Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2 Registre à décalage à 4 bits: 17
2.1 Bascule D: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2 Programme final: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3 Additionneur-soustracteur 4-bit: 20
3.1 Additionneur complet à 1 bit: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2 Multiplexeur 2 → 1: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.3 Programme final: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4 Détecteur de séquences: 25
5 Parcomètre: 28
1
1 Additionneur complet à 4 bits:
Un additionneur 4 bits est un circuit numérique qui effectue l’addition de deux nombres binaires
de 4 bits. Il a:
4 bits d’entrée, représentés par A3 , A2 , A1 et A0 , et 4 bits d’entrée, représentés par B3 ,
B2 , B1 et B0 .
Le bit de retenue d’entrée Cin , qui représente la retenue d’une addition précédente.
L’additionneur produit:
Une sortie de somme de 4 bits, représentée par S3 , S2 , S1 et S0 .
Cout (bit), qui représente une retenue pour une addition ultérieure.
Figure 1: Additionneur complet à 1 bit
Une méthode pour implémenter un additionneur de 4 bits consiste à cascader 4 additionneurs
complets de 1 bit. Chaque additionneur complet prend deux bits d’entrée (A et B) et un bit de
retenue (Cin ), et produit un bit de sortie de somme (S) et un bit de retenue (Cout ).
1. Les bits les moins importants (A0 et B0 ) sont les entrées du premier additionneur avec le
bit de retenue (C0 ). L’additionneur produit un bit de sortie de somme (S0 ) et un bit de
sortie de retenue (C1 ).
2. Les bits suivants les plus importants (A1 et B1 ) sont les entrées du deuxième additionneur,
ainsi que le bit de retenue du premier additionneur (C1 ). L’additionneur produit un bit de
sortie de la somme (S1 ) et un bit de retenue (C2 ).
3. Les bits suivants les plus importants (A2 et B2 ) sont les entrées du troisième additionneur,
ainsi que le bit de retenue du deuxième additionneur (C2 ). L’additionneur produit un bit
de sortie de somme (S2 ) et un bit de retenue (C3 ).
4. Les bits les plus importants (A3 et B3 ) sont les entrées du quatrième additionneur ainsi
que le bit de retenue du troisième additionneur (C3 ). L’additionneur produit un bit de
sortie de la somme (S3 ) et le bit de retenue final (C4 ).
2
Figure 2: Additionneur à 4 bits
1.1 Comment créer un nouveau projet ?
Pour créer un nouveau projet, ouvrez d’abord Quartus Web Edition et cliquez sur New Project
Wizard (figure 3).
Figure 3: New Project Wizard
Après l’apparition de la fenêtre New Project Wizard (figure 4), cliquez sur Next.
3
Figure 4: la fenêtre New Project Wizard
Dans la fenêtre suivante (figure 5), il vous sera demandé de spécifier les informations suivantes:
1. Le dossier dans lequel le projet sera sauvegardé. Il est préférable de créer/choisir un dossier
à l’intérieur du dossier Altera.
2. Le nom du projet. On le nomme additionneur 4 bits.
3. Comme l’additionneur 4 bits est le programme principal, on nomme le fichier principal
FA 4 .
4
Figure 5: Configuration de projet
Après avoir rempli toutes les informations nécessaires, cliquez sur ”Finish”.
Ce projet possède deux programmes VHDL, un sous-programme qui contient le code de
l’additionneur complet de 1 bit, et un programme principal qui contient le code de l’additionneur
de 4 bits. Pour créer un fichier VHDL, cliquez sur File −→ New (figure 6), puis sur VHDL
File (figure 7).
5
Figure 6: File −→ New Figure 7: VHDL File
On crée deux fichiers VHDL:
FA.vhd: Ce fichier contiendra le code de l’additionneur complet 1-bit.
FA 4.vhd: Ce fichier contiendra le code de l’additionneur complet 4-bits.
Pour garder votre projet organisé et structuré, il est préférable de créer un dossier séparé
appelé source code où vous gardez tous vos fichiers VHDL.
Maintenant que nous avons créé tous les fichiers nécessaires, il ne nous reste plus qu’à les remplir
de code.
1.2 Additionneur complet sur un bit:
Une description comportementale est un modèle utilisè lorsque les connexions du circuit à con-
cevoir sont compliquée ou inconnues, mais que son comportement est bien dèfini. C’est-à-dire
que l’on connait la sortie de chaque combinaison possible des entrées.
Pour décrire un circuit par son comportement, on a besoin de sa table de vérité. Voilá la
table de vérité d’un additionneur complet sur un bit.
6
A B Cin S Cout
0 0 0 0 0
0 0 1 0 1
0 1 0 0 1
0 1 1 1 0
1 0 0 0 1
1 0 1 1 0
1 1 0 1 0
1 1 1 1 1
Table 1: La table de vérité d’un additionner complet sur un bit.
Avec:
■ A et B: sont les bits à additionner.
■ Cin : est la retenue d’entrée.
■ S: est la somme.
■ Cout : est la retenue de sortie.
Chaque programme VHDL doit comporter une Entity et au moins une Architecture. En-
tity définit les ports du circuit (entrées et sorties), tandis que l’Architecture définit le com-
portement du circuit. On définit l’Entity comme suit :
ENTITY FA IS
PORT (
A, B, C_in : IN BIT;
S, C_out : OUT BIT
);
END FA;
FA est le nom de l’entité, qui signifie ”Full Adder” en anglais.
Tous les ports de l’additionneur complet sont des bits. Donc, on les définit comme BIT.
Pour implementer la description comportementale de FA en VHDL, on utilise l’instruction if
else sur (A & B & C)
architecture rt1 of FA is
begin
S <= a XOR b XOR c_in;
C_out <= (A AND B) OR (((A XOR B) AND C_in));
end architecture rt1;
ARCHITECTURE comportemental OF FA IS
BEGIN
PROCESS (A, B, C_in)
VARIABLE E : BIT_VECTOR(2 DOWNTO 0);
7
BEGIN
E := A & B & C_in;
IF (E = "001" OR E = "010" OR E = "100" OR E = "111") THEN
C_out <= '1';
ELSE
C_out <= '0';
END IF;
Comme l’instruction if else est séquentielle, if faut l’utiliser à l’interieur d’un Process.
A, B, et Cin doivent être inclues dans la liste de sensibilité du Process.
pour chaque sortie (S et Cout ), on liste toutes les combinaisons qui donnent la valeur 1
dans la partie if, les autres combinaisons sont traitées dans la partie else.
Pour vérifier si le programme fonctionne correctement, nous allons reproduire la table de
vérité dans un fichier ”waveform” et vérifier si les résultats sont corrects.
On configure temporairement le fichier FA.vhd pour être le programme principal. Cela nous
permet de synthétiser le fichier pour le visualiser dans une simulation Waveform. Ouvrez le
fichier FA.vhd, puis cliquez sur File −→ Set as Top level Entry (figure 8). Pour compiler le
code, cliquez sur Start Analysis & Synthesis (figure 9).
Figure 8: File −→ Set as Top level En- Figure 9: Start Analysis & Synthesis
try
Pour créer une simulation Waveform, cliquez sur File −→ New, puis sur University
Program WVF.
8
Puisque la table de vérité commence à 000 et se termine à 111 (0 à 7) . On va fixer le temps
total de simulation à 8µs et le pas à 1µs.
Pour modifier la durée de la simulation, cliquez sur Edit −→ Set End Time (figure 10).
Puis fixez le temps à 8µs (figure 11).
Figure 10: Edit −→ Set End Time Figure 11: Le temps de simulation.
Pour modifier le pas, cliquez sur Edit −→ Grid Size (figure 12), puis fixez sa valeur à 1µs
(figure 13).
9
Figure 12: Edit −→ Grid Size Figure 13: l’unité de temps par division
Pour ajouter les ports (entrées et sorties) dans la simulation, cliquez sur Edit −→ Insert
−→ Insert Node or Bus(figure 14). Dans la fenêtre de la figure 15, cliquez sur Node Finder.
Figure 14: Figure 15:
Dans la fenêtre Node Finder, cliquez sur List puis sur le bouton ” >> ”(figure 16).
10
Figure 16:
Pour faciliter la création de la table de vérité, on regroupe les signaux A, B et Cin en un
signal 3 bits. Sélectionnez les trois signaux, faites un clic droit, Grouping −→ group (figure
17). Dans la fenêtre Group (figure 18), nommez le nouveau signal ABCin .
Figure 17: Grouping −→ group Figure 18: Group
On regroupe également S et Cout en un signal de 2 bits appelé SCout . Sélectionnez ABCin
et cliquez sur Count Value, et fixez la ”start value” à 000, ”Incremented by” à 1, et ”Count
every” à 1µs (figure 19). Ceci permet de créer un compteur de 0 à 7 qui s’incrémente de 1 chaque
1µs.
11
Figure 19:
Pour exécuter la simulation, cliquez sur Run Functional Simulation.
Figure 20: Simulation Waveform
Comme nous pouvons le voir, le résultat de la figure 20 est identique à la table de vérité de
la table 1.
1.3 Additionneur complet à 4 bits:
Dans cette section, on va développer le code d’un additionneur de 4 bits basé sur l’additionneur
complet (FA). On présente trois variantes de ce code :
Une utilisant Component.
Une utilisant Function.
Une autre utilisant Procedure.
12
Puisque l’Entité du circuit ne changera pas à travers les différentes implémentations, on l’écrit
en premier.
ENTITY FA_4 IS
PORT (
A, B : IN BIT_VECTOR(3 DOWNTO 0);
C_in : IN BIT;
S : OUT BIT_VECTOR(3 DOWNTO 0);
C_final : OUT BIT
);
END FA_4;
On remarque que A, B et S sont définis comme des vecteurs de bits de longueur 4.
On utilise 3 DOWNTO 0 parce que l’addition se fait du bit le moins important au bit le
plus important (de droite à gauche).
1.3.1 Component
ARCHITECTURE comp_imp OF FA_4 IS
COMPONENT FA IS
PORT (
a, b, c_in : IN BIT;
s, c_out : OUT BIT
);
END COMPONENT;
SIGNAL c_i : BIT_VECTOR(4 DOWNTO 0);
BEGIN
c_i(0) <= C_in;
ADDERS : FOR i IN 0 TO 3 GENERATE
adder_1 : FA PORT MAP(A(i), B(i), c_i(i), S(i), c_i(i + 1));
END GENERATE;
C_final <= c_i(4);
END comp_imp; -- comp_imp
Dans l’architecture, avant BEGIN, on utilise le bloc COMPONENT pour utiliser le
code FA à l’intérieur du fichier principal.
Comme il y a 4 additionneurs complets, il y aura 4 retenues intermédiaires où la retenue
de sortie d’un additionneur est la retenue d’entrée de l’additionneur suivant, sauf pour le
premier additionneur où Cin est sa retenue d’entrée. On déclare un signal de 5 bits ci dont
le premier élément est la valeur de Cin. De cette façon, on écrit la boucle sans avoir à
vérifier si i = 0 ou i > 0.
FOR GENERATE est utilisé pour créer 4 instances de FA.
13
Figure 21: RTL Viewer pour Component
1.3.2 Function
ARCHITECTURE fun_imp OF FA_4 IS
FUNCTION Sum(a, b, c_in : BIT)
RETURN BIT IS
VARIABLE s : BIT;
BEGIN
s := a XOR b XOR c_in;
RETURN s;
END Sum;
FUNCTION Carry(a, b, c_in : BIT)
RETURN BIT IS
VARIABLE c : BIT;
BEGIN
c := (a AND b) OR (((a XOR b) AND c_in));
RETURN c;
END Carry;
SIGNAL c_i : BIT_VECTOR(4 DOWNTO 0);
BEGIN
c_i(0) <= C_in;
ADDERS : FOR i IN 0 TO 3 GENERATE
S(i) <= Sum(A(i), B(i), c_i(i));
c_i(i + 1) <= Carry(A(i), B(i), c_i(i));
END GENERATE;
C_final <= c_i(4);
14
END fun_imp; -- fun_imp
On utilise deux fonctions, l’une pour calculer la somme (S), et l’autre pour calculer la
retenue (Cout ).
Figure 22: RTL Viewer pour Function
1.3.3 Procedure
ARCHITECTURE proc_imp OF FA_4 IS
PROCEDURE Add(SIGNAL a, b, c_in : IN BIT; SIGNAL s, c_out : OUT BIT) IS
BEGIN
s <= a XOR b XOR c_in;
c_out <= (a AND b) OR (((a XOR b) AND c_in));
END Add;
SIGNAL c_i : BIT_VECTOR(4 DOWNTO 0);
BEGIN
c_i(0) <= C_in;
ADDERS : FOR i IN 0 TO 3 GENERATE
Add(A(i), B(i), c_i(i), S(i), c_i(i + 1));
END GENERATE;
C_final <= c_i(4);
END proc_imp; -- proc_imp
15
Figure 23: RTL Viewer pour Procedure
Pour vérifier si le code produit des résultats corrects, on crée une simulation Waveform, et
on effectue les opérations suivantes :
1111 + 1111 = 11110 (15 + 15 = 30).
1011 + 1100 = 10111 (11 + 12 = 23).
0111 + 0011 = 1010 (7 + 3 = 10).
1101 + 1000 = 10101 (13 + 8 = 21).
Notez que les trois variations de code présentées dans cette section donneront les mêmes résultats
que la figure 24.
Figure 24: Additionneur complet à 1 bit
Comme on peut le voir sur la figure 24, la simulation produit les mêmes résultats que ceux
que l’on attendait. Notez que l’on doit également inclure Cf inal lors de la lecture des résultats.
Car l’addition de deux nombres de 4 bits peut donner un nombre de 5 bits. Donc le 5ème bit
est stocké dans Cf inal .
16
2 Registre à décalage à 4 bits:
Un registre à décalage est un circuit numérique qui peut stocker et décaler des valeurs binaires
dans une direction prédéfinie (vers le gauche ou vers le droite). Les valeurs sont stockées dans
une série de bascules (bascules D), qui sont de petites cellules de mémoire pouvant contenir une
seule valeur binaire (0 ou 1).
Dans cet exercice, on étudie un registre à décalage de 4 bits. Le registre à décalage de 4 bits
possède quatre bascules, chacune d’entre elles pouvant stocker une seule valeur binaire. L’entrée
de données série (D) est connectée à la première bascule, et la sortie de données série (Q) est
extraite de la dernière bascule. Elles sont décalées de la gauche vers la droite. Lorsque l’horloge
passe du niveau bas au niveau haut (front montant), les valeurs stockées dans les bascules sont
décalées d’une position vers la droite (Un exemple est donné dans la deuxième section).
Comme un registre à décalage est basé sur la bascule D, on a besoin de deux programmes :
un sous-programme qui contient le code de la bascule D, qui est utilisé comme composant dans
le programme principal qui contient le code du registre à décalage.
2.1 Bascule D:
Une bascule D est un type de bascule où il y a une seule entrée appelée ”D” et une seule sortie
appelée ”Q”. La valeur de D est capturée et mémorisée dans la bascule à un moment précis
du cycle d’horloge (comme le front montant de l’horloge). La valeur de Q est ensuite actualisée
pour correspondre à la valeur de D. Dans cet exemple, on va travailler avec une bascule qui est
activée par le front montant de l’horloge. Cela signifie que la bascule ne capture la valeur de D
que lorsque l’horloge passe du bas au haut.
Voici une implémentation vhdl de la bascule D:
ENTITY bascule_D IS
PORT (
H, D : IN BIT;
Q : OUT BIT
);
END bascule_D;
ARCHITECTURE bascule_arch OF bascule_D IS
BEGIN
PROCESS (H)
BEGIN
IF (H'event AND H = '1') THEN
Q <= D;
END IF;
END PROCESS;
END bascule_arch;
L’entité bascule D est définie avec trois ports:
H : Un signal d’un bit représente l’horloge.
D : Un signal d’un bit représente l’entrée de la bascule D.
Q : Un signal d’un bit représente la sortie de la bascule D.
17
L’architecture (bascule arch) contient un PROCESS qui est sensible à l’horloge (H), ce qui
signifie qu’il s’exécutera chaque fois qu’il y aura un changement sur H.
Le PROCESS possède une instruction conditionnelle qui détecte le front montant de
l’horloge.
Lorsque l’horloge a un front montant, la sortie Q reçoit la valeur D.
Le code ci-dessus est interprété par le compilateur comme une bascule D (figure 25). On peut
vérifier si le code fonctionne comme prévu en réalisant une simulation Waveform (figure 26).
Comme on peut le voir, Q prend la valeur de D uniquement sur les fronts montants de l’horloge.
Figure 25: RTL Viewer
Figure 26: Simulation Waveform
2.2 Programme final:
Voici une implémentation VHDL d’un registre à décalage de 4 bits.
ENTITY registre_d4 IS
18
PORT (
H, D : IN BIT;
Q : OUT BIT
);
END registre_d4;
ARCHITECTURE reg_arch OF registre_d4 IS
COMPONENT bascule_D IS
PORT (
H, D : IN BIT;
Q : OUT BIT
);
END COMPONENT;
SIGNAL Q_D : BIT_VECTOR(4 DOWNTO 0);
BEGIN
Q_D(0) <= D;
boucle : FOR i IN 0 TO 3 GENERATE
BD : bascule_D PORT MAP(H, Q_D(i), Q_D(i + 1));
END GENERATE;
Q <= Q_D(4);
END reg_arch;
L’entité registre d4 est définie avec trois ports:
D: Puisque les données d’entrée d’un registre à décalage sont transmises en série à travers
les bascules, on définit D comme un signal à un bit.
H: est le signal d’horloge qui synchronise tous les bascules du registre.
Q: Un signal d’un bit représente la sortie de registre.
L’architecture registre d4 contient :
Une déclaration COMPONENT pour utiliser la bascule D comme composant dans le
programme principal.
Un signal appelé Q D qui est un vecteur de 5 bits. Le premier élément de Q D reçoit la
valeur de D.
La boucle GENERATE est utilisée pour instancier quatre instances du composant bas-
cule D.
Q reçoit la valeur du dernier élément de Q D.
19
Figure 27: RTL Viewer
Pour vérifier si le code que l’on a développé fonctionne comme prévu, on va créer une autre
simulation de waveform où l’on va décaler la séquence 1011.
La séquence (valeur de 4 bits) prendra 4 cycles d’horloge pour être stockée dans le registre.
Dans la simulation, on s’attend à voir la séquence émerger après 4 cycles d’horloge (figure 28).
Figure 28: Simulation Waveform
3 Additionneur-soustracteur 4-bit:
Un additionneur-soustracteur de 4 bits est un circuit numérique capable d’effectuer des opérations
d’addition et de soustraction sur deux nombres binaires de 4 bits. Les entrées sont :
A: Nombre binaire de 4 bits à additionner-soustraire (A3 , A2 , A1 , et A0 ).
B: Nombre binaire de 4 bits à additionner-soustraire (B3 , B2 , B1 , et B0 ).
M : signal de contrôle (0 pour l’addition, 1 pour la soustraction). On peut utiliser le signal
de contrôle comme retenue de l’additionneur du bit de poids faible.
Les sorties sont :
S : Somme/différence de A et B (S3 , S2 , S1 , et S0 ).
20
Cf : retenue finale.
On peut réaliser un additionneur-soustracteur de 4 bits à partir d’un additionneur de 4 bits avec
des modifications mineures. Premièrement, on sait qu’une soustraction peut être exprimée en
termes de sommes (en utilisant le complément à 2). Par exemple, A − B peut s’écrire A + B + 1,
où B est une inversion bit à bit de B (1101 devient 0010). Pour obtenir B, on ajoute une porte
XOR à chaque additionneur et on effectue Bi ⊕ M (M est le signal de contrôle). Si M = 0, alors
le résultat est B, si M = 1, alors Bi ⊕ M sera évalué à B. Voici le montage de l’additionneur-
soustracteur de 4 bits (figure 29).
Figure 29: Additionneur-soustracteur 4-bit
Comme on le voit, on a besoin de 4 additionneurs complets, 5 portes xor, et un multiplexeur.
Le XOR est déjà implémenté dans le VHDL. Donc les seules parties que l’on doit implémenter
sont l’additionneur complet et le multiplexeur.
3.1 Additionneur complet à 1 bit:
On a déjà développé un programme pour un additionneur complet de 1 bit, mais il existe une
autre implémentation qui est basée sur les équations de la somme (S) et de la retenue de sortie
(Cout ) que l’on va présenter dans cette section.
ENTITY FA IS
PORT (
A, B, C_in : IN BIT;
S, C_out : OUT BIT
);
END FA;
ARCHITECTURE FA_arch OF FA IS
BEGIN
S <= A XOR B XOR C_in;
21
C_out <= (A AND B) OR ((A XOR B) AND C_in);
END FA_arch;
Le code est simple et facile à comprendre. On affecte simplement à S et Cout les équations
correspondantes, qui sont :
S = A ⊕ B ⊕ Cin
Cout = A · B + (A ⊕ B) · Cin
Figure 30: Additionneur complet à 1 bit
3.2 Multiplexeur 2 → 1:
Un multiplexeur est un circuit numérique qui sélectionne l’une de ses entrées pour la transmettre
à sa sortie. Un multiplexeur 2 vers 1 est un type de multiplexeur qui possède deux entrées (E0
et E1 ) et une entrée de contrôle (sel). L’entrée de contrôle détermine laquelle des deux entrées
est transmise à la sortie. Par exemple, si l’entrée de contrôle est 0, le multiplexeur transmet la
première entrée à la sortie. Si l’entrée de contrôle est 1, le multiplexeur transmet la deuxième
entrée à la sortie. Voici l’implémentation vhdl d’un multiplexeur 2 vers 1:
ENTITY MUX_2 IS
PORT (
E0, E1, sel : IN BIT;
S : OUT BIT
);
END MUX_2;
ARCHITECTURE mux_arch OF MUX_2 IS
BEGIN
PROCESS (sel, E0, E1)
BEGIN
CASE sel IS
WHEN '0' => S <= E0;
WHEN '1' => S <= E1;
END CASE;
END PROCESS;
END mux_arch;
Le code définit une entité appelée MUX 2 avec les ports suivants :
22
Les entrées sont :
– E0 : le premier signal d’entrée.
– E1 : le deuxième signal d’entrée.
– sel: signal de sélection qui détermine quelle entrée est transmise à la sortie.
La sortie est :
– S : signal de sortie.
L’architecture consiste en un processus dont la liste de sensibilité comprend les entrées sel, E0
et E1. Cela signifie que le processus sera exécuté chaque fois que l’un de ces signaux change.
Dans le processus, il y a une instruction CASE qui détermine quelle entrée doit passer à la sortie
en fonction de la valeur du sélecteur sel :
Si sel est égal à 0, l’entrée E0 est transmise à la sortie S.
Si sel est égal à 1, l’entrée E0 est transmise à la sortie S.
Figure 31: Multiplexeur 2 vers 1
3.3 Programme final:
Voici une implémentation VHDL d’un additionneur-soustracteur de 4 bits.
ENTITY add_sous IS
PORT (
A, B : IN BIT_VECTOR(3 DOWNTO 0);
M : IN BIT;
Mcov, Cf : OUT BIT;
S : OUT BIT_VECTOR(3 DOWNTO 0);
Ovf : OUT BIT
);
END add_sous;
23
ARCHITECTURE add_sous_arch OF add_sous IS
FUNCTION MUX_2(e0, e1, sel : BIT) RETURN BIT IS
VARIABLE s : BIT;
BEGIN
CASE sel IS
WHEN '0' => s := e0;
WHEN '1' => s := e1;
END CASE;
RETURN s;
END MUX_2;
PROCEDURE Add(SIGNAL a, b, c_in : IN BIT; SIGNAL s, c_out : OUT BIT) IS
BEGIN
s <= a XOR b XOR c_in;
c_out <= (a AND b) OR ((a XOR b) AND c_in);
END PROCEDURE;
SIGNAL c_i : BIT_VECTOR(4 DOWNTO 0);
SIGNAL bxorm : BIT_VECTOR(3 DOWNTO 0);
SIGNAL Ovf_m : BIT;
BEGIN
c_i(0) <= M;
ADDERS : FOR i IN 0 TO 3 GENERATE
BEGIN
bxorm(i) <= B(i) XOR M;
Add(A(i), bxorm(i), c_i(i), S(i), c_i(i + 1));
END GENERATE;
Cf <= c_i(4);
Ovf_m <= c_i(4) XOR c_i(3);
Mcov <= MUX_2(c_i(4), Ovf_m, M);
Ovf<=Ovf_m;
L’architecture (add sous arch) contient les composants suivants :
Fonction appelée MUX 2 qui implémente un multiplexeur 2 vers 1.
Une procédure appelée Add qui implémente un additionneur complet de 1 bit. Cette
procédure possède trois signaux d’entrée : a, b et cin . Elle a deux signaux de sortie : s et
cout . La procédure utilise des opérations logiques pour calculer la somme et la retenue.
Un signal appelé ci qui représente le signal de retenue pour chaque bit de l’opération.
A signal called bxorm that represents the result of the XOR operation between the input
signal B and the input signal M .
Une boucle GENERATE qui itère sur les bits des signaux d’entrée A et bxorm. Pour
chaque itération, la procédure Add est appelée pour effectuer une opération d’addition
complète de 1 bit. La sortie de chaque opération d’additionneur est stockée dans le signal
de sortie S, et le retenue de chaque opération d’additionneur complet est stockée dans le
signal ci .
24
la fonction MUX 2 est utilisée pour calculer la valeur de M cov.
Figure 32: RTL Viewer
On va tester le code via une simulation Waveform et voir s’il fonctionne correctement. On effectue
4 opérations :
1010 + 1111 = 11001 (10 + 15 = 25).
1111 + 1111 = 11110 (15 + 15 = 30).
0010 − 1010 = 1000 (2 − 10 = −8, −8 est 1000 en complément à 2).
1001 + 1110 = 1011 (9 − 14 = −5, −5 est 1011 en complément à 2).
Figure 33: Simulation Waveform
4 Détecteur de séquences:
Dans cet exercice, on va concevoir une machine capable de détecter une séquence spécifique,
0110, dans une chaı̂ne d’entrée appelée X. Si la séquence 0110 est détectée dans X, la sortie de
la machine, appelée Y , doit être égale à 1. La machine doit être capable de traiter n’importe
quelle chaı̂ne d’entrée X et de déterminer avec précision si la séquence 0110 y apparaı̂t. La sortie
Y ne doit être mise à 1 que si la séquence 0110 est détectée dans X ; sinon, elle doit rester à 0.
25
Par exemple, si la chaı̂ne d’entrée est 0110110, la machine doit pouvoir détecter que la séquence
0110 apparaı̂t deux fois dans X, et par conséquent, la sortie Y doit être mise à 1. Un diagramme
temporel du comportement attendu est donné (figure 34).
Figure 34: Diagramme temporel du comportement attendu
D’abord, on dessine le diagramme d’état de cette machine (figure 35).
1 0
E0 0 E1 0 E4
Reset
0 0 1
1 0 1 0
E2 1 E3
0 0
1
Figure 35: le diagramme d’état
Après avoir établi le diagramme d’état, on va le traduire en un programme VHDL. On peut
le faire manuellement ou utiliser l’outil ” state machine ” disponible sur Quartus, qui permet de
définir le graphe d’états (via une interface utilisateur) et de générer automatiquement un code
VHDL.
ENTITY sequence_detecteur IS
PORT (
H, X, R : IN BIT;
Y : OUT BIT
);
END sequence_detecteur;
ARCHITECTURE arch OF sequence_detecteur IS
TYPE etat IS (E0, E1, E2, E3, E4);
26
SIGNAL etat_present, etat_futur : etat;
BEGIN
PROCESS (H, R)
BEGIN
IF R = '1' THEN
etat_present <= E0;
ELSIF (H = '1' AND H'event) THEN
etat_present <= etat_futur;
END IF;
END PROCESS;
PROCESS (etat_present, X)
BEGIN
CASE etat_present IS
WHEN E0 =>
Y <= '0';
IF X = '0' THEN
etat_futur <= E1;
ELSE
etat_futur <= E0;
END IF;
WHEN E1 =>
Y <= '0';
IF X = '1' THEN
etat_futur <= E2;
ELSE
etat_futur <= E1;
END IF;
WHEN E2 =>
Y <= '0';
IF X = '1' THEN
etat_futur <= E3;
ELSE
etat_futur <= E1;
END IF;
WHEN E3 =>
Y <= '0';
IF X = '0' THEN
etat_futur <= E4;
ELSE
etat_futur <= E0;
END IF;
WHEN E4 =>
Y <= '1';
IF X = '0' THEN
27
etat_futur <= E1;
ELSE
etat_futur <= E2;
END IF;
WHEN OTHERS =>
Y <= '0';
etat_futur <= E0;
END CASE;
END PROCESS;
END arch;
Pour assurer la précision et la fiabilité de notre code, on a réalisé une simulation de ”waveform”
pour comparer la sortie de ce code avec le diagramme temporel attendu présenté dans la figure 34.
Après avoir exécuté la simulation (figure 36), on a trouvé que la sortie générée était identique
à celle montrée dans la figure, indiquant que ce code est capable de produire avec succès les
résultats désirés.
Figure 36: Simulation Waveform
5 Parcomètre:
Dans cet exercice, on va concevoir un parcmètre qui n’accepte que les pièces de 1¿ et 2¿, qui
doivent être insérées l’une après l’autre. Une fois que la machine a reçu suffisamment d’argent
pour payer le parking, elle émet un ticket et rend l’argent excédentaire. Le prix du parking est
de 3¿. À partir de l’état initial S0 , la machine passe à l’état S1 ou S2 selon qu’une pièce de 1¿
ou de 2¿ a été insérée. À la fin, elle émet un ticket (K) et la monnaie éventuelle (R).
D’abord, on dessine le diagramme d’etat de cette machine (figure 37).
28
p1 = p2 = 0
p1 = 1
S0 p2 = 0 S1 S3
Reset
K=R=0 K=R=0 p1 = 0 K=1
R=0
p2 = 1
p1 = 0 p1 = 1
p2 = 1 p2 = 0
p1 = p2 = 0
p1 = 1
S4 S2 p2 = 0
K=1 p1 = 0 K=R=0
R=1
p2 = 1
p1 = p2 = 0
Figure 37: le diagramme d’état
Où :
p1 : un signal d’entrée d’un bit qui représente la pièce de 1¿.
p2 : un signal d’entrée d’un bit qui représente la pièce de 2¿.
K : un signal de sortie d’un bit qui représente le ticket.
R : un signal de sortie à un bit qui représente la monnaie.
Après avoir établi le diagramme d’état, on va le traduire en un programme VHDL. On peut
le faire manuellement ou utiliser l’outil ” state machine ” disponible sur Quartus, qui permet de
définir le graphe d’états (via une interface utilisateur) et de générer automatiquement un code
VHDL.
ENTITY parcometre IS
PORT (
p1, p2 : IN BIT;
clk, reset : IN BIT;
K, R : OUT BIT
);
END ENTITY parcometre;
ARCHITECTURE arch OF parcometre IS
TYPE etat IS (S0, S1, S2, S3, S4);
SIGNAL etat_present, etat_futur : etat;
BEGIN
29
PROCESS (clk, reset)
BEGIN
IF (reset = '1') THEN
etat_present <= S0;
ELSIF (clk'event AND clk = '1') THEN
etat_present <= etat_futur;
END IF;
END PROCESS;
PROCESS (etat_present, p1, p2)
BEGIN
etat_futur <= etat_present;
CASE etat_present IS
WHEN S0 =>
K <= '0';
R <= '0';
IF (p1 = '1') THEN
etat_futur <= S1;
ELSIF (p2 = '1') THEN
etat_futur <= S2;
END IF;
WHEN S1 =>
K <= '0';
R <= '0';
IF (p1 = '1') THEN
etat_futur <= S2;
ELSIF (p2 = '1') THEN
etat_futur <= S3;
END IF;
WHEN S2 =>
K <= '0';
R <= '0';
IF (p1 = '1') THEN
etat_futur <= S3;
ELSIF (p2 = '1') THEN
etat_futur <= S4;
END IF;
WHEN S3 =>
K <= '1';
R <= '0';
etat_futur <= S0;
WHEN S4 =>
K <= '1';
R <= '1';
etat_futur <= S0;
30
WHEN OTHERS =>
K <= '0';
R <= '0';
etat_futur <= S0;
END CASE;
END PROCESS;
END ARCHITECTURE arch;
Pour vérifier si le code produit des résultats corrects, on crée une simulation de waveform et
on effectue les paiements suivants :
trois pièces consécutives de 1¿ (p1 = 1, 1, 1). Le résultat attendu est K = 1, R = 0.
deux pièces consécutives de 2¿ (p2 = 1, 1). Le résultat attendu est K = 1, R = 1.
Pièces de 1¿ et 2¿ (p1 = 1, p2 = 1). Le résultat attendu est K = 1, R = 0.
Comme on peut le voir sur la figure 38, la simulation confirme nos attentes.
Figure 38: Simulation Waveform
31