在verilog中使用带有for循环的generate

CDN*_*CDN 7 verilog

我试图理解为什么我们在verilog中使用generate和for循环.

一起使用generate和for循环:

reg [3:0] temp;
genvar i;
generate
for (i = 0; i < 3 ; i = i + 1) begin: 
    always @(posedge sysclk) begin
        temp[i] <= 1'b0;
    end
end
endgenerate
Run Code Online (Sandbox Code Playgroud)

仅用于循环:

reg [3:0] temp;
genvar i;
always @(posedge sysclk) begin
  for (i = 0; i < 3 ; i = i + 1) begin: 
    temp[i] <= 1'b0;
    end
end
Run Code Online (Sandbox Code Playgroud)

我正在考虑这两个片段基本上会产生相同的结果,即temp [0]到temp [10]等于值0.在这种情况下,使用generate语句我们看到的区别/优势是什么?

Gre*_*reg 6

在没有 the 的例子中generatei应该是genvarnot integer。否则,两者均有效,具体取决于您的工具集支持的 IEEE Std 1364 版本。IEEE Std 1364-2001 中添加了生成结构,其中明确需要generate/关键字。endgenerate在 IEEE Std 1364-2005 中,它成为可选的,唯一的要求是如果generate使用它必须有一个匹配的endgenerate.

当使用 IEEE Std 1364-2005 或 SystemVerilog (IEEE Std 1800) 时,这是隐式声明与显式声明的编码风格偏好的问题。显式确实具有向后可比较的优点。


当通过参数更改模块的物理结构时,生成块非常有用。例如,选择 negedge 或 posege 时钟并仅启用其中之一:

if ( param_use_pos == 1) begin : use_pos
  always @(posedge sysclk) begin
    ...
  end
end
else begin : use_neg
  always @(negedge sysclk) begin
     ...
  end
end
Run Code Online (Sandbox Code Playgroud)

如果不更改物理结构,通常最好在always 块内使用for 循环和if-else 语句。两种方法都可以合成相同的结果,但在运行 RTL 仿真时,非生成块方法通常会仿真得更快。这是因为模拟器通常可以比 N 个 1 位操作更快地处理单个 N 位操作。再次合成也是同样的结果

// faster :: 1 always block, simulator can optimize the for loop
always @(posedge sysclk) begin 
  for (i = 0; i < 3 ; i = i + 1) begin
    temp[i] <= 1'b0;
  end
end

// slower :: creates 4 always blocks, harder for the simulator to optimize
genvar i;
generate // optional if > *-2001
for (i = 0; i < 3 ; i = i + 1) begin 
    always @(posedge sysclk) begin
        temp[i] <= 1'b0;
    end
end
endgenerate // match generate 
Run Code Online (Sandbox Code Playgroud)


小智 5

通常,generate for循环和regular for循环之间的主要区别在于generate for循环正在为每次迭代生成一个实例。这意味着在您的示例中将始终有3个块(与常规循环情况下的1个块相反)。

需要为之生成代码的一个很好的例子是:

module A();
..
endmodule;

module B();
parameter NUM_OF_A_MODULES = 2; // should be overriden from higher hierarchy
genvar i;
for (i=0 i<NUM_OF_A_MODULES; i=i+1) {
  A A_inst();
}
endmodule;
Run Code Online (Sandbox Code Playgroud)

在此示例中,常规for无法完成创建NUM_OF_A_MODULES实例的工作。

您的示例中,您可以通过两种方式实现所需的结果。(只要您修复了一些小错误:))