Préambule
Objectifs
VHDL est un langage typé où il est obligatoire de spécifier le type des objets utilisés. Le tableau ci dessous illustre la classification des types du langage VHDL :
L'objectif de ce chapitre est de vous présenter les types et les opérateurs.
A l'issue de ce chapitre, vous serez en mesure de choisir le meilleur type pour l'objet que vous voulez modéliser.
Plan du chapitre.
- Types entiers
C'est le type de base, sur 32 bits
- Types énumérés
Les types Booléens et bits font partie de cette catégorie.
- Types tableau
Indispendables pour représenter des vecteurs, des matrices, des mémoires.
- Types fichiers
Servent à effectuer des tests en lisant et/ou générant des données contenues dans ces fichiers.
- Autres types
Une vue d'ensemble des autres types définis dans les bibliothèques standards.
- Attibuts
Permettent de consulter les caractéristiques des types ou d'objets déclarés. Il est possible de déclarer ses propres attributs.
- Opérateurs
La palette d'opérateurs standards.
- IEEE
Bibliothèque utilisée par tous les outils de synthèse et permettant de travailler sur des types logiques à 9 états.
- Résumé
Remarque importante
Ce chapitre, comme tous
les chapitres sur la syntaxe des langages, est un peu indigeste. Il
vaut mieux le voir comme une référence, une page
à laquelle vous
pourrez vous rapporter tout au long du cours, ou en cas de
problème.
Par contre, il est conseillé de l'avoir lue au moins une
fois, pour
garder en tête où se trouvent les
pièges éventuels.
TYPES ENTIERS
Le type entier integer
prédéfini dans le paquetage standard STD
permet de définir
des nombres signés sur 32 bits entre -2-31
et 231 - 1 .
Un sous type subtype permet de
déclarer un type héritant des
propriétés du type père.
Il existe 2 "sous types" subtype associés
à INTEGER :
les entiers naturels et les entiers positifs. Leur
déclaration dans le paquetage STD est la suivante :
subtype natural is integer range 0 to integer'high; subtype positive is integer range 1 to integer'high
|
Notez que
- range permet
d'indiquer l'intervalle
- 'HIGH indique
la plus grande valeur du type INTEGER,
c'est un attribut de type
Les types entiers servent à définir des indices de tableaux et de boucles. Pour cela il est intéressant de les restreindre de façon à contrôler les débordements.
Par exemple on peut déclarer :
subtype UN_A_DIX is natural range (1 to 10); subtype DIX_A_UN is natural range (10 downto 1);
|
Il s'agit d'objets compatibles entre eux mais avec un ordre
d'indexation différent.
Il est donc possible d'effectuer des opérations entre ces
objets
En revanche si on avait déclaré :
type UN_A_DIX is natural range (1 to 10); type DIX_A_UN is natural range (10 downto 1);
|
Les 2 types étant indépendants, une opération entre des objets
UN_A_DIX
et
DIX_A_UN
aurait causé une erreur de compilation.
Types ENUMERE
Un type
énuméré est un type défini
par une énumération exhaustive :
type COULEURS is (ROUGE, JAUNE, BLEU, VERT, ORANGE);
|
L'ordre de déclaration est important. Lors de
l'initialisation d'un signal de type
enuméré T, le
signal prend la valeur T'LEFT.
Par exemple un signal de type COULEURS sera ROUGE en début
de simulation.
Dans le paquetage
STANDARD
de la bibliothèque
STD,
plusieurs types énumérés sont
définis :
type boolean is (FALSE, TRUE); type bit is ('0', '1'); type severity_level is (NOTE, WARNING, ERROR, FAILURE); type character is ( NUL, SOH, STX, ETX,..., '0','1', ...);
|
Notez que
la valeur d'un bit
est équivalente à un caractère et est
toujours
entre quotes : '0' et '1' différents des
entiers 0
et 1.
Dans le paquetage
STD_LOGIC_1164
de la bibliothèque
IEEE,
le type STD_ULOGIC est défini par :
type std_ulogic is ('U', 'X, 'O', '1', 'Z', 'W', 'L', 'H', '-');
|
Ce permet d'avoir 9 états significatifs de la logique. Ces états
illustrent les cas où le signal est soumis à de multiples affectations.
Dans ce cas chaque valeur à un niveau de priorité.
La liste suivante donne la signification de ces 9 valeurs en commençant
par la valeur de plus grande priorité :
- Au démarrage les signaux sont dans un état inconnu 'U'.
- 'X' indique un
conflit, le signal est affecté d'un côté à '1' et d'un
autre à '0'.
- '0' et '1' correspondant aux valeurs
booleennes du signal.
- 'Z' correspond
à l'état haute 'impédance".
- 'W' est la
valeur d'un signal relié à 2 résistances de tirage, une tirant à 0 et
l'autre à 1.
- 'H' et
'L' sont des
valeurs d'un signal relié respectivement à une
résistance de tirage à 1 et à 0.
- '-' est un
état indifférent. Utile pour décrire les tables
de vérité.
Le type énuméré est aussi très utile pour définir les états d'une
machine à états d'une façon symbolique, sans avoir à définir le codage.
TYPES TABLEAU
Les types TABLEAU ou array
sont des collections d'objets de même type,
indéxés par des entiers ou des
énumérés.
Exemples :
type bus is array (0 to 31) of bit; type RAM is array (0 to 1024, 0 to 31) of bit; type PRIX is ranger 0 to 1000; type COULEURS is (BLANC, BLEU, VERT, ROUGE, JAUNE, NOIR, ARC_EN_CIEL); type PRIX_PEINTURES is array (COULEUR range BLANC to NOIR) of PRIX;
|
Un tableau peut avoir une taille inconnue donc non contraint, par exemple le type BIT_VECTOR de la bibliothèque STD est un tableau de dimension 1 (vecteur) de taille quelconque :
type bit_vector is array (natural range <>) of bit;
|
et le type STD_ULOGIC_VECTOR de la bibliothèque IEEE :
type std_ulogic_vector is array (natural range <>) of std_logic_vector;
|
La contrainte de taille est alors exprimée dans la
déclaration de l'objet :
signal toto bit_vector(31 downto 0); signal titi std_ulogic_vector(7 downto 0);
|
Il faut noter que l'indexation peut être MSB en tête
(31 downto 0) , la plus courante,
ou LSB en tête
(0
to 31).
Attention,
une affectation de signaux vectoriels ayant des indexations différente
provoque une inversion des composantes du signal.
La valeur d'un vecteur peut être
représentée dans une base différente :
"001100" = 0"14" = X"0C"
Il peut y avoir des tableaux de tableaux ou des
tableaux à plusieurs dimensions; Les affectations
diffèrent quelque peu comme illustré dans
l'exemple
suivant :
type TAB1 is array(0 to 2) of bit_vector(7 downto 0); type TAB2 is array(0 to 3, 1 to 8) of bit; signal A : TAB1; signal B : TAB2; -- begin
A(0) <="01001111"; A(2)(5) <= '1';
B(3,5) <= '0'; -- end exemple;
|
Notation d'agrégat
Cette notation permet d'initialiser les tableaux facilement.
Exemple :
type OPTYPE is (ADD,SUB,MUL,DIV,BRA); type T is array ( 1 to 10) of OPTYPE; signal A : T; -- A <= (ADD,SUB,MUL,DIV,BRA); A <= (ADD,SUB,5=>BRA,4=>DIV,3=>MUL); A <= (ADD,2|4=>SUB,others => DIV); --
|
Cet exemple illustre l'affectation par position
et à la position par dénomination. Notez l'utilisation de la clause
'others' pour compléter
automatiquement les valeurs du tableau.
TYPES FICHIERS
Les types fichiers FILE
permet
l'échange de données entre l'extérieur
et le
simulateur VHDL. Il est utilisé principalement pour
créer des fichiers de test ou TESTBENCH
de modèles.
Le paquetage
TEXTIO de la
bibliothèque
STD
définit un type fichier texte
TEXT
et des procédures pour accéder aux lignes du
fichier et aux chaînes dans la ligne.
Pour l'utiliser il est nécessaire de le déclarer
en début de fichier :
use STD.TEXTIO.ALL;
Un fichier peut être soit en lecture soit en écriture
mais pas les 2 en même temps.
L'exemple commenté suivant illustre 2 processus permettant
respectivement de lire le fichier "
entrees.dat"
et d'écrire les résultats dans "
sorties.dat"
:
LECTURE: process variable L: line; file ENTREES: text open READ_MODE is "entrees.dat"; variable A: bit_vector(7 downto 0); variable B: natural range 0 to 11; begin readline(ENTREES, L); read(L, A); VA <= A; read(L, B); VB <= B; wait for 20 ns; end process LECTURE; -- ECRITURE: process(S) variable L: line; file SORTIES: text open WRITE_MODE is "sorties.dat"; begin write(L, S); write(L, string'(" à t = ")); write(L, now); writeline(SORTIES, L); end process ECRITURE;
|
AUTRES TYPES
Types réels
Il existe un type réel prédéfini
REAL.
Il permet de représenter des nombres entre -1.0E+38 à 1.0E+38. Il n'est pas synthétisable.
Voici quelques exemples d'affectation d'un signal de type réel :
A <= 1.0;
B <= 5.9E10;
C <= -8.5E20;
Notez la présence obligatoire du point.
Types physiques
VHDL permet de définir des types physiques pour
représenter une grandeur physique, comme le temps, la
tension, etc...
Un type physique est la combinaison d'un type entier et d'un
système d'unité.
Le type TIME, est le seul
type physique prédéfini :
type time is range $- to $+ units fs; ps = 1000 fs; ns = 1000 ps; us = 1000 ns; Ms = 1000 us; sec = 1000 ms; min = 60 sec; hr = 60 min; end units; |
Les simulateurs VHDL utilsent la fonction now, de la bibliothèque
STD , qui retourne le temps physique de type TIME.
Type STRING
Ce type permet de définir les chaînes de
caractères. Il est définit comme un
tableau
d'éléments de type CHARACTER
dans la bibliothèque STD.
type string is array (positive range <>) of character; -- "ceci est une chaîne de caractère" |
Type enregistrement RECORD
Ce type permet de définir un objet dont les
composantes sont hétérogènes.
type OPTYPE is (MOV, ADD, SUB, JMP, CALL) type INSTRUCTION is record -- OPCODE : OPTYPE; ADR : bit_vector(7 downto 0); OP2 : bit_vector(7 downto 0); -- end record; |
L'affectation d'un objet de type RECORD peut
s'effectuer de différentes façons :
signal INST1 : INSTRUCTION; signal INST2 : INSTRUCTION: -- begin -- INST1 <= (MOV, "00011100", X"FF"); INST2.ADR <= X"8A"; -- end; |
Les
RECORD sont
très utiles pour les entités dont
les ports peuvent être amenés à changer en nombre et en type. Les ports
sont alors de type
RECORD
et ne changent pas. En cas
de modification il suffit de modifier le contenu du type
RECORD plutôt que de modifier les
ports dans les entités.
Type pointeur ACCESS
Les pointeurs sont peu utilisés en VHDL car on leur
préfère les tableaux
indicés qui peuvent
être synthétisables, à la
différence des
pointeurs. Nous ne les étudieront pas
dans ce
cours.
ATTRIBUTS
Il s'agit de caractéristiques de types ou d'objet
qu'il est
possible d'utiliser dans le modèle. Ils sont
représentés de cette façon :
<OBJET>'<ATTRIBUT>
Il existe des attributs sur les types, sur les objets de type
tableau et sur les signaux.
Il est possible de créer ces propres attributs.
Certains
outils de synthèse en tirent profit pour passer des
arguments de
synthèse.
Attributs sur les types
L'exemple suivant illustre les principaux attributs de type :
type COULEUR is (BLEU, ROUGE, VERT); -- COULEUR'left renvoie BLEU COULEUR'right renvoie VERT COULEUR'pos(BLEU) renvoie 0 COULEUR'val(0) renvoie BLEU COULEUR'succ(BLEU) renvoie ROUGE COULEUR'pred(ROUGE) renvoie BLEU |
Attributs sur les objets de type tableau
exemples :
type MOT is bit_vector(7 downto 0); type TAB is array (4 downto 0) of MOT; signal NOM : MOT; signal TABLEAU : TAB;
|
MOT'LEFT renvoie 7;
MOT'LENGTH renvoie 8;
TABLEAU'RIGHT renvoie 0;
TABLEAU'RANGE renvoie 4
downto 0;
Ces attributs sont très utiles pour créer des
indices ou
pour écrire des sous-programmes manipulant des tableaux de
taille
variable.
Attributs sur les signaux
Ils servent à indiquer les caractéristiques
d'évolution temporelle des signaux.
Exemples :
CLK'EVENT renvoie un
BOOLEAN indiquant si le signal CLK
a changé.
CLK'DELAYED(1 ns) est un
signal identique à CLK décalé de 1 ns.
Attributs définis par le concepteur
Ils permettent d'associer des caractéristiques propres aux
objets. Certains outils de synthèse ont leurs propres
attributs
pour rentrer des contraintes de synthèse dans le
code.
L'exemple suivant défini le brochage de certains signaux.
Exemple :
ATTRIBUTE NUMERO_BROCHE : POSITIVE;
ATTRIBUTE NUMERO_BROCHE of ENTREE1 is
12;
ATTRIBUTE NUMERO_BROCHE of ENTREE2 is
17;
OPERATEURS
Les opérateurs prédifinis en VHDL sont
classiques. Ils
ne portent que sur les types prédéfinis, BOOLEAN,
BIT,
INTEGER. Il faut donc définir une surcharge
d'opérateur
lorsqu'il s'agit d'effectuer des opérations sur un nouveau
type.
Il faut noter l'absence du xnor et la différence
entre REM et MOD pour exprimer le reste de la division.
Type
d'opérations |
opérateurs |
notes |
Logiques |
and, or, nand, nor, xor, not |
|
Relationnels |
=, /=, < , <=, > , <= |
|
Arithmétique |
*, / , mod, rem |
(A rem B) a le signe de A
(A mod B) a le signe de B |
Divers |
**, abs, & |
** : exponentiation
abs : valeur absolue
& : concaténation |
En
résumé
On a vu:
- La diversité des types VHDL
- les attributs
- les opérateurs
Prochain chapitre
le VHDL structurel.