Académique Documents
Professionnel Documents
Culture Documents
Chapitre 02 :
Concepts de base du langage VHDL
Objectives du cours
Introduction au langage de description matérielle VHDL
Comprendre la structure du code VHDL
Différencier entre un type de donné prédéfini et un type défini par l’utilisateur
Comprendre les opérateurs et les attributs en VHDL
Comprendre l’utilité des objets de donnée dans la description des circuits numériques.
VHDL est l'acronyme de langage de description matérielle VHSIC (Very High Speed Integrated
Circuit) et résulte d'une initiative financée par le ministère de la Défense des États-Unis dans les
années 1980. Il a été le premier langage de description matérielle normalisé par l'IEEE, par le biais des
normes 1076 et 1164.
Le VHDL permet la synthèse de circuits ainsi que la simulation de circuits. La première est la
traduction d'un code source en une structure matérielle qui implémente les fonctionnalités spécifiées ;
la seconde est une procédure de test pour s'assurer que ces fonctionnalités sont réalisées par le circuit
synthétisé.
Une fois que le code VHDL a été écrit, il peut être utilisé soit pour implémenter le circuit dans un
dispositif de carte programmable (Altera, Xilinx, Atmel, etc.) ou peut être soumis à une fonderie pour
la fabrication d'une puce ASIC. Actuellement, de nombreuses puces commerciales complexes sont
conçues selon une telle approche.
Déclarations
LIBRARY
ARCHITECTURE
Pour déclarer une librairie, deux lignes de code sont nécessaires, l'une pour déclarer la
LIBRARY et l'autre mot clé USE pointant vers le paquet spécifique dans la librairie, comme
illustré ci-dessous
LIBRARY Nom de la bibliothèque;
USE Nom de la Bibliothèque. Nom du Package. Partie du Package;
Library ieee
Package std_logic_1164 : Définit le type à neuf valeurs STD_ULOGIC et son sous-
type résolu STD_LOGIC (8 états). Seuls les opérateurs logiques sont inclus, ainsi que
certaines fonctions de conversion de type.
Package numeric_ std : Définit les types numériques SIGNED et UNSIGNED, avec
STD_LOGIC comme type de base. Comprend également les opérateurs logiques,
arithmétiques, de comparaison et de décalage.
2.2.2. Entity
L'entité est une liste avec les spécifications de tous les ports d'E/S en cours de conception.
Elle permet également de déclarer des paramètres génériques, ainsi que plusieurs autres
ENTITY nomEntity IS
[GENERIC (nom de constante : type de constante := valeur de constante ;
nom de constante : type de constante := valeur de constante ;
. . .);]
PORT (nom du port: mode de signal type de signal;
nom du port: mode de signal type de signal;
. . .);
END nomEntity;
2.2.3. Architecture
L'architecture est la description du comportement interne du circuit. Cette partie contient le
code proprement dit. Il peut être concurrent ou séquentiel. Sa syntaxe est présentée ci-dessous
Partie déclarative (facultative) : Peut contenir des objets de données de type SIGNAL,
plus les déclarations COMPONENT.
Code : Peut-être concurrent, séquentiel ou mixte. Pour être séquentiel, les déclarations
doivent être placées à l'intérieur d'un PROCESS. Cependant, dans son ensemble, le code
VHDL est toujours concurrent, ce qui signifie que toutes ses parties sont traitées en
"parallèle", sans priorité. Par conséquent, tout PROCESS est compilé de manière
concurrente avec toutes les autres instructions situées à l'extérieur de celui-ci.
(a) (b)
SOLUTION
Un code VHDL pour cet exemple est présenté à la Figure 2.4. Notez qu'il contient les trois
sections de code décrites ci-dessus. Le paquetage supplémentaire est précisément
std_logic_1164 (lignes 2 et 3).
L'entité se trouve aux lignes 5 à 9, sous le nom de Multiplexeur4vers1 (n'importe quel nom
peut être choisi sauf les mots réservés en VHDL) et contient trois signaux d'entrée et un signal
de sortie (notez les modes IN et OUT). Les signaux a à d et y ont une largeur de 8 bits et sont
de type STD_LOGIC_VECTOR; dans a et b et y, l'indexation va de 7 à 0. Le type de sel a été
déclaré comme INTEGER, bien qu'il puisse également être BIT, entre autres options.
L'architecture est dans les lignes 11-18, avec le nom myarch (peut être n'importe quel nom, y
compris le même nom que celui de l'entité). Dans sa partie déclarative (entre les mots
ARCHITECTURE et BEGIN), aucun signal interne n’a été déclaré. L'Affectation sélection
(décrite en détails dans le chapitre prochain) est utilisé pour décrire le fonctionnement du
circuit Multiplexeur come on peut le voir aux lignes 13-17.
Notez que les lignes 1, 4, 10 et 19 ont été incluses uniquement pour améliorer l'organisation et
la lisibilité du code (" -- " est utilisé pour les commentaires). Enfin, le VHDL n'est pas
sensible à la casse, mais pour faciliter la visualisation des lettres majuscules ont été employées
pour les mots VHDL réservés.
Figure 2.4. Code VHDL pour le circuit de la figure 2.3 (exemple 2.2).
x <= '1';
-- x est un signal à un seul bit, dont la valeur est '1'.
-- Notez que des guillemets simples (' ') sont utilisés pour un bit unique.
y <= "0111";
-- y est un signal de 4 bits, dont la valeur est "0111" (MSB='0').
-- Notez que des guillemets doubles (" ") sont utilisés pour les vecteurs.
signed(taille_vecteur) et unsigned(taille_vecteur)
Exemples:
SIGNAL y: signed (3 DOWNTO 0);
-- y est un vecteur de 4 bits de valeurs positives ou négatives.
SIGNAL y: unsigned (3 DOWNTO 0);
-- y est un vecteur de 4 bits de valeurs positives.
Exemples :
x1 <= "00101011’’; --bit, bit_vector, signed, or unsigned
x2 <= "0010_1011’’ ; --le trait de soulignement est autorisé pour faciliter la visualisation
x3 <= ‘‘10011’’ ; --Représentation binaire de la valeur décimale 19
x4 <= B‘‘10011’’ ; --Représentation binaire de la valeur décimale 19
x5 <= O‘‘23’’ ; --Représentation octal de la valeur décimale 19
x6 <= X‘‘13’’ ; --Représentation hexadécimal de la valeur décimale 19
n <= 1500 ; --Entier
m <= 1_500 ; --Entier, le trait de soulignement est autorisé
IF lecture THEN --Boolean, execute IF lecture=TRUE
Comme mentionné précédemment dans la section 2.2.1.1, ces types sont définis dans le
package std_logic_arith de la bibliothèque ieee. Leurs syntaxes sont illustrées dans les
exemples ci-dessous.
Exemples :
SIGNAL x: SIGNED (7 DOWNTO 0);
SIGNAL x: UNSIGNED (0 TO 3);
Remarquez que leur syntaxe est similaire à celle de STD_LOGIC_VECTOR, et non à celle
d'un INTEGER, comme on aurait pu s'y attendre.
Une valeur UNSIGNED est un nombre jamais inférieur à zéro. Par exemple, "0101"
représente le chiffre décimal 5, tandis que "1101" signifie 13. Si l'on utilise plutôt le type
SIGNED, la valeur peut être positive ou négative (au format complément à deux). Ainsi,
"0101" représenterait la valeur décimale 5, tandis que "1101" signifierait -3.
Pour utiliser les types de données SIGNED ou UNSIGNED, il faut déclarer le package
std_logic_arith, de la bibliothèque ieee. Malgré leur syntaxe, les types de donnée SIGNED ou
UNSIGNED sont principalement destinés aux opérations arithmétiques, c'est-à-dire que,
contrairement à STD_LOGIC_VECTOR, ils acceptent les opérations arithmétiques. En
revanche, les opérations logiques ne sont pas autorisées. En ce qui concerne les opérations
relationnelles (comparaison), il n'y a pas de restrictions.
Exemple : Opérations Légal ou Illégal avec des types de donnée SIGNED/ UNSIGNED
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL ;
USE IEEE.STD_LOGIC_ARITH.ALL ; -- Package STD_LOGIC_ARITH est nécessaire
…
SIGNAL a : SIGNED (7 DOWNTO 0);
SIGNAL b : SIGNED (7 DOWNTO 0);
SIGNAL x : SIGNED (7 DOWNTO 0);
….
v <= a + b; -- légal (opération arithmétique AUTORISER)
w <= a AND b; --illégal (opération logique PAS AUTORISER)
…..
SIGNAL a : STD_LOGIC_VECTOR (7 DOWNTO 0);
SIGNAL b : STD_LOGIC_VECTOR (7 DOWNTO 0);
SIGNAL x : STD_LOGIC_VECTOR (7 DOWNTO 0);
….
v <= a + b; -- illégal (opération arithmétique PAS AUTORISER)
w <= a AND b; -- légal (opération logique AUTORISER)
Malgré la contrainte mentionnée ci-dessus, il existe un moyen simple de permettre aux
données de type STD_LOGIC_VECTOR de participer directement aux opérations
arithmétiques. Pour cela, la bibliothèque ieee fournit deux packages, std_logic_signed et
std_logic_unsigned, qui permettent d'effectuer des opérations avec de donnée
STD_LOGIC_VECTOR comme si les donnée étaient de type SIGNED ou UNSIGNED,
respectivement.
Exemple : Opérations arithmétiques avec STD_LOGIC_VECTOR.
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL ; -- Package STD_LOGIC_ARITH n’est pas nécessaire
USE IEEE.STD_LOGIC_UNSIGNED.ALL ; -- Package STD_LOGIC_UNSIGNED inclus
…….
SIGNAL a : STD_LOGIC_VECTOR (7 DOWNTO 0);
SIGNAL b : STD_LOGIC_VECTOR (7 DOWNTO 0);
SIGNAL x : STD_LOGIC_VECTOR (7 DOWNTO 0);
….
v <= a + b; -- légal (opération arithmétique AUTORISER)
w <= a AND b; -- légal (opération logique AUTORISER)
Syntaxe:
Exemples:
Syntaxe:
Exemples:
TYPE ma_logique IS (‘0’, ‘1’ , ‘Z’) ; -- Un sous-ensemble défini par l'utilisateur de STD_LOGIC
TYPE couleur IS (vert, rouge, bleu, blanc);
TYPE etatMachine IS (arret, marche, defaillant);
Exemples : Les sous-types ci-dessous sont dérivés des types présentés dans les exemples
précédents.
SUBTYPE natural IS INTEGER RANGE 0 TO INTEGER 'HIGH ;
-- Comme prévu, NATURAL est un sous-type (sous-ensemble) de INTEGER.
La figure 2.6 illustre la construction de tableaux de données. Une valeur unique (scalaire) est
représentée en (a), un vecteur (tableau 1D) en (b), un tableau de vecteurs (tableau 1Dx1D) en
(c), et un tableau de scalaires (tableau 2D) en (d).
En effet, les types de donnée VHDL prédéfinis (vus dans la section 2.3) ne comprennent que
les catégories scalaire (un seul bit) et vectorielle (tableau unidimensionnel de bits). Les types
prédéfinis synthétisables dans chacune de ces catégories sont les suivants :
Scalaires : BIT, STD_LOGIC, STD_ULOGIC, and BOOLEAN.
Figure 2.6. Illustration des tableaux de données, (a) scalaire, (b) 1D, (c) , et (d) 2D.
Comme on peut le constater, il n'y a pas de tableaux 2D ou 1Dx1D prédéfinis, qui, le cas
échéant, doivent être spécifiés par l'utilisateur. Pour ce faire, le nouveau TYPE doit d'abord
être défini, puis le nouveau SIGNAL, VARIABLE ou CONSTANTE peut être déclaré en
utilisant ce type de donnée. La syntaxe ci-dessous doit être utilisée.
Pour spécifier un nouveau type de tableau :
Dans la syntaxe ci-dessus, un SIGNAL a été déclaré. Cependant, il pourrait également s'agir
d'une CONSTANTE ou d'une VARIABLE. Notez que la valeur initiale est facultative (pour la
simulation uniquement).
Il s'agit alors d'un tableau 1Dx1D (voir figure 2.6). Appelons chaque vecteur par vector, et le
tableau complet par matrix.
L'implémentation du tableau serait alors la suivante (remarquez qu'un signal, appelé x, de type
matrix, a été déclaré à titre d'exemple) :
Exemples :
sig1 <= '1'; -- affectation à un signal à un seul bit
sig2 <= "00001111"; -- affectation à un signal multibit
sig3 <= (OTHERS => '0'); --résultat est sig3 <= "00...0"
VARIABLE var1: INTEGER := 0; -- affectation de la valeur initiale
var2 := "0101"; -- affectation à une variable multibit
2.6.3. Opérateurs logiques NOT, AND, NAND, OR, NOR, XOR, XNOR
Le seul opérateur logique ayant la priorité sur les autres est NOT.
Exemples :
x <= a NAND b; -- résultat: x = (a.b)'
y <= NOT(a AND b); -- résultat: comme ci-dessus
z <= NOT a AND b; -- résultat: x = a'. b
Exemples :
x <= (a + b)**N;
y <= ABS(a) + ABS(b);
Responsable de cours : Fatah YAHIAOUI
16 Concepts de base du langage VHDL
Exemples :
a <= "11001";
x <= a SLL 2; --résultat: x <= "00100"
y <= a SLA 2; --résultat: y <= "00111"
Exemple :
IF a >= b THEN x <= '1';
2.7. Attributs
Les attributs VHDL prédéfinis peuvent être répartis dans les trois catégories suivantes :
Puis :
d'LOW=0, d'HIGH=7, d'LEFT=7, d'RIGHT=0, d'LENGTH=8, d'RANGE=(7 downto 0),
d'REVERSE_RANGE=(0 to 7).
Exemple : Considérons le signal suivant :
SIGNAL x : STD_LOGIC_VECTOR (0 TO 7) ;
Alors les quatre instructions LOOP ci-dessous sont synthétisables et équivalentes.
FOR i IN RANGE (0 TO 7) LOOP ...
FOR i IN x'RANGE LOOP ...
FOR i IN RANGE (x'LOW TO x'HIGH) LOOP ...
FOR i IN RANGE (0 TO x'LENGTH-1) LOOP ...
Bien que la plupart des attributs de signaux ne servent qu'à des fins de simulation, les deux
premiers de la liste ci-dessus sont synthétisables, s'EVENT étant le plus utilisé d'entre eux.
2.8.1. CONSTANT
Une constante peut être déclarée et utilisée pratiquement partout (entité, architecture, package,
composant, bloc, configuration et sous-programmes). Sa syntaxe est présentée ci-dessous.
(Les constantes peuvent également être déclarées à l'aide de l'instruction GENERIC vue à la
section Entity).
Syntaxe :
CONSTANT nom_objet : Type := valeur;
Exemples:
CONSTANT ensembles_bit : BIT_VECTOR := “1001”;
CONSTANT n : NATURAL := 6;
2.8.2. SIGNAL
Les signaux définissent les E/S du circuit et les fils internes. Sa syntaxe est présentée ci-
dessous. La valeur initiale n'est là encore que pour les simulations.
Syntaxe :
SIGNAL nom_objet : Type [:= valeur_initiale];
Exemples:
SIGNAL control: BIT := '0';
SIGNAL count: INTEGER RANGE 0 TO 100;
SIGNAL y: STD_LOGIC_VECTOR (7 DOWNTO 0);
circuit
entity circuit is
port ( A,B,C : in std_logic;
So, Sb : out std_logic);
end circuit;
architecture descrip1 of circuit is
begin
So <= A and B or C;
S<= not So;
end descrip1;
entity circuit is
port ( A,B,C : in std_logic;
So, Sb : out std_logic);
end circuit;
architecture descrip1 of circuit is
signal output : std_logic;
begin
output <= A and B or C;
So<= output;
Sb<= not output;
end descrip1;
2.8.3. VARIABLE
Les variables ne peuvent être déclarées et utilisées que dans des sous-programmes
(PROCESS, FUNCTION, ou PROCEDURE dans notre définition plus large), elles ne
représentent donc que des informations locales. Sa syntaxe est présentée ci-dessous. La valeur
initiale n'est là encore que pour les simulations.
Syntaxe :
VARIABLE nom_objet : Type [:= valeur_initiale];
Exemples:
VARIABLE control: BIT := '0';
VARIABLE count: INTEGER RANGE 0 TO 100;
VARIABLE y: STD_LOGIC_VECTOR (7 DOWNTO 0) ;