在Systemverilog中,通过`define macros选择生成语句,反之亦然?
例如,如果我想有条件地实例化module1或module2,似乎我可以做到
`ifdef COND1
module1 ();
`else
module2 ();
或
generate
if (COND1) begin
module1 ();
end else begin
module2();
end
endgenerate
答案 0 :(得分:2)
人们会有不同的意见,但两者之间的一个很大的区别是生成允许不同的实例配置不同,但宏不会。这是因为生成在详细说明时进行评估,而不是在编译时进行评估。
例如,如果我们有一个模块:
module ahwoogaa #(bit COND1) ();
generate
if (COND1) begin
module1 ();
end else begin
module2();
end
endgenerate
endmodule
我可以用COND1实例化两次,如下所示:
module neeenaaaw();
ahwoogaa #(1'b0) alarm1();
ahwoogaa #(1'b1) alarm2();
endmodule
对于define
,您必须为所有实例设置单个值COND1
,因为在编译模块时将值设置为一次。
就个人而言,我说只要你可以就去生成。
答案 1 :(得分:1)
`ifdef
可以在端口列表中使用:
module music
output [31:0] left,
`ifdef STEREO
output [31:0] right,
`enfif
...
生成允许循环,实例化X次
genvar inst;
generate
for (inst=0; inst<3; inst=inst+1) begin : gen_block
sub_module instancex( .clk, .din(din[inst]), .dout(dout[inst]) );
end
endgenerate
注意:这引入了额外的层次结构(gen_block)。
答案 2 :(得分:1)
我假设问题仅涉及条件实例化。
前一段时间我们遇到了类似的困境,当时我们的项目最初是为了集成到特定平台而开发的,必须适应其他平台。我们希望使用IFDEF / Generate来区分单个源代码。
在我看来:
1)IFDEF看起来比Generates简单得多(而且确实如此),但它们很危险。只有当您完全确定条件实例化是独占的时才使用它们(请参阅Paul S的答案),您无法使用generate实现相同的功能,并且您完全确定需要此条件实例化。使用IFDEF的通常位置是顶级层次结构。
编辑:有another question on StackOverflow这是验证工程师因为某些设计师滥用`ifdef而挣扎的一个例子。
2)在用上面的1警告你之后,我可以说IFDEF具有巨大的优势(由于它们被预处理):你可以使用IFDEF有条件地实例化网络,参数和端口。比较IFDEF的以下用法:
module module1 (
input in1,
output logic out1
`ifdef COND
, output logic out2
`endif
);
assign out1 = in1;
`ifdef COND
submodule submodule1(.in(in1), .out(out2));
`else
endmodule
并生成:
module module1 (
input in1,
output logic out1,
output logic out2
);
assign out1 = in1;
generate if (COND)
submodule submodule1(.in(in1), .out(out2));
else
assign out2 = in1;
endgenerate
endmodule
在上面(非常简单)的示例中,当COND不为真并且您使用IFDEF时,您可能不担心驱动“out2” - 此端口将不存在。作为缺点,在实例化“module1”时,您必须使用相同的IFDEF。 在这个例子中,IFDEF的优势可能并不明显,但想象你有100个连接某个子模块的端口(或网络)。如果未实例化子模块,则在使用Generate时,所有这些端口都会绑定一些值,但您可以使用IFDEF删除它们。
3)正如Morgan所说,Generate引入了一个额外的层次结构。虽然在设计导航器中看到这一点有点令人恼火,但当你想在现有代码中插入生成并且有一些工具利用模块的路径时,它会成为真正的痛苦 - 你必须找到所有这些工具和改变那里的等级。
4)我听说IFDEF严重“老化”。这意味着如果使用IFDEF而不是Generates,维护代码会更加困难。总结:经过一段时间将我们的设计与IFDEF和Generates区分开来后,我们意识到它不实用。现在我们并行维护两个源代码 - 每个平台一个。在顶层模块中使用IFDEF来移除/切换模块并删除不必要的端口和参数。如果要在略微不同的参数化中使用相同的模块,请使用“生成”。请勿使用这些结构对设计进行重大更改。