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.