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

SignalVariableConstante
DéclarationZone architecturale ou portDans un process ou sous-programmeArchitecture, package
Mise à jourAprès le delta-cycle (différé)ImmédiateJamais (lecture seule)
ScopeArchitecture entièreProcess uniquementArchitecture ou global
SynthèseFil ou registreVariable temporaireConstante 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

SituationUtiliser
Communication entre processSignal
Valeur intermédiaire dans un processVariable
Valeur fixe utilisée partoutConstante
Port d'un composantSignal (port)
Compteur ou registre synthétisableSignal avec préfixe r_
Calcul combinatoire intermédiaireVariable 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)