Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

累加器

复习

  • 给电路一个共同节拍:用时钟统一各部件交接数据的时机
  • 触发器:触发器在时钟边沿保存一个比特,避免锁存器跟随输入
  • 寄存器:多个触发器并排,形成能保存多位数据的寄存器

TL;DR

  • 累加器保存当前结果,让多步加法连续进行
  • 时序逻辑的输出同时取决于当前输入和过去状态
  • 组合逻辑负责计算,寄存器负责把结果留到下一拍

正文

  这一章,来完成前面一直做不到的那道题:

2 + 3 + 4

  我们已经有了会算的 ALU,也有了会记的寄存器,是时候把两者接起来了。

把中间结果留在手里

  准备一个寄存器,专门保存“到目前为止的和”,把它接到 ALU 的 A 端。新的加数接到 B 端,ALU 的输出再绕回寄存器的输入:

             ┌──────────┐
新加数 ─────>│ B      结果├────┐
             │   ALU     │    │
        ┌───>│ A         │    │
        │    └──────────┘    │
        │                     ▼
        └───────────────[寄存器]

  这个专门保存当前总和的寄存器,叫作累加器(accumulator)。它就像我们做竖式加法时,手边一直记着的那一栏“已算之和”。

三拍算完

  先把累加器清成 0,之后每一拍送进一个加数:

时钟边沿新加数ALU 计算边沿后的累加器
第 1 拍20 + 22
第 2 拍32 + 35
第 3 拍45 + 49

  每个周期里,累加器稳定地提供旧结果,ALU 用它算出新结果;到下一个边沿,累加器再把新结果收进来。旧结果不会在半路消失,新结果也不会在同一拍里反复绕圈。一拍算一步,三步就得到了 9。

  这正是前面缺的那块拼图:中间结果 5 终于有了安身之处,不再随着输入变化而消失。

过去开始影响现在

  留意一个奇妙的现象:同样输入一个 3,累加器原来装的是 2,结果就得到 5;原来装的是 7,结果就得到 10。输出不再只看当前输入,还要看寄存器里保存的过去。

  这种电路叫作时序逻辑电路(sequential logic)。相比之下,半加器、ALU 属于组合逻辑:输入相同,输出就相同,完全不管上一拍发生过什么。

  可以说,从这一刻起,电路第一次有了“记忆带来的个性”——它的反应,取决于它曾经经历过什么。

还差一个自动指挥者

  累加器已经能保存中间结果,但目前仍需要有人在每一拍手动更换加数。要想让机器自己完成“检查、累加、移位、继续”,它还得记住当前走到了哪一步,并据此自动决定下一步该干嘛。

  下一章,我们让机器把步骤也存进寄存器。

思考题 1

  为什么只把 ALU 的输出接回输入还不够,必须在反馈路径中加入寄存器?

思考题 2

  累加器算 2 + 3 + 4 需要三拍。如果换成先算 3 + 4 再算 2 + 5,拍数会变吗?这说明累加器的运算顺序有什么特点?

小结

知识点

  • 累加器保存并反馈当前运算结果
  • 时序逻辑会受到过去状态影响
  • 寄存器让反馈结果只在时钟边沿更新

参考资料

  1. Wikipedia(zh):累加器:累加器的历史与作用
  2. Wikipedia(zh):时序逻辑:输出与过去状态有关的电路

思考题答案(仅供参考)

思考题 1

  如果没有寄存器,ALU 的新输出会立刻绕回输入,再次改变输出,信号可能在同一个周期里不断变化,永远稳定不下来。寄存器把结果锁到下一个时钟边沿,才把连续运算切成清楚的一步一步。

思考题 2

  拍数一样,都是三拍(包括从 0 开始的那一拍)。因为累加器每一拍只做一次“旧和 + 新加数”,无论先加哪个数,都只是换了相加的先后。正常加法满足交换律和结合律,所以最终结果相同。这也提醒我们:累加器的本质,是把一串加法拆成固定节奏的若干拍。

协议

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

封面图

设计师 | 南国微雪