本章目录 23 节

← 返回课程首页

第 9 章 二进制算术电路

1. 本章要解决的问题

第 6 章已经会把位模式解释成无符号数或二补码数,第 8 章已经会把小型组合逻辑模块级联起来。本章把这两条知识合在一起:怎样用逻辑门完成二进制加法,怎样把一位加法器连接成多位加法器,以及怎样判断结果是否超出当前位宽。

本章还会回答三个容易混淆的问题:最高位产生进位是否一定表示错误?无符号溢出和有符号溢出为什么不同?为什么一个加法器只增加少量逻辑就能同时完成减法?

2. 与第 8 章的联系

本章继续使用第 8 章的模块化方法。先设计半加器和全加器,再把多个全加器级联成多位加法器。每个全加器只负责一位,但相邻位之间通过进位信号连接。

本章工作在逻辑和门级抽象:输入输出先按理想 0、1 处理。真实门存在传播延迟,进位不会瞬间穿过所有级。第 10 章会用波形和路径延迟分析加法器的暂态行为。

3. 前置知识快速检查

  1. 二进制 \(1+1\) 的结果为什么写成 10
  2. 4 bit 无符号数的范围是多少?4 bit 二补码数的范围是多少?
  3. \(A\oplus B\) 在什么条件下为 1?
  4. 怎样求一个位模式的二补码负值?
前置检查答案
  1. 和为十进制 2,最低位写 0,同时向更高位进 1。
  2. 无符号范围是 0~15;二补码范围是 −8~7。
  3. \(A,B\) 不同时为 1。
  4. 在固定位宽内逐位取反再加 1。也可以用 \(2^N-x\)\(-x\) 的编码。若这些问题不熟悉,先复习第 6 章第 7 章

4. 学习目标

学完本章后,你应当能够:

5. 一位相加为什么需要两个输出

先看两个一位数 \(A\)\(B\) 的加法:

\(A\) \(B\) 十进制和 和位 \(S\) 进位 \(C\)
0 0 0 0 0
0 1 1 1 0
1 0 1 1 0
1 1 2 0 1

\(A=B=1\) 时,结果是二进制 10。最低位的 0 是和位(sum),更高位的 1 是进位(carry)。因此,一位加法器也需要两个输出。

6. 半加器:相加两个输入位

半加器(half adder, HA)有两个输入 \(A,B\),输出和位 \(S\) 与进位 \(C\)。从真值表可直接读出:

\[ S=A\oplus B, \]

\[ C=AB. \]

\(S\) 在两个输入不同时为 1,所以使用 XOR;\(C\) 只在两个输入都为 1 时产生,所以使用 AND。图 9-1 把真值表、算术含义和门级结构放在一起。

图 9-1 半加器把两个输入位转换成和位与进位

半加器的限制也很明确:它没有来自低位的进位输入,因此只能用于最低位且初始进位固定为 0 的场景,或者作为全加器的内部组成部分。

7. 全加器:把低位进位也加进来

全加器(full adder, FA)有三个输入:当前位 \(A_i\)\(B_i\) 和来自低一位的进位 \(C_i\)。输出为当前和位 \(S_i\) 和送往高一位的进位 \(C_{i+1}\)

它完成的算术关系是:

\[ A_i+B_i+C_i=2C_{i+1}+S_i. \]

式中所有量都是 0 或 1。右侧的 \(C_{i+1}\) 权重是 2,\(S_i\) 权重是 1。

7.1 全加器真值表

\(A_i\) \(B_i\) \(C_i\) \(S_i\) \(C_{i+1}\)
0 0 0 0 0
0 0 1 1 0
0 1 0 1 0
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1
1 1 0 0 1
1 1 1 1 1

和位在三个输入中有奇数个 1 时为 1:

\[ S_i=A_i\oplus B_i\oplus C_i. \]

进位在三个输入中至少有两个 1 时为 1:

\[ C_{i+1}=A_iB_i+A_iC_i+B_iC_i. \]

另一种常用形式是:

\[ C_{i+1}=A_iB_i+(A_i\oplus B_i)C_i. \]

第一项表示本位输入自己产生进位;第二项表示 \(A_i,B_i\) 不同时,本位把输入进位传播到下一位。

7.2 用两个半加器构成全加器

图 9-2 展示两个半加器怎样分两步相加。

图 9-2 两个半加器和一个 OR 门构成全加器

第一个半加器计算 \(A_i+B_i\),得到中间和 \(P_i=A_i\oplus B_i\) 和进位 \(G_i=A_iB_i\)。第二个半加器计算 \(P_i+C_i\),得到最终和 \(S_i\) 以及进位 \(P_iC_i\)。两个进位不可能同时为 1,因此用 OR 合并:

\[ C_{i+1}=G_i+P_iC_i. \]

8. 传播与产生:理解进位的两种来源

定义本位产生信号(generate)和传播信号(propagate):

\[ G_i=A_iB_i, \]

\[ P_i=A_i\oplus B_i. \]

于是:

\[ S_i=P_i\oplus C_i, \]

\[ C_{i+1}=G_i+P_iC_i. \]

“传播”和“产生”是逻辑条件,不表示进位已经瞬间到达。真实电路仍要等待门延迟。

9. 行波进位加法器:让进位逐位向高位传播

\(N\) 个全加器首尾连接,就得到 \(N\) bit 行波进位加法器(ripple-carry adder, RCA)。第 \(i\) 位的输出进位 \(C_{i+1}\) 接到第 \(i+1\) 位的输入进位。

图 9-3 使用 0111 + 0001 展示进位怎样从最低位一路传到最高位。

图 9-3 4 bit 行波进位加法器中的长进位传播路径

这次运算中,最低位产生进位;中间三位的 \(A_i\oplus B_i=1\),所以进位连续传播,最终得到 1000。稳定结果正确,但最高位和位必须等待前面各级进位确定。

9.1 行波结构的优点与限制

优点:

限制:最坏情况下,进位要经过几乎全部位。位宽增加时,关键路径大致随全加器级数增长。精确延迟取决于单元结构、输入到达时间、负载和布线,第 10 章会正式分析。

10. 多位加法的数值含义

对两个 \(N\) bit 无符号数 \(A,B\) 和初始进位 \(C_0\),完整加法关系为:

\[ A+B+C_0=2^N C_N+S, \]

\(S\) 是保留的 \(N\) bit 和,\(C_N\) 是最高位输出进位。若把 \(C_N\)\(S\) 拼成 \(N+1\) bit,就得到完整无符号结果。

例如:

  1011   (11)
+ 0110   ( 6)
------
1 0001   (17)

4 bit 输出 \(S=0001\)\(C_4=1\)。保留 5 bit 时结果是 10001;只保留 4 bit 时结果按模 \(2^4\) 回绕为 1。

11. 无符号进位与有符号溢出不是同一件事

同一个加法器只处理位模式。输入按无符号还是二补码解释,决定怎样判断范围错误。

11.1 无符号加法

两个 \(N\) bit 无符号数相加时,\(C_N=1\) 表示真实结果至少为 \(2^N\),超出 \(N\) bit 无符号范围。因此最高位进位就是无符号溢出标志。

11.2 二补码有符号加法

两个 \(N\) bit 二补码数相加时,有符号溢出(signed overflow)发生在:

若两输入符号不同,真实结果位于两者之间,不会产生有符号溢出。

定义 \(A_{N-1},B_{N-1},S_{N-1}\) 为符号位,则

\[ V=\overline{A_{N-1}}\,\overline{B_{N-1}}S_{N-1} +A_{N-1}B_{N-1}\overline{S_{N-1}}. \]

也可以用符号位的输入、输出进位判断:

\[ V=C_{N-1}\oplus C_N. \]

\(C_{N-1}\) 是进入符号位的进位,\(C_N\) 是离开符号位的进位。

图 9-4 对比两个使用同一 4 bit 加法器的例子。

图 9-4 无符号进位与二补码有符号溢出的判断依据不同

1111+0001=0000 产生最高位进位。按无符号解释是 \(15+1=16\),4 bit 放不下;按二补码解释是 \(-1+1=0\),没有有符号溢出。

0111+0001=1000 没有最高位进位。按无符号解释是 \(7+1=8\),结果合法;按二补码解释是 \(7+1\) 得到符号位为 1,超出 −8~7,发生有符号溢出。

12. 二补码减法:把减法改写成加法

\(N\) bit 二补码系统中:

\[ A-B=A+(\overline{B}+1). \]

\(\overline{B}+1\) 正是 \(-B\) 的二补码编码,所以减法可以交给加法器完成。

例如用 4 bit 计算 \(5-3\)

 B       = 0011
 NOT B   = 1100
 NOT B+1 = 1101   (-3)

   0101
 + 1101
 ------
 1 0010

保留低 4 bit 得到 0010,即 2。最高位进位丢弃。

12.1 无符号减法中的借位

\(A+\overline{B}+1\) 完成无符号减法时:

因此,无符号借位标志常写成

\[ B_{out}=\overline{C_N}. \]

具体处理器或 HDL 的状态标志定义可能不同,阅读接口时要确认它报告的是 carry、not-borrow 还是 borrow。

12.2 二补码减法的有符号溢出

\(A-B\)\(A\)\(B\) 符号不同、且结果符号与 \(A\) 不同时发生有符号溢出:

\[ V_{sub}=(A_{N-1}\oplus B_{N-1})(S_{N-1}\oplus A_{N-1}). \]

统一加减法器内部仍可使用 \(C_{N-1}\oplus C_N\) 判断有符号溢出。

13. 统一加减法电路

设置控制信号 SUB

让每一位 \(B_i\) 先经过 XOR:

\[ B_i'=B_i\oplus SUB, \]

并令最低位初始进位

\[ C_0=SUB. \]

整体运算是

\[ S=A+(B\oplus\{N\{SUB\}\})+SUB. \]

\(\{N\{SUB\}\}\) 表示把 SUB 复制成 \(N\) bit;按位 XOR 后,SUB=1 时全部 \(B\) 位取反。

图 9-5 展示控制信号如何同时决定“是否取反 \(B\)”和“初始进位是否为 1”。

图 9-5 统一加减法器用 SUB 同时控制 B 取反和初始进位

SUB=0\(B'=B,C_0=0\),所以执行 \(A+B\)

SUB=1\(B'=\overline{B},C_0=1\),所以执行 \(A+\overline{B}+1=A-B\)

这种结构复用了同一条加法路径。电路仍需要根据数据类型分别产生无符号 carry/borrow 和有符号 overflow 标志。

14. 选学:先行进位的基本思想

先修知识: 掌握第 8 节的传播 \(P_i\) 和产生 \(G_i\)
学习收益: 理解高速加法器为什么不必等待进位逐级爬过全部位。

\[ C_{i+1}=G_i+P_iC_i \]

可以提前展开:

\[ C_1=G_0+P_0C_0, \]

\[ C_2=G_1+P_1G_0+P_1P_0C_0. \]

\(C_2\) 可以直接由 \(A_1,B_1,A_0,B_0,C_0\) 的传播与产生信号计算,不必等 \(C_1\) 物理传播完成。这就是先行进位(carry lookahead)的核心思想。

图 9-6 对比行波路径与并行生成进位的结构直觉。

图 9-6 行波进位逐级等待,先行进位从传播与产生信号并行预测

展开位数增加后,直接表达式会迅速变大,实际设计通常使用分组传播、分组产生和层次化结构。本章只要求理解“用更多组合逻辑换取更短进位路径”。

15. 完整例题

例题 1:分析半加器输入 11

已知 \(A=1,B=1\)

\[ S=A\oplus B=0, \]

\[ C=AB=1. \]

因此输出写成 \(CS=10\),对应十进制 2。若只观察 \(S\) 会误以为结果为 0;进位是完整结果的一部分。

变式: 输入 10\(S=1,C=0\),完整输出 01

例题 2:分析全加器输入 101

\(A_i=1,B_i=0,C_i=1\)。输入中有两个 1,所以和为十进制 2:

\[ S_i=1\oplus0\oplus1=0, \]

\[ C_{i+1}=1\cdot0+(1\oplus0)\cdot1=1. \]

输出 \(C_{i+1}S_i=10\)

变式:\(C_i\) 改为 0,输出变成 01

例题 3:完成 4 bit 无符号加法

计算

\[ 1011_2+0110_2. \]

从 LSB 向 MSB 逐位计算,初始 \(C_0=0\)

\(i\) \(A_i\) \(B_i\) \(C_i\) \(S_i\) \(C_{i+1}\)
0 1 0 0 1 0
1 1 1 0 0 1
2 0 1 1 0 1
3 1 0 1 0 1

所以

\[ C_4S_3S_2S_1S_0=10001_2=17. \]

4 bit 和为 0001\(C_4=1\),表示无符号结果超出 0~15。

变式: 若输出总线扩为 5 bit,应保留最高进位,结果就是 10001

例题 4:判断二补码有符号溢出

计算 4 bit 二补码:

\[ 0111+0011=1010. \]

两个输入符号位都为 0,表示 \(7\)\(3\);结果符号位为 1,位模式 1010 按二补码解释为 −6。两个正数相加得到负号,因此 \(V=1\)

真实结果 \(10\) 超出 4 bit 二补码范围 −8~7。这里 \(C_4=0\),再次说明“没有最高位进位”不代表没有有符号溢出。

变式: 1110+0011=0001 表示 \(-2+3=1\)。输入符号不同,所以不发生有符号溢出,尽管可能产生最高位进位。

例题 5:使用统一电路计算减法

计算 4 bit 的 \(5-3\)。输入

\[ A=0101,\qquad B=0011,\qquad SUB=1. \]

XOR 阵列产生

\[ B'=B\oplus1111=1100, \]

初始进位 \(C_0=1\)

\[ 0101+1100+1=1\,0010. \]

低 4 bit 为 0010,结果是 2。\(C_4=1\) 表示无符号减法没有借位。

变式: \(3-5\) 得到 1110\(C_4=0\)。按无符号解释发生借位;按 4 bit 二补码解释结果为 −2。

16. 常见误区与反例

误区 1:半加器可以直接放在任意一位

半加器没有输入进位。多位加法中除非确定该位 \(C_i=0\),否则需要全加器。

误区 2:进位和和位可以合并成一个输出

一位加法可能得到 0、1、2、3。至少需要两位输出才能完整表示,其中低位是 \(S\),高位是 \(C\)

误区 3:最高位进位等于有符号溢出

最高位进位直接判断无符号范围。有符号溢出要看符号关系,或比较进入与离开符号位的进位。

误区 4:两个符号不同的数相加也可能有符号溢出

二补码加法中,一正一负的和位于两者之间,不会超出同一位宽的表示范围。

误区 5:减法只需把 \(B\) 取反

二补码负值是 \(\overline{B}+1\)。统一加减法器还要把初始进位设为 1。

误区 6:减法后的最高进位就是借位

用二补码加法执行无符号减法时,\(C_N=1\) 表示没有借位,借位标志为 \(\overline{C_N}\)

误区 7:稳定结果正确就说明中间过程也始终正确

行波进位需要时间逐级传播,中间和位可能短暂变化。第 10 章会用路径延迟解释这些毛刺。

误区 8:先行进位可以没有代价地消除延迟

先行结构增加逻辑、连线和扇入,并不让延迟归零。它用更多硬件和更复杂连接缩短长进位链。

17. 工程中的实际意义

加法器不仅用于数值相加,还用于地址递增、计数、数组索引、比较、减法和定点运算。统一加减法器是算术逻辑单元(arithmetic logic unit, ALU)的基础组成。

设计中必须同时明确三件事:

  1. 数据位宽;
  2. 数据按无符号还是二补码解释;
  3. 输出需要哪些状态标志,如 carry、borrow、overflow 和 zero。

加法器的功能真值表与具体实现可以分开优化。综合工具可能选择行波、选择进位、先行进位或其他库结构;功能验证仍要覆盖边界值、符号组合和进位链。

18. 本章知识链

两个输入位
   ↓ XOR 得和、AND 得进位
半加器
   ↓ 加入低位进位 C_i
全加器
   ↓ C_{i+1}=G_i+P_iC_i
传播 / 产生
   ↓ 多个全加器级联
行波进位加法器
   ├─ 无符号:C_N 判断范围
   ├─ 二补码:符号关系或 C_{N-1}⊕C_N 判断溢出
   └─ B 取反并令 C_0=1
统一加减法器
   ↓ 缩短长进位路径
先行进位直觉(选学)

19. 本章小结

  1. 半加器输出 \(S=A\oplus B\)\(C=AB\)
  2. 全加器把 \(A_i,B_i,C_i\) 相加,满足 \(A_i+B_i+C_i=2C_{i+1}+S_i\)
  3. 全加器可写成 \(S_i=P_i\oplus C_i\)\(C_{i+1}=G_i+P_iC_i\)
  4. 行波进位加法器结构规则,但最坏进位路径随位宽增长。
  5. \(C_N\) 判断无符号加法是否超出当前位宽。
  6. 二补码有符号溢出发生在同号输入相加得到异号结果,也可用 \(C_{N-1}\oplus C_N\) 判断。
  7. 二补码减法使用 \(A+\overline{B}+1\)
  8. 统一加减法器用 SUB 同时控制 \(B\) 的 XOR 阵列和初始进位。
  9. 先行进位通过并行计算传播与产生条件缩短进位等待路径。

20. 练习

先独立完成,再展开答案。题目 1~6 检查基本模块,7~13 训练多位运算与标志,14~17 完成结构分析和设计。

20.1 基础题

  1. 写出半加器的两个输出方程。
  2. 全加器比半加器多了哪个输入?这个输入来自哪里?
  3. 写出全加器和位 \(S_i\) 与输出进位 \(C_{i+1}\) 的方程。
  4. \(A_iB_iC_i=111\),求 \(C_{i+1}S_i\)
  5. 定义 \(P_i=A_i\oplus B_i\)\(G_i=A_iB_i\),说明 \(P_i=1\)\(G_i=1\) 各表示什么。
  6. 为什么行波进位加法器的位宽越大,最坏延迟通常越长?

20.2 计算与分析题

  1. 完成 4 bit 无符号加法 1001 + 0110,给出 \(C_4\)、4 bit 和以及是否无符号溢出。
  2. 完成 4 bit 无符号加法 1110 + 0101,给出完整 5 bit 结果。
  3. 把题 7 的两个输入按 4 bit 二补码解释,求真实数值并判断有符号溢出。
  4. 判断 4 bit 二补码加法 0101 + 0100 = 1001 是否有符号溢出,并说明依据。
  5. 判断 1100 + 1011 = 0111 是否有符号溢出,并解释输入和结果的十进制值。
  6. 使用取反加一计算 4 bit 的 0110 - 0011,给出 \(C_4\)、结果和无符号借位情况。
  7. 使用 4 bit 统一加减法器计算 0010 - 0101。给出低 4 bit 结果、\(C_4\),并分别按无符号和二补码解释。

20.3 综合题

  1. 对运算 0111 + 0001,逐位写出 \(C_0\)\(C_4\),指出为什么它形成长进位链。
  2. 一个 8 bit 加减法器输入 \(A,B\) 和控制 SUB。写出 \(B_i'\)\(C_0\) 和整体运算关系;说明 SUB=0SUB=1 分别执行什么。
  3. 设计一个 4 bit 算术模块的状态输出,要求同时给出 CARRYBORROWOVERFLOW。说明在加法与减法模式下各信号怎样解释,哪些信号依赖无符号或有符号数据类型。
  4. 已知 \[C_1=G_0+P_0C_0,\] \[C_2=G_1+P_1C_1.\]\(C_1\) 代入并展开 \(C_2\)。说明展开式怎样避免等待 \(C_1\) 逐级传播,以及这种方法增加了什么代价。

21. 练习答案

展开第 9 章练习答案

题 1

\[ S=A\oplus B,qquad C=AB. \]

题 2

全加器多了输入进位 \(C_i\)。它来自低一位全加器的输出进位 \(C_i\);最低位的 \(C_0\) 由运算模式或外部输入给定。

题 3

\[ S_i=A_i\oplus B_i\oplus C_i, \]

\[ C_{i+1}=A_iB_i+A_iC_i+B_iC_i. \]

也可写成 \(C_{i+1}=A_iB_i+(A_i\oplus B_i)C_i\)

题 4

\(1+1+1=3=11_2\),所以

\[ C_{i+1}S_i=11. \]

题 5

\(P_i=1\) 表示 \(A_i,B_i\) 不同,本位会把输入进位传播到下一位;\(G_i=1\) 表示 \(A_i=B_i=1\),本位自行产生输出进位。

题 6

最坏输入会让进位从最低位依次经过多个全加器后才到达最高位。位宽增加时,串联的进位逻辑级数增加,因此最坏传播延迟通常变长。

题 7

\[ 1001_2+0110_2=1111_2. \]

\(9+6=15\),所以 \(C_4=0\)、4 bit 和为 1111,没有无符号溢出。

题 8

\[ 1110_2+0101_2=1\,0011_2. \]

\(14+5=19\),完整 5 bit 结果为 10011

题 9

1001 按 4 bit 二补码表示 −7,0110 表示 +6:

\[ -7+6=-1, \]

结果 1111 正是 −1。输入符号不同,所以没有有符号溢出。

题 10

0101 是 +5,0100 是 +4,真实结果 +9 超出 4 bit 二补码最大值 +7。位模式结果 1001 符号位为 1,因此发生有符号溢出。

题 11

1100 表示 −4,1011 表示 −5,真实结果 −9 小于 4 bit 二补码最小值 −8。结果 0111 表示 +7。两个负数相加得到正号,因此发生有符号溢出。

题 12

\[ \overline{0011}=1100, \]

\[ 0110+1100+1=1\,0011. \]

低 4 bit 结果为 0011,即 3;\(C_4=1\),表示无符号减法没有借位。

题 13

\[ \overline{0101}=1010, \]

\[ 0010+1010+1=1101. \]

\(C_4=0\)。按无符号解释,\(2<5\),发生借位,低 4 bit 是模 16 结果 13;按二补码解释,1101 表示 −3,结果正确且没有有符号溢出。

题 14

初始 \(C_0=0\)

  • bit 0:\(1+1+0\),得到 \(S_0=0,C_1=1\)
  • bit 1:\(1+0+1\),得到 \(S_1=0,C_2=1\)
  • bit 2:\(1+0+1\),得到 \(S_2=0,C_3=1\)
  • bit 3:\(0+0+1\),得到 \(S_3=1,C_4=0\)

所以

\[ (C_0,C_1,C_2,C_3,C_4)=(0,1,1,1,0). \]

进位由 bit 0 产生,连续穿过 bit 1、bit 2,并在 bit 3 被吸收,最高和位要等待这条链稳定。

题 15

对每一位:

\[ B_i'=B_i\oplus SUB, \]

\[ C_0=SUB. \]

8 bit 整体关系为

\[ S=A+(B\oplus\{8\{SUB\}\})+SUB. \]

SUB=0 时执行 \(A+B\)SUB=1 时执行 \(A+\overline{B}+1=A-B\)

题 16

  • 加法模式:CARRY=C_4,表示无符号加法超出 4 bit;BORROW 不使用或按接口置为 0。
  • 减法模式:可定义 BORROW=\overline{C_4};此时 \(C_4=1\) 表示没有借位。
  • 两种模式都可用 OVERFLOW=C_3\oplus C_4 判断二补码有符号溢出。

CARRYBORROW 服务于无符号解释,OVERFLOW 服务于二补码有符号解释。接口应说明非适用模式下的输出值。

题 17

代入 \(C_1\)

\[ \begin{aligned} C_2&=G_1+P_1(G_0+P_0C_0)\\ &=G_1+P_1G_0+P_1P_0C_0. \end{aligned} \]

展开后,\(C_2\) 可以由 \(P_1,P_0,G_1,G_0,C_0\) 并行组合得到,不需要让一个物理 \(C_1\) 信号先稳定再进入下一全加器。代价是更多 AND/OR 逻辑、更高扇入和更复杂布线。

22. 自测清单

若第 6~9 项不稳定,把同一组 4 bit 位模式分别按无符号和二补码解释,再单独填写 CARRYBORROWOVERFLOW,不要把三个标志合并判断。

23. 下一章衔接

本章一直在讨论输入稳定后的正确结果。真实加法器中,每一级门都有传播延迟,行波进位会使中间和位先后变化,组合逻辑也可能产生短暂毛刺。第 10 章将正式学习组合路径、关键路径、静态冒险、动态冒险和毛刺,并解释同步系统为什么通常只在规定时刻采样数据。