第四章 存储器

存储器存放了程序和数据存储程序的思想,使得计算机从专用走向通用。

存储器 ROM和RAM
存储器的图不要求画,但是需要知道特点,能看懂就行。需要了解刷新计算。
非常重要的是动态RAM和静态RAM的比较表
绝对会考存储器的电路图,而且占比分高,重中之重。参考教材PPT和作业
单体多体了解一下就行。
cache编码映射率概念肯定要会算的,都得背。知道地址编码后,给一种映射能不能算这种映射方式下主存如何编码。还要算利用率。

前面我们提到了CPU通过总线与计算机的各个部件间进行通信,那么现在,我们就来学习占用计算机结构最大的部分:存储器。计算机大部分信息,都存储在存储器内。

按存取方式可分为两类存储器:随机存储器(RAM)和只读存储器(ROM)。前者在程序执行过程中可读可写,后者则只读。

按在计算机中的作用分类如下:

image-20240616195445786

主存储器:即内存,直接和CPU交互信息,速度快,容量小,价位高;对应内存条。

辅助存储器:即外存,存放暂时不用的程序和数据,速度慢,容量大,价位低;对应硬盘。

缓冲存储器:用在两种速度不同的部件中,即Cache,通过映射加快数据读取效率。

现在的计算机运用层次存储器系统,旨在实现:以最低的价格提供尽可能大的存储空间,以最快速的技术实现高速访问。于是选用生产与运行成本不同的、存储容量不同的、读写速度不同的多种存储介质,组成一个统一的存储器系统,使每种介质都处于不同的地位,发挥不同的作用,充分发挥各自在速度、容量、成本方面的优势,从而达到最优性能价格比,以满足使用要求。

image-20240617152036076

随机存取存储器RAM

静态RAM(SRAM)

  • 利用触发器工作原理存储信息
  • 信息读出后,仍保持原状态
  • 电源断电后,原存信息丢失
  • 速度快、能耗高、存储密度低

动态RAM(DRAM)

  • 利用电容存储电荷的原理来存储信息
  • 即使电源不断电,信息也会自动消失
  • 集成度高、容量大、功耗低、速度慢

一般来说,DRAM组成内存条,而SRAM则充当内存条和主存之间的Cache。

因为动态RAM的信息容易丢失,所以需要刷新RAM以维持信息。刷新即对所有存储单元回复一次原状态的过程。先将原信息读出,再由刷新放大器形成原信息重新写入。刷新周期即对动态ROM的全部基本单元电路作一次刷新的时间。

刷新方法有三种:集中刷新、分散刷新和异步刷新

集中刷新是在规定的时间内,对全部存储单元集中一段时间进行逐行刷新,此时必须停止读写操作。这样做会出现“死区”。

image-20240616204944733

分散刷新时指对每个存储单元的刷新分散到每个存取周期完成,即把存储周期分为两段,前半段用来读写或维持信息,后半段用来刷新。这样做没有死区,且128us就可全部刷新一遍,但是存取周期变长了,整体系统变慢了。

image-20240616205127898

异步刷新则结合了分散刷新和集中刷新,将集中刷新分散到了2ms内。如果将刷新安排在指令译码阶段,将不会出现死区。

image-20240616210200154

动态RAM和静态RAM的比较

重点!需要加强记忆。

DRAM主存 SRAM缓存
存储原理 电容 触发器
集成度
芯片引脚
功耗
价格
速度
刷新

只读存储器ROM

有掩膜ROM等。了解就好。

存储器与CPU的连接

这节是重点之一,其中会涉及到非常多的图像。

存储器容量的扩展

先从最基本的一步开始,了解如何扩大存储器的容量。

首先了解一个概念:如何表示存储芯片的容量?正如前面所介绍的,一个存储体能够存储多少容量取决于MAR和MDR的宽度。如果地址总线宽度为10,数据总线宽度为1,那么总容量就为:210*1=1K。要拓展存储量,可以使用位扩展字扩展两种方法。

位扩充

我们可以通过增加存储字长的方法来扩展存储容量。

同理,我们可以用2片1K×4位(10根地址线,4根数据线)的存储芯片组成1K×8位(10根地址线,8根数据线)的存储器。画图如下:

image-20240616211043971

其中A0~A9是地址线,D0~D7是数据线;CS\overline{CS}是片选信号,WE\overline{WE}是写允许信号,两者低电平有效。画图的时候不必深究,只需要记得上面连地址线,下面连数据线,再依次从右边接上CS\overline{CS}WE\overline{WE}就好。

字拓展

还可以通过增加存储字的数量来扩充内存。

用2片1K × 8位(10根地址线,8根数据线) 存储芯片组成 2K × 8位(11根地址线,8根数据线) 的存储器。画图如下:

image-20240616211921979

与位扩展不同的是,除了地址线和数据线的数量,还有CS\overline{CS}片选信号的改变。这里把A10当做片选信号,并使用一个反相器来选择芯片。当A10分别为正负电平时,机器会选中左或右两块存储芯片,以达到扩展字长的目的。仅用一根片选信号线和反相器就替代了再额外添加地址线(还是多加了一根)。

字位扩展

结合上述两种方法,可以用8片 1K × 4位 存储芯片组成 4K × 8位 的存储器。

计算小tip:在计算用几片已有芯片组成指定芯片存储器时,分别用地址线和数据线除以原地址线和数据线根数,再将得到的倍数相乘就好了。比如8片=4K/1K×8位/4位

结合上述两种方式的方法,可作图如下:

image-20240616212735930

首先确定最后共有8位数据线,12根地址线;有4K/1K=4个芯片作为一组来进行字扩充,有8位/4位=2个芯片一组作为位扩充;再根据有4块作为字扩充的区域需要额外的2根地址线作为片选信号扩展(2根地址线能索引22=4个区域),最终作图如上。

小结

总结扩充存储容量的画图方法:

  1. 计算需要多少块芯片才能扩展成要求的芯片容量:直接用容量相除可得片数
  2. 计算最终需要多少根地址线、数据线以及作为片选信号的额外地址线:
    • 计算数据线:很简单,即扩充后位的数量
    • 计算地址线:与原芯片的地址线相同,注意1K=10根地址线,1M=20根地址线
    • 计算片选信号额外地址线:计算字扩充的倍数得到要选择的片数n,然后计算log2nlog_2n即可得到需要的额外地址线
  3. 连接WE\overline{WE}CS\overline{CS}。前者直接在数据线下补充,后者则经过一个反相器或者片选编码器。两者均连接在芯片的右侧。

存储器与 CPU 的连接

在了解存储器如何扩展容量后,我们就得到了符合要求的存储器。接下来就需要把存储器连接到CPU,其中要点如下:

  1. 地址线的连接
  2. 数据线的连接
  3. 读/写命令线的连接
  4. 片选线的连接
  5. 合理选择存储芯片
  6. 其他
  7. 时序、负载

我们在设计CPU与存储器连接电路时,主要关注1~5点。即:地址线、数据线、读写命令线、片选线、芯片选择。

我们就直接从一道例题开始学习。

例题一

设CPU有16根地址线,8根数据线

MREO\overline{MREO}:访存控制信号

WE\overline{WE}:读/写控制信号

可使用芯片:
1K*4位RAM、4K*8位RAM、8K*8位RAM、2K*8位ROM、4K*8位ROM、8K*8位ROM

74138译码器

要求:

主存地址分配空间:

6000H~67FFH为系统存储区

6800H~6BFFH为用户程序

要解答这道题我们要进行一下几个步骤:

  1. 写出对应的二进制地址码
  2. 确定芯片的数量和类型
  3. 分配地址线
  4. 确定片选信号,画图

首先我们先写二进制地址码,如图:

image-20240617135802810

因为题给条件有16根地址线,所以我们列出A15~A0十六位,然后依次把地址范围用二进制表示

比如系统存储区6000H~67FFH就是对应二进制数:

  • 0110 0000 0000 0000
  • 0110 0111 1111 1111

可以看到,16位地址线中只有11位是不同的,剩下5位自始至终都保持01100没有改变。也就是说,存储系统的存储器只需要11位的地址线足矣,对应2×210=2K。而CPU有8根数据线,故存储系统的存储器容量应为2K×8位

同理,用户存储区6800H~6BFFH对应二进制数:

  • 0110 1000 0000 0000
  • 0110 1011 1111 1111

只有10位发生了改变,也就是分配10根地址线。最终存储用户程序的存储器容量应为1K×8位

接着我们来确定芯片的类型与数量。系统存储器应该是可读存储器,故使用ROM芯片来作为存储器。只需要1片题给的2K×8位ROM就可以满足条件;而用户存储器应该储存在可读可写存储器中,于是我们选用2片题给的1K×4位RAM,通过位扩充即可满足要求。

之后我们来分配地址线

image-20240617141527051

可以看到,ROM和RAM分别分配了对应于它们地址线根数的地址线。其中,A11~A13被分配至A、B、C接口(稍后介绍74138译码器会提到)。A14~A15则和MREO\overline{MREO}(访存信号,低电平有效)被用来作为片选信号。

关于74138译码器,可以参考下图:

image-20240617141942379

G1,G2A,G2BG_1,\overline{G_{2A}},\overline{G_{2B}}是控制端,只有三接口均有效才能使译码器正常工作(注意后两者是低电平有效,即需要保证第一个接口为高电平,后两个接口为低电平才能正常工作);A、B、C是功能端,用来输入二进制数;Y0\overline{Y_0}等端口则是十进制输出端,对应功能端输入的二进制数,同样是低电平有效。

最后,我们确定片选信号,并画出CPU与存储器的连接图。

image-20240617142423776

由74138译码器输入逻辑关系可知,必须保证控制端G1,G2A,G2BG_1,\overline{G_{2A}},\overline{G_{2B}}第一个接口为高电平,后两个接口为低电平,才能使译码器正常工作。根据第一步写出的存储器地址范围得出,A15始终为低电平,A14始终为高电平,它们正好可分别与译码器的G低,G高对应。而访存控制信号 MREO\overline{MREO}(低电平有效)又正好可与G(低)对应。故分配两个低电平信号连接低电平有效的接口,高电平信号连接高电平有效的接口。

剩下的A13、A12、A11可分别接到译码器的C、B、A输入端。其输出Y4\overline{Y_4}有效时,选中1片ROM;Y5\overline{Y_5}与A10同时有效均为低电平时,与门输出选2片RAM。这里之所以没有把Y5\overline{Y_5}和RAM单独连接是因为,当出现Y5\overline{Y_5}和A10高电平时,此时表示的范围超出了题给范围,不应该继续选择RAM,所以必须限定A10Y5\overline{Y_5}同时为低电平才可以。

图中ROM 芯片的PD/progr端接地,以确保在读出时低电平有效(因为需要始终确保系统运行,所以直接用接地低电平信号启动ROM)。RAM芯片的读写控制端与CPU的读写命令端WR\overline{WR}相连。ROM的8根数据线直接与CPU的8根数据线相连,2片RAM的数据线分别与CPU数据总线的高4位和低4位相连。

小小总结一下,比起存储器的扩展,连接CPU和存储器多了CPU和译码器两个要素,归纳一下要点如下:

  • 先画出CPU,译码器。将访存信号、译码器控制端连接好。
  • 从下至上依次画出数据线和地址线。
  • 画出ROM和RAM,注意如果需要扩展存储器使用的是位扩展还是字扩展,并连接好数据线、地址线、写入信号和PD接地信号。
  • 将译码器的端口输出和门电路组合成片选信号,原理类似于字扩展,但是这里用来选择系统存储器和用户存储器。
  • 将片选信号连接至存储器
例题二

假设同前,要求最小 8K为系统程序区,相邻 16K为用户程序区,接着又有最大4K为系统程序工作区

同样按照四步走:写出地址二进制码、确定芯片数量和类型、分配地址线、确定片选信号。

image-20240617144922150

过程不再给出证明。不过这里请留意,RAM选用了两片8K×8位的芯片组成了16K×8位的用户存储器,这里是字扩展。并且第三块区域是“系统工作区”而非系统存储区,所以选用RAM而非ROM。

接着分配地址线并确定片选信号:

image-20240617145120310

这里地址线最大的是8K的存储器,故一共使用了23×210=213共13根地址线,剩下3根地址线用作译码器的功能端。可以看到,当Y\overline{Y}端口:

  • 输出为0时,CPU选择第一块系统存储器ROM;
  • 当输出为1、2时,CPU选择用户存储器RAM;1和2又分别对应16K×8位RAM中使用了字扩展的两块8K×8位RAM。
  • 当输出为7时,CPU选择第二块系统工作区存储器RAM。

最后,画图如下:

image-20240617145539789

同理,这里之所以要把A12的信号与一个非门连接最后和Y7\overline{Y_7}做与非运算,就是为了确保选择系统工作区RAM的唯一性。

至此关于CPU和存储器连接的重难点就讲解完毕了,相信大家都能够画出正确的图。最后再强调一遍画图总结:

  • 先画出CPU,译码器。将访存信号、译码器控制端连接好。
  • 从下至上依次画出数据线和地址线。
  • 画出ROM和RAM,注意如果需要扩展存储器使用的是位扩展还是字扩展,并连接好数据线、地址线、写入信号和PD接地信号。
  • 将译码器的端口输出和门电路组合成片选信号,原理类似于字扩展,但是这里用来选择系统存储器和用户存储器。
  • 将片选信号连接至存储器

提高访存速度的措施

计算机不断发展,访问主存的速度成为计算机发展的掣肘。为了提高访存效率,先前我们已经介绍过两种方法,即:采用高速器件和层次结构。要么是提升硬件的属性,要么是在层次结构中使用Cache让快速器件更快的访问数据而避免耗时长的内存索引。

但是Cache的造价昂贵,所以不能普遍推广到计算机整体,而只能把钱花在刀刃上。所以,我们还可以通过第三种方法,即调整主存结构。主存结构有两种:单体多字系统和多体并行系统。掌握概念就好。

单体多字系统

结构图如下:

image-20240617153022511

原理很简单:假设指令在内存中时连续存取的,那么地址寄存器只需要储存第一条指令的地址,设位数为w。当主存控制器取指令时,就直接按地址在一个存储周期内读出4×w位数据,能使主存的带宽提高4倍。但是当遇到转移指令或者操作数不连续存放时,这种效果就不明显。

多体并行系统

多体的特点在于一个体正在与CPU交换信息时,其他体可以与外设交互,实现多个体并行工作,加快了访存效率。

多体并行系统分为高位交叉编址顺序存放低位交叉编址交叉存放。前者高位存储体号,低位存储体内地址;后者反之。结构图分别如下:

高位交叉:

image-20240617154154913

低位交叉:

image-20240617154229272

低位交叉能在不改变存取周期的前提下,增加存储器的带宽。因为高位交叉的信息是按顺序存储在一个体内,导致该模块成为瓶颈;而低位交叉存储则可以通过并行的方式读取来加快效率。

例题:设4个模块组成的四体存储器结构,每个体的存储字长为32位,存取周期200ns,数据总线宽度32位,总线传输周期为50ns,求顺序存储和交叉存储的存储器带宽。

  1. 顺序存储:

    不增加带宽不增加带宽

    读出一个字的时间为200ns读出一个字的时间为200ns

    带宽为:32/200ns=16×107bps带宽为:32/200ns=16×10^7bps

  2. 交叉存储:

    读出4个字的时间为200ns+50ns×(41)=350ns读出4个字的时间为200ns+50ns×(4-1)=350ns

    带宽为:(32×4)/350ns=37×107bps带宽为:(32×4)/350ns=37×10^7bps

我们在 DRAM 的芯片内 集成 了一个由 SRAM 组成的 Cache ,有利于 猝发式读取 ,这就体现了计算机的层次结构运用。可见很多时候提高访存速度的手段是结合起来运用的。

高速缓冲存储器Cache

我们之前提到了,可以用单体或者多体来一次性将多条指令或数据读入高速缓存Cache或者是通过并行工作从主存中将数据读入Cache再送入CPU中。

但是,这么做还是不够快。研究发现:最近被访问的信息和临近的信息很可能还要被访问。比如我们在程序中调用多个函数或者过程。此时,如果每次都去从主存中读取数据到Cache中会浪费时间。所以,我们选择一次性将最近被访问的信息项临近的信息一起装入到Cache中。这样就可以避免CPU在原地空等Cache去从主存中读取信息了,提高了计算机访存效率。

我们在在这一节主要介绍Cache编码、命中率的计算以及映射方式、利用率的概念。非常重要,要求掌握。

Cache的工作原理

参考下图:

image-20240617160906983

我们把主存地址划分为两部分:假设一个字n位,前m位储存主存块号,后b位字储存块内地址。这样就把主存按块划分,共有M=2m块;同理,将Cache的地址也划分为两部分,其中c位存储缓存块号,b位存储块内地址,C=2c反映了缓存块的数量,2b代表了块的大小,其中M>>C。通过这样做就建立起了Cache和主存间的映射关系,主存块号用标记记录与某缓存块建立了对应关系。

命中与未命中

在建立对应关系后,CPU欲读取主存某字有两种结果:主存已在Cache中,那么就直接从Cache中读取一个字,在较高层次的存储器中发现要访问的内容成为Cache命中;如果主存不在Cache中,那么就从主存中将整个字块一起调入Cache,再传入CPU,称为Cache未命中

Cache 的命中率

Cache 的命中率是CPU欲访问的信息在Cache 中的比率,命中率与 Cache 的容量与块长有关。一般每块可职4~8 个字,块长取一个存取周期内从主存调出的信息长度。

设Nc是访问Cache的总命中次数,Nm是访问主存的总次数,则命中率h为:

h=NcNc+Nmh=\frac{N_c}{N_c+N_m}\\

Cache的效率

效率e与命中率有关。

e=访问Cache的时间平均访问时间×100%e=\frac{访问Cache的时间}{平均访问时间}×100\%\\

设Cache命中率为h,访问Cache的时间为tc,访问主存的时间tm,则有:

e=tch×tc+(1h)×tm×100%e=\frac{t_c}{h×t_c+(1-h)×t_m}×100\%\\

例题:设CPU共访问Cache命中2000次,访问主存50次。 Cache存取周期为50ns,主存存取周期为200ns,求Cache -主存系统的命中率和效率

  1. 命中率:

    20002000+50=0.97\frac{2000}{2000+50}=0.97\\

  2. 效率

    e=50ns0.97×50ns+(10.97)×200ns×100%=91.7%e=\frac{50ns}{0.97×50ns+(1-0.97)×200ns}×100\%=91.7\%\\

Cache的基本结构

下图清晰的显示出了Cache的工作流程:

image-20240617164528821

Cache的替换机构后续会详细介绍。

Cache的读与写

更加底层,Cache是如何进行读写操作的呢?

当CPU要读取Cache信息时,结构图如下,也是我们主要讨论的:

image-20240617164924128

当CPU要对Cache执行写入操作时,有两种方法:写直达法和写回法。前者同时写入Cache和主存;而后者仅写入Cache,当Cache的数据要被替换出去时才把数据写入主存。

Cache的改进

可以通过增加Cache的级数和统一与分立缓存来实现。

Cache-主存的地址映射

重点小节,需要掌握。

Cache与主存通过划分块的方式实现映射,而映射地址的方式又有三种:直接映射(固定的映射方式)、全相连映射(灵活性大的映射关系)、组相联映射(前两者的折中)

全相联映射

结构图如图所示:

image-20240617165537981

这种方式的主存中的任一块可以映射到缓存中的任一块,Cache的标记位就是主存的字块号。利用率高,但比较电路的成本太高。标志位要有m位。如果Cache有n块,则需要有n个比较电路

直接映射

结构如图所示:

image-20240617165814185

这种方式把主存划分为跟整个Cache大小相同的块,Cache的标记位就是主存高地址t位。先找到Cache字块号,然后比较标记位和地址高t位

比较电路的成本低。如果主存空间有2m块,Cache中字块有2c块,则标志位只要有m-c位。且仅需要比较一次。

计算主存和Cache的映射关系公式为i=jmod2ci=j\bmod2^c,或者i=jmodCi=j\bmod C。总之就是主存块的序号对Cache的块数取模。

组相联映射

结构如图所示:

image-20240617170541668

此时映射关系为i=jmod2qi=j\bmod2^qq=crq=c-r。即此时可以任意指定映射的长度。

例题:共25=32个字块,分为24=16个组,每组21=2块c=5,q=4,r=1。画出组相联映射的结构图。

image-20240617170901889

这里的例题值得细读,但是篇幅有点多,日后再补上。

……

……

第二部分到此结束!敬请阅读第三部分😃


121455066_p0