完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
SDRAM(Synchronous Dynamic Random Access Memory),同步动态随机存储器。同步是指 Memory工作需要同步时钟,内部的命令的发送与数据的传输都以它为基准;动态是指存储阵列需要不断的刷新来保证存储的数据不丢失,因为SDRAM中存储数据是通过电容来工作的,大家知道电容在自然放置状态是会有放电的,如果电放完了,也就意味着SDRAM中的数据丢失了,所以SDRAM需要在电容的电量放完之前进行刷新;随机是指数据不是线性依次存储,而是自由指定地址进行数据的读写。
SDRAM内部其实是一个存储阵列,大家可以想象一下,如果SDRAM内部不是以阵列的形式存在而是以管道的形式存在,那SDRAM是很难做到随机访问的。阵列就如同一张表格一样,将数据填进去。和表格的检索原理一样,先确定一个行(Row),再确定一个列(Col),我们就可以准确的找到所需要的单元格,这就是内存芯片寻址的基本原理。对于内存,这个单元格可以成为存储单元,那么这个表格(存储阵列)叫什么呢?这就是逻辑Bank (Logic Bank,下文简称Bank).
SDRAM的厂商一般为了节约成本,采用同一总线来对SDRAM进行寻址是无可厚非的,对于Row地址用到了12根线,也就是总共有2^12=4096个Row地址,而col地址使用9根线,也就是有2^9=512个col地址,而总共加起来的话,一个Bank就有4096×512=2097152 (2x1024x1024) ,也就是有2M个地址,这样的话,就与我们前面计算SDRAM的容量想吻合了。
就拿咱们使用的这块SDRAM芯片来讲,数据线有16根,也就是说明我们数据的位数可以达到16位,但是呢,请注意,也许在我们使用SDRAM的时候,也许我们在向SDRAM写数据的时候,我们生成的数据只有8位,但FPGA是与SDRAM的16根数据线连在一起的,这个时候,存到SDRAM中的数据还是16位的,所以为了避免这个问题,我们就可以使用掩码来屏蔽掉高8位了。当然掩码在读数据的时候起到的作用也是类似的。
根据官方文档的介绍,SDRAM在刚上电的100us期间,除了“COMMAND INHIBIT”或“NOP”是不可以给SDRAM发其他指令的,所以大家能看到发送“Precharge”命令与刚上电的时间间隔“T”最小值为100us,这个100us其实也相当于SDRAM的一个稳定期。看过《高手进阶 终极内存技术指南》这篇文章的朋友可能会发现,在《高手进阶 终极内存技术指南》上写的稳定器是200us,而这里出现的却是100us,这样岂不是出现了矛盾,Kevin刚看手册的时候,也出现了这个疑问。我们可以肯定的一点是,官方的手册出错的可能性是很小的,如果连官方的文档都出错了,那还让我们这些使用他们器件的人怎么活呢 ╭( T □ T )╮。那会不会是《高手进阶 终极内存技术指南》的作者写错了呢?这么久经考验的经典文章,如果有错误,肯定是早就提出来了。最终,Kevin在官方手册上找到了答案:对于这段英文,Kevin的理解是:在200us期间,SDRAM是都有可能执行“COMMAND INHIBIT”或“NOP”命令的,所以这里我们就索性把稳定器弄成200us。(如果理解出错,请大家批评指出)稳定器过了之后,我们先给“Precharge”命令,然后再过“tRP”的时间再给“Auto Refresh”命令,然后再过“tRC”的时间再给“Auto Refresh”命令,然后再经过“tRP”的时间进行模式寄存器设置。在给命令的时候,我们需要注意,“Precharge”、“Auto Refresh”、”Load Mode REGISITER“这三个命令都是只出现了一次的,没有给这些命令的时候都是给的”NOP“命令。给”Precharge”命令时,我们需要指定A10及Bank地址,如果A10为高(All Banks),就意味着是给所有的Bank进行预充电,此时不需要给Bank地址,如果A10为低(SINGLE BANK),就需要指定某一个bank的地址。给”Auto Refresh“命令时,是不需要指定bank地址的(大家注意看右下角有说明,灰色部分的数据我们是不需要关心的)。进行模式寄存器设置的时候,需要给的指令会稍微复杂一点,手册上显示A0~A11及BA0,BA1都用到了,下面我们来看下模式寄存器应该怎么进行设置,请看图:A9:用来指定操作模式:为高表示突发读/突发写,为低表示突发读/单写;A4~A6:指定潜伏期的长度,关于潜伏期,《高手进阶 终极内存技术指南》上有非常详细的介绍,不过潜伏期设置的实际效果就是,如果潜伏期设置的是3,在我们进行SDRAM读操作的时候,读出来的数据就会相对于”READ”命令延后3个周期出来,如果潜伏期是2,那就会延后2个周期。A3:设置突发的类型,连续型和非连续型。A2~A0:用来指定突发的长度。对于上面的解释,大家可能会由于不懂突发是什么会觉得Kevin这里边写得可能还是显得不够直白,下面Kevin举个例子:A9设置为0,潜伏期设置为3,突发类型A3为0,突发长度(A2~A0)设置为4,在我们进行写操作的时候,数据是每4个数据写一次的,就是说我们给一次写指令,就会向SDRAM写进去4个数据,而且四个地址是连续的(如果突发类型设置的是非连续,则地址不会连续,具体的地址会是怎么样的一种规律,Kevin自己也没搞懂);在我们进行读操作的时候,在给完一次读命令的3个周期(潜伏期为3)后,会有4个数据连续的崩出来.至此,对于初始化的过程,到这里算是基本讲完了。
在初始化完成后的 “tMRD” 之间之后,给一个”ACT”命令,同时指定是哪一个bank的哪一行,然后再经过 “tRCD”的时间给“WRITE”指令,同时指定是bank地址和列地址并把A10拉低,然后再根据设定好的突发长度将对应数量的数据写进去,这样就完成了我们的写操作。写完四个数据之后干嘛呢,这个就完全是我们自己说了算,如果我不给SDRAM发任何指令,那SDRAM内部还是处于“WRITE”状态的,如果我还想让SDRAM进行写,那我可以在给SDRAM发送写指令,如果此时刷新SDRAM的时间到了,那我们就必须去执行SDRAM的刷新操作来保证SDRAM的数据不被丢失。可能看到这里大家会想,如果我正在让SDRAM写数据,是不是SDRAM刷新的时间到了,我就必须是让SDRAM马上执行刷新操作吗?这样的话肯定不是现实的。大家试想一下,SDRAM写数据是每四个每四个数据进行的,如果正在写第二数据却马上让SDRAM执行刷新操作,那必然会把还没写的剩下的两个数据丢失,On My God, 我们是断然不能让我们的数据丢失的。不能让我们的数据丢失,又要保证SDRAM进行刷新来保证我们整个SDRAM相应BANK中的数据不被丢失,我们应该怎么来写代码呢?天啊,想到这里,是不是已经有朋友头都要快炸了呢?大家不要慌,关于如何写代码,Kevin会在下一篇博文中进行讲解的,大家先耐着性子把SDRAM的时序彻底弄明白。关于刷新的时序,会在这篇文章的后续部分进行介绍。写操作到这里就已经基本上说完了。
首先,依然要给“ACT”命令,记住不要忘了指定ROW地址和BANK地址,然后在给“READ”指令,经过设定好的潜伏期之后,咱们的数据就出来了。大家也不要忘了,在给相关命令的时候,千万不要忘记其他信号线上的信号。
在每次自动刷新时,我们需要给一个“Precharge”命令,这个命令有什么作用呢?大家可以看下在前面的那张状态图,如果此时SDRAM正处于“WRITE”或“READ”状态时,这个“Precharge”命令可以使SDRAM跳出“WRITE”或“READ”状态从而进入“IDLE”状态。接下来,经过“tRP”的时间,给一个“Auto-Refresh”命令,然后再经过“tRC”的时间,再给一个“Auto-Refresh”命令,至此,自动刷新操作就完成了。关于这里的自动刷新操作,和我们的初始化过程有点类似,只是在这里没了模式寄存器的设置。
只看该作者
举报
只有小组成员才能发言,加入小组>>
14个成员聚集在这个小组
FPGA所支持各种电平标准及应用电路设计
3548 浏览 1 评论
电子发烧友网
电子发烧友论坛
查看 »
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 22:15 , Processed in 0.637564 second(s), Total 57, Slave 50 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com