Décrire et interconnecter des composants

Modules

Contrairement à VHDL, le langage Verilog ne sépare pas la description de l’interface d’un circuit et la description de son implémentation. Les deux notions sont regroupées sous la forme de modules.

À titre de comparaison, voici la description d’un circuit comparateur en VHDL :

entity Comparator is
    port(
        a_i, b_i         : in  integer range 0 to 255;
        lt_o, eq_o, gt_o : out std_logic
    );
end Comparator;

architecture Behavioral of Comparator is
    signal lt, gt : std_logic;
begin
    lt   <= '1' when a_i < b_i else '0';
    gt   <= '1' when a_i > b_i else '0';
    lt_o <= lt;
    gt_o <= gt;
    eq_o <= lt nor gt;
end Behavioral;

Et voici une traduction possible en Verilog :

module Comparator (
    input  [7:0] a_i,
    input  [7:0] b_i,
    output       lt_o,
    output       gt_o,
    output       eq_o
);

assign lt_o = a_i < b_i;
assign gt_o = a_i > b_i;
assign eq_o = ~(lt_o | gt_o);

endmodule

La syntaxe générale d’un module est :

module nom du module (
    port, port, ...
);

déclarations et instructions

endmodule

ou, pour les versions récentes du langage :

module nom du module #(
    paramètre, paramètre, ...
)
(
    port, port, ...
);

déclarations et instructions

endmodule

Ports

Selon la version du langage utilisée, la déclaration des ports pourra prendre différentes formes. Dans l’exemple ci-dessous, on déclare les ports suivants :

Port Direction Type Rôle
a_i Entrée Vecteur de 8 bits numérotés de 7 à 0 La première valeur à comparer
b_i Entrée Vecteur de 8 bits numérotés de 7 à 0 La première valeur à comparer
lt_o Sortie Logique 1 si a_i est strictement inférieur à b_i
gt_o Sortie Logique 1 si a_i est strictement supérieur à b_i
eq_o Sortie Logique 1 si a_i est égale à b_i

En Verilog 1995 :

module Comparator (a_i, b_i, lt_o, gt_o, eq_o);

input  [7:0] a_i;
input  [7:0] b_i;
output       lt_o;
output       gt_o;
output       eq_o;

...

endmodule

À partir de Verilog 2001, on peut placer les déclarations de ports entre les parenthèses :

module Comparator (
    input  [7:0] a_i,
    input  [7:0] b_i,
    output       lt_o,
    output       gt_o,
    output       eq_o
);

...

endmodule

ou encore :

module Comparator (
    input  [7:0] a_i, b_i,
    output       lt_o, gt_o, eq_o
);

...

endmodule

Paramètres

En Verilog, le mot-clé parameter introduit un paramètre d’un module, similaire aux paramètres génériques du VHDL.

Par exemple, dans le module Comparator, on peut rendre le nombre de bits des entrées réglable de la manière suivante. Si la valeur du paramètre n’est pas précisée à l’instanciation, c’est la valeur indiquée après l’opérateur = qui sera utilisée :

module Comparator (a_i, b_i, lt_o, gt_o, eq_o);

parameter WIDTH = 8;

input  [WIDTH-1:0] a_i;
input  [WIDTH-1:0] b_i;
output             lt_o;
output             gt_o;
output             eq_o;

...

endmodule

Avec des versions récentes de Verilog, on peut écrire :

module Comparator #(
    parameter WIDTH = 8
)
(
    input  [WIDTH-1:0] a_i,
    input  [WIDTH-1:0] b_i,
    output             lt_o,
    output             gt_o,
    output             eq_o
);

...

endmodule

L’instruction d’instanciation

L’instanciation crée un exemplaire d’un module à l’intérieur d’un autre module. Par exemple, si je souhaite utiliser le module Comparator en tant que composant dans un circuit plus grand, je peux écrire :

module MyCircuit (
    ...
);

...

wire [7:0] a;
wire [7:0] b;
wire       lt;
wire       gt;
wire       eq;

Comparator my_comparator (a, b, lt, gt, eq);

...

endmodule

Ici, les ports de l’instance my_comparator seront reliés à des signaux a, b, lt, gt, eq qui doivent être indiqués dans le bon ordre entre les parenthèses.

Une pratique courante, en VHDL comme en Verilog, consiste à spécifier les associations de ports par noms :

Comparator my_comparator (
    .a_i(a), // Le port a_i de my_comparator est relié au signal a
    .b_i(b),
    .lt_o(lt),
    .gt_o(gt),
    .eq_o(eq)
);

Si l’on souhaite donner une valeur particulière au paramètre WIDTH du module Comparator, on peut l’indiquer de la manière suivante :

wire [11:0] a;
wire [11:0] b;
...

Comparator my_comparator #(
    .WIDTH(12)
)
(
    .a_i(a),
    .b_i(b),
    .lt_o(lt),
    .gt_o(gt),
    .eq_o(eq)
);