verilog - Is it possible to conditionally generate a for loop in System Verilog?
问题描述
Currently when I try to conditionally generate a for loop I get a compile error stating that I "Cannot nest generate regions".
Example of what I'm trying to do:
generate
if (x == 0) begin
for (genvar i = 0; i < 16; i++) begin
*some code here*
end
end
else begin
for (genvar k = 0; k < 16; k++) begin
*some code here*
end
endgenerate
Edit: Thank you all for the responses and help, but I've discovered the problem. Thank you Greg for reminding me about not being able to use generate within another generate.
Here's the Minimal Reproducible example that was causing me problems.
module test ();
parameter x = 1;
parameter y = 1;
if (y == 1) begin
generate
if (x == 1) begin
for (genvar i = 0; i < 16; i++) begin
test_inner test_inner1();
end
end
else begin
for (genvar k = 0; k < 16; k++) begin
test_inner test_inner2();
end
end
endgenerate
end
endmodule
As you can see I had a conditional statement nested within another conditional statement. Because I didn't use the generate keyword in the outer conditional I didn't realize that it counted as a generate within another generate.
To solve the problem I moved the generate to the outer conditional, as such:
module test ();
parameter x = 1;
parameter y = 1;
generate
if (y == 1) begin
if (x == 1) begin
for (genvar i = 0; i < 16; i++) begin
test_inner test_inner1();
end
end
else begin
for (genvar k = 0; k < 16; k++) begin
test_inner test_inner2();
end
end
end
endgenerate
endmodule
解决方案
keyword generate
is optional in system verilog. If used, its starts a new generate block. Such generate blocks cannot be nested.
However, if you use generate if
or for
statements without the generate
keyword, the compiler will take care of correct generate block boundaries for you.
In your case #1 you are missing the end
keyword, it cannot be compiled.
In your case #2 you use if (y == 1) begin
which starts a generate block. Then you use the keyword generate
inside the already started block. It makes them nested.
Case #3 is correct use of the generate block.
You do not have case #4, but if you just get rid or both generate
and endgenerate
, it should work the same way as #3.
It always a good idea to name your generated blocks in order to control generated instance names. Like this:
module test ();
parameter x = 1;
parameter y = 1;
if (y == 1) begin: y1
if (x == 1) begin: x1
for (genvar i = 0; i < 16; i++) begin: x1_loop
test_inner test_inner1();
end
end
else begin
for (genvar k = 0; k < 16; k++) begin: x2_loop
test_inner test_inner2();
end
end
end
endmodule
推荐阅读
- javascript - 图例与 Highcharts 中 xAxis 上的列刻度不匹配
- php - 网站抛出“未安装 PHP-GD”但已安装
- c++ - 使用递归打印所有增加的子序列
- swift - 如何从另一个文件更新 NSStausItem?
- google-app-engine - 如何在 Google Cloud AppEngine 上强制使用 https
- python-3.x - 如何修复 plotly trace1 = go.Scatter() 未在 python 上按需要绘制
- android - 在 TableLayout Android 中绘制圆圈
- docker - 创建 Docker 自己的 node_modules
- laravel - 非常简单的 Laravel + Vue 应用程序上的“未捕获 RangeError:超出最大调用堆栈大小”
- kubernetes - 拒绝从同一集群上的 CronJob 连接到 Kubernetes Pod