Signaux, Variables et Constantes
Les trois façons de stocker une valeur en VHDL : signal, variable et constante — différences et usages.
Les trois types de stockage
| Signal | Variable | Constante | |
|---|---|---|---|
| Déclaration | Zone architecturale ou port | Dans un process ou sous-programme | Architecture, package |
| Mise à jour | Après le delta-cycle (différé) | Immédiate | Jamais (lecture seule) |
| Scope | Architecture entière | Process uniquement | Architecture ou global |
| Synthèse | Fil ou registre | Variable temporaire | Constante de synthèse |
Les signaux (signal)
Les signaux sont les fils du circuit. Ils communiquent entre les blocs concurrents.
architecture rtl of exemple is
-- Déclaration dans la zone architecturale
signal w_intermediate : std_logic;
signal r_counter : unsigned(7 downto 0) := (others => '0');
begin
-- Les affectations de signaux sont différées
w_intermediate <= i_a AND i_b;
o_result <= w_intermediate OR i_c;
end architecture rtl;Mise à jour différée (delta-cycle)
Un signal n'est pas mis à jour immédiatement après son affectation — il le sera au prochain delta-cycle :
process(i_clk)
begin
if rising_edge(i_clk) then
r_a <= '1';
r_b <= r_a; -- r_b reçoit l'ANCIENNE valeur de r_a !
-- r_a et r_b sont tous deux mis à jour après le process
end if;
end process;Cela simule le comportement réel des bascules : r_b suit r_a avec un cycle de retard.
Les variables (variable)
Les variables sont des registres temporaires dans un process. Leur mise à jour est immédiate.
process(i_clk)
variable v_temp : unsigned(8 downto 0);
variable v_sum : unsigned(7 downto 0);
begin
if rising_edge(i_clk) then
v_temp := unsigned('0' & i_a) + unsigned('0' & i_b); -- mise à jour immédiate
v_sum := v_temp(7 downto 0); -- v_temp est déjà à jour !
r_result <= std_logic_vector(v_sum);
end if;
end process;Différence clé : signal vs variable dans un process
process(i_clk)
variable v_x : std_logic;
begin
if rising_edge(i_clk) then
-- Avec variable (mise à jour immédiate)
v_x := i_data; -- v_x prend i_data immédiatement
o_y <= v_x; -- o_y = i_data (synchrone, même cycle)
-- Avec signal (différé)
-- w_x <= i_data;
-- o_y <= w_x; -- o_y = ancienne valeur de w_x !
end if;
end process;Règle pratique : utiliser les variables pour des calculs intermédiaires dans un process. Utiliser des signaux pour la communication entre processus ou blocs.
Les constantes (constant)
Les constantes sont des valeurs immuables définies à la compilation.
architecture rtl of uart is
constant c_CLK_FREQ : integer := 100_000_000; -- 100 MHz
constant c_BAUD_RATE : integer := 115_200;
constant c_DIVISOR : integer := c_CLK_FREQ / c_BAUD_RATE;
constant c_PREAMBLE : std_logic_vector(7 downto 0) := x"55";
begin
-- c_DIVISOR = 868 (calculé à la compilation)
end architecture rtl;Constantes dans les packages
Pour partager des constantes entre fichiers :
package pkg_common is
constant c_DATA_WIDTH : integer := 8;
constant c_ADDR_WIDTH : integer := 16;
end package pkg_common;
-- Dans un autre fichier
use work.pkg_common.all;Tableau de décision
| Situation | Utiliser |
|---|---|
| Communication entre process | Signal |
| Valeur intermédiaire dans un process | Variable |
| Valeur fixe utilisée partout | Constante |
| Port d'un composant | Signal (port) |
| Compteur ou registre synthétisable | Signal avec préfixe r_ |
| Calcul combinatoire intermédiaire | Variable ou signal w_ |
Préfixes recommandés
Selon les règles de codage (cours 07) :
signal w_combinatoire : std_logic; -- w_ = wire, non registré
signal r_registre : std_logic; -- r_ = registered, flip-flop
constant c_MAX : integer := 255; -- c_ = constant
variable v_temp : unsigned(7 downto 0); -- v_ = variable (usage interne)