Skip to content
  • 定点数运算:
  • 算术运算:
    • 带符号整数:取负/符号扩展/加减乘除/算术移位
    • 无符号整数:0扩展/加减乘除
  • 逻辑运算:
    • 与或非
    • 逻辑左右移
  • 浮点数运算:
  • 加减乘除
  • 所有运算都可以由ALU或加法器+移位器+多路选择器+控制逻辑实现

基本运算部件

算数逻辑部件ALU

  • image-20231105174808375
  • 操作控制端ALUop决定ALU进行操作的种类数目(\(2^k\)
  • image-20231105174900014
  • image-20231105174954396

串行进位加法器

  • 从低位开始进行串行计算
  • image-20231105171818848
  • \(C_0\)\(C_n\) 会产生约 \(2n\) 级门延迟
  • 延迟大,速度慢

并行进位加法器CLA

  • 采用先行进位的方式,减少电路延迟
  • 辅助函数
  • 进位生成函数\(G_i=A_iB_i\)
    • 两个数都是1,则该位产生进位
  • 进位传递函数 \(P_i=A_i+B_i\)

    • 两个数至少有一个 1,则该位有一个进位要传递
  • 全加逻辑方程:\(\displaylines{F_i=A_i\bigoplus B_i\bigoplus C_{i-1} \\ C_i=G_i+P_iC_{i-1}(i=1,\dots,n)}\)

  • 进位条件:产生进位/上一位产生进位并且本位可以传递进位
  • image-20231105172706634
  • 位数较多时逻辑方程很长,成本高。可以使用分组,组内并行组间串行
  • image-20231105174018935

n位带标志加法器

  • image-20231105174629282

难点

  • 标志位
  • (有符号)溢出标志位\(OF=C_n\bigoplus C_{n-1}\)
  • 符号标志\(SF=F_{n-1}\)
  • 零标志位\(ZF=1 \ iff \ F=0\)
  • (无符号)进位、借位标志\(CF=Cout\bigoplus Cin\)

    • \(Cin=sub=1\)(这里这个 1 的作用就是减法时的"各位取反,末位加一")
    • image.png|475
  • image-20231105174550051

定点数运算

加减运算

  • 补码运算规律
  • \[ \displaylines{ [X]_补=2^n+X \ (-2^n<=X<2^n,mod \ 2^n) \\ [-X]_补=\overline{[X]_补}+1\\ [X+Y]_补=[X]_补+[Y]_补(mod \ 2^n)\\ [X-Y]_补=[X]_补+[-Y]_补(mod \ 2^n)\\ } \]
  • 有无符号的差别仅限于使用标志位解释结果的方式不同

  • image-20231105181038239
  • 有符号做减法 \(OF=SF\) 表示大于 image.png|198

  • image-20231105181300013

  • 无符号溢出判断:CF=1(减法时代表差为负数,即产生了借位) (加法时Cin=0,所以CF=1代表产生了进位,也就是加法溢出了)
  • 无符号 \(CF=0\) 表示大于 image.png|300

  • 溢出分类

  • 减法

    • image-20231105181509957
    • image.png|200
    • image-20231105181556258
  • 加法

    • image-20231105181549079
    • image-20231105181606779

乘法运算

  • 使用加法+移位实现
  • 由于源码运算只用于浮点数尾数计算,因此约定数据:
  • \([X]_原=x_0.x_1...x_n \ \ [Y]_原=y_0.y_1...y_n\)
  • 数值部分的下标从1开始

无符号乘法

  • 假定 \([X]_{原}=x_0.x_{1}\dots x_{n} \ \ \ y_{原}=y_{0}.y_{1}\dots y_{n}\)
  • \(P_i=2^{-1}(Xy_i+P_{i-1})\)
  • 即相加+右移
  • image-20231105182304501

  • 硬件实现

  • image-20231105185939698
  • 被乘数寄存器X:存放被乘数
  • 乘积寄存器P:开始置初始部分积P0 = 0;结束时,存放的是64位乘积的高32位
  • 乘数寄存器Y:开始时置乘数;结束时,存放的是64位乘积的低32位
  • 进位触发器C:保存加法器的进位信号(进位信号在右移时要移入)
  • 循环次数计数器Cn:存放循环次数。初值32,每循环一次,Cn减1,Cn=0时结束
  • ALU:乘法核心部件。在控制逻辑控制下,对P和X的内容“加”,在“写使能”控制下运算结果被送回P,进位位在C中

难点

有符号乘法

原码乘法
  • 用于浮点数尾数乘运算,符号与数值分开处理
  • image-20231105190334917

  • 一位乘法:每次只取乘数的一位判断,需 n 次循环,速度慢。

  • 两位乘法:每次取乘数两位判断,只需 n/2次循环,快一倍。

  • 原码两位乘法

  • image-20231105191146716
  • 使用T触发器向下一级传递信息,告知是否在下一级+x,因为+x,+2x很方便,但是+3x很慢
  • 由于x有加有减,使用补码算术右移
  • 使用三位符号位,因为若用模4补码(2位),中间涉及+2X会导致P和Y同时右移2位时,得到的P3是负数,就错了。(1位就更不行,2x直接溢出)
    • 如00 111+111*2=00 111 + 01 110= 10 101,再右移变成了负数!
  • image-20231105192357005
    • 使用3(符号位)+len(x/y)*2+1(T)
补码乘法(booth)
  • 用于带符号整数的乘法运算,因为\([x*y]_补!=[x]_补*[y]_补\)
  • 补码的部分积公式\([P_i]_补=[2^{-1}([P_{i-1}]_补+(y_{i-1}-y_i)\cdot x)]\)
  • 下标从低位到高位递增,\(y_{-1}=0\)
  • image.png|475

ss - 先把xy都转化为整数计算,最后看是否需要转化为负数,即对符号位单独考虑 - 注意移位使用算数右移 - 每一位可以分为:+-x以及右移两个过程 - 不用使用类似原码乘法的C位缓存进位

  • 补码两位乘法
  • image-20231105224641175
  • image-20231105224748592

补充

  • 乘法结果的位数是乘数和被乘数的二倍,对于无符号乘法和有符号乘法低位是完全一致的。可以使用高位判断是否(从低位到高位)溢出
  • image-20231105225258824

  • 仅保留低位时使用高位判断是否发生溢出

  • 无符号:全0则不溢出
  • 有符号:高位全部等于低位最高位
  • image-20231105225334705

*除法运算

无符号除法

  • 进行除法前的判断:由软件/硬件进行
  • 被除数=0,除数!=0或被除数的绝对值小于除数的绝对值则商为0
  • 被除数!=0,除数=0则发生除数为0异常
  • 被除数=0,除数=0则返回NaN
  • 被除数和除数均!=0才进一步进行除法运算
  • 通过被除数(中间余数)减除数得到每一位商(够减为1)
  • 基本操作为减法(加法实现)和移位,与乘法用同一套硬件
  • 定点无符号数相除前要在被除数的高位添加n个0,定点小数则在低位添加
  • 即被除数被扩展到2n位
  • image-20231105230733853
  • 若第一次试商(第n+1位)商为1,则说明结果不能使用n位无符号整数表示,即会发生溢出
  • \(1111 \ 1111/1111=1 \ 0001\)
  • image-20231105230954470
  • 除数寄存器Y:存放除数。
  • 余数寄存器R:初始时高位部分为高32位被除数结束时是余数
  • 余数/商寄存器Q:初始时为低32位被除数;结束时是32位商
  • 循环次数计数器Cn:存放循环次数。初值是32(不包括第一次试商),每循环(移位)一次,Cn减1,当Cn=0时,除法运算结束。
  • ALU:除法核心部件。在控制逻辑控制下,对于寄存器R和Y的内容进行“加/减”运算,在“写使能”控制下运算结果被送回寄存器R
    • 加减是因为需要“试减”,即比大小,看能不能直接间减
  • image-20231105231658252
  • 恢复余数法的试除后如果最高位为1则说明要恢复(变为负数了,不该减!),即下一步加回来(现恢复再左移),为0则表示可以减,如果可以除则下次左移移入1,否则移入0。
  • 实际上,商有n+1位,但是在高位中的那一位应该是0(否则会发生溢出),即第一位不用于结果,只用于判断是否发生溢出
  • 余数是高位部分的前n-1位,因此最终还要右移一次
  • 加减交替法(不恢复余数除法)
  • \(R_i=2R_{i-1}-D\)为第i次中间余数(D为除数)
  • image-20231105235408085
  • 下一次的加减是由上一次决定的,负(1开头)上0下次加是联动的
  • 注意:最后一次上商为“0”的话,需要“纠余”处理,即把试商时被减掉的除数加回去,恢复真正的余数。(为1则不需要
    • 要注意的是,在左移之前的基础上加
    • 如5/2可以得到11110001,此时还要进行最后一次计算
    • 易知为11100010,因为最后一位加了0,所以进行纠正,因该加上0010(2),即1111+0010=0001(不是用0111)
  • image-20231105235449227

有符号除法

原码除法
  • 商的符号和值分开处理
  • 数值由无符号除法求出
  • 符号由被除数和除数是否同号判断
  • 余数的符号同被除数的符号
  • 使用恢复余数法实现
  • image-20231116005746325
  • 因为一开始余商寄存器就设为5位(最右边留了空位给第一次试商结果),所以后面只需要左移四次(填入四位后面的试商结果),就能够获得五位的商了,而且最后一次减法算出了余数,这个余数也没有再被移动了。
  • 前面几个例子,一开始余商寄存器的后半部分是只有4位的,所以需要左移5次才能空出5个位置给5次试商结果。
  • 使用交替加减法实现
  • image-20231116005755410
补码除法k*
  • 方法1:同原码除法一样,先转换为正数,先用无符号数除法,然后修正商和余数。
  • 方法2:直接用补码除法,符号和数值一起进行运算,商符直接在运算中产生。
  • 被除数可能需要符号扩展,被除数的长度应该是除数的二倍
  • 也使用加减交替法(不恢复余数法)
  • 补码除法判断是否“够减”的规则
  • 当被除数(或当前余数)与除数同号时做减法,得到新余数
  • 当被除数(或当前余数)与除数异号时做加法,得到新余数
  • 新余数的符号与当前余数符号一致表示够减(即不变号),否则为不够减;
  • image-20231116012510861
  • image-20231116012523757

快速除法

  • 除以\(2^k\)
  • 无符号整数:逻辑右移,高位补0,低位丢弃
  • 无符号整数:逻辑右移,高位补0,低位丢弃
  • 除以\(2^k\)时整数除法的近似处理
  • 不能整除时,采用朝零舍入,即截断方式
  • 无符号数、带符号正整数(地板):移出的低位直接丢弃
  • 带符号负整数(天板):加偏移量(2k-1),然后再右移k 位 ,低位截断(这里K 是右移位数)
    • image-20231116011240005

补充

  • 变量与常数之间的除运算

  • 只使用右移、加法位运算实现x/32

  • 问题:不能通过比较判断x是否需要纠偏

    int div32(int x)
    {  /* 根据x的符号得到偏移量b */
        int b=(x>>31) & 0x1F;
        return (x+b)>>5;
    }
  • 定点运算部件

  • 所有运算都可以通过加和移位实现

  • 一个或多个ALU为核心,加上移位器、存放中间临时结果的寄存器组,在相应控制逻辑的控制下, 通过多路选择器和实现数据传送的总线等,即可以实现各种运算——也就是构成了一个运算数据通路。