Code templates: Generate for loop


This is the first part of a series of posts I will write on various code structures and examples for HDL designs. Here I want to talk about the generate statement and particularly the for loop.

Most programmers think of a for loop as being a code segment that is repeated during execution of the program. The generate for loop is similar in concept however the difference is that the code segment is repeated on compilation time. For example, I could write the code:

for(i = 0; i < 8; i++)
  printf("hello world");

To achieve the same functional effect, I could have written the printf statement 8 times. Of course you wouldn’t do this because it’s not good coding practice and likewise you would not do this in HDL. But what does the compiler do with the for loop? In reality, the C compiler will not replace your for loop with 8 copies of the printf statement, but in the case of the generate for loop, the synthesis program will do that! That is precisely the point of the generate for loop: to save you writing the same code segment multiple times, preventing you from making errors and making for cleaner code.

The example below shows a generate for loop that generates 8 regional clock buffers (BUFR) using the same chip enable (CE) and clear (CLR) signals but with their own clock input and output signals. The separate clock input and output signals are referenced to different bits of a signal vector using the variable called index.

VHDL generate for loop:

gen_code_label:
  for index in 0 to 7 generate
    begin
      BUFR_inst : BUFR
      generic map (
        BUFR_DIVIDE => "BYPASS")
      port map (
        O => clk_o(index),
        CE => ce,
        CLR => clear,
        I => clk_i(index)
      );
  end generate;

Verilog generate for loop:

genvar index;
generate
for (index=0; index < 8; index=index+1)
  begin: gen_code_label
    BUFR BUFR_inst (
      .O(clk_o(index)), // Clock buffer ouptput
      .CE(ce), // Clock enable input
      .CLR(clear), // Clock buffer reset input
      .I(clk_i(index)) // Clock buffer input
    );
  end
endgenerate

Now you might ask why you would want to write the same code segment multiple times so here are a couple of examples where you would want to use the generate for loop:

  • Instantiating multiple RocketIO, HDL modules, buffers, etc. Using the generate for loop makes your code cleaner and is easier to check and debug later on. Going up a notch, when you have to instantiate hundreds of thousands of something, the generate loop becomes absolutely necessary, not just convenient.
  • Making a large number of connections between several signals. Writing out the connections for a hundred signal vectors can be made easier by grouping the vectors into an array and writing a generate for loop to make the connections.

So if you have written code that contains lots of repetitive stuff, try using the generate loop to clean it up. If you’ve got questions about the generate for loop, leave them in the comments below.


See also