第 18 章 存储器基础
1. 本章要解决的问题
第 17 章使用独立寄存器保存 \(R_A\)、\(R_B\)、\(R_C\)、临时结果和最终结果。数据只有几项时,这种画法清楚。若系统需要保存 1024 个 32 bit 数据,为每个数据单独画寄存器、写使能和输出 MUX,会得到庞大的重复结构。
存储器把这些重复结构组织成规则阵列,并用地址选择其中一个或若干个存储字。使用者不必直接控制每一只存储单元,只需给出:
- 要访问哪个位置;
- 读还是写;
- 写入什么数据;
- 何时请求,何时读取结果。
本章回答九个问题:
- 存储深度、字宽、地址位数和容量怎样换算?
- 地址怎样经过译码器选择阵列中的一行?
- ROM、RAM、SRAM、DRAM 和寄存器文件分别解决什么问题?
- 6T SRAM 单元怎样依靠反馈保存一位?
- SRAM 的读写为什么需要字线、位线、预充电和感应放大?
- 1T1C DRAM 单元为什么需要刷新,读出后为什么要恢复?
- 多端口寄存器文件怎样同时提供多个操作数?
- 异步读、同步读、同步写和读写冲突应怎样理解?
- 控制器怎样把存储器接入数据通路并满足接口时序?
2. 与第 17 章的联系
存储器仍然属于数据通路。控制器发出地址、写使能和读请求,存储器返回读数据或完成状态。二者关系没有改变,只是数据通路中的“许多独立寄存器 + 大量选择器”被规则阵列替代。
在寄存器传输写法中,可以把
R_T ← R_A
推广为
Memory[write_addr] ← write_data
read_data ← Memory[read_addr]
第一句表示写入选中地址,第二句表示读出选中地址。它们究竟在时钟边沿执行还是经过组合延迟响应,由存储器接口规格决定,不能只凭“Memory”这个名字猜测。
3. 前置知识快速检查
- 一个 \(A\) bit 二进制编号最多能区分多少个位置?
- 3 线—8 线译码器在使能有效时会选中几路输出?
- D 锁存器和 D 触发器分别怎样保存状态?
- MUX 在数据通路中解决什么问题?
- 同步写入时,地址、数据和写使能要满足哪个边沿附近的时序要求?
答案是:\(2^A\) 个;8 路中选中 1 路;锁存器在透明期跟随、保持期保存,触发器在有效边沿采样;从多路候选数据中选择一路;写入有效边沿的建立与保持要求。若第 1、2、4 题不熟,回看第 6、8 章;若第 3、5 题不熟,回看第 11、12、14 章。
4. 学习目标
完成本章后,你应能够:
- 解释“深度 × 字宽”的存储器规格;
- 计算容量、地址位数和未使用地址数量;
- 从地址译码、字线、位线和列选择理解存储阵列;
- 区分 ROM 与可写 RAM 的功能接口;
- 从交叉耦合反馈解释 6T SRAM 的保持;
- 按保持、读出和写入三个阶段解释 SRAM 单元;
- 从电荷存储解释 DRAM 的读出、恢复与刷新;
- 说明寄存器文件为何常具有多读端口和写端口;
- 读取异步读、同步读和同步写的基础时序;
- 为同地址读写冲突规定明确行为;
- 根据容量、端口、延迟、密度和刷新要求选择基础存储结构;
- 把存储器接口接入第 17 章的控制器与数据通路。
5. 存储器的外部抽象
先不看内部晶体管,把一个存储器当作带编号抽屉的模块。地址(address)是抽屉编号,一个抽屉中的多 bit 数据称为一个字(word)。常见接口包括:
addr[A-1:0]:地址;wdata[W-1:0]:待写数据;rdata[W-1:0]:读出数据;we:高有效写使能;re或oe:读使能或输出使能;cs:片选或模块使能;clk:同步接口使用的时钟。
图 18-1 中地址不是数据内容,它只选择位置;wdata 与
rdata
才承载一个完整字。读口和写口可以分开,也可以共用一组双向引脚,具体由接口定义。
图 18-1 地址选择存储位置,数据端承载字内容,控制端规定本次访问是读、写还是禁用
立即检查
一个 256 × 16 存储器中,256 与
16 分别表示什么?
它有 256 个可寻址字,每个字 16 bit。地址选择 256 个位置之一,读写数据宽度为 16 bit。
6. 深度、字宽、地址位数与容量
存储器常写作
\[ D\times W\ \text{bit}, \]
其中:
- \(D\) 是深度(depth),表示可寻址字的数量;
- \(W\) 是字宽(word width),表示每个字包含的 bit 数;
- 总容量为
\[ C_{bit}=D\cdot W. \]
若每个地址对应一个完整字,所需最小地址位数为
\[ A=\lceil\log_2D\rceil. \]
若 \(D=2^A\),全部地址编码都有效。若 \(D\) 不是 2 的幂,\(A\) bit 仍能产生 \(2^A\) 个编码,多出的地址必须在接口中定义为无效、保留或映射到其他功能。
bit、byte、KiB 不要混写
1 byte = 8 bit。二进制容量单位通常采用:
1 KiB = 1024 byte
1 MiB = 1024 KiB
芯片手册也可能用 K 表示 1024
个字或其他行业约定,阅读时必须看完整规格,而不是只看字母。
例题 1:计算
1024 × 32 bit
深度 \(D=1024=2^{10}\),所以地址需要 10 bit。总容量为
\[ C_{bit}=1024\times32=32768\ \text{bit}. \]
换成 byte:
\[ C_{byte}=32768/8=4096\ \text{byte}=4\ \text{KiB}. \]
数据端宽度为 32 bit,即每个地址读写 4 byte。
变式: 512 × 64 bit 的总容量同样是
32768 bit,也是 4 KiB,但地址只需 9 bit,单次访问字宽为 64 bit。
例题 2:非 2 的幂深度
一个 24 × 8 bit 存储器需要
\[ A=\lceil\log_2 24\rceil=5 \]
个地址位。5 bit 可表示 32 个编码,因此有 \(32-24=8\) 个未使用地址。总有效容量为
\[ 24\times8=192\ \text{bit}=24\ \text{byte}. \]
地址 24~31
的读写行为必须由接口规定,例如读回 0 并忽略写入,或报告地址错误。
变式: 深度 17 仍需要 5 bit 地址,会留下 15 个未使用编码。
7. 从地址到选中一行
一个规则存储阵列可以看成 \(D\) 行、\(W\) 列:
- 每一行保存一个 \(W\) bit 字;
- 每一列对应字中的一个 bit 位置;
- 行译码器把 \(A\) bit 地址变成一条独热字线(word line, WL);
- 位线(bit line, BL)沿列传送读写信息;
- 较大阵列还会加入列选择、分块译码和局部/全局位线。
图 18-2 使用 4 × 4 bit 阵列展示最基本关系。地址
10 经过 2 线—4 线译码器,只令 WL2
有效,因此访问第 2 行的 4 个单元。列电路同时得到一个 4 bit 字。
图 18-2 地址译码选择一条字线,同一行的多个存储单元共同组成一个可寻址字
真实大容量存储器不会只使用一条巨长字线和位线。阵列会分块,以控制电容、延迟、能耗与版图尺寸。本章先保留“地址—译码—行—列—数据口”这条基础主线。
8. 读操作与写操作的共同语言
读
读操作把所选地址中的已有内容送到
rdata。根据接口,读出可能是:
- 地址变化后经过访问时间直接变化的异步读;
- 在时钟边沿接受地址,经过规定周期数后给出结果的同步读。
写
写操作把 wdata 存入所选地址。同步写常写作:
在 CLK 上升沿,若 cs=1 且 we=1:Memory[addr] ← wdata
地址、数据和写使能都要在该边沿满足存储器宏或寄存器阵列规定的建立与保持要求。
禁用
cs=0 或输出未使能时,模块可能保持输出、输出
0、输出高阻或不承诺数据。不同器件和宏单元行为不同,系统设计必须按接口规格使用。
9. ROM:地址到固定数据的映射
只读存储器(read-only memory, ROM)在正常系统运行中主要提供读取。功能上,它实现
\[ rdata=F(addr), \]
也就是地址到固定数据字的组合映射。它可用于:
- 固定查找表;
- 启动代码或常量表;
- 字符、波形或控制序列;
- 复杂组合函数的表格实现。
“只读”描述正常接口权限,不等于所有 ROM 在制造后都永远不可改变。掩模 ROM、一次可编程存储、Flash/EEPROM 和用组合逻辑综合出的常量表,写入或配置机制不同,但都可在系统读取侧表现为 ROM。
例题 3:用 ROM 实现平方查找表
设计一个输入 \(x[2:0]\)、输出 \(y[5:0]\) 的查找表,保存 \(y=x^2\):
| 地址 \(x\) | 十进制 | ROM 数据 \(y\) | 十进制 |
|---|---|---|---|
000 |
0 | 000000 |
0 |
001 |
1 | 000001 |
1 |
010 |
2 | 000100 |
4 |
011 |
3 | 001001 |
9 |
100 |
4 | 010000 |
16 |
101 |
5 | 011001 |
25 |
110 |
6 | 100100 |
36 |
111 |
7 | 110001 |
49 |
需要 8 × 6 bit ROM,共 48
bit。地址直接选择一行,输出对应平方值。
图 18-3 把真值表、行译码和固定连接放在同一条阅读路径上。黑点表示该地址行在对应输出列存储 1;无点位置表示 0。具体 ROM 工艺可能用不同物理极性,图中只表达逻辑映射。
图 18-3 ROM 用地址选择固定数据行,规则阵列能够直接实现查找表函数
变式: 若只保留 \(x^2\) 的低 4 bit,ROM 变为
8 × 4 bit,但 \(x=4\) 和
\(x=0\)
等输入可能得到相同低位结果。
10. RAM:运行时可以读写
随机存取存储器(random-access memory, RAM)允许在正常运行中按地址读写。这里的“随机存取”表示访问某个位置不必依次经过前面位置,和软件中的随机数没有关系。
RAM 的两类基础实现是:
- SRAM:用双稳态反馈单元保存状态,只要供电存在且不被改写,就能维持数据;
- DRAM:用电容电荷表示数据,电荷会泄漏,需要周期性刷新。
二者可以具有相似的逻辑读写接口,但内部单元、读出方法、密度、延迟与控制要求不同。
11. 6T SRAM 单元:反馈保存一位
典型 6T SRAM 单元由六只 MOSFET 组成:
- 两个交叉耦合 CMOS 反相器,共 4 只晶体管,形成双稳态节点 \(Q\) 与 \(\overline Q\);
- 两只访问 NMOS,由同一条字线
WL控制,把 \(Q\)、\(\overline Q\) 分别接到互补位线BL、BLB。
这与第 11 章的双稳态完全同源。区别是 SRAM 单元被排成高密度阵列,并围绕它加入字线驱动、位线预充电、写驱动和感应放大器。
图 18-4 左侧画逻辑结构,右侧分三步说明保持、读和写。WL=0
时访问管关断,交叉耦合反相器维持状态;WL=1
时单元连接到位线,执行读或写。
图 18-4 6T SRAM 用交叉耦合反相器保存状态,两只访问管在字线有效时接通互补位线
“静态”表示无需像 DRAM 那样定期刷新,不表示断电后仍保留,也不表示没有静态漏电功耗。
12. SRAM 读操作
基础读过程可按四步理解:
- 预充电:把
BL与BLB预充到规定电平并使二者接近相等; - 选择字线:地址译码令目标
WL有效; - 产生微小差分:存储 0 的内部节点通过访问管使对应位线轻微放电,另一条位线保持较高;
- 感应放大:感应放大器(sense amplifier)检测
BL与BLB的小电压差并恢复成完整逻辑值。
位线连接许多单元,电容较大。若等待某个单元把整条位线拉到电源轨,读出会很慢;差分感应允许在较小摆幅时判断数据。
读操作必须保持单元稳定。若访问管和下拉网络尺寸关系不合适,预充位线可能在读取 0 时把内部低节点抬得过高,造成读扰动。实际 6T 单元通过器件尺寸、字线/位线条件和感应时序共同保证读稳定性。
13. SRAM 写操作
写入时,写驱动器主动把互补位线置为目标值:
- 写 \(Q=1\):驱动
BL=1、BLB=0; - 写 \(Q=0\):驱动
BL=0、BLB=1。
随后拉高
WL,位线驱动必须足以改变交叉耦合单元的原状态。状态翻转后,关闭字线,反馈继续保持新值。
读稳定性希望单元内部反馈足够强,写入能力又希望外部位线能够推翻旧状态。6T SRAM 的器件比例和工作条件需要同时兼顾读、写、保持和面积。本章只建立这个约束方向,不展开单元尺寸优化与统计良率设计。
14. SRAM 阵列的外围电路
一个可用 SRAM 宏远不止存储单元阵列,还包括:
- 行译码器与字线驱动器;
- 位线预充电与均衡电路;
- 写驱动器;
- 感应放大器;
- 列选择与数据输入输出电路;
- 时钟、使能与内部控制;
- 冗余修复、测试与电源管理等实现结构。
因此“容量为 \(D\times W\) bit”只统计有效数据位,不代表芯片只包含 \(D\times W\) 个晶体管或单元。外围电路会带来面积、延迟和功耗开销,小阵列中外围占比尤其明显。
15. DRAM:用电容电荷保存一位
典型 1T1C DRAM 单元由一只访问晶体管和一只存储电容组成:
- 字线
WL控制访问晶体管; - 位线
BL通过访问管连接存储电容; - 电容中较多或较少的电荷表示逻辑状态。
单元器件少,适合实现高密度大容量存储。电容电荷会因漏电逐渐变化,所以数据必须在规定时间内刷新(refresh)。
读出为何需要恢复
读之前,位线被预充到参考电平。字线打开后,存储电容与大位线电容发生电荷共享,只产生很小的电压偏差。感应放大器检测并放大该偏差,同时把完整电平写回单元。
这次读出改变了原存储电容的电荷状态,因此 DRAM 读常称为破坏性读出;感应放大过程必须完成恢复。
图 18-5 依次画出保持、读出/恢复和刷新。刷新并不需要外部逐位读写数据,DRAM 控制器按行激活并让感应放大器恢复整行。
图 18-5 1T1C DRAM 以电容电荷保存信息,读出依靠电荷共享与感应恢复,漏电要求周期刷新
例题 4:计算平均刷新节奏
题设某教学用 DRAM 阵列有 8192 行,要求在 64 ms 内完成全部行刷新。若均匀安排,平均每次行刷新之间的时间为
\[ t_{row}=\frac{64\ \text{ms}}{8192}=7.8125\ \mu\text{s}. \]
这表示控制器平均每约 \(7.8125\ \mu\)s 安排一次行刷新。实际 DRAM 的刷新命令、分组方式、温度要求和忙碌占用由具体器件标准与手册规定,本题数值只用于理解“总刷新窗口如何分摊到各行”。
变式: 若相同行数要求在 32 ms 内刷新完,平均间隔减半为 \(3.90625\ \mu\)s。
16. SRAM 与 DRAM 的基础比较
| 项目 | SRAM | DRAM |
|---|---|---|
| 典型单元 | 6T 双稳态单元 | 1T1C 电荷单元 |
| 保持方式 | 有电时由反馈维持 | 电容电荷,需刷新 |
| 读出 | 差分位线与感应,单元应保持状态 | 电荷共享与感应,读后恢复 |
| 单元密度 | 较低 | 较高 |
| 控制复杂度 | 相对直接 | 行激活、预充电、刷新更复杂 |
| 常见用途 | 片上缓存、小型高速存储 | 大容量主存及高密度存储 |
“SRAM 一定更快”或“DRAM 一定更省电”都缺少完整条件。容量、工艺、阵列尺寸、端口、接口协议、待机模式和访问模式都会影响最终指标。基础选择先抓住:SRAM 用反馈换速度与直接访问,DRAM 用电荷单元换密度并承担刷新与复杂控制。
17. 寄存器文件:按编号访问一组寄存器
寄存器文件(register file)把若干个等宽寄存器组织成可寻址阵列。它的容量通常不如 SRAM/DRAM 大,但常提供多个端口,以便数据通路在同一周期读取多个操作数并写回一个结果。
典型 2R1W 寄存器文件具有:
- 两个独立读地址
raddr_a、raddr_b; - 两个读数据
rdata_a、rdata_b; - 一个写地址
waddr; - 一个写数据
wdata; - 一个写使能
we; - 一个写时钟
clk。
两个读口能够在同一周期选择两个不同地址,也可以读取同一地址。写口在规定边沿更新一个字。图 18-6 上半部分显示端口结构,下半部分展示同步写与组合读的一种接口时序。
图 18-6 2R1W 寄存器文件用两套读选择网络并行提供操作数,在写边沿更新选中的一个字
多端口不是免费的。每增加一个独立端口,存储单元、位线、译码、选择和布线都更复杂。实际寄存器文件可能使用多端口位单元、复制阵列、分银行或时间复用等方法。
18. 读端口可以是异步的,也可以是同步的
异步读
也称组合读。地址稳定后,rdata
经过地址译码、阵列和输出选择的访问延迟变为对应数据。它不需要等待时钟边沿,但输出可能在地址转换期间出现暂态。
可用访问时间表示:
\[ t_{valid}\ge t_{addr\_stable}+t_{AA}, \]
其中 \(t_{AA}\) 是从地址稳定到数据保证有效的最大访问时间。
若还受输出使能控制,则输出有效时刻要满足所有相关条件:
\[ t_{valid}\ge\max(t_{addr\_stable}+t_{AA},\ t_{oe\_active}+t_{OE}). \]
同步读
存储器在有效时钟边沿接受读地址或读请求,经过规定的一个或多个周期后输出数据。同步接口把访问放在明确的周期边界上,便于流水化大阵列,但增加可见读延迟。
“SRAM 就是异步读”不成立。SRAM 描述单元技术;异步/同步描述外部接口时序。一个 SRAM 宏可以提供同步读接口,一个触发器阵列也可以做组合读。
例题 5:异步读最晚有效时刻
某教学用异步存储接口规定:
- 地址在 20 ps 时稳定,\(t_{AA}=450\) ps;
oe在 300 ps 时有效,\(t_{OE}=180\) ps;- 其他使能已提前满足。
地址路径给出的最晚时刻为
\[ 20+450=470\ \text{ps}. \]
输出使能路径给出的最晚时刻为
\[ 300+180=480\ \text{ps}. \]
两项都满足后数据才保证有效,因此
\[ t_{valid}=\max(470,480)=480\ \text{ps}. \]
变式: 若 oe 在 100 ps
已有效,则输出由地址路径限制,最晚在 470 ps 有效。
19. 同步写时序
同步写接口可抽象为:
\[ M^{+}[addr]= \begin{cases} wdata, & cs=1\text{ 且 }we=1,\\ M[addr], & \text{否则}. \end{cases} \]
该更新发生在规定有效边沿。写地址、写数据、cs 和
we
都是捕获寄存器或内部写控制要采样的输入,因此要满足建立与保持时间。
若写地址在边沿附近违例,问题不只是“数据可能写错一位”,还可能选错字或使内部译码进入不可靠状态。存储器宏的时序模型会分别规定地址、数据和控制端的约束。
20. 同地址读写冲突必须写进规格
若同一周期读地址与写地址相同,读口看到什么?常见策略包括:
- 读旧值(read-first):本次读返回写入前内容;
- 读新值(write-first):本次读返回正在写入的新数据;
- 保持输出(no-change):读输出保持之前的值;
- 未定义/不允许:接口不承诺本次读数据。
这些名称在不同工具或厂商资料中可能有具体定义,使用时以目标存储器宏为准。系统若依赖“写后立即读新值”,可以增加旁路(bypass):检测
we && waddr==raddr 时,直接把 wdata
送到读输出。
例题 6:2R1W 寄存器文件的同址访问
初始 R3=0x25。某上升沿前:
we=1,waddr=3,wdata=0xA7
raddr_a=3,raddr_b=5
写边沿后 R3 一定更新为 0xA7。读口 A
在边沿附近看到什么,取决于接口:
- write-first 或显式旁路:读 A 返回
0xA7; - read-first:本次关联读取可能返回旧值
0x25,随后组合读更新为新值; - 未定义策略:冲突窗口内不能使用读 A。
读口 B 访问地址 5,不受本次写地址 3 的同址冲突影响。
变式: 若
we=0,没有写入,两个读口都按各自地址返回原内容。
21. 字节写使能与部分写入
较宽存储字常允许只更新其中一部分。例如 32 bit 字分成 4 个 byte
lane,控制 be[3:0] 分别决定每个 8 bit 字节是否写入:
be[0]=1:更新 wdata[7:0]
be[1]=1:更新 wdata[15:8]
be[2]=1:更新 wdata[23:16]
be[3]=1:更新 wdata[31:24]
未使能字节保持旧值。部分写需要阵列支持独立列写使能,或先读旧字、合并后再写。接口必须明确字节顺序与地址含义,避免把最低地址字节和最高有效字节混为一谈。
22. 地址是字地址还是字节地址
在一个 256 × 32 bit 存储器宏中,若每个地址选择一个 32
bit 字,地址范围是 0~255,需要 8 bit,这称为字寻址。
在处理器常见的字节寻址空间中,每个地址编号一个 byte。同一个 32 bit 字覆盖 4 个连续字节地址,低 2 位可选择字内 byte,高位选择存储字。两种接口都合理,必须在规格中明确。
容量计算相同,地址解释不同。看到 addr[7:0]
时,先问“一个地址对应多少 bit”,再判断可覆盖多少 byte。
23. 存储器怎样接入控制器与数据通路
一个基础读事务可以分成:
- 控制器在
READ_REQ状态给出地址并拉高读使能; - 异步存储器等待访问时间,或同步存储器等待规定周期;
- 存储器给出
rdata,必要时返回ready/valid; - 控制器在
READ_CAPTURE状态使目标寄存器装载; - 进入下一控制状态。
写事务则由控制器同时准备地址、数据与
we,在指定边沿或握手完成时提交。
若存储器固定一周期响应,控制器可以使用固定状态序列;若延迟可变,就要等待
ready,并在等待期间保持地址、数据和请求满足接口要求。不能用“通常一拍完成”的经验替代明确协议。
24. 存储器访问也是时序路径
异步读接入同步数据通路时,常见建立路径为:
地址寄存器 Q → 地址译码/阵列/感应/输出 → 数据寄存器 D
它必须满足第 14、15 章的建立与保持约束。存储器访问时间可能成为关键路径。
同步读宏内部已经设置地址寄存器或输出寄存器,但外部仍要检查:
- 发出地址和控制的寄存器到存储器输入;
- 存储器输出到下游捕获寄存器;
- 时钟偏斜与不确定性;
- 宏模型规定的读延迟与输出时序。
写路径还要检查地址、写数据和写使能是否同时满足存储器输入约束。
25. 选学:为什么大存储器要分银行
把全部单元放在一条超长字线和位线上,会增加电阻、电容、传播延迟和开关能量。分银行(banking)把大阵列拆成多个较小子阵列:
- 高位地址选择银行;
- 低位地址选择银行内部的行列;
- 局部位线较短;
- 不同银行在接口允许时可交错访问。
分银行增加银行选择、全局布线与控制,也引入同银行冲突等调度问题。基础学习只需理解:规则阵列仍要通过层次化组织控制物理线长和并行度。
26. 怎样选择基础存储结构
按问题逐项判断:
- 数据是否需要运行时修改? 固定表可用 ROM,可修改数据需要 RAM 或寄存器;
- 容量多大? 少量控制状态适合触发器,大容量更适合规则阵列;
- 需要几个并行端口? 多操作数读取常用寄存器文件或多端口存储;
- 读写延迟和吞吐率是多少? 明确异步/同步、周期数和可连续访问节奏;
- 数据需要断电保留吗? 本章 SRAM/DRAM 都是易失性存储;
- 是否能承担刷新? DRAM 需要刷新控制与访问调度;
- 目标技术是什么? ASIC 存储宏、FPGA 块 RAM 与触发器阵列的可用结构不同;
- 同址读写行为是什么? 提前定义旧值、新值、保持或禁止;
- 位宽和写掩码怎样组织? 明确字地址、字节地址与部分写。
27. 常见误区与反例
误区 1:地址位数等于存储数据位数
地址位数决定能选多少个字,数据位数决定每个字多宽。1024 × 32 bit
使用 10 bit 地址和 32 bit 数据。
误区
2:1024 × 32 bit 的容量是 1024 byte
它共有 32768 bit,即 4096 byte。深度不能直接当作 byte 容量。
误区 3:5 bit 地址一定表示 32 个有效字
5 bit 能产生 32 个编码,但模块可能只实现其中 24 个。未使用地址需要接口定义。
误区 4:ROM 是一种固定的晶体管电路
ROM 是读取侧的功能抽象,可由掩模连接、可编程器件或综合逻辑实现。
误区 5:SRAM 的“静态”表示断电保持
SRAM 是易失性存储。静态表示有电时无需周期刷新,断电后数据丢失。
误区 6:6T SRAM 读出就是把 \(Q\) 直接接到输出
阵列读出通常通过预充位线、微小差分和感应放大完成。位线负载与读稳定性是核心条件。
误区 7:DRAM 只要读取,不必恢复
读出发生电荷共享,会扰动存储电容;感应放大器必须把完整数据恢复回单元。
误区 8:刷新等于把全部数据重新从外部写一遍
刷新由内部行激活和感应恢复完成,不要求外部提供每个数据字。
误区 9:SRAM 一定异步读,寄存器文件一定组合读
单元技术与接口时序是两个层次。任何模块都要按实际端口协议判断读延迟。
误区 10:同一地址同时读写自然返回新值
读旧值、读新值、保持或未定义都可能成立。必须按宏规格或旁路逻辑确定。
误区 11:增加读端口只是多复制一组输出线
独立端口需要额外选择、位线、单元连接和布线,面积、功耗与时序都会变化。
误区 12:存储器宏可以跳过时序分析
地址、数据、控制和输出仍位于同步路径中。宏的时序模型必须参与建立、保持和访问延迟分析。
28. 工程中的实际意义
存储器经常占据数字芯片的大部分晶体管和面积。规则阵列让设计能够保存远多于独立寄存器的数据,但同时引入新的物理与接口问题:
- 长字线、位线带来延迟与动态能耗;
- 小信号读出需要感应放大;
- 写入要克服存储单元原状态;
- 多端口增加单元和布线复杂度;
- DRAM 需要刷新与行管理;
- 存储宏的 PVT 表征进入静态时序分析;
- 制造缺陷需要测试、冗余和修复。
在 RTL 设计中,数组写法可能被综合成触发器、寄存器文件、FPGA 块 RAM 或 ASIC 存储宏。代码相似,不代表最终硬件相同。第 19 章会从“代码对应什么硬件”出发,学习怎样表达组合逻辑、寄存器和基础存储数组。
29. 与贯穿式交通信号项目的连接
贯穿式综合项目可以增加一组配置寄存器:
duration[0]:主路绿灯持续拍数
duration[1]:主路黄灯持续拍数
duration[2]:支路绿灯持续拍数
duration[3]:支路黄灯持续拍数
它在功能上是 4 × W bit
小型寄存器文件。控制状态选择读地址,读数据作为计时比较上限;配置接口使用写地址、写数据和写使能更新某一项。
若控制器在状态转移边沿同时切换阶段地址并清零计数,要确认比较器使用的是旧阶段上限还是新阶段上限。清楚的设计会在进入新阶段时确定读地址,并从下一周期开始用对应持续时间进行比较。
30. 本章知识链
许多独立寄存器
↓ 规则化
深度 × 字宽的存储阵列
↓
地址 → 行/列译码 → 选中一个字
↓
读数据 / 写数据 / 使能 / 时钟
↓
按功能与实现选择
├─ ROM:固定地址映射
├─ SRAM:双稳态反馈,免刷新
├─ DRAM:电容电荷,读后恢复并刷新
└─ 寄存器文件:小容量、多端口
↓
明确异步/同步读写和同址冲突
↓
接入控制器与数据通路
↓
检查访问延迟、建立保持、容量和接口协议
31. 本章小结
- 存储器用地址从规则阵列中选择一个字,避免为大量数据逐个连接寄存器。
D × W bit表示 \(D\) 个可寻址字、每字 \(W\) bit,总容量为 \(D W\) bit。- 最小地址位数为 \(\lceil\log_2D\rceil\),非 2 的幂深度会留下未使用编码。
- 地址译码选择字线,同一行的多个单元构成一个数据字,位线沿列传送信息。
- ROM 在读取侧实现固定的地址—数据映射,可用于查找表和常量。
- 6T SRAM 用两个交叉耦合反相器保存状态,两只访问管连接互补位线。
- SRAM 读出依靠预充、微小位线差分和感应放大;写入由位线驱动翻转单元。
- 1T1C DRAM 用电容电荷保存数据,读出后要恢复,并因漏电周期刷新。
- 寄存器文件常提供多个并行读口和写口,端口数量会增加硬件成本。
- 异步读按访问时间响应,同步读按规定时钟延迟返回;单元技术不能决定接口时序。
- 同地址读写必须规定旧值、新值、保持或未定义行为,必要时加入旁路。
- 存储器的地址、数据、控制和输出都参与数据通路时序与协议检查。
32. 练习
基础题
64 × 8 bit中的深度和字宽分别是多少?总容量是多少 bit?- 深度为 256 的存储器最少需要多少位地址?
- 写出一般深度 \(D\) 的最小地址位数公式。
- 地址译码器、字线和位线分别承担什么任务?
- ROM 与 RAM 在正常运行接口上的主要区别是什么?
- 典型 6T SRAM 单元由哪些部分组成?
- 典型 1T1C DRAM 单元用什么物理量保存数据?为什么需要刷新?
2R1W寄存器文件中的2R1W表示什么?
分析与计算题
- 计算
2048 × 16 bit的地址位数、总 bit 数、byte 数和 KiB。 - 一个
100 × 24 bit存储器需要多少位地址?有多少个未使用地址编码?总容量是多少 byte? - 设计一个 4 bit 输入的立方查找 ROM,输出要完整表示 \(15^3\)。求最小输出位数、ROM 组织和总容量。
- 图 18-2 的
4 × 4 bit阵列中,地址11选中哪条字线?一次读出几 bit? - 解释 SRAM 读出为什么先预充互补位线,再用感应放大器检测小差分。
- 解释 SRAM 写入时为什么位线驱动必须能够克服单元原有反馈状态。
- 某 DRAM 有 16384 行,要求 64 ms 内刷新全部行。若均匀分配,平均行刷新间隔是多少?
- 某异步 ROM 的地址在 50 ps 稳定,\(t_{AA}=600\) ps;
oe在 200 ps 有效,\(t_{OE}=300\) ps。数据最晚何时保证有效? - 一个同步读存储器在边沿 \(n\) 接受地址,规定读延迟为 2 个周期,\(T_{clk}=5\) ns。对应数据在哪个边沿可用?从接受到可用经过多长时间?
- 一个 32 bit 存储字原值为
0xA1B2C3D4,写数据为0x11223344,字节使能be[3:0]=0101,规定be[0]控制最低 8 bit。求写后结果。
综合题
- 为例题 3 的平方 ROM 写出地址
101、110、111的输出,并说明输出宽度为何不能只有 5 bit。 - 为一个
8 × 8 bit、异步读、同步写的小型存储器写出完整接口契约,包括禁用行为和同址读写策略。 - 比较用 32 个独立 16 bit 寄存器和一个
32 × 16 bit单端口存储器保存数据时,在并行访问、选择网络和控制方式上的差别。 - 某
2R1W寄存器文件要求写入 R4 的同时两个读口分别读取 R4 与 R7,并要求读 R4 立即看到新值。写出所需的冲突检测与旁路关系。 - 为交通信号项目的四项持续时间设计一个
4 × 8 bit配置寄存器文件:定义地址映射、读写端口、复位值和非法地址行为。 - 一个控制器要从固定延迟一周期的同步 ROM 连续读取地址 0、1、2、3,并把四个数据依次累加。写出控制状态或流水调度,说明地址发出拍与数据使用拍的对应关系。
- 独立设计一个
16 × 8 bit小型数据存储模块的纸面规格:定义异步读或同步读、同步写、片选、输出使能、同址冲突、非法情况、复位策略、至少八个测试场景,并画出地址译码到阵列和数据口的框图。
33. 练习答案
展开第 18 章练习答案
题 1
深度为 64,字宽为 8 bit,总容量为
\[ 64\times8=512\ \text{bit}=64\ \text{byte}. \]
题 2
\(256=2^8\),最少需要 8 bit 地址。
题 3
\[ A=\lceil\log_2D\rceil. \]
\(A\) 为地址位数,\(D\) 为可寻址字数。
题 4
地址译码器把二进制地址转换为独热选择;字线沿一行使目标单元连接到列;位线沿列传送读出差分或写入数据。
题 5
ROM 在正常读取接口上提供固定地址映射,系统运行时通常不通过该接口改写;RAM 允许系统按地址读写数据。
题 6
两个交叉耦合 CMOS 反相器形成双稳态核心,共 4
只晶体管;两只由字线控制的访问 NMOS 分别把 \(Q\)、\(\overline
Q\) 接到 BL、BLB。
题 7
1T1C DRAM 用存储电容上的电荷状态表示一位。漏电会使电荷随时间衰减,因此必须周期性刷新。
题 8
它表示两个独立读端口、一个写端口,可在接口允许时同周期读取两个地址并写入一个地址。
题 9
\(2048=2^{11}\),地址需要 11 bit。总容量为
\[ 2048\times16=32768\ \text{bit}=4096\ \text{byte}=4\ \text{KiB}. \]
题 10
\[ A=\lceil\log_2 100\rceil=7. \]
7 bit 有 128 个编码,未使用 \(128-100=28\) 个。容量为
\[ 100\times24=2400\ \text{bit}=300\ \text{byte}. \]
题 11
最大值为
\[ 15^3=3375. \]
\(2^{11}=2048<3375<4096=2^{12}\),所以最少需要
12 bit 输出。4 bit 输入有 16 个地址,因此 ROM 为
16 × 12 bit,总容量
\[ 16\times12=192\ \text{bit}=24\ \text{byte}. \]
题 12
地址 11 的无符号编号为 3,因此选中
WL3。字宽为 4 bit,一次读出 4 bit。
题 13
位线连接许多单元,电容大。预充使两条位线从相同已知条件开始;选中单元只需产生小差分,感应放大器就能快速恢复为完整逻辑值,避免等待整条位线大幅摆动。
题 14
交叉耦合反相器会主动维持旧状态。写驱动通过互补位线和访问管强制内部节点朝目标电平变化,驱动力不足时单元不会翻转或写入时间过长。
题 15
\[ t_{row}=\frac{64\ \text{ms}}{16384}=3.90625\ \mu\text{s}. \]
题 16
地址路径要求
\[ 50+600=650\ \text{ps}, \]
输出使能路径要求
\[ 200+300=500\ \text{ps}. \]
两者都满足后有效,因此数据最晚在 650 ps 保证有效。
题 17
边沿 \(n\) 接受地址,延迟 2 个周期,因此数据在边沿 \(n+2\) 可用。经过时间为
\[ 2\times5\ \text{ns}=10\ \text{ns}. \]
题 18
按从高到低字节写出:
原值:A1 B2 C3 D4
写值:11 22 33 44
be: 0 1 0 1
be[2]=1 更新字节 [23:16] 为
0x22,be[0]=1 更新最低字节为
0x44;其余保持,所以结果为
0xA122C344
题 19
- 地址
101即 5,输出 \(25=\)011001; - 地址
110即 6,输出 \(36=\)100100; - 地址
111即 7,输出 \(49=\)110001。
5 bit 最大只能表示 31,不能完整表示 36 与 49,因此至少需要 6 bit。
题 20
一个完整示例:
addr[2:0]选择 8 个字;wdata[7:0]、rdata[7:0]为写入和读出数据;cs=1模块有效,oe=1允许读输出,we=1在上升沿写入;- 异步读:
cs=1、oe=1、we=0时,地址稳定后经过规定 \(t_{AA}\) 输出对应数据; - 同步写:上升沿采到
cs=1、we=1时执行 \(M[addr]\leftarrow wdata\); cs=0或oe=0时规定rdata=0;- 同一地址写与读采用 write-first,组合旁路使
rdata=wdata; - 地址全部 3 bit 编码均有效;
- 写入边沿要求地址、数据、
cs、we满足建立与保持时间。
其他策略可以成立,但每一项必须明确。
题 21
32
个独立寄存器可以按需要提供大量并行输出和独立写使能,但连接与选择网络会迅速增大。32 × 16 bit
单端口存储器用 5 bit
地址选择一个字,接口规则、版图和选择结构更规整,一次通常只访问一个地址。若需要同拍读取多个独立数据,单端口存储器必须增加端口、复制数据、分银行或分多个周期访问。
题 22
写后读新值的读口 A 旁路条件为
\[ bypass_A=we\cdot(waddr=raddr_A). \]
\[ rdata_A= \begin{cases} wdata,&bypass_A=1,\\ RF[raddr_A],&bypass_A=0. \end{cases} \]
读口 B 同理:
\[ bypass_B=we\cdot(waddr=raddr_B). \]
本题 waddr=raddr_A=4,所以 A 返回新
wdata;raddr_B=7 与写地址不同,B 返回原
R7。
题 23
一种规格如下:
| 地址 | 配置项 | 复位值(拍) |
|---|---|---|
00 |
主路绿灯 | 30 |
01 |
主路黄灯 | 5 |
10 |
支路绿灯 | 20 |
11 |
支路黄灯 | 5 |
接口为 raddr[1:0]、组合
rdata[7:0]、waddr[1:0]、wdata[7:0]、we、clk
和同步 clear。clear
优先,在边沿装入四个默认值;否则 we=1 时写选中项。2 bit
的四个地址全部有效,没有非法地址。可规定同址读写使用 write-first
旁路,便于配置写入后立即读取确认。
题 24
固定一周期读延迟可使用地址发出与数据使用重叠的调度:
| 周期 | 发出 ROM 地址 | 本周期末/下一边沿可用数据 | 累加动作 |
|---|---|---|---|
| 0 | 0 | 无 | 清零累加器 |
| 1 | 1 | ROM[0] |
\(ACC\leftarrow ACC+ROM[0]\) |
| 2 | 2 | ROM[1] |
\(ACC\leftarrow ACC+ROM[1]\) |
| 3 | 3 | ROM[2] |
\(ACC\leftarrow ACC+ROM[2]\) |
| 4 | 无 | ROM[3] |
\(ACC\leftarrow ACC+ROM[3]\) |
| 5 | 无 | 无 | 给出 done |
控制器要保存“当前发出到哪个地址”和“已经使用到哪个返回数据”,不能把本周期地址与本周期返回数据当成同一项。
题 25
合格规格应至少包含:
addr[3:0]、8 bit 写数据与读数据、cs、oe、we、clk;- 明确选择异步读或固定周期同步读,并给出数据有效时刻;
- 上升沿同步写及地址、数据、控制的建立/保持要求;
cs=0、oe=0时输出行为;- 同址读写采用 read-first、write-first、no-change 或禁止中的一种;
- 4 bit 地址全部有效,无地址空洞;
- 是否复位数据阵列。常见 SRAM 数据阵列不逐位复位,可只复位控制/有效位;若要求清零全部 16 个字,需要写清逐拍清零过程或实现代价;
- 框图包含 4 线—16 线行译码、16 行 × 8 列阵列、写驱动与读出选择;
- 测试覆盖读、写、连续地址、边界地址 0/15、禁用、同址冲突、写使能无效、时序边界和上电未知内容。
八个基本测试场景可以是:写后读地址 0;写后读地址
15;连续写不同地址;连续读不同地址;cs=0
禁止写;oe=0
检查输出;同址读写;未初始化地址读取。若选择逐拍清零,还要增加清零期间访问测试。
34. 自测清单
若第 1、2 项不稳定,请重做例题 1、2;若第 5~8 项不稳定,请遮住图 18-4、18-5 的说明,分别讲出“状态由什么保存、怎样读、怎样写回”;若第 9~11 项不稳定,请重画图 18-6 并明确每个端口的地址、数据与时钟语义。
35. 下一章衔接
前 18 章一直使用方程、框图、状态表和寄存器传输描述硬件。第 19 章将把这些结构写成 Verilog/SystemVerilog:组合逻辑怎样写成连续赋值或组合过程,寄存器和同步写怎样写成时序过程,数组怎样表达存储器,以及阻塞/非阻塞赋值为什么对应不同的硬件时间语义。