使用的流程

W9825G6JH winbond sdram 4M words X 4banks X 16bits=.

Accesses to the SDRAM are burst oriented.

Up to 200MHz

CAS Latency 2 and 3

Burst Length 1,2,4,9 and Full page

BUrst Read, Single Writes Mode

8K Refresh Cycles/64mS

1 After power up, an initial pause of 200uS is required followed by a precharge of all banks using the precharge commmand.DQM and CKE held high during the pause.

2 Once all banks have been precharged ,the Mode Register Set Command must be issued to initialize the Mode Register.

All banks must be in a precharged state and CKE must be high at least one cycle before the Mode Register Set Command can be issued. ()A delay equals to must be waited when the next command can be issued.

3 An Additional eight Auto Refresh cycles are also requred before or after programming the Mode Register .

4 Bank Active Command

before any read or write command

5 Read and Write Access Modes

6 Burst Read Command

7 Burst Write Command

8 Auto-precharge Command

9 Precharge Command

10 Self Refresh Command

11 NOP

 `timescale 1ns/1ps

 ////////////////////////////////////////////////////////////////////////////////
// Company :
// Engineer : Yang Li yangli0534@gmail.com
// Create Date : 2015.01.20
// Design Name :
// Module Name : sdram
// Project Name :
// Target Device: Spartan 6
// Tool versions: ISE 14.7
// Description : SDRAM control
// read or write one word a time
// the sdram is WINBOND W9825G6JH
// Revision : V1.0 created
// Additional Comments :
//
////////////////////////////////////////////////////////////////////////////////
module sdram(
input clk_i, //clock 100M ,
input rst_n_i, // reset ,active low input wr_req_i, // write request
input rd_req_i, // read request
output wr_ack_o, //write ack
output rd_ack_o, //read ack input [:] wr_addr_i, // address to write
input [:] wr_data_i, //data to write input [:] rd_addr_i, // read address
output [:] rd_data_o, // read data
output rd_data_valid_o,// data output valid
output busy_sdram_o, // sdram is busy , unable to be operated // SDRAM interface
output [:] SDRAM_ADDR,
output SDRAM_BA_0,
output SDRAM_BA_1,
output SDRAM_CAS_N,
output SDRAM_CKE,
// output SDRAM_CLK,
output SDRAM_CS_N,
inout [:] SDRAM_DQ,
output SDRAM_LDQM,
output SDRAM_UDQM,
output SDRAM_RAS_N,
output SDRAM_WE_N
);
//Timing parameters of SDRAM winbond W9825G6JH
localparam T_200us='d20000,
T_RC='d6-15'd1,//60ns Ref/Active to Ref/Active Command Period
T_RCD='d3-15'd1,//15ns Active to Read/Write Command Delay Time
T_RP='d2-15'd1,//15ns Precharge to Active Command Period
T_RSC='d3-15'd1,//////Mode register set cycle time
T_LATENCY='d3-15'd2,//column to data valid latency
T_WR='d2-15'd1;// Write recovery time
//SDRAM command
localparam CMD_INIT = 'b01111 ,// power on
CMD_NOP = 'b10111 ,// nop command
CMD_ACTIVE = 'b10011 ,// active command
CMD_READ = 'b10101 ,// read commadn
CMD_WRITE = 'b10100 ,// write command
CMD_B_STOP = 'b10110 ,// burst stop
CMD_PRECHARGE= 'b10010 ,// precharge
//CMD_A_REF = 5'b10001 ,// aoto refresh
CMD_A_REF = 'b10010 ,// aoto refresh
CMD_LMR = 'b10000 ;// lode mode register
//fsm of initialization
localparam
INIT_WAIT ='b00000001 ,//power on ,and wait 200us
INIT_PRECHARGE ='b00000010, //precharge
INIT_TRP ='b00000100, //wait precharge to be done, Trp
INIT_AUTO_REFRESH ='b00001000, // Auto Refresh for 8 times
INIT_TRC ='b00010000, //Refresh-to-Refresh interval
INIT_MRS ='b00100000, //load the Mode Register
INIT_TRSC ='b01000000, //wait the MRS
INIT_DONE ='b10000000; //initialization done
//fsm of normal operation
localparam IDLE ='b000000000001, //wait to fresh or read\write
WORK_ACTIVE ='b000000000010, //active the ROW
WORK_TRCD ='b000000000100, //Row-to-Column delay
WORK_READ ='b000000001000 ,//read
WORK_LATENCY ='b000000010000, //column latency
WORK_READ_DATA ='b000000100000, //read data from DQ bus
//WORK_WAIT =12'b000001000000,
WORK_WRITE ='b000010000000, //write
WORK_TWR ='b000100000000,//write recovery delay
WORK_TRP ='b001000000000,//precharge to active command period
WORK_AUTO_REFRESH='b010000000000, //refresh
WORK_TRC ='b100000000000;// Ref/Act to Ref/Act delay ,unused reg[:] init_state_reg, init_state_next; // SDRAM initialization state
reg[:] init_timer_reg, init_timer_next; // delay timer
reg [:] ref_cnt_reg, ref_cnt_next; // repeat timer //------------------------------------------------------------------------------
//SDRAM initialization state transition begin here
//------------------------------------------------------------------------------ always @(posedge clk_i or negedge rst_n_i)
if(!rst_n_i) begin
init_state_reg <= INIT_WAIT;
init_timer_reg <= T_200us;
ref_cnt_reg <= 'd0;
end
else begin
init_state_reg <= init_state_next;
init_timer_reg <= init_timer_next;
ref_cnt_reg <= ref_cnt_next;
end always @* begin
init_state_next = init_state_reg;
init_timer_next = init_timer_reg;
ref_cnt_next = ref_cnt_reg;
if(init_timer_reg != 'd0)
init_timer_next = init_timer_reg - 'd1; case(init_state_reg)
INIT_WAIT: begin
if(init_timer_reg=='d0)
init_state_next = INIT_PRECHARGE;
end
INIT_PRECHARGE: begin
init_state_next = INIT_TRP;
init_timer_next = T_RP;
end
INIT_TRP: begin
if(init_timer_reg=='d0) begin
init_state_next = INIT_AUTO_REFRESH;
ref_cnt_next = 'd8;
end
end
INIT_AUTO_REFRESH: begin
init_state_next = INIT_TRC;
init_timer_next = T_RC;
end
INIT_TRC: begin
if(init_timer_reg == 'd0) begin
if(ref_cnt_reg == 'd0) begin
init_state_next = INIT_MRS;
end
else begin
ref_cnt_next = ref_cnt_reg - 'd1;
init_state_next = INIT_AUTO_REFRESH;
end
end end
INIT_MRS: begin
init_state_next = INIT_TRSC;
init_timer_next = T_RSC;
end
INIT_TRSC: begin
if(init_timer_reg == 'd0)
init_state_next = INIT_DONE;
end
INIT_DONE : begin
init_state_next = INIT_DONE;
end
endcase
end
//SDRAM initialization state transition end here
reg[:] work_timer_reg, work_timer_next; // delay timer
reg[:] work_state_reg, work_state_next; // SDRAM normal operation state
assign sdram_init_done = (init_state_reg == INIT_DONE);
//------------------------------------------------------------------------------
//self refresh every 7 us
//------------------------------------------------------------------------------
reg sdram_ref_req; // SDRAM self refresh request
wire sdram_ref_ack; // SDRAM elf refresh ack
reg[:] cnt_7us; // always @ (posedge clk_i or negedge rst_n_i)
if(!rst_n_i) cnt_7us <= 'd0;
else if(cnt_7us < 'd700) cnt_7us <= cnt_7us+11'b1; // 60ms(64ms)/8192=7.9us
else cnt_7us <= 'd0; always @ (posedge clk_i or negedge rst_n_i)
if(!rst_n_i) sdram_ref_req <= 'b0;
else if(cnt_7us == 'd699) sdram_ref_req <= 1'b1; //refresh request
else if(sdram_ref_ack) sdram_ref_req <= 'b0; //request has been acknowledged //------------------------------------------------------------------------------
//SDRAM normal operation state transition begin here
//------------------------------------------------------------------------------
reg wr_ctrl_reg, wr_ctrl_next;
always @(posedge clk_i or negedge rst_n_i)
if(!rst_n_i) begin
work_state_reg <= IDLE;
wr_ctrl_reg <= 'b0;
work_timer_reg <= 'd0;
end
else begin
work_state_reg <= work_state_next;
wr_ctrl_reg <= wr_ctrl_next;
work_timer_reg <= work_timer_next;
end
//SDRAM normal operation state transition end here always @* begin
work_state_next = work_state_reg;
wr_ctrl_next = wr_ctrl_reg;
if(sdram_init_done & work_timer_reg != 'd0)
work_timer_next = work_timer_reg - 'd1;
else work_timer_next = work_timer_reg;
case(work_state_reg)
IDLE: begin
if(sdram_init_done & sdram_ref_req) begin
work_state_next = WORK_AUTO_REFRESH;
end
else if(sdram_init_done & wr_req_i) begin
work_state_next = WORK_ACTIVE;
wr_ctrl_next = 'b0;//write
end
else if(sdram_init_done & rd_req_i) begin
work_state_next = WORK_ACTIVE;
wr_ctrl_next = 'b1;//read
end
else begin
work_state_next = IDLE;
wr_ctrl_next = 'b1;
end
end
WORK_ACTIVE: begin
work_state_next = WORK_TRCD;
work_timer_next = T_RCD;
end
WORK_TRCD : begin
if(work_timer_reg == 'd0) begin
if(wr_ctrl_reg == 'b0)
work_state_next = WORK_WRITE;
else
work_state_next = WORK_READ;
end end
//write
WORK_WRITE: begin
work_state_next = WORK_TWR;
work_timer_next = T_WR;
end
WORK_TWR: begin
if(work_timer_reg=='d0) begin
work_state_next = WORK_TRP;
work_timer_next = T_RP;
end
end
WORK_TRP: begin
if(work_timer_reg == 'd0)
work_state_next = IDLE;
end //read
WORK_READ: begin
work_state_next = WORK_LATENCY;
work_timer_next = T_LATENCY;
end
WORK_LATENCY:begin
if(work_timer_reg == 'd0)
work_state_next = WORK_READ_DATA;
end
WORK_READ_DATA: begin
work_state_next=WORK_TRP;
work_timer_next= 'b1;
end //refresh
WORK_AUTO_REFRESH: begin
work_state_next = WORK_TRC;
work_timer_next = T_RC;
end
WORK_TRC: begin
if(work_timer_reg=='d0)
work_state_next = IDLE;
end
endcase
end assign busy_sdram_o = (sdram_init_done && work_state_reg == IDLE) ? 'b0 : 1'b1;
assign sdram_ref_ack =(work_state_reg == WORK_AUTO_REFRESH);
assign rd_ack_o = (work_state_reg ==WORK_READ_DATA);
assign rd_data_valid_o = (work_state_reg == WORK_TRP)&(wr_ctrl_reg == 'b1)&(work_timer_reg==15'd0);
assign wr_ack_o = (work_state_reg == WORK_TWR) ; reg[:] sdram_cmd_r; // SDRAM command
reg[:] sdram_ba_r;
reg[:] sdram_addr_r; assign {SDRAM_CKE,SDRAM_CS_N,SDRAM_RAS_N,SDRAM_CAS_N,SDRAM_WE_N} = sdram_cmd_r;
assign {SDRAM_BA_1, SDRAM_BA_0} = sdram_ba_r;
assign SDRAM_ADDR = sdram_addr_r;
assign SDRAM_LDQM = (init_state_reg == INIT_WAIT)? 'b1 : 1'b0;
assign SDRAM_UDQM = (init_state_reg == INIT_WAIT)? 'b1 :1'b0;
//-------------------------------------------------------------------------------
//SDRAM command
always @ (posedge clk_i or negedge rst_n_i) begin
if(!rst_n_i) begin
sdram_cmd_r <= CMD_INIT;
sdram_ba_r <= 'b11;
sdram_addr_r <= 'hfff;
end
else
case (init_state_reg)
INIT_WAIT, INIT_TRP,INIT_TRC,INIT_TRSC: begin
sdram_cmd_r <= CMD_NOP;
sdram_ba_r <= 'b11;
sdram_addr_r <= 'h1fff;
end
INIT_PRECHARGE: begin
sdram_cmd_r <= CMD_PRECHARGE;
sdram_ba_r <= 'b11;
sdram_addr_r <= 'h1fff;
end
INIT_AUTO_REFRESH: begin
sdram_cmd_r <= CMD_A_REF;
sdram_ba_r <= 'b11;
sdram_addr_r <= 'h1fff;
end
INIT_MRS: begin //
sdram_cmd_r <= CMD_LMR;
sdram_ba_r <= 'b00; // Reserved
sdram_addr_r <= {
'b00, //Reserved
'b0, //Wite Mode Burst Read and Burst Write
'b00, //
'b011, // CAS Latency,{A6,A5,A4}=011
'b0, //Adressing Mode,A3=b0
'b000 //Brust Length(1,{A2,A1,A0}=000)
};
end
INIT_DONE:
case (work_state_reg)
IDLE,WORK_TRCD,WORK_LATENCY,WORK_TRC,WORK_READ_DATA,WORK_TWR,WORK_TRP: begin
sdram_cmd_r <= CMD_NOP;
sdram_ba_r <= 'b11;
sdram_addr_r <= 'h1fff;
end
WORK_ACTIVE: begin
sdram_cmd_r <= CMD_ACTIVE;
if(wr_ctrl_reg=='b0)begin
sdram_ba_r <= wr_addr_i[:]; //L-Bank address
sdram_addr_r <= wr_addr_i[:]; //row address
end
else begin
sdram_ba_r <= rd_addr_i[:]; //L-Bank address
sdram_addr_r <= rd_addr_i[:]; //row address
end
end
WORK_READ: begin
sdram_cmd_r <= CMD_READ;
sdram_ba_r <= rd_addr_i[:]; //L-Bank address
sdram_addr_r <= {
'b0010, // A10=1,precharge
rd_addr_i[:] //column address
};
end
WORK_WRITE: begin
sdram_cmd_r <= CMD_WRITE;
sdram_ba_r <= wr_addr_i[:]; //L-Bank address
sdram_addr_r <= {
'b0010, // A10=1,precharge
wr_addr_i[:] //column address
};
end
WORK_AUTO_REFRESH: begin
sdram_cmd_r <= CMD_A_REF;
sdram_ba_r <= 'b11;
sdram_addr_r <= 'h1fff;
end
default: begin
sdram_cmd_r <= CMD_NOP;
sdram_ba_r <= 'b11;
sdram_addr_r <= 'h1fff;
end
endcase
default: begin
sdram_cmd_r <= CMD_NOP;
sdram_ba_r <= 'b11;
sdram_addr_r <= 'h1fff;
end
endcase
end // write data control
reg [:] sdr_din;
reg sdr_dlink;
always @ (posedge clk_i or negedge rst_n_i)
if(!rst_n_i) sdr_din <= 'd0; //
else if((work_state_reg == WORK_WRITE) | (work_state_reg == WORK_TWR)) sdr_din <= wr_data_i;
always @ (posedge clk_i or negedge rst_n_i)
if(!rst_n_i) sdr_dlink <= 'b0;
else if((work_state_reg == WORK_WRITE) | (work_state_reg == WORK_TWR)) sdr_dlink <= 'b1;
else sdr_dlink <= 'b0;
assign SDRAM_DQ = sdr_dlink ? sdr_din : 'hzzzz; // read data control
reg[:] sdr_dout;
always @ (posedge clk_i or negedge rst_n_i)
if(!rst_n_i) sdr_dout <= 'd0;
//else if((work_state_reg == WORK_READ_DATA)| (work_state_reg == WORK_LATENCY)) sdr_dout <= SDRAM_DQ;
else if ( (work_state_reg == WORK_READ_DATA)| (work_state_reg == WORK_LATENCY)) sdr_dout <= SDRAM_DQ;
assign rd_data_o = sdr_dout; endmodule

仿真波形:

初始化状态机:

工作状态机:

SDRAM总结的更多相关文章

  1. 【iCore3 双核心板_FPGA】实验二十八:基于SDRAM 的VGA 驱动器的设计

    本实验设计的VGA显示驱动完全基于FPGA实现,用SDRAM做缓存设备,通过ARM控制VGA显示的内容.ARM 通过FSMC总线向FPGA发送数据,由于总线的速度和VGA的显示速度与SDRAM的读写速 ...

  2. (三)内存 SDRAM 驱动实验 (杨铸 130 页)(勉强能懂个大概)

    SDRAM 芯片讲解: 地址: 行地址 (A0-A12) 列地址 (A0-A8)    片选信号(BA0 BA1)(L-BANK)(因为SDRAM有 4片) 两片SDRAM 连线唯一区别在 UDQM ...

  3. SDRAM控制器的Verilog建模之一

    前言:作为经典存储器的三剑客中的flash和sram已经建模测试过了,虽然现在都已经ddr2,ddr3,667MHZ.1333MHZ的天下了,但是接下这周来准备写一下sdram的controller. ...

  4. SDRAM的主要参数

    (1) 容量.SDRAM的容量经常用XX存储单元×X体×每个存储单元的位数来表示.例如某SDRAM芯片的容量为4M×4×8bit,表明该存储器芯片的容量为16 M字节.或128 M bit. (2) ...

  5. SDRAM,DRAM,SRAM,DDR的概念

    一:SDRAM SDRAM(Synchronous Dynamic Random Access Memory),同步动态随机存储器,同步是指 Memory工作需要同步时钟,内部的命令的发送与数据的传输 ...

  6. RAM,SRAM,DRAM,SDRAM,DDR RAM,ROM,PROM,EPROM,EEPROM,NAND FLASH,NOR FLASH的区别

    RAM:由字面意思就可以理解,SDRAM SRAM DRAM(下面蓝色字体的这几种)都可以统称RAM,random access memory(随机存取存储器)的缩写,下面是51hei.com为大家整 ...

  7. 调试2440 RAM拷贝至SDRAM遇到的问题

    汇编代码主要是初始化一些寄存器,关狗,初始化时钟,初始化存储管理器以便访问内存,然后将SoC上4k RAM数据拷贝至SDRAM,然后在SRAM里面运行,由于代码未正常跑起来,于是使用JLinkExe来 ...

  8. ARM学习篇 SDRAM理解

    1.SDRAM单管存储单元 SDRAM单管电路图 C记忆单元 T控制门管 Z字线 W位线 注:图示为N沟道耗尽型MOS管 写入:Z加高电平,MOS导通,W状态决定了电容C的状态 读出:Z加高电平,MO ...

  9. SDRAM和dcfifo的联合

    SDRAM和dcfifo的联合 设计原理 在"SDRAM突发读写页"实验中,留下了一个问题,就是从SDRAM读取数据的速度要与SDRAM的驱动时钟同步,这就造成了读出的数据的速率过 ...

  10. SDRAM读写一字(下)

    SDRAM读写一字 SDRAM控制模块 上电后进行初始化状态,初始化完成后进入空闲状态,在此进行判断如下判断: 如果自刷新时间到,则进行自刷新操作,操作完成后重新进入空闲状态: 如果读使能有效则进行读 ...

随机推荐

  1. 用Perl编写Apache模块续二 - SVN动态鉴权实现SVNAuth 禅道版

    代码地址:https://code.csdn.net/x3dcn/svnauth 以禅道项目管理系统的数据库结构为标准,实现了可用的svn authz验证功能. 以用户名.密码.项目的acl开发程度o ...

  2. git 给远程库 添加多个url地址

     目录[-] 前提 使用流程 原理解析 注意 Other 参考文章 作者:shede333主页:http://my.oschina.net/shede333 && http://blo ...

  3. Hibernate+maven+mysql

    最近在研究hibernate,想建立一个简单的Hibernate+maven+mysql工程,网上找了一大堆的示例,要么看不懂结构,要么就是缺少必要文件.总之都没有成功,结果无意在一个外文网上找了一个 ...

  4. tomcat下bin文件夹下shell文件分析

    在bin下面有9个sh文件,本文将逐步分析,今天就以version.sh为例 os400=false #uname取操作系统名称 如Linux 如果为OS400的操作系统 特殊处理 case &quo ...

  5. IOS6学习笔记(一)

    一.ARC 1.ARC环境下可以使用-(void)dealloc{};处理一些事情(比如移除KVO观察),但不要调用[super dealloc]; 2.ARC与非ARC混编要注意符合Cocoa命名约 ...

  6. Vue表单

    gitHub地址: https://github.com/lily1010/vue_learn/tree/master/lesson11 一 vue表单 实在是太简单了,直接来个例子 <!DOC ...

  7. Javascript面向对象编程(三) --- 非构造函数的继承

    一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Chinese = { nation:'中国' }; 还有一个对象,叫做&qu ...

  8. [android] SQLite 数据库的升级 和 降级

    public class SqliteHelp extends SQLiteOpenHelper { /* * context:创建数据库所需的 上下文对象 * name: 数据库名字 * facto ...

  9. Android 程序目录及UI的简介

    Android程序的目录结构 src:源码的组织管理目录. gen:自动生成的目录,会生成一些重要的文件,如R.java,该目录一般不需要我们编写. assets:该目录文件不会被编译成二进制编码,多 ...

  10. 内存管理2(主讲MRR)

    内存管理2 我们讨论过properties 后,所有的内存管理系统都是通过控制所有对象的生命周期来减少内存的占用.iOS和OS X应用程序完成这些是通过对象拥有者来实现的,它保证了只要对象使用就会存在 ...