Verilog `ifdef 条件编译
Verilog 支持一些编译器指令,这些指令基本上指导编译器以某种方式处理代码。例如,部分代码可能代表某个功能的实现,如果不使用该功能,则应该有某种方式不将代码包含在设计中。
这可以通过 conditional 解决 编译,设计者可以将代码包装在编译器指令中,这些指令告诉编译器在设置给定的命名标志时包含或排除要编译的代码。
语法
Verilog `ifdef
可以实现条件编译 和 `ifndef
关键词。这些关键字可以出现在设计中的任何位置,并且可以嵌套在另一个里面。
关键字 `ifdef
只是告诉编译器包含这段代码,直到下一个 `else
或 `endif
如果给定的名为 FLAG 的宏是使用 `define
定义的 指令。
// 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
关键字 `ifndef
只是告诉编译器包含这段代码,直到下一个 `else
或 `endif
如果给定的名为 FLAG 的宏是 not 使用 `define
定义 指令。
带有`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
测试台
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
请注意,默认情况下,rstn 在设计编译期间不会包含在内,因此它不会出现在端口列表中。但是,如果一个名为 INCLUDE_RSTN 的宏在属于文件编译列表的任何 Verilog 文件中定义,或者通过命令行传递给编译器,则 rstn 将包含在编译中,并且设计将拥有它。
通过在左侧窗格的“编译和运行选项”中添加和删除 +define+INCLUDE_RSTN 进行实验,以了解区别。
Verilog `ifdef `elsif 示例
以下示例在单独的 `ifdef
中有两个显示语句 没有默认 `else
的范围 参与其中。所以这意味着默认情况下不会显示任何内容。如果定义了宏或者MACRO,则包含相应的显示消息,并将在模拟过程中显示
module tb;
initial begin
`ifdef MACRO1
$display ("This is MACRO1");
`elsif MACRO2
$display ("This is MACRO2");
`endif
end
endmodule
模拟日志# 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 示例
可以用 `ifndef
编写相同的代码 结果会适得其反。
module tb;
initial begin
`ifndef MACRO1
$display ("This is MACRO1");
`elsif MACRO2
$display ("This is MACRO2");
`endif
end
endmodule
模拟日志# 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 嵌套`ifdef 示例
`ifdef
并且它的风格可以相互嵌套,以创建复杂的代码包含和排除方式,并使用定义的宏。
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
模拟日志# 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.
请注意,只要未定义父宏,就不会编译其中任何其他嵌套宏的定义。例如,没有 FLAG 的 NEST1_A 或 WHITE 宏定义不会使编译器拾取嵌套代码。
Verilog