Verilog定点转换结果异常:regA与regB值不同的原因排查
Verilog定点转换中regA与regB结果差异的原因
问题代码
reg signed [31:0] regA; reg signed [31:0] regB; reg signed [15:0] regC; reg signed [15:0] regD; initial begin regA = 0.006 * 2**31; regB = 0.006 * (32'b1 << 31); regC = 0.006 * 2**15; regD = 0.006 * (16'b1 << 15); $display("regA = 0x%b, %d", regA, regA); $display("regB = 0x%b, %d", regB, regB); $display("regC = 0x%b, %d", regC, regC); $display("regD = 0x%b, %d", regD, regD); end
运行结果
regA = 0x11111111001110110110010001011010, -12884902 regB = 0x00000000110001001001101110100110, 12884902 regC = 0x0000000011000101, 197 regD = 0x0000000011000101, 197
差异原因分析
1. 2**31的有符号整数溢出
Verilog中整数常量表达式默认以32位有符号整数计算:
2**31的数学值为2147483648,但32位有符号整数的最大值仅为2^31-1=2147483647,触发有符号整数溢出后,结果变为32位有符号数的最小负值**-2147483648**。- 该负数乘以0.006得到实数
-12884901.888,赋值给regA时取整为-12884902,对应运行结果中的负数输出。
2. 32'b1 << 31的无符号位向量运算
32'b1是无符号位向量常量,左移31位后得到32'b10000000000000000000000000000000:
- 该值作为无符号数的数值为2147483648,参与实数运算时会被转换为实数
2147483648.0,不存在溢出问题。 - 乘以0.006得到实数
12884901.888,赋值给regB时取整为12884902,即正数结果。
3. 16位寄存器无差异的原因
2**15的数学值为32768,远小于32位有符号整数的最大值,运算无溢出,结果为正数32768;16'b1 <<15作为无符号位向量左移后的值同样为32768。两者乘以0.006后均得到196.608,取整后为197,因此regC和regD结果一致。
内容的提问来源于stack exchange,提问作者Šatov
相关产品推荐
相关产品推荐

