您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 能源与动力工程 > 特权同学sdram源程序分析
特权同学SDRAM-测试程序程序分析知识点:sdram控制器,时序约束,测试文件第一部分:基本模块Sdram测试包括外部数据产生模块,fifo模块,sdram控制器,uart-RS232传输模块。Sdram控制器模块分块三块:控制模块,命令模块,数据传输模块具体来说,1.为什么要用FIFO模块呢?是因为外部数据与SDRAM控制器接收的速率不匹配,外部数据产生速率是FPGA系统时钟(25MHz),而SDRAM是100MHz;同样,把SDRAM中数据通过串口传输出到上位机时,也会有一个速率匹配问题,所以就有两个FIFO,其中一个写FIFO,一个读FIFO。2.Sdram控制器中控制模块完成初始化,自刷新,读写控制。命令模块有两个状态机,一个是初始化状态,另一个是工作状态。第二部分:各个部分详解1.Sdram控制模块输入引脚有:读、写请求,输出引脚有:写应答(表明正在写),读应答,忙信号(表明正在工作),初始状态,工作状态,计数时钟(用于定义时间段,与数据传输模块紧密联系)因为要用到好多时间参数,就直接建立一个参数文件。这个参数文件不是一个模块,所以不能用moduleendmodule来表示,里面所有参数有`define来开始,只是最后命名为.v文件。要用这个文件参数必须要前面加个“`”。`defineend_trpcnt_clk_r==TRP_CLK,其中cnt_clk_r与控制模块中cnt_clk_r一致。(这点是新学的)初始化过程分为200us等待,所有L-band预充电,8个预刷新,模式寄存器设置。//------------------------------------------------------------------------------//上电后200us计时,计时时间到,则done_200us=1//-----------------------------------------------------------------------------reg[14:0]cnt_200us;always@(posedgeclkornegedgerst_n)if(!rst_n)cnt_200us=15'd0;elseif(cnt_200us15'd20_000)cnt_200us=cnt_200us+1'b1;//计数assigndone_200us=(cnt_200us==15'd20_000);//条件满足则done_200us=1,此后一直保持高电平,因为计数器保持不变,这不同于一个脉冲信号//------------------------------------------------------------------------------//SDRAM的初始化操作状态机//------------------------------------------------------------------------------主要分析一个这个时间计算相当于用一个计时开关,这个开关就是cnt_rst_n(低电平计数器复位)。在参数文件中,`defineend_trpcnt_clk_r==TRP_CLK。cnt_clk_r在启动时就一直递增,而达到TRP_CLK时,也就是end_trp成立,完成标志,关闭开关cnt_rst_n.always@(posedgeclkornegedgerst_n)if(!rst_n)cnt_clk_r=9'd0;//计数寄存器复位elseif(!cnt_rst_n)cnt_clk_r=9'd0;//计数寄存器清零elsecnt_clk_r=cnt_clk_r+1'b1;//启动计数延时//计数器控制逻辑always@(init_state_rorwork_state_rorcnt_clk_r)begincase(init_state_r)`I_NOP:cnt_rst_n=1'b0;`I_PRE:cnt_rst_n=(TRP_CLK!=0);//预充电延时计数启动`I_TRP:cnt_rst_n=(`end_trp)?1'b0:1'b1;//预充电计数正好是TRP_CLK,计数结束,清零计数器//------------------------------------------------------------------------------//15us计时,产生自刷新请求。//每60ms全部4096行存储区进行一次自刷新,一行刷新时间是15us,这是一直在循环//(存储体中电容的数据有效保存期上限是64ms)//------------------------------------------------------------------------------这怎么与行选通配合呢?应该是在15us内进行了一次行有效跳转。刷新操作分为两种:自动刷新(AR)和自刷新(selfrefresh,SR),不论是何种刷新方式,都不需要外部提供行地址信息,因为这是一个内部的自动操作。,SDRAM内部有一个行地址生成器(也叫刷新计数器)用来自动的依次生成行地址。由于刷新是针对一行中所有存储体进行,所以无需列寻址。由于刷新是涉及到所有L-Bank,因此,在刷新过程中,所有的L-Bank都停止工作,占用N(PC133为9)个时钟后就可以进行正常的工作状态。SR则主要用于休眠模式低功耗状态下的数据保存,这方面最著名的应用就是STR(SuspendtoRAM,休眠挂起于内存)。在发出AR命令时,将CKE置于无效状态,就进入了SR模式,此时不再依靠系统时钟工作,而是根据内部的时钟进行刷新操作。在SR期间除了CKE之外的所有外部信号都是无效的(无需外部提供刷新指令),只有重新使CKE有效才能退出自刷新模式并进入正常操作状态。,外在表现:自动刷新CKE始终保持有效(置高),而自动刷新是CKE前一个时钟为高,后一个时钟为低。。内在表现:自动刷新就是需要CPU提供刷新的时钟,自刷新就是SDRAM芯片自己刷新,不需要CUP提供刷新的时钟这个时间是怎么计算的?对于ARAR与SR的区别本源程序用的就是AR如果要对同一L-Bank的另一行进行寻址,就要将原来工作的行关闭,重新发送行/列地址,L-Bank关闭现有的工作行,准备打开新行的操作就是预充电(precharge)。预充电可以通过命令控制(需要提供L-Bank的地址),也可以通过设置A10(置高)来让芯片在每次读写操作之后自动进行预充电。自刷新与预充电的区别?自刷新是对所有的行,而且不需要提供行地址信息。预充电是对指定的行(工作的行,工作的列)进行。具体如下图reg[10:0]cnt_15us;//计数寄存器always@(posedgeclkornegedgerst_n)if(!rst_n)cnt_15us=11'd0;elseif(cnt_15us11'd1499)cnt_15us=cnt_15us+1'b1;//60ms(64ms)/4096=15us循环计数,这是一个脉冲信号,高电平只保留一个时钟周期elsecnt_15us=11'd0;//每15us就产生一个自刷新求,sdram_ref_ack是自刷新工作指示always@(posedgeclkornegedgerst_n)if(!rst_n)sdram_ref_req=1'b0;elseif(cnt_15us==11'd1498)sdram_ref_req=1'b1;//产生自刷新请求elseif(sdram_ref_ack)sdram_ref_req=1'b0;//已响应自刷新assignsdram_ref_ack=(work_state_r==`W_AR);//SDRAM自刷新应答信号//------------------------------------------------------------------------------//SDRAM的读写以及自动刷新操作状态机//------------------------------------------------------------------------------读写控制信号是在完成初始化后进行的,自刷新与自动刷新不一样,它是手动操作(这种想法是错误的,它们都是自动操作),每隔15us产生一个刷新请求,自刷新优先级高于读写操作,这个很好理读写后都有一个等待时间进行预充电以便进行下一次读写操作。为什么这里没有解,要是超过这个时间,信息就会丢失。读写开始状态是行有效,根据命令进行读写。预充电操作呢?这是因为本源程序使用的是自动预充电(A10置高),所以这里就只用一个等待就行。reg[3:0]work_state_r;//SDRAM读写状态regsys_r_wn;//SDRAM读/写控制信号case(work_state_r)`W_RD:work_state_r=(`end_tread)?`W_RWAIT:`W_RD;//后面需要添加一个读完成后的预充电等待状态`W_RWAIT:work_state_r=(`end_trwait)?`W_IDLE:`W_RWAIT;//SDRAM写数据状态`W_WRITE:work_state_r=`W_WD;`W_WD:work_state_r=(`end_twrite)?`W_TDAL:`W_WD;`W_TDAL:work_state_r=(`end_tdal)?`W_IDLE:`W_TDAL;//SDRAM自动刷新状态`W_AR:work_state_r=(TRFC_CLK==0)?`W_IDLE:`W_TRFC;`W_TRFC:work_state_r=(`end_trfc)?`W_IDLE:`W_TRFC;default:work_state_r=`W_IDLE;endcaseendassignsdram_busy=(sdram_init_done&&work_state_r==`W_IDLE)?1'b0:1'b1;//SDRAM忙标志位,在进行初始化也是工作的一部分。//`defineend_twritecnt_clk_r==TWRITE_CLK-2(为6),这就好理解下面这些数字是怎么来,也就是在写没完成时就就指示在写。assignsdram_wr_ack=((work_state==`W_TRCD)&~sys_r_wn)|(work_state==`W_WRITE)|((work_state==`W_WD)&(cnt_clk_r9'd6));//写SDRAM响应信号,作为wrFIFO的输出有效信号//`defineend_treadcnt_clk_r==TREAD_CLK+2(为10)assignsdram_rd_ack=(work_state_r==`W_RD)&(cnt_clk_r9'd1)&(cnt_clk_r9'd10);//读SDRAM响应信号assignsys_dout_rdy=(work_state_r==`W_RD&&`end_tread);//SDRAM数据输出完成标志2.Sdram命令控制模块这个比较简单,只是利用命令。注意只有上电初始化时使时钟使CKE为无效(复位为0),其它命令CKE均置1.在模式寄存器设置(MRS)时,或写均是8Words.assign{sdram_cke,sdram_cs_n,sdram_ras_n,sdram_cas_n,sdram_we_n}=sdram_cmd_r;//SDRAM控制信号命令`defineCMD_INIT5'b01111//上电初始化命令端口设置突发长度为8,即是一次读`defineCMD_NOP5'b10111//NOPCOMMAND`defineCMD_ACTIVE5'b10011//ACTIVECOMMAND`defineCMD_READ5'b10101//READCOMMADN`defineCMD_WRITE
本文标题:特权同学sdram源程序分析
链接地址:https://www.777doc.com/doc-5141258 .html