SDRAM小项目——SDRAM初始化配置

主要写了SDRAM的初始化模块,注重文档信息的查找,时序图的设计,SDRAM仿真插件的使用。

文档信息:

        根据文档说明,SDRAM在使用之前必须先进行初始化

        初始化之前要进行100us的延迟,在100us内除了INHIBIT和NOP命令,其他命令都不可以执行,

时序图如下:

CLK为系统时钟,根据时序图,在100us的延迟后执行precharge命令,在经过trp时间后进行auto refresh命令 ,经过trc时间后再执行一次auto refresh,再经过trc时间后惊醒寄存器配置命令mode register,到此初始化完成。

阅读手册:

发现Nop模式下 cs_n.ras_n,cas_n.we_n的数据分别为0111/1xxx,同理precharge为0010,auto_ref为0001,

trc的最小时间间隔为63ns,4个周期(80ns——50hz/20ns),

trp的最小时间间隔为20ns,1个周期

配置模式寄存器:选择配置  A0-A11  分别为0100_0110_0000

根据文档说明画出时序图:

为了稳定设置延迟时间为200us,200us后flag200us拉高,命令计数器cnt_cmd开始计数(计时钟周期数),一开始进行precharge(周期0),进行autoref命令(周期1,5),进行mest(周期9)命令。初始化完成。

cmd_reg:用来进行命令的寄存,当cmd_cnt计数到相应周期的时候写入相应的配置。

sdram_addr:选择地址A0-A11

flag_init_end:当初始化任务完成后拉高点评,标志此时初始化完成

根据时序图编写verilog:

module sdram_init(
	input				sclk,
	input				srst,
	output	reg	[3:0]	cmd_reg,	//片选信号
	output	wire [11:0]	sdram_addr,	//A0-A11
	output	wire 		flag_init_end
);

//==========================================================
//=======	define parameter and internal signal	========
//==========================================================
localparam		delay_200us	= 10000;
// sdram command
localparam		nop			=	4'b0111;
localparam		pre			=	4'b0010;
localparam		aref		=	4'b0001;
localparam		mest		=	4'b0000;


reg [13:0]		cnt_200us		;
wire			flag_200us		;
reg [3:0]		cnt_cmd			;

//==========================================================
//====================	main	code	====================
//==========================================================
// cnt_200us
always@(posedge sclk or negedge srst) begin
		if(srst == 1'b0)
			cnt_200us <= 	'd0;
		else if(flag_200us == 1'b0)
			cnt_200us	<=	cnt_200us + 1'b1;
end


//cnt_cmd
always@(posedge sclk or negedge srst) begin
		if(srst == 1'b0)
			cnt_cmd		<=		'd0;
		else if(flag_200us	==	1'b1	&&	flag_init_end == 1'b0)
			cnt_cmd		<=	cnt_cmd + 1'b1;							//最后不需要归零,保持下去也可
end		

//cmd_reg
always@(posedge sclk or negedge srst) begin
		if(srst == 1'b0)
			cmd_reg		<=	nop		;
		else if(flag_200us == 1'b1)
			case(cnt_cmd)
				0:	cmd_reg	<=	pre	;
				1:	cmd_reg	<=	aref;
				5:	cmd_reg	<=	aref;
				9:	cmd_reg	<=	mest;
				default:cmd_reg <= nop;
			endcase
end

assign	flag_init_end	=	(cnt_cmd >= 'd10) ? 1'b1:1'b0;
assign	sdram_addr		=	(cmd_reg == mest) ? 12'b0000_0011_0010:12'b0100_0000_0000;
assign	flag_200us		= 	(cnt_200us	>=	delay_200us)? 1'b1:1'b0;

endmodule

根据文档说明编写SDRAM顶层模块:

  根据文档引脚描述:

clk为系统时钟输入,cke输出时钟使能信号,设置为高电平使SDRAM处于一直工作状态,cs,ras,cas,we,A0-A11,BA0-BA1,dqm(udqm和ldqm)均为输出,D0-D15为输入输出,vss/vdd/vssq/vddq为电源。

顶层模块代码:

module	sdram_top(
		input			sclk,
		input			srst,
		//sdram		interface
		output	wire	sdram_clk,
		output	wire	sdram_cke,
		output	wire	sdram_cs_n,
		output	wire	sdram_cas_n,
		output	wire	sdram_ras_n,
		output	wire	sdram_we_n,
		output	wire	[1:0]	sdram_bank,
		output	wire	[11:0]	sdram_addr,
		output	wire	[1:0]	sdram_dqm,
		inout			[15:0]	sdram_dq
);

//==========================================================
//=======	define parameter and internal signal	========
//==========================================================
wire 			flag_init_end;
wire	[3:0]	init_cmd;
wire	[11:0]	init_addr;


//==========================================================
//====================	main	code	====================
//==========================================================
assign	sdram_cke	=	1'b1;
assign	sdram_addr	=	init_addr;
assign	{sdram_cs_n, sdram_ras_n, sdram_cas_n, sdram_we_n} = init_cmd;
assign 	sdram_dqm	=	2'b00;
assign	sdram_clk	=	~sclk;	//内部时钟上升沿采集命令,命令又是由系统时钟上升沿产生的??(为了保证采样时刻处在数据中间时刻)


sdram_init	sdram_init_inst(
	.sclk				(sclk)	,
	.srst				(srst)	,
	.cmd_reg			(init_cmd)	,	
	.sdram_addr			(init_addr)	,	
	.flag_init_end	    		(flag_init_end)
);	

endmodule

注意在代码中设置了一个sdram_clk,它是系统时钟sclk的反相,sdram_clk连接到SDRAM的clk端口,是为了在中间时刻读取传输过来的数据,因为系统时钟上升沿从FPGA中传输数据到SDRAM,如果SDRAM的clk和系统clk保持一致,则在数据传输的一开始就开始写入SDRAM,可能数据传输仍然处在不稳定状态,反相之后可以保证在数据传输的中间时刻写入,保证稳定性。

测试模块代码:

例化了顶层模块,使用了sdram的插件(模仿SDRAM功能)

`timescale	1ns/1ns

module	tb_sdram_top;

	reg			sclk;
	reg			srst;
//----------------------------------------
	wire	sdram_clk;
	wire	sdram_cke;
	wire	sdram_cs_n;
	wire	sdram_cas_n;
	wire	sdram_ras_n;
	wire	sdram_we_n;
	wire	[1:0]	sdram_bank;
	wire	[11:0]	sdram_addr;
	wire	[1:0]	sdram_dqm;
    wire	[15:0]	sdram_dq;
//----------------------------------------

initial begin
			sclk = 1;
			srst <= 0;
			#100
			srst <=1;
end

always	#10		sclk = ~sclk;

defparam sdram_model_plus_inst.addr_bits =    12;
defparam sdram_model_plus_inst.data_bits =    16;
defparam sdram_model_plus_inst.col_bits  =    9;
defparam sdram_model_plus_inst.mem_sizes =    2*1024*1024;//1 M 


sdram_top		sdram_top_inst(
			.sclk							(sclk		),
			.srst							(srst		),
			.sdram_clk						(sdram_clk	),
			.sdram_cke						(sdram_cke	),
			.sdram_cs_n						(sdram_cs_n	),
			.sdram_cas_n						(sdram_cas_n),
			.sdram_ras_n						(sdram_ras_n),
			.sdram_we_n						(sdram_we_n	),
			.sdram_bank						(sdram_bank	),
			.sdram_addr						(sdram_addr	),
			.sdram_dqm						(sdram_dqm	),
			.sdram_dq						(sdram_dq	)
);


sdram_model_plus sdram_model_plus_inst(
 .Dq				(sdram_dq)	,
 .Addr				(sdram_addr), 
 .Ba				(sdram_bank), 
 .Clk				(sdram_clk), 
 .Cke				(sdram_cke), 
 .Cs_n				(sdram_cs_n), 
 .Ras_n				(sdram_ras_n), 
 .Cas_n				(sdram_cas_n), 
 .We_n				(sdram_we_n), 
 .Dqm				(sdram_dqm),
 .Debug				(1'b1)
 );
 
 
 
endmodule

SDRAM仿真代码:

/***************************************************************************************
 作者:    李晟
 2003-08-27    V0.1    李晟 
  
  添加内存模块倒空功能,在外部需要创建事件:sdram_r ,本SDRAM的内容将会按Bank 顺序damp out 至文件
  sdram_data.txt 中
 ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
 //2004-03-04    陈乃奎    修改原程序中将BANK的数据转存入TXT文件的格式
 //2004-03-16    陈乃奎    修改SDRAM 的初始化数据
 //2004/04/06    陈乃奎    将SDRAM的操作命令以字符形式表示,以便用MODELSIM监视
 //2004/04/19    陈乃奎    修改参数 parameter tAC  =   8;
 //2010/09/17    罗瑶    修改sdram的大小,数据位宽,dqm宽度;
 /****************************************************************************************
 *
 *    File Name:  sdram_model.V  
 *      Version:  0.0f
 *         Date:  July 8th, 1999
 *        Model:  BUS Functional
 *    Simulator:  Model Technology (PC version 5.2e PE)
 *
 * Dependencies:  None
 *
 *       Author:  Son P. Huynh
 *        Email:  sphuynh@micron.com
 *        Phone:  (208) 368-3825
 *      Company:  Micron Technology, Inc.
 *        Model:  sdram_model (1Meg x 16 x 4 Banks)
 *
 *  Description:  64Mb SDRAM Verilog model
 *
 *   Limitation:  - Doesn't check for 4096 cycle refresh
 *
 *         Note:  - Set simulator resolution to "ps" accuracy
 *                - Set Debug = 0 to disable $display messages
 *
 *   Disclaimer:  THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY 
 *                WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY 
 *                IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
 *                A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
 *
 *                Copyright ?1998 Micron Semiconductor Products, Inc.
 *                All rights researved
 *
 * Rev   Author          Phone         Date        Changes
 * ----  ----------------------------  ----------  ---------------------------------------
 * 0.0f  Son Huynh       208-368-3825  07/08/1999  - Fix tWR = 1 Clk + 7.5 ns (Auto)
 *       Micron Technology Inc.                    - Fix tWR = 15 ns (Manual)
 *                                                 - Fix tRP (Autoprecharge to AutoRefresh)
 *
 * 0.0a  Son Huynh       208-368-3825  05/13/1998  - First Release (from 64Mb rev 0.0e)
 *       Micron Technology Inc.
 ****************************************************************************************/
 
 `timescale 1ns / 100ps
 
 module sdram_model_plus (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm,Debug);
 
     parameter addr_bits =    13;
     parameter data_bits =    16;
     parameter col_bits  =    9;
     parameter mem_sizes =    4*1024*1024 -1;//1 Meg 
 
     inout     [data_bits - 1 : 0] Dq;
     input     [addr_bits - 1 : 0] Addr;
     input                 [1 : 0] Ba;
     input                         Clk;
     input                         Cke;
     input                         Cs_n;
     input                         Ras_n;
     input                         Cas_n;
     input                         We_n;
     input                 [1 : 0] Dqm;          //高低各8bit
     //added by xzli
     input              Debug;
 
     reg       [data_bits - 1 : 0] Bank0 [0 : mem_sizes];//存储器类型数据
     reg       [data_bits - 1 : 0] Bank1 [0 : mem_sizes];
     reg       [data_bits - 1 : 0] Bank2 [0 : mem_sizes];
     reg       [data_bits - 1 : 0] Bank3 [0 : mem_sizes];
 
     reg                   [1 : 0] Bank_addr [0 : 3];                // Bank Address Pipeline
     reg        [col_bits - 1 : 0] Col_addr [0 : 3];                 // Column Address Pipeline
     reg                   [3 : 0] Command [0 : 3];                  // Command Operation Pipeline
     reg                   [3 : 0] Dqm_reg0, Dqm_reg1;               // DQM Operation Pipeline
     reg       [addr_bits - 1 : 0] B0_row_addr, B1_row_addr, B2_row_addr, B3_row_addr;
 
     reg       [addr_bits - 1 : 0] Mode_reg;
     reg       [data_bits - 1 : 0] Dq_reg, Dq_dqm;
     reg       [col_bits - 1 : 0] Col_temp, Burst_counter;
 
     reg                           Act_b0, Act_b1, Act_b2, Act_b3;   // Bank Activate
     reg                           Pc_b0, Pc_b1, Pc_b2, Pc_b3;       // Bank Precharge
 
     reg                   [1 : 0] Bank_precharge     [0 : 3]
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值