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
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
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’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)
);