我试图理解为什么我们在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
仅用于循环:
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
我正在考虑这两个片段基本上会产生相同的结果,即temp [0]到temp [10]等于0。在这种情况下使用generate语句我们看到的区别/优势是什么?
答案 0 :(得分: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;
在此示例中,常规for无法执行创建NUM_OF_A_MODULES个实例的工作。
在您的示例中,您可以通过两种方式获得所需的结果。 (只要你修复一些小错误:))
答案 1 :(得分:2)
在没有generate
的示例中,i
应该是genvar
而不是integer
。否则,两者都有效,具体取决于工具集支持的IEEE Std 1364版本。在IEEE Std 1364-2001中添加了generate构造,其中明确要求generate
/ endgenerate
个关键字。在IEEE Std 1364-2005中,它成为可选项,唯一的要求是如果使用generate
,它必须具有匹配的endgenerate
。
使用IEEE Std 1364-2005或SystemVerilog(IEEE Std 1800)时,需要对隐式声明与显式声明的编码样式优先级进行编码。明确确实具有向后可比性的优势。
通过参数更改then模块的物理结构时,生成块很有用。例如,选择negedge或posedge clock并仅启用一个:
if ( param_use_pos == 1) begin : use_pos
always @(posedge sysclk) begin
...
end
end
else begin : use_neg
always @(negedge sysclk) begin
...
end
end
如果您不更改物理结构,通常最好在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
答案 2 :(得分:0)
generate for
循环让您可以访问(使用分层名称)生成的实例的内部信号。常规的 for
循环不允许您这样做。
否则,原则上,循环展开对两者都会发生(至少对于可合成结构)。
因此,对于测试平台,使用常规 for
循环可能更常见,但对于设计模块,使用 generate for
循环可能更常见。