主存储器
主存的基本组成

在我们之前知道的存储体 MAR和MDR上有增加了 驱动器 译码器 控制电路 读写电路等
不过MDR和MAR在内存中
主存和CPU的联系

主要就是读写的控制信号 和 数据总线和地址总线
主存中存储单元地址的分配
12345678H 这八位二进制是如何在主存储器中储存的呢?
假设我们的机器的存储结构的存储字长是32位:
意味着我们对存储器读或者是写的话,一次性可以读出或者写入32位的01码
但是我们存储器的编址单位都是字节,这在CSAPP中都学过的


这里也提到了大端法和小端法的不同 这都是CSAPP中的内容
主存的技术指标
- 存储容量
- 存储速度
存储时间
存储器的访问时间:就是说存储器得到地址一直到稳定的输入或者输出
- 读出时间:给出地址信号 一直到 数据线上得到稳定的输出
- 写入时间:给出地址信号一直到写入给定的存储单元中
存储周期
连续的完成两次独立的存储器操作所需要的最小时间间隔
存储器的带宽
单位时间内存储器存取的信息量
半导体存储芯片的基本结构

地址线都是单向的 由CPU指向存储设备或者IO设备
数据线是双向的
通过地址线和数据线算芯片容量:
假如说地址线由n根,是说共有
数据线为m根,是说一个存储单元可以存m位
所以公式为
片选线就是芯片选择线

内存条上有好多芯片 片选线就是指定往哪个芯片上存或者往哪几个芯片上存的
半导体存储芯片的片选线一般有两种标识
上面的横线的意思是低电平有信号
CS(chip select)芯片选择的缩写
CE(chip enable)芯片使能的缩写
读写操作可以用一根线标识或者两根线标识
- 一根线的时候
低电平写 高电平读 - 两根线的时候
片选线的作用
用16K * 1位的 存储芯片 组成 64K * 8位 的 存储器
16K * 1 表示的存储容量是16 每一个存储单元 放1位
如果我们用8个 16K * 1 位的芯片同时读写,每一个芯片就会给出或者是写入一位二进制信息,8个芯片放在一起位一组 就构成了一个可以存八位的单元

对这八个芯片形同的地址同时进行操作 每个芯片一位 就会同时操作六位
布置四组就是题目的要求

每八片时一起工作的,我们把每一组的片选线连接在一起
我们把64K空间进行划分 第一组就是0~16K-1 这样子 每一个地址都能同时操作8片的同一地方
半导体存储芯片的译码驱动方式
线选法

在图片上给出的是
数据线是从
地址译码器 输入是 4个信号 译码成了 16个信号 每一个输入 16根线中只有1跟线有信号
下图是一个读选通的过程
当地址线是4个0的时候,只有0这根片选线是可用的

但是问题是我们的存储器没有这么小的
如果说我们是1兆的存储器,进入是二十条线的 出来就是1兆条线 呃呃
重合法
实际上线选法是把整个存储单元做成一个线性的数组的样子
重合法是做成一个二维矩阵的样子

X叫行地址 Y叫列地址 分别译码 来确定存储单元
过程如图所示:

事实上其实0,31的数据也会输出 但是由于Y这上面Y31这边的管子(其实是栅级管)不导通 所以不会送到数据线上 没法得到输出
存就是两边
随机存取存储器(RAM)
静态RAM(SRAM)
Question:
- 既然是存储器 就要有存储元件 存储元件保存01的原理是什么?
- 基本单元电路是怎么构成的?
- 对单元电路如何进行读出和写入?
- 用单元电路做出来的典型芯片的结构是怎么样的?
- 这个芯片如何进行读出和写入操作?
其实保存01的方法有好多种,比如说我们可以通过一个开关来表示 比如说断开是0 连通是1。也可以用熔丝表示,但是熔丝一旦断开 再连起来 就非常难了
对于随机存取存储器的静态RAM的核心其实就是用了一个触发器

触发器是由四个管子构成的 t1-t4 这是一个双稳态的触发器 一端是0 另一端就是1
除了这四个管子之外,还有两个管子 t5 t6
t1 - t4解决了用什么样的电路来存放01 t5 t6 是用来解决我们对这个存储元件进行读或者写的,t5 t6是通过行地址选择来进行控制的,如果这个行地址选择一旦有效的话,两个管子就会导通
t5 t6叫行开关
一共是六个晶体管
其中不单单是这么一个 是这么多排在一起的
其中t7 t8是这一列的开关
当行地址被选择的 这一行上的t5 t6都会被打开
由于是双稳态的电路 当我们进行写入的时候 要给A和A'都写入数据 我们在A端输入数据 比如是0 在另一端我们是采用了 三态门 取反 变成1 给了A'
静态RAM基本电路读操作

值得注意的是前面也提到了 行都打开了 但是在t7这边被截止了 就是最右边的这个线没被画红
静态RAM基本带路写操作

举例:Intel 2114
外特性

WE是读写信号 低电平为写 高电平为读
CS为片选信号 只有为低电平的时候,这个2114芯片才能被选中
左侧是地址 1k个存储单元
右侧是数据线 每个存储单元读入读出4位信号
容量:1K * 4 -> 64 * 64 阵列

分成了四组 每一组是16列
行地址 是 6位 通过 译码器 变为64位 即64行
列地址 由于Intel 2114是想一次性 读写4位 所以Intel 2114分成了4组 每一组是16列 也就是图中译码完后的0-15 每一个列选信号控制了每一组当中的一列 比如说第0个列选信号控制的是第一二三四组中的第零列 刚好四位
Intel2114 读操作

Intel2114 写操作

动态RAM(DRAM)
解决以下的问题:
- 保存0和1的原理是什么?
- 基本单元电路的构成是什么?
- 对单元电路如何读出和写入?
- 典型芯片的结构是什么样子的?
- 动态RAM芯片如何进行读出和写入操作
- 动态RAM为什么要加进行刷新,刷新方法是什么?
前面也提到过了 保存0和1的方法其实有很多,我们在静态RAM的时候用的是双稳态触发器
动态RAM我们利用的电容 电容保存电荷为1
三管动态RAM

这是一个基本的结构 核心就是Cg电容
t1 t2 t3是是哪个控制管 控制读出和写入
读选择线有效 t2导通
写选择线有效 t3导通
下面我们来看一下三管动态RAM的操作过程
预充电信号有效 t4打开 Vdd通过t4会对读数据线进行充电 使得读数据线变成高电平
1.如果现在Cg当中保存的信息是0 也就是说这个电容并没有进行充电 t1的栅极就是低电平 t1不会导通,读数据线就会保持高电平
也就是说如果我们电容里面保存的数据是0 在读数据线上读出来的就是1

2.如果我们保存的信息是1 也就是说Cg这个电容是被充电的 那么T1的栅极就是1 有电 t1导通 这个时候读数据线保存的高电平就会通过t1 t2放点 变成低电平

这个过程说明我们读出的信息和原存的信息是相反的!!! 所以说我如果想读出里面存的数据的话,我要在读数据线上加一个非门
如果进行写入的话,写入的信息和存的信息是相同的
当要写入的时候 写选择线有效 为1 t3接通
- 如果写数据线为高电平 那么会通过t3 像Cg充电 Cg存1
- 如果写数据线为低电平 那么会通过t3 像Cg放点 Cg存0
单管动态RAM

原理都是保存在电容中
字线是控制线,如果相应的被选中 那么字线就会被选中 T就会打开 电容就可以通过t进行充电和放电了
三管动态RAM 芯片 Intel 1103


我们发现Intel1103其实就是有好多个这个三管动态RAM构成的 明显的能看到图片中每一个都有上线两根线 就是读选择线和写选择线
我们发现行地址译码器 的输出是每一行都对应了两个信号
这就说明在行地址译码器这个地方参加译码的不仅仅是地址,还有读写控制信号!
读操作:
如果我们给出的行地址是0 进行读操作 第零行读选择线有效,第零行所有的单元都被选中 进行读操作
列地址依然是0 第0列被选中 交叉单元被选中
该单元通过读数据线将数据送到读写控制电路上,同时向外进行输出

这儿有一个三角形的电子器件,这个器件是一个刷新放大器
使用刷新放大器的原因?
我们在存储1和0是通过电容存电荷这个原理来保存信息的,电容呢会漏电,经过一段时间后,电容上的信号会消失,所以采用刷新放大器把电容中保存的信息进行从现,没经过一段时间都对给定的单元电路中的信息进行刷新
写操作:
假设行地址是5个1 第31行所有的单元都被选中 写选择线有效
假设列地址是0001 第1列被选中 交叉单元被选中
数据通过D经过读写控制电路写入该单元

单管动态RAM 4116芯片

这个4116芯片是16K * 1位的
16K需要14根地址线的 但是这个芯片只有七根地址线 这14位地址是分两次进行传送的
- 第一次接收到的是7位行地址 放到行地址缓冲器当中
第二次接受到的是7位列地址 放到列地址缓冲器当中
右边有一个IO缓冲器 输入通过数据输入寄存器通过缓冲器输入 输出通过缓冲器和数据输出驱动输出
值得注意的是这个芯片有一个小的控制器:
就是上面那一部分
该控制器的输入是:
- 行选通信号
- 列选通信号
读写控制信号
产生的是:
- 行时钟
- 列时钟
写时钟
进一步控制了读操作和写操作

16K 的存储单元 被放在128行 128列上
在第63行到64行之间 每一列都有一个读放大器
这个读放大器是一个跷跷板电路 所谓的跷跷板电路 就是说 如果一端为0 另一端就为1
读操作:
加入写入的行信号是1000000的话,那么第63行被选中 管子打开 这个时候如果电容有点 那么读放大器左端就是1 右端就是0 如果电容没有电,那么读放大器左端就是0 右端就是1
然后给出列地址 相对应的列的晶体管打开 读放大器右侧的信号送入读写线 经过IO缓冲 经过输出驱动 输出

但是有一个问题 就是
0-63行:
- 电容有电 读选择线上读到的是0
电容没电 读选择线上读到的是1
64行往后 读放大器上的这些行
- 电容有电 读选择线上读到的是1
电容没点 读选择线上读到的是0
????
啊那为啥加放大器????
写操作:
要写入的数据通过数据输入 通过IO缓冲 被放入数据线
所有的行被选中
当列地址输入之后
唯一的那个管子变得有效
数据从数据线传到读放大器
如果再读放大器左边当时就是数据线上是0 电容就有电

其实存的时候就反转了 读的时候再反转 其实也不会出错哈哈哈哈
但是为啥放大器
好像是为了再生 恢复电路 上面提到过
这就引出了动态RAM的刷新
动态RAM刷新
动态RAM的原理 就是通过电容来存储0 1
但是电容的弊端是会漏电
也就是说 如果我们一段时间不对电容中的信息再生的话 那么这部分信息就丢失了
比如说对电容充过电 一段时间后就 漏完了
所以要进行动态RAM刷新
这个动态RAM刷新是跟行地址有关的
换句话说 就是每一次刷新操作刷新的是动态RAM当中一行所有的基本单元

对于当时学的Intel 1103 我们发现
当行信号有效后 其实这一行的所有单元都会选中 而且这一行所有数据都会到读数据线上?
我们如果在读数据线和写数据线之间放一个刷新放大器的话 那么就会再次写入存储单元
-
集中式刷新
将刷新的时间断放到相对集中的时间断来操作
假设 存取周期为0.5微秒 动态RAM刷新的整个过程周期为2ms
依然为128 128矩阵作为例子

2ms一共是4000个存取周期
前3872个周期可以供CPU或者IO进行读出或者写入
后128个周期用于刷新再生 这段时间是不能用的 叫“死区”
集中刷新存在的问题是 在死区这段时间里 如果CPU和IO想要写入或者读写 CPU只能进行等待
-
分散刷新
假设存取周期为1微秒
存取周期从0.5微秒变成1微秒是因为

整个存储周期就是图片上的tc
原来的存储周期是tm 也就是CPU和IO要读写的那个时间
tr专门用于动态RAM某一行的刷新
这种方法128微秒就把128行刷新完了 过渡刷新 刷的太快了?
虽然没有死区 但是把读写周期加长了 芯片的性能下降了
-
异步刷新:分散刷新和集中刷新 相结合

那就把2ms分成128分 每一份是15.6微秒
每一段时间里最后进行某一行的刷新
相对于每一个15.6 微秒来说 这是一个集中式刷新
相对于整个来说 这是个分散刷新
这样每行没2ms刷新一次 没有过渡刷新
死区为每15.6微秒中的0.5微秒
如果这段时间安排的好的话,比如安排在指令译码阶段 不会影响CPU和IO对静态RAM的读写就不能叫出现了死区
只读存储器(ROM)
只读存储器一般用于保存系统程序或者是系统的配置信息
掩膜 ROM

最上面这一排是预充电管 VCC可以概括为电路的供电电压或者电源电压
当VCC是高电平 经过预充电管充电以后 所有的位线都是高电平(位线就是竖着的线)
行信号列信号选择交叉点被选中
如果这个点上有管子 那位线就接地了 位线高电平变成低电平
如果没有管子 仍然是低电平
位线上的数据 通过列管空管 只有这一列的数据能到达最下面这根线上 然后通过读放大器 和取反 输出

呃呃其实往里存的时候
如果行和列的交叉点有MOS管的话 就是1 没有 就是0
行和列有没有MOS管 是厂家在生产芯片的时候制作的,用户是无法改变的
PROM(一次性编程)

核心就是这个熔丝
通过熔丝断没断区别1 和 0
要想保存0 就用一个大的电流把熔丝烧断
一旦断了就没法复原了 所以这是一种破坏性的编程和烧录
EPROM(多次性编程)
N型沟道浮动栅MOS电路

- G 栅极
- S 源
D 漏
按理说当G为高电平 D和S应该是导通的
但是对于N型沟道浮动栅MOS管,如果我们在D加上正电压,那么源和漏端会形成一个浮动栅 使得D和S没法导通 保存0
如果不加电压 没有浮动栅 保存1
也就是说 希望保存0的地方 我们给D加高电压 希望保存1的地方我们不加电压
如果要更改的话,我们要驱散浮动栅
驱散浮动栅要用紫外线来擦洗(用紫外线照射)

这种芯片有一个石英窗口 ,紫外线通过石英窗口来进行浮动栅的驱散
EEPROM
电可擦写
局部擦写
全部擦写
Flash Memory 闪存
存储器与CPU的连接
存储器容量的扩展
要构成一个主存储器 往往需要多个存储芯片公共组成
对于存储器容量的扩展有三种
- 位扩展
- 字扩展
- 同时扩展
位扩展
目的:增加存储器的字长
核心:两个芯片当成一个芯片来用
eg:1K * 4位芯片 -> 1K * 8位 存储器
1K * 4 位的意思是说 我们手头的这个芯片有10根地址线,1K个存储单元,每个存储单元可以存储4位数据
但我们要构成的存储器要存储8位数据
从原理上将 我们把两个芯片放到一起 只要一起片选就好
字扩展
目的:增加存储字的数量
eg:1K * 8 位存储芯片组成 2K * 8位的存储器
我们使用两片 1K的 来组成2K的存储器
但是值得注意的是2K的存储器 需要有11根地址线
但是1K的只有10根地址线
我们把地址线和数据线都接入这两个芯片 如下:

这时候我们不想让两个芯片同时工作的办法就是:
第11根地址线(其实编号是10)为0的时候 放入第一个存储器 如果为1放入第二个存储器

从11个0开始 到1个0 10个1 这1k空间放给了第一个芯片 其余的在第二个芯片
字位同时扩展
eg:1K * 4位 存储芯片 组成 4K * 8位的存储器

值得注意的是 通过a11 和a10进行片选 :
00选择第一组(两个)
01选择第二组
.......
所以这里用了一个2-4的译码器
存储器与CPU的连接
地址线的连接
存储器要根据CPU给出的地址找到相应的存储单元。
这个存储单元是哪个芯片的哪个存储单元
数据线的连接
CPU的数据线可能比存储器的数据线条数要多 所以我们为了CPU能认,所以要对存储器的数据线做位扩展
- 读写控制线的连接
片选线的连接
落在哪几个芯片上
确认CPU这次访问访问的存储器 而不是 IO
- 合理选择芯片
选择ROM和RAM?
保存系统程序 ROM
配置信息 ROM
用户程序区 系统程序运行区 RAM
- 选择两个1k * 4 还是一个 1k * 8的
eg:

MREQ(低电平有效)作为访存控制信号的意思是说
低电平即为访问存储器
高电平为访问IO设备
6000H~67FFH为系统程序区
6800H~6BFFH为用户程序区
-
先转换成二进制
系统程序区:
0110 0000 0000 0000
......
0110 0111 1111 1111
用户程序区:
0110 1000 0000 0000
.......
0110 1011 1111 1111
-
确定芯片的类型
对于系统程序区 我们使用ROM
系统程序区是从低11位全为0 变成低11位全为1
即2K * 8位(CPU地址线位8位)
由于正好有一片2K * 8的ROM
所以选择这片ROM
对于用户程序区 我们选择RAM
从后10位全为0 到后10位全为1
位1K * 8
只能用题目中的1K * 4 的RAM了 只能用两片
选择原则是芯片数量尽量少!
-
分配地址线
对于ROM 2K需要11根地址线 即a0-a10
0110 0|000 0000 0000
0110 0|111 1111 1111
竖线右边是直接和芯片连接 左边作为芯片的选择信号
对于两片 1K * 4 的RAM 需要10根地址线 即a0-a9
0110 10|00 0000 0000
0110 10|11 1111 1111
右边接到两片RAM上

-
确定片选信号
教材上给出的是74138译码器

74138译码器有三个输入CBA
74138的G1高电平 G2A G2B要是低电平 才能工作
我们发现A14 一直为1 所以可以接入G1上
MREQ(一定不要忘了MREQ)和 A15一直是0 接到G2A 和G2B
那么a11 a23 a13就接到abc上
我们其实发现对于74128的输入就是abc这三个输 那么3个二进制数可以表示0~7 刚好就是输出的y0~y9
所以在这里100 其实就是y4 所以是从y4接出来的
同时注意在RAM的时候要求a10为 CBA为101 从y5接出来并起来
-
信号线的连接
信号线 读写信号只需要和RAM相连
如果ROM有OE 也需要和信号线相连(OE是输出允许,低电平有效)
-
数据线的连接
存储器的校验解决问题
-
为什么要对存储器的信息进行校验?
以内存为例
内存的信息 动态RAM保存在电容当中 如果是静态RAM 保存在触发器中
如果内存所处的电磁环境比较复杂 或者收到带电粒子的打击
就会造成电容的充放电 和 触发器的翻转
存放在存储器中的信息就会出错
内存中是放了程序的代码中 如果不进行校验 如果出错 就会造成程序运行错误
-
为了能够校验出信息是否正确,如何进行编码?
-
纠错和检错能力和哪些因素有关
-
校验出信息出错后如何进行纠错?
-
除了教材上给出的校验码,还有哪些校验码 原理是什么?
汉明码介绍
我们有一个合法代码的集合
如果代码集合是
如果001 发生错误 变成000 还被认为是正确的 显然代码集合长这样不可取
如果代码集合是
如果代码发生错误变成了100 可以检测出错误来
但是不知道这个错误是110 还是000 还是101 变出来的
检1位错,纠0位错
如果采用三倍冗余的方式来存储0和1 000存0 111存1
可以判断1位错 但是很难判断两位错
检1位错,纠1位错
四备份冗余的方式
只能检测到两位错 凑错只能到1位错
五备份冗余
检2位错 纠2位错
编码的检测能力和纠错能力和什么有关?
任意两组合法代码之间的二进制位的最小差异数
差异的越多,检错能力越强 纠错能力越强
新概念:编码的最小记录:就是任意两组合法代码之间的二进制位数的最小差异
- L——编码的最小距离
- D——检测错误的位数
- C——纠正错误的位数
汉明码是具有一位纠错能力的编码
汉明码采用奇偶校验的方式
汉明码采用分组校验的方式
假设有一串代码是00100011 采用汉明码偶数校验 需要加一位校验位 使得1位偶数
变为1 00100011
假如最后的1不是偶数个 那说明一位出现了错误 哪一位不知道
但我们可以通过分组来更精确的划定是哪一个范围出错
我们采用两位奇偶校验位 那就是把这八位分成两组
每一组加一个校验位 就得到了一个新的校验码:1 0010 0 0011
我们这个例子采用的是划分的方式分组 组和组之间没有重叠
汉明码实际上是采用了一种非划分的方式分组 组合组有交叉
假设有7位 交叉处放和

对着三组分别用异或门(异或的规则是相同为1不同为0)
分别得到P3P2P1
- 如果得到3个0 那么无擦错
- 如果是001 那么是第一组唯一的位置出错 那就是1
如果为101 那么就是第三组和第一组的公共位置出错 那就是5
校验位是这一组自己有的 所以是124 都放在2的a次方的位置
汉明码的特征和求解
汉明编码的特征是
第一组 位置的二进制数 从右边数第一位为1 如XXXX1
第二组 XXX1X
……
也就是说如果X的地方为1 那么就是两组所共有的
如果是X都是0 那就是这一组所独有的
汉明码的组成
汉明码的组成需要添加?位检测位 换句话说 就是分成几组?
校验位的位置?
2的整数次方
检测位的取值?
跟奇偶校验的 个数有关
eg:0101按“偶校验”配置汉明码
1. 确定需要添加多少位汉明码
n=4 根据
2. 汉明码排序
校验位放在2的整数次放位置
就是1,2,4的地方 其他地方放上0101
那么就是C1 C2 0 C4 1 0 1
3. 分组确定C1 C2 C4的值
第一组有 01 11 101 111 即 1,3,5,7位 这四个位置上已经有偶数个1了
那么C1为0
第二组有 10 11 110 111 即 2,3,6,7
C2为1
第三组有 100 101 110 111 即 4,5,6,7
C4为0
所以最终汉明码为0100101

提高访存速度的措施
在计算机发展的过程中
- CPU的速度提升的非常快 指数级增长
- 存储器的提升 很慢
但是CPU执行程序的时候需要的指令和数据要来自于内存,运行结果要放到内存
CPU得不到所需要的数据和指令就只能空等
这个叫做存储墙现象
- 采用高速器件
- 采用层次结构Cache-主存
- 调整主存结构
调整主存结构
单体多字系统

比如说CPU的字长为16位
我们可以设置存储器的存储字长为64位 每一次CPU都可以访问出四个机器字长
存在的问题是
- 我往里存16位的时候 要经过单字长寄存器和数据寄存器然后才能存到存储体中 往里写的时候可能会造成这64位中 有48位被修改 这样就得用另外的硬件 来判断和实现防止出错
- 如果我要去取的指令不是连续存放的
多体并行系统
-
高位交叉
所谓的高位交叉就是一种顺序编址
前两位是编号编码 后四位是编码
很自然
如果每一个存储体都有自己的MAR MDR 和译码器 驱动器 那么这四个存储体就可以并行的工作
CPU给出一个地址:
- 体号
- 体内地址

在这种电路下,每个存储体都可以独立进行工作,而且每个存储体都有自己的控制电路来完成这个缓存操作
存在一个问题:
如果用户使用一个程序的话,程序按序存储
按序执行的时候
CPU不停的访问第一个存储体
那么其他三个存储体虽然是并行的 但好像并没有并行哈
这种用高位选择存储体然后低位去找存储体内容的方式 其实就是之前的存储器容量的扩展
-
低位交叉
各个体轮流编址 说白了就是横着编址
高位为体内地址
低位为体号

分离式通信

设四体低位交叉存储器,存取周期为T,总线传输周期为
,为实现流水线方式存取