Reputation: 21
I have the following verilog code within a genvar, although the variable 'j' is not a genvar variable. When I check the syntax (using Xilinx) I receive the error "Illegal condition expression in generate if statement" on the line with the 'if' statement. Changing 'j' to a genvar variable doesn't fix the issue, how can I make read 'j' properly? Thanks for any help.
genvar i;
generate
integer j=0;
for(i=0; (i<10); i=i+1) begin: gen_columns
if (j==0) begin
//some code
end
assign j=j+1;
end
endgenerate
Upvotes: 0
Views: 20175
Reputation: 3820
From your code snippet above, I could not figure out what type of hardware you are trying to model.
For-loops: In Verilog for-loops are used primarily for
- iterating over a set of bits for an operation (XORing, demux, et cetera)
- creating multiple instances of a structure using generate statements
Straight from the Verilog LRM for generate-loops:
A generate-loop permits one or more variable declarations, modules, user defined primitives, gate primitives, continuous assignments, initial blocks and always blocks to be instantiated multiple times using a for-loop. The index loop variable used in a generate for-loop
shall be declared as a genvar. Both genvar assignments in the for-loop shall assign to the same genvar, which is the loop index variable. The first genvar assignment in the for-loop shall not reference the loop index variable on the right-hand side.
In your code, what is the purpose of j? In Verilog it is bad form to assign a variable and then use it as control logic in the same procedural block. Most likely you need another procedural block for j outside of the generate-loop. I don't know the purpose of j in your code, but perhaps something like the following?
// continuously increment counter each clock cycle
// asynchronous reset capability
integer j;
always @(posedge clock, posedge reset)
if (reset) j <= 0;
else j <= j + 1;
Upvotes: 1
Reputation: 4866
The generate block needs to be resolved to standard verilog module items when the design is elaborated (before simulation starts). In your example, the tool is trying to evaluate if (j==0)
as a constant, and can't do it.
It's not clear from your example what you're trying to do. Here are a couple examples that work for me:
wire [9:0] w;
genvar i;
generate
for(i=0; (i<10); i=i+1) begin: gen_columns
if (i==0) begin
assign w[i] = 1'b0;
end else begin
assign w[i] = 1'b1;
end
end
endgenerate
initial begin
$display ("%x", w);
$finish;
end
This code iterates over the bits of a bus and assigns a different value depending on the bit. The output is 3fe
.
reg clk;
integer j [0:1];
genvar i;
generate
for(i=0; (i<2); i=i+1) begin: gen_columns
always @(posedge clk) begin
if (j[i]==0) begin
j[i] <= j[i] + 1;
end
end
end
endgenerate
initial clk = 1'b0;
always #1 clk = ~clk;
initial begin
$monitor ("%d: j[0]: %d, j[1]: %d", $time, j[0], j[1]);
repeat (2) @(posedge clk);
j[0] = 0;
j[1] = 0;
repeat (2) @(posedge clk);
$finish;
end
This code creates identical logic for j[0]
and j[1]
to increment them if they are zero. The output is:
0: j[0]: x, j[1]: x
3: j[0]: 0, j[1]: 0
5: j[0]: 1, j[1]: 1
The difference between my second case and your example is that the if statement and assignment are placed within an always block. When the design is elaborated, the tool will replace the generate block with two always blocks, one with i=0
and one with i=1
.
A style note: although it is legal verilog to update a variable from multiple always blocks, it is not considered good practice. It will likely synthesize as a multiply-driven signal and may introduce race conditions in simulation. In my second example, if the assignment were j = j + 1
(without [i]
), then j
would be assigned in multiple always blocks.
Upvotes: 1