在Verilog中按位'和'一组寄存器

时间:2014-11-25 00:22:59

标签: bit-manipulation verilog bitwise-operators bitwise-and

我有一个寄存器/总线阵列和一个结果总线定义如下。

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循环存在问题,但我无法解决问题。

1 个答案:

答案 0 :(得分:1)

很可能是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