赞
踩
关于补码运算中进位溢出的问题及延伸,hdlbits中Exams/ece241 2014 q1c给出了很好的解释,首先来看问题:
Assume that you have two 8-bit 2’s complement numbers, a[7:0] and b[7:0]. These numbers are added to produce s[7:0]. Also compute whether a (signed) overflow has occurred.
译文:*假设你有两个8位2的补码,a[7:0]和b[7:0]。把这些数字相加就得到s[7:0]。还要计算是否发生了(带符号的)溢出
我们需要了解一下补码的概念,二进制数据计算时,由于负数的出现,单纯的二进制数无法计算(即原码)。为了区分正数和负数,在原码的最高位前新添加了一位,称之为符号位(0表示正,1表示负),但是仅仅这样是不够的,你可以尝试计算一下-3+5,因此把负数中所有二进制数取反(此时为反码),然后+1,正数还是原来的样子,此时这种形式的数据称之为原数据的反码。由于反码的存在,带二进制数可以直接进行加减运算。
然而在反码计算的过程中,会出现符号位溢出的问题,例如-7-5的计算为1001+1010=(1)0011,即结果为+3,这显然是不正确的,因此该问题中除了简单的相加,更要考虑进位问题的存在,下面是该题的代码:
module top_module (
input [7:0] a,
input [7:0] b,
output [7:0] s,
output overflow
);
assign s=a + b;
assign overflow=a[7] & b[7] & ~s[7] | ~a[7] & ~b[7] & s[7];
endmodule
要明确,出现错误的根源是两个数相加后的进位与原本的符号位进行运算,覆盖掉了原本的符号位,也就是以下两种情况:
1.输入为两个正数,并产生了进位1,覆盖了原本得数的符号位0.(例如反码计算 0100+0100)
2.输入为两个负数,两个数符号位相加产生0(例如反码计算1001+1001)
其实 为了避免这种情况的发生,产生了一种反码的另一种形式,即变形补码:
变形补码,又称”模4补码“即用两个二进制位来表示数字的符号位,其余与补码相同。变形补码,用“00”表示正,用“11”表示负,也称为模4的补码。用变形补码进行加减运算时,当运算结果的符号位出现“01”或者“10”时,则表示产生溢出。变形补码的最高位(第一个符号位)总是表示正确的符号,比如"00"、 “01”分别表示正数、正溢出(上溢),“11”、“10”表示负数、负溢出(下溢)。(摘自百度百科)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。