I have an array of registers/buses and a single result bus defined as follows.
wire [BW-1:0] bus_array[NUM-1:0];
reg [BW-1:0] and_result;
where
parameter BW = 4;
parameter NUM = 8;
I wish to perform a BW-bit AND operation on the elements of the array and assign the result to the register and_result
.
I try doing this as follows.
integer l;
generate
genvar m;
for (m=0; m<BW; m=m+1)
begin : BW_LOOP
always @ (*)
begin
and_result[m] = 1'b1;
for (l=0; l<NUM; l=l+1)
and_result[m] = and_result[m] & bus_array[l][m];
end
end
endgenerate
However when I simulate this in Modelsim 10.1e, I get the following error.
Error: (vsim-3601) Iteration limit reached at time 2 ns
If I do not use the generate loop, and instead have BW instances of the always @ (*)
block, the simulation works okay.
I can infer from the error message, that there is a problem with the generate for loop, but I am not able to resolve the problem.
Most likely a bug with ModelSim. Reproducible on EDAplayground with ModelSim10.1d. Works fine with Riviera2014 (After localizing
l
inside the generate loop). I'm guessing thatand_result[m]
is somehow in the@(*)
sensitivity list, which it shouldn't be.l
needs to be localized or it will be accessed in parallel with the generated always blocks; creating a potential raise condition.One workaround is to use SystemVerilog and use
always_comb
instead ofalways @(*)
.A backwarnd compatable solution is to change
and_result[m] = and_result[m] & bus_array[l][m];
toif (bus_array[l][m]==1'b0) and_result[m] = 1'b0;
which is equivalent code. This keepsand_result[m]
only on as a left hand expression so it cannot be in the sensitivity list.Working code here