SDRAM读写状态解析
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读写状态解析的更多相关文章
- SDRAM读写一字(下)
SDRAM读写一字 SDRAM控制模块 上电后进行初始化状态,初始化完成后进入空闲状态,在此进行判断如下判断: 如果自刷新时间到,则进行自刷新操作,操作完成后重新进入空闲状态: 如果读使能有效则进行读 ...
- SDRAM读写一字(上)
SDRAM读写一字 系统设计 SDRAM指令 指令 常量名 CKE CSn RAS CASn WEn 备注 空操作 NOP 1 0 1 1 1 行激活 ACTIVE 1 0 0 1 1 读操作 ...
- nmap端口状态解析
nmap端口状态解析 状态 说明 open 应用程序在该端口接收 TCP 连接或者 UDP 报文 closed 关闭的端口对于nmap也是可访问的, 它接收nmap探测报文并作出响应.但没有应用程序在 ...
- Java线程Thread的状态解析以及状态转换分析 多线程中篇(七)
线程与操作系统中线程(进程)的概念同根同源,尽管千差万别. 操作系统中有状态以及状态的切换,Java线程中照样也有. State 在Thread类中有内部类 枚举State,用于抽象描述Java线程的 ...
- SDRAM读写操作
SDRAM读写操作 1.读操作 2.写操作 SDRAM所有时序参数都可以在芯片手册上查到.
- SCI投稿过程总结、投稿状态解析、拒稿后对策及接受后期相关问答
SCI投稿过程总结.投稿状态解析.拒稿后对策及接受后期相关问答 http://muchong.com/t-9174366-1 SCI投稿过程总结.投稿状态解析.拒稿后处理对策及接受后期相关问答综合 ...
- TCP协议 状态解析和状态统计
一.三次握手和四次挥手 1.建立连接(三次握手) (1)服务器会处于listen状态,客户端发送一个带SYN标志的TCP报文到服务器. (2)服务器端回应客户端的请求,这是三次握手中的第2个报 ...
- ORM进阶之Hibernate中对象的三大状态解析
ORM进阶之 ORM简单介绍 ORM进阶之Hibernate简单介绍及框架搭 ORM进阶之Hibernate的三大对象 ORM进阶之Hibernate中对象的三大状态解析 在Hibernatea中每一 ...
- OpenCV读写图像文件解析
OpenCV读写图像文件解析 imdecode 从内存中的缓冲区读取图像. C++:Mat imdecode(InputArray buf, int flags) C++:Mat imdecode(I ...
随机推荐
- 新装的主机没有ifconfig,route等命令,怎么查找对应的安装包
公司最近有台新装的主机,主机上一些常用的命令都没有,比如说ifconfig,route等命令. 没有这些命令主机很难工作,所以我们就需要把他安装上 第一种方法:是你需要知道对应的是那个包 比如说ifc ...
- 用sql获取一段时间内的数据
我把我CSDN写的 搬来博客园了.. SELECT * FROM 表名 WHERE timestampdiff(MINUTE, SYSDATE(), send_time) <=60 AND ...
- mysql8绿色免安装win64版本(自带heidisql.exe客户端)应该兼容老版第三方工具。
https://pan.baidu.com/s/1cvQ4AJX6rmqSpMhBQTPz4Q 如果缺c库,自己去找下. 使用方法:先执行initdb.bat初始化数据 如果要安装为服务:执行inst ...
- nginx配置 location及rewrite规则详解
1. location正则写法 语法规则: location [=|~|~*|^~] /uri/ { … } = 开头表示精确匹配 ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url ...
- error LNK2001: 无法解析的外部符号 "public: char * __thiscall
error LNK2001: 无法解析的外部符号 "public: char * __thiscall CamPinPadCtrl::KeysConvert(unsigned long,ch ...
- 我写的python代码的规则
1.Python文件的命名: 采用每个单词的首字母大写,不使用下划线 2.Python类的命名: 采用每个单词的首字母大写,不使用下划线 3.Python包名的命名:采用每个单词都是小写,不使用下划线 ...
- vue.js中的全局组件和局部组件
组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能. 组件的使用有三 ...
- Ubuntu命令操作
1../ 当前路径2.ls 列举当前路径下的所有文件及文件夹 默认情况不显示隐藏文件 ls -a 显示隐藏文件 ls -lah h是文件大小 l是显示文件3.cd 跳转路径4.pwd 查看当前所在路径 ...
- .NET开发微信小程序-接收微信支付回调数据
获取微信支付传回来的数据 1.MVC控制器 /// <summary> /// 付款返回的数据 /// </summary> /// <returns></r ...
- goroutine和线程区别
从调度上看,goroutine的调度开销远远小于线程调度开销. OS的线程由OS内核调度,每隔几毫秒,一个硬件时钟中断发到CPU,CPU调用一个调度器内核函数.这个函数暂停当前正在运行的线程,把他的寄 ...