从寄存器到存储器
复习
- 状态机:时序逻辑用状态和输入决定下一步动作
- 乘法器:乘法拆成移位和多次加法,并用状态机推动
- 除法器:除法拆成逐位试减和移位,并用状态机推动
TL;DR
- 把许多寄存器排在一起,再为每格编号,就得到存储阵列
- 地址说明这次访问哪一格
- 译码器选择写入位置,多路选择器选择读取位置
正文
一个 8 位寄存器能记一个数。要记 16 个数,可以摆 16 个寄存器;可如果每个寄存器都单独拉出读线、写线和开关,机器很快就会被线淹没——16 个还行,到了成千上万个,光是接线就撑不住了。
这时,那个反复出现的老办法又来了:给每一格编一个号,对外只留一组公共入口。
给格子编地址
假设先摆 4 个 8 位寄存器:
| 地址 | 保存的数据 |
|---|---|
00 | 第 0 格的 8 位数据 |
01 | 第 1 格的 8 位数据 |
10 | 第 2 格的 8 位数据 |
11 | 第 3 格的 8 位数据 |
两位地址有 4 种组合,刚好选中 4 格。一般来说,n 位地址可以区分 2ⁿ 个位置。这个“编号”就是地址(address)。
写入时只开一扇门
写入时,所有寄存器都能看到同一根公共数据线,但地址译码器只打开其中一格的写使能。因此只有被选中的那个寄存器会在时钟边沿更新,其余继续保存原值。这就像一整排柜子共用一个投递口,但每次只有一格的锁被打开。
读取时反过来:所有寄存器都把自己的内容摆到输出线上,多路选择器再根据地址,只把其中一格送到公共出口。
无论里面有 4 格还是 1024 格,对外操作都只有两种:
读:给地址 → 得到该地址的数据
写:给地址和数据 → 发出写入信号
接口始终是这么简单——内部再复杂,也可以被一组合约式的接口挡住。
这就是存储器
继续扩展行列、地址和选择电路,这排有编号的抽屉就成了真正的存储器(memory)。站在机器其他部件的角度,它只暴露几样东西:
- 地址线:打开哪个抽屉
- 数据线:放进去或拿出来的内容
- 读写控制线:这次是读还是写
要特别分清:地址不是数据本身,只是数据所在的位置。 就像“12 号抽屉”并不是抽屉里的那张纸条,它只是告诉我们去哪儿找。
临时存储与长期存储
正在运行的程序和计算中的数据,可以放进 RAM(随机存取存储器)。它能按地址反复读写,但断电后通常记不住内容——所以叫“易失”。
这又留下一个小问题:机器一断电,里面什么都没了,那下一次通电时,最初的启动指令从哪儿来?这部分内容要放进 ROM 或其他断电后仍能保存数据的存储里。这样一来,机器每次通电,都至少有第一步可走。
寄存器很快,却昂贵;存储器能保存更多数据,也为程序和中间结果提供了统一的地址。现在,会算的运算器和会记的存储器都准备好了。下一章,把它们接成一台需要人手控制、但已经能读取、计算和写回的小计算机。
思考题 1
要区分 256 个位置,地址至少需要多少位?如果每格保存 8 位,总容量是多少?
思考题 2
为什么地址译码器在写入时“只开一扇门”,而读取时却是“所有寄存器都把内容摆出来,再选一格”?这两种做法为什么不对称?
思考题 3
存储器里的比特,也可能因为干扰、器件老化等原因悄悄翻转。有什么办法能发现,甚至纠正这类错误?
小结
知识点
- 地址为多个存储位置编号
- 译码器负责写入选择,多路选择器负责读取选择
- 存储器通过地址、数据和读写控制线工作
- RAM 与非易失存储承担不同任务
参考资料
- Wikipedia(zh):随机存取存储器:RAM 的结构与特点
- Wikipedia(zh):地址译码器:把地址变成选择信号
思考题答案(仅供参考)
思考题 1
需要 8 位地址,因为 2⁸ = 256。每格保存 8 位,也就是 1 字节,因此总容量为 256 字节。
思考题 2
因为写入是“改”,必须保证只有一个位置被改动,否则多个寄存器同时写入会把数据搅乱,所以只能用译码器精确打开一格。而读取是“看”,多个寄存器同时给出内容并不会互相破坏,最后用多路选择器挑一格即可。写要独占,读可共享,这就是不对称的根源。
思考题 3
可以在数据之外附加一些冗余的校验位:写入时按约定算出校验位一起存入,读回后再按同一规则核对,就能发现出错。更进一步,海明码(Hamming code)通过巧妙安排多个校验位,不仅能发现错误,还能定位出错的位并加以纠正。它的具体编码规则涉及编码与数字电路知识,这里不展开,感兴趣的话可以自行查阅了解。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪