Fonctions IEEE utiles
Les fonctions VHDL pratiques à connaître dans std_logic_1164, numeric_std, std.env, textio et math_real.
Pourquoi ce chapitre
Les bibliothèques IEEE ne servent pas seulement à déclarer std_logic ou unsigned. Elles contiennent aussi des fonctions très utiles pour écrire du code plus sûr, plus lisible et plus facile à tester.
L'objectif n'est pas de tout apprendre par cœur. L'objectif est de savoir quelle fonction utiliser dans les cas courants.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;Gardez cette règle simple : pour l'arithmétique, utilisez numeric_std. Évitez les anciens packages non standard comme std_logic_arith, std_logic_unsigned ou std_logic_signed.
std_logic_1164
Le package std_logic_1164 définit std_logic, std_logic_vector et les fonctions liées aux valeurs logiques à 9 états.
| Fonction | Usage |
|---|---|
rising_edge(i_clk) | Détecter un front montant d'horloge |
falling_edge(i_clk) | Détecter un front descendant |
Is_X(w_bus) | Détecter une valeur inconnue ('U', 'X', etc.) |
To_01(w_bus) | Ramener un vecteur vers des 0/1 |
to_hstring(w_bus) | Afficher un vecteur en hexadécimal en simulation |
Fronts d'horloge
Pour une logique synchrone FPGA, l'idiome standard reste :
p_reg : process(i_clk)
begin
if rising_edge(i_clk) then
if i_rst = '1' then
r_count <= (others => '0');
else
r_count <= r_count + 1;
end if;
end if;
end process p_reg;rising_edge est préférable à i_clk'event and i_clk = '1', car il tient compte des transitions valides du système std_logic.
Détecter les inconnues en simulation
Is_X est utile dans les testbenches. Il évite de valider un résultat qui contient encore une valeur inconnue.
assert not Is_X(o_data)
report "o_data contient une valeur inconnue : " & to_hstring(o_data)
severity error;En synthèse, ce genre de test n'a pas de sens matériel direct. Il sert surtout à sécuriser les simulations.
numeric_std
numeric_std ajoute l'interprétation numérique des vecteurs via unsigned et signed.
| Fonction | Usage |
|---|---|
to_unsigned(i, n) | Convertir un entier naturel vers unsigned(n-1 downto 0) |
to_signed(i, n) | Convertir un entier signé vers signed(n-1 downto 0) |
to_integer(x) | Convertir unsigned ou signed vers integer |
resize(x, n) | Adapter la largeur d'un unsigned ou signed |
shift_left(x, n) | Décalage à gauche |
Conversions propres
signal r_count : unsigned(7 downto 0);
signal w_index : integer range 0 to 255;
w_index <= to_integer(r_count);
r_count <= to_unsigned(42, r_count'length);La largeur doit être explicite. C'est ce qui évite les ambiguïtés entre un nombre abstrait et un bus réel.
resize et largeur des résultats
resize adapte la taille en respectant le type :
- avec
unsigned, extension par0; - avec
signed, extension du signe.
signal r_a : unsigned(7 downto 0);
signal r_b : unsigned(7 downto 0);
signal r_sum : unsigned(8 downto 0);
r_sum <= resize(r_a, r_sum'length) + resize(r_b, r_sum'length);Pour une addition qui doit garder la retenue, il faut élargir les opérandes avant l'opération.
Fonctions d'affichage
Dans un testbench, afficher les valeurs en hexadécimal rend les erreurs beaucoup plus lisibles.
report "data = 0x" & to_hstring(o_data) severity note;Pour un bus large, to_hstring est souvent plus clair qu'une chaîne binaire complète.
std.env
Depuis VHDL-2008, le package std.env permet de terminer proprement une simulation.
library STD;
use STD.ENV.ALL;
-- fin de testbench
report "Test terminé" severity note;
finish;finish est plus explicite qu'un simple wait; quand le testbench a réellement terminé.
textio
textio sert à lire ou écrire des fichiers en simulation. C'est utile pour :
- charger des stimuli ;
- comparer des résultats attendus ;
- générer un journal de simulation.
Pour les vecteurs logiques, les fonctions hread et hwrite permettent de travailler directement en hexadécimal.
library STD;
use STD.TEXTIO.ALL;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
file f_vectors : text open read_mode is "vectors.txt";
variable v_line : line;
variable v_data : std_logic_vector(7 downto 0);
variable v_ok : boolean;
readline(f_vectors, v_line);
hread(v_line, v_data, v_ok);
assert v_ok
report "Ligne de stimulus invalide"
severity error;Ce code est destiné à la simulation. Ne l'utilisez pas dans un bloc RTL synthétisable.
math_real
math_real contient des fonctions mathématiques sur le type real : sqrt, ceil, floor, sin, cos, uniform, etc.
En FPGA, ce package sert surtout aux testbenches et aux constantes calculées à l'élaboration. Il ne faut pas l'utiliser comme logique matérielle en temps réel.
Exemple de stimulus pseudo-aléatoire :
library IEEE;
use IEEE.MATH_REAL.ALL;
variable v_seed1 : positive := 101;
variable v_seed2 : positive := 203;
variable v_rand : real;
uniform(v_seed1, v_seed2, v_rand);À retenir
| Besoin | Fonction typique |
|---|---|
| Détecter un front | rising_edge |
| Convertir un entier vers un bus | to_unsigned, to_signed |
| Convertir un bus numérique vers entier | to_integer |
| Changer une largeur | resize |
| Afficher un bus en hexadécimal | to_hstring |
| Lire un vecteur hexadécimal en simulation | hread |
| Finir un testbench | finish |
| Générer des stimuli aléatoires | uniform |
📝 Tester mes connaissances - Quiz du chapitre