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

时间:2014-07-05 13:19:37

标签: verilog

初学者。我试图在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 <= 1'b1;
else if((a_in < 0) && (b_in > 0) && (res_out >= 0)) o <= 1'b1;
else o <= 1'b0;

控制矩阵负责a_in和b_in的保持时间,以便溢出检测可以完成,因为只有在计算结果后才会完成(在下一个时钟周期)。

我做了一些环顾四周,我发现所有人都在检测其他语言的溢出,例如C或C ++。我正在寻找有符号乘法中检测溢出的示例实现。

两个输入a_in和b_in均为带符号线,宽度为16位。结果寄存器res_out是有符号的,也是16位宽。理想情况下,我有一个33位宽的结果寄存器,无论如何都不会发生溢出,但这不是一个选项。

帮助表示赞赏。任何更好的方法来检测加法和减法中的溢出也是受欢迎的。

3 个答案:

答案 0 :(得分:7)

另外,在检测溢出和下溢时,分析一个简单的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

现在导致下溢:结果应该是-9但不能用4位表示。

  -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位乘法器和额外逻辑来检测溢出条件。

答案 1 :(得分:0)

例如,如果添加7和-3,则会失败。

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

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

答案 2 :(得分:0)

只想对上面的@Morgan's答案提供一个解释。

首先,应注意,在Two的补码表示形式中,无论您有多少个前导零(正数或负数的前导零),其值都相同。也就是说:111011110相同,都为-2。

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

  +7 : [0]0111
  +1 : [0]0001 
  +8 : [0]1000

我们可以看到我们采用了结果的进位/有符号位,该值以二进制补码形式(01000+8)是正确的。但是,由于结果线只能容纳4位,因此从硬件角度来看,该值仅为1000,即2的补码为-8。

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