学习SDRAM断断续续的算起来两个星期的时间是有的,但到现在程序还是没有调出来,并且还是参照特权同学的程序调的。还是要继续调,总结一下前段时间的学习。
SDRAM的工作大致可以分为:上电初始化和工作状态里面始终贯穿的刷新。对于上电初始化
还是按特权的思路来写,SDRAM的控制器主要包括三个模块:sdram_ctrl,
sdram_cmd,sdram_wr_data. sdram_ctrl 里面主要包括:初始化状态机,工作状态机,定时产生刷新请求,SDRAM时序操作的延时,sdram_cmd模块用于向SDRAM 发出命令,sdram_ctrl把init_state[4:0]和work_state[3:0]的信号给它,它根据
不同的状态发不同的命令,基本的几个是空命令('CMD_NOP),预充电命令('CMD_PRGE),刷新命令('CMD_A_REF),模式寄存器配置命令('CMD_LMR)。sdram_wr_data模块接受sdram_ctrl的work_state[4:0]信号并且只看是读还是写状态,读状态把SDRAM的数据读出来,写状态是往里面写。
输入稳定期200us可以通过一个计数器进行延时,设一个标志位,当延时到了以后标志位置一,在初始化状态机里面的(' I_NOP)判断是否为一,如果是跳到下一个状态所有BANK预充电(' I_PRE),在这个状态只会停留一个时钟周期,但命令模块会发出预充电命令,然后进入预充电等待状态(' I_TRP),所有等待状态的延时都是通过后面的SDRAM时序操作的延时部分完成的,它定义了几个参数,一个时钟计数器,看时钟计数器的值是不是等于相应的参数,相等着条件满足,进入下一个状态自动刷新状态(' I_AR1),跟预充电状态一样只停留一个周期,但命令模块会发出相应的命令,再到自刷新等待状态(' I_TRF1),延时都是那个SDRAM时序部分完成的,直到8次完成,凡是在等待状态命令模块发出的都是空命令(' CMD_NOP),再进入模式寄存器设置状态(' I_MRS),在这个状态sdram_cmd模块不仅要发出配置寄存器命令' CMD_LMR,同时还需要地址线发相应的数据(根据你的需要选择不同的模式,就是写寄存器的值)。再到寄存器设置等待状态,完了以后设置初始化完成标志位(sdram_init_done = 1)。
对于工作状态机可以分三条主线:
1, 工作空闲状态(W_IDLE)-->自动刷新状态(W_AR)-->自动刷新等待状态(W_TRFC)-->工作空闲状态。
2, 工作空闲状态(W_IDLE)-->行有效状态(W_ACTIVE)-->行有效等待状态(W_TRCD)-->读数据准备状态(W_READ)-->读等待潜伏期(W_CL)-->读数据状态(W_RD)-->读完后预充电等待状态(W_RWAIT)-->工作空闲状态。
3,工作空闲状态(W_IDLE)-->行有效状态(W_ACTIVE)-->行有效等待状态(W_TRCD)-->写数据准备状态(W_WRITE)-->写数据状态(W_WD)-->等待数据写完并自刷新结束状态(W_TDAL)-->工作空闲状态。
在开始的工作空闲状态判断前面初始化是否完成的同时还需要看有没有自动刷新请求或则写请求或则读请求(他们是有优先权的),根据相应的请求进入相应的状态,命令模块则根据相应的状态发送相应的命令,数据模块其实很简单只是在读写两个状态的时候要么把数据写入SDRAM要么把数据从SDRAM里面读出来。
sdram_ctrl里面的时序操作的延时部分写的不错,在需要发有效(非空)命令的状态(这些状态只停留一个时钟周期)将cnt_rst_n置1,则cnt_clk_r开始计数,在等待状态就等着cnt_rst_n是否到达设定的值,如果不相等cnt_rst_n继续为1,继续计数,如果相等cnt_rst_n则为0,cnt_clk_r则清零。当下一个有效命令状态时又将cnt_rst_n置1,重新开始计数。这样完成各状态的延时。
在sdram_ctrl 模块中还有一重要部分就是产生刷新请求信号(sdram_ref_req),业界公认的刷新周期是64ms,我们用的SDRAM行地址是12跟线共有4096行,64/4096ms大约是15us,这部分则每隔15us发一个刷新请求信号,当工作状态机进入刷新状态,它就会发出 刷新应答信号,刷新请求信号清零。
这就是特权同学程序的思路。
补充:
几个关键的延时和几个重要的概念
1, tRCD(即RAS to CAS Delay) 可以理解为行选通周期,也就是发行地址后要过几个时钟才能发列地址。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
2,CL(CAS Latency,CAS潜伏期)在发送CAS之后,仍要经过一定时间才能使数据通过I/O通道(DQ)输出到内存总线上,才能读数据(CL延时里面已经包括了tAC),切忌这个CL延时是在读操作的时候才有,在写操作的时候没有这个。
3,在写操作的时候数据可以和CAS同时发出,但电容充电需要一定的时间。为了保证数据的可靠写入都会留一点时间(tWR,Write Recovery Time),这个操作也被称为写回(Write Back).
4,tRP(Precharge command period) 预充电有效周期,也就是说在发出预充电命令之后,要经过一段时间才允许发送RAS行有效或则是其他的命令。
5刷新,预充电是对一个BANK或则是全部BANK中的工作行进行操作,并且是不定期的,而刷新时有固定周期的,依次对所有行进行操作,以保留那些久久没有经历重写的存储体中的数据。但与所有L-BANK预充电不同的是,这里的行是指所有L-BANK中地址相同的行,而预充电中各L-BANK中的工作行地址并不一定是相同的。公认的刷新周期是64ms每行,如果一个存储体有N行,那你就要每隔N/64ms发一次刷新命令。刷新命令一次只对一行有效,发送间隔也总是随着行数的变化而变化。刷新的操作分为两种:自动刷新(Auto Refresh,简称AR)与自刷新(Self Refresh,简称SR),无论哪种刷新方式,都不需要外部提供行地址信息,因为这是一个内部的自动操作。
对于AR,SDRAM内部有行地址生成器,不需要列地址因为它是对一行中所有的都刷新。由于刷新涉及到所有的BANK,所以在刷新过程中,所有BANK 都停止工作,而每次刷新的周期是9个时钟周期,在此期间所有的工作指令自能等待。
SR则主要用于休眠模式低功耗状态下的数据保存。
6,预充电:由于SDRAM的寻址具有独占性,所以在进行完读操作后,如果要对同一L-BANK的另一行进行寻址,就要关闭原来的工作行,重新发送行/列地址。L-BANK关闭现有工作行,准备打开新行的操作就是预充电(precharge).预充电可以通过命令控制,也可以通过辅助设定让芯片在每次读写操作之后自动进行预充电。实际上预充电是一种对工作行中所有存储体进行数据重写,并对行地址进行复位。
用户377235 2013-1-29 16:38
"一个时钟计数器,看时钟计数器的值是不是等于相应的参数,相等着条件满足,进入下一个状态自动刷新状态(' I_AR1),跟预充电状态一样只停留一个周期" 为什么是一个时钟周期呢?应该根据延时参数计算延时时间吧!
用户415124 2012-7-2 16:29