SDRAM学习(一)——初始化

一、SDRAM概念
  SDRAM 的全称即同步动态随机存储器(Synchronous Dynamic Random Access Memory),同步是指其时钟频率与对应控制器(CPU/FPGA)的系统时钟频率相同,并且内部命令的发送与数据传输都是以该时钟为基准;动态是指存储阵列需要不断的刷新来保证数据不丢失;随机指数据的读取和写入可以随机指定地址,而不是必须按照严格的线性次序变化。
二、SDRAM存取原理
存储单元主要由行列选通三极管,存储电容,刷新放大器组成。对于这一位的数据,首先需要打开行地址,然后打开列地址,则电容的电平状态就能呈现在数据线(data_bit)上,即实现了读取。数据线上的电平值被送到电容上,从而实现写入数据。注意此处行列打开后,数据不会立刻被处理,有延时,称作行列选通潜伏期,不同速度延时tRP不同。

三、SDRAM引脚

四、SDRAM操作命令

{CS_N,RAS_N,CAS_N,WE}命令说明
0011激活命令BA0 和 BA1 用来选择需要操作的 BANK,地址线A0–A12 选择指定的行。该行会一直保持激活状态并可以进行读写,只有执行一个预充电命令后,才能关闭,并对其他行进行操作
0101已经激活行的突发读取操作位 A0–A9, A11(x4),A0–A9(x8),A0–A8(x16))指定需要读取的数据起始列地址,A10读取完成之后立即执行预充电,即关闭当前行操作
0100写命令位 A0–A9, A11(x4),A0–A9(x8),A0–A8(x16))指定需要写的数据起始列地址,A10写完成之后立即执行预充电,即关闭当前行操作
0010预充电关闭指定或全部BANK(由A10状态选择)中已经打开的行,等待 tRP 的时间后对应的 BANK 将可以重新被操作
xxxx自动预充电不额外增加执行指令的使用预充电指令,A10指明是否在突发读写完成后立即自动执行预充电操作
0110突发中断离该命令最近的一次被 SDRAM 寄存的读或者写命令被截断,截断后仍处于激活状态
0001自动刷新用来保持SDRAM中的数据,该命令是非持续性的,自动刷新命令之前,所有的BANK必须被预充电(关闭)
五、SDRAM操作时序
上电初始化步骤:
加载电源—— CKE设置为低电平——时钟信号——等待100毫秒,禁止命令操作,其中一时刻cke拉高——全部 BANK 的预充电命令——预充电后等待tRP后才能进行命令——自动刷新命令,然后等待tRFc——重复自动刷新命令,然后等待tRFc——发出装载模式寄存器命令设置模式寄存器——等待时间 tMRD——初始化完成
//定义操作操作命令{CS_N,RAS_N,CAS_N,WE}           
parameter   C_NOP = 4'b0111,  //空操作命令
            C_PRE = 4'b0010,  //预充电命令
            C_AREF = 4'b0001, //自动刷新命令
            C_MSET = 4'b0000, //加载模式寄存器命令
            C_ACT = 4'b0011,  //激活命令
            C_RD = 4'b0101,   //读命令
            C_WR = 4'b0100;   //写命令
//线性序列机
parameter	INIT_PRE = 20000;//初始化等待时间>100us,取200us
         	REF_PRE = 3;     //tRP  >=20ns,取30ns
         	REF_REF = 10;    //tRRC  >=66ns,取100ns
localparam init_PRE_TIME = INIT_PRE,           //预充电时刻
				  init_AREF1_TIME = INIT_PRE + REF_PRE, //自动刷新时刻
				  init_AREF2_TIME = INIT_PRE + REF_PRE + REF_REF,    //自动刷新时刻
				  init_LMR_TIME = INIT_PRE + REF_PRE + REF_REF * 2,  //加载模式寄存器
				  init_END_TIME = INIT_PRE + REF_PRE + REF_REF * 2 + LMR_ACT;   //结束时刻
//相应时刻发出对应的命令和操作
	always@(posedge clk or negedge rst_n)
	begin
	if(!rst_n)begin		//复位地址清零,空操作命令
			command <= C_NOP;
			saddr <= 0;
		end
		else begin
			case(init_cnt)
				init_PRE_TIME:begin    //预充电时刻,预充电命令,A10拉高,对所有BANK行进行预充电(若A10为低电平,则只对BA0和BA1定的BANK中的行进行预充电)
					command <=  C_PRE;   
					saddr[10] <= 1'b1;
				end
				
				init_AREF1_TIME:begin		//自动刷新时刻,自动刷新命令
					command <=  C_AREF;
				end
				
				init_AREF2_TIME:begin		//第二次自动刷新时刻,自动刷新命令
					command <=  C_AREF;
				end
				
				init_LMR_TIME:begin			//加载模式寄存器,加载模式寄存器命令,A0-A10为{写突发模式设置,00,列选通潜伏期设置,突发类型设置,突发长度设置}此处各位对应功能查表
					command <=  C_MSET;
					saddr <= {OP_CODE,2'b00,SDR_CL,SDR_BT,SDR_BL};
				end
				
				default:begin
					command <= C_NOP;
					saddr <= 0;
				end
			endcase
		end	
	end

对初始化后代码进行仿真验证,此处调用镁光SDRAM 仿真模型

`timescale 1ns/1ns
`define clock_period 10           //100M

module sdram_int_tb;

`include "../rtl/Sdram_Params.h"

	reg clk;
	reg rst_n;
	wire [3:0]command;
	wire [`ASIZE - 1:0]saddr;
	wire init_done;
	
	wire sd_clk;
	wire cs_n;
	wire ras_n;
	wire cas_n;
	wire we_n;
	
	//SDRAM初始化模块例化
	sdram_init sdram_init(
			.clk(clk),
			.rst_n(rst_n),
			.command(command),
			
			.saddr(saddr),
			.init_done(init_done)
			);
	
	assign {cs_n,ras_n,cas_n,we_n} = command;
	assign sd_clk = ~clk;
	
	//SDRAM模型例化
	sdr sdram_model(
			.Dq(), 
			.Addr(saddr),
			.Ba(), 
			.Clk(sd_clk), 
			.Cke(rst_n), 
			.Cs_n(cs_n), 
			.Ras_n(ras_n), 
			.Cas_n(cas_n), 
			.We_n(we_n), 
			.Dqm()
			);
	
	//系统时钟产生
	initial clk = 1'b1;
	always #(`clock_period/2) clk = ~clk;
	
	initial 
	begin 
		rst_n = 1'b0;
		#(`clock_period*200 + 1);
		rst_n = 1'b1;
		
		@(posedge init_done)
		#2000;
		$stop;
	end
endmodule

仿真图像

镁光自动打印信息

至此SDRAM初始化完成。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值