FPGA中用verilog直接读写操作SDRAM

1 简介

 SDRAM 型号为MT48LC32M16A2。SDRAM,英文名是: Synchronous Dynamic Random Access Memory,相较于 SRAM(静态存储器), SDRAM 具有:容量大和价格便宜的特点,但是需要动态刷新,保持存储单元内的数据不丢失。

1.1  简洁使用说明

1、auto refresh 
     每一行数据需要间隔最大64ms刷新一次,否则数据不稳定。只需要发送命令,存储器行地址自动更新。每次同时刷新所有bank的相同行地址的行。
     每次auto refresh 前要先关闭all bank的打开行。
2、突发模式
     full page表示一行中所有1024列,到达边界后从0开始循环,需要突发停止命令结束突发;

      一行突发到边界仍在本行,从头循环;

       突发读写全页,必须加突发停止。一页=1024=一行中总列数。
3、read write with auto precharge
   写行地址时,若A10=1,则读写结束后自动precharge.
   precharge操作是关闭当前打开的行。
4、专门的precharge命令
  关闭all  bank 或指定bank;
5、可以配置读写都突发,或者读突发写不突发。
6、各个操作之间需要满足时序关系。
    读数据延时CL=2或3;
    每次读写前,先激活一行,读写完成,关闭行;
7、不同bank可以乒乓操作,关闭一个bank的同时,操作另一bank.

     precharge一个bank的同时,可以无缝同时读取操作其它三个bank中任一个,不用等待;
8、芯片所有操作均在始终上升沿采样,向芯片发数据时用下降沿处理。

1.2 存储单元组织结构

4个BANK,每个BANK有8192行,每一行有1024列,每个地址存储位宽16bits,整个芯片的容量为: 8192*1024*4*16=64M 字节。

1.3参数

1.4信号接口

2 操作命令

1)指令禁止(COMMAND INHIBIT)

         阻止执行新命令。正在进行的操作不受影响。

2) 空操作(NO OPERA)

     不执行任何操作,防止执行不需要的命令。正在进行的操作不受影响。

3) 行激活(ACTIVE)

     激活特定 Bank 块中的行,address 总线提供行地址。可以依次激活多个bank的某一行。行保持活动状态,直到向该 Bank块发出 PRECHAEGE 命令。在本bank中先关闭一行,才能打开另一行。

4)读(READ)

       READ 命令用于启动对已经被激活行的突发读取访问。BA0~BA1 选择Bank ,地址总线选择起始列位置。A10 上的值决定了是否使用自动预充电。如果选择了自动预充电,则正在访问的行在 READ 突发结束时被预充电。如果未选择自动预充电。则该行要保持打开状态以供后续访问。

 DQM 信号为高电平,则相应的读数据 DQ 将在两个时钟之后为 High-Z。

  读取的数据延时命令CL=2个clk出现在数据总线。

5)写(WRITE)

     WRITE 命令用于启动对已经被激活行的突发写访问。地址为操作同READ操作。 DQM 信号为高电平,立即屏蔽数据输入。

注意DQM在数据读写的区别:

   在读数据时, DQM出现后延迟两个周期才起作用,屏蔽 DQ 总线(DQM提前2clk出现才能完整屏蔽输出的DQ数据);

   在写数据时,数据与 DQM 时同步的,只要 DQM 有效,则数据立马被写入。

   在读写转换时,在写操作前必须至少有2clk的DQM=1,把DQ的输出状态变位高阻,准备写数据到总线。

6) PRECHARGE(预充电)

       PRECHARGE 命令用于关闭一个 Bank 中打开的行或者所有 Bank 中的打开的行。输入 A10 的值确定是否要预充电一个或所有 Bank。在 Bank 预充电后处于空闲状态, READ 或者 WRITE 命令之前激活。

        对一行的读写操作会干扰原电荷,需要预充电操作,回写原数据。

7)REFRESH(刷新)

       PRECHARGE是对一个或所有  L-Bank  中的工作行操作,并且是不定期的,而刷新则是有固定的周期,依次对所有行进行重写操作。REFRESH的行是指所有 Bank 中地址相同的行同时刷新,而预充电中各 L-Bank 中的工作行地址并不是一定是相同的。

        存储体中电容的数据有效保存期上限是 64ms,每一行刷新的循环周期是 64ms。刷新命令一次对一行有效,发送间隔也是随总行数而变化,  8192 行时就为 7.8125μs。

       刷新操作分为两种:自动刷新(Auto Refresh,简称 AR)与自刷新(Self Refresh,简称 SR)。不论是何种刷新方式,都不需要外部提供行地址信息,因为这是一个内部的自动操作。对于 AR, SDRAM 内部有一个行地址生成器(也称刷新计数器)用来自动的依次生成行地址。由于刷新是针对一行中的所有存储体进行,所以无需列寻址,或者说 CAS 在 RAS之前有效。所以, AR 又称 CBR(CAS Before RAS,列提前于行定位)式刷新。由于刷新涉及到所有 L-Bank,因此在刷新过程中,所有 L-Bank 都停止工作,而每次刷新所占用的时间为 9 个时钟周期(PC133 标准),之后就可进入正常的工作状态,也就是说在这 9 个时钟期间内,所有工作指令只能等待而无法执行。 64ms 之后则再次对同一行进行刷新,如此周而复始进行循环刷新。

       SR 则主要用于休眠模式低功耗状态下的数据保存,最著名的应用就是 (Suspend to RAM,休眠挂起于内存)。在发出 AR 命令时,将 CKE 置于无效状态,就进入了 SR 模式,此时不再依靠系统时钟工作,而是根据内部的时钟进行刷新操作。在 SR 期间除了 CKE之外的所有外部信号都是无效的(无需外部提供刷新指令),只有重新使 CKE 有效才能退出自刷新模式并进入正常操作状态。行地址增加,时钟,都由内部控制

       问题:如果clk不是133M,刷新时间由多长???

8)LOAD MODE REGISTER(加载模式寄存器)

      在启动时期,模式寄存器处于未知的状态,在发送操作命令之前需要先对模式寄存器进行配置。当模式寄存器被配置完之后,其信息一直保留到下一次被配置之前或者掉电。模式寄存器位 :

M[2:0]  指定突发长度(BL):在同一行中相邻的存储单元连续传输的周期数,1 -2 -4 -8 或fullpage整行突发(可配合突发停止命令,中断突发);

M3      指定突发类型:顺序或者交替,一般选择顺序;

M[6:4]指定 CAS 延迟(CL):延迟 CL 周期读出数据(注意:写入数据不需要考虑 CL 值);

M7 和 M8 指定操作模式,一般[00]标准模式;

M9 指定写突发模式,按M[2:0]设置的长度,或不突发单个地址;

M10-Mn 应设置为零确保与未来的新一代的 SDRAM 兼容。当所有存储体空闲时,必须加载模式寄存器。

3 读写操作

3.1 上电初始化

初始化过程分为五步:

(1)上电:至少等待 100us(时钟稳定工作的时间),在这个时间内,提前使能 CKE时钟,并发送 NOP(No Operation 命令)。

(2)发送预充电命令:给所有或单个 L- Bank 预充电。

(3)发送自动刷新命令:发送预充电命令之后至少等待 tRP 时间, 在这个时间内 NOP或者 DESELECT 命令一定要给出,完成所以的 bank 的预充电。接着给出预充电的命令。预充电命令与自动刷新命令之间至少需要 8 个时钟周期(50MHz 的时钟)。

(4)设置模式寄存器:发送模式寄存器的值,配置 SDRAM 的工作参数。配置完成后,需要等待 tMRD(也叫 tRSC),使模式寄存器的配置生效,才能发送其他命令,否则将导致未知的操作结果。

(5)完成:经过前面四步的操作, SDRAM 的初始化就完成了,接下来,就可以发送激活命令和读/写命令,进行数据的读/写了。这里提到的 tRP、 tMRD 和 tRSC 见 SDRAM 的芯片数据手册。

3.2 写操作

SDRAM 的写流程如下:

(1)发送激活命令:同时设置行地址和  BANK 地址,发送该命令后,需要等待  tRCD时间,才可以发送写命令。

(2)发送写命令:该命令同时设置列地址,完成对  SDRAM 的寻址,同时,将数据通过  DQ 数据线,存入  SDRAM。

(3)使能自动预充电(突发完成时,自动预充电):在发送写命令的同时,拉高  A10地址线,使能自动预充电,以提高读写效率。

(4)完成一次数据写入:最后,发送第二个激活命令,启动下一次数据传输。这样,就完成了一次数据的写入。

3.3 读操作

SDRAM 的读流程如下:

(1)发送行激活命令:同时设置行地址和 BANK 地址,发送该命令后,需要等待 tRCD时间,才可以发送读命令。

(2)发送写命令:在发送完激活命令,并等待 tRCD 后,发送读命令,该命令同时设置列地址,完成对 SDRAM 的寻址。读操作还需要考虑 CL 延迟(CAS Latency),所以需要等待给定的 CL 延迟(2 个或 3 个 CLK)后,才可以从 DQ 数据总线上读取数据。

(3)使能自动预充电:在发送读命令的同时,拉高 A10 地址线,使能自动预充电,以提高读写效率。

(4)完成一次数据写入:最后,发送第二个激活命令,启动下一次数据传输。这样,就完成了一次数据的读取。

4 其它注意

4.1 DQM的使用注意

 

4.2 代码说明

   把各个命令以task 的形式来调用,命令发出用下降沿。可以使用micron官方提供的代码作为参考来更改自己的代码(官方代码4077mt48lc32m16a2.zip),可在官网下载。


task active;
    input  [1 : 0] bank;
    input [12 : 0] row;
    input [15 : 0] dq_in;
    begin
        cke   = 1;
        cs_n  = 0;
        ras_n = 0;
        cas_n = 1;
        we_n  = 1;
        dqm   = 0;
        ba    = bank;
        addr  = row;
        dq    = dq_in;
    end
endtask

  本地命令用时钟下降沿发送命令,以便SDRAM在上升沿采到数据中间。

always @(negedge clk or negedge rst)
begin
	if(!rst)
		begin
			cke   = 0;     
			cs_n  = 1;     
			ras_n = 1;     
			cas_n = 1;     
			we_n  = 1;     
			dqm   = 3;
			ba    = 0;  
			addr  = 0;
			dq    = hi_z; 
			dq <= 16'd0 ;
		end
	else	
		begin
			case(cnt_reg)
				//写SDRAM—— 写 一 列
				'd0 : nop (0, hi_z);                     //空操作  
				'd1 : precharge_all_bank(0, hi_z);       //对全部的块预充电                           
				'd2 : nop (0, hi_z); 
				'd4 : auto_refresh;                      //自动刷新                                                 
				'd5 : nop (0, hi_z);                     
				'd12: auto_refresh; 
				'd13: nop (0, hi_z);  
				'd20: load_mode_reg (13'd39);            //加载模式 潜伏期CL=2,突发长度:全页
				'd21: nop (0, hi_z);                                                   
				'd22: active (wr_bank, row_wr, hi_z);    //ACTIVE命令用于激活特定库中的一行以备后续使用访问      
				'd23: nop (0, hi_z);                     
				'd24: write(wr_bank, 0, sdram_wr_data, 0); //写命令,关闭自动precharge
				'd25: nop (0,sdram_wr_data);					//写数据,此处时间长度1022clk,突发写全页
				'd26:  burst_term; 							//数据突发停止
				'd27: nop (0, hi_z);
				
				//读SDRAM —— 读 一 列
				'd30: nop (0, hi_z);                     //空操作                             
				'd31: precharge_all_bank(0, hi_z);       //对全部的块预充电,关闭所有打开的行                 
				'd32: nop (0, hi_z);                                                 
				'd34: auto_refresh;                      //自动刷新,每隔64ms/一个bank行数执行一次                     
				'd35: nop (0, hi_z);  
//				'd42: auto_refresh; 
				'd43: nop (0, hi_z);  				
				'd50: load_mode_reg (13'd39);            //加载模式   
				'd51: nop (0, hi_z);                                                    
				'd52: active (rd_bank, row_rd, hi_z);    //ACTIVE命令用于激活特定库中的一行以备后续使用访问      
				'd53: nop (0, hi_z);                     
				'd54: read (rd_bank, 0, hi_z, 0);		  //读命令,关闭自动precharge
				'd55: nop (0, hi_z);
				'd56: nop (0, hi_z); 	//读数据,长1022clk,突发读全页
				'd57: burst_term;		//数据突发停止,burst读写full page必须跟随 burst_term
				'd58: nop (0, hi_z);
			endcase
		end
end

4.3 RANK

一个RANK指数据位宽64bits,则可由4个16bits DDR片子组成。
一个模组可包含几个RANK,数量由模组的地址深度决定。

4.4 硬件

硬件使用的是《凌智Winner双4代核开发板》,ARM+FPGA架构,可使用其提供的例程做参考设计。

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值