07

二进制加法器

算术运算

阅读量:1 · 预计 12 分钟读完

半加器全加器进位
阅读进度5%

第七章 二进制加法器 — 算术运算

导读

在前面的章节中,我们学会了用逻辑门处理逻辑信息——判断真假、做选择、比较大小。但计算机不仅要处理逻辑,还要做数学运算。加减乘除,这些我们在小学就学会的基本运算,计算机是如何完成的呢?

答案可能比你想象的要简单。计算机的算术运算本质上也是逻辑运算——通过巧妙地组合逻辑门,可以构建出执行加法、减法等算术操作的电路。其中,加法器(Adder)是最基本、最重要的算术电路,因为所有的算术运算最终都可以归结为加法操作。

本章将从零开始,一步步构建二进制加法器。我们将从最简单的半加器开始,然后构建全加器,再将多个全加器级联成多位加法器。我们将学习如何用加法器实现减法,了解进位传播的问题和解决方案,最后探索乘法器和除法器的基本原理。通过本章的学习,你将亲眼看到抽象的二进制数如何在物理电路中完成算术运算。

核心概念详解

7.1 二进制加法规则

在构建加法器电路之前,我们先回顾一下二进制加法的规则。二进制加法与十进制加法类似,只是进位规则不同:逢二进一(而不是逢十进一)。

一位二进制加法规则:

0 + 0 = 0    (和=0,进位=0)
  0 + 1 = 1    (和=1,进位=0)
  1 + 0 = 1    (和=1,进位=0)
  1 + 1 = 10   (和=0,进位=1)

考虑来自低位的进位时:

0 + 0 + 0 = 0    (和=0,进位=0)
  0 + 0 + 1 = 1    (和=1,进位=0)
  0 + 1 + 0 = 1    (和=1,进位=0)
  0 + 1 + 1 = 10   (和=0,进位=1)
  1 + 0 + 0 = 1    (和=1,进位=0)
  1 + 0 + 1 = 10   (和=0,进位=1)
  1 + 1 + 0 = 10   (和=0,进位=1)
  1 + 1 + 1 = 11   (和=1,进位=1)

从这些规则中,我们可以提取出两个关键观察:

和(Sum):当三个输入中有奇数个1时,和为1;否则为0。这恰好是异或(XOR)运算。

Sum = A ⊕ B ⊕ Cin

进位(Carry):当三个输入中至少有两个为1时,产生进位。

Cout = A·B + A·Cin + B·Cin

7.2 半加器(Half Adder)

半加器是最简单的加法电路,它只能处理两个一位二进制数的相加,不考虑来自低位的进位。

输入:A、B(两个一位二进制数)

输出:S(和)、C(进位)

真值表:

ABSC
0000
0110
1010
1101

逻辑表达式:

  • S = A ⊕ B(异或)
  • C = A · B(与)

电路实现:只需要一个XOR门和一个AND门。

半加器之所以叫"半"加器,是因为它只能处理两个输入的相加,不能处理来自低位的进位输入。在实际的多位加法中,每一位都需要考虑来自低位的进位,因此半加器只能用于最低位(最低位没有来自更低位的进位)。

7.3 全加器(Full Adder)

全加器可以处理三个一位二进制数的相加:两个加数和一个来自低位的进位。

输入:A、B(两个加数)、Cin(来自低位的进位)

输出:S(和)、Cout(向高位的进位)

真值表:

ABCinSCout
00000
00110
01010
01101
10010
10101
11001
11111

逻辑表达式:

  • S = A ⊕ B ⊕ Cin
  • Cout = A·B + A·Cin + B·Cin = A·B + Cin·(A ⊕ B)

电路实现:可以用两个半加器和一个OR门来构建全加器:

第一个半加器计算 A ⊕ B 和 A·B

第二个半加器计算 (A ⊕ B) ⊕ Cin 和 (A ⊕ B)·Cin

OR门将两个进位项合并:Cout = A·B + (A ⊕ B)·Cin

7.4 行波进位加法器(Ripple Carry Adder)

将多个全加器级联,就构成了行波进位加法器(也称为串行进位加法器)。每个全加器处理一位的相加,并将进位传递给下一级。

4位行波进位加法器:

Cin
         |
  ┌──────┴──────┐
  │  全加器 0    │──→ C0
  │ A₀ B₀       │
  └─────────────┘
         C0
          |
  ┌──────┴──────┐
  │  全加器 1    │──→ C1
  │ A₁ B₁       │
  └─────────────┘
         C1
          |
  ┌──────┴──────┐
  │  全加器 2    │──→ C2
  │ A₂ B₂       │
  └─────────────┘
         C2
          |
  ┌──────┴──────┐
  │  全加器 3    │──→ C3(最终进位)
  │ A₃ B₃       │
  └─────────────┘

输入:A₃A₂A₁A₀、B₃B₂B₁B₀(两个4位二进制数)、Cin(初始进位,通常为0)

输出:S₃S₂S₁S₀(4位和)、Cout(最终进位)

行波进位加法器的优点是结构简单、易于扩展。但它的致命缺点是速度慢

速度分析:假设每个全加器的传播延迟为T_FA,则n位行波进位加法器的总延迟为n × T_FA。这是因为进位必须从最低位逐级传播到最高位。对于4位加法器,最坏情况下(如1111 + 0001),进位需要经过4个全加器,延迟为4 × T_FA。对于32位加法器,延迟为32 × T_FA;对于64位加法器,延迟为64 × T_FA。

这种线性增长的延迟在高速CPU中是不可接受的。为了解决这个问题,工程师们设计了更快的加法器结构。

7.5 超前进位加法器(Carry Lookahead Adder)

超前进位加法器(CLA)通过并行计算进位来消除行波进位的延迟。

核心思想是:不等待进位从低位逐级传播,而是直接根据输入数据计算出每一位的进位。

定义两个中间信号:

  • 生成信号(Generate):Gᵢ = Aᵢ · Bᵢ(该位本身会产生进位)
  • 传播信号(Propagate):Pᵢ = Aᵢ ⊕ Bᵢ(该位会传递来自低位的进位)

则每一位的进位可以表示为:

  • C₀ = G₀ + P₀ · Cin
  • C₁ = G₁ + P₁ · G₀ + P₁ · P₀ · Cin
  • C₂ = G₂ + P₂ · G₁ + P₂ · P₁ · G₀ + P₂ · P₁ · P₀ · Cin
  • C₃ = G₃ + P₃ · G₂ + P₃ · P₂ · G₁ + P₃ · P₂ · P₁ · G₀ + P₃ · P₂ · P₁ · P₀ · Cin

这些表达式可以直接用逻辑门实现,不需要等待前级的进位。因此,超前进位加法器的延迟不再随位数线性增长,而是取决于逻辑门的级数。

代价:超前进位加法器的电路复杂度随位数呈指数增长(进位表达式越来越长)。因此,实际的CLA通常采用分组策略:将加法器分成若干小组(如4位一组),组内使用CLA,组间使用行波进位,形成分组超前进位加法器

7.6 用加法器实现减法

计算机中通常不单独设计减法器,而是利用加法器来实现减法。这得益于补码的巧妙设计:A - B = A + (-B),而-B的补码等于B的补码取反加1。

4位减法器电路:

1(Sub控制信号)
         |
  ┌──────┴──────┐
  │  XOR门 × 4  │
  │ B₀→B₀'      │
  │ B₁→B₁'      │
  │ B₂→B₂'      │
  │ B₃→B₃'      │
  └─────────────┘
         │
  ┌──────┴──────┐
  │  4位加法器   │
  │ A + B' + 1  │
  └─────────────┘

当Sub=0时(加法模式):

  • XOR门不改变B的值(B ⊕ 0 = B)
  • Cin = 0
  • 结果 = A + B

当Sub=1时(减法模式):

  • XOR门将B取反(B ⊕ 1 = B')
  • Cin = 1
  • 结果 = A + B' + 1 = A + (-B) = A - B

这种设计的优雅之处在于:加法和减法共用同一套硬件(加法器+XOR门),只需要一个控制信号(Sub)来切换模式。

7.7 算术逻辑单元(ALU)

算术逻辑单元(ALU)是CPU中执行算术和逻辑运算的核心部件。一个简单的ALU可以执行加法、减法、AND、OR等多种操作。

4位ALU的基本结构:

A₃A₂A₁A₀    B₃B₂B₁B₀
             |           |
        ┌────┴───────────┴────┐
        │    4位加法器         │
        │  (B经过操作选择)    │
        └────────┬────────────┘
                 |
        ┌────┴────────────┐
        │  操作选择逻辑    │
        │  (MUX)         │
        └────────┬────────┘
                 |
           S₃S₂S₁S₀

操作选择信号(如2位选择码S₁S₀)决定ALU执行哪种操作:

  • 00:AND → 输出 A AND B
  • 01:OR → 输出 A OR B
  • 10:ADD → 输出 A + B
  • 11:SUB → 输出 A - B

实际的ALU远比这复杂,还可能包括移位、比较、取反等操作。

7.8 乘法器

二进制乘法比加法复杂得多。让我们先回顾二进制乘法的规则:

1011  (11)
    × 1101  (13)
    ------
      1011  (11 × 1)
     0000   (11 × 0,左移1位)
    1011    (11 × 1,左移2位)
   1011     (11 × 1,左移3位)
   --------
  10001111  (143)

二进制乘法的每一位要么是被乘数本身(当乘数位为1时),要么是0(当乘数位为0时)。因此,二进制乘法可以分解为一系列的移位加法操作。

最简单的乘法器实现是使用"移位-加法"算法:

从乘数的最低位开始

如果当前位为1,将被乘数加到部分积中

将被乘数左移一位

将乘数右移一位

重复步骤2-4,直到乘数为0

这种方法的硬件实现相对简单,但速度较慢(需要n个时钟周期来完成n位乘法)。

阵列乘法器(Array Multiplier)是一种更快的并行乘法器。它使用一个二维阵列的加法器来同时计算所有的部分积并相加。对于n位×n位的乘法,阵列乘法器需要大约n²个全加器,但只需要O(n)的门延迟。

现代CPU中的乘法器通常使用更复杂的算法,如Booth编码、Wallace树等,以进一步减少延迟和面积。

7.9 除法器

除法是最复杂的算术运算。二进制除法的过程与十进制除法类似,通过反复的比较、减法和移位来完成。

恢复余数除法的基本步骤:

将被除数的高n位与除数比较

如果被除数 ≥ 除数,商1,做减法

如果被除数 < 除数,商0

将被除数左移一位(或除数右移一位)

重复步骤1-4

非恢复余数除法是恢复余数除法的改进版本,它避免了"恢复余数"的步骤,通过加减交替来简化操作。

SRT除法是一种更高效的除法算法,使用冗余数字系统,允许商位取{-1, 0, 1}三个值,从而减少迭代次数。现代CPU中的除法器通常基于SRT算法。

与乘法器不同,除法器通常采用迭代方式实现,因为并行除法器的硬件代价太高。一个n位的除法通常需要n个时钟周期。

7.10 溢出检测

在有限位数的二进制运算中,结果可能超出表示范围,这种情况称为溢出(Overflow)

无符号数加法溢出:当最高位产生进位时发生溢出。例如,4位无符号数的范围是0-15,12 + 5 = 17 > 15,发生溢出。

有符号数(补码)加法溢出:当两个正数相加得到负数,或两个负数相加得到正数时发生溢出。

溢出检测电路:

  • 无符号数:V = Cout(最高位的进位)
  • 有符号数:V = Cn ⊕ Cn-1(最高位进位与次高位进位的异或)

溢出检测是CPU中异常处理的重要组成部分。当溢出发生时,CPU会设置状态寄存器中的溢出标志位,操作系统可以根据这个标志位采取相应的处理措施。

重要知识点

知识点一:半加器和全加器

半加器处理两个一位数的相加,全加器处理三个一位数(含进位)的相加。全加器可以用两个半加器和一个OR门构建。

知识点二:行波进位加法器简单但慢

行波进位加法器将全加器级联,结构简单但速度慢,因为进位必须逐级传播。

知识点三:超前进位加法器通过并行计算进位提高速度

CLA直接计算每一位的进位,消除了进位传播延迟,但电路复杂度较高。

知识点四:减法可以用加法实现

利用补码的性质,A - B = A + (-B),其中-B = B取反加1。这使得加法和减法可以共用硬件。

知识点五:ALU是CPU的运算核心

ALU通过操作选择信号,可以在同一套硬件上执行多种算术和逻辑运算。

常见误区

误区一:"计算机有专门的减法器"

大多数计算机不设计专门的减法器。减法通过补码转换为加法,使用同一套加法器硬件完成。这体现了补码设计的精妙之处。

误区二:"加法器的速度不重要,反正很快"

在CPU中,加法器位于关键路径上,其速度直接决定了CPU的时钟频率。一个慢的加法器会拖慢整个CPU的性能。这就是为什么工程师们投入大量精力设计高速加法器。

误区三:"乘法就是反复加法"

虽然乘法在数学上可以理解为反复加法,但在硬件实现中,这种方式的效率极低。实际的乘法器使用移位-加法或并行阵列的方式,大大减少了操作次数。

误区四:"溢出和进位是一回事"

进位(Carry)是无符号数运算中的概念,表示结果超出了无符号数的表示范围。溢出(Overflow)是有符号数运算中的概念,表示结果超出了有符号数的表示范围。两者的检测方法不同。

实践应用

应用一:设计一个4位行波进位加法器

使用全加器模块,设计一个4位行波进位加法器:

画出完整的电路图

计算最坏情况下的传播延迟

验证 1011 + 0110 的计算过程

应用二:用加法器实现减法

设计一个4位加减法切换电路:

画出电路图(包括XOR门和加法器)

验证 7 - 3 = 4 的计算过程

验证 3 - 7 的结果(考虑补码表示)

应用三:分析溢出

对于4位有符号数(补码,范围-8到+7),判断以下运算是否溢出:

5 + 3

(-4) + (-5)

6 + (-2)

(-3) + (-4)

应用四:设计简单的ALU

设计一个2位ALU,支持以下操作:

  • 00:AND
  • 01:OR
  • 10:ADD
  • 11:NOT A

本章小结

本章系统地介绍了二进制算术运算电路的设计:

半加器和全加器:全加器是构建多位加法器的基本单元,可以处理两个加数和一个进位输入。

行波进位加法器:结构简单但速度慢,进位逐级传播。

超前进位加法器:通过并行计算进位提高速度,是高速CPU中的常用方案。

减法实现:利用补码,减法可以转换为加法,共用硬件。

ALU:通过操作选择,在同一套硬件上执行多种运算。

乘法和除法:乘法通过移位-加法实现,除法通过比较-减法-移位实现。

溢出检测:区分无符号数的进位和有符号数的溢出,采用不同的检测方法。

从加法器到ALU,我们已经构建了计算机的"算术大脑"。但一个完整的计算机不仅需要计算能力,还需要记忆能力——能够存储数据和程序。在下一章中,我们将探索计算设备从算盘到芯片的演进历程,理解存储和计算是如何结合在一起的。