Appearance

第 6 章 运算方法和运算部件

第一讲 基本运算部件

算数逻辑单元(ALU)没有统一的结构,可以根据功能进行设计。

Note

从需求角度,硬件的设计会去符合软件的需求

高级程序设计中所涉及到的运算

基本类型

  • 基本数据类型:无符号数、带符号整数、浮点数、位串、字符(串)
  • 基本运算类型:算数(加减乘除)、按位(与或非)、逻辑、移位(左移右移)、扩展和截断、匹配

底层实现

  • 将各类表达式编译(转换)为指令序列
  • 计算机直接执行指令来完成运算
底层需要提供哪些运算来满足这些运算需求?

  • 整数算术运算、浮点数算数运算
  • 按位、逻辑、移位、位扩展和位截断

其中逻辑运算、移位、扩展和截断等指令实现较为容易,而算术运算指令较难实现。可以使用多路选择器实现输出对应功能的效果。

指令集中涉及的运算

RISC-V 指令系统提供的运算类指令

  • 定点数算数运算
    • 带符号整数:取负、符号扩展、加减乘除、算术移位
    • 无符号整数:0 扩展、加减乘除
  • 逻辑运算
    • 逻辑操作:与或非
    • 逻辑移位:逻辑左移、逻辑右移
  • 浮点数算数运算:加减乘除

串行进位加法器

通过组合逻辑电路实现:[[第 3 章 组合逻辑电路#串行进位加法器/行波进位加法器|串行进位加法器]]

module FA(
    input x, y, cin,
    output f, cout
);
    assign f = x ^ y ^ cin;
    assign cout = (x & y) | (x & cin) | (y & cin);
endmodule

并行进位加法器(CLA 加法器)

通过组合逻辑电路实现:[[第 3 章 组合逻辑电路#超前进位加法器|并行进位加法器]] 通过展开和推导,搭建出可根据输入,计算出先行进位的 CLU 部件

先行进位计算过程

构造:

  • 进位生成函数:Gi=XiYi
  • 进位传递函数:Pi=Xi+Yi(或 Pi=XiYi

得到全加逻辑方程:{Si=XiYiCiCi=Gi+PiCi1(i=1,2,,n)C2,C3,,Cn 逐级展开,即可实现仅用输入表示出进位

局部(单级)先行进位加法器

思路:组内并行,组间串行

局部先行进位加法器(PartialLookahead Adder):全使用先行进位加法器的成本太高(需要在 CLU 中使用太多的逻辑部件),因此使用 N 位先行进位加法器,合成一个大加法器。 最长延迟 = GP 计算 + CLU 中最长的逻辑表达式计算 + S 计算

两级/多级先行进位加法器

思路:组内并行,组间并行

当前最常用的方法,通过 BCLU 部件计算出组间进位,使计算进一步加速。 输入接入 BCLU,BCLU 的输出逐级上传,计算出组间进位,然后下传后开始并行计算加法。 最长延迟 = GP 计算 + CLU 中最长的逻辑表达式计算(除了最顶层,上行和下行均要计算,上行算的是最高位进位,下行算的是每一位具体的进位)+ S 计算

n 位带标志加法器

需求:增加运算结果的标志信息

  • 判断是否溢出
  • 比较大小 标志:
  • 溢出标志 OF=CnCn1
  • 符号标志 SF=Fn1
  • 零标志 ZF=1 当且仅当 F=0(实现是将所有输出接入一个或非门)
  • 进位/借位标志位 CF=CoutCin

算数逻辑部件(ALU)

通过选择器控制 ALU 处于的工作状态。 ALU 具有如下功能:

  • 加减:add, sub, addu, subu
  • 逻辑:or
  • 比较:slt, sltu

第二讲 定点数运算

定点数加减运算

补码加减运算

n 位整数加减运算器

可以实现四种运算:

无符号整数有符号整数
加法
减法
  • A1=AA0=A,可用异或门对加减法中 B 的状态进行处理。

标志位

溢出标志 OF
  • 符号位进位与最高数值位进位相同,则无溢出,即 OF=CnCn1
符号位进位
(最高位进位)
最高数值位进位
(次高位进位)
加数类型溢出状态 OF
00两个正数
一正一负
0
01两个正数1
10两个负数1(负+负出现了正数)
11两个负数0(符号位保持了不变)
进位/借位标志 CF
  • CF=CinCout
加减标志 Cin输出 Cout进位/借位状态 CF
0 (加法)00 无进位
0(加法)11 进位
1(减法)01 借位
1(减法)10 无借位
减法的借位

(AB)mod2n=([A]+[B])mod2n=(AB+2n)mod2n
  • A>B,则不借位,此时自然溢出
  • A<B,则借位,此时不会溢出

使用减法进行大小比较

使用减法来比较大小:

  • 有符号整数:
    • A>B,则 ABOF=SF (OFSF=0)
    • A<B,则 ABOFSF (OFSF=1)
  • 无符号整数:
    • A>B,则 ABCF=0
    • A<B,则 ABCF=1

原码加减运算

原码加减用于浮点数位数运算,原理如下:

  • 符号位和数值位分开处理
  • 仅对数值部分进行加减运算,符号位起到判断和控制作用 规则如下:
  • 比较两数符号,对加法实行“同号求和,异号求差”的运算,对减法实行“异号求和,同号求差”的运算
  • 求和:数值位相加,和的符号取被加数的符号。若最高位产生进位,则结果溢出。
  • 求差:被减数加上减数的补码。
    • 差的符号位

移码加减运算

移码的和、差等于和、差的补码运算后转为移码(同态)

定点数乘法运算

无符号数的乘法运算

列竖式,使用加法和左移运算来实现乘法。

手算模拟竖式,此处没有进行左移改右移优化。

优化:

  • 累算部分积,而不是最终累加
  • 存数改为高位在右,左移改右移
  • 只用最高 n 位长度的加法器滑动即可
  • 遇到 0 的时候,直接右移(在二进制下,遇 0 右移,遇 1 直接加)
电路实现
  • 被乘数寄存器 X:存放被乘数
  • 乘积寄存器 P:开始置初始部分积 P0=0;结束时,存放的是64位乘积的高32位
  • 乘数寄存器 Y:开始时置乘数;结束时,存放的是64位乘积的低32位
  • 进位触发器 C:保存加法器的进位信号
  • 循环次数计数器 Cn:存放循环次数。初值32,每循环一次,Cn减1,Cn=0时结束
  • ALU:乘法核心部件。在控制逻辑控制下,对 P 和 X 的内容“加”,在“写使能”控制下运算结果被送回 P,进位位在 C 中

原码的乘法运算

用于浮点数尾数乘运算。符号与数值分开处理,积的符号通过符号位异或得到,数值部分用无符号乘法计算。

两位乘法

与一位乘法不同,两位乘法每次取乘数的两位进行处理,因此可以将运行时间降低到原来的一半:

情况迭代公式进行操作
00Pn+1=22P直接移两位
01Pn+1=22(P+X)+X,移两位
10Pn+1=22(P+2X)+X+X,移两位
11Pn+1=22(P+3X)=22(PiX)+X+[X],移两位,再+X

补码乘法运算

Booth’s Algorithm: 部分积公式:Pi=21(Pi1+(yi1yi)X) 符号与数值统一处理,右移为算数右移

定点数除法运算

核心原理:竖式除法——试商法

除前预处理

  1. =00,或定点整数除法时 ||<||,则商为0,不再继续
  2. 0=0,则发生“除数为0”异常(浮点数时为∞)若浮点除法被除数和除数都为0,则有些机器产生一个不发信号的NaN,即“quiet NaN”
  3. 0,且 0 时,才进一步进行除法运算。 计算机内部无符号数除法运算与手算一样,通过被除数(中间余数)减除数来得到每一位商够减上商1;不够减上商0(从msb→lsb得到各位商) 基本操作为减(加)法和移位,故可与乘法合用同一套硬件两个n位数相除的情况:
  • 定点正整数(即无符号数)相除:在被除数的高位添 n 个 0
  • 定点正小数(即原码小数)相除:在被除数的低位添加 n 个 0。这样,就将所有情况都统一为:一个 2n 位数除以一个 n 位数。

电路实现

  • 除数寄存器 Y:存放除数。
  • 余数寄存器 R:初始时高位部分为高32位被除数;结束时是余数。
  • 余数/商寄存器 Q:初始时为低32位被除数;结束时是32位商。
  • 循环次数计数器 Cn:存放循环次数。初值是32,每循环一次,Cn减1,当Cn=0时,除法运算结束。
  • ALU:除法核心部件。在控制逻辑控制下,对于寄存器 R 和 Y 的内容进行“加/减”运算,在“写使能”控制下运算结果被送回寄存器 R。

不恢复余数法(加减交替法)

根据恢复余数法(设 B 为除数,Ri 为第 i 次中间余数),有:

  • Ri<0,则商上“0”,把先做加法恢复余数再移位,改为直接在下一步做加法
  • Ri>=0,则商上“1”,不需恢复余数 由此省去了恢复余数的过程。但注意:最后一次上商为“0”的话,需要“纠余”处理,即把试商时被减掉的除数加回去,恢复真正的余数。

带符号数除法

  • 原码除法
    • 商符和商值分开处理
    • 商的数值部分由无符号数除法求得
    • 商符由被除数和除数的符号确定:同号为0,异号为1
    • 余数的符号同被除数的符号
  • 补码除法
    • 方法1:同原码除法一样,先转换为正数(类似原码表示),先用无符号数除法,然后修正商和余数。
    • 方法2:直接用补码除法,符号和数值一起进行运算,商符直接在运算中产生。

第三讲 浮点数运算