当我尝试写入a [b + 1]时,其中b的所有位均为'1'时,reg a [0]的值不会更新,但是当我尝试a [b + 1'b1]时,它会更新更新
awaddr_wa <= awaddr_wa + 2; awaddr[awaddr_wa] <= AWADDR_M; awlen [awaddr_wa] <= 4'd0; awaddr[awaddr_wa+6'd1] <= AWADDR_M+16; awlen [awaddr_wa+6'd1] <= 4'd0
所以为什么?
这是一个可重现的示例:
module M; integer a[0:7] = {0,1,2,3,4,5,6,7}; reg [2:0] b = -1; initial begin $display("a[b+1]=", a[b+1]); $display("a[b+1'b1]=", b+1'b1); end endmodule
https://www.edaplayground.com/x/26Za
(如果包含此内容,您的问题会更好)
您将看到输出类似于:
a[b+1]= x a[b+1'b1]=0
1
是32位宽。(Verilog中的所有无基础文字都是32位宽。)
在Verilog中混合这样的位宽时,Verilog必须决定要使用多少位。
当您在Verilog中对数组进行索引超出范围时,这不会像在C中那样造成灾难。而是返回数组类型的默认值。a
是的数组integer
,其默认值为32'bx
。
使用a[b+1]
,Verilog将采用3位(b
)和32位(1
)中的较大者,即32位。所以,用b=3'b111
,1
被添加到b
使用32位运算。在32位算术中,7 + 1为8,因此a[b+1]
与a[8]
超出范围的相同,因此32'bx
。
使用a[b+1'b1]
,Verilog将采用3位(b
)和1位(1'b1
)中的较大者,即3位。因此,带有b=3'b111
,1'b1
被添加到b
使用3位算法。在3位算术,7 + 1为0,所以a[b+1'b1]
是相同的a[0]
,其是不超出范围,是32'b0
在我的例子。
这是Verilog中的经典陷阱。这是Verilog 自定义表达式的一个示例。自定义表达式是一种表达式,其中用于计算的位数仅取决于操作数的宽度。还有上下文确定的表达式(例如F = A + B
),其中位数还取决于分配给变量的宽度(或净值)。