Search code examples
verilogsystem-verilog

Can I use multi-level nested generate statement?


I'm curious if using multi-level nesting of the generate statement is possible.
As far as I know, it's impossible.
Here is a very simplified problem that I want to find a solution for. Suppose there is a design composed of blocks in a hierarchy. For example, there are 32 grids, there are 64 blocks in each grid, and there are 1024 threads in each block. This is very weird and inefficient code, but can I do the code below using a nested generate statement?

// 32 grids, 64 blocks in each grid, 1024 threads in each block

initial begin
        grid0.block0.thread0.reset = 1;
end
initial begin
        grid0.block0.thread1.reset = 1;
end
...
initial begin
        grid0.block0.thread1023.reset = 1;
end

initial begin
        grid0.block1.thread0.reset = 1;
end
initial begin
        grid0.block1.thread1.reset = 1;
end
...
initial begin
        grid0.block1.thread1023.reset = 1;
end


...
        
initial begin
        grid31.block63.thread1022.reset = 1;
end
initial begin
        grid31.block63.thread1023.reset = 1;
end

I would be very happy if I could do something like :

genvar grididx,blockidx,threadidx;
generate for(grididx=0;grididx<32;grididx++) begin
generate for(blockidx=0;blockidx<32;blockidx++) begin
generate for(threadidx=0;threadidx<32;threadidx++) begin
        initial begin
                grid`grididx.block`blockidx.thread`threadidx = 1;
        end
endgenerate  
endgenerate
endgenerate

(I can generate code using a C program with print loops and include it of course.)


Solution

  • It is legal to use nested generate for loops, but you can not achieve what you want given your current design hierarchy. For example, you have unrelated instances: grid0 and grid31. You gave the instances static names.

    If you had created an array of instances (grid[31:0], for example), then you could have used generate for loops for your assignments. You would have also had to create instance arrays of block and thread as well. Then, your assignment would look something like:

    genvar grididx,blkidx,threadidx;
    for(grididx=0;grididx<32;grididx++) begin
    for(blockidx=0;blockidx<32;blockidx++) begin
    for(threadidx=0;threadidx<32;threadidx++) begin
            initial begin
                    grid[grididx].block[blockidx].thread[threadidx].reset = 1;
            end
    end
    end
    end
    

    The generate/endgenerate keywords are optional. Also, you can not nest generate keywords like you tried.

    Refer to IEEE Std 1800-2017, section 23.6 Hierarchical names:

    Names in a hierarchical path name that refer to instance arrays or loop generate blocks may be followed immediately by a constant expression in square brackets. This expression selects a particular instance of the array and is, therefore, called an instance select. The expression shall evaluate to one of the legal index values of the array.