码迷,mamicode.com
首页 > 其他好文 > 详细

SDRAM读写状态解析

时间:2018-05-27 13:36:19      阅读:863      评论:0      收藏:0      [点我收藏+]

标签:手册   充电   截图   try   ali   完成后   Edito   分析   速度   

SDRAM的写状态流程

IDLE状态到WRITE状态

(1)在IDLE状态需要先给ACT命令激活某一行,此时处于Row Active状态。

(2)在Row Active状态之后,给Write命令则会进入WRITE状态。

(3)在WRITE状态后,再给一次Write命令,就可以继续写入数据

WRITE状态到IDlE状态

(1)在WRITE状态给PRE命令,则SDRAM将跳出WRITE状态进入Precharge状态。

(2)在Precharge状态后,就会自动进入IDLE状态了。

WRITE状态下面还有一个WRITEA状态,当处于WRITEA状态时,它会自动进入到Precharge状态,想要继续写入就要再次重复激活行和进行写操作。也就是说WRITEA状态的工作效率要低很多,所以在某些对数据交互速度较快的场景中,我们要使用WRITE状态

在设计写模块之前还是有有下面三种情况需要退出当前写状态。

(1)     数据已经写完。

(2)     SDRAM需要进行刷新操作。

(3)     数据未写完,需要激活下一行继续写。

利用状态机实现

技术分享图片

从写状态时序图上读出,先给一个Active row命令,激活行地址,A0~A9,A10,A11,A12(A12一般不用)输入行地址,选择bank,手册中查阅Trcd为20ns。

然后给write命令,A10选择是WRITE状态(A10高电平),还是WRITEA状态(A10低电平),由于WRITEA状态写完一个burst length的数据后会自动跳转到预充电命令,(要等突发长度结束后才能退出写状态)随后进入IDLE状态,所以我们选择WRITE状态,可连续写入数据。所以WRITE状态适用于高速数据的读写,WRITEA状态适用于低速数据的读写。DQM置低电平(数据总线的低字节全为0),输入列地址(A0~A8),A10置低电平,选择bank。Tdpl为2个时钟周期。

进行Precharge命令,对all bank进行操作,一个Trp时间后然后进行下一次的Active row命令,Trp为20ns。

这个模块我采用的是三段式状态机,第二段应该采用组合逻辑,不然有些情况会在pre_state和next_state两个状态之间不停跳转。这是刚开始我把第二段用的时序逻辑,后面仿真的时候发现了这个问题。状态机的状态转移图如下。

技术分享图片

SDRAM写模块的内部时序图理解,首先需要一个写触发信号wr_trig,然后进行write操作,write_flag操作为高进行写操作,写数据结束后write_flag置低电平,wr_trig信号触发后,wr_req(写请求)信号发出,状态机由初始状态进入写请求状态,等仲裁状态机发出写使能(wr_en)信号,状态机跳转到激发行命令操作(S_ACT),有一个flag_act_end激发完成标志信号,激发完成后状态机跳转到WRITE(写状态),当Sd_row_end信号置高时表示第一行写完,换下一行写。在换下一行写之前要重弄新激发新的一行地址,所以仲裁状态机要回到IDLE状态,再次激发写状态,写模块内部状态机跳到PRECHARGE(预充电命令状态),当预充电完成后flag_pre_end置高,状态机跳到再次激发行地址命令,等行地址激发完成后,状态机跳到WRITE(写状态),当Ref_req(刷新请求)信号来到时(在写的同时也要进行自刷新操作),状态机跳转到预充电状态,然后自刷新完成,在即进入写请求状态,激发行地址,等激发行地址状态完成后进行写状态,(注意:每一个突发长度完成后都需要进行一次写命令)

写操作模块仿真

技术分享图片

技术分享图片

         写操作中,最后有个数重复操作,但是应该是写不进去,这里的原因是写模块的数据写完成标志没有及时给到仲裁状态机,导致命令一直停留在写命令下,这个问题得到解决。

技术分享图片

技术分享图片

技术分享图片

写入两行数据后,停止写,SDRAM每过15us自刷新一次。

读操作模块

读操作模块和写操作模块是完全相同的,这里可以直接把写操作模块的代码复制过来,顶层添加,修改相关命令和参数即可。

写完数据之后,激发读数据

技术分享图片

中间遇到需要刷新,进行刷新,刷新完成后继续读数据

技术分享图片

一行写完接着写下一行

技术分享图片

写完之后给个预充电命令,然后每隔15us进行自刷新。

技术分享图片

如上几幅截图,在每次跳到预充电命令,后面紧接着还是正常读出数据,但是理论上来说应该是读出数据完全完成后再跳入预充电命令,从代码和波形分析中没有找到解决。这个问题是预留。这个问题的原因下面得到解决。

技术分享图片

         为什么数据会在precharge命令后面出来,这是因为我们设置的潜伏期的缘故,在给读命令之后,数据会延迟三个时钟周期出来,所以最后出来的数据,会在precharge命令之后。

       写到这里其实一个简易的SDRAM控制器就写的差不多了,重点是要把这个SDRAM控制器使用起来,设置一个给SDRAM写数据和读数据的标志,使用上位机用串口发送数据到FPGA,当接收到写指令FPGA将数据紧接着的四个数据写入到SDRAM,写完之后给出读指令,SDRAM已经写入SDRAM的四个数据再通过串口发送给上位机,这里需要注意的是因为SDRAM的速度远比串口传输的速度快,如果直接把串口发送过来的数据接到SDRAM的数据端口上,就可能会出现重复写入或写入数据错误等原因,所以这里要使用两个FIFO进行缓冲。

读写FIFO

使用读写FIFO原因,再给SDRAM写数据的时候,我们写入SDRAM的数据的速率,即串口速率,要远远小于SDRAM写入数据的速率,所以这里需要使用FIFO进行缓存,读取SDRAM的数据也是如此。

技术分享图片

通过串口向SDRAM中写入四个数据,然后再读取出来发送到上位机。

FIFO的仿真需要在Modelsim中添加库文件,我使用的是QuartusII进行开发,在生成IP的时候IP Core配置界面会提示你用到了哪个库文件,把这个库文件和生成的IP Core顶层文件直接添加到工程里面就行了,进行充分仿真后就可以下载板子了。

结果完成

技术分享图片

       在做这个实验的时候博主基本上是仿真完成后直接下板子就成功了,这就体现到充分仿真的重要性,仿真的过程也是十分痛苦的,经过了多次的重复仿真,最后总算是调了出来了。

这个简易SDRAM控制器的工程我放在GitHub了,欢迎指点批评。

  https://github.com/NingHeChuan/Open-FPGA.git

技术分享图片

 

转载请注明出处:NingHeChuan(宁河川)

个人微信订阅号:开源FPGA

如果你想及时收到个人撰写的博文推送,可以扫描左边二维码(或者长按识别二维码)关注个人微信订阅号

知乎ID:NingHeChuan

微博ID:NingHeChuan

原文地址:https://www.cnblogs.com/ninghechuan/p/9095436.html 

SDRAM读写状态解析

标签:手册   充电   截图   try   ali   完成后   Edito   分析   速度   

原文地址:https://www.cnblogs.com/ninghechuan/p/9095436.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!