Leçon 4 sur 22

Chapitre 4 — Types de données et objets VHDL

Objectif — Finalité du chapitre

Choisir des objets et des types adaptés à une description matérielle, comprendre leur comportement en simulation et en synthèse, effectuer des opérations numériques fiables et maîtriser les conversions nécessaires entre entiers et vecteurs.

Objectifs pédagogiques

À la fin de ce chapitre, l’étudiant devra être capable de :

  • distinguer un signal, une variable, une constante et un objet fichier ;
  • expliquer les différences de mise à jour entre un signal et une variable ;
  • choisir entre bit, boolean, std_logic et leurs formes vectorielles ;
  • interpréter les neuf valeurs du type std_logic ;
  • utiliser correctement integer, natural, positive, signed et unsigned ;
  • réaliser des opérations arithmétiques avec IEEE.NUMERIC_STD ;
  • déclarer des types énumérés, tableaux, enregistrements et sous-types ;
  • convertir un entier en vecteur et un vecteur en entier ;
  • identifier les incompatibilités de types et corriger les erreurs de compilation ;
  • justifier le type choisi en fonction du matériel à décrire.

Prérequis

  • structure générale d’une entité et d’une architecture VHDL ;
  • bibliothèques IEEE et clauses library/use ;
  • ports d’entrée et de sortie ;
  • opérations logiques binaires et représentation binaire des nombres.

Organisation du chapitre

Section

Contenu

Compétence principale

4.1Objets VHDLChoisir le support d’une valeur
4.2Types logiquesReprésenter des états logiques
4.3Valeurs de std_logicInterpréter simulation et trois états
4.4Types numériquesReprésenter et calculer des nombres
4.5numeric_stdEffectuer une arithmétique portable
4.6Autres typesModéliser des données structurées
4.7ConversionsPasser explicitement d’un type à un autre
TDExercices et correctionsAppliquer les règles de typage

 

Concept clé — Principe fondamental

VHDL est fortement typé : deux valeurs de même représentation binaire ne sont pas automatiquement compatibles. Les types documentent l’intention du concepteur et permettent au compilateur de détecter de nombreuses erreurs.

 

4.1 Objets VHDL

Un objet VHDL est un élément nommé qui possède un type et qui peut contenir ou représenter une valeur. Les principaux objets sont le signal, la variable, la constante et le fichier. Leur portée, leur mode d’affectation et leur comportement temporel sont différents.

4.1.1 Vue d’ensemble

Objet

Affectation

Mise à jour

Usage principal

Signal<=Après l’exécution du processus, lors d’un cycle delta ou à la date planifiéeConnexions matérielles et communication entre processus
Variable:=Immédiatement dans le processus ou sous-programmeCalculs intermédiaires et algorithmes locaux
Constante:= à la déclarationJamais modifiéeParamètres fixes et valeurs symboliques
FichierOpérations de lecture/écritureSelon les appels de sous-programmesStimuli, résultats et modèles de simulation

 

4.1.2 Signal

Un signal représente une connexion ou une information observable par plusieurs instructions concurrentes. Il peut correspondre à une entrée, une sortie, un fil interne, un registre ou un bus. Une affectation de signal planifie une nouvelle valeur ; elle ne modifie pas nécessairement le signal immédiatement.

Déclaration et affectation d’un signal  |  VHDL
architecture rtl of exemple_signal is
    signal resultat_interne : std_logic;
begin
    resultat_interne <= a and b;
    y <= resultat_interne;
end architecture rtl;

 

  • Un signal est déclaré dans une architecture, une entité, un bloc ou un paquetage.
  • Il utilise l’opérateur d’affectation <=.
  • Il peut déclencher un processus lorsqu’il change de valeur.
  • Il peut conserver un historique temporel en simulation.
  • Plusieurs pilotes sont possibles seulement si le type dispose d’une fonction de résolution, comme std_logic.

4.1.3 Variable

Une variable est locale à un processus, une fonction ou une procédure, sauf cas particuliers de variables partagées. Son affectation avec := prend effet immédiatement dans le flot séquentiel courant. Elle est utile pour calculer un résultat intermédiaire avant de l’affecter à un signal.

Variable dans un processus combinatoire  |  VHDL
process(a, b, c)
    variable temp : std_logic;
begin
    temp := a and b;
    temp := temp or c;
    y <= temp;
end process;

 

Lecture — Interprétation

La deuxième affectation de temp utilise immédiatement la valeur obtenue par la première. La sortie y reçoit ensuite la valeur finale de la variable.

 

4.1.4 Constante

Une constante est associée à une valeur fixe. Elle améliore la lisibilité, évite la répétition de valeurs littérales et facilite la modification d’un paramètre de conception.

Constantes locales  |  VHDL
architecture rtl of temporisateur is
    constant FREQUENCE_HZ : positive := 50_000_000;
    constant DUREE_MS     : positive := 10;
    constant NB_CYCLES    : positive :=
        FREQUENCE_HZ / 1000 * DUREE_MS;
begin
    -- Utilisation de NB_CYCLES dans la logique
end architecture rtl;

 

  • Une constante doit être initialisée lors de sa déclaration.
  • Elle peut être scalaire, vectorielle, énumérée ou structurée.
  • Elle peut dépendre d’un générique ou d’une autre constante.
  • Le synthétiseur remplace généralement la constante par sa valeur.

4.1.5 Fichier

L’objet fichier permet d’accéder à des données externes. Il est surtout utilisé dans les bancs de test pour lire des vecteurs de test, écrire des résultats ou comparer des sorties. Les accès aux fichiers ne sont généralement pas synthétisables pour construire directement du matériel.

Déclaration d’un fichier texte  |  VHDL
library STD;
use STD.TEXTIO.ALL;

architecture simulation of tb_exemple is
    file fichier_entree : text open read_mode is
        "stimuli.txt";

    file fichier_sortie : text open write_mode is
        "resultats.txt";
begin
    -- Processus de lecture et d'écriture
end architecture simulation;

 

Attention — Synthèse

Un fichier peut servir à initialiser certaines mémoires selon l’outil, mais l’ouverture et la lecture séquentielle d’un fichier pendant le fonctionnement du circuit sont des opérations de simulation, pas du matériel autonome.

 

4.1.6 Différence entre signal et variable

La différence principale concerne la date de prise en compte de l’affectation. Dans un processus, une variable est mise à jour immédiatement, tandis qu’un signal reçoit sa nouvelle valeur après la suspension du processus ou selon le retard planifié.

Comparaison directe  |  VHDL
process(clk)
    variable v_compteur : integer := 0;
begin
    if rising_edge(clk) then
        v_compteur := v_compteur + 1;
        signal_compteur <= signal_compteur + 1;

        sortie_variable <= v_compteur;
        sortie_signal   <= signal_compteur;
    end if;
end process;

 

Critère

Signal

Variable

Opérateur<=:=
Mise à jourPlanifiéeImmédiate
Portée typiqueArchitecture ou entitéProcessus ou sous-programme
Communication entre processusOuiNon, sauf variable partagée
Modélisation naturelleFil, bus, registre, état visibleCalcul intermédiaire
Valeur lue après affectationAncienne valeur jusqu’à la mise à jourNouvelle valeur immédiatement

 

4.1.7 Exemple révélant la différence

Signal et variable affectés deux fois  |  VHDL
process(a)
    variable v : integer := 0;
begin
    s <= 1;
    s <= 2;

    v := 1;
    v := 2;

    sortie_s <= s;
    sortie_v <= v;
end process;

 

Sans retard explicite, les deux affectations de s planifient des transactions pour le même instant ; la dernière remplace généralement la précédente. La variable v vaut immédiatement 2. La lecture de s dans le même processus renvoie encore son ancienne valeur, tandis que la lecture de v renvoie 2.

Bonne pratique — Règle pratique

Utiliser les signaux pour les communications et les éléments matériels visibles. Utiliser les variables pour les calculs locaux, en restant conscient qu’une variable dans un processus cadencé peut aussi conduire à du matériel synthétisé.

 

4.2 Types logiques

Les types logiques représentent des états binaires ou multivalués. Le choix dépend du niveau de réalisme souhaité, des besoins de simulation et du nombre de pilotes possibles.

4.2.1 Type bit

Le type bit est défini par deux valeurs : '0' et '1'. Il convient aux modèles strictement binaires ne nécessitant ni état inconnu ni haute impédance.

Signal de type bit  |   VHDL
signal activation : bit := '0';

activation <= '1';

 

  • Simple et strictement binaire.
  • Ne représente pas un signal non initialisé.
  • Ne représente pas la haute impédance.
  • Moins utilisé que std_logic dans les projets FPGA.

4.2.2 Type bit_vector

bit_vector est un tableau unidimensionnel de valeurs bit. Il représente un mot binaire ou un bus dont chaque élément vaut uniquement '0' ou '1'.

Vecteurs bit  |   VHDL
signal mot_8bits : bit_vector(7 downto 0);
signal adresse   : bit_vector(0 to 15);

mot_8bits <= "10100110";

 

Repère — Sens des indices

La plage 7 downto 0 est descendante ; la plage 0 to 15 est ascendante. Les deux formes sont valides, mais les interfaces doivent utiliser des orientations compatibles.

 

4.2.3 Type boolean

Le type boolean contient les valeurs false et true. Il exprime naturellement une condition logique dans une instruction if, une fonction ou une constante de configuration.

Utilisation d’un booléen  |  VHDL
constant ACTIVER_PARITE : boolean := true;

process(a, b)
    variable egaux : boolean;
begin
    egaux := (a = b);

    if egaux then
        y <= '1';
    else
        y <= '0';
    end if;
end process;

 

Un boolean ne se connecte pas directement à une broche physique attendue comme std_logic sans conversion explicite. Il est particulièrement utile pour les décisions internes et les paramètres génériques.

4.2.4 Type std_logic

std_logic est le type logique le plus courant. Il possède neuf valeurs, permettant de représenter les états binaires, les inconnues, la haute impédance, les niveaux faibles ou forts et le caractère indifférent.

Ports de type std_logic  |  VHDL
entity bascule_d is
    port (
        clk   : in   std_logic;
        reset : in  std_logic;
        d     : in   std_logic;
        q     : out std_logic
    );
end entity bascule_d;

 

  • Défini dans IEEE.STD_LOGIC_1164.
  • Type résolu : plusieurs pilotes peuvent être combinés par une fonction de résolution.
  • Très adapté à la simulation de bus et d’entrées-sorties.
  • Utilisé par la majorité des outils et bibliothèques FPGA.

4.2.5 Type std_logic_vector

std_logic_vector est un tableau de std_logic. Il représente un bus logique, mais il ne porte pas intrinsèquement de signification numérique. Pour calculer, on le convertit généralement en unsigned ou signed.

Vecteurs logiques  |  VHDL
signal donnees  : std_logic_vector(7 downto 0);
signal commande : std_logic_vector(2 downto 0);

donnees <= x"3A";
commande <= "101";

 

Concept clé — Point important

Un std_logic_vector(7 downto 0) peut représenter des bits indépendants, un code, une adresse ou un nombre. Le compilateur ne choisit pas automatiquement une interprétation arithmétique.

 

4.2.6 Comparaison des types logiques

Type

Valeurs

Vectoriel

Résolution

Usage recommandé

bit'0', '1'NonNonModèle binaire simple
bit_vector'0', '1'OuiNonBus strictement binaire
booleanfalse, trueNonNonConditions et paramètres
std_logic9 valeursNonOuiSignaux matériels usuels
std_logic_vector9 valeurs par bitOuiOuiBus et mots logiques

 

4.2.7 Littéraux binaires, hexadécimaux et agrégats

Différentes écritures de vecteurs  |  VHDL
signal a : std_logic_vector(7 downto 0);

a <= "10100101";           -- Littéral binaire
a <= x"A5";                -- Littéral hexadécimal
a <= (others => '0');     -- Tous les bits à 0
a <= (7 => '1',
      0 => '1',
      others => '0');     -- Bits 7 et 0 à 1

 

Les littéraux hexadécimaux simplifient l’écriture des vecteurs dont la longueur est un multiple de quatre. Les agrégats permettent de construire une valeur en nommant des positions ou en utilisant others.

4.3 Valeurs du type std_logic

Le type std_logic utilise neuf symboles pour représenter plus finement le comportement des signaux numériques. Certains symboles sont principalement utiles en simulation et permettent de détecter des défauts qui seraient invisibles avec un type strictement binaire.

Valeur

Nom

Signification

Situation typique

'U'UninitializedNon initialiséSignal jamais affecté au début de la simulation
'X'Forcing unknownInconnu fortConflit entre pilotes forts ou résultat indéterminé
'0'Forcing zeroZéro logique fortNiveau bas actif
'1'Forcing oneUn logique fortNiveau haut actif
'Z'High impedanceHaute impédancePilote déconnecté d’un bus trois états
'W'Weak unknownInconnu faibleConflit entre niveaux faibles
'L'Weak zeroZéro faibleRésistance de tirage vers 0
'H'Weak oneUn faibleRésistance de tirage vers 1
'-'Don’t careValeur indifférenteSpécification, synthèse ou motif de sélection

 

4.3.1 Valeurs '0' et '1'

Ces valeurs représentent les niveaux logiques forts utilisés pour la majorité des signaux fonctionnels. Elles correspondent aux décisions binaires du circuit.

Affectations binaires  |  VHDL
reset <= '0';
enable <= '1';
bus_data <= "10010110";

 

4.3.2 Valeur 'U'

'U' indique qu’un signal n’a pas encore reçu de valeur. C’est la valeur initiale par défaut de std_logic lorsqu’aucune initialisation n’est fournie.

Signal non initialisé  |  VHDL
signal etat : std_logic;
-- Au début de la simulation, etat vaut 'U'

 

Attention — Diagnostic

Une valeur 'U' persistante signifie souvent qu’un signal n’est jamais piloté, qu’un reset n’a pas été appliqué ou qu’une connexion a été oubliée.

 

4.3.3 Valeur 'X'

'X' représente une valeur logique inconnue forte. Elle apparaît notamment lorsque deux pilotes imposent simultanément '0' et '1' sur un signal résolu.

Conflit de pilotes  |  VHDL
signal bus_partage : std_logic;

bus_partage <= '0' when commande_a = '1' else 'Z';
bus_partage <= '1' when commande_b = '1' else 'Z';

-- Si commande_a = commande_b = '1',
-- bus_partage est résolu à 'X'.

 

Une opération logique impliquant une valeur inconnue peut propager 'X'. Cette propagation est utile pour révéler les erreurs d’initialisation ou de contention.

4.3.4 Valeur 'Z'

'Z' signifie qu’un pilote est en haute impédance : il ne force ni 0 ni 1. Elle permet à plusieurs circuits de partager une même ligne, à condition qu’un seul pilote actif impose une valeur à un instant donné.

Sortie trois états  |  VHDL
sortie_bus <= donnee when oe = '1'
              else 'Z';

 

Matériel — FPGA

Les trois états sont principalement utilisés aux broches externes. Dans la logique interne, les synthétiseurs remplacent généralement les structures trois états par des multiplexeurs.

 

4.3.5 Valeurs 'W', 'L' et 'H'

Ces valeurs modélisent des niveaux faibles. 'L' est un zéro faible, 'H' un un faible et 'W' une valeur faible inconnue. Elles peuvent représenter des résistances de tirage ou certains modèles électriques.

Niveau faible de rappel  |  VHDL
signal ligne : std_logic := 'H';

-- Un pilote fort à '0' domine le niveau faible 'H'.

 

Dans les conceptions RTL ordinaires, les valeurs faibles sont rarement affectées explicitement. Elles restent utiles dans les modèles de composants et de bus.

4.3.6 Valeur '-'

Le symbole '-' signifie que la valeur est indifférente dans un contexte donné. Il peut aider le synthétiseur à optimiser une table de vérité ou être utilisé dans certains motifs de comparaison, mais il ne doit pas être considéré comme un troisième état logique réel.

Choix indifférent dans une table  |  VHDL
with selection select
    y <= '0' when "00",
         '1' when "01",
         '-' when others;

 

Bonne pratique — Prudence

En simulation, '-' est une valeur réelle du type std_logic et ne correspond pas automatiquement à 0 ou 1. Utiliser '-' uniquement lorsque le comportement indifférent est clairement maîtrisé.

 

4.3.7 Résolution de plusieurs pilotes

std_logic est un type résolu. Lorsqu’un signal reçoit plusieurs contributions, une fonction de résolution calcule la valeur effective. Par exemple, 'Z' combiné à '1' donne '1', tandis que '0' combiné à '1' donne 'X'.

Pilote A

Pilote B

Valeur résolue

Interprétation

'Z''0''0'Un seul pilote actif à 0
'Z''1''1'Un seul pilote actif à 1
'Z''Z''Z'Aucun pilote actif
'0''1''X'Conflit fort
'L''H''W'Conflit faible
'H''0''0'Le niveau fort domine

 

4.4 Types numériques

Les types numériques permettent de représenter des quantités et d’utiliser les opérateurs arithmétiques. Le choix doit tenir compte de l’intervalle des valeurs, de la largeur matérielle, du signe et des conversions nécessaires.

4.4.1 Type integer

integer représente un entier signé dans une plage définie par l’implémentation, au minimum de −2 147 483 647 à +2 147 483 647. Pour la synthèse, il est préférable de préciser une plage afin de permettre au synthétiseur de dimensionner le matériel.

Entiers avec plages  |  VHDL
signal compteur : integer range 0 to 255 := 0;
signal erreur   : integer range -128 to 127 := 0;

constant MAXIMUM : integer := 1000;

 

Bonne pratique — Dimensionnement

Un integer sans plage explicite peut conduire à une largeur matérielle plus grande que nécessaire. Une plage limitée documente l’intention et facilite l’optimisation.

 

4.4.2 Type natural

natural est un sous-type de integer limité aux valeurs positives ou nulles.

Compteur naturel  |  VHDL
signal nombre_elements : natural range 0 to 63 := 0;

 

Il convient aux compteurs, tailles, indices et nombres d’éléments qui ne peuvent pas être négatifs.

4.4.3 Type positive

positive est un sous-type de integer dont la valeur minimale est 1. Il est souvent utilisé pour les génériques représentant une largeur, une fréquence ou un nombre d’étages.

Générique strictement positif  |  VHDL
entity registre_generique is
    generic (
        N : positive := 8
    );
    port (
        d : in  std_logic_vector(N-1 downto 0);
        q : out std_logic_vector(N-1 downto 0)
    );
end entity registre_generique;

 

4.4.4 Type unsigned

unsigned est un tableau de std_logic interprété comme un entier binaire non signé. Il est défini dans IEEE.NUMERIC_STD et convient aux compteurs, adresses, tailles et données non négatives.

Compteur unsigned  |  VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

signal compteur_u : unsigned(7 downto 0) :=
                    (others => '0');

compteur_u <= compteur_u + 1;

 

Un vecteur unsigned de N bits représente normalement les valeurs de 0 à 2^N − 1, sous réserve que tous les bits soient binaires connus.

4.4.5 Type signed

signed est un tableau de std_logic interprété en complément à deux. Le bit le plus à gauche est le bit de signe.

Nombre signé sur 8 bits  |   VHDL
signal temperature : signed(7 downto 0);

temperature <= to_signed(-12, temperature'length);

 

Un vecteur signed de N bits représente les valeurs de −2^(N−1) à 2^(N−1) − 1.

4.4.6 Comparaison des types numériques

Type

Signe

Largeur

Plage typique

Usage

integerSignéDéduite de la plagePlage déclarée ou implémentationCalculs et compteurs
naturalNon négatifDéduite de la plage0 à une borneIndices et quantités
positiveStrictement positifDéduite de la plage1 à une borneGénériques de taille
unsigned(N-1 downto 0)Non signéN bits explicites0 à 2^N − 1Bus arithmétiques
signed(N-1 downto 0)Complément à deuxN bits explicites−2^(N−1) à 2^(N−1)−1Nombres signés

 

4.4.7 Débordement

Les opérations sur signed et unsigned produisent un résultat dont la largeur dépend des opérandes et de l’opérateur. Une valeur dépassant la largeur disponible peut être tronquée ou provoquer une erreur de dimension selon l’affectation.

Addition avec retenue  |  VHDL
signal a, b : unsigned(7 downto 0);
signal somme  : unsigned(8 downto 0);

somme <= ('0' & a) + ('0' & b);

 

À retenir — Extension

Ajouter un bit à gauche avant l’addition permet de conserver la retenue. Pour un nombre signed, l’extension doit reproduire le bit de signe, ce que la fonction resize réalise correctement.

 

4.4.8 Redimensionnement

Utilisation de resize  |  VHDL
signal a8  : unsigned(7 downto 0);
signal a12 : unsigned(11 downto 0);

a12 <= resize(a8, a12'length);

 

Redimensionnement signé  |  VHDL
signal s8  : signed(7 downto 0);
signal s12 : signed(11 downto 0);

s12 <= resize(s8, s12'length);

 

Pour unsigned, les bits ajoutés à gauche valent 0. Pour signed, le bit de signe est répliqué afin de préserver la valeur.

4.5 Bibliothèque numeric_std

IEEE.NUMERIC_STD fournit une définition normalisée de signed et unsigned ainsi que les opérateurs et fonctions nécessaires à l’arithmétique. Elle constitue le choix recommandé pour écrire du VHDL portable.

4.5.1 Déclaration de la bibliothèque

Clauses usuelles  |  VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

 

STD_LOGIC_1164 apporte les types logiques ; NUMERIC_STD ajoute les types numériques vectoriels, les conversions et les opérations arithmétiques.

4.5.2 Utilisation de signed et unsigned

Déclarations numériques  |  VHDL
signal adresse      : unsigned(15 downto 0);
signal echantillon  : signed(11 downto 0);
signal compteur     : unsigned(7 downto 0);
signal difference   : signed(12 downto 0);

 

Règle — Choix du signe

Utiliser unsigned lorsque toutes les valeurs sont non négatives. Utiliser signed lorsque les données peuvent être négatives et sont codées en complément à deux.

 

4.5.3 Addition

Addition non signée  |  VHDL
signal a, b : unsigned(7 downto 0);
signal s    : unsigned(8 downto 0);

s <= resize(a, s'length)
   + resize(b, s'length);

 

Addition signée  |  VHDL
signal x, y : signed(7 downto 0);
signal r    : signed(8 downto 0);

r <= resize(x, r'length)
   + resize(y, r'length);

 

Les opérandes doivent avoir des types compatibles. Le redimensionnement explicite rend la largeur du résultat claire et évite la perte du bit de retenue ou du signe.

4.5.4 Soustraction

Soustraction signée  |  VHDL
signal a, b : signed(7 downto 0);
signal d    : signed(8 downto 0);

d <= resize(a, d'length)
   - resize(b, d'length);

 

Une soustraction non signée peut produire un résultat mathématique négatif, impossible à représenter en unsigned. Le concepteur doit empêcher ce cas, élargir le traitement ou utiliser un type signed selon le besoin.

4.5.5 Comparaisons numériques

Comparaison de deux valeurs unsigned  |  VHDL
plus_grand <= '1' when a > b else '0';
egaux      <= '1' when a = b else '0';

 

Comparaison signée  |  VHDL
process(x, y)
begin
    if x < y then
        resultat <= "00";
    elsif x = y then
        resultat <= "01";
    else
        resultat <= "10";
    end if;
end process;

 

Concept clé — Interprétation

Les mêmes bits peuvent conduire à des résultats différents selon le type. Par exemple, «11111111» vaut 255 en unsigned et −1 en signed.

 

4.5.6 Conversion entre vecteurs et entiers

unsigned vers integer  |  VHDL
signal u : unsigned(7 downto 0);
signal n : integer range 0 to 255;

n <= to_integer(u);

 

signed vers integer  |  VHDL
signal s : signed(7 downto 0);
signal n : integer range -128 to 127;

n <= to_integer(s);

 

integer vers unsigned  |  VHDL
signal u : unsigned(7 downto 0);
signal n : integer range 0 to 255;

u <= to_unsigned(n, u'length);

 

integer vers signed  |  VHDL
signal s : signed(7 downto 0);
signal n : integer range -128 to 127;

s <= to_signed(n, s'length);

 

4.5.7 Arithmétique sur std_logic_vector

std_logic_vector n’est pas directement un type numérique. Il faut exprimer explicitement l’interprétation souhaitée, puis reconvertir le résultat si l’interface impose un std_logic_vector.

Addition de deux std_logic_vector non signés  |  VHDL
signal a_slv, b_slv : std_logic_vector(7 downto 0);
signal s_slv        : std_logic_vector(8 downto 0);

s_slv <= std_logic_vector(
    resize(unsigned(a_slv), 9)
    + resize(unsigned(b_slv), 9)
);

 

Addition de deux std_logic_vector signés  |  VHDL
signal x_slv, y_slv : std_logic_vector(7 downto 0);
signal r_slv        : std_logic_vector(8 downto 0);

r_slv <= std_logic_vector(
    resize(signed(x_slv), 9)
    + resize(signed(y_slv), 9)
);

 

4.5.8 Exemple complet : additionneur paramétrable

Additionneur unsigned générique — Partie 1  |  VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity additionneur_unsigned is
    generic (
        N : positive := 8
    );
    port (
        a     : in   std_logic_vector(N-1 downto 0);
        b     : in   std_logic_vector(N-1 downto 0);
        somme : out std_logic_vector(N downto 0)
    );
end entity additionneur_unsigned;

 

Additionneur unsigned générique — Partie 2  |  VHDL
architecture rtl of additionneur_unsigned is
    signal a_u : unsigned(N-1 downto 0);
    signal b_u : unsigned(N-1 downto 0);
begin
    a_u <= unsigned(a);
    b_u <= unsigned(b);

    somme <= std_logic_vector(
        resize(a_u, N+1) + resize(b_u, N+1)
    );
end architecture rtl;

 

Méthode — Séparation interface/calcul

L’interface utilise std_logic_vector pour faciliter les connexions. L’architecture convertit les entrées en unsigned, effectue le calcul, puis reconvertit le résultat.

 

4.5.9 Erreurs fréquentes avec numeric_std

Erreur

Cause

Correction

No function '+'Les opérandes sont std_logic_vector.Convertir en signed ou unsigned.
Size mismatchRésultat et destination ont des longueurs différentes.Utiliser resize ou modifier la largeur.
Value out of boundsL’entier dépasse la plage ou la taille de conversion.Vérifier la plage et le nombre de bits.
Comparaison incohérenteUn opérande est signed et l’autre unsigned.Choisir une même interprétation.
Résultat inattendu négatifVecteur interprété en signed.Vérifier le type et le bit de signe.
Anciennes bibliothèques en conflitnumeric_std mélangé avec des paquetages non standards.Conserver uniquement numeric_std.

 

4.6 Autres types

VHDL permet de définir des types adaptés au problème. Cette possibilité améliore la lisibilité, limite les valeurs autorisées et permet de modéliser des structures complexes sans réduire toutes les informations à des vecteurs anonymes.

4.6.1 Types énumérés

Un type énuméré définit une liste finie de valeurs symboliques. Il est particulièrement utile pour représenter les états d’une machine à états.

Type énuméré pour un contrôleur  |  VHDL
type etat_t is (
    ATTENTE,
    CHARGEMENT,
    TRAITEMENT,
    TERMINE
);

signal etat_courant : etat_t := ATTENTE;

 

Utilisation dans une instruction case  |  VHDL
case etat_courant is
    when ATTENTE =>
        pret <= '1';

    when CHARGEMENT =>
        pret <= '0';

    when TRAITEMENT =>
        pret <= '0';

    when TERMINE =>
        pret <= '1';
end case;

 

Lisibilité — Avantage

Les noms symboliques rendent le code plus lisible qu’un codage manuel «00», «01», «10», «11». Le synthétiseur choisit ou optimise ensuite le codage binaire.

 

4.6.2 Tableaux

Un tableau regroupe plusieurs éléments de même type. std_logic_vector, signed et unsigned sont eux-mêmes des tableaux. Le concepteur peut créer des tableaux de mots pour modéliser une mémoire, une fenêtre de données ou un ensemble de registres.

Tableau contraint  |  VHDL
type memoire_16x8_t is array (0 to 15)
    of std_logic_vector(7 downto 0);

signal memoire : memoire_16x8_t;

 

Tableau non contraint  |  VHDL
type tableau_mots_t is array (natural range <>)
    of std_logic_vector(15 downto 0);

signal tampon : tableau_mots_t(0 to 31);

 

Le symbole <> indique que la plage sera fixée lors de la déclaration de l’objet.

4.6.3 Enregistrements

Un enregistrement, ou record, regroupe des champs de types éventuellement différents. Il facilite la manipulation d’une interface composée de plusieurs signaux associés.

Type enregistrement pour une transaction  |  VHDL
type transaction_t is record
    adresse : unsigned(15 downto 0);
    donnee  : std_logic_vector(31 downto 0);
    ecriture: std_logic;
    valide  : std_logic;
end record;

signal requete : transaction_t;

 

Accès aux champs  |  VHDL
requete.adresse  <= to_unsigned(16#1200#, 16);
requete.donnee   <= x"DEADBEEF";
requete.ecriture <= '1';
requete.valide   <= '1';

 

Pratique — Portabilité

Les enregistrements sont très utiles pour les signaux internes et les interfaces modernes. Certaines contraintes d’outil peuvent exister pour les ports de niveau supérieur ou l’affectation directe aux broches.

 

4.6.4 Sous-types

Un sous-type restreint un type existant sans créer un type totalement distinct. Il peut imposer une plage numérique ou une longueur de vecteur.

Sous-types numériques et vectoriels  |  VHDL
subtype octet_t is std_logic_vector(7 downto 0);
subtype compteur_t is natural range 0 to 999;
subtype temperature_t is integer range -40 to 125;

signal donnee      : octet_t;
signal compteur_ms : compteur_t;
signal temperature : temperature_t;

 

Les objets d’un sous-type restent compatibles avec le type de base, mais une affectation hors de la plage autorisée peut déclencher une erreur.

4.6.5 Types définis par l’utilisateur

La déclaration type crée un nouveau type distinct. Deux types possédant la même structure ne sont pas automatiquement compatibles, ce qui renforce la sécurité du modèle.

Deux types distincts de même forme  |  VHDL
type adresse_t is array (15 downto 0) of std_logic;
type donnee_t  is array (15 downto 0) of std_logic;

signal adresse : adresse_t;
signal donnee  : donnee_t;

-- adresse <= donnee;  -- Incompatible sans conversion

 

Choix — Type ou sous-type ?

Créer un type lorsqu’on veut distinguer sémantiquement deux catégories de données. Utiliser un sous-type lorsqu’on veut seulement restreindre ou nommer une variante compatible d’un type existant.

 

4.6.6 Type physique

VHDL permet aussi de définir des types physiques avec unités. Le type time est l’exemple standard. Ces types sont utiles pour la simulation et le calcul de constantes temporelles.

Constante temporelle  |  VHDL
constant PERIODE : time := 20 ns;

clk <= not clk after PERIODE / 2;

 

Les retards explicites avec after sont généralement destinés aux bancs de test et aux modèles de simulation.

4.6.7 Attributs utiles des types et tableaux

Attributs de plage  |  VHDL
signal bus_data : std_logic_vector(15 downto 0);

-- bus_data'length = 16
-- bus_data'left   = 15
-- bus_data'right  = 0
-- bus_data'high   = 15
-- bus_data'low    = 0
-- bus_data'range  = 15 downto 0

 

Boucle indépendante de la taille  |  VHDL
process(bus_data)
    variable parite : std_logic := '0';
begin
    parite := '0';

    for i in bus_data'range loop
        parite := parite xor bus_data(i);
    end loop;

    parite_sortie <= parite;
end process;

 

Bonne pratique — Généricité

Les attributs comme 'length et 'range évitent de coder des dimensions fixes. Le composant reste correct lorsque la largeur du vecteur change.

 

4.7 Conversions de types

Les conversions sont explicites en VHDL. Elles indiquent clairement comment interpréter les bits et permettent au compilateur de vérifier les plages et les longueurs.

4.7.1 Fonction to_integer

to_integer convertit un signed ou un unsigned en integer.

Conversions vers integer  |  VHDL
signal u : unsigned(7 downto 0);
signal s : signed(7 downto 0);

signal entier_u : integer range 0 to 255;
signal entier_s : integer range -128 to 127;

entier_u <= to_integer(u);
entier_s <= to_integer(s);

 

Attention — Valeurs non binaires

Si le vecteur contient 'U', 'X', 'Z' ou une autre valeur non binaire, la conversion peut produire un avertissement, une erreur ou une valeur dépendant de l’outil. Les données numériques doivent être correctement initialisées.

 

4.7.2 Fonction to_unsigned

to_unsigned convertit un entier non négatif en unsigned. Le deuxième argument indique la longueur du résultat.

Entier vers unsigned  |  VHDL
signal compteur : integer range 0 to 999;
signal mot      : unsigned(9 downto 0);

mot <= to_unsigned(compteur, mot'length);

 

La longueur doit être suffisante pour représenter la valeur. Dix bits permettent de coder les valeurs de 0 à 1023.

4.7.3 Fonction to_signed

to_signed convertit un entier positif ou négatif en représentation complément à deux.

Entier vers signed  |  VHDL
signal temperature_entier : integer range -40 to 125;
signal temperature_codee  : signed(7 downto 0);

temperature_codee <= to_signed(
    temperature_entier,
    temperature_codee'length
);

 

4.7.4 Conversion std_logic_vector vers unsigned ou signed

Interprétation non signée  |  VHDL
signal bus_slv : std_logic_vector(7 downto 0);
signal bus_u   : unsigned(7 downto 0);

bus_u <= unsigned(bus_slv);

 

Interprétation signée  |  VHDL
signal bus_slv : std_logic_vector(7 downto 0);
signal bus_s   : signed(7 downto 0);

bus_s <= signed(bus_slv);

 

Ces conversions ne modifient pas les bits ; elles changent seulement leur type et leur interprétation arithmétique.

4.7.5 Conversion signed ou unsigned vers std_logic_vector

Retour vers une interface logique  |  VHDL
signal resultat_u   : unsigned(7 downto 0);
signal resultat_slv : std_logic_vector(7 downto 0);

resultat_slv <= std_logic_vector(resultat_u);

 

Conversion d’un signed  |  VHDL
signal resultat_s   : signed(7 downto 0);
signal resultat_slv : std_logic_vector(7 downto 0);

resultat_slv <= std_logic_vector(resultat_s);

 

4.7.6 Chaînes de conversion fréquentes

Source

Destination

Expression

std_logic_vectorunsignedunsigned(vecteur)
std_logic_vectorsignedsigned(vecteur)
unsignedstd_logic_vectorstd_logic_vector(valeur_u)
signedstd_logic_vectorstd_logic_vector(valeur_s)
unsignedintegerto_integer(valeur_u)
signedintegerto_integer(valeur_s)
integer non négatifunsignedto_unsigned(n, largeur)
integersignedto_signed(n, largeur)
std_logic_vectorinteger non signéto_integer(unsigned(vecteur))
std_logic_vectorinteger signéto_integer(signed(vecteur))

 

4.7.7 Exemple : addition d’entrées std_logic_vector

Conversion complète  |  VHDL
signal a, b : std_logic_vector(7 downto 0);
signal somme : std_logic_vector(8 downto 0);

somme <= std_logic_vector(
    resize(unsigned(a), somme'length)
    +
    resize(unsigned(b), somme'length)
);

 

Les étapes sont : interpréter a et b comme des unsigned, les redimensionner à neuf bits, les additionner, puis convertir le résultat en std_logic_vector.

4.7.8 Exemple : entier vers vecteur et retour

Aller-retour de conversion  |  VHDL
signal nombre      : integer range 0 to 255 := 37;
signal representation : std_logic_vector(7 downto 0);
signal verification   : integer range 0 to 255;

representation <= std_logic_vector(
    to_unsigned(nombre, representation'length)
);

verification <= to_integer(
    unsigned(representation)
);

 

4.7.9 Conversions dangereuses ou ambiguës

Situation

Risque

Solution

Entier négatif vers unsignedValeur non représentableUtiliser signed ou interdire le cas
Valeur trop grande pour la largeurTroncature, avertissement ou erreurCalculer le nombre de bits requis
std_logic_vector converti en signed par erreurInterprétation négative possibleDocumenter le signe attendu
Vecteur contenant X ou UConversion numérique invalideInitialiser et valider les signaux
Redimensionnement signé manuel par zérosSigne perduUtiliser resize(signed, longueur)
Plages ascendantes et descendantes mélangéesOrdre des bits inversé ou association incorrecteVérifier 'range et les connexions

 

4.7.10 Déterminer la largeur nécessaire

Pour représenter une valeur maximale M non signée, il faut choisir N tel que 2^N > M. Pour une plage signée en complément à deux, N bits représentent de −2^(N−1) à 2^(N−1) − 1.

Plage souhaitée

Largeur minimale

Type possible

0 à 154 bitsunsigned(3 downto 0)
0 à 2558 bitsunsigned(7 downto 0)
0 à 99910 bitsunsigned(9 downto 0)
−8 à +74 bitssigned(3 downto 0)
−128 à +1278 bitssigned(7 downto 0)
−2048 à +204712 bitssigned(11 downto 0)

 

Travaux dirigés

TD 1 — Détermination du type approprié

Pour chaque information, proposer un type VHDL et justifier le choix.

Information à représenter

Contraintes

Bouton-poussoirDeux niveaux logiques, entrée physique
État d’un contrôleurATTENTE, LECTURE, CALCUL, FIN
Compteur de 0 à 999Aucune valeur négative
Échantillon audioValeurs de −32768 à +32767
Bus de données externe32 fils logiques
Adresse mémoire0 à 65535
Activation optionnelle d’une fonctionParamètre connu à l’élaboration
Transaction de busAdresse, donnée, écriture et validité

 

Correction indicative du TD 1

Information

Type conseillé

Justification

Bouton-poussoirstd_logicCompatible avec une broche et les états de simulation
État du contrôleurType énuméréValeurs symboliques lisibles et limitées
Compteur 0 à 999natural range 0 to 999 ou unsigned(9 downto 0)Plage non négative ; 10 bits suffisent
Échantillon audiosigned(15 downto 0)Complément à deux sur 16 bits
Bus de donnéesstd_logic_vector(31 downto 0)Bus logique sans interprétation numérique imposée
Adresse mémoireunsigned(15 downto 0)Valeur non signée sur 16 bits
Option de fonctionboolean génériqueDécision symbolique connue avant synthèse
Transaction de busrecordRegroupe plusieurs champs liés

 

TD 2 — Conversion d’un entier en vecteur

On dispose d’un entier n compris entre 0 et 1023. Écrire les déclarations et l’affectation permettant d’obtenir sa représentation binaire sur 10 bits dans un std_logic_vector.

Correction  |   VHDL
signal n      : integer range 0 to 1023;
signal n_slv  : std_logic_vector(9 downto 0);

n_slv <= std_logic_vector(
    to_unsigned(n, n_slv'length)
);

 

Question complémentaire : quelle valeur binaire obtient-on pour n = 37 ?

Calcul  |   Raisonnement
37 = 32 + 4 + 1

Sur 10 bits :
0000100101

 

TD 3 — Conversion d’un vecteur en entier

Le port code reçoit un std_logic_vector(7 downto 0) représentant un entier non signé. Écrire la conversion vers un integer.

Correction non signée  |  VHDL
signal code : std_logic_vector(7 downto 0);
signal valeur : integer range 0 to 255;

valeur <= to_integer(unsigned(code));

 

Si le même vecteur représente une valeur signée en complément à deux, la conversion devient :

Correction signée  |  VHDL
signal valeur_signee : integer range -128 to 127;

valeur_signee <= to_integer(signed(code));

 

Interprétation — Exemple

Pour code = «11111111», la conversion unsigned donne 255, tandis que la conversion signed donne −1.

 

TD 4 — Addition de deux nombres binaires

Deux entrées a et b sont des std_logic_vector de 8 bits et représentent des nombres non signés. Produire une somme de 9 bits conservant la retenue.

Correction  |   VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

signal a, b  : std_logic_vector(7 downto 0);
signal somme : std_logic_vector(8 downto 0);

somme <= std_logic_vector(
    resize(unsigned(a), somme'length)
    +
    resize(unsigned(b), somme'length)
);

 

Exemple : a = 200 et b = 100. La somme vaut 300, qui nécessite 9 bits : 100101100.

TD 5 — Soustraction et signe

On souhaite calculer a − b, avec a et b compris entre 0 et 255, mais le résultat peut être négatif. Proposer un type de résultat et une expression correcte.

Correction  |   VHDL
signal a, b : unsigned(7 downto 0);
signal difference : signed(8 downto 0);

difference <= signed('0' & a)
            - signed('0' & b);

 

Les opérandes sont d’abord étendus à 9 bits avec un bit de signe nul, puis convertis en signed. La plage de 9 bits signés couvre de −256 à +255.

TD 6 — Identifier les erreurs de compatibilité

Pour chaque extrait, identifier l’erreur et proposer une correction.

Erreur A  |   VHDL
signal a, b, s : std_logic_vector(7 downto 0);

s <= a + b;

 

Erreur : l’opérateur + n’est pas défini par numeric_std pour std_logic_vector. Correction : convertir a et b en unsigned ou signed.

Correction A  |   VHDL
s <= std_logic_vector(
    unsigned(a) + unsigned(b)
);

 

Erreur B  |   VHDL
signal u : unsigned(7 downto 0);
signal s : signed(7 downto 0);

u <= s;

 

Erreur : signed et unsigned sont des types distincts. Il faut préciser l’interprétation souhaitée.

Correction B  |   VHDL
u <= unsigned(s);

 

Attention — Sens de la conversion

unsigned(s) conserve les bits mais change leur interprétation. Si s est négatif, la valeur unsigned correspondante sera grande. Cette conversion doit donc être justifiée.

 

Erreur C  |   VHDL
signal compteur : integer range 0 to 15 := 15;

compteur <= compteur + 1;

 

Erreur d’exécution possible : la valeur 16 sort de la plage. Il faut gérer le retour à zéro ou élargir la plage.

Correction C  |   VHDL
if compteur = 15 then
    compteur <= 0;
else
    compteur <= compteur + 1;
end if;

 

Erreur D  |   VHDL
signal a : unsigned(7 downto 0);
signal s : unsigned(7 downto 0);

s <= a + 300;

 

La constante 300 ne tient pas sur 8 bits et l’expression mélange des formes dont la largeur doit être maîtrisée. Utiliser une destination plus large et convertir explicitement.

Correction D  |   VHDL
signal s_large : unsigned(9 downto 0);

s_large <= resize(a, s_large'length)
         + to_unsigned(300, s_large'length);

 

TD 7 — Signal ou variable ?

Analyser le processus suivant et déterminer les valeurs affectées à sortie_v et sortie_s après un front d’horloge.

Énoncé  |   VHDL
process(clk)
    variable v : integer := 0;
begin
    if rising_edge(clk) then
        v := v + 1;
        v := v + 1;

        s <= s + 1;
        s <= s + 1;

        sortie_v <= v;
        sortie_s <= s;
    end if;
end process;

 

Correction : la variable v est incrémentée deux fois immédiatement. Le signal s reçoit deux affectations fondées sur la même ancienne valeur ; la dernière ne produit pas une double incrémentation. sortie_s lit également l’ancienne valeur de s durant le processus.

Correction — Pour incrémenter un signal de deux

Écrire directement s <= s + 2, ou utiliser une variable intermédiaire puis affecter une seule fois le signal.

 

TD 8 — Type énuméré et machine à états

Déclarer un type d’état pour un feu tricolore : ROUGE, ROUGE_ORANGE, VERT et ORANGE. Créer un signal état initialisé à ROUGE.

Correction  |   VHDL
type etat_feu_t is (
    ROUGE,
    ROUGE_ORANGE,
    VERT,
    ORANGE
);

signal etat_feu : etat_feu_t := ROUGE;

 

TD 9 — Tableau et enregistrement

Déclarer une mémoire de 64 mots de 16 bits et un type record décrivant un échantillon avec une donnée signée de 16 bits et un drapeau de validité.

Correction  |   VHDL
type memoire_t is array (0 to 63)
    of std_logic_vector(15 downto 0);

type echantillon_t is record
    valeur : signed(15 downto 0);
    valide : std_logic;
end record;

signal memoire    : memoire_t;
signal echantillon: echantillon_t;

 

TD 10 — Mini-problème de synthèse

Concevoir un bloc qui reçoit deux entrées std_logic_vector de 12 bits représentant des nombres signés, calcule leur somme sur 13 bits et produit un indicateur positif lorsque le résultat est supérieur ou égal à zéro.

Correction — Partie déclarative  |  VHDL
signal a_s, b_s : signed(11 downto 0);
signal somme_s  : signed(12 downto 0);

a_s <= signed(a);
b_s <= signed(b);

 

Correction — Calcul et sorties  |  VHDL
somme_s <= resize(a_s, 13)
         + resize(b_s, 13);

somme <= std_logic_vector(somme_s);

positif <= '1' when somme_s >= 0
           else '0';

 

Résultat — Analyse matérielle

Le bloc synthétisé contient un additionneur signé de 13 bits et un test du bit de signe pour produire l’indicateur positif.

 

Méthode de choix d’un type VHDL

  1. Identifier la nature de l’information : logique, numérique, état symbolique ou structure de données.
  2. Déterminer si la valeur peut être négative.
  3. Calculer ou limiter la plage des valeurs.
  4. Déterminer si la donnée est un signal matériel, un calcul local ou une constante.
  5. Choisir un type standard ou définir un type utilisateur explicite.
  6. Vérifier la compatibilité avec les ports et les bibliothèques utilisées.
  7. Prévoir la largeur des résultats des opérations.
  8. Écrire les conversions de manière explicite et documentée.
  9. Tester les valeurs limites et les états non initialisés en simulation.

Arbre de décision simplifié

Question

Réponse

Choix probable

Est-ce une condition interne ?Ouiboolean
Est-ce un signal physique scalaire ?Ouistd_logic
Est-ce un bus sans signification numérique ?Ouistd_logic_vector
Est-ce un nombre non négatif sur N bits ?Ouiunsigned
Est-ce un nombre signé sur N bits ?Ouisigned
Est-ce une quantité bornée pratique à manipuler ?Ouiinteger/natural avec range
Est-ce un ensemble d’états nommés ?Ouitype énuméré
Est-ce un groupe de champs différents ?Ouirecord
Est-ce une collection d’éléments identiques ?Ouiarray

 

Checklist de compatibilité

  • Les deux opérandes d’une opération ont-ils le même type numérique ?
  • Les longueurs des vecteurs sont-elles compatibles ?
  • Le résultat dispose-t-il d’assez de bits ?
  • Le signe est-il conservé lors du redimensionnement ?
  • Les valeurs non binaires ont-elles été éliminées avant une conversion numérique ?
  • Les plages d’integer, natural et positive sont-elles respectées ?
  • Les clauses IEEE.STD_LOGIC_1164 et IEEE.NUMERIC_STD sont-elles présentes ?
  • L’interface utilise-t-elle un type adapté aux autres composants ?

Erreurs classiques à éviter

Mauvaise pratique

Pourquoi

Bonne pratique

Utiliser std_logic_vector pour tous les calculsLe sens numérique est absentConvertir en signed ou unsigned
Mélanger plusieurs bibliothèques arithmétiquesSurcharges ambiguës et faible portabilitéUtiliser numeric_std
Ignorer les largeurs de résultatsDébordement ou erreur d’affectationÉtendre ou resize explicitement
Utiliser integer sans plageDimensionnement matériel moins clairDéclarer une plage adaptée
Masquer U et X dans les testsLes défauts d’initialisation restent invisiblesObserver et corriger les inconnues
Utiliser inout par commoditéRisque de pilotes multiplesSéparer entrée, sortie et validation
Créer des types anonymes partoutCode difficile à comprendreNommer types et sous-types

 

Synthèse du chapitre

Notion

Résumé

SignalObjet de communication dont les affectations sont planifiées.
VariableObjet local mis à jour immédiatement dans le flot séquentiel.
ConstanteValeur fixe qui améliore la lisibilité et le paramétrage.
FichierObjet surtout utilisé en simulation pour les entrées-sorties externes.
std_logicType logique résolu à neuf valeurs.
std_logic_vectorBus logique sans interprétation numérique automatique.
integer/natural/positiveTypes scalaires utiles lorsque la plage est explicitement bornée.
signed/unsignedVecteurs numériques définis par numeric_std.
Type énuméréListe de valeurs symboliques adaptée aux états.
Array/recordStructures pour collections homogènes ou champs hétérogènes.
Sous-typeRestriction compatible d’un type existant.
ConversionsOpérations explicites garantissant une interprétation maîtrisée.

 

Autoévaluation

1. Quel opérateur affecte un signal ?

Réponse : <=.

2. Quel opérateur affecte une variable ?

Réponse : :=.

3. Quelle est la valeur initiale par défaut d’un std_logic non initialisé ?

Réponse : 'U'.

4. Quelle valeur représente la haute impédance ?

Réponse : 'Z'.

5. Quelle bibliothèque définit signed et unsigned ?

Réponse : IEEE.NUMERIC_STD.

6. Comment convertir un unsigned en integer ?

Réponse : to_integer(valeur_unsigned).

7. Comment convertir un integer en unsigned ?

Réponse : to_unsigned(entier, longueur).

8. Quelle différence existe entre signed et unsigned ?

Réponse : L’interprétation du bit de poids fort et de la plage numérique.

9. Quel type convient aux états nommés d’un contrôleur ?

Réponse : Un type énuméré.

10. Pourquoi std_logic_vector ne doit-il pas être additionné directement avec numeric_std ?

Réponse : Parce qu’il n’a pas d’interprétation numérique intrinsèque.

Exercice de consolidation

Écrire un bloc qui reçoit un std_logic_vector de 10 bits représentant une valeur non signée, ajoute la constante 125, produit un résultat sur 11 bits et un signal depassement indiquant si le résultat dépasse 1023.

Correction proposée — Partie 1  |  VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity ajout_constante is
    port (
        entree      : in   std_logic_vector(9 downto 0);
        resultat    : out std_logic_vector(10 downto 0);
        depassement : out std_logic
    );
end entity ajout_constante;

 

Correction proposée — Partie 2  |  VHDL
architecture rtl of ajout_constante is
    signal entree_u   : unsigned(9 downto 0);
    signal resultat_u : unsigned(10 downto 0);
begin
    entree_u <= unsigned(entree);

    resultat_u <= resize(entree_u, 11)
                + to_unsigned(125, 11);

    resultat <= std_logic_vector(resultat_u);

    depassement <= '1' when resultat_u > 1023
                   else '0';
end architecture rtl;

 

Suite du cours — Transition vers la suite

La maîtrise des types et conversions permet d’aborder sereinement les opérateurs, les expressions, les affectations concurrentes et les descriptions combinatoires plus complexes.