Composants & Instanciation
Concevoir des architectures structurelles en VHDL : déclaration de composants, port map, generic map, et instanciation directe.
Conception structurelle
En VHDL, il existe deux grandes façons de décrire un circuit :
| Style | Description |
|---|---|
| Comportemental (RTL) | On décrit ce que fait le circuit (process, affectations) |
| Structurel | On assemble des composants existants comme sur un schéma |
Le style structurel est indispensable pour organiser les grands designs en blocs hiérarchiques. Un top-level connecte des composants (UART, ALU, FIFO…) via des signaux internes.
Déclaration de composant (component)
Avant d'instancier un composant, il faut déclarer son interface dans la zone architecturale :
architecture rtl of top_level is
-- Déclaration du composant (copie de l'entité)
component additionneur is
generic (
g_WIDTH : integer := 8
);
port (
i_a : in std_logic_vector(g_WIDTH-1 downto 0);
i_b : in std_logic_vector(g_WIDTH-1 downto 0);
o_sum : out std_logic_vector(g_WIDTH-1 downto 0);
o_cout : out std_logic
);
end component additionneur;
-- Signaux de connexion
signal w_result : std_logic_vector(7 downto 0);
signal w_carry : std_logic;
begin
-- Instanciation
U_ADD : additionneur
generic map (g_WIDTH => 8)
port map (
i_a => i_operande_a,
i_b => i_operande_b,
o_sum => w_result,
o_cout => w_carry
);
end architecture rtl;La convention veut que les instances soient préfixées
U_(Unit) ou numérotéesU1,U2.
Instanciation directe (VHDL-93)
La méthode moderne sans component — directement depuis l'entité :
architecture rtl of top_level is
signal w_sum : std_logic_vector(7 downto 0);
signal w_carry : std_logic;
begin
U_ADD : entity work.additionneur
generic map (g_WIDTH => 8)
port map (
i_a => i_op_a,
i_b => i_op_b,
o_sum => w_sum,
o_cout => w_carry
);
end architecture rtl;work désigne la bibliothèque de travail courante — celle qui contient vos fichiers du projet.
Association nommée vs positionnelle
-- Association nommée (recommandée — explicite et sûre)
port map (
i_clk => i_clk,
i_rst => i_reset,
o_data => w_data_out
);
-- Association positionnelle (déconseillée — fragile)
port map (i_clk, i_reset, w_data_out);Toujours utiliser l'association nommée. L'association positionnelle casse si l'ordre des ports change dans l'entité.
Port open — sortie non connectée
Si une sortie d'un composant n'est pas utilisée, on la laisse explicitement open :
U_CPT : entity work.compteur
port map (
i_clk => i_clk,
i_rst => i_rst,
o_count => w_count,
o_tc => open -- Terminal Count non utilisé
);
openest interdit sur les entrées — une entrée doit toujours être connectée à un signal ou une valeur ('0','1', etc.).
Exemple complet : top-level structurel
Voici un top-level qui connecte un compteur BCD à un décodeur 7 segments :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity top_afficheur is
port (
i_clk : in std_logic;
i_rst : in std_logic;
o_seg : out std_logic_vector(6 downto 0)
);
end entity top_afficheur;
architecture structural of top_afficheur is
signal w_bcd : std_logic_vector(3 downto 0);
begin
-- Compteur BCD : compte de 0 à 9
U_CPT : entity work.bcd_counter
port map (
i_clk => i_clk,
i_rst => i_rst,
i_en => '1',
o_count => w_bcd,
o_tc => open
);
-- Décodeur 7 segments : BCD → afficheur
U_DEC : entity work.decodeur_7seg
port map (
i_bcd => w_bcd,
o_seg => o_seg
);
end architecture structural;La valeur BCD transite via le signal interne w_bcd — les composants ne se connectent jamais directement, ils passent par des signaux.
Plusieurs instances du même composant
Un composant peut être instancié plusieurs fois. Exemple : 4 bascules D formant un registre à décalage :
architecture structural of shift_reg_4 is
signal w_chain : std_logic_vector(4 downto 0);
begin
w_chain(0) <= i_data;
GEN_FF : for i in 0 to 3 generate
U_FF : entity work.bascule_d
port map (
i_clk => i_clk,
i_rst => i_rst,
i_d => w_chain(i),
o_q => w_chain(i+1)
);
end generate GEN_FF;
o_data <= w_chain(4);
end architecture structural;L'instruction generate crée N instances automatiquement — indispensable pour les structures régulières (tableaux de registres, matrices).
Mixte : structurel + comportemental
Les deux styles peuvent coexister dans la même architecture :
architecture rtl of exemple_mixte is
signal w_count : unsigned(7 downto 0);
signal w_done : std_logic;
begin
-- Bloc comportemental (process)
p_ctrl : process(i_clk)
begin
if rising_edge(i_clk) then
if w_done = '1' then
o_led <= '1';
end if;
end if;
end process p_ctrl;
-- Bloc structurel (instanciation)
U_CPT : entity work.compteur_8bit
port map (
i_clk => i_clk,
i_rst => i_rst,
o_count => w_count,
o_tc => w_done
);
end architecture rtl;Résumé
| Concept | Syntaxe |
|---|---|
| Instanciation directe | U_X : entity work.nom |
| Avec générique | generic map (g_PARAM => valeur) |
| Connexion des ports | port map (port => signal) |
| Sortie non utilisée | o_port => open |
| Plusieurs instances | Boucle generate |
Règle d'or : le top-level ne contient que des instanciations et des signaux de connexion — toute logique métier est dans les sous-composants.