Verilog `ifdef voorwaardelijke compilatie'
Verilog ondersteunt een aantal compiler-richtlijnen die de compiler in wezen opdragen om de code op een bepaalde manier te behandelen. Een deel van de code kan bijvoorbeeld een implementatie van een bepaalde functie vertegenwoordigen en er moet een manier zijn om de code niet in het ontwerp op te nemen als de functie niet wordt gebruikt.
Dit kan worden opgelost met voorwaardelijk compilatie waarbij de ontwerper de code kan inpakken in compilerrichtlijnen die de compiler vertellen om de code voor compilatie op te nemen of uit te sluiten wanneer de opgegeven benoemde vlag is ingesteld.
Syntaxis
Voorwaardelijke compilatie kan worden bereikt met Verilog `ifdef
en `ifndef
trefwoorden. Deze trefwoorden kunnen overal in het ontwerp voorkomen en kunnen in elkaar worden genest.
Het trefwoord `ifdef
vertelt de compiler gewoon om het stuk code op te nemen tot de volgende `else
of `endif
als de gegeven macro genaamd FLAG is gedefinieerd met een `define
richtlijn.
// 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
Het trefwoord `ifndef
vertelt de compiler gewoon om het stuk code op te nemen tot de volgende `else
of `endif
als de gegeven macro genaamd FLAG niet . is gedefinieerd met een `define
richtlijn.
Ontwerpvoorbeeld met `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
Testbank
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
Merk op dat rstn standaard niet zal worden opgenomen tijdens het samenstellen van het ontwerp en daarom niet zal verschijnen in de portlist. Als een macro met de naam INCLUDE_RSTN echter is gedefinieerd in een Verilog-bestand dat deel uitmaakt van de compilatielijst van bestanden of via de opdrachtregel naar de compiler is doorgegeven, wordt rstn in de compilatie opgenomen en zal het ontwerp het hebben.
Experimenteer door +define+INCLUDE_RSTN toe te voegen aan en te verwijderen uit 'Opties voor compileren en uitvoeren' in het linkerdeelvenster om het verschil te zien.
Verilog `ifdef `elsif Voorbeeld
Het volgende voorbeeld heeft twee weergave-instructies binnen afzonderlijke `ifdef
scopes die geen standaard `else
. hebben er deel aan. Dit betekent dus dat er standaard niets wordt weergegeven. Als de macro of MACRO is gedefinieerd, wordt het bijbehorende displaybericht opgenomen en wordt dit weergegeven tijdens de simulatie
module tb;
initial begin
`ifdef MACRO1
$display ("This is MACRO1");
`elsif MACRO2
$display ("This is MACRO2");
`endif
end
endmodule
Simulatielogboek # 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.
Verilog `ifndef `elsif Voorbeeld
Dezelfde code kan worden geschreven met `ifndef
en de resultaten zullen precies het tegenovergestelde zijn.
module tb;
initial begin
`ifndef MACRO1
$display ("This is MACRO1");
`elsif MACRO2
$display ("This is MACRO2");
`endif
end
endmodule
Simulatielogboek # 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.
Verilog genest `ifdef-voorbeeld
`ifdef
en zijn smaken kunnen in elkaar worden genest om complexe manieren te creëren voor het opnemen en uitsluiten van code met gedefinieerde macro's.
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
Simulatielogboek # 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.
Merk op dat zolang de bovenliggende macro niet is gedefinieerd, de definitie van een andere geneste macro erin niet wordt gecompileerd. NEST1_A of WHITE macrodefinities zonder FLAG zorgen er bijvoorbeeld niet voor dat de compiler de geneste code oppikt.
Verilog