SDRAM学习(二)之初始化
目录
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、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学习(二)之初始化的更多相关文章
- vue 源码学习二 实例初始化和挂载过程
vue 入口 从vue的构建过程可以知道,web环境下,入口文件在 src/platforms/web/entry-runtime-with-compiler.js(以Runtime + Compil ...
- Quartz学习--二 Hello Quartz! 和源码分析
Quartz学习--二 Hello Quartz! 和源码分析 三. Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...
- 集成学习二: Boosting
目录 集成学习二: Boosting 引言 Adaboost Adaboost 算法 前向分步算法 前向分步算法 Boosting Tree 回归树 提升回归树 Gradient Boosting 参 ...
- Android JNI学习(二)——实战JNI之“hello world”
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- emberjs学习二(ember-data和localstorage_adapter)
emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用 ...
- ReactJS入门学习二
ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...
- TweenMax动画库学习(二)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- Hbase深入学习(二) 安装hbase
Hbase深入学习(二) 安装hbase This guidedescribes setup of a standalone hbase instance that uses the local fi ...
- Struts2框架学习(二) Action
Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...
- Python学习二:词典基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...
随机推荐
- yii相关手册文档
1.Yii官方手册 Yii Framework 2.0 权威指南:http://www.yiichina.com/doc/guide/2.0/start-databases 2.yii高级应用程序手册 ...
- 动态规划专题(二)——树形DP
前言 \(DP\)这东西真的是博大精深啊...... 简介 树形\(DP\),顾名思义,就是在树上操作的\(DP\),一般可以用\(f_i\)表示以编号为\(i\)的节点为根的子树中的最优解. 转移的 ...
- 2018.5.22 Oracle安装配置在虚拟机中外部电脑连接服务
1.拷贝老师的集成文件(win系统和oracle服务) 2.安装虚拟机,并且打开镜像文件 3.启动监听程序(实例服务[自动].监听服务) 4.查看虚拟机ip,此ip要主机ip在同一个网段 5.检查虚拟 ...
- os.walk 模块
os.walk()可以得到一个三元tupple(dirpath, dirnames, filenames),其中第一个为起始路径,第二个为起始路径下的文件夹,第三个是起始路径下的文件. 其中dirpa ...
- ubuntu jdk install
1.下载jdk-7u75-linux-x64.tar.gz,默认在/home/csf/Downloads 2.csf@ubuntu:~/Downloads$ sudo mkdir /usr/java ...
- windows下编辑器Emacs的安装与配置
一年成为Emacs高手(像神一样使用编辑器) http://blog.csdn.net/redguardtoo/article/details/7222501 原创作品,允许转载,转载时请务必以超 ...
- java从键盘输入学生成绩,找出最高分,并输出学生成绩等级。
/*从键盘输入学生成绩,找出最高分,并输出学生成绩等级:成绩 >=最高分-10 等级为A成绩 >=最高分-20 等级为B成绩 >=最高分-30 等级为C其余为 等级为D 提示:先输入 ...
- oracle 多行数据合并一行数据
在工作中遇见的oracle知识,多行合并成一行,记录一下 1.取出需要的数据,代码: (SELECT to_char(m.f_meetdate, 'yyyy-MM-dd'), decode(nvl(m ...
- cf550D. Regular Bridge(构造)
题意 给出一个$k$,构造一个无向图,使得每个点的度数为$k$,且存在一个桥 Sol 神仙题 一篇写的非常好的博客:http://www.cnblogs.com/mangoyang/p/9302269 ...
- 14.2-ELK 经典用法—企业自定义日志收集切割和mysql模块
本文收录在Linux运维企业架构实战系列 一.收集切割公司自定义的日志 很多公司的日志并不是和服务默认的日志格式一致,因此,就需要我们来进行切割了. 1.需切割的日志示例 2018-02-24 11: ...