出于某种原因,我一直无法找到任何确定的资源或stackoverflow问题来回答这个问题:
verilog在乘以有符号数时是否会处理输入和输出维数?
具体而言,如果我将带符号的32位与带符号的64位数相乘,会发生什么?如果我有:
reg signed [31:0] a = -5;
reg signed [63:0] b = 5;
wire signed [63:0] c;
assign c = a*b;
c是否等于-25(在64位2的补码方案中)?
如果我将c声明为32位数怎么办?它仍然是-25(在32位2的补码方案中)?
谢谢!
答案 0 :(得分:6)
i)Verilog中的乘法运算符导致所谓的上下文确定的表达式。在自定义表达式中用于算术的宽度取决于操作数的宽度和结果。与
assign c = a*b;
用于乘法的宽度将是a
,b
和c
中最宽的。在您的情况下,b
是最宽的64位,因此将使用64位算术进行乘法。
然后,您将结果分配给32位宽wire
- c
。因此,64位结果将被截断为32位; MSB将丢失,这可能会导致奇怪的结果,例如:
reg signed [3:0] a = 3;
reg signed [7:0] b = 63;
wire signed [3:0] c;
assign c = a*b;
http://www.edaplayground.com/x/f3b
为c
提供-3
的值,因为虽然使用8位(最宽a
,b
和c
)进行了多次转换,使用了带符号算术(因为a
和b
都已签名),结果为189,当截断为4位有符号数时为-3。
因此,您可以根据预期的操作数范围使用合适的宽度。
ii)在Verilog中,如果混合无符号和有符号操作数,则将使用无符号算术。因此,在您的情况下,由于两个操作数都已签名,因此将使用带符号的算术。 (结果是未签名还是签名无关紧要。)