Introduction au VHDL

publicité
Introduction au VHDL
Introduction au VHDL
Préambule :
L'objectif de ce cours introductif est d'apprendre à décrire un circuit logique en langage
VHDL (HDL pour Hardware Description Langage), mais en se limitant à des instructions simples.
En année 4, un cours beaucoup plus détaillé sera proposé.
Néanmoins, l'ambition du propos est d'aider l'étudiant à comprendre les principes fondamentaux du
VHDL qui en font langage très particulier, à manier avec beaucoup de finesse.
1. Introduction
Le VHDL est un langage de programmation dont la vocation est de donner naissance à
un circuit logique et non à un programme exécutable. Ce circuit peut se matérialiser dans un CPLD
(Complex Programmable Logic Device) ou plus grand encore, dans un FPGA (Field Programmable
Gate Array).
Un circuit logique programmable (CPLD ou FPGA) ne doit pas être confondu avec un
micro-contrôleur. Le micro-contrôleur est une structure logique compliquée, figée, qui exécute des
instructions rangées dans une ROM ou une RAM, les unes après les autres. L'utilisateur, via des
langages de haut niveau (C, ADA, Pascal, JAVA...) ou de bas niveau (Assembleur), ne fait rien
d'autre que remplir la ROM d'instructions élémentaires que le processeur exécute une à une.
Un circuit programmable, est un ensemble de portes et de bascules élémentaires,
intégrées dans une même puce, mais déconnectées les unes des autres. L'utilisateur, via un éditeur
de schéma, ou un langage de description (Verilog, VHDL), ne fait rien d'autre que relier des portes
ou des bascules nécessaires, en vue d'obtenir une structure logique souhaitée.
Notons enfin, qu' un micro-contrôleur est une structure logique. Il est donc à ce titre,
possible de matérialiser un tel circuit dans un circuit programmable...
SFO 3MIC
1/11
Introduction au VHDL
Voici de manière très simpliste, une comparaison entre un flot de conception pour un circuit
programmable et celui corrspondant à un processeur :
JAVA/ADA/C/Assembleur
Schéma / Description VHDL
- assemblage / compilation
- édition de lien
- synthèse
- placement / routage
Programmation (mise en place
du code en ROM ou RAM)
Programmation (mise en
place des connexions)
Micro-contrôleur programmé
(le logiciel est implanté)
FPGA ou CPLD programmé
(la fonction électronique existe)
Fig. 1 : comparaison des conceptions pour processeur et
pour circuit logique programmable
Le langage VHDL peut avoir d'autres vocations que celle de réaliser un circuit. On peut
d'ailleurs distinguer deux types de descriptions VHDL :
– Les descriptions VHDL synthétisables : Elles peuvent, après implémentation (synthèse,
placement routage) donner lieu à un circuit logique bien réel. C'est de ce type de description
que nous venons de parler.
– Les descriptions VHDL non synthétisables : Elles ne peuvent pas aboutir à un circuit, à
cause de l'utilisation d'instructions n'ayant aucune réalité physique. Ceci étant, ce mode de
description peut être utile au démarrage d'une conception complexe (mais devra être
retravaillée pour la rendre synthétisable, si l'on veut aboutir à la programmation de circuits
logiques). Nous verrons également, que pour décire des stimuli (signaux de tests) lors de
simulation, cette manière d'écrire est tout à fait appropriée.
SFO 3MIC
2/11
Introduction au VHDL
2. Structure d'un fichier VHDL
Un fichier VHDL est constitué de deux parties. La première est la description des
entrées et sorties de la fonction réalisée ( Entity ). Son rôle est de définir le nom, la direction, le
type et la taille des connexions d'entrées et de sortie.
Exemple :
Ici, on trouve 3 entrées binaires et une
sortie de type bus à 4 fils. Le type utilisé
est std_logic, ou std_logic_vector (pour
un bus). Il peut prendre plusieurs états
(autre que 0 ou 1) :
Valeurs d'un std_logic :
L'architecture, seconde partie du fichier VHDL décrit le
fonctionnement du circuit :
'U' – Uninitialized
'X' – Forcing Unknown
'1' – Forcing 1
'0' – Forcing 0
'Z' – High impedance
'W' – Weak Unknown
'H' – Weak 1
'L' – Weak 0
'-' - Don't care
3. Structuration d'une architecture, process
Une architecture doit être vue, pensée comme un circuit logique. Tout comme un circuit
peut se décomposer en sous-circuits, une architecture qui décrit une logique compliquée peut être
décomposée en plusieurs parties. En VHDL, ces divers sous-circuits sont décrits par des process
(processus).
La notion de processus est centrale en VHDL. Du point de vue langage, un processus est
un bloc qui contient une suite d'instructions séquentielles (au sens algorithme) qui a une durée
d'exécution nulle (la notion d'exécution n'a pas de sens en VHDL) qui est en sommeil la plupart du
SFO 3MIC
3/11
Introduction au VHDL
temps, qui se réveille sur évènement particulier. Un processus active des sorties (selon l'algorithme
décrit). Celles-ci sont mises à jour lorsque le processus retombe en sommeil, c'est à dire à la fin de
son traitement. A l'intérieur d'un processus, un signal ne change donc pas d'état.
Du point de vue circuit, une architecture dotées de plusieurs process peut se schématiser comme de
la manière suivante :
Frontière de l’entité
Signal de type INOUT
Architecture VHDL
Architecture Arch of .. is
Begin
F2
F1
F3
A
C
Process(…)
…
End Process ;
B
Signaux
de type IN
Signaux
de type OUT
F4
liste de
se n sibilité
Process(…)
…
End Process ;
Process(…)
…
End Process ;
C<=A AND B ;
End arch;
Fig. 2 : Association process – structure logique
Dans cet exemple, F1, F2 et F4 sont des blocs logiques lourds nécessitant une
description comportementale, on utilise donc 3 processus. Par contre F3 est une fonction triviale,
parfaitement définissable.
avec les opérateurs logiques de base (pas besoin de processus explicite). Notons tout de même, qu'il
s'agit bien d'un processus (implicite).
Ces 4 ensembles sont dits concurrents car le déroulement de chacun d’eux est indépendant. L'ordre
dans lequel on écrit les divers process est donc sans importance.
SFO 3MIC
4/11
Introduction au VHDL
Pour comprendre un peu mieux le concept, analysons de près l'architecture du compteur
décrit précédemment :
Process 1
On distingue dans cette description deux process. Le
second est ultra simple et implicite. C'est juste la liaison
du signal interne Q_int vers la sortie de l'architecture, Q.
Le premier mérite une explication. Tout d'abord, il
contient deux signaux dans sa liste de sensibilité.
⇒ il se réveillera sur la variation de H ou de RAZ
⇒ le signal d'entrée UP_DOWN peut toujours changer,
il ne réveillera pas le process. Du point de vue
électronique, il n'affectera pas directement la sortie.
NB: L'entrée d'un circuit logique ne fait pas
forcément partie de la liste de sensibilité, loin de là.
Process 2
L'entrée RAZ est de type asynchrone. En effet, dès que
son état change, elle est susceptible de mettre à 0 la
sortie du process Q_int sans attendre de front d'horloge.
Dès que H ou RAZ évoluent, la sortie du process Q_int est évaluée instantanément. Pour
le lecteur, cette instantanéité est discutable, puisqu'il faut lire l'ensemble du process (ça prend du
temps !) pour évaluer, en fin de process, la valeur de Q_int.
Dès que le process est actif, il faut imaginer qu'une photo est prise de l'ensemble des
signaux d'entrée du process, y compris Q_int (entrée-sortie). La nouvelle valeur de Q_int sera celle
qui correspond à la dernière affectation.
Par exemple, si à l'intérieur d'un process on écrit :
Q_int = Q_int+1;
Q_int = Q_int+1;
Q_int = Q_int+1;
Avec au départ Q_int = 2, alors quand le process retombe en sommeil (se termine), Q_int vaut 3 et
pas 5 ! En effet, en cours de process, Qint est figé. Les premières lignes sont donc “oubliées” au
profit de la dernière qui prend effet lorsque le process se rendort (si en cours de route, Q_int n'a pas
été une fois encore retouchée...)..
La structure if then else de l'horloge est dépourvue de else. Cela produit un effet mémoire. En effet,
du point de vue du signal H, Q_int est affecté UNIQUEMENT lorsqu'il y a front montant. En
dehors de cet évènement, rien n'est spécifié dans le process. Q_int demeure inchangé. On appelle
cela l'effet mémoire par omission. Ici c'est voulu, mais parfois, lorsqu'on débute, cet oubli
involontaire lors de la description d'un circuit logique combinatoire est catastrophique, puisqu'il
crée une bascule qui n'a rien à faire là !
SFO 3MIC
5/11
Introduction au VHDL
4. Des exemples de descriptions de circuits usuels..
4.1 Un décodage d'adresse :
Version avec un process
Cette version utilise un process
explicite. Les 3 signaux sont donc
déterminé
par
un
algorithme
(comportement attendu).
Notons qu'il s'agit d'une logique
combinatoire : à toute combinaison
d'entrée correspond une et une seule
combinaison de sortie. Ainsi, toute
variation d'une entrée a une
conséquence directe sur la sortie. C'est
pourquoi le bus Ad apparaît dans la
liste de sensibilité.
Deux remarques très importantes :
- Dans chaque condition, l'ensemble
des 3 signaux de sortie est déteminé :
pas d'effet mémoire par omission
- dans le même esprit, la structure if
then se finit par un else. Autrement dit,
toutes les combinaisons d'entrée sont
explorées.
Version sans process
Voici une description possible. Elle est
plus élégante, nécessite moins de
lignes et parfaitement adaptée à la
conception de logique combinatoire.
Chaque ligne décrit une sortie, et
l'instruction de termine par un else, qui
garantit l'aspect combinatoire.
SFO 3MIC
6/11
Introduction au VHDL
4.2 Un buffer 3 états, 8 bits
On retrouve ici la même construction
que la précédente (adaptée à une
logique combinatoire).
On y observe la manière de créer, en
VHDL le “fameux état HZ “ (haute
impédance).
Si OE (pour Output Enable) = '1' , la
sortie Dout se retrouve connectée à
l'entrée Din. Ce sont des bus 8 bits.
Dans le cas contraire, le bus de sortie
est “en l'air” au sens physique du
terme, comme un interrupteur ouvert (8
en parallèle ici) .
4.3 Un multiplexeur 8 bits
Ici encore, le circuit décrit est
combinatoire.
Il utilise la construction With Select...
On peut observer que ce multiplexeur a
sa sortie reliée à E2 pour les
combinaisons autres que “00” et “01”.
Ceci garantit l'aspect combinatoire du
circuit décrit.
4.4 Une bascule RS
La bascule RS, de type logique séquentielle asynchrone est décrite par un
process.
Sa liste de sensibilité contient les signaux R (reset) et S (set) puique les
deux entrées commandent directement la sortie.
NB: Comme toutes les bascules RS, il n'y a pas “d' état interdit”
contrairement à l'idée reçue. Simplement, il existe en effet une combinaison
qui peut paraître un peu stupide, à savoir positionner simultanément R et S
à 1.
Toute bascule est à Set prioritaire ou Reset prioritaire (l'une des entrées
l'emporte sur l'autre). Ainsi, lorsque le cas se présente la sortie prend la
valeur '1' ou '0'.
Dans l'exemple, c'est le Set qui a la priorité . En effet, si les deux signaux
sont à '1', le process se réveille, la structure if-elsif est évaluée, et c'est la
première condition vraie qui l'emporte, à l'exclusion des autres (par
définition de la structure if, elsif...).
SFO 3MIC
7/11
Introduction au VHDL
4.5 Une bascule D, avec set et reset asynchrone
Les entrées de la bascule sont au nombre de 4
(D, R, S et C). La dernière est l'horloge. La
première est une entrée à action synchrone
(son effet sur la sortie ne se fera sentir qu'au
front d'horloge). C'est pour cette raison qu'elle
ne fait pas partie de la liste de sensibilité.
Au contraire, R et S sont à action asynchrone :
elles agissent immédiatement sur la sortie. Elles
font partie de la liste de sensibilité.
Pour la sortie Q, l’ordre de priorité est Set, puis
Reset, puis le fonctionnement en bascule D.
Chronogrammes :
reset
Forçage
set, malgré
reset
Copie de D
4.6 Une bascule D, avec set et reset synchrone
Toutes les entrées sont à action synchrone.
Ainsi, seul un front montant de C affecte la
sortie, en fonction, de S, R, et D.
Ici encore, on observe le même ordre de
priorité.
Chronogrammes :
État
indéterminé
SFO 3MIC
reset
Copie de D
8/11
reset
Forçage
set, malgré
reset
Introduction au VHDL
5. Le test des descriptions VHDL
Le test d'un design VHDL se fait par un fichier que l'on appelle testbench (banc d'essais), lui-même
écrit en VHDL. Voici par exemple, celui qui a permis l'obtention des chronogrammes précédents
(bascule D avec Set et Reset) :
Entitée vide (pas d'entrée,
pas de sortie).
Inclusion du composant à
tester (UUT : Unit Under
Test)
Signaux internes qui sont
précisément les stimili
Câblage entre les stimuli (les signaux internes),
et les entrées / sorties de l'UUT
Horloge écrite par une équation logique + l'instruction non
synthétisable after
Descriptions temporelles de chaque signal avec l'instruction after
On remarque que le coeur du test est écrit avec une syntaxe non synthétisable puisque ces tests n'ont
justement pas pour vocation de donner un circuit logique.
NB: Après l'instruction after, le temps qui est donné est absolu, c'est à dire qu'il s'agit de dates
référencées par rapport à l'origine 0.
NB: Les signaux internes de test sont initialisés à 0. Ce n'est pas une obligation sauf pour l'horloge.
En effet, celle-ci est décrite par une rétroaction sur elle-même, ce qui nécessite une valeur de
démarrage.
SFO 3MIC
9/11
Introduction au VHDL
On peut aussi rédiger les stimuli en utilisant un process qui se réveille à des instants particuliers. En
effet, nous avons vu que la liste de sensibilité détermine les signaux susceptibles de réveiller un
process. Une autre possibilité est de garder une liste vide, mais d'utiliser à la place l'instruction wait.
Voici pour exemple, un extrait du test du compteur possédant une entrée de remise à zéro et une
entrée qui précise le sens de comptage, vu au chapitre 2.
Horloge écrite par une équation logique + l'instruction
non synthétisable after
Process qui décrit la séquence temporelle de
l'ensemble des signaux
NB: Les valeurs de temps données dans les intructions wait for, sont relatives. Cela veut dire, dans
cet exemple, que le signal RAZ passera à 0, à la date 220 + 10 = 230ns.
Nous allons maintenant présenter un dernier test, un peu plus évolué, qui sert pour tester le
décodeur d'adresses présenté au paragraphe 4.1.
Il s'agit de réaliser un test où TOUTES les adresses possibles sont évaluées. Ceci se fait bien
entendu par un compteur 16 bits que l'on réalise dans le testbench suivant :
SFO 3MIC
10/11
Introduction au VHDL
Architecture qui décrit le test :
Compteur 16 bits
Le bus Ad du décodeur d'adresses est relié à Q_int (sortie du compteur). Ceci est réalisé dans le bloc
PORT MAP.
Les initialisations de Q_int et H sont obligatoires ici. Sans ça, le compteur ne peut jamais démarrer.
Auteur :
Thierry ROCACHER
SFO 3MIC
11/11
Téléchargement