上节中介绍的ALU进行计算后得到的结果需要对其进行存储,可能还要进行多个连续操作,这就需要用到计算机内存了。计算机使用的是随机存取存储器(Random Access Memory, RAM),其只能在有电的情况下存储东西。另一种存储称为持久存储(Persistent Memory),电源关闭时数据也不会丢失,它用来存其他东西。
这一节中首先构建能够存储1位的存储器,然后对其扩展来得到内存模块。
之前构建的都是单向电路,我们同样可以构建回向电路,把输出连回输入。

当将OR门构建成回向电路时,可以分析其电路特性
- A和B初始为0时,输出结果为0
- 将A修改为1时,输出结果为1,此时B的输入就变为了1。随后输出始终保持为1,不论A如何变化。
所以这个电路能够永久记录1,并且无法将1变回0。

同理可以分析下AND门构建成回向电路时的特点
- A和B初始化为1,则输出结果为1
- 将A修改为0时,输出结果为0,此时B的输入就变成了0。随后输入始终保持为0,无论A如何变化。
所以这个电路能够永久记录0,并且无法将0变回1。
所以我们就得到了能够存储1和0的电路,为了得到有用的Memory,需要将两个电路结合起来,可以得到AND-OR锁存器(AND-OR Latch),上方的是SET输入,下方的是RESET输入,当SET=1、RESET=0,就能将输出设置为1,当RESET=1,就能将输出设置为0,当SET=0、RESET=0,则输出最后放入的内容。由此能够存储1位的信息(该信息存储在OR门上方的输入电极中)!

技巧:当OR门其中一个输入为0,或AND门其中一个输入为1,则相当于另一个输入直接穿过这个门。当OR门其中一个输入为1,则直接输出1;当AND门其中一个门为0,则直接输出0。
这叫"锁存", 因为它"锁定"了一个值,放入数据的动作叫 "写入" ,拿出数据的动作叫 "读取"。
对其进行SET和RESET进行合并,并添加其他门控单元,可以得到一个门锁(GATE LATCH)

其中DATE INPUT表示数据输入,WRITE ENABLE表示允许写入线,用来控制是否保存当前输入的数据。对这个电路进行分析。
- 当WRITE ENABLE=1时,电路可以化简为以下形式。当数据输入为0时,AND门可以忽略OR门的输出,直接输出0,并且OR门上方电极也将保存0。当数据输入为1时,相当于忽略了AND门,OR门的输出直接和OUTPUT相连,OR门输出1,并且OR门上方电极也将保存1。所以,当WRITE ENABLE=1时,数据输入会直接传到输出,而且数据输入会保存在OR门的上方电极,进行数据存储。

2. 当WRITE ENABLE=0时,电路可化简为以下形式。此时能够忽略AND门,直接将OR门的输出当做OUTPUT,而OR门的输出其实就是上方电极的数据,由于上方电极就是当前OUTPUT的数据,所以会保持OUTPUT不变。所以,当WRITE ENABLE=0时,会忽略数据输入,保持OUTPUT不变。

可以将门锁进行抽象,得到一个能够存储一个bit的部件。当允许写入线为0时,输出保持不变,当允许写入线为1时,输出就是数据输入,并且能够将数据输入进行存储。

如果我们并排8个锁存器,就能存储8位信息。一组这样的锁存器称为寄存器(Register),寄存器能够存一个数字,这个数字的位数称为寄存器的位宽(Width)。
写入寄存器之前,要先启动里面所有的锁存器,可以将所有锁存器的允许写入线都连接在一起,把它设为1,然后用8条数据线发送数据,然后将允许写入线设回0,就能将8位数据存储在寄存器中。

但是通过这种形式排列锁存器需要太多的线路,64位寄存器需要129条线,256位寄存器需要513条线,可以通过矩阵形式排列来进行化简。我们可以构建16x16门锁矩阵(Latch Matrix),其中一共有256个,通过打开相应的行线和列线来启用某个锁存器。

局部更大的细节如下图所示。首先,只有当行列都为1时,设置WRITE ENABLE和READ ENABLE才有用,否则这两条线的经过AND门的输出始终为0。当WRITE ENABLE=1时,输入数据就会保存在门锁中。当READ ENABLE=1时,就会连通晶体管,将存储在门锁中的数据输出。这里添加了一个READ ENABLE线来控制读取,同时将输入输入和数据输出线合并,从3条线减少为2条。并且由于每次能够控制唯一一个锁存器,所以所有的数据线可以合并成一条。也就是说,对于256位存储,只需要一条数据线,一条允许写入线,一条允许读取线和16行16列的线用来选择锁存器,一共35条线。

由于16x16门锁矩阵最多16行16列,所以可以分别用4位表示行和列的地址,就能用一共8位来定位一个锁存器,比如“12行8列”可以表示为11001000。
为了将地址转换成“行和列”,需要多路复用器(Multiplexer),多路复用器可以有不同的大小。当输入一个4位数字,它就会将那根线连接到对应的输出线,比如对列地址输入0000,它就会选择第一条线,输入0001,就会选择第二条线……有一个多路复用器处理行,一个多路复用器处理列,由此通过输入行和列的坐标就能定位到对应的锁存器了。

可以对256位寄存器进行封装,它的输入是一个8位地址,4位表示行,4位表示列,同时需要允许写入线和允许读取线,然后需要一条数据线用于读写数据。(注意:每次只能选择一个锁存器,所以数据线只能读写1bit数据)

对其再进步一扩展,可以将8个256位内存拼在一起,这样就能一次读写8bit数据,也就是一个字节数据。由于每个256位内存都使用相同的8位数据线,因此8位数据会存在每个256位内存的相同地址中,并且第一个256位内存存放第一位,第二个256位内存存放第二位,以此类推。这个模块可以在256个地址中存储256个字节。(由于这种设计,所以计算机中以一个字节为寻址的最小单位)

可以对其进行抽象,看成一个整体的可寻址内存,其中有256个地址,每个地址能读写一个字节的值。

现代计算机可以在此基础上将内存扩展到MB和GB级别。我们这里使用8个16x16门锁矩阵可以得到256字节的内存,然后可以用4位表示行4位表示列来进行寻址,由此可以将门锁矩阵扩展到更大范围,但是需要更多位来表示地址。所以对于nxn门锁矩阵,存储空间为
内存的一个重要特性是:能够随时访问任何位置。所以称为随机存取寄存器(Random Access Memory, RAM)。RAM只记录当前在做什么。
RAM中存储的数据是保存在OR门其中一个电极上,所以断电后就无法保存。
这一节用锁存器做了一块静态随机存取存储器(Static Random-Access Memory,SRAM),还有很多其他类型的RAM,比如DRAM、闪存和NVRAM,它们的功能和SRAM相似,但是使用不同的电路存放单个位。但是根本上,这些技术都是矩阵层层嵌套来存储大量信息。