本章节采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 转载请注明原始出处:https://tinysnow.github.io

算术逻辑单元

复习

  1. 第七章:设计完成了加法器,可以处理三个输入(两个加数和一个进位),并可以串联构成多位加法器
  2. 第八章:掌握了原码、反码和补码的概念,理解了补码可以统一加减法运算
  3. 第九章:设计完成了减法器,本质是加上一个负数(补码)
  4. 第十章:设计完成了乘法器,本质是多次加法,也可以用 Booth 算法等进行优化
  5. 第十一章:设计完成了除法器,本质是移位和减法的组合

TL;DR

  • 算术逻辑单元(ALU)是计算机的核心运算部件
  • ALU 可以完成算术运算(加减乘除)和逻辑运算(与或非等)
  • ALU 通过控制信号选择不同的运算功能

正文

引言

  回想一下,现在有了什么:加法,减法,乘法,除法。可以做一些基础的运算了。除此之外,还有一些逻辑操作:与,或,非,异或,移位等等。

  注意,花十秒钟想一下,上面那些东西是怎么来的。如果不能清楚明白地了解其组成和原理,说明还没有学懂,建议回头再看一次。 这里简单提示一下:

  1. 晶体管组成逻辑门(与,或,非,异或等);
  2. 部分逻辑门的计算逻辑与加法一致,所以组成加法器;
  3. 分出一位作为符号,在逻辑上弥补二进制减法的问题,使用 诱骗加法器在形式上做减法,形成减法器;
  4. 用加法器和减法器,组成乘法器和除法器,如果愿意,其中可以有移位器。

  利用上面的模块,一个简单的 ALU(Arithmetic Logic Unit,算术逻辑单元)就产生了。

设计简单 ALU

  我们可以尝试简单设计一个 8 位 ALU。

准备基本部件

添加输入(两个操作数,A 和 B)和输出(Y)

  我们注意到,加法器、减法器等等运算部件,还有一个额外的输出:溢出,所以我们也需要将它连接到输出。

连接运算电路

  现在很明显问题来了。

  1. 所有部件都在运算,我们怎么知道哪种运算是我们需要的?换而言之,我们怎么控制 ALU 做特定的运算?
  2. 对于这些运算的输出,连接到哪里?

  对于第一个问题,最简单的方法是每一种运算单独连一根线,然后根据线的通断来决定做什么运算:加法一根线,减法一根线,乘法一根线,除法一根线,等等。

思考题 1

  我们这个简单的 ALU 只有 加、减、乘、除、与、或、非、与非、或非、异或、同或 这 11 种运算,按照这个方法,就需要 11 根线。要是功能更强大的 ALU,运算种类更多,线的数量和控制运算的比特位不会突破天际吗?有什么办法能优化吗?

  对于第二个问题,最简单的方法是所有运算的输出都连接到同一根输出线上,只要控制好不要数据冲突就好了,这也是最简单的方式了。如果所有运算输出都拉到一起,仍然识别不了我们需要哪个输出。

添加选择逻辑

思考题 2

  我们此处选择了控制元件是否运算(事前控制):如果不是希望的运算,我们直接让元器件不算了。

  有没有其他控制方式?比如事后控制,先运算,运算完了再控制输出?哪种方式更好?

ALU 的工作原理

运算选择

  ALU 通过控制信号来选择执行什么运算。例如,一个简单的 4 位 ALU 的控制信号可能如下:

控制信号功能选择
000加法
001减法
010与运算
011或运算
100非运算
101异或

  这个过程使用多路选择器(我们在第五章学过)来实现:控制信号决定选择哪个运算电路的输出作为最终输出。具体实现方式参考第五章的"根据表达式拼接组合逻辑"方法:

  1. 每个运算单元的输出连接到多路选择器的不同输入通道
  2. 控制信号作为选择信号输入多路选择器
  3. 最终输出由选择信号指定的运算结果

状态标志

  ALU 在运算过程中会设置一些状态标志位,用于表示运算的特殊情况:

  • 零标志(Zero Flag):结果为零时置 1
  • 符号标志(Sign Flag):结果为负数时置 1
  • 进位标志(Carry Flag):产生进位时置 1
  • 溢出标志(Overflow Flag):结果超出表示范围时置 1

ALU 的实现细节

状态标志的生成

  1. 零标志的实现

    • 使用第五章介绍的"或非门"组合电路
    • 将所有结果位进行或运算后取反
  2. 符号标志的实现

    • 直接使用最高位的值(与第五章的符号扩展原理一致)
  3. 进位标志的实现

    • 使用加法器的进位输出(参考第六章加法器设计)
  4. 溢出标志的实现

    • 应用第五章的异或门特性(当最后两级进位不同时输出1)

ALU 的应用示例

  让我们看一个简单的例子:计算 5 + 3

  1. 数据输入:
    • 输入 A = 5(二进制 0101)
    • 输入 B = 3(二进制 0011)
  2. 控制信号:
    • 设置为 000(选择加法运算)
  3. 运算过程:
    • ALU 内部的加法器执行 0101 + 0011
  4. 输出结果:
    • 结果 = 8(二进制 1000)
    • 零标志 = 0(结果不为零)
    • 符号标志 = 0(结果为正数)
    • 进位标志 = 0(没有进位)
    • 溢出标志 = 0(结果在范围内)

ALU 的意义

  1. 集中化处理:将所有运算功能集中在一个部件中,便于控制和管理
  2. 资源共享:不同运算可以共享一些基本电路,节省硬件资源
  3. 标准化接口:为其他部件提供统一的运算服务接口
  4. 灵活性:通过控制信号可以灵活选择不同的运算功能

补充

  现代计算机中的 ALU 比我们学习的要复杂得多,可能包含流水线、并行处理等高级特性。但基本原理是相同的:通过组合各种运算电路,在控制信号的选择下完成不同的运算任务。下一章我们将学习如何把运算结果存储起来,这就要用到反馈电路了。

总结

  本章我们学习了 ALU 的基本结构、功能、设计方法和工作原理。通过设计一个简单的 ALU,我们了解了如何将运算电路和控制逻辑组合起来,实现不同的运算功能。同时,我们也学习了 ALU 的应用示例和意义,了解了 ALU 在计算机中的重要性。

思考题

  1. 什么是 ALU?它的主要功能是什么?
  2. 简述 ALU 的基本结构和工作原理。
  3. 设计一个支持加法和与运算的简单 2 位 ALU。
  4. 什么是状态标志?如何实现状态标志的生成?

实验

  1. 使用数字电路实验箱或软件模拟工具,设计和实现一个支持加法和与运算的简单 2 位 ALU。
  2. 测试 ALU 的功能,确保其能够正确执行加法和与运算。
  3. 修改 ALU 的设计,添加更多的运算功能,例如或运算和非运算。