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 ...
随机推荐
- spring中用xml配置构造注入的心得
spring中用xml配置构造注入时,如果 <constructor-arg> 属性都是 ref ,则不用理会参数顺序 <constructor-arg ref="kill ...
- COGS 2769. mk去撸串
[题目描述] 今天 mk 去撸串 ,恰逢店里活动 ,如果吃一种串串超过记录, 可以 赠送 328, 所以 mk 想知道他吃的串串中吃的最多的种类是什么. [输入格式] 第一行一个整数 1<=n& ...
- 聊聊javascript的事件
javascript事件1.点击事件 onclick obtn.click=function(){};2.移入/移出事件 onmouseover/onmouseout 注意:在父级中移入移出,进 ...
- PPII打不开 更改I.bat
http://jingyan.baidu.com/article/3a2f7c2e7d277126afd6118d.html
- POJ-1936 All in All---字符串水题
题目链接: https://vjudge.net/problem/POJ-1936 题目大意: 给两个字符串,判断是s1是不是s2的子序列 思路: 水 #include<iostream> ...
- 【转】iOS 上常用的两个功能:点击屏幕和return退出隐藏键盘和解决虚拟键盘挡住UITextField的方法
iOS上面对键盘的处理很不人性化,所以这些功能都需要自己来实现, 首先是点击return和屏幕隐藏键盘 这个首先引用双子座的博客 http://my.oschina.net/plumsoft/blog ...
- Java环境变量搭建(Windows环境)
变量名:JAVA_HOME 变量值:C:\Program Files (x86)\Java\jdk1.8.0_91 // 要根据自己的实际路径配置 变量名:CLASSPATH 变量值:. ...
- java 类和成员的修饰符
- mahout算法解析
1.下载ubuntu的iso 2.安装虚拟机,vmware,最好英文原版 3.在vm里面安装ubuntu,安装vm tools 4.本地连接设置为共享上网,虚拟机采用NAT,打开ubuntu,自动连接 ...
- HDU-3366-Count the string(KMP,DP)
Count the string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...