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: 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

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

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 

ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJobWlraGh9eoOOoqpmoaRivbC%2F0qKZpZ1dqbxur86nm6KsmaS7orjLsmSgnZ6av6LAxGaYZp6fp3qtu86pZKKmXajGtMDEpmSvnaKeubCz

 Share!