Instanciation d'une entité

Définition

Traditionnellement, on distingue deux types de descriptions :

Pour être utilisable dans une description structurelle, chaque composant doit lui-même avoir été décrit en VHDL sous la forme d’une entité et d’une architecture. Il faut considérer ces derniers comme un plan de fabrication qui permet de construire autant d’exemplaires de ce composant que nous en avons besoin. Comme dans les langages de programmation à objets, ces exemplaires sont appelés instances. L’opération de création de ces instances est appelée instanciation.

Cette page illustre la notion d’architecture structurelle à travers des exemples. Le détail de la syntaxe est expliqué dans la section : L’essentiel de VHDL / Instructions concurrentes / Instanciation.

Exemple

Nous allons décrire un circuit capable d’afficher la valeur d’un compteur sur un afficheur 7 segments. Il possédera une entrée horloge clk_i, une entrée de réinitialisation reset_i et une sortie segments_o. Nous partons de l’hypothèse que clk_i a une fréquence de 100 MHz. La valeur affichée sera mise à jour toutes les secondes, c’est-à-dire toutes les cent millions de périodes de clk_i.

Affichage de la valeur d'un compteur sur un afficheur (entité)

Nous proposons de construire le circuit en mettant deux compteurs en cascade pour compter respectivement les fronts d’horloge et les secondes. Nous utiliserons pour cela le circuit compteur modulo N présenté dans la section Architectures.

Affichage de la valeur d'un compteur sur un afficheur (architecture)

Afficher la légende des schémas.

La description VHDL correspondante est détaillée ci-dessous. Il s’agit d’une description structurelle qui contient deux instances de l’entité CounterModN avec l’architecture Behavioral, et une instance de SegmentDecoder avec l’architecture TruthTable.

entity CounterDemo is
    port(
        clk_i, reset_i : in  std_logic;
        segments_o     : out std_logic_vector(0 to 6)
    );
end CounterDemo;

architecture Structural of CounterDemo is
    signal sec_inc   : std_logic;
    signal sec_value : integer range 0 to 15;
begin
    div_counter_inst : entity work.CounterModN(Behavioral)
        generic map(
            N => 100e6
        )
        port map(
            clk_i   => clk_i,
            reset_i => '0',
            inc_i   => '1',
            value_o => open,
            cycle_o => sec_inc
        );

    sec_counter_inst : entity work.CounterModN(Behavioral)
        generic map(
            N => 16
        )
        port map(
            clk_i   => clk_i,
            reset_i => reset_i,
            inc_i   => sec_inc,
            value_o => sec_value,
            cycle_o => open
        );

    decoder_inst : entity work.SegmentDecoder(TruthTable)
        port map(
            digit_i    => sec_value,
            segments_o => segments_o
        );
end Structural;

Analyse d’une instruction d’instanciation

Le corps de cette architecture contient trois instructions d’instanciation. Examinons les éléments qui composent ces instructions.

div_counter_inst : entity work.CounterModN(Behavioral)

signifie :

div_counter_inst est une instance de l’entité CounterModN et de son architecture Behavioral qui se trouvent dans la bibliothèque de travail work.

La clause generic map associe une valeur à chaque paramètre générique de l’instance. Cette valeur doit être une constante. Pour l’instance div_counter_inst, les lignes ci-dessous associent la valeur 100e6 (100 000 000) au paramètre N :

generic map(
    N => 100e6
)

La clause port map établit des connexions entre les ports de l’instance et les signaux disponibles dans son environnement. Pour l’instance div_counter_inst les lignes ci-dessous signifient :

port map(
    clk_i   => clk_i,
    reset_i => '0',
    inc_i   => '1',
    value_o => open,
    cycle_o => sec_inc
);

Dans les clauses port map et generic map, les flèches sont toujours dirigées vers la droite : à gauche de la flèche, on trouve le nom d’un paramètre ou d’un port de l’entité à instancier ; à droite de la flèche, on trouve la valeur ou le nom du signal auquel il est associé.

Rôle des signaux internes

Les signaux sec_inc et sec_value sont déclarés dans l’architecture Structural.

signal sec_inc   : std_logic;
signal sec_value : integer range 0 to 15;

Ce ne sont ni des entrées, ni des sorties. Ces signaux servent à relier entre eux les trois composants de notre circuit :

div_counter_inst : entity work.CounterModN(Behavioral)
    ...
    port map(
        ...
        cycle_o => sec_inc
    );

sec_counter_inst : entity work.CounterModN(Behavioral)
    ...
    port map(
        ...
        inc_i   => sec_inc,
        value_o => sec_value,
        ...
    );

decoder_inst : entity work.SegmentDecoder(TruthTable)
    port map(
        digit_i => sec_value,
        ...
    );

La distinction entre les descriptions structurelles et comportementales est là pour faciliter la compréhension des notions et leur mise en application. En réalité, VHDL n’impose pas de respecter strictement ces deux types de description. Dans une même architecture, il est possible de mélanger des instructions comportementales et des instructions d’instanciation.

Cependant, un usage fréquent consiste à utiliser le nom Behavioral pour les architectures à dominante comportementale, et Structural pour les architectures à dominante structurelle.