目录
内存控制器
S3C2440是三星公司开发的一款基于ARM9内核(ARM920T CPU core)的微处理器,它的数据总线是32位宽,故这是一颗32位的芯片。
CPU只管向内存控制器发出一个地址,内存控制器负责其余的所有工作。它根据该地址选择不同的BANK模块,然后从模块中得到数据或者发送数据到模块中。对于GPIO/门电路接口、协议类接口,内存控制器都不会把地址输出到外部;但是对于内存类接口,则会把地址输出到外部,比如Nor Flash、网卡、SDRAM。
CPU把地址发送给内存控制器,内存控制器根据不同的地址来选择发送哪个片选信号。只有当一个内存设备的片选信号被选中时,该内存设备才会工作。所以,同一个时刻只有一个设备被选中,不选中的芯片不工作。所以说,GPIO、UART、IIC、SDRAM、DM9000和Nor Flash都属于CPU统一编址。
需要特别注意的是,Nand Flash不属于CPU统一编址,它和CPU之间没有连接任何地址线。
S3C2440的地址空间
由上图可知,不同BANK的基地址是不同的。Nor Flash使用BANK0,那么它的基地址就是0x0;网卡DM9000使用BANK4,它的基地址就是0x20000000;SDRAM使用片选6,基地址是0x30000000。
图片中的SROM表示ROM或者SRAM类型的存储器。通过阅读用户手册,可知内存控制器具有如下特性:
- 支持软件编程选择大小字节序
- 每个BANK的地址空间都是128MB,总共8个BANK,合计1GB空间
- 可编程选择总线的位宽(8/16/32位),但是BANK0只支持两种位宽(16/32位)
- 共有8个BANK,其中BANK0~BANK5只支持外接ROM或SRAM,BANK6、BANK7还支持外接SDRAM
- BANK0~BANK6的起始地址是固定的
- 由于可以编程设置BANK6和BANK7的大小(二者需要相等),故BANK7的起始地址是可编程选择的
- 每个BANK的访问周期都是可编程控制的
- 可以通过外部的wait信号延长总线的访问周期
- 外接SDRAM时,支持自刷新(self-refresh)和省电模式(power down mode)
- 当访问相应的地址时,存储控制器会自动将对应的nGCSx引脚输出低电平,从而选中外接设备
当OM[1:0]位0b01或0b10时,不使用Nand Flash启动设备,即使用Nor Flash启动。从如下电路原理图可以看出,
Nor Flash外接在了BANK0上,当使用非Nand Flash启动时,Nor Flash对应的地址空间为0x0000 0000~0x7FF FFFF。
与此同时,BANK0的数据总线位宽应该设置为16位或32位。这是通过OM[1:0]引脚来进行设置的,如下图所示:
由开发板电路原理图可知,OM1接地强制为0,所以当是NorFlash启动时,数据总线宽度为16位。
我们查看用户手册,数据总线宽度和地址线接线的关系如下表所示:
由于我们硬件选择的是16位的数据总线宽度,所以需要将SoC的A1地址线接到NorFlash的A0地址线上,如下图所示:
SDRAM
定义
SDRAM:Synchronous Dynamic Random Access Memory,同步动态随机存储器。同步是指其时钟频率和CPU前端总线的系统时钟相同,并且内部命令的发送与数据的传输都以它为基准;动态是指存储阵列需要不断的刷新来保证数据不丢失;随机是指数据不是线性依次存储,而是自由指定地址进行数据的读写。
物理BANK
传统内存系统为了保证 CPU 的正常工作,必须一次传输完 CPU 在一个传输周期内所需要的数据。而CPU 在一个传输周期能接受的数据容量就是 CPU 数据总线的位宽,单位是 bit(位)。控制内存与 CPU之间数据交换的北桥芯片也因此将内存总线的数据位宽等同于 CPU 数据总线的位宽,而这个位宽就称之为物理 Bank(Physical Bank,下文简称 P-Bank)的位宽。在一些文档中,也把 P-Bank 称为 Rank。
每个内存芯片也有自己的位宽,即每个传输周期能提供的数据量。理论上,完全可以做出一个位宽为64bit 的芯片来满足 P-Bank 的需要,但这对技术的要求很高,在成本和实用性方面也都处于劣势。所以芯片的位宽一般都较小。台式机市场所用的 SDRAM 芯片位宽最高也就是 16bit,常见的则是 8bit。这样,为了组成 P-Bank 所需的位宽,就需要多颗芯片并联工作。对于 16bit 芯片,需要4颗(4×16bit=64bit)。对于 8bit 芯片,则就需要 8 颗了。
对于S3C2440来说,由于其CPU核是32位的,故其P-BANK的位宽也是32bit。此时,对于开发板所采用的内存芯片EM63A165TS-6G,
这是16bit的芯片,一个P-BANK需要2颗芯片。由于我们只使用了两片EM63A165TS-6G并且接到了BANK6上,所以我们的开发板只有一个物理BANK。
逻辑BANK
对于单独的一个内存芯片,涉及的主要概念就是逻辑BANK。对于我们所使用的EM63A165TS-6G芯片,其单独一个芯片内部有4个逻辑BANK(4M word x 16-bit x 4-bank)。
简单地说,一个逻辑BANK 就是一个存储阵列。因为如果是管道式存储(就如排队买票),就很难做到随机访问了。阵列就如同表格一样,将数据“填”进去,你可以把它想象成一张表格。和表格的检索原理一样,先指定一个行(Row),再指定一个列(Column),我们就可以准确地找到所需要的单元格,这就是内存芯片寻址的基本原理。对于内存,这个单元格可称为存储单元,那么这个表格(存储阵列)叫什么呢?它就是逻辑 Bank(Logical Bank,下文简称 L-Bank)。
由于技术、成本等原因,不可能只做一个全容量的 L-Bank,而且最重要的是,由于 SDRAM 的工作原理限制,单一的 L-Bank 将会造成非常严重的寻址冲突,大幅降低内存效率(在后文中将详细讲述)。所以人们在 SDRAM 内部分割成多个 L-Bank,较早以前是两个,目前基本都是 4 个,这也是 SDRAM 规范中的最高 L-Bank 数量。到了 RDRAM 则最多达到了 32 个,在最新 DDR-Ⅱ的标准中,L-Bank 的数量也提高到了 8 个。
这样,在进行寻址时就要先确定是哪个 L-Bank,然后再在这个选定的 L-Bank 中选择相应的行与列进行寻址。可见对内存的访问,一次只能是一个 L-Bank 工作,而每次与北桥交换的数据就是 L-Bank 存储阵列中一个“存储单元”的容量。在某些厂商的表述中,将 L-Bank 中的存储单元称为 Word(此处代表位的集合而不是字节的集合)。
SDRAM 内存芯片一次传输率的数据量就是芯片位宽,那么这个存储单元的容量就是芯片的位宽(也是 L-Bank 的位宽),但要注意,这种关系也仅对 SDRAM 有效。
所以,对于EM63A165TS-6G芯片,其内部的4个L-BANK,每个L-BANK的位宽为16bit。每次工作时,同时选中两颗芯片中的各一个L-BANK来同时工作。
硬件介绍
只有BANK6和BANK7支持SDRAM,而JZ2440开发板只把SDRAM接到了BANK6上,所以我们只需要设置BANK6即可。由于SDRAM外接在了BANK6上,所以内存的基地址是0x30000000。
由原理图可知,SDRAM由两片16bit的芯片组成,数据总线的宽度为32bit。
JZ2440开发板使用的SDRAM型号为EM63A165TS-6G,这款SDRAM芯片是台湾钰创科技公司(EtronTech)的产品。这款芯片的参数如下所示:
可知其最大工作频率为166MHz,所以我们之前设置的HCLK为100MHz满足其工作时钟频率要求。这款芯片是一个位宽为16位,容量为32MB的芯片。具体来讲,它内部有4个逻辑Bank组成,每个逻辑BANK均为4M x 16bit。
怎么计算内存的容量呢?显然,内存芯片的容量就是所有 L-Bank 中的存储单元的容量总合。计算有多少个存储单元和计算表格中的单元数量的方法一样:
存储单元数量 = 行数× 列数(得到一个 L-Bank 的存储单元数量)× L-Bank 的数量
在很多内存产品介绍文档中,都会用M×W的方式来表示芯片的容量(或者说是芯片的规格/组织结构)。M 是该芯片中存储单元的总数,单位是兆(英文简写 M,精确值是 1048576,而不是 1000000),W 代表每个存储单元的容量,也就是 SDRAM 芯片的位宽(Width),单位是 bit。计算出来的芯片容量也是以 bit为单位,但用户可以采用除以 8 的方法换算为字节(Byte)。
SDRAM信号
对于SDRAM,S3C2440提供了一组专用的SDRAM信号:
- SDRAM时钟有效信号SCKE
- SDRAM时钟信号SCLK0/SCLK1
- 数据掩码信号DQM0/DQM1/DQM2/DQM3
- SDRAM片选信号nSCS0
- SDRAM行地址选通脉冲信号nSRAS
- SDRAM列地址选通脉冲信号nSCAS
- 写允许信号nWE(该信号不是专用于SDRAM的)
SDRAM 芯片初始化、行有效、列读写时序
-
芯片初始化
在 SDRAM 芯片内部还有一个逻辑控制单元,并且有一个模式寄存器为其提供控制参数。因此,每次开机时 SDRAM 都要先对这个控制逻辑核心进行初始化。有关预充电和刷新的含义在下文有讲述,关键的阶段就在于模式寄存器(MR,Mode Register)的设置,简称 MRS(MR Set),这一工作由北桥芯片在 BIOS 的控制下进行,寄存器的信息由地址线来提供。
SDRAM 模式寄存器所控制的操作参数:地址线提供不同的 0/1 信号来获得不同的参数。在设置到 MR之后,就开始了进入正常的工作状态。 -
行有效(L-BANK有效)
初始化完成后,要想对一个 L-Bank 中的阵列进行寻址,首先就要确定行(Row),使之处于活动状态(Active),然后再确定列。虽然之前要进行片选和 L-Bank 的定址,但它们与行有效可以同时进行。
从上图可以看出,在 CS#、L-Bank 定址的同时,RAS(Row Address Strobe,行地址选通脉冲)也处于有效状态。此时 An 地址线则发送具体的行地址。如图中是 A0-A11,共有 12 个地址线,由于是二进制表示法,所以共有 4096 个行(212=4096),A0-A11 的不同数值就确定了具体的行地址。由于行有效的同时也是相应 L-Bank 有效,所以行有效也可称为 L-Bank 有效。 -
列读写
行地址确定之后,就要对列地址进行寻址了。但是,地址线仍然是行地址所用的 A0-A11(本例)。没错,在 SDRAM 中,行地址与列地址线是共用的。不过,读/写的命令是怎么发出的呢?其实没有一个信号是发送读或写的明确命令的,而是通过芯片的可写状态的控制来达到读/写的目的。显然 WE#信号就是一个关键。WE#无效时,当然就是读取命令。SDRAM 基本操作命令, 通过各种控制/地址信号的组合来完成(H 代表高电平,L 代表低电平,X 表示高低电平均没有影响)。此表中,除了自刷新命令外,所有命令都是默认 CKE 有效。
列寻址信号与读写命令是同时发出的。虽然地址线与行寻址共用,但 CAS(Column Address Strobe,列地址选通脉冲)信号则可以区分开行与列寻址的不同,配合 A0-A9,A11(本例)来确定具体的列地址。然而,在发送列读写命令时必须要与行有效命令有一个间隔,这个间隔被定义为 tRCD,即 RAS to CAS Delay(RAS 至 CAS 延迟),大家也可以理解为行选通周期,这应该是根据芯片存储阵列电子元件响应时间(从一种状态到另一种状态变化的过程)所制定的延迟。tRCD 是 SDRAM 的一个重要时序参数,可以通过主板 BIOS 经过北桥芯片进行调整,但不能超过厂商的预定范围。广义的 tRCD 以时钟周期(tCK,Clock Time)数为单位,比如 tRCD=2,就代表延迟周期为两个时钟周期,具体到确切的时间,则要根据时钟频率而定,对于 PC100 SDRAM,tRCD=2,代表 20ns 的延迟,对于 PC133 则为 15ns。
SDRAM 的读/写时序与突发长度
-
数据输出(读)
在选定列地址后,就已经确定了具体的存储单元,剩下的事情就是数据通过数据 I/O 通道(DQ)输出到内存总线上了。但是在 CAS 发出之后,仍要经过一定的时间才能有数据输出,从 CAS 与读取命令发出到第一笔数据输出的这段时间,被定义为 CL(CAS Latency,CAS 潜伏期)。由于 CL 只在读取时出现,所以CL 又被称为读取潜伏期(RL,Read Latency)。CL 的单位与 tRCD 一样,为时钟周期数,具体耗时由时钟频率决定。不过,CAS 并不是在经过 CL 周期之后才送达存储单元。实际上 CAS 与 RAS 一样是瞬间到达的。那为什么还有tCL的延迟呢?假设芯片位宽为 n 个 bit,列数为 c,那么一个行地址要选通 n×c 个存储体,而一个列地址只需选通 n 个存储体。但存储体中晶体管的反应时间仍会造成数据不可能与 CAS 在同一上升沿触发,肯定要延后至少一个时钟周期。
由于芯片体积的原因,存储单元中的电容容量很小,所以信号要经过放大来保证其有效的识别性,这个放大/驱动工作由 S-AMP 负责,一个存储体对应一个 S-AMP 通道。但它要有一个准备时间才能保证信号的发送强度(事前还要进行电压比较以进行逻辑电平的判断),因此从数据 I/O 总线上有数据输出之前的一个时钟上升沿开始,数据即已传向 S-AMP,也就是说此时数据已经被触发,经过一定的驱动时间最终传向数据 I/O 总线进行输出,这段时间我们称之为 tAC(Access Time from CLK,时钟触发后的访问时间)。tAC 的单位是 ns,对于不同的频率各有不同的明确规定,但必须要小于一个时钟周期,否则会因访问时过长而使效率降低。比如 PC133 的时钟周期为 7.5ns,tAC 则是 5.4ns。需要强调的是,每个数据在读取时都有 tAC,包括在连续读取中,只是在进行第一个数据传输的同时就开始了第二个数据的 tAC。
CL 的数值不能超出芯片的设计规范,否则会导致内存的不稳定,甚至开不了机(超频的玩家应该有体会),而且它也不能在数据读取前临时更改。CL 周期在开机初始化过程中的 MRS 阶段进行设置,在 BIOS中一般都允许用户对其调整,然后 BIOS 控制北桥芯片在开机时通过 A4-A6 地址线对 MR 中 CL 寄存器的信息进行更改。 -
数据输入(写)
数据写入的操作也是在 tRCD 之后进行,但此时没有了 CL(记住,CL 只出现在读取操作中),行寻址与列寻址的时序图和上文一样,只是在列寻址时,WE#为有效状态。
数据可以与 CAS 同时发送,也就是说写入延迟为 0。不过,数据并不是即时地写入存储电容,因为选通三极管(就如读取时一样)与电容的充电必须要有一段时间,所以数据的真正写入需要一定的周期。为了保证数据的可靠写入,都会留出足够的写入/校正时间(tWR,Write Recovery Time),这个操作也被称作写回(Write Back)。tWR 至少占用一个时钟周期或再多一点(时钟频率越高,tWR 占用周期越多)。 -
突发长度
突发(Burst)是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输所涉及到存储单元(列)的数量就是突发长度(Burst Lengths,简称 BL)。 在目前,由于内存控制器一次读/写 P-Bank 位宽的数据,也就是 8 个字节,但是在现实中小于 8 个字节的数据很少见,所以一般都要经过多个周期进行数据的传输。上文讲到的读/写操作,都是一次对一个存储单元进行寻址,如果要连续读/写就还要对当前存储单元的下一个单元进行寻址,也就是要不断的发送列地址与读/写命令(行地址不变,所以不用再对行寻址)。虽然由于读/写延迟相同可以让数据的传输在 I/O 端是连续的,但它占用了大量的内存控制资源,在数据进行连续传输时无法输入新的命令,效率很低。为此,人们开发了突发传输技术,只要指定起始列地址与突发长度,内存就会依次地自动对后面相应数量的存储单元进行读/写操作而不再需要控制器连续地提供列地址。这样,除了第一笔数据的传输需要若干个周期(主要是之前的延迟,一般的是 tRCD+CL)外,其后每个数据只需一个周期的即可获得。在很多北桥芯片的介绍中都有类似于 X-1-1-1 的字样,就是指这个意思,其中的 X 代表就代表第一笔数据所用的周期数。
非突发连续读取模式:
突发连续读取模式: -
Full Page突发传输
Full Page(全页)突发传输是指L-BANK里的一行中所有存储单元从头至尾进行连续传输。此时,具体的突发长度则是指内存芯片的L-BANK中一行的存储单元的数量。不过,这种全页的定义是狭义的。我们通常使用的则是广义上的页。因为内存系统每次传输都是以一个P-BANK位宽为单位的,需要多颗芯片同时工作。每次寻址时,P-BANK内每个芯片所**的L-BANK地址和行地址都是相同的。这样,在全页突发传输时,是对P-BANK所包含的每一个芯片内同一L-BANK中的同一行的所有存储单元进行读写操作。这些所有存储单元的总和就是整个系统而言的全页。
通过查询EM63A165TS-6G芯片的数据手册可知,其容量为4M word x 16-bit x 4-bank,故一个L-BANK的容量为4M word x 16-bit,行地址为A0-A12,共13列;列地址为A0-A8,共9列。芯片位宽为16bit。同时JZ2440开发板组成一个P-BANK的芯片数目为2,所以一个狭义的Full Page Length为29=512,一个广义的Full Page的大小为:29 x 16bit x 2 = 16,384bit,即2048Byte,即2KB。
另外,在 MRS 阶段除了要设定 BL 数值之外,还要具体确定读/写操作的模式以及突发传输的模式。突发读/突发写,表示读与写操作都是突发传输的,每次读/写操作持续 BL 所设定的长度,这也是常规的设定。突发读/单一写,表示读操作是突发传输,写操作则只是一个个单独进行。突发传输模式代表着突发周期内所涉及到的存储单元的传输顺序。顺序传输是指从起始单元开始顺序读取。假如 BL=4,起始单元编号是 n,顺序就是 n、n+1、n+2、n+3。交错传输就是打乱正常的顺序进行数据传输(比如第一个进行传输的单元是 n,而第二个进行传输的单元是 n+2 而不是 n+1),至于交错的规则在 SDRAM 规范中有详细的定义表,但在这此出于必要性与篇幅的考虑就不列出了。
SDRAM 芯片的预充电与刷新操作
-
预充电
由于 SDRAM 的寻址具体独占性,所以在进行完读写操作后,如果要对同一 L-Bank 的另一行进行寻址,就要将原来有效(工作)的行关闭,重新发送行/列地址。L-Bank 关闭现有工作行,准备打开新行的操作就是预充电(Precharge)。预充电可以通过命令控制,也可以通过辅助设定让芯片在每次读写操作之后自动进行预充电。实际上,预充电是一种对工作行中所有存储体进行数据重写,并对行地址进行复位,同时释放 S-AMP(重新加入比较电压,一般是电容电压的 1/2,以帮助判断读取数据的逻辑电平,因为 S-AMP是通过一个参考电压与存储体位线电压的比较来判断逻辑值的),以准备新行的工作。具体而言,就是将S-AMP 中的数据回写,即使是没有工作过的存储体也会因行选通而使存储电容受到干扰,所以也需要 S-AMP进行读后重写。此时,电容的电量(或者说其产生的电压)将是判断逻辑状态的依据(读取时也需要),为此要设定一个临界值,一般为电容电量的 1/2,超过它的为逻辑 1,进行重写,否则为逻辑 0,不进行重写(等于放电)。为此,现在基本都将电容的另一端接入一个指定的电压(即 1/2 电容电压),而不是接地,以帮助重写时的比较与判断。现在我们再回过头看看读写操作时的命令时序图,从中可以发现地址线 A10 控制着是否进行在读写之后当前 L-Bank 自动进行预充电,这就是上文所说的“辅助设定”。而在单独的预充电命令中,A10 则控制着是对指定的 L-Bank 还是所有的 L-Bank(当有多个 L-Bank 处于有效/活动状态时)进行预充电,前者需要提供 L-Bank 的地址,后者只需将 A10 信号置于高电平。
在发出预充电命令之后,要经过一段时间才能允许发送 RAS 行有效命令打开新的工作行,这个间隔被
称为 tRP(Precharge command Period,预充电有效周期)。和 tRCD、CL 一样,tRP 的单位也是时钟周期数,具体值视时钟频率而定。
读取时预充电时序图:图中设定:CL=2、BL=4、tRP=2。自动预充电时的开始时间与此图一样,只是没有了单独的预充电命令,并在发出读取命令时,A10 地址线要设为高电平(允许自动预充电)。可见控制好预充电启动时间很重要,它可以在读取操作结束后立刻进入新行的寻址,保证运行效率。 -
刷新
之所以称为 DRAM,就是因为它要不断进行刷新(Refresh)才能保留住数据,因此它是 DRAM 最重要的操作。刷新操作与预充电中重写的操作一样,都是用 S-AMP 先读再写。但为什么有预充电操作还要进行刷新呢?因为预充电是对一个或所有 L-Bank 中的工作行操作,并且是不定期的,而刷新则是有固定的周期,依次对所有行进行操作,以保留那些久久没经历重写的存储体中的数据。但与所有 L-Bank 预充电不同的是,这里的行是指所有 L-Bank 中地址相同的行,而预充电中各 L-Bank 中的工作行地址并不是一定是相同的。
那么要隔多长时间重复一次刷新呢?目前公认的标准是,存储体中电容的数据有效保存期上限是 64ms(毫秒,1/1000 秒),也就是说每一行刷新的循环周期是 64ms。这样刷新速度就是:行数量/64ms。我们在看内存规格时,经常会看到 4096 Refresh Cycles/64ms 或 8192 Refresh Cycles/64ms 的标识,这里的4096 与 8192 就代表这个芯片中每个 L-Bank 的行数。刷新命令一次对一行有效,发送间隔也是随总行数而变化,4096 行时为 15.625μs(微秒,1/1000 毫秒),8192 行时就为 7.8125μs。
刷新操作分为两种:自动刷新(Auto Refresh,简称 AR)与自刷新(Self Refresh,简称 SR)。不论是何种刷新方式,都不需要外部提供行地址信息,因为这是一个内部的自动操作。对于 AR, SDRAM 内部有一个行地址生成器(也称刷新计数器)用来自动的依次生成行地址。由于刷新是针对一行中的所有存储体进行,所以无需列寻址,或者说 CAS 在 RAS 之前有效。所以,AR 又称 CBR(CAS Before RAS,列提前于行定位)式刷新。由于刷新涉及到所有 L-Bank,因此在刷新过程中,所有 L-Bank 都停止工作,而每次刷新所占用的时间为 9 个时钟周期(PC133 标准),之后就可进入正常的工作状态,也就是说在这 9 个时钟期间内,所有工作指令只能等待而无法执行。64ms 之后则再次对同一行进行刷新,如此周而复始进行循环刷新。显然,刷新操作肯定会对 SDRAM 的性能造成影响,但这是没办法的事情,也是 DRAM 相对于 SRAM(静态内存,无需刷新仍能保留数据)取得成本优势的同时所付出的代价。
SR 则主要用于休眠模式低功耗状态下的数据保存,这方面最著名的应用就是 STR(Suspend to RAM,休眠挂起于内存)。在发出 AR 命令时,将 CKE 置于无效状态,就进入了 SR 模式,此时不再依靠系统时钟工作,而是根据内部的时钟进行刷新操作。在 SR 期间除了 CKE 之外的所有外部信号都是无效的(无需外部提供刷新指令),只有重新使 CKE 有效才能退出自刷新模式并进入正常操作状态。