一,SDRAM基本概念应用和分类
1.1SDRAM简介
六代:
1.2存储器分类
静态动态RAM的区别就是动态RAM数据会刷新
二.SDRAM内部存储结构
2.1SDRAM存储阵列
本实验中使用的SDRAM存储空间被分为4个bank(如下图就是一个bank),每个bank选定行地址13位,列地址9位可以确定一个存储单元,每个存储单元16bit。那么它的存储空间就是(4 * (2^13) * (2^9) * 16) = 256M(bit)
2.2数据存取原理
特性:
- 需要自刷新来保持数据,否则数据会丢失。7.8us刷新一行
三芯片手册分析
3.1SDRAM的IO
3.2 SDRAM的操作详解
预充电后需要等待trp(66ns)时间
8个刷新周期每个周期需要tRFC
模式寄存器后需要等待tMRD(2个时钟周期)
保证所有的bank未被激活
3.3命令详解
命令一共有:
- COMMAND INHIBIT (NOP) 禁止命令
- NO OPERATION (NOP) 无命令
- ACTIVE (select bank and activate row) 激活指令
- READ (select bank and column, and start READ burst) 读指令(选择行列,选择突发)
- WRITE (select bank and column, and start WRITE burst) 写指令 (选择行列,之后开始写突发)
- BURST TERMINATE 突发终止
- PRECHARGE (Deactivate row in bank or banks) 预充电指令(停用bank)
- AUTO REFRESH or SELF REFRESH (enter self refresh mode) 自动刷新或者自我刷新
- LOAD MODE REGISTER 负载模式寄存器
- Write enable/output enable 写入启动/输出启用
- Write inhibit/output High-Z 禁止写入/输出为Z
3.4.1COMMAND INHIBIT
命令禁止指令,阻止设备进行新的命令,但是不会影响已经执行的命令
3.4.2NO OPERATION
无操作指令,避免设备在空闲和等待时间执行其他不需要的指令
3.4.3LOAD MODE REGISTER
配置模式寄存器
2. CAS延迟为2或3
3. 突发长度有1.2.4.8或整页(512个byte)突发
3.4.4ACTIVE
当设备处在空闲状态时,激活指令用于激活指定的bank的指定的row,其中BA【1:0】用于激活指定的bank
注意:在打开一个bank的不同row之前,必须先发送预充电指令,
在发送预充电指令之前,当前bank的当前row都可以被持续的访问
3.4.5READ
读指令用在激活指令(ACTIVE)以后,其中A[8:0]用来选择bank的列,其中A10用来标记是否使用自动预充电(因为在读指令状态下,列地址只使用A[8:0]所以A10挪作他用),读取到的数据出现在DQ上,根据DQM[1:0]也就是掩码,用来控制高D[15:8]和D[7:0]
注意:如果选择自动预充则在本次READ结束后就会就会跟上一个预充电指令,也就是无法再立刻访问该行
如果没有选择则在本次READ结束后不会跟上一个预充电指令,也就是说该行可以继续
访问
3.4.6WRITE
基本跟READ相同,只是写使能拉低(有效),在这个阶段跟读指令相同,都是选择列
3.4.7PRECHARGE
用于将指定的bank中处于开放状态下的row进入禁止状态,也可以让所有bank下的所有row进入禁止状态。当发送预充电指令后,经过一个时间:tRP,就可以访问指定的bank中的指定的row
同样的A10在预充电过程中用于指定bank的row进入禁止状态还是所有的bank中的row进入禁止状态
3.4.8BURST TERMINATE
终止固定长度或者连续页的读和写操作
3.4.9REFRESH
3.4.9.1AUTO REFRESH
这种叫做自动刷新,需要我们在一个指定的时间间隔中去刷新一次也就是发送一次自动刷新指令
在每次发送自动刷新操作指令之前都必须要进行一次预充电指令,并且要在预充电命令发送完毕以后等待tRP时间,再去发送自动刷新指令
在发送命令期间,内部地址寄存器会自动的去递增的生成,因此外部输入的地址无效
根据要求256Mb的SDRAM需要每64ms(企业级)或者16ms(车规级)执行8192次
可以有两种方法,一种是将64ms分为8192次也就是7.813us刷新一次,另一种是在64ms到来之前一次性发送8192次(但是这种无法处理即时突发的连续数据)
3.4.9.2SELF REFRESH
真正的自动刷新,不需要外部的参与,完全是由SDRAM内部进行刷新,从而保持内部数据有效性
进入这种模式需要将CKE也就是时钟使能信号拉低,并且这种模式的最低持续时间为tRAS,
退出自我刷新模式
1.CLK保持稳定 2. CKE使能拉高 3. 至少两个周期的NOP无操作指令(因为内部需要完成自己的刷新)
3.5 ,SDARAM的状态
3.5.1 IDLE
当bank被预充电后,等待tRP时间过后,SDRAM处于空闲状态
3.5.2 Row active
处在IDLE状态下的row,收到激活指令后,bank和row被选中,等待了tRCD时间后的等待状态
3.5.3 Read
处于Row active状态下的SDRAM,在收到READ指令后,bank和列被选中的状态
3.5.4 Write
处于Row active状态下的SDRAM,在收到WRITE指令后,bank和列被选中的状态
3.5.5 Refreshing
当发送 Refresh 后,等待 tRFC 时间,bank 进入 IDLE状态
3.5.6 Lode mode register
当发送 LOAD MODE REGISTER 指令后,等 tMRD 时间,bank进入IDLE状态:
3.5.7 PRECHARGE
发送预充电指令后等待tRP时间:
四 sdram_ip调用
五 awalon协议简析
在这里调用awalon协议ip是为了简化接口操作,不需要考虑激活,预充电等操作的时间
读写时序:
六 代码设计思路
6.1 利用awalon协议ip简单实现sdram读写
这里需要使用pll对时钟进行倍频和相位偏移,控制模块和ip使用100MHZ,仿真模型使用100MHZ并且偏移270度
ip端口描述
控制模块实现
/**************************************功能介绍***********************************
Date :
Author : WZY.
Version :
Description:
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module sdram_control(
input wire clk,
input wire rst_n,
input wire rd_req,
input wire [23:0] rd_addr,
output wire rd_data_vld,
output wire [15:0] rd_data,
input wire wr_req,
input wire [23:0] wr_addr,
input wire wr_data_vld,
input wire [15:0] wr_data ,
output wire done ,
//awalon
output wire am_wr_req_n,
output wire am_rd_req_n,
output wire [23:0] am_addr ,
output wire [15:0] am_wr_data ,
output wire [01:0] am_be_n ,//掩码
output wire am_cs ,//片选信号
input wire [15:0] am_rd_data ,
input wire am_rd_data_vld,
input wire am_waitrequest
);
//---------<参数定义>---------------------------------------------------------
//状态机参数定义
localparam IDLE = 'b0001,//
WRITE = 'b0010,//
READ = 'b0100,//
DONE = 'b1000;//
//---------<内部信号定义>-----------------------------------------------------
reg [3:0] cstate ;//现态
reg [3:0] nstate ;//次态
wire idle2write ;
wire idle2read ;
wire write2done ;
wire read2done ;
wire done2idle ;
//****************************************************************
// 数据寄存
//****************************************************************
reg [23:0] wr_addr_r;
reg [23:0] rd_addr_r;
reg [15:0] wr_data_r;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
wr_addr_r <= 0;
wr_data_r <= 0;
end
else if (wr_req) begin
wr_addr_r <= wr_addr;
wr_data_r <= wr_data;
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
rd_addr_r <= 0;
end
else if (rd_req) begin
rd_addr_r <= rd_addr;
end
end
//****************************************************************
// 状态机
//****************************************************************
//第一段:时序逻辑描述状态转移
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cstate <= IDLE;
end
else begin
cstate <= nstate;
end
end
//第二段:组合逻辑描述状态转移规律和状态转移条件
always @(*) begin
case(cstate)
IDLE : begin
if (idle2write) begin
nstate = WRITE;
end
else if (idle2read) begin
nstate = READ;
end
else begin
nstate = cstate;
end
end
WRITE : begin
if (write2done) begin
nstate = DONE;
end
else begin
nstate = cstate;
end
end
READ : begin
if (read2done) begin
nstate = DONE;
end
else begin
nstate = cstate;
end
end
DONE : begin
if (done2idle) begin
nstate = IDLE;
end
else begin
nstate = cstate;
end
end
default : nstate = IDLE;
endcase
end
assign idle2write = cstate == IDLE && wr_req;
assign idle2read = cstate == IDLE && rd_req;
assign write2done = cstate == WRITE && ~am_waitrequest;
assign read2done = cstate == READ && ~am_waitrequest;
assign done2idle = cstate == DONE && 1;
//****************************************************************
// Awalon Master 时序
//****************************************************************
assign am_wr_req_n = ~(cstate == WRITE);
assign am_rd_req_n = ~(cstate == READ );
assign am_cs = 1