使用的流程

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

仿真波形:

初始化状态机:

工作状态机:

最新文章

  1. Linux基本命令(一)
  2. 使用智能指针来管理对象 (基于RAII)
  3. C++ c++与C语言的区别(实用性增强,register关键字增强,全局变量检测增强)
  4. BaseColumns以及自定义Column
  5. 超级MINI STLINK V2 官方固件自动升级 ST-Link 【worldsing 笔记】
  6. Compiling aSmack
  7. 安装python3.4
  8. PostgreSQL与MySQL比较(转)
  9. npm下设置NODE_ENV下mac与windows的差异
  10. Python基础-python数据类型之集合(四)
  11. maven 项目中没有src/test/java文件夹
  12. ORM Active Record Data Mapper
  13. TeamWork#3,Week5,Release Notes of the Alpha Version
  14. properties编程示例
  15. js绘制圆形时钟
  16. Hello world &amp;博客客户端试用
  17. Two-stage rotation animation is deprecated. This application should use the smoother single-stage an
  18. C#语言各个版本特性(一)
  19. 将本地项目放到GitHub上托管并展示
  20. 什么是Http无状态?Session、Cookie、Token三者之间的区别

热门文章

  1. git 使用笔记(一)
  2. Python参数组合
  3. Glide
  4. windbg定位死锁
  5. android的Project has no default.properties file! Edit the project properties to set one. 的解决
  6. linux服务器如何设置目录权限,让开发只能在测试目录下开发,不在线上目录上开发
  7. android XMl 解析神奇xstream 四: 将复杂的xml文件解析为对象
  8. 学习android学习必备的java基础知识--四大内部类
  9. 【读书笔记】iOS-特性
  10. 安装VVDocumenter-Xcode-master (Xcode 7.1)的过程