> For the complete documentation index, see [llms.txt](https://s2.shizhz.me/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://s2.shizhz.me/s2e4/4.md).

# 4.4. 地址：可寻址的存储单元

有了能够存储 1 Bit 数据的 DFF 后， 我们可以将多个 DFF 并起来构建出能够存储多位数据的电子元件。下图演示的是一个存储 4 Bit 数据的电子元件的构建方式：

![4 Bit Register](/files/-MdWOvjAQ52sv0Fm252y)

我们增加了一个开关引脚叫 Write, 当要写入数据时才将该线路设置为 1, Write 信号与时钟信号一起通过一个 AND 门来共同控制数据的写入，不考虑电路内部实现，该电路图可以简化为：

![4 Bit Register](/files/-MdWPBNo6Z9Au9Jjl7Mn)

我们将该组件的输入信号分为两类：数据信号（DI0 到 DI3）与控制信号（Write 与 CLK）。

该电子元件是构成寄存器或内存芯片的基础组件。而 CPU 中包含多个寄存器，内存的存储容量则更大，因此当 CPU 存取数据时，必须指定寄存器或者内存的具体位置，也就是说 CPU 除了提供数据信号与控制信号之外，还需要提供地址信号。而上图的电子元件的输入中并不包含地址信号。

因此我们最好重新设计存储多位数据的电子元件，让其也能接受地址信号作为输入。

现在我们有了能够存储 4 Bit 的电子组件，假设想要存储 16 Bit 的话需要 4 个该组件，我们可以将 4 个组件中的 16 个 DFF 看成一个 4 X 4 的矩阵，如果将每 4 Bit 看着一个数据单元的话，那么存储一个数据单元的方式有两种，如下图所示：

![4x4 Bit Matrix](/files/-MdWPThpzDygjrmYYf1y)

如果使用蓝色方框的存储方式，那么我们需要单独设计寻址电路来定位每个4位寄存器，因为将地址信号作为每个组件的输入是无意义的，每个4位寄存器就是一个独立的存储单元。

红色方框这种存储方式也满足需求，但对于每个数据单元，每个组件仅贡献了 1 Bit 的存储能力，因此我们需要某种机制，能够使我们从寄存器的 4 Bit 中筛选出任意一位进行操作。下图中我们将所存放的 4 个数据单元按照二进制依次编号：

![](/files/-MdWQ1pnaOLUI7kX1H8T)

事实上，这两位数字编号代表的便是一个组件内部各个 DFF 的地址，在每次进行读写操作时，我们都需要将该地址作为输入传入寄存器，以便筛选出对应的 DFF。对于二进制而言，n 位地址能够寻址的范围是 \[0, 2^n), 因此上图中每个组件需要 2 个输入引脚作为地址信号。不考虑内部实现，加入地址引脚的组件如下图所示：

![](/files/-MdWQIOFAqW_dfGMFF9j)

注意：此时输入、输出引脚都变成了一位，因为现在每次只会操作组件内部的一位数据，具体是哪一位数据通过 Addr 引脚来指定。同时我们将 Write 引脚改为了 R/W, 该位为 1 时用以写入数据，为 0 时用以读取数据。

现在我们来讨论如何利用地址信号来选择组件内部的目标位置。

在写入端，如果我们能够将 Write 信号仅仅“路由”到目标 DFF 中，而将其它三个 DFF 的 Write 位保持为 0 的话, 就能顺利完成写入操作。以本文中的 2 位地址为例，该“路由电路”的示意图如下：

![2-4 Decoder](/files/-MdWQbBDFPijLCdsIHRH)

当输入信号 DI 为 1 时，该电路的真值表为：

| Addr0 | Addr1 | DO0 | DO1 | DO2 | DO3 |
| ----- | ----- | --- | --- | --- | --- |
| 0     | 0     | 1   | 0   | 0   | 0   |
| 0     | 1     | 0   | 1   | 0   | 0   |
| 1     | 0     | 0   | 0   | 1   | 0   |
| 1     | 1     | 0   | 0   | 0   | 1   |

该电路叫着 Decoder, 上图是一个 2-4 Decoder, Decoder 电路可以使用与门与非门构建，例如下图是一个 2-4 Decoder 的电路图：

![2-4 Decoder Impl](/files/-MdWQjnu3ztqqOwPD4xZ)

在读取端，我们需要根据地址信号选择目标 DFF 的输出信号，该电路是 Decoder 的一个逆向操作，以本文的 2 位地址为例，该电路示意图如下：

![4-1 Selector](/files/-MdWQsxN1Yi533JPq1pp)

该电路的输出信号与输入信号的关系为：

| Addr0 | Addr1 | DO  |
| ----- | ----- | --- |
| 0     | 0     | DI0 |
| 0     | 1     | DI1 |
| 1     | 0     | DI2 |
| 1     | 1     | DI3 |

该电路叫着 Selector, 上图是一个 4-1 Selector, 可以通过如下方式实现（三个输入引脚的与门可以通过串联两个与门实现）：

![4-1 Selector Impl](/files/-MdWR-J1uUC8v3TeN1uF)

有了 Decoder 与 Selector, 我们就可以设计出一个带地址引脚、拥有 4 Bit 空间的基础存储组件了，如下图所示：

![Addressable 4 Bit Register](/files/-MdWR6H6i-ZQbr1WZSFY)

该组件是构建大容量存储芯片的基础积木，寄存器、内存都可以基于该组件组装出来。
