SDRAM控制器操作时序

SDRAM控制器操作时序此为学习http://dengkanwen.com/137.html整理的笔记,侵删!SDRAM工作原理内部的状态跳转图我们所需关注的几个地方:1)粗黑线表示在该状态下会自动跳转到另一个状态,细黑线表示需要给命令才会跳转。2)我们重点关注的几个地方:IDLE状态到WRITE状态:​1)在IDLE状态需要先给ACT命令激活某一行,此时处于Row

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

此为学习http://dengkanwen.com/137.html整理的笔记,侵删!

SDRAM工作原理

内部的状态跳转图

img

我们所需关注的几个地方:

1)粗黑线表示在该状态下会自动跳转到另一个状态,细黑线表示需要给命令才会跳转。

2)我们重点关注的几个地方:

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 状态跳到IDLE 状态的一个原因是,我们需要进行刷新操作,进
入刷新操作,必须从IDLE 状态进入。
​ 另外一点,可能有些朋友看到了WRITE 状态下边还有一个WRITEA 状态,的
确,但是细心的你有没有发现当处于WRITEA 状态时,它会自动的进入Precharge 状态。也就是说WRITEA 比在WRITE 状态的工作效率要低很多,所以在某些对数据交互速度较快的场景中,我们使用WRITE 状态。在本套教程中,我们也只讲WRITE 状态。速度快的都能搞定,那速度慢的操作也是不在话下的。

SDRAM 初始化模块

首先看一下官方数据手册给出的初始化时序图

这里写图片描述

初始化过程

1)首先需要有200us 的一个延时(对应图中左下方的T),

2)在延时满足之后,给一次Precharge 命令,同时需要指定A10及Bank地址;(如果A10为高(All Banks),就意味着是给所有的Bank进行预充电,此时不需要给Bank地址,如果A10为低(SINGLE BANK),就需要指定某一个bank的地址。一般为高)

3)然后再过“tRP”的时间,给“AutoRefresh”命令,然后再过“tRC”的时间,再给“Auto Refresh”命令,(不需要指定bank地址的(大家注意看右下角有说明,灰色部分的数据我们是不需要关心的)。

4)然后再经过“tRP”的时间进行模式寄存器设置。进行模式寄存器设置的时候,需要给的指令会稍微复杂一点,手册上显示A0~A11及BA0,BA1都用到了,下面我们来看下模式寄存器应该怎么进行设置,如图:

这里写图片描述

​ 这里解释一下突发读写:突发长度(A2~A0)设置为4,在我们进行写操作的时候,数据是每4个数据写一次的,就是说我们给一次写指令,就会向SDRAM写进去4个数据,而且四个地址是连续的(如果突发类型设置的是非连续,则地址不会连续,需要我们写一个数据给一次地址,比较耗内存)

初始化时序图中的几个问题

1)tRC、tRP、tMRD的时间是多少,几个时钟周期?

参照官方数据手册ML0006 0012-2中的AC ELECTRICAL CHARACTERISTICS部分给出

tRC:63ns

tRP:20ns

tMRD:2cycle

若fpga内部频率为50MHZ,正好是20ns。(4clk、1clk)

2)时序图中几个command命令的参数怎样设置

这里写图片描述

上述就是整个初始化过程,我们最后以kevin画的时序图作为一个总结

这里写图片描述

具体代码为sdram_init;

SDRAM 刷新模块

我们还是先看一下官方数据手册给出的刷新时序图

img

刷新操作的时序图分析与前面类似。

刷新时序图中的几个问题

1)两次刷新时间间隔有多久呢?

​ SDRAM内部电容保存数据的最长时间是64ms,而我们一个BANK有4096行,64ms/4096~=15us,也就是说为了保证SDRAM内部的数据不被丢失,两次刷新之间的最大时间间隔为15us,所以为了能让SDRAM有更多的时间进行读或者写,我们就设定SDRAM刷新的周期为15us.(若按系统时钟50MHZ,就是计750个数)

​ SDRAM每进行一次刷新,是对每一行进行操作的,并不是单独针对每一个电容进行充电,所以每进行一次刷新,该行中的电容进行充电我们可以理解为是同步发生的

2)在每次自动刷新时,我们需要给一个“Precharge”命令,这个命令有什么作用呢?

大家可以看下开头的那张状态图,如果此时SDRAM正处于“WRITE”或“READ”状态时,这个“Precharge”命令可以使SDRAM跳出“WRITE”或“READ”状态从而入“IDLE”状态。接下来,过“tRP”的时间,给一个“Auto-Refresh”命令可以进入刷新状态。

但此时的Precharge命令我们在写状态模块中给出。在刷新模块中不需要Precharge命令。

SDRAM仲裁模块

在介绍仲裁模块前我们先考虑一个问题:

​ 如果我正在让SDRAM写数据,是不是SDRAM刷新的时间到了,我就必须是让SDRAM马上执行刷新操作吗?这样的话肯定不是现实的,那必然会把还没写的剩下的数据丢失。不能让我们的数据丢失,又要保证SDRAM进行刷新来保证我们整个SDRAM相应BANK中的数据不被丢失,我们应该怎么来写代码呢?

我们可以考虑这样来做:如果刷新的时间到了,先让写操作把正在写的4个数据(突发长度为4)写完,然后再去进行刷新操作。而如果在执行读操作也遇到需要刷新的情况,我们也可以这样来做,先让数据读完,再去执行刷新操作。

为了解决各个模块之间不方便控制的情况,我们引入一个新的机制 ——“仲裁”机制。“仲裁”用来干什么呢?在这里边,“仲裁”相当于我们这个SDRAM控制器的老大,对SDRAM的各个操作统一协调:读、写及自动刷新都由“仲裁”来控制。

仲裁模块状态机示意图:

这里写图片描述

仲裁模块和其他各模块之间的连线:

这里写图片描述

注:一定要搞清楚说的是模块之间连线的关系还是状态机之间跳转的关系哦。

仲裁模块分析

1)初始化操作完成之后便进入到了“ARBIT”仲裁状态,只有处于仲裁状态的时候,“仲裁老大”才能进行下命令。

2)当状态机处于“WRITE”写状态时,如果SDRAM刷新的时间到了,刷新模块同时向写模块和仲裁模块发送刷新请求ref_req信号。

3)当写模块接受到ref_req之后,写模块在写完当前4个数据(突发长度为4)之后,写模块的写结束标志flag_wr_end拉高,然后状态机进入“ARBIT”仲裁状态。

4)处于仲裁状态之后,此时有刷新请求ref_req,然后状态机跳转到“AREF”状态并且仲裁模块发送ref_en刷新使能,刷新模块将刷新请求信号ref_req拉低并给sdram发送刷新的命令。

5)等刷新完毕之后,刷新模块给仲裁模块发送flag_ref_end刷新结束标志,状态机跳转到“ARBIT”仲裁状态。

注意了,当刷新完跳转到“ARBIT”仲裁状态之后,如果之前我们的全部数据仍然没有写完(Kevin指的是全部数据,并不是一个突发长度的4个数据哦),那么此时我们仍然要给仲裁模块写请求“wr_req”,然后仲裁模块经过一系列判断之后,如果符合写操作的时机,那就给写模块一个写使能信号“wr_en”,然后跳转到“WRITE”写状态并且写模块开始工作。

SDRAM写模块

官方数据手册给出的写操作时序图

这里写图片描述

该时序图的分析可以参照前面初始化过程的分析。

现在我们考虑另一个问题:假设我们现在需要往SDRAM 中写入两行数据,那什么时候可以退出仲裁状态机的写状态:
1) 数据已经写完;若我们还想要再写,就需要外部的Wr_trig触发
2) SDRAM 需要进行刷新操作;外部有一个刷新请求信号,并且本次数据已经写完;转到外部仲裁模块去执行刷新操作,如果刷新完毕需要继续写,写模块请求,仲裁模块使能。
3) 数据未写完,需要激活下一行继续写。本行写完标志,重新输入act命令去写下一行

我们将这三个状态化成一个状态机。如图所示:

这里写图片描述

注意上图中的IDLE状态和前面的初始化中的IDLE状态不要搞混。这个IDLE就是写模块中状态机的初始化部分。

S_WR:
        if(wr_data_end == 1'b1)                       
                state   <=      S_PRE;                 
        else if(ref_req == 1'b1 && burst_cnt_t == 'd2 && flag_wr == 1'b1)       
                state   <=      S_PRE;                 
        else if(sd_row_end == 1'b1 && flag_wr == 1'b1)
                state   <=      S_PRE;
S_PRE:
        if(ref_req == 1'b1 && flag_wr == 1'b1)         
                state   <=      S_REQ;
        else if(flag_pre_end == 1'b1 && flag_wr == 1'b1) 
                state   <=      S_ACT;
        else if(flag_wr == 1'b0)                       
                state   <=      S_IDLE;  

我们由以上所述画出写模块时序图:

这里写图片描述

这里写图片描述

分析写模块中五个状态机:

1)IDLE:外部Wr_trig触发写信号,进入S_REQ状态。写模块将Flag_wr拉高直到数据完全写完结束。

2)S_REQ:Flag_wr信号拉高,S_REQ状态向外部仲裁发出请求写信号wr_req,外部仲裁模块判断可以进行写操作了并向写模块发出wr_en 使能信号,告诉写模块可以开始写了。进入S_ACT状态。

3)S_ACT:写模块在S_ACT状态,发出ACT命令(command),并且指定bank的行地址。ACT命令结束发出Flag_act_end结束标志。进入S_WR状态。

4)S_WR:发出写命令开始写数据,此时需要指定列地址

一行数据写完发出Sd_row_end标志信号。刷新请求出现时,该组数据写完发出Flag_wr_end标志信号。所有数据写完返回Wr_data_end信号标志。

5)S_PRE:预充电命令 ,进入预充电状态,充电完毕返回Flag_pre_end标志信号。

SDRAM读模块

SDRAM读模块与写模块一样在此不再详述。

读模块时序图:

这里写图片描述

有一个问题需要注意:

我们再给出读命令后,数据延时了两个周期给出,这个时间段叫潜伏期CAS。

写代码技巧:

1)先写主状态机

2)把时序图中用到的时序信号标志定义出来;

reg                             flag_wr       ;
reg     [ 4:0]                  state         ;
//-----------------------------------------------
reg                             flag_act_end  ;
reg                             flag_pre_end  ;
reg                             sd_row_end    ;
reg     [ 1:0]                  burst_cnt     ; 
reg     [ 1:0]                  burst_cnt_t   ; 
reg                             wr_data_end   ;
//-----------------------------------------------
reg     [ 3:0]                  act_cnt       ;
reg     [ 3:0]                  break_cnt     ;
reg     [ 6:0]                  col_cnt       ;
//-----------------------------------------------
reg     [11:0]                  row_addr      ;
wire    [ 8:0]                  col_addr      ;

3)然后按照这个表写出每个标志信号产生的代码

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/160105.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 在点光源的基础上利用光域网来分布光的传播范围及方向_daiding

    在点光源的基础上利用光域网来分布光的传播范围及方向_daiding在点光源的基础上利用光域网来分布光的传播范围及方向 daiding VRIES 在点光源的基础上利用光域网来分布光的传播范围及方向 来模拟生活中射灯 筒灯 台灯等的真实照明效果 鼠标左键一直拖动一定长度 不要与造型重合 功率 越大越亮 1500 再添加光域网文件 点击目标下边 找到 ies 文件 渲染即可 复制的时候一定要实例复制 IES 文件 加载一张 ies 文件 旋转 XYZ 旋转灯的方向 覆盖图形 就是把 ies 灯变得有形状有体积 这个

    2026年1月24日
    1
  • JAVA实现数据库_数据库是如何解决并发问题

    JAVA实现数据库_数据库是如何解决并发问题Java开源数据库引擎,数据库计算封闭性的一站式解决方案。

    2025年7月22日
    2
  • 电子设计竞赛控制组——完整旋转倒立摆程序

    电子设计竞赛控制组——完整旋转倒立摆程序以前也想过要写博客,但是却一直没有付诸于实践,作为第一篇原创,我还是选择将以前电赛时的作品拿出来,毕竟当初可是花费了好多心血的,汗~旋转倒立摆是控制组校内赛练手的题目,需要对PID非常熟悉才能调好参数,以下代码是自己搭建好结构后调试出来的程序,其中的参数会根据不同的结构作出调整。结构组成:K60开发板(带液晶屏和按键),角度编码器,直流减速电机(带编码器),12V的电机驱动,金属摆臂,…

    2022年8月18日
    7
  • Android【本地Json处理工具类】

    Android【本地Json处理工具类】

    2021年3月12日
    152
  • 什么是5g微基站(三大运营商基站数量)

    大家都知道,要想使用5G网络,必须要有5G基站做支撑,那么5G基站长啥样,又是如何建成的呢?▲中国移动的5G天线设备▲北斗+GPS的双星授时设备5G天线设备、北斗+GPS的双星授时设备两…

    2022年4月11日
    113
  • visio2013专业版激活密匙[通俗易懂]

    visio2013专业版激活密匙[通俗易懂]Visio2013最新产品密钥分享,在安装时可以使用以下密钥:  2NYF6-QG2CY-9F8XC-GWMBW-29VV8  FJ2N7-W8TXC-JB8KB-DCQ7Q-7T7V3  VXX6C-DN3HQ-3CRXG…

    2022年6月24日
    90

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号