为何Verilog中$signed系统任务在乘加运算中未按预期工作?
Verilog中$signed()运算结果不符合预期的原因分析
问题代码及现象
module main; reg [5:0] result; reg [3:0] a = -1; reg [3:0] b = 3; initial begin result = 0; result = result + $signed(a)*$signed(b); $display("%d", result); end endmodule
运行结果为45,而非预期的61;将result改为reg signed [5:0] result;后,结果变为-3。
原因拆解
1. 变量赋值与$signed()的作用
reg [3:0] a = -1;:因为a是无符号4位寄存器,-1会被转换为无符号的4'b1111(十进制15)。$signed(a)将其视为4位有符号数,即-1(4'b1111作为有符号补码对应-1)。reg [3:0] b = 3;:$signed(b)将无符号的4'b0011转换为有符号数3。
2. 乘法运算的结果
两个4位有符号数相乘,Verilog会自动将结果扩展为8位有符号数:-1 * 3 = -3,对应二进制8'b11111101。
3. 加法运算与位数处理(无符号result场景)
result是6位无符号寄存器,初始值0(6'b000000)。进行加法时,需将其零扩展为8位无符号数:8'b00000000。- 当无符号数与有符号数进行加法运算时,Verilog会按无符号运算处理,因此:
8'b00000000 + 8'b11111101 = 8'b11111101(十进制253)。 - 赋值给6位
result时,会截断为低6位:6'b111101,对应无符号十进制45,这就是最终显示的结果。
4. 有符号result场景的差异
- 当
result改为reg signed [5:0]时,初始值0会被符号扩展为8位有符号数8'b00000000。 - 两个有符号数相加:
0 + (-3) = -3(8'b11111101)。 - 赋值给6位有符号寄存器时,截断为低6位6'b111101,作为有符号补码对应-3,
$display("%d")按有符号数输出,因此显示-3。
内容的提问来源于stack exchange,提问作者Tokubara
相关产品推荐
相关产品推荐

