是否可以在 System Verilog 中有条件地生成 for 循环?
Is it possible to conditionally generate a for loop in System Verilog?
目前,当我尝试有条件地生成 for 循环时,我收到一个编译错误,指出我 "Cannot nest generate regions".
我正在尝试做的事情的例子:
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
编辑:
谢谢大家的回复和帮助,但我已经发现了问题所在。谢谢 Greg 提醒我不能在另一个生成器中使用生成器。
这是给我带来问题的最小可重现示例。
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
如您所见,我在另一个条件语句中嵌套了一个条件语句。因为我没有在外部条件中使用 generate 关键字,所以我没有意识到它算作另一个生成中的生成。
为了解决这个问题,我将生成移到了外部条件,这样:
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
关键字generate
在系统verilog中是可选的。如果使用,它会启动一个新的生成块。这样的生成块不能嵌套。
但是,如果您使用不带 generate
关键字的生成 if
或 for
语句,编译器将为您处理正确的生成块边界。
在您的案例 #1 中,您缺少 end
关键字,它无法编译。
在您的案例 #2 中,您使用 if (y == 1) begin
来启动生成块。然后在已经启动的块中使用关键字 generate
。它使它们嵌套。
案例 #3 是生成块的正确使用。
您没有第 4 种情况,但如果您只是摆脱或同时摆脱 generate
和 endgenerate
,它的工作方式应该与第 3 种情况相同。
为生成的块命名以控制生成的实例名称始终是个好主意。像这样:
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
目前,当我尝试有条件地生成 for 循环时,我收到一个编译错误,指出我 "Cannot nest generate regions".
我正在尝试做的事情的例子:
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
编辑: 谢谢大家的回复和帮助,但我已经发现了问题所在。谢谢 Greg 提醒我不能在另一个生成器中使用生成器。
这是给我带来问题的最小可重现示例。
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
如您所见,我在另一个条件语句中嵌套了一个条件语句。因为我没有在外部条件中使用 generate 关键字,所以我没有意识到它算作另一个生成中的生成。
为了解决这个问题,我将生成移到了外部条件,这样:
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
关键字generate
在系统verilog中是可选的。如果使用,它会启动一个新的生成块。这样的生成块不能嵌套。
但是,如果您使用不带 generate
关键字的生成 if
或 for
语句,编译器将为您处理正确的生成块边界。
在您的案例 #1 中,您缺少 end
关键字,它无法编译。
在您的案例 #2 中,您使用 if (y == 1) begin
来启动生成块。然后在已经启动的块中使用关键字 generate
。它使它们嵌套。
案例 #3 是生成块的正确使用。
您没有第 4 种情况,但如果您只是摆脱或同时摆脱 generate
和 endgenerate
,它的工作方式应该与第 3 种情况相同。
为生成的块命名以控制生成的实例名称始终是个好主意。像这样:
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