累加器
复习
- 给电路一个共同节拍:用时钟统一各部件交接数据的时机
- 触发器:触发器在时钟边沿保存一个比特,避免锁存器跟随输入
- 寄存器:多个触发器并排,形成能保存多位数据的寄存器
TL;DR
- 累加器保存当前结果,让多步加法连续进行
- 时序逻辑的输出同时取决于当前输入和过去状态
- 组合逻辑负责计算,寄存器负责把结果留到下一拍
正文
这一章,来完成前面一直做不到的那道题:
2 + 3 + 4
我们已经有了会算的 ALU,也有了会记的寄存器,是时候把两者接起来了。
把中间结果留在手里
准备一个寄存器,专门保存“到目前为止的和”,把它接到 ALU 的 A 端。新的加数接到 B 端,ALU 的输出再绕回寄存器的输入:
┌──────────┐
新加数 ─────>│ B 结果├────┐
│ ALU │ │
┌───>│ A │ │
│ └──────────┘ │
│ ▼
└───────────────[寄存器]
这个专门保存当前总和的寄存器,叫作累加器(accumulator)。它就像我们做竖式加法时,手边一直记着的那一栏“已算之和”。
三拍算完
先把累加器清成 0,之后每一拍送进一个加数:
| 时钟边沿 | 新加数 | ALU 计算 | 边沿后的累加器 |
|---|---|---|---|
| 第 1 拍 | 2 | 0 + 2 | 2 |
| 第 2 拍 | 3 | 2 + 3 | 5 |
| 第 3 拍 | 4 | 5 + 4 | 9 |
每个周期里,累加器稳定地提供旧结果,ALU 用它算出新结果;到下一个边沿,累加器再把新结果收进来。旧结果不会在半路消失,新结果也不会在同一拍里反复绕圈。一拍算一步,三步就得到了 9。
这正是前面缺的那块拼图:中间结果 5 终于有了安身之处,不再随着输入变化而消失。
过去开始影响现在
留意一个奇妙的现象:同样输入一个 3,累加器原来装的是 2,结果就得到 5;原来装的是 7,结果就得到 10。输出不再只看当前输入,还要看寄存器里保存的过去。
这种电路叫作时序逻辑电路(sequential logic)。相比之下,半加器、ALU 属于组合逻辑:输入相同,输出就相同,完全不管上一拍发生过什么。
可以说,从这一刻起,电路第一次有了“记忆带来的个性”——它的反应,取决于它曾经经历过什么。
还差一个自动指挥者
累加器已经能保存中间结果,但目前仍需要有人在每一拍手动更换加数。要想让机器自己完成“检查、累加、移位、继续”,它还得记住当前走到了哪一步,并据此自动决定下一步该干嘛。
下一章,我们让机器把步骤也存进寄存器。
思考题 1
为什么只把 ALU 的输出接回输入还不够,必须在反馈路径中加入寄存器?
思考题 2
累加器算
2 + 3 + 4需要三拍。如果换成先算3 + 4再算2 + 5,拍数会变吗?这说明累加器的运算顺序有什么特点?
小结
知识点
- 累加器保存并反馈当前运算结果
- 时序逻辑会受到过去状态影响
- 寄存器让反馈结果只在时钟边沿更新
参考资料
- Wikipedia(zh):累加器:累加器的历史与作用
- Wikipedia(zh):时序逻辑:输出与过去状态有关的电路
思考题答案(仅供参考)
思考题 1
如果没有寄存器,ALU 的新输出会立刻绕回输入,再次改变输出,信号可能在同一个周期里不断变化,永远稳定不下来。寄存器把结果锁到下一个时钟边沿,才把连续运算切成清楚的一步一步。
思考题 2
拍数一样,都是三拍(包括从 0 开始的那一拍)。因为累加器每一拍只做一次“旧和 + 新加数”,无论先加哪个数,都只是换了相加的先后。正常加法满足交换律和结合律,所以最终结果相同。这也提醒我们:累加器的本质,是把一串加法拆成固定节奏的若干拍。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪