所以,如果你对无符号数字的加法进位为1,你就溢出了,如果你的减法进位为0,你就下溢了。然而,这在所有情况下都有效吗?
如果你做5-0: 0101 -0000
= 0101 +(1111 + 1)
= 0101 +0000
= 0101...这里有一个0的进位,而不是1。如何解释这种情况?有没有不同的方法呢?
(使用MIPS架构或其他任何东西)
-编辑
谢谢阿玛丹。不过,我理解这一点。我的问题是,零似乎是一个特例。它似乎不遵循正常数字的作用:在我上面的例子中,没有进位1。
我正在做电路设计,目前正在与ALU合作,并试图实现溢出检测,当这个案例出现时,并没有遵循其他案例的做法。
我们假设使用减法时,第二个操作数在进入算术逻辑单元(然后与第一个操作数相加)之前被预反转(二进制补码)。因此,只要减法的"invert_b“被设置为1,b就被反转,我们假设我们检查的情况是减法,它的进位应该是1。
发布于 2011-10-22 10:51:51
我相信msbit进位在它自己的封面上是无符号的,对于有符号的,你可以看看msbit的进位和进位是否不同。
5-0不会溢出,因为结果适合可用的位数。同样的方式,15-1不会使有符号数的4位系统溢出
5-0= 0101 + 1111 +1
1
0101
+1111
=====
11111
0101
+1111
=====
0101因此,5-0肯定会执行1,因为这是一个不溢出的减法
15 -1= 1111 + ~1,进位设置
1
1111
1110
====
11111
1111
1110
====
1110带1输出的减法不是您所说的无符号溢出
同样-1 -1= 1111 + ~1,进位设置
11111
1111
1110
====
1110进位到最后一位的进位是1,进位输出是他们匹配的1,没有带符号的溢出。
8+8= 1000 + 1000,进位清除
0
1000
+1000
=====
10000
1000
+1000
=====
0000无符号溢出。
hmmm 4+4
0
0100
+0100
=====
01000
0100
+0100
=====
1000unsigned add进位输出为0这不是无符号溢出。但是这是带符号溢出,因为进位到msbit和进位不同。+4 + +4 = +8,在4位有符号系统中,您不能表示+8,因此有符号溢出是准确的。
不管有多少位,奇怪的数字都是0和1,其余的0,对于4位系统,0和8或-8。
制作一个包含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生成上述代码的代码
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);
}
}现在你的问题是关于无符号数,对吗?所以你可能不关心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];
}我已经在其他逻辑中看到有符号溢出的msbit的事情,但在尝试正面到正面分析中的每种可能组合时,找不到它与进位和进位方法不匹配的情况。
如果我在答案中走得太远,我不介意在开始时把它剪掉,因为它显示5-0有一个1作为1的进位,这对于减法来说不是溢出。答案很长,因为很难理解有符号的和无符号的,以及加法器在逻辑上是如何工作的。加法器不知道也不关心有符号或无符号,它关心的是加法和减法,用减法反转第二个操作数,反转进位到lsbit和msbit的进位(想想加法、进位加法、sub和sub进位)。有符号vs无符号需要注意自身(二进制的美是互补的)。将上面的讨论简化为unsigned only讨论使其简单一半以上,因为对于不经意的观察者来说,签名溢出并不明显(就像unsigned overflow一样)。
我当然希望我剪切并粘贴了调试过的HDL,如果我没有这样做,会得到很多响应/更正……我花了几天的时间说服自己相信上面的所有内容,并与我可以访问的其他处理器的结果进行比较,等等。希望这能节省你几天时间。
发布于 2011-10-21 09:45:17
不是专家,但关于减法的整个陈述似乎是错误的。
您可以通过两种基本方式实现减法:直接作为减法,或者作为二的补码的相加。
如果你使用2的补码加法,那么正如你所说的:进位1是下溢。
5 - 6
= 0101 - 0110
= 0101 + (1001 + 1)
= 0101 + 1010
= (0)1111, carry 0 = underflow如果直接减法,则1进位是下溢:
0101 - 0110:
0 to 1 is 1
1 to (1)0 is 1, carry 1
1 + 1 to (1)1 is 1, carry 1
0 + 1 to (1)0 is 1, carry 1 = underflow发布于 2011-10-21 10:43:54
为加法器设计溢出检测单元可能有其他等效的方法,但最常见的是Cin XOR Cout。例如,请参阅第4课的末尾http://cs.nyu.edu/~gottlieb/courses/2007-08-fall/arch/class-notes.html
它只是简单地检查被添加的数字(如果某些数字被倒置为2的补码或不重要,我们随后查看这些值)是否进入最后一个数字的计算,而不是进入超过支持的位大小的数字,或者相反。
这是有道理的,因为如果它们进位而不是输出,结果肯定是负的(因为MSB必须是1),但操作数必须是正的(因为如果它们是负的,就会有进位)。这是溢出的定义,因为两个正和不能等于负。
这是一个签名的模型,但是,我不确定这是否是你想要的,因为你提到了未签名。如果是这种情况,那么你是对的,当进位输出为1时,简单的加法模型有溢出(这相当于上面的情况,如果你认为加法对于每个操作数的MSB有额外的0,那么进位输出将始终是0,如果进位输入是1,那么就会有溢出。在这种情况下,进位输入就是我们模型中的进位)。
如果该值为负值,则减法会导致下溢。如果我们认为正操作数的MSB附加为0,而负操作数的MSB为1(符号扩展),则我们可以再次推导出等价性。当我们的原始模型(新模型中的进位)的进位是0时,我们就是负的,因为只有这样,新模型中结果的MSB才会保持1。
您的示例也不例外: 0101 + 1111 +1= 0101,进位为1,因此没有下溢,因为结果是肯定的。
https://stackoverflow.com/questions/7844120
复制相似问题