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...
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
1 Answer
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