本系列文章为哈尔滨工业大学刘宏伟计算机组成原理学习笔记,前面的系列文章链接如下:
计算机组成原理:P1-计算机系统概述
计算机组成原理:P2-系统总线
文章目录
一、概述
存储器是计算机系统中最重要的部件之一。我们执行程序的时候,我们所需要的指令、数据都来自于存储器,程序的执行结果也保存在存储器中。另外,我们的各种文档、视频音乐等文件都是保存在存储器中。
1.1 存储器分类
对存储器的分类方法非常多,我们来看三种分类方法。
按存储介质分类
①半导体存储器:主要分为两种,TTL(Transistor-Transistor Logic,三极管-三极管逻辑)、MOS(Metal Oxide Semiconductor,金属氧化物半导体晶体管)
TTL型的存储器集成度低,功耗高,但是速度快。MOS型的存储器集成度高,功耗低。计算机的存储器主要是MOS型的存储器。
②磁表面存储器:需要有磁头、载磁体,如磁盘、磁带。
我们以磁盘为例,它有一个塑料或者合金的机片,在机片的表面涂一层磁层,利用磁层不同的磁化方向来存储0和1。这个磁层被分成了若干个同心圆,每一个同心圆叫磁道,每个磁道又分成若干扇区,每个扇区可以保存几百到几K个数据。
③磁芯存储器:需要有硬磁材料、环状元件
磁芯里面有导线,导线通过一定电流可以对磁芯进行磁化。磁芯本身是铁氧体,在电流的作用下被磁化,磁化成N级和S级,根据磁场的方向就可以来保存0和1
④光盘存储器:需要激光、磁光材料
特点:半导体存储器是易失的,也就是说给存储器去掉电源,里面的信息就会消失。其余三种存储器是不易失的。
按存取方式分类
①存取时间与物理地址无关(随机访问)
------随机存储器 在程序的执行过程中 可 读 可 写
------只读存储器 在程序的执行过程中 只 读。可以在这类存储器中存放一些系统参数或系统程序。
②存取时间与物理地址有关(串行访问)
------顺序存取存储器 磁带
------直接存取存储器 磁盘
按在计算机中的作用分类
其中:
主存储器又可以分为RAM和ROM,RAM(Random Access Memory)是可读可写的,ROM(Read Only Memory)是只读存储器。RAM又可以分为静态RAM和动态RAM
主存储器和辅助存储器中间可以放上Flash Memory,常见的如我们的U盘。它是半导体存储器,速度比磁盘快,但是比主存储器慢。Flash Memory除了作为便携式存储器,还可以作为高性能计算机硬盘。Flash Memory还可以作为主存与辅存之间的缓冲器,由于主存辅存速度差异大,当主存需要辅存中的数据时,如果Flash Memory中有这些数据,就可以直接从Flash Memory中读取。
Cache放在出主存与CPU之间,速度很快,一般作为CPU与主存之间的缓冲。实际上Cache一般都是由静态RAM做的,它的速度大于主存。
1.2 存储器的层次结构
存储器的层次结构与特性的关系
存储器三个主要特性就是:速度、容量、价格。
计算机中存储器的层次结构与特性的关系如下:
其中,
①寄存器是做在CPU中的。但是,寄存器不仅CPU有,I/O端口也有。这些寄存器还可以分为两类,体系结构寄存器(机器指令可以直接对这些寄存器进行操作)和非体系结构寄存器(机器指令不可以直接对这些寄存器进行操作)。
②缓存的一部分是做在CPU中的
③主存+寄存器+缓存时放在主机里的
④磁盘、光盘、磁带时放在辅助存储器中。
从上面可以看出:
用户所需要的高速度、大容量、低价格的存储器不存在。解决的办法就是采用层次体系,形成一个存储体系。存储体系指把两种或两种以上存储介质构成的存储器用软件、硬件或软硬件结合的方式连接成一个整体,使得从某一级程序员的角度去看,这个整体具有高速度、大容量、低价格。
存储层次
①主存-辅存层次:主存容量不够大,如果我们的程序够大,在主存中根本放不下。另外,我们经常需要放一些文档、视频、资料等数据在电脑中,这就需要辅助存储器。但是,程序的运行在主存中,因此需要用软硬件结合的方式将主层辅层构成一个存储层次。从应用程序员的角度来看,这个存储层次有主存的速度和辅存的容量和价格。在程序执行过程中,即使程序非常大,超过了主存的容量,应用程序员也不用去考虑如何把这个程序进行分割,也不用考虑要执行辅存中的程序该如何将其调入主存中,这些都由软硬件结合的那个结构来完成。
②缓存-主存层次:CPU和主存的速度存在较大差异,通过硬件的方法我们在它们中间加上一个缓存,也就是我们常说的Cache。缓存容量比储存小得多,功耗比主存大,但是速度比主存高很多。 缓存里面保存了主存中一些信息的副本,CPU可以通过访问缓存来直接访问主存。如果将CPU常用的数据和指令放在Cache中,计算机的速度将大大加快。
③缓存-主存层次是为了解决速度问题,因此让硬件去做许多事情。主存-辅存是为了解决容量问题,因此采用软硬件结合的方式。主存-辅存构成的整体一般叫做虚拟存储器,它的地址空间如何定义就是个问题,因此我们使用虚拟地址,在使用时由特定结构将其转化为物理地址。缓存-主存间的地址就是实际的物理地址
二、主存储器
2.1 概述
主存储器的基本组成
前面我们已经介绍了存储器的构成,包括了存储体、MAR、MDR三大部分。当时我们给的是简化的结构,实际的结构如下。
其中:
①存储体保存了数据、指令等信息。
②MAR保存了我们要访问的那个存储单元的地址,必须经过译码器之后才能选定指定的存储单元。
③MDR保存了我们要读出或写入的数据,控制电路就来控制是读还是写。如果是写入的话,就把MDR中的数据送到MAR指定的存储单元中。如果是读出,指定的存储单元内容将会被送到MDR中。
主存和CPU的联系
CPU和主存的连接信号分成了三类:数据总线、地址总线、控制总线
①数据总线完成主存与CPU之间的信息传输,因此数据总线直接连接在MDR寄存器上,是双向的,可能读出也可能写入。
②地址总线连接在MAR寄存器上,给出了要访问的内存地址,所以是单向的,从CPU送到主存。
③控制信号这里只给了两个,读和写,由CPU送到主存。后面还会接触到另外一个控制信号。
主存中存储单元地址的分配
假设主存中的存储字长是32位,另外主存的编址单位是字节,每一个字节都有一个地址。在这种情况下,一个存储字是32位,一个字节是8位,都有一个地址。现在我们有一个8位的16进制数12345678H,每位16进制数是4位,8位16进制数就刚好是32位,即一个存储单元长度。这个数据如何在主存储器中进行存储?
①高位字节地址为字地址
将高位字节地址存放在低地址,低位字节地址存放在高地址,并且让高位字节地址位存储字地址。
②低位字节地址为字地址
将低位字节地址存放在低地址,高位字节地址存放在高地址,并且让低位字节地址位存储字地址。
一些问题
这两种存储方式在本质上没太大区别,X86系列机器采用小尾方式,但是两种存储方式的机器通信就会出现问题。
现在假设我们的存储器有地址线24根,如果我们进行按字节寻址,即一次访问是访问一个字节,这样访问的范围就是 2 24 = 16 M B \rm{2^{24}=16MB} 224=16MB
如果我们寻址的方式发生变化,按 字 寻址,字长为16位,这时存储器的容量范围就是8MW,这个W就是Word的缩写,16位。
若字长为 32 位,即4个字节构成一个字,这时存储器的容量范围就是4MW
主存的技术指标
①存储容量:主存存放二进制代码的总位数
②存储速度:
----存取时间:从存储器给出地址,一直到得到稳定的数据输入输出,包含读出时间、写入时间
----存取周期:连续两次独立的存储器操作(读或写)所需的最小间隔时间,包含读周期、写周期
一般来说,存储周期比存取时间长。
③存储器的带宽:单位时间内能向存储区读取或写入多少位数据,单位是位/秒
2.2 半导体存储芯片简介
半导体存储芯片的基本结构
核心的结构就三大部分,
存储矩阵
、译码驱动
、读写电路
。同时还包含了许多接口,通过许多线与CPU等外部设备连接。CPU等外部设备通过单向的地址线
给出地址,经过译码驱动电路去选择指定的位置。然后通过读写电路和数据线
完成数据的处理。除了地址线和数据线,还包括一些控制线,如片选线和读写控制线。
①片选线:拿出一个内存条,你可以看到上面有很多芯片。片选线上面的是芯片选择信号,它指出了这次操作给出的地址在哪个芯片中。半导体存储芯片的片选线一般有两种标识方式: C S ‾ \rm{\overline {CS}} CS和 C E ‾ \rm{\overline {CE}} CE。其中,上面那条横线代表低电平有效。如果是低电平,就代表这次操作的地址就是在这个芯片中。
②读写控制线:可以用一个信号来控制, W E ‾ \rm{\overline {WE}} WE(低电平写,高电平读)。也可以用两个信号来控制, O E ‾ \rm{\overline {OE}} OE(允许读) W E ‾ \rm{\overline {WE}} WE(允许写)
③地址线、数据线与芯片容量的关系:
地址线(单向)----数据线(双向)----芯片容量
10----4----1K×4位
14----1----16K×1位
13----8----8K×8位
对于第一个例子,代表我有 2 10 \rm{2^{10}} 210个存储单元,每个存储单元包含了4位数据,则芯片容量就是 2 10 ∗ 4 = 1 K × 4 \rm{2^{10}*4=1K\times4} 210∗4=1K×4位
存储芯片片选线的作用
现在我们只有16K×1位的存储芯片,我们需要用这些芯片组成64K×8位的存储器。
解决方案:
16K×1表示我们的芯片容量是16K,每个存储单元保存1位的数据。如果我们用8个这样的芯片,对这8个芯片同时读写,就构成了8位。所以我们将这8个芯片分成一组,对这8个芯片相同的地址同时进行操作,这就构成了一个16位×8位的芯片。然后将这样的芯片布置4组,就构成了64K×8位的存储器。
我们来看下片选线:每一组8个芯片要同时进行工作才能够在每个芯片中读出或写入1位二进制信号,所以每一组的信号是连接在一起的。于是我们将64K空间进行划分:
0~16K-1,分配给第一组
16K~32K-1,分配给第二组
32K~48K-1,分配给第三组
48K~64K-1,分配给第四组
如果我要访问65535=64K-1,说明在第四组,其它三组的片选信号就是高电平,无效。于是最后一组芯片片选有效,对最后一组的8个芯片进行同时访问。
半导体存储芯片的译码驱动方式
①线选法
现在地址线是4条,数据线是8条,说明芯片容量是 2 4 × 8 2^4\times8 24×8。输入是4根线,输出是16根线,给定一个输入,输出这端只有一个是有效的。
假设我的输入是0000,同时读写控制电路时读选通。0000通过地址译码器后,我们就知道去第1条线取得数据。
问题:假设我输入的地址线是10M条,那么地址译码器的输出端就有 2 10 M \rm{2^{10M}} 210M条线,这时非常恐怖的,我们的存储芯片很难做到这么高的集成度。因此,对于一些容量稍大的半导体存储芯片,一般不用这种方式。
②重合法
线选法是将存储单元排布局一个线性的数组,而重合法是将存储单元布局成一个二维的阵列。我们将地址分成两部分,通常我们叫做行地址和列地址。行列地址分别进行译码,它们都只能有一条线是有效的。假设我们的数据线是1,行地址是全0,列地址是全0。于是一交叉,就得到第一行第一列的那个存储单元,并通过对应的线输出。
优点:如果我的地址线是20条,用线选法则地址译码器的输出是 2 20 = 1 M 2^{20}=1\rm{M} 220=1M条线。如果用重合法,则行列地址分别是10条,行列地址译码的输出都是 2 10 = 1 K 2^{10}=1\rm{K} 210=1K条,总共是2K条。2K远小于1M,这样就可以使得芯片集成度做的更高。
2.3 随机存取存储器(RAM)
2.3.1 静态RAM(SRAM)
保存0和1的原理
保存0和1的方式很多,比如我们可以用个开关来表示,断开是0,闭合是1。也可以用熔丝来表示,熔丝断开是0,熔丝连接是1。但是一旦写入数据到熔丝中,就很难修改,特别是熔丝断开了,很难再熔合起来。大家学过数字电路,触发器就可以保存0和1。静态RAM就是使用触发器。
静态RAM基本电路构成
静态RAM基本电路的核心就是这个4根管子的
双稳态触发器
。两端(T1、T4)用于存储信息,一端就是触发器的原端
,另一端就是触发器的非端
。如果T1是1,那么T4就是0。如果T1是0,那么T4就是1。T5和T6用于控制对存储文件进行读还是写。当需要读写时,它们就连通。下面只是一个存储元件,做到芯片里绝对不止一个,因此虚线框中的部分会在上下两个方向进行分布。T7和T8就是这一列共有的开关,叫做列开关
。由于是双稳态触发器,所以写操作时不光要在原端写入数据,还要非端写入这个数据的非。
静态RAM基本电路的读写操作
①读操作
要进行读操作,我们要给出行选信号
,控制T5和T6,让其打开。然后还要给出列选信号
,让T7和T8打开。然后现在是读有效,A上面的数据就通过T6这个晶体管送到位线上。同时,T8也是导通的,于是数据继续向前送到数据总线上。我们知道T5和T6打开后,触发器的非端也在进行数据输出,而列选择信号T7也是打开的,于是送到T7这里。但是无法继续向下了,因为没有使能写操作。
②写操作
写操作与读操作类似,给出行选信号和列选信号,打开T5、T6、T7、T8。此时写选择有效,于是数据从写放晶体管中间那条线输入,左边是数据的非,右边是数据,然后向上分别传输至触发器的非端和原端。
静态RAM芯片举例----Intel 2114
外观特性如下所示
这个芯片容量是4K,我们可以将其布局成64x64的一个阵列。使用前面的重合法,可以知道64/1=64个芯片构成一组,前面我们讲过了重合法控制一条数据线输出,而Intel 2114存储芯片的数据线是4条,如何实现一个列选信号控制4列数据?
Intel 2114 RAM 矩阵 (64 × 64) 的读操作
我们先将这64列分成4组,每组16列。行地址是6位,译码过后可以产生0到63共64个行选信号。4位列地址产生16位列选信号,每一个列选信号控制了每一组当中的一列。比如第0个列选信号控制了第1组、第2组、第3组、第4组中的第0列 。假设现在输入的行列地址分别是6个0和4个0,这时候:
①第一行所有单元被选择。
②经过列地址译码,每一组的第0列被选中
③如果是读操作,则 W E ‾ \rm{\overline {WE}} WE和 C S ‾ \rm{\overline {CS}} CS有效。第一行中每一组的第0列数据通过列控制管和读写电路输出到相应的数据线上,这就完成了读操作。
Intel 2114 RAM 矩阵 (64 × 64) 的写操作
2.3.2 动态RAM(DRAM)
保存0和1的原理
动态RAM使用电容来保存0和1。电容中保存了电荷,则我们认为存储了1。如果没有电荷,则被认为保存了0。
动态RAM的基本电路结构
①三管动态RAM
动态RAM的一种基本电路结构如下所示,三管动态RAM。其中, C g C_g Cg这个电荷保存0/1。T1、T2、T3都是控制管,读选择线有效则T2导通,写选择线有效则T3导通,数据通过T3向电容写入。
②单管动态RAM
另外一种结构只有一个晶体管,叫做单管动态RAM
动态RAM的基本电路的读写操作
①三管动态RAM的读写操作
----T4是一个预充电管,如果预充电信号有效,则T4被打开。Vdd通过T4对读数据线进行充电,使读数据线变成高电平。如果我们选择读出,则读选择线有效,T2导通。如果 C g C_g Cg现在保存的信息是0,即 C g C_g Cg这个电容没有进行充电,那么T1的栅极是低电平不会导通,读数据线保持高电平。也就是说,如果保存的信息是0,则读出的数据是1。如果保存的是1,则 C g C_g Cg是被充电的,T1的栅极有电,那么T1是导通的。数据线预充电的时候保存的是1,这个高电平就会通过T2和T1这两个管子进行放电,变成低电平。
----如果进行写入,写选择信号有效,则T3导通。写数据线会通过T3向 C g C_g Cg进行充放电。如果写入的是1,写数据线是高电平,通过T3向 C g C_g Cg充电使 C g C_g Cg保存1。如果写入低电平, C g C_g Cg通过T3放电, C g C_g Cg中保存0。
②单管动态RAM的读写操作
竖着的字线是控制线,如果相应的行被选中,则T被打开,电容就可以通过T进行充电或放电。如果 C s C_s Cs保存的是0,数据线就没电流。如果 C s C_s Cs保存的是1,数据线就有电流。通过数据线有无电流,就可以直到 C s C_s Cs保存的是0还是1。
三管动态动态RAM芯片(Intel 1103)
读操作
10位的地址线,说明容量是1K,每次读出或写入1位数据。行地址经过译码后产生的信号每一行对应两个,一个是读选择线,一个是写选择线。如果我们给出的行地址是00000,进行读操作,则第0行所有单元被选中。如果列地址也是00000,则第0行第0列交叉的那个单元被选中,通过读数据线将数据送到读写控制电路上,并向外进行输出。在这个电路中,有三角形的刷新放大器,这是因为电容会漏电,经过一段时间后电容上的信号会消失。所以使用刷新放大器就是每经过一段时间对电容里的信号进行重写。
写操作
现在我们要进行写操作,行地址是11111,列地址是00001,则第31行第1列的单元被选中。数据通过D端进行输入,经过读写控制电路通过写数据线将数据进行写入。
单管动态RAM芯片(Intel 4116)
外观特征
这里面有些不一样,它是16Kx1位,说明需要14根地址线。但是只有7根地址线,这14位地址实际上是经过两次进行操作。第一次接收到7位行地址,放到行地址缓存器中。第二次接收到7位列地址,放到列地址缓存器中。在右侧有个I/O缓存器,完成输入输出数据的缓存。两端连接了数据输入寄存器和数据输出驱动,完成数据输入输出。这个芯片上面还有个控制器,这个控制器以行选通信号、列选通信号、读写控制信号作为输入,产生行时钟、列始终、写时钟,控制芯片内部的读写操作。
读操作
芯片16K个基本单元电路被放在128行128列上。在这个电路中,横的方向是列,竖的方向是行。在63-64行之间,每一列都有个读放大器,这是个跷跷板电路。跷跷板电路是指如果将其中一段强制设置为1,另外一段就会成为0,即左右两侧电平相反。如果我的行地址是0111111,则第63行对应的行选择线有效,所有的晶体管被打开,电容中保存的信息被送出到读放大器的左侧。如果列地址是0000000,则第0列被选中,列选信号有效,对应的晶体管打开。读放大器右侧的数据通过晶体管送到读写线上,然后送到I/O缓冲、读出驱动。可以看出输出信号与原信号相反,因此,在读放大器右侧电容存储0/1的逻辑也要相反。比如读放大器左侧是有电为1,没电为0,则右侧应该是有电为0,没电为1。
写操作
动态RAM刷新
电容做得非常小,很容易漏电,在一段时间内我们需要对其信息进行再生。刷新与行地址有关,即每次刷新是刷新一行所有的电容
①集中刷新
把刷新的这段时间集中在相对集中的一段时间内。我们假设存储单元是128x12的矩阵,存取周期是0.5us,对所有的电容进行一次刷新的周期是2ms。2ms也就是4000个存取周期,前面的3872个周期可以供CPU、I/O对动态RAM进行读出或写入,后面这128个周期专门用于对芯片的刷新操作。这128个周期中,无论是I/O还是CPU,都无法与芯片进行信息交互,这段时间叫死区
②分散刷新
以128x128矩阵为例,存取周期假设为1us。这个存储周期就是下面的 t C t_C tC,它包含了 t M t_M tM和 t R t_R tR。 t M t_M tM是专门用于数据存取的时间,为0.5us, t R t_R tR专门用于刷新一行电容。这样看来,每一个us我们就刷新一行,128个us我们就将这128行刷新完了。2ms内,我们将所有行刷新了2000/128=15.6次,这实际上是一种过度刷新,动态RAM不需要这么频繁的刷新。虽然没有死去,但是读写周期变成原来两倍,性能下降
③分散刷新与集中刷新相结合(异步刷新)
把2ms分成128份,每15.6us刷洗一次。相对于单独的这15.6us,这时集中刷新。相对于整个2ms,这是分散刷新。这样每2ms所有电容刷新一次,死区仅0.5us,如果将死区安排得好,如安排在CPU进行指令译码的时候,就不会出现死区。
2.3.3 动态RAM和静态RAM的比较
集成度:动态RAM每一个单元电路非常简单,包含了1个晶体管1个电容。静态RAM的单元电路比较复杂,包含了6个晶体管。所以动态RAM集成度更高
芯片引脚:动态RAM行列地址可以分别进行传输,地址线条数可以减少为原来的一半,芯片的管脚数也就减少。而静态RAM为了速度,不会分别传输行列地址再进行译码,这样比较花费时间。
功耗:DRAM只是对电容充放电,而SRAM会对一些晶体管持续供电
由于SRAM速度快,集成度低,所以用来做缓存Cache。DRAM用来做主存,拔出你的内存条,上面的那些芯片就是DRAM芯片。