我有一个寄存器/总线阵列和一个结果总线定义如下。
wire [BW-1:0] bus_array[NUM-1:0];
reg [BW-1:0] and_result;
哪里
parameter BW = 4;
parameter NUM = 8;
我希望对数组的元素执行BW位AND操作,并将结果分配给寄存器and_result
。
我尝试这样做如下。
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
但是当我在Modelsim 10.1e中模拟这个时,我得到以下错误。
错误:(vsim-3601)在2 ns时达到迭代限制
如果我不使用生成循环,而是使用always @ (*)
块的BW实例,则模拟可以正常工作。
我可以从错误消息中推断出generate for循环存在问题,但我无法解决问题。
很可能是ModelSim的一个错误。使用ModelSim10.1d可在EDAplayground上重现。与Riviera2014一起工作正常(在生成循环中本地化l
之后)。我猜测and_result[m]
在@(*)
灵敏度列表中不知何故,它不应该。
l
需要本地化,或者与生成的always块并行访问;创造潜在的加薪条件。
一种解决方法是使用SystemVerilog并使用always_comb
而不是always @(*)
。
后向兼容的解决方案是将and_result[m] = and_result[m] & bus_array[l][m];
更改为if (bus_array[l][m]==1'b0) and_result[m] = 1'b0;
,这是等效的代码。这使and_result[m]
仅作为左手表达,因此它不能在敏感列表中。
genvar m;
for (m=0; m<BW; m=m+1)
begin : BW_LOOP
integer l; // <== 'l' is local to this generate loop
always @ (*)
begin
and_result[m] = 1'b1;
for (l=0; l<NUM; l=l+1) begin
if (bus_array[l][m]==1'b0) begin
and_result[m] = 1'b0;
end
end
end
工作代码here