SDRAM控制器

博主上一篇介绍了一些SDRAM的基本原理是否有必要学习使用纯Verilog写一个SDRAM控制器,接下来记录SDRAM控制器的工作原理。首先是上电初始化。

上电初始化

时序图中,tRP、tRC、这些时间参数可以从手册中找到,这里的系统时钟采用50Mhz。

从初始化的时序图可以看出,首先在进行预充电(Precharge)命令之前要等待100us(手册要求是至少100us,我们设定延时200us),等待系统上电稳定和时钟稳定,然后对所有bank进行预充电(Precharge),经历一个trp(20ns,一个时钟周期,手册可以查询)时间,然后进行至少两次自刷新(Auto refresh)(我这里设置进行8次自刷新,),每次自刷新至少需要trc(63ns,四个时钟周期,手册查询)时间,最后进行模式寄存器(MODE register)的配置,需要tmrd(两个时钟周期)时间,初始化完成。

预充电时当A10为高电平对所有的bank进行操作,当A10为低电平时对单个bank进行操作,BA0,BA1选择bank。我们这里预充电时对所有的bank操作,把A10置高即可。

SDRAM初始化流程

  1. 上电后延时200us
  2. 对所有的bank进行预充电(Precharge)
  3. 8个自刷新操作,每次自刷新使用四个时钟周期
  4. 进行模式寄存器的配置 ,配置完后输出初始化完成标志。

这里先设置SDRAM的突发长度为4               Addr = 12’b0000_0110_0010

SDRAM初始化仿真

这里仿真需要用到SDRAM的仿真模型,通过仿真模型可以把当前SDRAM进行的操作打印出来,如果有错误也会提示错误,这时候再去查看波形时序。这里需要注意的是仿真的时候sdram_dqm信号必须和仿真模型连接,否则数据是写不进去的,设置sdram_dqm = 0就可以了。

将SDRAM仿真模型添加进去后,要对放着模型的参数进行重定义

对于各个参数的值,不同的SDRAM芯片的参数是不同的,具体根据手册而定,mem_sizes设置的是1个bank的容量。Verilog语法笔记:这种方式可以对例化模块里面已有的宏定义进行重定义,写法是defparam + 例化之后的模块名+ . +需要重定义名。

然后在transcript中输入run 200us,先跑200us等待系统上电稳定,在输入run 50us,如上图所示CAS Latency(列选通潜伏期)为3,burst length(突发长度)为4,burst type(突发类型)顺序(Sequrntial)执行,模式寄存器配置都按照我们设置的进行。

SDRAM工作原理

初始化模块设计完成后,对SDRAM已经有了一些简单的了解,下面先来看看SDRAM的工作原理。

粗线——自动跳转,细线——受到命令后才能跳转(看不清楚图片点击阅读原文)

从一个官方给的SDRAM手册的参考状态转移图看,我们可以简单写一下SDRAM的工作流程。这部分用状态机来实现最好不过了。

上电后,给一个Precharge命令,进入Precharge状态,然后自动进入IDLE(初始化)状态,然后给自刷新命令,进入自刷新状态,自刷新完后回到IDLE状态,IDLE状态给一个配置模式寄存器命令,进入模式寄存器的配置,配置完后才能自动回到IDLE状态,然后进行读写状态的操作。

以写操作为例,需要给一个行激发命令,进入行激发状态,给出写命令才能进入写状态,写完后自动返回行激发状态,给一次写命令,会写入一个突发长度的数据,在一行没有写完不需要跳回行激发状态,只需要继续给写命令,只有当一行写完或刷新请求来临或数据写完才会跳出写状态,这里后面设计写模块再讲。数据写完或刷新请求来临或数据写完,需要先进入预充电状态,给一次预充电命令,然后自动跳转到初始状态进行重新等待命令。至于读模块的操作和写模块是完全一样的,读者自行读图。

这里要提的是图中有两个状态WRITEA和READA,这里我们不需要用到,如图也可以看到,这两个状态在进行一次读或写后会自动跳入预充电状态,从而回到初始化状态,这样和WRITE和READ这两个状态相比,读写速度肯定是会慢的,WRITE和READ可以连续给读写命令进行读写,所以直接忽略掉这两个状态不管。

仲裁机制

这里要引出一个设计技巧,初始化完成后,进行自刷新和读写操作状态都是相互独立的,所以我们需要写一个状态机去完后这些状态之间的跳转,大概意思就如下图所示,写一个仲裁状态机,当SDRAM控制器要进行自刷新时,自刷新模块需要给一个刷新请求,仲裁状态收到后,就结束当前进行的状态,给一个刷新使能,刷新模块才会进行刷新操作。同样的,当SDRAM控制器要进行写数据时,写数据模块需要给一个写请求,仲裁状态收到后,就结束当前进行的状态,给一个写使能,写数据模块才会进行写操作。后面的模块相应的也是这样的设计。

刷新模块

手册规定SDRAM自刷新需在64ms内刷新4096次(不同型号的芯片对应的不同),必须64ms是因为SDRAM内部使用电容存储数据的,它保证不断电的时间就是64ms。4096次的意思是,我所使用的这款SDRAM芯片它的行地址为A0~A11,一共是12位,2的12次方一共是4096行,我们每给一次刷新命令实际上是刷新一行,且是四个bank同时刷新,所以说一共要刷新4096次。两次刷新间隔15us。刷新是在SDRAM初始化完成后就要开始进行刷新。

从时序图可以看出,先给一个precharge命令(一般都是对all bank进行操作),经过trp(20ns,一个周期)时间进行一次自刷新命令,再过trc时间,进行再一次自刷新命令,然后trc(63ns, 四个周期)时间后激发读或写命令。

在时序图中我们看到了两次自刷新命令,但是实际上只要给一次自刷新命令即可,所以不要被时序图忽悠了,当然给两次也是没有什么关系的。这里的意思是,每次进行自刷新操作都需要给一次预充电即可。

刷新模块仿真

仿真的时候发现我犯了一个错误,就是每15us的刷新操作是不用每次都给预充电(Percharge)命令,但是从另一个状态跳转到自刷新状态是需要给一个预充电(Percharge)命令。之后便不需要再给了,这上面这里的原因是因为在刷新模块里有预充电(Percharge)命令,所以每次状态跳转到执行刷新模块,都会给一个预充电(Percharge)命令。这个问题已经得到解决。如图每15us进行一个自刷新。

关于SDRAM的读模块和写模块操作,下一篇再写。博主最近基于上次50Mhz下的简易SDRAM控制器的基础上修改成100Mhz的SDRAM控制器,实现用上位机串口发送一副彩色图片到SDRAM存储,再用VGA显示,下一步的目标是实现摄像头实时采集视频流数据显示。目前把最近写的这两个项目工程放到了Github上分享出来,希望能一起讨论,多多指点,这个东西我个人感觉不懂内部的操作时序,想要移植也是很麻烦的,所以干脆直接分享出来,后面博主会继续优化,尽量做成一个像IP Core一样的直接修改参数就可以调用的一个SDRAM控制器。

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

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

个人微信订阅号:开源FPGA

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

知乎ID:NingHeChuan

微博ID:NingHeChuan

原文地址:http://www.cnblogs.com/ninghechuan/p/8992683.html

继续死磕SDRAM控制器的更多相关文章

  1. 是否有必要学习使用纯Verilog写一个SDRAM控制器

    在做这个SDRAM控制器之前,博主有一个疑问,对于学生来说,是否有必要学习用纯Verilog写一个SDRAM控制器?因为目前X家和A家都有了DDR IP Core,对于要实现一个应用可以直接调用IP ...

  2. 死磕安卓前序:MVP架构探究之旅—基础篇

    前言 了解相关更多技术,可参考<我就死磕安卓了,怎么了?>,接下来谈一谈我们来学习一下MVP的基本认识. 大家对MVC的架构模式再熟悉不过.今天我们就学习一下MVP架构模式. MVC和MV ...

  3. 【死磕NIO】— 阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,这你真的分的清楚吗?

    通过上篇文章([死磕NIO]- 阻塞.非阻塞.同步.异步,傻傻分不清楚),我想你应该能够区分了什么是阻塞.非阻塞.异步.非异步了,这篇文章我们来彻底弄清楚什么是阻塞IO,非阻塞IO,IO复用,信号驱动 ...

  4. mysql每秒最多能插入多少条数据 ? 死磕性能压测

    前段时间搞优化,最后瓶颈发现都在数据库单点上. 问DBA,给我的写入答案是在1W(机械硬盘)左右. 联想起前几天infoQ上一篇文章说他们最好的硬件写入速度在2W后也无法提高(SSD硬盘) 但这东西感 ...

  5. 【死磕Java并发】-----Java内存模型之happend-before

    在上篇博客([死磕Java并发]-–深入分析volatile的实现原理)LZ提到过由于存在线程本地内存和主内存的原因,再加上重排序,会导致多线程环境下存在可见性的问题.那么我们正确使用同步.锁的情况下 ...

  6. 死磕 java集合之DelayQueue源码分析

    问题 (1)DelayQueue是阻塞队列吗? (2)DelayQueue的实现方式? (3)DelayQueue主要用于什么场景? 简介 DelayQueue是java并发包下的延时阻塞队列,常用于 ...

  7. 死磕 java集合之PriorityBlockingQueue源码分析

    问题 (1)PriorityBlockingQueue的实现方式? (2)PriorityBlockingQueue是否需要扩容? (3)PriorityBlockingQueue是怎么控制并发安全的 ...

  8. 死磕 java集合之PriorityQueue源码分析

    问题 (1)什么是优先级队列? (2)怎么实现一个优先级队列? (3)PriorityQueue是线程安全的吗? (4)PriorityQueue就有序的吗? 简介 优先级队列,是0个或多个元素的集合 ...

  9. 【死磕 Spring】----- IOC 之解析 bean 标签:开启解析进程

    原文出自:http://cmsblogs.com import 标签解析完毕了,再看 Spring 中最复杂也是最重要的标签 bean 标签的解析过程. 在方法 parseDefaultElement ...

随机推荐

  1. H3C数据中心虚拟化解决方案技术白皮书

    缩略语清单: 缩略语 英文全名 中文解释 IDC Internet Data Center 互联网数据中心 VRF Virtual Router Forwarding 虚拟路由器转发 SMP Symm ...

  2. Centos6.6上源码安装Nodejs V4版本

    本来就是想在vps上装一个Ghost博客,这个博客依赖的是Nodejs,然后推荐的是V4版本.然后我就对着官网的步骤安装,发现根本没有Centos6 i386的资源了(64位的还是有的), 我只能在那 ...

  3. 安卓自定义日期控件(仿QQ,IOS7)续

    本篇是在原来的基础上修改了界面效果,使其更加接近ios7,qq等日期选择控件,看图: 源码地址:http://download.csdn.net/detail/baiyuliang2013/87601 ...

  4. 06 Activity显示跳转

    <span style="font-size:18px;">package com.fmy.day8_29task; import com.fmy.day8_29tas ...

  5. SSH深度历险(五) 深入浅出-----IOC AND AOP

    IOC就是Inversion of Control,控制反转.在Java开发中,IoC意味着将你设计好的类交给系统(容器)来控制实现,而不是在你的类内部控制.这称为控制反转. 本人理解:就是把原本你自 ...

  6. Android的事件处理-android学习之旅(四十四)

    androd事件处理简介 控制飞机移动的简单实例 package peng.liu.test; import android.app.ActionBar; import android.app.Act ...

  7. Mysql中limit的用法详解

    Mysql中limit的用法详解 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,为我们提供了limit这样一个功能. SELECT * FROM table LIMIT [offset ...

  8. 【Unity Shaders】Using Textures for Effects —— 实现Photoshop的色阶效果

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  9. Chipmunk僵尸物理对象的出现和解决(六)

    既然出现了这个问题下面就是如何找到原因. 因为该问题不是每次都出现,偶尔反弹棒碰到五角星时才会多出一个僵尸棒,现象比较随机,较难悉知具体原因. 有时多次触碰又没有出现问题,有时短时间内每次触碰都出现问 ...

  10. 如何成为一名优秀的web前端工程师

    我所遇到的前端程序员分两种: 第一种一直在问:如何学习前端? 第二种总说:前端很简单,就那么一点东西. 我从没有听到有人问:如何做一名优秀.甚至卓越的WEB前端工程师. 何为:前端工程师? 前端工程师 ...