Comparer signal, variable et constante en VHDL : portée, mise à jour après delta-cycle, synthèse et choix selon le contexte.
Signaux, variables et constantes n'ont pas la même manière de transmettre une valeur. Leur choix décrit le comportement du modèle ; le matériel obtenu dépend ensuite des affectations.
Propriété
Signal
Variable
Constante
Usage courant
Connexion entre blocs ou port
Calcul local
Paramètre fixe
Affectation
Mise à jour programmée
Mise à jour immédiate
Aucune après élaboration
Visibilité
Selon la région de déclaration
Selon la région de déclaration
Selon la région de déclaration
Synthèse
Logique ou mémoire selon le code
Logique ou mémoire selon le code
Valeur constante
Relier les blocs avec des signaux
Un signal transmet des valeurs entre blocs concurrents. Il peut représenter une liaison combinatoire ou une valeur mémorisée :
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;
Une affectation de signal programme une mise à jour. Sans délai explicite, celle-ci intervient lors d'une étape suivante du simulateur, un delta-cycle. Le simulateur applique les valeurs prévues puis réévalue les blocs concernés, sans avancer le temps affiché.
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;
Dans ce process, r_b lit l'ancienne valeur de r_a. Les deux registres se mettent à jour après l'exécution du process ; r_b suit donc r_a avec un cycle d'horloge de retard. Le delta-cycle explique l'ordre de simulation, et le front d'horloge la mémorisation matérielle.
Calculer localement avec des variables
L'affectation := modifie immédiatement la variable pour les instructions suivantes du process ou du sous-programme :
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;
Cette différence change la valeur utilisée dans la suite du calcul :
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;
Une variable est pratique pour un résultat intermédiaire. Elle n'impose pas à elle seule un registre : elle peut décrire de la logique combinatoire ou de la mémoire selon son usage. Les signaux servent aux échanges entre process et aux ports.
Fixer les paramètres avec des constantes
Une constante garde la valeur déterminée lors de son élaboration. Elle peut notamment dépendre de paramètres génériques :