何时使用define macro vs generate

时间:2013-05-20 03:57:44

标签: macros system-verilog

在Systemverilog中,通过`define macros选择生成语句,反之亦然?

例如,如果我想有条件地实例化module1或module2,似乎我可以做到

`ifdef COND1
module1 ();
`else
module2 ();

generate
if (COND1) begin
module1 ();
end else begin
module2();
end
endgenerate

3 个答案:

答案 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来移除/切换模块并删除不必要的端口和参数。如果要在略微不同的参数化中使用相同的模块,请使用“生成”。请勿使用这些结构对设计进行重大更改。

相关问题