Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

算术逻辑单元

复习

  1. 第十一章:设计完成了全加器,可以串联构成多位加法器
  2. 第十二、十三章:掌握了原码、反码和补码,理解了补码可以统一加减法
  3. 第十四~十六章:设计完成了减法器、乘法器、除法器

TL;DR

  • 算术逻辑单元(ALU)是计算机的核心运算部件
  • 它把加减乘除和与或非等运算都集成在一起
  • 用一组“操作码“选择当前要做哪种运算,再用译码器把它翻译成控制信号

正文

引言

  到这里,我们手里已经有加法、减法、乘法、除法,还有与、或、非、异或、移位等逻辑操作。它们个个都能独立工作,但要真正用来算题,我们总不能让数据在十几个部件之间手动转来转去吧?

  我们需要一个统一的地方,把这些运算装在一起,需要哪个就用哪个。它就叫 ALU(Arithmetic Logic Unit,算术逻辑单元)

  特别说明:乘法器和除法器不太懂也没关系,因为在简单的 ALU 中,压根儿就没有这种东西。乘法就是多次加法,除法就是多次减法。

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

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

设计简单 ALU

  我们试着设计一个 4 位 ALU,它支持 12 种功能:加、减、乘、除、取余、与、或、非、与非、或非、异或、同或。

准备基本部件

  先列出需要的部件,同时列出各自的输入和输出。

  注意:

  1. 因为非门只有一个输入,所以此处硬编码为 A 引脚,需要取反的数值应该永远连接到 A 输入上。
  2. 加法器、减法器等等运算部件,还有一个额外的输出:溢出,所以我们也需要将它连接到输出。但因为连接这些溢出输出会使电路变得复杂,所以我们暂时不考虑连接(溢出标志会在下一章细讲)。

连接运算电路

  很快,两个问题冒了出来:

  1. 这些运算的输出,都接到哪里去?
  2. 所有部件都在同时运算,我们怎么控制 ALU 只输出我们需要的那一个?
第一个问题:输出接哪儿

  最简单的办法:所有运算的输出都接到同一根输出线上,只要保证同一时刻只有一个结果在上面就好。

  为此,我们需要一个控制开关:由一根 Enable 信号决定“这个结果要不要送出去“。

  它的构造简单到可爱——画个真值表就会发现,它就是一个与门

输入 Data控制信号 Enable输出
000
010
100
111

  对多位数据,就是位宽个与门并排(4 位 4 个,8 位 8 个),每个与门管一位。

  加上控制开关,ALU 大概是这样:

第二个问题:怎么选择运算

  最直接的办法:每种运算单独连一根线,线的通断决定做哪种运算——加法一根、减法一根……但这样,12 种运算就要 12 根线。功能一多,线的数量就爆炸。

  停一下。每根线只有“通/断“两种状态,这……不就是二进制吗?

  如果我们把这些线的通断编码成二进制数,线的数量就能大幅压缩。12 种运算,只需要 4 根线就够了:2³(8) < 12 < 2⁴(16)

添加选择逻辑

  用 4 根线表示 12 种运算,我们这样规定:

控制信号功能
0000加法
0001减法
0010乘法
0011除法
0100取余
0101
0110
0111
1000与非
1001或非
1010异或
1011同或

  恭喜你!我们已经在初步接触**“指令”**的概念了——上面这串控制信号,就是告诉 ALU“做什么运算“的指令。

  那么,怎么把指令翻译成“选中某一根线“呢?用一个译码器(Decoder)。它的作用,就是把输入的二进制码翻译成特定的信号。看图就懂:

  把操作码(op_code)送进译码器,译码器就点亮对应的那一路运算,其余全部关闭。

  ALU 就完成了。

验证 ALU

  来验证一下:设 A = 4(0100),B = 2(0010),按操作码依次计算结果(加法对应 0000,减法对应 0001……):

加法减法乘法除法取余与非或非异或同或
011000101000001000000000011010111111100101101001

  把这个电路改造一下,让操作码自增,依次观察结果:

  结果正确。

思考题

  我们用“操作码 + 译码器“来选择运算。如果有一天 ALU 要支持的功能从 12 种增加到 20 种,操作码需要几根线?如果增加到 40 种呢?这说明了什么?

小结

知识点

  • ALU 的组成
  • 用控制开关(与门)决定结果是否输出
  • 用操作码 + 译码器选择运算
  • “指令“概念的初步接触

参考资料

  1. Wikipedia(zh):算术逻辑单元:详细的算术逻辑单元介绍

推荐

思考题答案(仅供参考)

  20 种功能需要 5 根线(2⁴=16 < 20 < 32=2⁵),40 种需要 6 根线。功能数量每次翻倍,只需要多加一根线——这就是二进制编码的威力。反过来说,如果不用编码、一种运算一根线,线数会跟着功能数线性、甚至爆炸式增长。用编码换线数,是数字设计里非常典型的一招。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪