目录

1、SDRAM初始化的内容(结合英文数据手册)

2、SDRAM初始化的时序

3、代码的编写

4、modesim的仿真


SDRAM初始化的内容

SDRAMs must be powered up and initialized in a predefined manner. The 64M SDRAM is initialized after the power is applied to Vdd and Vddq, and the clock is stable with DQM High and CKE High.  A 100μs delay is required prior to issuing any command other than a COMMAND INHIBIT or a NOP.

    The COMMAND INHIBIT or NOP may be applied during the 100μs period and continue should at least through the end of the period.With at least one COMMAND INHIBIT or NOP command having been applied, a PRECHARGE command should be applied once the 100μs delay has been satisfied. All banks must be precharged. This will leave all banks in an idle state, after which at least two AUTO REFRESH cycles must be performed. After the AUTO REFRESH cycles are complete, the SDRAM is then ready for mode register programming.The mode register should be loaded prior to applying any operational command because it will power up in an unknown state. After the Load Mode Register command, at least two NOP commands must be asserted prior to any command.

Sdram 在工作前需要进行初始化
1、sdram 上电,时钟稳定,DQM高,CKE高,开始初始化
2、至少100us的等待时间,在这个等待时间之内不能有除了COMMAND INHIBIT 或 NOP 以外的任何命令,COMMAND INHIBIT 或 NOP命令需持续生效。
3、在100us等待时间结束之后,所有的 bank 需要预充电,(执行 PRECHARGE 需要 tRP 的时间)。
4、至少两个自动刷新命令(每个自动刷新都需要tRC的时间)
5、模式寄存器的配置(需要tMRD的时间)。
6、初始化完成以后处于idle的状态,每隔 64ms/2^12 =64_000_000 ns/4096=15625ns,因为工作时钟为100Mhz,所以需要每隔1562个时钟需要发一个自动刷新指令(这个64ms将所有行刷新一次是由SDRAM的内部结构决定的)
 注意:所需要的时间需要从数据手册中得到(datasheet一定要看英文原版)

 

状态机
 

SDRAM初始化的时序

这个时序图可以结合状态机的图理解,非常重要,因为每个状态需要的时间都不一样,所以需要设计计数器。

1、CKE 一直为高电平

2、command 由 cs,ras,cas,we 四个控制信号实现,具体如下图

例如 NOP命令 cs=0,ras=1,cas=1,we=1

3、DQM在初始化的时候始终为1

4、A10为高,则忽略BA0,BA1,对所有bank 进行预刷新。

5、在配置模式寄存器时,根据自己的需求设置参数

例如当 mode_value=000_00_011_0_111 即全页模式,顺序,CL=3,突发读,突发写。


代码的编写

初始化代码

/*1、工作时钟定为100Mhz
2、 Sdram 初始化
3、Sdram 的自动刷新功能:每隔 64ms/2^12=15625 个时钟周期,给出刷新命令。*/
//------------------------------------------------------------------------------------ module Sdram_initial(
clk ,
rst_n ,
cke ,
cs ,
ras ,
cas ,
we ,
dqm ,
addr ,
bank ,
dq
); input clk ; //100Mhz
input rst_n ;
output cke ; //clk enable
output cs ; //片选信号
output ras ; //行
output cas ; //列
output we ; //读写控制端
output [:] dqm ; //byte controlled by LDQM and UDQM
output [:] addr ; //12个位地址
output [ :] bank ; //sdram有4个逻辑bank
inout [:] dq ; //是三态门 wire cs ;
wire ras ;
wire cas ;
wire we ;
wire [:] dq ; reg [:] dqm ;
reg [:] addr ;
reg [ :] bank ; reg [:] command ;
reg [:] c_state ;
reg [:] n_state ;
reg [:] cnt_0 ;
wire get_100us ;
wire get_trp ;
wire get_trc1 ;
wire get_trc2 ;
wire get_tmrd ;
wire get_1562 ;
wire get_trc3 ; //----------------------------------------------------------------------
parameter NOP = 'b000;
parameter PRECHARG = 'b001;
parameter AUTO_REF1 = 'b010;
parameter AUTO_REF2 = 'b011;
parameter MODE_REG = 'b100;
parameter IDLE = 'b101;
parameter AUTO_REF = 'b110; parameter TIME_100US = 10_000 ;
parameter TRP = ; //这些数据由数据手册可以获得
parameter TRC = ;
parameter TMRD = ;
parameter TIME_1562 = ;
parameter MODE_VALUE = 'b000_00_011_0_111; //即全页模式,顺序,CL=3,突发读,突发写。 parameter NOP_CD = 'b0111;
parameter PRECHARGE_CD = 'b0010;
parameter AUTO_REF_CD = 'b0001;
parameter MODE_REG_CD = 'b0000; //----------------------------------------------------------------------状态机的设计 always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
c_state<=NOP;
end
else begin
c_state<=n_state;
end
end always @(*)begin
case(c_state)
NOP :begin
if(get_100us) //等待100us后跳转
n_state = PRECHARG;
else
n_state = c_state;
end
PRECHARG :begin
if(get_trp) //trp时间后
n_state = AUTO_REF1;
else
n_state = c_state;
end
AUTO_REF1 :begin
if(get_trc1) //trc
n_state = AUTO_REF2;
else
n_state = c_state;
end
AUTO_REF2 :begin
if(get_trc2) //trc
n_state = MODE_REG;
else
n_state = c_state;
end
MODE_REG :begin
if(get_tmrd) //tmrd
n_state = IDLE;
else
n_state = c_state;
end
IDLE :begin
if(get_1562) //等待1562个始终周期
n_state = AUTO_REF;
else
n_state = c_state;
end
AUTO_REF :begin if(get_trc3) //trc
n_state = IDLE;
else
n_state = c_state;
end default : n_state = NOP; //其他状态转移到NOP endcase
end assign get_100us = (c_state == NOP && cnt_0 == )? 'b1 : 1'b0; //cnt_0是一个递减计数器
assign get_trp = (c_state == PRECHARG && cnt_0 == )? 'b1 : 1'b0;
assign get_trc1 = (c_state == AUTO_REF1&& cnt_0 == )? 'b1 : 1'b0 ;
assign get_trc2 = (c_state == AUTO_REF2&& cnt_0 == )? 'b1 : 1'b0 ;
assign get_tmrd = (c_state == MODE_REG && cnt_0 == )? 'b1 : 1'b0 ;
assign get_1562 = (c_state == IDLE && cnt_0 == )? 'b1 : 1'b0 ;
assign get_trc3 = (c_state == AUTO_REF && cnt_0 == )? 'b1 : 1'b0 ; always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
cnt_0 <= TIME_100US-;
end
else if(get_100us) begin
cnt_0 <= TRP-;
end
else if(get_trc1 || get_1562||get_trp) begin
cnt_0 <= TRC-;
end
else if(get_trc2)begin
cnt_0 <= TMRD-;
end
else if(get_tmrd||get_trc3)
cnt_0 <= TIME_1562-;
else if(cnt_0 != )
cnt_0 <= cnt_0 -;
end //---------------------------------------------------------------------- assign cke=; //cke始终为1
always @(posedge clk or negedge rst_n)begin //dqm在初始化状态始终为1
if(rst_n=='b0)begin
dqm<='b11;
end
else if( c_state == NOP || c_state == PRECHARG || c_state == AUTO_REF1 ||
c_state == AUTO_REF2 || c_state ==AUTO_REF2 || c_state == MODE_REG ) begin
dqm<='b11;
end
else
dqm<='b00;
end assign dq = 'hzzzz; //dq为高阻态 assign {cs,ras,cas,we} = command; //cs,ras,cas,we的设计
always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
command <= NOP_CD ;
end
else if(get_100us) begin
command <= PRECHARGE_CD ;
end
else if(get_trp || get_trc1 || get_1562 )
command <= AUTO_REF_CD ;
else if(get_trc2)
command <= MODE_REG_CD ;
else
command <= NOP_CD ; end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
addr <= ;
end
else if(get_trc2) begin
addr <= MODE_VALUE;
end
else if(get_100us)
addr <= ('b1 << 10 ); //A10=1
else
addr <= ;
end always @(posedge clk or negedge rst_n)begin //bank初始化用不到,取0;
if(rst_n=='b0)begin
bank <= 'b00;
end
else begin
bank <= 'b00;
end
end
endmodule

testbench

`timescale  ns/ ns

module Sdram_test();

//时钟和复位
reg clk ;
reg rst_n; //uut的输入信号
wire cke ;
wire cs ; //片选信号
wire ras ; //行
wire cas ; //列
wire we ; //读写控制端
wire [:] dqm ; //byte controlled by LDQM and UDQM
wire [:] addr ; //12个位地址
wire [ :] bank ; //sdram有4个逻辑bank
wire [:] dq ; //是三态门 //时钟周期,单位为ns,可在此修改时钟周期。
parameter CYCLE = ; //复位时间,此时表示复位3个时钟周期的时间。
parameter RST_TIME = ; //待测试的模块例化
Sdram_initial uu1(
.clk (clk ),
.rst_n(rst_n),
.cke (cke ),
.cs (cs ),
.ras (ras ),
.cas (cas ),
.we (we ),
.dqm (dqm ),
.addr (addr),
.bank (bank),
.dq (dq )
); //生成本地时钟50M
initial begin
clk = ;
forever
#(CYCLE/)
clk=~clk;
end //产生复位信号
initial begin
rst_n = ;
#;
rst_n = ;
#(CYCLE*RST_TIME);
rst_n = ;
end
endmodule

 modesim的仿真

1、2、3、4、5就是初始化的5个状态,用红框框起来的数字就是各种时间的初始值 Trp=3 , Trc=7, Tmrd=2(倒数到0,因此需要减1)

由图可知,自动刷新也正常。

如有问题欢迎指正交流。

转载请注明出处:http://www.cnblogs.com/aslmer/p/5860382.html

SDRAM学习(二)之初始化的更多相关文章

  1. vue 源码学习二 实例初始化和挂载过程

    vue 入口 从vue的构建过程可以知道,web环境下,入口文件在 src/platforms/web/entry-runtime-with-compiler.js(以Runtime + Compil ...

  2. Quartz学习--二 Hello Quartz! 和源码分析

    Quartz学习--二  Hello Quartz! 和源码分析 三.  Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...

  3. 集成学习二: Boosting

    目录 集成学习二: Boosting 引言 Adaboost Adaboost 算法 前向分步算法 前向分步算法 Boosting Tree 回归树 提升回归树 Gradient Boosting 参 ...

  4. Android JNI学习(二)——实战JNI之“hello world”

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  5. emberjs学习二(ember-data和localstorage_adapter)

    emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用 ...

  6. ReactJS入门学习二

    ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...

  7. TweenMax动画库学习(二)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

  8. Hbase深入学习(二) 安装hbase

    Hbase深入学习(二) 安装hbase This guidedescribes setup of a standalone hbase instance that uses the local fi ...

  9. Struts2框架学习(二) Action

    Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...

  10. Python学习二:词典基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...

随机推荐

  1. 初学基础python记录

    1.对于python来说,最重要的就是缩进.相当于其他语言的{}中括号. 2.转义快捷等 alt+p和alt+n来复制上下一行.变量使用时得先赋值,且大小写敏感,遵循变量命名规则.Python还允许用 ...

  2. DDL与DML语句

    1. DDL语句 SQL语句:结构化查询语句,使用SQL与数据库“沟通”,完成相应的数据库操作. l DDL:数据定义语言,用来维护数据库对象 1.1 创建表 Ø CREATE:创建表 演示:创建员工 ...

  3. pat乙级1051

    当结果中a或者b小于0,大于0.005时,保留两位小数会输出-0.00,但应输出0.00. #include <iostream> #include <math.h> usin ...

  4. ios 几种快速写法

    //NSString .... NSString *str1 = @"str1"; NSLog(@"str %@",str1); //NSArray NSArr ...

  5. Java的内存回收机制详解X

    http://blog.csdn.net/yqlakers/article/details/70138786 1 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前 ...

  6. 在主机端和设备端进行”incrementArray“并对结果进行比较

    实验思想: 在主机端将数据初始化后传输到设备端,设备端和主机端进行同样的操作对数据加1,然后将设备端的结果传输到主机,最后核对主机端的计算结果和设备端的计算结果是否一直. // incrementAr ...

  7. Bootstrap HTML编码规范

    语法 1.用两个空格来代替制表符(Tab)--这是唯一能保证在所有的环境下获得一致展现的方法. 2.嵌套元素应当缩进一次(即两个空格). 3.对于属性的定义,属性值确保全部都用双引(避免使用单引号). ...

  8. C# StreamReader对象

    1.读取文件 输入流用于从外部源读取数据,在很多情况下,数据源可以是磁盘上的文件或网络的某些位置,任何可能发送数据的位置都可以是数据源,比如网络应用程序,web服务,甚至是控制台.StreamRead ...

  9. Java算法面试题:编写一个程序,将e:\neck目录下的所有.java文件复制到e:\jpg目录下,并将原来文件的扩展名从.java改为.jpg

    package com.swift; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; i ...

  10. 问题009:java当中的关键字有哪些?在Editplus文本编辑软件中是什么颜色的?java当中的标识符有什么要求?Java中注释分为几类?

    (1) public 公共的,表示访问的权限 (2) private 私有的,表示一种访问权限 (3) class 类关键字,表示定义一个类 java中的关键字都是大写的还是小写的?小写的,在Edit ...