Electronic – Question about Synthesizable For loop and Generate

loopverilog

I am using the Verilog language and Zedboard as a target board.

As far as I know, the for loop can be synthesized, and the synthesis tool translates the for loop as a sequence of duplicated instructions like the loop unrolling.

For example,

for ( i = 0; i < 4; i=i+1) begin
  mem[i] = i;
end

will be translated to 
mem[0] = 0;
mem[1] = 1;
mem[2] = 2;
mem[3] = 3;

Therefore, as far as I know, the for loop can be used if the resource is available to infer the multiple but same purposed gates.

However, it seems that the generate in Verilog can be used to, not only imply the multiple instances, but also the multiple instructions same as the for loop.

I understand the generate can only imply the multiple instances of the module and the for loop cannot be used for that purpose.

Then what is the difference between the generate + for loop and just for loop? I think both works like the loop unrolling though. Is there any noticeable difference? If there is no difference, which one is preferable coding style to induce loop-unrolling?

Best Answer

Verilog for-loops are perfectly synthesizable under certain conditions:

  • You can use any procedural statement within a loop (e.g. if-else).
  • The number of loops must be predetermined.
    • The limiting expression must be a comparison between the loop variable and either a constant or a parameter.
    • The step assignment must be incrementing the loop value by a constant amount.
  • You can assign a different value to the same variable in each loops (e.g. calculating an index from the loop variable).
  • For synthesis purposes, the loop is evaluated in zero time – i.e. if you tried to make a counter, you would only ever see the final value.

Those same rules apply whether you use a for-loop in a procedural block, or in a generate block.

When done in a procedural block, initial and always, you can use a for loop to change elements in an array (exactly as your example), or you could change the same value multiple times, for example:

for (idx = 0; idx < 4; idx=idx+1) begin
    a = a + b[idx];
    c = c + 2;     //You can change more than one variable in a for loop
end

In that example, the resulting hardware will be a chain of adders, summing the values from four array indices.

The key thing is that you can't create new variables or modules in a procedural for loop. This rule applies to procedural blocks in general, not just for loops (i.e. you can't declare a variable in a procedural block).

 

Generate blocks on the other hand do allow the creation of variables and the instantiation of modules. That means in a generate block, you can use a generate for loop to infer modules. That's pretty much the only difference.

For generate for loops, you must use a genvar as the loop variable (i.e. the value you use to count through each loop). You must also give the for loop a name:

for (loopVal = 0; loopVal < 4; loopVal = loopVal + 1) begin : loopName

This name is prepended to any piece of hardware you instantiate in the loop. So if you create an instance called bob, the above loop would create instances:

loopName[0]|bob
loopName[1]|bob
loopName[2]|bob
loopName[3]|bob

This results in multiple instances with unique names.

 

Both generate and procedural for loops will perform loop unrolling as you say. The difference is simply how you can use them. Procedural can be used in procedural blocks (e.g. for initialising a memory). Generate can only be used in generate blocks.

They are both useful and preferred. One can't replace the other.