Compilation conditionnelle Verilog `ifdef
Verilog prend en charge quelques directives de compilateur qui ordonnent essentiellement au compilateur de traiter le code d'une certaine manière. Par exemple, une partie du code peut représenter une implémentation d'une certaine fonctionnalité et il devrait y avoir un moyen de ne pas inclure le code dans la conception si la fonctionnalité n'est pas utilisée.
Cela peut être résolu avec conditionnel compilation où le concepteur peut envelopper le code dans des directives du compilateur qui indiquent au compilateur d'inclure ou d'exclure le code pour la compilation lorsque l'indicateur nommé donné est défini.
Syntaxe
La compilation conditionnelle peut être réalisée avec Verilog `ifdef
et `ifndef
mots clés. Ces mots-clés peuvent apparaître n'importe où dans le design et peuvent être imbriqués les uns dans les autres.
Le mot clé `ifdef
indique simplement au compilateur d'inclure le morceau de code jusqu'au prochain `else
ou `endif
si la macro donnée appelée FLAG est définie à l'aide d'un `define
directives.
// Style #1: Only single `ifdef
`ifdef <FLAG>
// Statements
`endif
// Style #2: `ifdef with `else part
`ifdef <FLAG>
// Statements
`else
// Statements
`endif
// Style #3: `ifdef with additional ifdefs
`ifdef <FLAG1>
// Statements
`elsif <FLAG2>
// Statements
`elsif <FLAG3>
// Statements
`else
// Statements
`endif
Le mot clé `ifndef
indique simplement au compilateur d'inclure le morceau de code jusqu'au prochain `else
ou `endif
si la macro donnée appelée FLAG n'est pas défini à l'aide d'un `define
directives.
Exemple de conception avec `ifdef
module my_design (input clk, d,
`ifdef INCLUDE_RSTN
input rstn,
`endif
output reg q);
always @ (posedge clk) begin
`ifdef INCLUDE_RSTN
if (!rstn) begin
q <= 0;
end else
`endif
begin
q <= d;
end
end
endmodule
Banc de test
module tb;
reg clk, d, rstn;
wire q;
reg [3:0] delay;
my_design u0 ( .clk(clk), .d(d),
`ifdef INCLUDE_RSTN
.rstn(rstn),
`endif
.q(q));
always #10 clk = ~clk;
initial begin
integer i;
{d, rstn, clk} <= 0;
#20 rstn <= 1;
for (i = 0 ; i < 20; i=i+1) begin
delay = $random;
#(delay) d <= $random;
end
#20 $finish;
end
endmodule
Notez que par défaut, rstn ne sera pas inclus lors de la compilation de la conception et n'apparaîtra donc pas dans la liste des ports. Cependant, si une macro appelée INCLUDE_RSTN est définie dans un fichier Verilog faisant partie de la liste de compilation des fichiers ou transmise via la ligne de commande au compilateur, rstn sera inclus dans la compilation et la conception l'aura.
Expérimentez en ajoutant et en supprimant +define+INCLUDE_RSTN de "Options de compilation et d'exécution" dans le volet de gauche pour connaître la différence.
Exemple Verilog `ifdef `elsif
L'exemple suivant a deux instructions d'affichage à l'intérieur de `ifdef
distinct portées qui n'ont pas de `else
par défaut en faire partie. Cela signifie donc que par défaut rien ne sera affiché. Si la macro ou MACRO est définie, le message d'affichage correspondant est inclus et sera affiché pendant la simulation
module tb;
initial begin
`ifdef MACRO1
$display ("This is MACRO1");
`elsif MACRO2
$display ("This is MACRO2");
`endif
end
endmodule
Journal de simulation # With no macros defined ncsim> run ncsim: *W,RNQUIE: Simulation is complete. # With +define+MACRO1 ncsim> run This is MACRO1 ncsim: *W,RNQUIE: Simulation is complete. # With +define+MACRO2 ncsim> run This is MACRO2 ncsim: *W,RNQUIE: Simulation is complete.
Exemple Verilog `ifndef `elsif
Le même code peut être écrit avec `ifndef
et les résultats seront tout le contraire.
module tb;
initial begin
`ifndef MACRO1
$display ("This is MACRO1");
`elsif MACRO2
$display ("This is MACRO2");
`endif
end
endmodule
Journal de simulation # With no macros defined ncsim> run This is MACRO1 ncsim: *W,RNQUIE: Simulation is complete. # With +define+MACRO1 ncsim> run ncsim: *W,RNQUIE: Simulation is complete. # With +define+MACRO2 ncsim> run This is MACRO1 ncsim: *W,RNQUIE: Simulation is complete. # With +define+MACRO1 +define+MACRO2 ncsim> run This is MACRO2 ncsim: *W,RNQUIE: Simulation is complete.
Exemple `ifdef imbriqué Verilog
`ifdef
et ses versions peuvent être imbriquées les unes dans les autres pour créer des méthodes complexes d'inclusion et d'exclusion de code avec des macros définies.
module tb;
initial begin
`ifdef FLAG
$display ("FLAG is defined");
`ifdef NEST1_A
$display ("FLAG and NEST1_A are defined");
`ifdef NEST2
$display ("FLAG, NEST1_A and NEST2 are defined");
`endif
`elsif NEST1_B
$display ("FLAG and NEST1_B are defined");
`ifndef WHITE
$display ("FLAG and NEST1_B are defined, but WHITE is not");
`else
$display ("FLAG, NEST1_B and WHITE are defined");
`endif
`else
$display ("Only FLAG is defined");
`endif
`else
$display ("FLAG is not defined");
`endif
end
endmodule
Journal de simulation # Without defining any macro ncsim> run FLAG is not defined ncsim: *W,RNQUIE: Simulation is complete. # With +define+FLAG +define+NEST1_B ncsim> run FLAG is defined FLAG and NEST1_B are defined FLAG and NEST1_B are defined, but WHITE is not ncsim: *W,RNQUIE: Simulation is complete. # With +define+FLAG +define+NEST1_B +define+WHITE ncsim> run FLAG is defined FLAG and NEST1_B are defined FLAG, NEST1_B and WHITE are defined ncsim: *W,RNQUIE: Simulation is complete. # With +define+FLAG ncsim> run FLAG is defined Only FLAG is defined ncsim: *W,RNQUIE: Simulation is complete. # With +define+WHITE ncsim> run FLAG is not defined ncsim: *W,RNQUIE: Simulation is complete. # With +define+NEST1_A ncsim> run FLAG is not defined ncsim: *W,RNQUIE: Simulation is complete.
Notez que tant que la macro parent n'est pas définie, la définition de toute autre macro imbriquée dans celle-ci n'est pas compilée. Par exemple, les définitions de macro NEST1_A ou WHITE sans FLAG n'obligent pas le compilateur à récupérer le code imbriqué.
Verilog