Ash
Ash

Reputation: 21

Verilog 'if' statement using variable

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

Answers (2)

Dr. Watson
Dr. Watson

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

Andy
Andy

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

Related Questions