Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verilog generate/genvar in an always block

Tags:

I'm trying to get a module to pass the syntax check in ISE 12.4, and it gives me an error I don't understand. First a code snippet:

parameter ROWBITS = 4;  reg [ROWBITS-1:0] temp;  genvar c; generate     always @(posedge sysclk) begin         for (c = 0; c < ROWBITS; c = c + 1) begin: test             temp[c] <= 1'b0;         end     end endgenerate 

When I try a syntax check, I get the following error message:

ERROR:HDLCompiler:731 - "test.v" Line 46: Procedural assignment to a non-register <c> is not permitted.

I really don't understand why it's complaining. "c" isn't a wire, it's a genvar. This should be the equivalent of the completely legal syntax:

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

Please, no comments about how it'd be easier to write this without the generate. This is a reduced example of a much more complex piece of code involving multiple ifs and non-blocking assignments to "temp". Also, don't just tell me there are newer versions of ISE, I already know that. OTOH, if you know it's fixed in a later version of ISE, please let me know which version you know works.

like image 995
user1684538 Avatar asked Sep 20 '12 00:09

user1684538


People also ask

Can I use generate inside always block?

We can only use generate statements in concurrent SystemVerilog code. This means we can't use generate statements inside procedural blocks such as always blocks. In addition to this, we have to use either an if statement, case statement or a for loop together with the generate keyword.

What is Genvar in Verilog?

A genvar is a variable used in generate-for loop. It stores positive integer values. It differs from other Verilog variables in that it can be assigned values and changed during compilation and elaboration time.

Is Genvar synthesizable Verilog?

Verilog Generate Loop The genvar is used as an integer to evaluate the generate loop during elaboration. The genvar declaration can be inside or outside the generate region, and the same loop index variable can be used in multiple generate loops, as long as the loops don't nest.

Is generate block synthesizable in Verilog?

Yes. It is possible. A generate statement is just a code generator directive to the synthesizer. Basically, it is just loop unrolling.


1 Answers

You need to reverse the nesting inside the generate block:

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

Technically, this generates four always blocks:

always @(posedge sysclk) temp[0] <= 1'b0; always @(posedge sysclk) temp[1] <= 1'b0; always @(posedge sysclk) temp[2] <= 1'b0; always @(posedge sysclk) temp[3] <= 1'b0; 

In this simple example, there's no difference in behavior between the four always blocks and a single always block containing four assignments, but in other cases there could be.

The genvar-dependent operation needs to be resolved when constructing the in-memory representation of the design (in the case of a simulator) or when mapping to logic gates (in the case of a synthesis tool). The always @posedge doesn't have meaning until the design is operating.

Subject to certain restrictions, you can put a for loop inside the always block, even for synthesizable code. For synthesis, the loop will be unrolled. However, in that case, the for loop needs to work with a reg, integer, or similar. It can't use a genvar, because having the for loop inside the always block describes an operation that occurs at each edge of the clock, not an operation that can be expanded statically during elaboration of the design.

like image 90
Andy Avatar answered Oct 20 '22 05:10

Andy