☰
计算机组成原理:存储器扩展(位扩展、字扩展、字位同时扩展)详解
2026/10/13 5:48:00 网站建设 项目流程

1. 存储器扩展到底在解决什么问题

1.1 从一个真实的踩坑经历说起

刚接触计算机组成原理那会儿,我做过一个很蠢的事情。当时在仿真软件里搭了一个简单的CPU模型,指令译码、ALU、寄存器堆都调通了,跑几条算术指令没问题。然后我信心满满地往指令存储器里塞了一段稍微长一点的程序,结果仿真直接跑飞了。查了半天才发现,我用的那片SRAM模型只有1K的地址空间,程序稍微大一点就溢出了。

这件事让我意识到一个很基础但极其重要的问题:单颗存储芯片的容量和位宽,往往满足不了实际系统的需求。CPU需要更大的程序空间、更大的数据缓冲区,而市面上能买到的单颗芯片容量是有限的,数据总线宽度也未必和CPU匹配。这时候就必须做存储器的扩展。

所谓存储器扩展,说白了就是用多片小容量的存储芯片,拼出一个大容量、宽位宽的存储系统。它要解决的核心问题有三个:位扩展(增加数据位宽)、字扩展(增加存储单元数量)、字位同时扩展(两者都要)。这三个概念是计算机组成原理里存储器章节的绝对重点,也是考试和实际工程中都绕不开的基本功。

这篇文章我会把存储器扩展的完整逻辑拆开讲透:为什么这么设计、地址怎么分配、片选怎么接、时序要注意什么、实际搭电路时容易踩哪些坑。不管你是正在准备考试的学生,还是想自己动手搭一个简易计算机系统的爱好者,这些内容都能直接拿来用。

1.2 先搞清楚几个基础概念

在讲扩展之前,得先把几个术语对齐,不然后面全是糊涂账。

存储单元和存储字长:一个存储单元存放一个数据单位,通常是一个字节(8位)或者一个字(比如16位、32位)。存储字长指的是每个存储单元能存多少位。比如一片芯片标注"1K×8位",意思是有1024个存储单元,每个单元8位。

地址线和数据线:地址线决定了能寻址多少个单元,n根地址线可以寻址2的n次方个单元。数据线决定了每次能读写多少位。1K×8的芯片,需要10根地址线(2的10次方=1024),8根数据线。

片选信号(CS)和读写控制(WE/OE):片选信号决定这片芯片是否被激活,只有被选中的芯片才会响应读写操作。读写控制决定是读还是写。这两类信号是扩展电路设计的核心。

地址译码:CPU发出的地址需要经过译码,转换成对具体芯片的片选信号。译码方式直接决定了地址空间的分配,是扩展设计里最容易出错的地方。

理解了这几个概念,后面的位扩展、字扩展就都是它们的组合应用了。我个人的经验是,把"地址线管选哪个单元,片选线管选哪片芯片,数据线管传什么"这三句话刻在脑子里,扩展电路的设计思路就永远不会乱。

2. 位扩展:让数据总线变宽

2.1 位扩展的核心逻辑

位扩展要解决的问题是:单颗芯片的数据位宽不够,需要多片并联来凑齐CPU要求的数据总线宽度。

举个最典型的例子。假设CPU的数据总线是8位,但你手头只有1K×1位的存储芯片(每片只能存1位数据)。这时候你需要8片这样的芯片,每片负责数据总线上的1位,8片合起来才能提供一个完整的8位数据。

位扩展的关键特征:所有芯片共享同一套地址线和片选信号,但各自的数据线分别接到数据总线的不同位上。因为每片芯片存储的是同一个地址下的不同数据位,所以它们的地址必须完全一致,片选也必须同时有效。

我打个比方。位扩展就像8个人合作记录一个8位数的电话号码,每个人只负责记其中一位数字。当你要查某个位置的号码时,8个人必须同时被叫到,各自报出自己负责的那一位,拼起来才是完整的号码。地址就是"第几个电话号码",片选就是"叫这8个人一起过来"。

2.2 位扩展的接线方法

具体接线规则如下:

  • 地址线:所有芯片的地址线全部并联,接到CPU地址总线的低位部分。1K容量需要10根地址线,8片芯片的A0到A9全部对应相连。
  • 数据线:第1片的数据线接数据总线的D0,第2片接D1,以此类推,第8片接D7。每片只占1位。
  • 片选信号:所有芯片的CS端并联在一起,由同一个片选信号控制。因为位扩展的芯片是"同生共死"的,要选就一起选。
  • 读写控制:所有芯片的WE(或OE)端并联,统一由CPU的读写信号控制。

这里有个容易搞混的点:位扩展之后,总的存储单元数量没有变,还是1K个单元,但每个单元的位数从1位变成了8位。所以地址线的数量不变,仍然是10根。

注意:位扩展时,如果某片芯片坏了,整个数据字的某一位就会出错,表现为读出的数据某一位恒为0或恒为1。排查时可以用写入全0和全1的方式,看哪一位不对,就能定位到具体是哪片芯片的问题。

2.3 位扩展的容量计算

位扩展后的总容量计算公式很简单:

总容量 = 单元数 × (单片位数 × 芯片数)

以上面的例子:1K × (1位 × 8片) = 1K × 8位 = 8Kb = 1KB。

这里要注意单位换算。1KB = 8Kb,因为1字节等于8位。很多人在计算时把Kb和KB搞混,导致算出来的容量差8倍。我的建议是统一换算成位(bit)来算,最后再根据需要转成字节。

位扩展在实际中还有一个变种:用2片4位芯片扩展成8位。这种场景更常见,因为4位宽的SRAM或DRAM芯片在历史上很普遍。接线逻辑完全一样,只是芯片数量从8片变成2片,每片负责4位数据。

3. 字扩展:让存储空间变大

3.1 字扩展要解决的核心矛盾

位扩展解决的是"数据不够宽"的问题,字扩展解决的是"装不下"的问题。

假设你有一片1K×8位的芯片,但你的系统需要4K×8位的存储空间。单片芯片只有1024个单元,怎么才能凑出4096个单元?答案是用4片1K×8的芯片,通过地址译码把它们的地址空间拼接起来。

字扩展的关键特征和位扩展正好相反:所有芯片的数据线并联(共享同一组数据总线),但片选信号各自独立。因为同一时刻只需要一片芯片工作(CPU一次只访问一个地址),所以4片芯片分时复用数据总线。

继续用打电话的比喻。字扩展就像4个接线员,每人负责一段电话号码区间。你拨的号码落在哪个区间,就由哪个接线员接听。同一时刻只有一个接线员在工作,但他们共用同一条电话线(数据总线)。

3.2 地址空间的分配逻辑

字扩展最核心的问题是:如何用高位地址产生片选信号。

还是用1K×8扩展成4K×8的例子。4K容量需要12根地址线(2的12次方=4096)。每片芯片需要10根地址线(1K=2的10次方)。那么12根地址线怎么分配?

答案是:低10位(A0-A9)接所有芯片的地址输入端,高2位(A10-A11)用来产生片选信号。

高2位有4种组合:00、01、10、11,正好对应4片芯片:

A11A10选中芯片地址范围
00芯片1000H - 3FFH
01芯片2400H - 7FFH
10芯片3800H - BFFH
11芯片4C00H - FFFH

这个表格是字扩展的核心。每一片芯片占据一段连续的地址空间,4片拼起来就是完整的4K空间。CPU发出一个地址,高2位决定选哪片,低10位决定片内哪个单元。

3.3 译码器的选择与使用

产生片选信号最常用的器件是译码器,比如2-4译码器、3-8译码器。2-4译码器有2个输入端、4个输出端,正好把A10和A11的4种组合翻译成4个片选信号。

用译码器的好处是:输出信号互斥,同一时刻只有一个输出有效,天然保证了不会同时选中多片芯片。如果用门电路自己搭,很容易出现竞争冒险或者逻辑错误。

常见的译码器型号有74LS139(双2-4译码器)、74LS138(3-8译码器)。选型时主要看两点:需要多少个片选信号,以及译码器的使能端怎么接。74LS138有3个使能端(G1、G2A、G2B),可以方便地实现地址空间的进一步划分。

实操心得:译码器的输出通常是低电平有效,而很多存储芯片的片选CS也是低电平有效,可以直接相连。但如果遇到高电平有效的片选,中间要加一个反相器。我第一次搭电路时就因为没注意极性,调了半天才发现片选一直是反的。

3.4 字扩展的容量计算

字扩展后的总容量:

总容量 = (单片单元数 × 芯片数) × 单片位数

上面的例子:1K × 4片 = 4K个单元,每个单元8位,总容量4K×8位 = 32Kb = 4KB。

注意字扩展后数据位宽不变,变的只是单元数量。地址线增加了log2(芯片数)根。4片需要增加2根地址线,8片需要增加3根。

4. 字位同时扩展:实战中最常见的场景

4.1 什么时候需要字位同时扩展

实际工程中,很少只做位扩展或只做字扩展,大多数情况是两者同时进行。

比如:用1K×4位的芯片,要组成4K×8位的存储系统。这时候既需要增加位数(从4位到8位),又需要增加单元数(从1K到4K)。

解决思路是分两步走:先做位扩展,再做字扩展。或者反过来,先字后位,结果一样。

具体来说:先用2片1K×4的芯片做位扩展,组成1K×8的存储模块。然后用4个这样的模块做字扩展,组成4K×8的系统。总共需要2×4=8片芯片。

4.2 芯片数量的计算方法

字位同时扩展时,芯片数量的计算公式:

所需芯片数 = (目标单元数 / 单片单元数) × (目标位数 / 单片位数)

以上面的例子:(4K / 1K) × (8位 / 4位) = 4 × 2 = 8片。

这个公式很好记:横向扩展倍数乘以纵向扩展倍数。横向是位数方向,纵向是单元数方向。

再举一个例子巩固一下。用16K×8位的芯片组成128K×32位的存储系统:

  • 单元数方向:128K / 16K = 8倍
  • 位数方向:32位 / 8位 = 4倍
  • 总芯片数:8 × 4 = 32片

4.3 地址线的分配策略

字位同时扩展时,地址线的分配需要仔细规划。原则是:先满足片内寻址,再用剩余高位做片选。

假设用1K×4的芯片组成4K×8的系统:

  • 总地址空间4K,需要12根地址线(A0-A11)
  • 单片容量1K,片内寻址需要10根地址线(A0-A9)
  • 剩余高位A10-A11共2根,用于片选译码,产生4个片选信号

每个片选信号同时控制2片芯片(因为这2片是位扩展关系,必须同时工作)。所以译码器的每个输出要驱动2片芯片的CS端。

这里有个细节:位扩展的芯片必须共享同一个片选信号,因为它们存储的是同一个地址下的不同数据位。如果给它们不同的片选,读出的数据就会错位。

4.4 一个完整的接线示例

我用一个具体的例子把整个接线过程走一遍。

目标:用1K×4位的SRAM芯片,组成2K×8位的存储系统。

第一步:确定芯片数量

  • 单元数:2K / 1K = 2倍
  • 位数:8位 / 4位 = 2倍
  • 总芯片数:2 × 2 = 4片

第二步:分组

  • 位扩展组1:芯片1和芯片2,组成1K×8
  • 位扩展组2:芯片3和芯片4,组成1K×8

第三步:地址线分配

  • 总地址空间2K,需要11根地址线(A0-A10)
  • 片内寻址需要10根(A0-A9)
  • 片选需要1根(A10)

第四步:接线

  • A0-A9:4片芯片全部并联
  • 数据线:芯片1和芯片3接D0-D3,芯片2和芯片4接D4-D7
  • 片选:A10直接作为片选信号(或经译码器)。A10=0时选中组1(芯片1、2),A10=1时选中组2(芯片3、4)
  • 读写控制:4片芯片的WE端全部并联

第五步:地址范围验证

  • 组1:A10=0,地址范围000H-3FFH
  • 组2:A10=1,地址范围400H-7FFH
  • 合起来正好覆盖000H-7FFH,共2K个单元

这个例子里,A10只有1根,可以直接用作片选,不需要译码器。但如果片选信号多于2个,就必须用译码器了。

5. 片选信号的产生方式与地址译码

5.1 线选法:简单但浪费地址空间

产生片选信号最简单的方法是线选法:直接用某一根高位地址线作为某片芯片的片选信号。

比如用4片1K×8芯片组成4K×8系统,需要12根地址线。线选法可以用A10选芯片1、A11选芯片2……但这样只能选2片(因为只有A10和A11两根高位)。要选4片,得用4根高位地址线,那就意味着地址空间会变得很大,而且不连续。

线选法的缺点是:地址空间不连续,且大量地址空间被浪费。比如用A10选芯片1,那芯片1的地址范围是A10=0时所有A11-A15的组合,这占了很大的空间,但实际只用了其中一小部分。

线选法只适合芯片数量很少的场合,实际工程中基本不用。

5.2 译码法:工程中的标准做法

译码法是用译码器把高位地址翻译成片选信号,这是实际工程中的标准做法。

译码法的优点是:地址空间连续、无浪费、片选信号互斥。用2-4译码器处理2根高位地址,正好产生4个片选,对应4片芯片,地址空间从0开始连续排列。

译码法又分为全译码和部分译码:

  • 全译码:所有高位地址线都参与译码。比如12根地址线,低10根片内寻址,高2根全部接译码器。这样每个存储单元都有唯一确定的地址,没有地址重叠。
  • 部分译码:只用部分高位地址线参与译码,剩下的高位地址线不接或接固定电平。这样会出现地址重叠,同一个物理单元对应多个地址。部分译码可以简化电路,但会浪费地址空间,且编程时容易混淆。

我的建议:除非地址空间非常紧张或者成本极度敏感,否则一律用全译码。地址重叠带来的调试麻烦,远比省下几根线值钱。

5.3 译码器的级联与扩展

当需要的片选信号超过译码器的输出数量时,可以用级联的方式扩展。

比如需要16个片选信号,可以用2片3-8译码器(共16个输出),或者用1片4-16译码器。级联时,高位地址线接第一级译码器,第一级的某个输出作为第二级译码器的使能信号。

级联的关键是使能端的正确连接。74LS138的G1高有效,G2A和G2B低有效。级联时,通常把第一级的输出经过反相后接第二级的使能端,确保同一时刻只有一级译码器工作。

这里有个实际经验:译码器的输出驱动能力有限,如果一片译码器的输出要驱动很多片存储芯片的CS端,可能需要加缓冲器。74LS138的输出驱动能力大约是8个LS负载,超过这个数量就要考虑加74LS244之类的缓冲器。

6. 存储器扩展中的时序问题

6.1 为什么时序是扩展电路的关键

很多人搭扩展电路时,逻辑连接全对,但就是工作不稳定。问题往往出在时序上。

存储器扩展后,地址信号要经过译码器产生片选,片选信号再控制芯片的读写。这个过程中,地址变化、译码器延迟、片选建立时间、数据输出延迟,每一个环节都有时间要求。如果CPU的读写时序和存储芯片的时序不匹配,就会出现读出错数据、写入失败等问题。

6.2 关键时序参数

几个必须关注的时序参数:

  • 地址建立时间:地址信号稳定后,片选信号才能有效。如果片选比地址先到,可能会选中错误的芯片。
  • 片选建立时间:片选有效后,要等一段时间才能进行读写操作。这个时间由芯片手册给出。
  • 数据输出延迟:片选和地址都有效后,芯片需要一定时间才能把数据放到数据总线上。CPU的读周期必须大于这个延迟。
  • 写脉冲宽度:写信号的有效宽度必须大于芯片要求的最小值,否则写入不可靠。

这些参数在芯片的数据手册(Datasheet)里都有,设计时必须逐一核对。我见过太多人只看逻辑连接,不看时序参数,结果电路时好时坏,查几天都查不出问题。

6.3 时序匹配的实用技巧

如果CPU时序和存储芯片不匹配,有几种解决办法:

第一种:插入等待周期。如果CPU支持等待状态(Wait State),可以在读写周期中插入等待周期,延长访问时间。这是最常用的方法。

第二种:降低时钟频率。如果系统对速度要求不高,可以降低CPU时钟,让时序自然匹配。这是最简单的办法,但会牺牲性能。

第三种:使用更快的芯片。如果预算允许,换用访问速度更快的存储芯片,从根上解决时序问题。

第四种:加锁存器或缓冲器。在地址总线和数据总线上加锁存器,可以改善信号质量,但会增加延迟。

实操心得:调试时序问题时,示波器是最好的朋友。把片选信号、读写信号、数据总线都接上示波器,看它们的先后顺序和脉宽,一眼就能看出问题。没有示波器的话,用逻辑分析仪也行,但不如示波器直观。

7. 常见问题与排查技巧实录

7.1 存储器扩展常见问题速查表

问题现象可能原因排查方法解决办法
读出的数据某一位恒为0或1位扩展中某片芯片故障或接触不良写入全0和全1,观察哪一位异常更换芯片或重新焊接
部分地址范围读写正常,部分异常片选译码错误或译码器故障用示波器观察各片CS信号检查译码器接线和使能端
读写完全无响应片选信号极性错误或使能端未接测量CS端电平调整极性或补接使能
数据偶尔出错,不稳定时序不匹配或信号干扰示波器观察时序关系插入等待周期或加滤波电容
地址重叠,同一单元多个地址部分译码导致检查高位地址线是否全部参与译码改为全译码
写入后读出的数据不对写脉冲宽度不够或写信号极性错误测量WE信号脉宽延长写脉冲或调整极性

7.2 几个我踩过的坑

坑一:忘记接使能端。有一次用74LS138做译码,电路搭好后怎么都不工作。查了半天才发现,G2A和G2B两个低有效使能端悬空了。悬空在TTL电路里通常被视为高电平,导致译码器一直被禁用。后来把这两个脚接地,立刻正常。这个教训是:TTL芯片的使能端绝对不能悬空,不用的话要接固定电平。

坑二:地址线接反。有一次把A0和A1接反了,结果读出的数据顺序全乱。这种错误很隐蔽,因为电路逻辑看起来是对的,只是地址映射错了。排查方法是:写入地址0的数据,然后逐个地址读,看数据出现在哪个地址,就能判断地址线是否接错。

坑三:数据总线冲突。字扩展时,如果两片芯片的片选同时有效,它们的输出会在数据总线上打架,导致数据错误甚至芯片发热。这种情况通常发生在译码器输出没有互斥,或者片选信号有毛刺的时候。解决办法是确保译码器输出互斥,必要时在片选信号上加滤波。

坑四:忽略负载效应。地址线并联太多芯片后,驱动能力不足,信号幅度下降,导致读写不稳定。这时候需要在地址总线上加缓冲器,比如74LS244。我一开始没注意这个问题,后来发现地址线电压只有2V多,远低于正常的3.5V,加了缓冲器就解决了。

7.3 调试存储器的系统方法

调试存储器扩展电路,我总结了一套流程:

  1. 静态检查:断电状态下,用万用表检查所有电源、地、使能端的连接,确保没有虚焊、短路。
  2. 片选验证:上电后,用示波器或逻辑笔逐个检查每片芯片的CS端,确认在对应地址范围内CS有效,其他时候无效。
  3. 单芯片测试:如果可能,先只焊一片芯片,测试读写是否正常,再逐步增加芯片。
  4. 全0全1测试:向每个地址写入全0,读出验证;再写入全1,读出验证。这能发现大部分数据线问题。
  5. 地址遍历测试:从起始地址到结束地址,逐个写入地址值(比如地址0写0,地址1写1),然后逐个读出,验证地址映射是否正确。
  6. 边界测试:重点测试每片芯片的起始地址和结束地址,这些地方最容易出片选问题。

这套流程走下来,基本能覆盖90%以上的问题。剩下的10%通常是时序问题,需要示波器深入分析。

8. 从理论到实践:一个可复现的扩展方案

8.1 方案设计

我以一个具体的方案为例,把整个设计过程完整走一遍。这个方案可以直接在仿真软件里复现,也可以在实际面包板上搭建。

目标:用1K×8位的SRAM芯片,组成4K×8位的存储系统。

芯片选型:假设手头有若干片1K×8的SRAM,型号不限,只要引脚兼容即可。典型引脚包括:A0-A9(地址输入)、D0-D7(数据输入输出)、CS(片选,低有效)、WE(写使能,低有效)、OE(输出使能,低有效)。

译码器:74LS139(双2-4译码器)或74LS138(3-8译码器)。这里用74LS139的一半即可。

8.2 详细接线步骤

第一步:确定地址分配

4K空间需要12根地址线(A0-A11)。低10位A0-A9用于片内寻址,高2位A10-A11用于片选。

A11A10选中芯片地址范围
00芯片1000H-3FFH
01芯片2400H-7FFH
10芯片3800H-BFFH
11芯片4C00H-FFFH

第二步:连接地址线

  • A0-A9:4片芯片的对应引脚全部并联
  • A10:接74LS139的A输入端
  • A11:接74LS139的B输入端

第三步:连接译码器

74LS139的一半有2个输入(A、B)、4个输出(Y0-Y3)、1个使能端(G,低有效)。

  • A接A10,B接A11
  • G接地(始终使能)
  • Y0-Y3分别接芯片1-4的CS端

74LS139的输出是低有效,正好匹配SRAM的低有效片选。

第四步:连接数据线

4片芯片的D0-D7全部并联,接到系统数据总线D0-D7。

第五步:连接控制线

  • 所有芯片的WE端并联,接系统写信号
  • 所有芯片的OE端并联,接系统读信号

第六步:电源和地

所有芯片的VCC接+5V,GND接地。译码器的VCC和GND也要接。

8.3 验证与测试

接线完成后,按以下步骤验证:

  1. 片选测试:分别设置A11A10为00、01、10、11,测量4片芯片的CS端,确认只有对应的那片有效。
  2. 写入测试:向地址000H写入55H,向400H写入AAH,向800H写入0FH,向C00H写入F0H。
  3. 读出测试:逐个读出上述地址,确认数据与写入一致。
  4. 边界测试:向3FFH、7FFH、BFFH、FFFH写入数据并读出,确认片选边界正确。
  5. 遍历测试:从000H到FFFH逐个写入地址低8位,再逐个读出验证。

如果所有测试通过,这个4K×8的存储系统就搭建成功了。

8.4 扩展思路的延伸

这个方案可以进一步扩展:

  • 容量扩展:如果需要8K×8,用8片1K×8芯片,地址线增加到13根,用3-8译码器产生8个片选。
  • 位宽扩展:如果需要4K×16,用8片1K×8芯片,4片一组做位扩展,两组做字扩展。
  • 混合扩展:用1K×4芯片组成8K×16系统,计算芯片数量:(8K/1K)×(16/4)=8×4=32片。

不管怎么扩展,核心逻辑都是一样的:先分组,再分配地址,最后接译码器。把这三步做好,再复杂的扩展都能搞定。

我在实际搭建这些电路的过程中,最大的体会是:理论上的逻辑连接只是第一步,真正的功夫在调试。时序、负载、干扰、接触不良,这些问题在课本上不会讲,但实际中一定会遇到。多动手、多测量、多总结,才能真正把存储器扩展这件事吃透。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询