无符号数的溢出/下溢

Ris*_*huu 3 unsigned numbers mips overflow underflow

因此,如果你在无符号数字上加上1,你就会溢出,如果你有一个带有减法的0,你就已经下溢了.这种情况在每种情况下都适用吗?

如果你做5-0:0101 -0000

= 0101 +(1111 + 1)

= 0101 +0000

= 0101 ...这里有一个零,而不是1.如何解释这个案例?有不同的方法吗?

(使用MIPS架构或其他任何东西)

- -编辑

谢谢Amadan.不过,我理解这一部分.我的问题只是零似乎是一个特例.它似乎不遵循正常数字所做的:在上面的例子中,没有执行1.

我正在进行电路设计,目前正在与ALU一起工作并试图实现溢出检测,当这一个案例出现时并不遵循其他人的做法.

我们假设通过减法,第二个操作数在进入ALU(然后添加到第一个操作数)之前被预转换(二进制补码).因此,每当减法的"invert_b"被设置为1时,b被反转并且我们假设我们正在检查的情况是减法,其应该具有1的进位.

old*_*mer 5

我相信msbit在它自己的位上执行无符号覆盖,对于签名,你看看是否进入msbit和进位不同.

5-0不会溢出,因为结果符合可用的位数.与15-1不会溢出4位系统的有符号数字的方式相同

5 - 0 = 0101 + 1111 + 1

    1
 0101
+1111
=====

11111
 0101
+1111
=====
 0101
Run Code Online (Sandbox Code Playgroud)

所以5 - 0肯定会执行1,因为这是一个不是溢出的减法

进位设置为15 - 1 = 1111 + ~1

    1
 1111
 1110
 ====

11111
 1111
 1110
 ====
 1110
Run Code Online (Sandbox Code Playgroud)

如你所说,减去1 out并不是无符号溢出

同样-1 - 1 = 1111 + ~1,进位位置位

11111
 1111
 1110
 ====
 1110
Run Code Online (Sandbox Code Playgroud)

进位到最后一位是1,进位是1匹配,没有符号溢出.

8 + 8 = 1000 + 1000,进位清晰

    0
 1000
+1000
=====

10000
 1000
+1000
=====
 0000
Run Code Online (Sandbox Code Playgroud)

无符号溢出.

嗯4 + 4

    0
 0100
+0100
=====

01000
 0100
+0100
=====
 1000
Run Code Online (Sandbox Code Playgroud)

unsigned add执行是0这不是无符号溢出.但这是一个带符号的溢出,因为进入msbit并执行不同.+4 + +4 = +8,在4位有符号系统中,您不能代表+8,因此有符号溢出是准确的.

无论多少位,奇怪的数字都是0和1,其余为零,0和8或-8用于4位系统.

使用2位,3位或4位数字组成一个图表,并手动查看所有组合,看看它们是否有意义.无论你找到什么,无论多少位宽,都会缩放,100位加法器的工作方式就像一个10位加法器......

add           C V  unsigned    signed
00 + 00 = 000 0 0  0 + 0 = 0   0 +  0 =  0
00 + 01 = 001 0 0  0 + 1 = 1   0 +  1 =  1
00 + 10 = 010 0 0  0 + 2 = 2   0 + -2 = -2
00 + 11 = 011 0 0  0 + 3 = 3   0 + -1 = -1
01 + 00 = 001 0 0  1 + 0 = 1   1 +  0 =  1
01 + 01 = 010 0 1  1 + 1 = 2   1 +  1 =  2  signed cannot represent a +2
01 + 10 = 011 0 0  1 + 2 = 3   1 + -2 = -1
01 + 11 = 100 1 0  1 + 3 = 4   1 + -1 =  0  unsigned cannot represent +4
10 + 00 = 010 0 0  2 + 0 = 2  -2 +  0 = -2 
10 + 01 = 011 0 0  2 + 1 = 3  -2 +  1 = -1
10 + 10 = 100 1 1  2 + 2 = 4  -2 + -2 = -4 neither +4 nor -4 will fit in 2 bits
10 + 11 = 101 1 1  2 + 3 = 5  -2 + -1 = -3 neither +4 nor -3 will fit in 2 bits
11 + 00 = 011 0 0  3 + 0 = 3  -1 +  0 = -1 
11 + 01 = 100 1 0  3 + 1 = 4  -1 +  1 = -2 +4 does not fit in 2 bits
11 + 10 = 101 1 1  3 + 2 = 5  -1 + -2 = -3 neither +5 nor -3 fit in 2 bits
11 + 11 = 110 1 0  3 + 3 = 6  -1 + -1 = -2 6 does not fit in 2 bits
sub
00 - 00 = 100 0 0
00 - 01 = 011 1 0  0 - 1 = -1   -1 does not fit in an unsigned result
00 - 10 = 010 1 1  0 - 2 = -2  0 - -2 = +2  
00 - 11 = 001 1 0  0 - 3 = -3
01 - 00 = 101 0 0
01 - 01 = 100 0 0
01 - 10 = 011 1 1  1 - 2 = -1  1 - -2 =  3
01 - 11 = 010 1 1  1 - 3 = -2  1 - -1 =  2
10 - 00 = 110 0 0  
10 - 01 = 101 0 1             -2 -  1 = -3
10 - 10 = 100 0 0
10 - 11 = 011 1 0  2 - 3 = -1
11 - 00 = 111 0 0
11 - 01 = 110 0 0
11 - 10 = 101 0 0
11 - 11 = 100 0 0
Run Code Online (Sandbox Code Playgroud)

生成上述代码

printf("add\n");
for(ra=0;ra<4;ra++)
{
    for(rb=0;rb<4;rb++)
    {
        rd=(ra&1)+(rb&1);
        rc=ra+rb;
        rd=(rd>>1)&1;
        re=(rc>>2)&1;
        if(re) c=1; else c=0;
        if(rd!=re) v=1; else v=0;

        if(ra&2) printf("1"); else printf("0");
        if(ra&1) printf("1"); else printf("0");
        printf(" + ");
        if(rb&2) printf("1"); else printf("0");
        if(rb&1) printf("1"); else printf("0");
        printf(" = ");
        if(rc&4) printf("1"); else printf("0");
        if(rc&2) printf("1"); else printf("0");
        if(rc&1) printf("1"); else printf("0");
        printf(" %u %u\n",c,v);
    }
}
printf("sub\n");
for(ra=0;ra<4;ra++)
{
    for(rb=0;rb<4;rb++)
    {
        rd=(ra&1)+((~rb)&1)+1;
        rc=ra+((~rb)&3)+1;
        rd=(rd>>1)&1;
        re=(rc>>2)&1;
        if(re) c=0; else c=1;
        if(rd!=re) v=1; else v=0;

        if(ra&2) printf("1"); else printf("0");
        if(ra&1) printf("1"); else printf("0");
        printf(" - ");
        if(rb&2) printf("1"); else printf("0");
        if(rb&1) printf("1"); else printf("0");
        printf(" = ");
        if(rc&4) printf("1"); else printf("0");
        if(rc&2) printf("1"); else printf("0");
        if(rc&1) printf("1"); else printf("0");
        printf(" %u %u\n",c,v);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你的问题是谈论无符号数字是吗?所以你可能不关心V位,也不关心右半边,签名的一半.

这是我实现的小型16位处理器的一些HDL/RTL:

case 4b0000:
{
    //0000 add rd,rs
    op_a = bundle(1b0,reg[bundle(2b0,inst[4;8])].value);
    op_b = bundle(1b0,reg[bundle(2b0,inst[4;4])].value);
    op_res = op_a + op_b;
    reg[1].value[CBIT] <= op_res[16];
    reg[1].value[NBIT] <= op_res[15];

    if(op_res[16;0] == 16h0000)
    {
        reg[1].value[ZBIT] <= 1b1;
    }
    else
    {
        reg[1].value[ZBIT] <= 1b0;
    }
    if((op_a[15] == op_b[15]) && (op_res[15] != op_b[15] ) )
    {
        reg[1].value[VBIT] <= 1b1;
    }
    else
    {
            reg[1].value[VBIT] <= 1b0;
    }
    reg[bundle(2b0,inst[4;8])].value <= op_res[16;0];
}
case 4b0001:
{
    //0001 sub rd,rs
    op_a = bundle(1b0,reg[bundle(2b0,inst[4;8])].value);
    op_b = bundle(1b0,reg[bundle(2b0,inst[4;4])].value);
    op_res = op_a - op_b;
    reg[1].value[CBIT] <= (~op_res[16]);
    reg[1].value[NBIT] <= op_res[15];

    if(op_res[16;0] == 16h0000)
    {
        reg[1].value[ZBIT] <= 1b1;
    }
    else
    {
        reg[1].value[ZBIT] <= 1b0;
    }
    if((op_a[15] != op_b[15]) && (op_res[15] == op_b[15] ) )
    {
        reg[1].value[VBIT] <= 1b1;
    }
    else
    {
        reg[1].value[VBIT] <= 1b0;
    }
    reg[bundle(2b0,inst[4;8])].value <= op_res[16;0];
}
Run Code Online (Sandbox Code Playgroud)

在其他逻辑中我已经/已经看过msbit事件的签名溢出,并且在头对头分析中尝试每种可能的组合时,无法找到它与进位vs执行方法不匹配的情况.

如果我对答案过度了,我不介意在开头剪掉它,它表明5 - 0有一个1作为1的进位,这对于减法不是溢出.答案很长,因为很难将你的头围绕着签名与无符号以及加法器如何在逻辑中起作用.加法器不知道或不关心符号或无符号,它不关心加VS减法,以减您反转第二个操作数,反转中,所以LSb进和运出最高位的(想想大约添加,添加具有携带,sub和sub with carry).签名vs unsigned照顾自己(两个补充的美).将上述内容简化为无符号唯一的讨论使得它变得超过一半,因为有符号溢出对于不经意的观察者来说并不明显(作为无符号溢出).

我真的希望我剪切和粘贴的调试HDL,会得到很多的回应/修正,如果我没有......我花了几天说服自己上述所有的和比较其他处理器我公司已获得的结果,希望这可以节省你几天.