SDRAM初始化模块
使用野火的波形图编程 首先明确各个信号之间的依赖关系
- state: 最后来考虑,先把他需要的信号准备好
- cnt_200us: 需要根据数据手册给的参数设定,这里等待200us,因此需要一个200us的计数器,这个计数器只完成一个使命,上电计数,计满200us就不管后面的事
- wait_end: 计满200us后要给出一个计满信号 (依赖 cnt_200us)
- cnt_cmd: 计数器,用来给3个等待时间计数 (依赖 cnt_cmd_reset)
- cnt_cmd_reset:上一个计数器的清零信号 (依赖计满信号:trp_end、trfc_end、tmrd_end)
- trp_end、trfc_end、tmrd_end: 自家延时结束的信号(依赖 状态)
- cnt_ref: 自动刷新的次数,至少需要2次自动刷新(依赖状态 INIT_AR)
//SDRAM初始化模块
// 使用野火的波形图编程
// 首先明确各个信号之间的依赖关系
// 1. state: 最后来考虑,先把他需要的信号准备好
// 2. cnt_200us: 需要根据数据手册给的参数设定,这里等待200us
// 因此需要一个200us的计数器,这个计数器只完成一个使命,上电计数,计满200us就不管后面的事
// 3. wait_end: 计满200us后要给出一个计满信号 (依赖 cnt_200us)
// 4. cnt_cmd: 计数器,用来给3个等待时间计数 (依赖 cnt_cmd_reset)
// 5. cnt_cmd_reset:上一个计数器的清零信号 (依赖计满信号:trp_end、trfc_end、tmrd_end)
// 6. trp_end、trfc_end、tmrd_end: 自家延时结束的信号(依赖 状态)
// 7. cnt_ref: 自动刷新的次数,至少需要2次自动刷新(依赖状态 INIT_AR)
module sdram_initial(
input clk,//100M时钟信号
input rst_n,
output reg [3:0] init_cmd,//SDRAM命令,组成{CS#,RAS#,CAS#,WE#}
output reg [1:0] init_bank,//BANK地址,共4个BANK
output reg [12:0] init_addr,//SDRAM地址总线
output init_end//初始化完成信号,初始化完成后拉高,其他时间保持低电平
);
//命令指令参数
localparam PRECHARGE = 4'b0010 , //预充电指令
AT_REF = 4'b0001 , //自动刷新指令
NOP = 4'b0111 , //空操作指令
MREG_SET = 4'b0000 ; //模式寄存器设置指令
// 状态参数
parameter INIT_IDLE = 8'b0000_0001;
parameter INIT_PRE = 8'b0000_0010;//预充电
parameter INIT_TRP = 8'b0000_0100;//等待tRP
parameter INIT_AR = 8'b0000_1000;//自动刷新
parameter INIT_TRFC = 8'b0001_0000;//等待tRFC
parameter INIT_MRS = 8'b0010_0000;//配置模式寄存器
parameter INIT_TMRD = 8'b0100_0000;//等待tMRD
parameter INIT_END = 8'b1000_0000;
// 计数器最大参数
parameter CNT_200 = 8'd20_000;//一个周期10ns,200us要用20_000个时钟周期
//最大刷新次数
parameter MAX_REF = 4'd8;
//等待时间参数定义
localparam TRP = 3'd2 , //发送预充电指令后进行下一个操作需要等待的时间
TRFC = 3'd7 , //发送自动刷新指令后进行下一个操作需要等待的时间
TMRD = 3'd3 ; //发送设置模式寄存器指令后进行下一个操作需要等待的时间
reg [7:0] state;
reg [7:0] next_state;
reg [7:0] cnt_200us;//芯片上电后需要等待 至少100us 的时间(在数据手册Figur18左下角)
reg [3:0] cnt_cmd; //计数:2、3、7
reg [3:0] cnt_ref; //自动刷新8次
//这些信号要提前准备好,要比状态变化提前一个时钟周期
wire wait_end;
wire cnt_cmd_reset;
wire trp_end;
wire trfc_end;
wire tmrd_end;
assign wait_end = (cnt_200us == CNT_200 - 1)? 1'd1: 1'd0;
assign trp_end = ((state == INIT_TRP) && (cnt_cmd == TRP - 1)) ? 1'd1:1'd0;
assign trfc_end = ((state == INIT_TRFC) && (cnt_cmd == TRFC - 1)) ? 1'd1:1'd0;
assign tmrd_end = ((state == INIT_TMRD) && (cnt_cmd == TMRD - 1)) ? 1'd1:1'd0;
assign cnt_cmd_reset = ((state == INIT_IDLE) || (state == INIT_END) || (trp_end) || (trfc_end) || (tmrd_end))?1'd1:1'd0;
assign init_end = (state == INIT_END)? 1'd1 : 1'd0;
// 200us计数器
always@(posedge clk or negedge rst_n)begin
if(!rst_n )begin
cnt_200us
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?