计算机组成原理:定点数加减法
文章目录
- 运算公式
- 溢出检测
- 溢出检测的方法
- 方法一
- 方法二
- 方法三
- 一位全加器的硬件逻辑实现
- 逻辑表达式
- 逻辑电路
- 串行进位加法器的硬件逻辑实现
- n 位串行进位加法器
- 串行进位加法器的性能
- 先行进位加法器的的硬件逻辑实现
- 4位快速加法器与4位串行进位加法器性能比较
- 更大位宽的快速加法器电路
- 可级联的4位先行进位电路
在计算机处理的所有数值运算中,加减运算看似基础,却是支撑复杂计算的 “基石”—— 从日常的整数加减,到浮点数运算、信号处理,最终都可拆解为定点数的加减操作。理解定点数加减运算的规则(尤其是补码的应用),不仅能搞懂 “计算机为什么能算对负数”,更能触达硬件层面 “算术逻辑单元(ALU)” 的工作原理,为后续学习更复杂的数值运算打下基础。
由于补码的符号位可以与数值位一起参加运算。采用补码可将减法运算转换成加法运算。补码的运算规则简单,易于实现,因此定点数(定点整数和定点小数)在计算机内部采用补码表示。
运算公式
补码加法和减法运算的公式如下:
加法:两数补码的和 = 两数和的补码
[A]补+[B]补=[A+B]补[A]_补+[B]_补=[A+B]_补[A]补+[B]补=[A+B]补
减法:两数补码的差 = 两数差的补码 [A]补−[B]补=[A−B]补=[A]补+[−B]补[A]_补-[B]_补=[A-B]_补 = [A]_补+[-B]_补[A]补−[B]补=[A−B]补=[A]补+[−B]补
-
补码减法运算可以转换成补码加法运算,因此在机器内部可不设计减法器,而将补码减法运算转换成补码加法运算,利用加法器完成运算即可。
-
在机器内部采用的是操作数各自的补码进行加法运算
由于我们讨论的是模数,因此在补码的加减法运算中,补码 mod M 为:
-
定点整数:M=2n+1M = 2^{n+1}M=2n+1,其中,n 为补码数值位的位数
-
定点小数:M=21=2M=2^1=2M=21=2
![![[定点数加减法示例.png]]](https://i-blog.csdnimg.cn/direct/1b8eef04cc7d476f8b0b7da569f71ad9.png)
溢出检测
计算机的字长是有限的,因此所能表示的数据范围也是有限的,当运算结果超出所能表示的数据范围时,就会出现溢出(Overflow),溢出会导致错误的运算结果。
计算机系统设计人员必须要解决溢出的检测问题,以便在发生溢出时计算机能做出相应的处理。定点数补码加减运算判断溢出的方法主要有以下 3 种:
-
根据 操作数的符号位 与 运算结果的符号位 是否一致进行判断
-
根据运算过程中 最高数值位的进位 与 符号位的进位 是否一致进行判断
-
利用变形补码(具有2位符号位的补码)的符号位进行判断
对于无符号数的加法运算,最高位的进位就是溢出检测信号。
溢出检测的方法
方法一
操作数的符号位与运算结果的符号位是否一致:两个操作数相加时,当它们的符号位相同(即同正或同负)时,才可能发生溢出。
![![[溢出检测的方法1.png]]](https://i-blog.csdnimg.cn/direct/d769712ecd564d81823a9000a9f612ec.png)
-
溢出:运算结果的符号位与原操作数的符号位不同(注意区分舍弃模数与算术溢出的区别,符号位进位的值为模数,应舍弃)
-
未溢出:运算结果的符号位与原操作数的符号位相同
![![[溢出检测的方法1示例.png]]](https://i-blog.csdnimg.cn/direct/5add3307a6d94b63bcaec873abb8ecdc.png)
由于采用补码可将减法运算转换成加法运算,因此不论作加法还是减法,只要实际参加运算的两个操作数符号相同,但运算结果的符号位与原操数不同,即为溢出。
![![[溢出检测的方法1示例2.png]]](https://i-blog.csdnimg.cn/direct/a4b0138990764e27bb4882e1e3dfcfd0.png)
溢出检测的逻辑表达式:
操作数 xxx 的符号位记为 xn−1x_{n-1}xn−1,操作数 yyy 的符号位记为 yn−1y_{n-1}yn−1,运算结果 sss 的符号位记为 sn−1s_{n-1}sn−1,
溢出标志位记为 OFOFOF,当 OFOFOF 为 1 时表示发生溢出。
xxx 与 yyy 的符号位相同,与 sss 的符号位相反,得出发生溢出时的逻辑表达式:
-
xn−1⋅yn−1⋅s‾n−1x_{n-1} \cdot y_{n-1} \cdot \overline{s}_{n-1}xn−1⋅yn−1⋅sn−1
-
x‾n−1⋅y‾n−1⋅sn−1\overline{x}_{n-1} \cdot \overline{y}_{n-1} \cdot s_{n-1}xn−1⋅yn−1⋅sn−1
可得出 OF 的 逻辑表达式
OF=xn−1⋅yn−1⋅s‾n−1+x‾n−1⋅y‾n−1⋅sn−1OF = x_{n-1} \cdot y_{n-1} \cdot \overline{s}_{n-1} + \overline{x}_{n-1} \cdot \overline{y}_{n-1} \cdot s_{n-1}OF=xn−1⋅yn−1⋅sn−1+xn−1⋅yn−1⋅sn−1
![![[溢出检测的方法1示例3.png]]](https://i-blog.csdnimg.cn/direct/af4ca71029cd4590a81dadba926e4de9.png)
方法二
根据运算过程中最高数值位的进位 与 符号位的进位 是否一致进行判断:
-
不同可判定为产生溢出
-
相同可判定为没有产生溢出
![![[溢出检测的方法2示例1.png]]](https://i-blog.csdnimg.cn/direct/a17e314ac6aa41babd0d3b9b58869c0c.png)
- 符号位进位的值为模数,应舍弃,但并不影响使用方法二进行溢出检测
溢出检测的逻辑表达式:
最高数值位的进位记为 Cn−1C_{n-1}Cn−1,符号位的进位记为 CnC_nCn,溢出标志位记为 OF,当 OF 为 1 时表示发生溢出。Cn−1C_{n-1}Cn−1 与 CnC_nCn 不同,则产生溢出(即 OF 为1):OF=Cn−1⊕CnOF=C_{n-1} \oplus CnOF=Cn−1⊕Cn
方法三
利用变形补码,也称为双符号补码(具有2个符号位,其余与补码相同)的符号位进行判断
-
双符号位为
00时,表示正数 -
双符号位为
11时,表示负数 -
双符号位为
01时,表示正溢出 -
双符号位为
10时,表示负溢出
使用变形补码溢出判断非常直观,适合手工运算时的溢出检测,但其硬件成本高,在计算机中主要采用单符号溢出检测方案。
负数变形补码转换成原码仍可以使用反码法或扫描法
![![[溢出检测的方法3示例1.png]]](https://i-blog.csdnimg.cn/direct/fb7c4a982a7b4863b837a3fd20a7811a.png)
溢出检测的逻辑表达式:
左起第一个符号位记为 Cn+1C_{n+1}Cn+1,左起第二个符号位记为 CnC_nCn,溢出标志位记为 OF,当 OF 为 1 时表示发生溢出。Cn+1C_{n+1}Cn+1 与 CnC_nCn 不同,则产生溢出(即 OF 为1):OF=Cn+1⊕CnOF=C_{n+1} \oplus CnOF=Cn+1⊕Cn
一位全加器的硬件逻辑实现
逻辑代数和逻辑门:
![![[逻辑代数和逻辑门.png]]](https://i-blog.csdnimg.cn/direct/9cb65b78d92343a9b67543e63c39067d.png)
逻辑表达式
通过八位二进制数手工加法运算的例子其中的规律,得出实现一位二进制数加法运算的逻辑电路
![![[八位二进制数手工加法运算.png]]](https://i-blog.csdnimg.cn/direct/d6787222d86b4383a567fc6644f7eb91.png)
- 若本位计算后未向高位产生进位,可认为本位向高位的进位为0
本位加数 XiX_iXi、YiY_iYi,来自低位的进位 CiC_iCi 的各种组合,与本位 SiS_iSi ,本位向高位的进位 Ci+1C_{i+1}Ci+1 的逻辑关系的真值表
![![[一位二进制数加法运算的逻辑关系.png]]](https://i-blog.csdnimg.cn/direct/b7980bb7f84c4bf49fa6065b9f701c76.png)
可得出本位和 SiS_iSi 的逻辑表达式:Si=X‾iY‾iCi+X‾iYiC‾i+XiY‾iC‾i+XiYiCiS_i = \overline{X}_i \overline{Y}_i C_i + \overline{X}_i Y_i \overline{C}_i + X_i \overline{Y}_i \overline{C}_i + X_i Y_i C_iSi=XiYiCi+XiYiCi+XiYiCi+XiYiCi
按设计要求利用公式或卡诺图化简,并转换成满足设计要求的表达式:Si=Xi⊕Yi⊕CiS_i=X_i\oplus Y_i\oplus C_iSi=Xi⊕Yi⊕Ci
- Xi,Yi,CiX_i, Y_i, C_iXi,Yi,Ci 的组合中,只要有奇数个 1,SiS_iSi 就为1。还可应用到奇偶校验。
本位向高位的进位 Ci+1C_{i+1}Ci+1 的逻辑表达式:Ci=X‾iYiCi+XiY‾iCi+XiYiC‾i+XiYiCiC_i = \overline{X}_i {Y}_i C_i + {X}_i \overline Y_i {C}_i + X_i {Y}_i \overline{C}_i + X_i Y_i C_iCi=XiYiCi+XiYiCi+XiYiCi+XiYiCi
按设计要求利用公式或卡诺图化简,并转换成满足设计要求的表达式::Ci+1=Xi⋅Yi+(Xi⊕Yi)⋅CiC_{i+1} = {X}_i \cdot {Y}_i + ({X}_i \oplus {Y_i})\cdot{C}_i Ci+1=Xi⋅Yi+(Xi⊕Yi)⋅Ci
-
若 XiX_iXi 和 YiY_iYi 都为 1,则 Ci+iC_{i+i}Ci+i 为 1
-
若 XiX_iXi 和 YiY_iYi 不同,且 CiC_iCi 为1,则 Ci+iC_{i+i}Ci+i 为 1
逻辑电路
根据得到的逻辑表达式,可画出相应的逻辑电路:
![![[一位全加器的硬件逻辑实现.png]]](https://i-blog.csdnimg.cn/direct/9789d387032b43a0b6d777172b0321cf.png)
-
不考虑信号在逻辑门之间的线路上的传播时延
-
除了一位全加器
FA,还有一位半加器HA(Half Adder)。HA没有进位输入 CiC_iCi,所以其内部逻辑只有一个异或门(用于产生本位和 SiS_iSi),一个与门(用于产生向高位的进位 Ci+1C_{i+1}Ci+1)
串行进位加法器的硬件逻辑实现
我们使用一位全加器来构建加法器,以便实现多位二进制加法运算。根据其进位信号产生的特点,称为串行进位加法器,也称为行波进位加法器。
我们以 8 位二进制数的加法运算为例进行介绍,可使用 8 个一位全加器 FA 通过进位串联得到 8 位串行进位加法器。
![![[QQ_1730444794906.png]]](https://i-blog.csdnimg.cn/direct/af1e9bb1a4cc40ebae9aa2be0a3ca9eb.png)
-
将前一个一位全加器的输出端连接到后一个一位全加器的进位输入端
-
对于无符号数的加法运算,最高位的进位 C7+1C_{7+1}C7+1 就是溢出检测信号
-
对于补码加减法运算,有两种溢出检测方法:
- 运算结果的符号位与原操作数的符号位不同
- 最高数值位的进位与符号位的进位不同(方便快捷)
为了让上图所示的 8 位串行进位加法器,在进行补码加减法运算时,具有溢出检测的功能,我们应该为其添加一个异或门,将最高数值位的进位信号连接到该异或门的一个输入端,将符号位的进位信号,连接到该异或门的另一个输入端,则该异或门的输出就是溢出检测信号。
n 位串行进位加法器
参照 8 位串行进位加法器的构建方法,可使用 n 个一位全加器 FA 通过进位串联得到 n 位串行进位加法器。
改造上面的电路,使得其既可以做补码加法,也可以做补码减法,将补码的减法运算转换为加法运算:[A]补−[B]补=[A−B]补=[A]补+[−B]补[A]_补-[B]_补=[A-B]_补 = [A]_补+[-B]_补[A]补−[B]补=[A−B]补=[A]补+[−B]补
-
断开操作数 Y 的每一位,与其对应的n位串行进位加法器中的一位全加器输入端的连接,在其之间各添加一个异或门
-
各异或门的输出的连接到相对应的一位全加器的输入端
-
操作数 Y 的每一位输入,连接到相对应的异或门的其中一个输入端
-
各异或门的另一个输入端连接在一起,作为加法运算和减法运算的切换控制端
Sub:-
当
Sub端输入 1 时,各异或门的输出为即为操作数 Y 的每一位的取反 -
当
Sub端输入 0 时,各异或门的输出与操作数的每一位相同
-
-
我们可将
Sub端连接到n位串行进位加法器中的最低位的一位全加器的进位输入端:-
当
Sub端输入 1 时,各异或门的输出为即为操作数 Y 的每一位的取反,输入到Sub端的1,也会输入到最低位的一位全加器的进位输入端,进而实现末位加 1 -
当
Sub端输入 0 时,各异或门的输出与操作数的每一位相同,输入到Sub端的 0,也会输入到最低位的一位全加器的进位输入端,相当于低位进位 C0C_0C0 为 0,不影响加法运算结果
-
串行进位加法器的性能
-
假设基本逻辑门
OR、AND的传播延迟为1T -
假设复合逻辑门
XOR的传播延迟为3T -
假设仅考虑逻辑门的传播延迟,不考虑信号在线路上的传播时延
一位全加器的进位输入端要依次等待其相邻一位全加器的进位输出端产生的进位信号,这就是所谓的串行进位或行波进位。
![![[串行进位加法器的性能.png]]](https://i-blog.csdnimg.cn/direct/f4f2e76dd129403dbc9564b9dea11d58.png)
在 n 位串行进位加法器中,每个高位的一位全加器 FA 的运算依赖于相邻低位的一位 FA 的进位 Ci+1C_{i+1}Ci+1,因此所有一位 FA 不能并行运行,其时间关键延迟(输出所有本位和所需的时间)为 (2n+4)T(2n+4)T(2n+4)T,与串行进位加法器的位数 n 呈线性关系,当 n 较大时性能较差。
先行进位加法器的的硬件逻辑实现
在串行进位加法器中,如果能够打破串行进位加法器中的进位依赖,提前得到所有一位全加器所需的进位输入信号,也就是所谓的先行进位。这样,所有一位全加器都可以并行运算,提高加法器的运算性能
![![[先行进位.png]]](https://i-blog.csdnimg.cn/direct/614c6541fedb440f86ce9c66617cc271.png)
-
向高位的进位输出 CnC_nCn 由 GiG_iGi、PiP_iPi 以及 C0C_0C0 经过逻辑运算得到,CnC_nCn 不再依赖于 Cn−1C_{n-1}Cn−1,例如,C4C_4C4 的产生不再依赖于 C3C_3C3、C3C_3C3 的产生不再依赖于 C2C_2C2、C2C_2C2 的产生不再依赖于 C1C_1C1。
-
先行进位电路的位数越多,逻辑门的扇入系数(输入引脚数)越大,制造难度越大,一般情况下,门电路的扇入系数为1~5,最多不超过8。先行进位电路通常采用 4 位一组
-
假定各逻辑门的传播延迟为
1T,不考虑信号在线路上的传播时延,则该电路的总时间延迟为2T
基于 4 位先行进位电路构建 4 位快速加法器,为了简单起见,我们屏蔽 4 位先行进位电路的组成细节,而用符号代替 4 位先行进位电路:Ci+1=Gi+PiCi,令Gi=XiYi,Pi=Xi⊕YIC_{i+1} = G_i + P_iC_i,令 G_i=X_iY_i,P_i = X_i\oplus Y_ICi+1=Gi+PiCi,令Gi=XiYi,Pi=Xi⊕YI
根据进位生成函数 GiG_iGi 的逻辑表达式可知,每个进位的输出函数,都是由参与加法运算的两个操作数 X 和 Y 的相应数位的与运算得出,因此我们给 4 位先行进位电路的 G0G_0G0~G3G_3G3 这四个输入端各连接一个与门。
根据进位传递函数Pi的逻辑表达式可知,每个数位的仅为传递函数,都是由参与加法运算的两个操作数 X 和 Y 的相应数位的异或运算得出,因此我们给 4 位先行进位电路的 P0P_0P0~P3P_3P3 这四个输入端各连接一个异或门。
之后,将两个操作数X和Y的名数位,连接到相应的与门和异或门的输入端,再在得到的电路的基础上增加求本位和的电路即可:Si=Pi⊕Ci,Ci+1=Ci+PiCiS_i = P_i\oplus C_i,C_{i+1}=C_i+P_iC_iSi=Pi⊕Ci,Ci+1=Ci+PiCi
![![[4 位快速加法器.png]]](https://i-blog.csdnimg.cn/direct/4802176d955d4d3a8b1d85e8ab364883.png)
4位快速加法器与4位串行进位加法器性能比较
![![[4位快速加法器与4位串行进位加法器性能比较.png]]](https://i-blog.csdnimg.cn/direct/d82d07e909574c54adef2f846d445724.png)
更大位宽的快速加法器电路
使用 4 位快速加法器构建更大位宽的加法器电路,为了方便起见,我们使用符号来屏蔽 4 位快速加法器电路的组成细节:
![![[4 位快速加法器电路.png]]](https://i-blog.csdnimg.cn/direct/89ba0bde0b134c87a61e21d73f52488b.png)
将 4 个 4 位快速加法器通过进位串联方式连接在一起,构建 1 个 16 位快速加法器,其组成与性能如下:
![![[16 位快速加法器的性能.png]]](https://i-blog.csdnimg.cn/direct/eabc8b5b460945558c2a40671e82a493.png)
可见,比使用16个一位全加器通过进位串联的方式构建的 16 位加法器的性能提升了约 2.6 倍
以上方式构建 64 位加法器,时间关键延迟为 38T
可级联的4位先行进位电路
为了进一步提升性能,对于4 位一组,组内并行进位、组间串行进位的 16 位加法器,如果可以利用先行进位电路提前产生 C4C_4C4、C8C_8C8、C12C_{12}C12、C16C_{16}C16 信号,则可以实现组间并行进位。
我们可以在之前的 4 位先行进位电路的基础上,构建可级联的 4 位先行进位电路。
![![[可级联的 4 位先行进位电路.png]]](https://i-blog.csdnimg.cn/direct/b3b66b4f889e4ae4b9120c198f0e8043.png)
为了方便我们后续使用该电路进行相关设计,我们将其使用符号表示。
- 使用可级联的 4 位先行进位电路来构建可级联的 4 位快速加法器,
- 使用 1 个级联的 4 位先行进位电路和 4 个可级联的 4 位快速加法器,来构建一个 16 位组内并行、组间并行加法器:
![![[16 位组内并行、组间并行加法器.png]]](https://i-blog.csdnimg.cn/direct/c8819fb52a894979a61d591234d4ff2d.png)
- 输入: 两个 16 位的加数 和一个初始进位 (C0C_0C0)
- 输出: 结果和 (C16C_{16}C16) 和最终进位 (C16C_{16}C16)
我们对该 16 位组内并行、组间并行加法器进行性能分析:
- 时间关键延迟为:12T
- S4S_4S4、S8S_8S8、S12S_{12}S12 在 10T 时刻就已同时产生。
以上方式构建 64 位加法器,时间关键延迟为 16T
