CDN
CDN

Reputation: 167

Using a generate with for loop in verilog

I'm trying to understand why we use generate in verilog along with a for loop.

Using a generate and for loop together:

reg [3:0] temp;
genvar i;
generate
for (i = 0; i < 3 ; i = i + 1) begin: 
    always @(posedge sysclk) begin
        temp[i] <= 1'b0;
    end
end
endgenerate

Using only for loop:

reg [3:0] temp;
genvar i;
always @(posedge sysclk) begin
  for (i = 0; i < 3 ; i = i + 1) begin: 
    temp[i] <= 1'b0;
    end
end

I'm considering the two snippets would basically produce the same result i.e. temp[0] to temp[10] equal to value 0. What is the difference/advantage we see by using a generate statement in this case ?

Upvotes: 14

Views: 132071

Answers (3)

vharihar
vharihar

Reputation: 79

generate for loops let you access (using hierarchical names) the internal signals of the instances generated. The regular for loop doesn't let you do that.

Otherwise, in principle, the loop unrolling happens for both (for synthesizable constructs, atleast).

Hence, for testbenches it may be more typical to use regular for loops, but for the design modules it may be more typical to use generate for loops.

Upvotes: 1

Greg
Greg

Reputation: 19094

In the example without the generate, i should be a genvar not integer. Otherwise, both are valid depending on the version of the IEEE Std 1364 supported by your tool set. The generate construct was added in in IEEE Std 1364-2001 where the generate/endgenerate keywords are explicitly required. In IEEE Std 1364-2005 it became optional with the only requirement that if generate is used it must have a matching endgenerate.

When using IEEE Std 1364-2005 or SystemVerilog (IEEE Std 1800), it is a matter for coding style preference of implicit vs explicit declaration. Explicit does have the advantage of being backward comparability.


Generate blocks are useful when change the physical structure of then module via parameters. For example choosing negedge or posedge clock and only enabling one:

if ( param_use_pos == 1) begin : use_pos
  always @(posedge sysclk) begin
    ...
  end
end
else begin : use_neg
  always @(negedge sysclk) begin
     ...
  end
end

If you are not changing the physical structure, it is typically better to use for loops and if-else statements inside the always block. Both approaches can synthesize the same but when running RTL simulation the non-generate block approach will typically simulate faster. This is because simulators normally can process a single N-bit operation faster than N 1-bit operations. Again synthesis is the same result

// faster :: 1 always block, simulator can optimize the for loop
always @(posedge sysclk) begin 
  for (i = 0; i < 3 ; i = i + 1) begin
    temp[i] <= 1'b0;
  end
end

// slower :: creates 4 always blocks, harder for the simulator to optimize
genvar i;
generate // optional if > *-2001
for (i = 0; i < 3 ; i = i + 1) begin 
    always @(posedge sysclk) begin
        temp[i] <= 1'b0;
    end
end
endgenerate // match generate 

Upvotes: 7

Razko
Razko

Reputation: 581

In general, the main difference between generate for loop and regular for loop is that the generate for loop is generating an instance for each iteration. Meaning that in your example there will be 3 always blocks (as opposed to 1 block in the regular loop case).

A good example of code that requires generate for is:

module A();
..
endmodule;

module B();
parameter NUM_OF_A_MODULES = 2; // should be overriden from higher hierarchy
genvar i;
for (i=0 i<NUM_OF_A_MODULES; i=i+1) {
  A A_inst();
}
endmodule;

In this example a regular for cannot do the work of creating NUM_OF_A_MODULES instances.

In your example, you can acheive the required result in both ways. (as long as you fix some minor bugs :) )

Upvotes: 14

Related Questions