Verilog中的有符号乘法溢出检测

Verilog中的有符号乘法溢出检测,verilog,Verilog,我是初学者。我正在尝试用Verilog编写一个简单的16位微处理器,并在Spartan 6上实现它。ALU实现所有有符号操作(完全没有无符号操作)。所有输入均为导线,并有符号。结果存储在签名寄存器中 我的问题是找到一种检测溢出的合理方法。目前检测到溢出的速度并不重要,因为它所做的只是触发故障并停止系统 我相信我已经找到了在加减法中检测溢出的方法,但我还是希望得到保证 这里还有一个补充,其中o是溢出标志寄存器: if((a_in >= 0) && (b_in >= 0)

我是初学者。我正在尝试用Verilog编写一个简单的16位微处理器,并在Spartan 6上实现它。ALU实现所有有符号操作(完全没有无符号操作)。所有输入均为导线,并有符号。结果存储在签名寄存器中

我的问题是找到一种检测溢出的合理方法。目前检测到溢出的速度并不重要,因为它所做的只是触发故障并停止系统

我相信我已经找到了在加减法中检测溢出的方法,但我还是希望得到保证

这里还有一个补充,其中o是溢出标志寄存器:

if((a_in >= 0) && (b_in >= 0) && (res_out < 0)) o <= 1'b1;
else if((a_in < 0) && (b_in < 0) && (res_out >= 0)) o <= 1'b1;
else o <= 1'b0;

if((a_in>=0)和&(b_in>=0)和&(res_out<0))o=0)和&(b_in<0)和&(res_out<0))o另外,分析一个简单的4位示例,符号扩展到5位

加法全部+ve

  3 : [0]0011
+ 3 : [0]0011
= 6 : [0]0110
带负数

  -3 : [1]1101 
+ -3 : [1]1101
= -6 : [1]1010
现在导致溢出:结果应该是+8,但不能用4位表示

  +7 : [0]0111
  +1 : [0]0001 
  +8 : [0]1000
  -8 : [1]1000
+ -1 : [1]1111
  -9 : [1]0111 
现在导致下溢:结果应该是-9,但不能用4位表示

  +7 : [0]0111
  +1 : [0]0001 
  +8 : [0]1000
  -8 : [1]1000
+ -1 : [1]1111
  -9 : [1]0111 
因此,如果我们将输入符号扩展1位,则很容易检测溢出和下溢

localparam WIDTH = 4;
localparam MSB   = WIDTH-1;
logic [WIDTH-1:0] a;
logic [WIDTH-1:0] b;
logic [WIDTH-1:0] result;
logic extra;
logic overflow;
logic underflow;


always @* begin
  {extra, result} = {a[MSB], a} + {b[MSB], b} ;
  overflow  = ({extra, result[MSB]} == 2’b01 );
  underflow = ({extra, result[MSB]} == 2’b10 );
end
关于乘法,我不明白为什么不能有32位寄存器。即使您将最终输出减少到16

执行位缩减时,您需要检查该值是否低于最大值,并高于缩减宽度可支持的最小负数

注:此外,结果比最大输入增长1位。截断回原始宽度时发生溢出/下溢

乘法的结果是两者相加的宽度,16位*16位的结果是32位的答案。很确定你不需要33位。如果不保留全宽度,则很难判断截断时结果是否会溢出。这是很常见的设计这些东西与广泛的组合结果,只有输出这么多位通过触发器为最终输出的ALU


我认为,保持32位输出并将其与有符号16位数字的最大/最小值进行比较,将比仅使用16位乘法器和额外逻辑来检测溢出情况的综合值小。

例如,如果添加7和-3,这将失败

  7 : [0]0111
- 3 : [1]1101
= 4 : [1]0100

结果将显示这是下溢,但这不是下溢,而是+4。

只是想对上述答案进行解释

首先,应该注意的是,在2的补码表示法中,无论正数有多少前导零,负数有多少前导零,值都是相同的。也就是说:
1110
11110
相同,都是-2

现在,考虑第一个溢出例子:

  +7 : [0]0111
  +1 : [0]0001 
  +8 : [0]1000
我们可以看到,如果我们取结果的进位/有符号位,则值以二的补码形式是正确的(
01000
is
+8
)。但是,由于结果线只能容纳4位,因此从硬件角度来看,该值仅为
1000
,在2的补码中为-8


因此,如果我们对结果二进制数的进位和MSB进行异或运算,我们可以确定硬件识别的值是否与预期值相同,或者确定是否发生了溢出。

这是一个非常优雅的解决方案。非常感谢。我知道我可以使用一个33位的结果寄存器进行乘法,但如果不是这样做,效率会更高。但是我可能会使用一个更大的结果寄存器,它不会改变当前的实现。@shryasvinod我已经添加了另一段来尝试并扩展它。如果不使用全宽结果,就无法很好地检测乘法器溢出。我不确定这一点,但我认为您需要额外的一位来保持符号。我看差不多。16位x 16位将是32d的4294967296。符号还需要一位。你是对的,因为斯巴达6中的18x18乘法器比我想要的16x16乘法器大。+7(00111)+(-3)(11101)是+4(00100)。你似乎已经尝试过减法了,而你已经在用2的补码了。如果你想减法,请理解你会做(+7)-(+3)而不是(+7)-(-3)。即00111-00011=00100。