verilog 有符号加法和减法
verilog signed addition and subtraction
我无法理解在 verilog 中加减有符号数时如何处理溢出。
当我用无符号数这样做时,它非常简单:
input [15:0] A;
input [15:0] B;
input [3:0] S;
output reg [15:0] AddAB;
...
always@(*)
begin
{OFAdd, AddAB} <= A + B;
{OFSub, SubAB} <= A - B;
...
case(S)
0:
begin
Display <= AddAB;
DisplayOF <= OFAdd;
end
1:
begin
Display <= SubAB;
DisplayOF <= OFSub;
end
...
我会得到正确的输出。
但是对带符号的输入做同样的事情,我得到了错误的溢出值
input signed [15:0] A;
input signed [15:0] B;
input [3:0] S;
output reg signed [15:0] AddAB;
...
always@(*)
begin
{OFAdd, AddAB} <= A + B;
{OFSub, SubAB} <= A - B;
...
case(S)
0:
begin
Display <= AddAB;
DisplayOF <= OFAdd;
end
1:
begin
Display <= SubAB;
DisplayOF <= OFSub;
end
...
例如,如果 A =-21846 和 B = 88,我得到正确的值 AddAB = -21758,但我得到 DisplayOF = 1。减法也会发生同样的情况。我得到了正确的 SubAB 值,但在我不应该的时候却在 DisplayOF 上得到了溢出。
如果有什么不同的话,我的测试平台基本上是这样的
A = 16'sb1010101010101010;
B = 16'sd88;
S = 4'd0;
#10;
A = 16'sb1010101010101010;
B = 16'sd88;
S = 4'd1;
#10;
我不关心可综合性,我只是想弄清楚如何处理带符号值的一元算术溢出。
如果有人能指出正确的方向,我将不胜感激,谢谢!
{OFAdd, AddAB} <= A + B;
在示例中,MSB (OFAdd
) 不是溢出位。如果您有权访问加法器最后一位的进位,这可能会导致溢出,但在 RTL 中您无法访问这唯一的另一个全加器位。
A more detailed previous answer,展示了如何使用两个MSB来检测上溢和下溢。
一个基本的 overflow/underflow 限制器:
AddAB = A + B;
case (AddAB[MSB:MSB-1])
2’b01 : add = MAX_POS;//Overflow
2’b10 : add = MAX_NEG;//Underflow
default: add = AddAB[MSB-1:0]; //In Range
endcase
如果两个输入具有相同的符号而结果具有相反的符号,则您已签名溢出。看
https://electronics.stackexchange.com/questions/476250/signed-overflow-detection/476254#476254
我无法理解在 verilog 中加减有符号数时如何处理溢出。
当我用无符号数这样做时,它非常简单:
input [15:0] A;
input [15:0] B;
input [3:0] S;
output reg [15:0] AddAB;
...
always@(*)
begin
{OFAdd, AddAB} <= A + B;
{OFSub, SubAB} <= A - B;
...
case(S)
0:
begin
Display <= AddAB;
DisplayOF <= OFAdd;
end
1:
begin
Display <= SubAB;
DisplayOF <= OFSub;
end
...
我会得到正确的输出。 但是对带符号的输入做同样的事情,我得到了错误的溢出值
input signed [15:0] A;
input signed [15:0] B;
input [3:0] S;
output reg signed [15:0] AddAB;
...
always@(*)
begin
{OFAdd, AddAB} <= A + B;
{OFSub, SubAB} <= A - B;
...
case(S)
0:
begin
Display <= AddAB;
DisplayOF <= OFAdd;
end
1:
begin
Display <= SubAB;
DisplayOF <= OFSub;
end
...
例如,如果 A =-21846 和 B = 88,我得到正确的值 AddAB = -21758,但我得到 DisplayOF = 1。减法也会发生同样的情况。我得到了正确的 SubAB 值,但在我不应该的时候却在 DisplayOF 上得到了溢出。
如果有什么不同的话,我的测试平台基本上是这样的
A = 16'sb1010101010101010;
B = 16'sd88;
S = 4'd0;
#10;
A = 16'sb1010101010101010;
B = 16'sd88;
S = 4'd1;
#10;
我不关心可综合性,我只是想弄清楚如何处理带符号值的一元算术溢出。
如果有人能指出正确的方向,我将不胜感激,谢谢!
{OFAdd, AddAB} <= A + B;
在示例中,MSB (OFAdd
) 不是溢出位。如果您有权访问加法器最后一位的进位,这可能会导致溢出,但在 RTL 中您无法访问这唯一的另一个全加器位。
A more detailed previous answer,展示了如何使用两个MSB来检测上溢和下溢。
一个基本的 overflow/underflow 限制器:
AddAB = A + B;
case (AddAB[MSB:MSB-1])
2’b01 : add = MAX_POS;//Overflow
2’b10 : add = MAX_NEG;//Underflow
default: add = AddAB[MSB-1:0]; //In Range
endcase
如果两个输入具有相同的符号而结果具有相反的符号,则您已签名溢出。看 https://electronics.stackexchange.com/questions/476250/signed-overflow-detection/476254#476254