内存控制器与SDRAM

内存接口概念:

通常ARM芯片内置的内存很少,要运行Linux,需要扩展内存。ARM9扩展内存使用SDRAM内存,ARM11使用 DDR SDRAM。S3C2440通常外接32位64MBytes的SDRAM,采用两片16位32M的SDRAM芯片,SDRAM芯片通过地址总线、数据总线、若干控制线与S3C2440芯片相连。

芯片资源:

S3C2440有ADDR0~ ADDR26共27根地址线(128M),其中ADDR0,ADDR16~ ADDR26为GPIO/地址线复用,GPIO只能是输出,DDR1~ADDR15为专用地址线,就只能是当地址线用。有32根数据线DATA0 ~DATA31全部都是专用数据线。虽然是32位的芯片,CPU发出的地址是32位的,但是只有27根地址线,所以32位地址只取了0 ~26位来使用。
内存控制器与SDRAM_第1张图片
外接的存储器可以像GPIO模块,USRT模块,I2C模块等一样,由CPU发起,通过内存控制器进行操作,只不过这个外设是在片外的。NAND FLASH和外接的存储器不是同一类型的,片内有一个专门的NAND控制来对外接的NAND FLASH硬件进行控制,所以NAND FLASH又属于另外一部分。
内存控制器与SDRAM_第2张图片
所有的外接存储器都是共用地址线和数据线,但是每个外接存储器有各自连接的独立片选信号引脚,以此可以得以区分当前地址线和数据线的外接模块。
内存控制器与SDRAM_第3张图片
片选信号是根据你的地址范围,自动进行拉低操作的,不需要再人为的去控制引脚。外接存储器处于写入或读取状态,要根据外接存储器的特性进行对引脚的操作,有的需要一个根W引脚,一个R引脚,有的只需要一根引脚控制W/R。

位宽:

这是官方说明书给出的8bit,16bit,32bit存储器的接法示意图:
8bit内存
内存控制器与SDRAM_第4张图片
16bit内存
内存控制器与SDRAM_第5张图片
两片16bit内存组合成的32bit内存
内存控制器与SDRAM_第6张图片

  • 8bit的地址线都是从A0接起
  • 16bit的地址线都是从A1接起
  • 32bit的地址线都是从A2接起
    之所以要这么连接,原理其实也是很简单,我们把内存的地址用一个图画出来,相信很快就能看懂了:
    内存控制器与SDRAM_第7张图片

假设CPU执行以Byte取值:

mov   r0, #3
ldrb  r1,[r0]     // 从地址3(00011)以Byte为单位取值到r1

在这里插入图片描述
对于8bit,A0-A0,,A1-A1,A2-A2,所以CPU发出什么地址,内存控制器就转发给存储器什么地址,返回值是精确哪个地址就是哪个地址。
对于16bit,A0没接,A1-A0,A2-A1,所以内存控制器转发给存储器的地址向右移动了一位,转发的不是3,而是1,但是16位的存储器返回的数据是16位的,所以返回到CPU的是Byte3|Byte2,但是内存控制器根据A0的0/1对这个返回的16为数据进行挑选,高低电平选择高位,低电平选择低位,所以返回到CPU的值依然是Byte3。虽然A0没接,但是依然是在起作用。
对于32bit,A0,A1没接,A2-A0,A3-A1,所以内存控制器转发给存储器的地址向右移动了两位,接收到的不是3,而是0,但是32位的存储器返回的数据是32位的,所以返回到内存控制器的是Byte3|Byte2|Byte1|Byte0,但是内存控制器根据A0,A1的0/1对这个返回的32为数据进行挑选,所以返回到CPU的值依然是Byte3。

假设CPU执行默认取值:

32位的机器,默认是以4字节进行取值:

mov   r0, #4
ldr   r1,[r0] 

内存控制器与SDRAM_第8张图片
对于8bit,CPU会发出1次取值地址,内存控制器转发了4次连续的地址出去,返回4个字节的数据,内存控制器再把这4个字节的数据拼凑成一个32位数据,返回给CPU
对于16bit,CPU会发出1次取值地址,内存控制器转发了2次连续的地址出去,返回2个16位的数据,内存控制器再把这2个16位的数据拼凑成一个32位数据,返回给CPU
对于32bit,CPU会发出1次取值地址,内存控制器转发了1次连续的地址出去,返回1个32位的数据,内存控制器直接把这个32位数据,返回给CPU
整个过程虽然看似复杂,但是根据不同位宽的不同接线方式,CPU只要发出取值地址,内存控制器就会自动的把所有的复杂的事情全部处理完返回给CPU一个数据,全程CPU不需要参与过程。

连接两片16位32M的SDRAM实例:

内存控制器与SDRAM_第9张图片
S3C2440的SDRAM控制线:
1、SDRAM片选----nGCS6(对应ARM的地址0x3000 0000);nGCS7(对应ARM的地址0x38000000),每一根片选可联接128MBytes内存。现在扩展64MBytes内存,只需一根片选线,通常为nGCS6。
2、nWE----写使能。
3、nSRAS----SDRAM行地址开关。
4、nSCAS----SDRAM列地址开关。
5、写字节使能四根线----nWBE[3:0]。4个字节共32位,为一个数据单元。
6、SDRAM时钟两根线----SCLK[1:0]。两根线分别联接两个SDRAM芯片。
7、SDRAM时钟使能----SCKE。
S3C2440与两片内存联接时,用到的地址线是15根:13根行列复用地址线,两根Bank 线。

Bank的概念

Bank相当于块,一个EM63A165TS-6G内有四个内存块,每块16*4M内存单元。
每地址对应16bits,共有4M (2的22次方)地址范围,因此应该有22位地址线,寻址时22位的地址分两次(行地址和列地址)输入SDRAM芯片,nSRAS有效时,ADDR[2:14] 输入的是行地址,nSCAS有效时,ADDR[2:14]输入的是列地址。所以寻址一个内存单元至少需要两个时钟时间,第一个时钟行地址,第二个时钟列地址,然后才能找到对应内存单元。
地址线从ADDR2开始使用,而不是ADDR0开始使用,这个上面已经讲过原理了。
S3C2440的数据线32根,其中DATA[15:0]这16根联接第一块EM63A165TS-6G芯片,DATA[31:16]这16根联接第二块EM63A165TS-6G芯片。

为什么要两片16bit内存组合在一起

ARM是32位处理器所以它一次处理数据都是以32位为单位的,也就是说它读或者写数据时,地址只能为0x0、0x04、0x08、。。。即4字节对齐,因为一般DDR的数据线都为16位,所以为了得到32位的数据,一般都是将2个DDR连在一起,它们的地址相同,所以对已DDR而言是一个地址对应4个字节(因为一个DDR对应2个字节,两个DDR就对因4个字节,低16位存储在第一片,高16位存储在第二片)

一片内存只接了13根地址线是如何寻址32M的地址?

bank0和bank1就是用来选择4片存储块的,bank0和bank1是用来确定是那个存储块,在
EM63A165TS-6G中有4个bank,00代表bank0, 01代表bank1, 10代表bank2, 11代表bank3,需要知道的是这4片存储块是相互独立的,并且每个存储块都是阵列结构,所谓阵列结构指的是它是由行列组成的。
我们可以把一个bank看做是由一个个方格组成的存储块,而方格的个数就是4Mbit,每个方格的容量则为16bit,你要想确定一个方格的地址首先要确定它的行地址,再确定它的列地址,两线相交确定一点,这一点就是你要的地址。
一般SDRAM的地址线都采用分时复用原则,即先送行地址,再送列地址,EM63A165TS-6G这款芯片Row address : RA0 ~ RA12, Column address : CA 0 ~ CA8,即前9个地址线是复用的。
所以寻址的时候先发送RA0 ~ RA12行地址,在发送CA 0 ~ CA8列地址,而RA0 ~ RA8和CA 0 ~ CA8用的其实是同一个管脚,按照行地址13个,列地址9个算,最多能寻址2^22,即4194304个地址,换算成Mbit刚好是4Mbit,即一个bank的大小,这就是为什么寻32M只用了13根地址线的原因。

为什么bank0和bank1与2440的ADDR24和ADDR25连接?

bank0和bank1是用来选择存储块的,32M的空间需要25根地址线寻址,但是
对于EM63A165TS-6G只需要24根,因为它每个存储单元存储2个字节,我们来分一下,这24根地址线的前13根行地址,紧接着的9根为列地址,那么最后两根是干嘛?显而易见它是bank地址,用来选择存储块,所以BANK0接23, BANK1接24,但是由于我们是从ADDR2开始连得原因前面已经解释过了,所以每个地址加2.最后的地址连接方法,就是ADDR2~ ADDR14对应行地址, ADDR15~ ADDR23对应列地址,(由于管脚的分时复用其实是DDR2~ ADDR14对应行地址, ADDR2~ ADDR10对应列地址)ADDR24~ ADDR25对应BANK0~ BANK1,这就是bank0和bank1与2440的ADDR24和ADDR25连接的原因。再简单一点理解就是,如果最后两个位有使用,那么就是一个BANK的容量4M*16bit=8MByte无法满足了,所以需要换到下一个BANK,那么此时最后两个位也是对应的数据。

配置过程:

内存控制器与SDRAM_第10张图片
不使用UB/LB引脚,这个选项是给SRAM使用的,SDRAM不用管。他的作用是,可以通过nWEB这三个引脚来区分32位数据的哪一个Byte的数据wait信号是指当我们信号和地址设置完毕后,需不需要让内存控制器再等待一段时间,让SDRAM反应一下再取值,这是性能比较差的芯片才需要使用。
我们选用BNK6,外接2片16bit的芯片,是32位数据访问。
内存控制器与SDRAM_第11张图片
内存控制器与SDRAM_第12张图片
这是EM63A165的说明书截取出来的数据,我们使用的是EM63A165-6G,Clock Cycle Time最小是6ns,我们是挂在100MHZ的总线上,1/100 000 000 = 110^-8 s = 10ns(1秒(s) =100厘秒(cs)= 1000 毫秒(ms) = 1,000,000 微秒(μs) = 1,000,000,000 纳秒(ns)),符合芯片要求。
4M word * 16-bit 4-bank :4M的存储单元,每个存储单元16bit(每个单元2个字节),总共4块,也就是2byte(4
1024*1024)*4=‭33554432‬byte=32M,两片接在一起就是64M
内存控制器与SDRAM_第13张图片
内存控制器与SDRAM_第14张图片
内存控制器与SDRAM_第15张图片
MT选SDRAM这个毫无疑问,在SDRAM模式下只需要关心[3:0]这四个位,Trcd RAS to CASdelay是指行地址与列地址之间的时间间隙,查芯片手册可以知道最少延时18ns,100MHZ一个时钟周期是10ns,所以2个时钟周期就够了。纵列数量是9个A0 ~ A8,行列是13个A0~A12
内存控制器与SDRAM_第16张图片
内存控制器与SDRAM_第17张图片
内存控制器与SDRAM_第18张图片
REFEN使能打开,TREFMD选择自动刷新,Trp根据手册看是18ns,选择2个时钟周期就可以了,Tsrc=Trc-Trp=60-18=42ns,选择5个时钟周期就够了,计算Refresh Counter的值首先要知道Refresh period的值(刷新周期),8192 / 64ms ,是指刷新8192字节需要64毫秒,一个字节是64/8192=0.0078125us=7.8125ns,和表格中提供的例程是一样的,HCLK也是100MHZ,所以都不用算,Refresh Counter=1269=0x4F5
内存控制器与SDRAM_第19张图片
BURST_EN开启突发访问使能,SCKE_EN开启掉电模式使能,SCLK_EN选用推荐,BK76MAP内存映射是64M内存控制器与SDRAM_第20张图片
内存控制器与SDRAM_第21张图片
其他选项你也没得选,只有CL可以做文章,CL是CAS latency,这个挺重要的,在开篇的时候就表明了,可以是2或3个时钟。这个CL是内存控制器给SDRAM输入一个CL时钟周期,比如CL=2, SDRAM收到这个CL时间后,每次接收完列地址后,等2个时钟周期再把数据返回给内存控制器。
以上就全部配置完成了。

以上很多知识都是通过看视频,和查找资料,外加自己的理解总结而成的,图片也是自己画的和截图的,肯定存在些许错误,如果哪位大神有发现错误的地方,请及时指正。
——冷亦花烟_CYB(菜蔡)
2019.2.12 21:01

你可能感兴趣的:(内存控制器与SDRAM,S3C2440,AMR9,linux)