浮点加法器设计
浮点加法器
算法流程
浮点加法完整数据通路:
graph LR
S1((输入处理))
--> S2[规格化指数减法 ES]
--> S3[尾数对齐 Align]
--> S4[有效数加法 SA]
--> S5[转化 Conv]
--> S6[前导零检测 LZD]
--> S7[归一化 Norm]
--> S8[舍入 Round]
--> S9((输出检查))
- Conv, LZD, Norm 这三步是为了将最后的输出进行规格化
- 输入处理和输出检查是所有浮点操作所必需的,因此可以和其他浮点操作共用
需要处理的问题:
- 不同指数导致的尾数对齐;
- 异号相加时可能发生严重相消;
- IEEE 754 正确舍入;
- NaN、无穷、非规格数和异常标志处理。
设输入为:
$$
A=(-1)^{s_A}M_A2^{E_A},\qquad
B=(-1)^{s_B}M_B2^{E_B}
$$
1. 输入处理
- 任一输入为 sNaN:置
invalid,输出 qNaN; - qNaN 输入:输出 NaN;
- 正负无穷相加 $+\infty+(-\infty)$:无效操作,输出 NaN;
- 同号无穷相加:保持无穷;
- 零和精确相消结果:需要按照舍入模式确定正负零
在 RISC-V 中,浮点指令产生对应的标志位(非异常)
fflags:
NV:invalid;DZ:divide by zero;OF:overflow;UF:underflow;NX:inexact。加法不会产生
DZ,但可能产生其余四种标志。RISC-V 默认使用规范 NaN,并要求支持非规格数运算。
2. 规格化指数减法 (Exponent Subtraction,ES)
求规格化的指数之差(求指数差的绝对值): $d=|E_A-E_B|$
硬件做法:
- 先比较:$(E_A,M_A)\quad\text{和}\quad(E_B,M_B)$
- 然后交换操作数,使 $E_L\geq E_S$, 其中 (L) 表示较大操作数,(S) 表示较小操作数。
- 计算指数差:$d=E_L-E_S$
这样做的好处是:
- 指数差始终非负;
- 异号时可以固定执行“大数减小数”;
- 结果符号通常就是较大操作数的符号;
- 尾数减法不需要处理负的中间结果。
3. 尾数对齐 (Alignment, Align)
较小操作数的尾数右移:$M’_S=M_S\gg d$
使二者指数相同:$A\pm B=\left(M_L\pm M’_S\right)2^{E_L}$
硬件不能简单丢弃被移出的位,因为它们决定最终舍入。一般至少保留三位:
G:Guard bit,保留位之后的第一位;R:Round bit,第二位;S:Sticky bit,其余所有被丢弃位的逻辑或, 即 $S=b_0\lor b_1\lor b_2\lor\cdots$
这种右移通常称为 shiftRightJam
如果指数差已经大于 (p+2) 或 (p+3),较小操作数对结果有效尾数已无直接贡献,硬件不必真正进行全距离移位,只需要判断它是否非零并生成 sticky 位 (p 指浮点格式的有效数精度,也就是尾数参与运算的总位数,包含规格数隐含的最高位 1)
对齐电路通常是浮点加法器中面积和延迟都很显著的模块,一般实现为多级桶形移位器和并行 sticky 归约树
4. 有效数加法 (Signicand addition,SA)
操作由符号决定:
- 同号 $s_A=s_B$, 执行 $M_R=M_L+M’_S$, 结果符号为共同符号
- 异号 $s_A\ne s_B$, 执行 $M_R=M_L-M’_S$, 结果符号为绝对值较大的操作数符号
硬件中通常是一个加法器实现,减法通过补码加法完成
5. 转化(Conversion, Conv)
将结果转换为符号-幅度表示 $(s_R, M_f)$, 这一步是为了方便规格化
如果有效数字加法结果 $M_R$ 为负:
- $s_R$ 就是 $M_R$ 的最高位, 即 1
- $M_f$ 就是 $M_R$ 的相反数(硬件补码加一)
否则,$s_R = 0, M_f = M_R$
6. 前导零检测(Leading zero detection,LZD)
计算结果规格化所需的左移或右移量 $E_n$ ,右移为正,否则为负。
- 先进行零检测:结果为 0 时 ($M_f = 0$), 跳过正常规格化,结果直接置 0
- 同号加法产生进位时 ($2 \le M_f \lt 4$), 需要右移一位 $E_n = 1$
- 异号减法发生相消时 ($0 \lt M_f \lt 1$), 前导零检测器计算第一个 1 前面的零数,并左移 $E_n=-LZD(M_f)$
- 其余情况不需要移动 ($1 \le M_f \lt 2$): 已满足规格化要求 $E_n = 0$
7. 归一化(Normalization, Norm)
- 通过移 $E_n$ 位将有效数字归一化: $M_R = M_f \times 2^{-E_n}$
- 将 $E_n$ 加到 $E_L$ 上: $E_R = E_n + E_L$
8. 舍入(Rounding, Round)
根据 IEEE-754 标准舍入
- 必要时在 $M_R$ 的 LSB 上加 1
设保留部分最低位为 (L),丢弃部分是否非零为:$D=G\lor R\lor S$
不同舍入模式的尾数加一条件为:
| 舍入模式 | 尾数加一条件 |
|---|---|
| RNE,最近偶数 | $G\land(R\lor S\lor L)$ |
| RTZ,向零 | 永不加一 |
| RUP,向 (+\infty) | 结果为正且 $D=1$ |
| RDN,向 (-\infty) | 结果为负且 $D=1$ |
| RMM,最近且中点远离零 | $G=1$ |
- 若舍入加一导致溢出,溢出时需要将尾数结果右移一位,同时指数 $E_R$ 加 1
9. 输出检查
最后检查指数
- 上溢: 指数超过最大值
- 某些舍入模式得到无穷;
- 某些舍入模式得到最大有限数;
- 设置
OF; - 通常同时设置
NX
- 下溢: 指数低于最小规格指数时,需要生成非规格结果:$0.f\times2^{E_{\min}}$
- 需要再次右移有效数,并把移出位纳入 GRS
- RISC-V 按舍入之后判断 tininess,因此只有最终结果既微小又不精确时才设置
UF。
硬件实现
单路径浮点加法器
单路径结构基本对应前面的串行算法:
1 | 指数比较 |
优点:
- 逻辑复用多, 面积较小;
- 适合嵌入式处理器、低成本 ASIC 和 FPGA。
缺点:
- 对齐移位、加减、LZD、规格化、舍入串在同一逻辑链上;
- 高频实现必须切成较多流水级;
- 正常加法也要经过为严重相消准备的复杂逻辑。
双路径浮点加法器
单通路浮点算法很慢,因为其步骤基本上都是串行执行的,可以通过以下方式改进该算法:
通过交换有效数字使 Conv 步骤和 Round 步骤可以互斥并行
- Conv 步骤仅当结果为负时才需要执行,并且可以通过交换两操作数的有效数字来避免该步骤
- 在指数不同的情况下, 通过检查 ES 步骤结果的正负号,并根据正负进行交换相应的有效数字,就可以保证总是计算较大的有效数字减去较小的有效数字
- 在指数相等的情况下(ES 步骤结果为 0), 结果仍可能为负,需要进行转换,但这种情况下不需要舍入
- 交换步骤只需要一个移位器
? LZD 步骤可以与 SA 步骤并行执行,将其从关键路径中移除(减法可能需要大量左移)
Align 和 Norm 步骤是互斥并行的
- 只有当 $d \le 1$ 时或者有效数减法时,归一化需要大量的左移
- 只有当 $d \gt 1$ 时,对齐步骤需要大量的右移
- SA 步骤在有效数减法的情况下,其中一个有效数字是 2 的补码,求补码步骤和舍入步骤是互斥并行的
- 等效加法或 $d \gt 1$ 的等效减法的通路称为 far 路径
- $d \le 1$ 且等效减法的通路称为 close 路径
- 含有无穷或 NaN 操作数的情况单独判断,不属于 far 路径或 close 路径
Far Path
处理:
- 等效加法
- $d \gt 1$ 的等效减法
并行计算规格化指数差和操作数交换
- 计算指数差: 为加快计算速度,使用两个加法器来计算规格化的指数差,同时计算 $d_{AB} = E_A - E_B$ 和 $d_{BA} = E_B - E_A$
- 根据结果大小的比较结果选择出:
- 正确的规格化的指数差 d
- 指数较大的操作数的有效数字 $M_L$
- 指数较小的操作数的有效数字 $M_S$
- 较大的指数 $E_L$
当等效减法时,$E_L–$, 目的是调整有效数字做完减法后的值域,和等效加法值域统一起来方便后面选择出最终结果
- 调整后有效数字加减结果的值域在 $[1-4)$ 之间,分为两种情况:
- $[1,2)$ 之间:之后不需要右移
- $[2,4)$ 之间:之后需要右移 1 位, 指数加 1
- 调整后有效数字加减结果的值域在 $[1-4)$ 之间,分为两种情况:
对较小的有效数字 $M_S$ 右移,并计算出右移后的 GRS 位
- 此处右移分两种情况:
- 等效减法时先取反再算数右移 (?)
- 等效加法时直接逻辑右移
- 为节省右移器的级数:
- 当 d 的高位全 0 时,右移时用 d 的低位 (具体位数 = log(有效数字宽度)) 进行右移
- 当 d 的高位不是全 0 时,表示 d 已超过有效数移位器关心的范围, 右移结果直接置 0
- 为了正确舍入,需要提前计算两组 GRS
- $GRS_{normal}$: 有效数字加减结果在 $[1,2)$ 之间:
- $GRS_{overflow}$: 有效数字加减结果在 $[2,4)$ 之间, 最终还要右移一位,GRS 也要随之变化
- 此处右移分两种情况:
进行有效数字加法: 两个有效数字加法器分别计算 $M_L + M_S’$ 和 $M_L + M_S’ + 2$, 最终舍入结果从中选择
产生最终结果
- 根据 $M_L + M_S’ 的结果分为两种情况:
- 情况一: $[1,2)$ 之间
- 情况二: $[2,4)$ 之间
- 尾数结果:根据两套 GRS 和舍入模式,分别确定两种情况选择两个有效数字加法器的条件,最后用四选一的独热码选择器选择出尾数结果
- 指数结果:
- 情况一且尾数舍入后 < 1 : $E_L$
- 情况二或情况一舍入后 = 2: $E_L + 1$
- overflow 情况: 最终结果由 overflow 选出 overflow 结果和正常计算结果
- 异常标志位: far 路径下只会产生上溢和不精确
- 根据 $M_L + M_S’ 的结果分为两种情况:
Close Path
处理:等效减法且 $|E_A-E_B|\leq1$, 即指数非常接近的异号运算
并行做四组有效数字减法, 同时根据指数大小关系计算出 GRS 位:
- d = 0, $M_A > M_B$: $M_A - M_B$, GRS 均为 0
- d = 0, $M_B > M_A$: $M_B - M_A$, GRS 均为 0
- d = 1, $E_A > E_B$: $M_A \times 2 - M_B$, RS 均为 0
- d = 1, $E_B > E_A$: $M_B \times 2 - M_A$, RS 均为 0
- 这四组加法器不能产生所有舍入的结果,增加第五个慢速加法器,$M_L - M_E >> 1$
确定选择四组有效数字减法的四个条件, 从四组加法器中选出减法结果后需要对减法结果进行 LZD + 左移
- 选择条件:
- d
- 加法器结果的最高位
- GRS
- 舍入模式
- 左移限制:根据 $E_L$ 的值产生一个 mask 值 (与减法结果位宽相同但最多只有一比特是 1),与减法结果或操作后再进行 LZD + 左移, 目的是限制左移位数不要超出规格化数的范围
- 选择条件:
确定选择第五个减法器的条件,选择第五个减法器结果时不需要左移,所以采用慢速加法器
指数结果和符号位结果
- 指数位结果需要用 $E_L - LZD$
- 若使用选择的是第五个减法器作为尾数结果,则指数保持原值
- 当 d = 1 时符号位的取值就是 $s_L$
- d = 0 时要根据尾数大小选择符号位, 结果为 0 且向下舍入时,符号位为 1