您的位置:首页 > 其它

力战SDRAM(三)

2015-10-28 17:46 148 查看
我们分两条主线来介绍SDRAM的读写:地址线和数据线首先地址线上,在FPGA启动,延时500微妙。然后地址计数器cntwr每等到延时500us加1(else if(delay_done) cntwr <=cntwr+1'b1)直到加到63,然后让地址寄存器addr加1。(else if(!wr_done && cntwr ==6'h3f) addr <= addr+1'b1)也就是说,32毫秒,地址线加1,但是这个地址线并不是最终送到SDRAM上的,只是产生的暂时地址信息。----------------------------------------------------------------------------------------------------------在数据线,FPGA启动,延时500微妙。为了写数据到写FIFO(写是名词,表示这个FIFO是用来写进数据的)而设定的计数器cnt于5时拉高写有效引脚,同时此时让数据寄存器wr_dinr加1,cnt与0d时,拉低写有效引脚,同时数据寄存器停止加1,结束数据写入,共写入8个数据。如此8个8个的往复写入!(else if(!wr_done && ((cntwr >6'h05) && (cntwr <= 6'h0d)))begin wrf_dinr <= wrf_dinr+1'b1)------------------------------------------------------------------------------------------------------------------------------一旦数据写入FIFO达到8个,则激活系统写SDRAM请求信号sdram_wr_req,使之有效(高)(assign sdram_wr_req = ((wrf_use >=9'd8) & ~syswr_done))。而sdram_wr_req有效,进而使读写状态机运行到`W_ACTIVE状态(elseif(sdram_wr_req & sdram_init_done) begin work_state_r <= `W_ACTIVE)。从而顺势走向`W_WRITE状态。而一旦进入这个状态,将激活sdram_wr_ack信号(assign sdram_wr_ack = (work_state ==`W_WRITE) | ((work_state == `W_WD) & (cnt_clk_r < 9'd8)& (cnt_clk_r>= 9'd0));)这个信号控制着写FIFO内的数据是否传输到q引脚,所以sdram_wr_ack有效后,写FIFO的数据就会传输到q进而传输到与其相连的sys_data_in数据寄存器。由于进入了`W_WRITE状态,就会启动写数据模块sdram_wr_data,把数据送到SDRAM芯片的数据端口(elseif((work_state == `W_WRITE) | ((work_state == `W_WD)&(cnt_clk <9'd8)& (cnt_clk >= 9'd0))) sdr_din<=sys_data_in;)(此状态完成一次后,进入等待状态IDEL,重新判断当前信息,如果满足,再次进入此状态,不满足此状态要求,进入其他状态)-----------------------------------------------------------------------------------------------------------------------------------再看地址线,在进入`W_WRITE状态时,我们是不知道此时addr已经计数到哪了,但是无论如何,到达`W_WRITE时,我们会把当前addr所形成的sys_addr的拆分成行,列数值数值传送到SDRAM的地址线上(sdram_addr_r <= {4'b0010, sys_addr[8:0] };)在传送地址的同时,数据也就跟着写进去了!就这样不停的传送地址,直到地址线加满。我们往SDRAM中写数据的时代也就过了(else if(addr == 22'h3fffff) wr_done <= 1'b1)。---------------------------------------------------------------------------------------------------------------------------------------这个时候地线写满标志syswr_done被激活(assign syswr_done = wr_done)同时由于读FIFO储存器之中数据为0,也就激活了往读FIFO储存器中写数据的信号线sdram_rd_req(assign sdram_rd_req = ((rdf_use <=9'd256) & syswr_done))此信号一有效,状态机即进入读SDRAM数据的状态`W_READ(else if(sdram_rd_req &&sdram_init_done) beginwork_state_r <= `W_ACTIVE;//读SDRAMsys_r_wn <= 1'b1; )在此状态下,会激活读数据请求信号sdram_rd_ack(assign sdram_rd_ack = (work_state_r ==`W_RD) & (cnt_clk_r >= 9'd0) & (cnt_clk_r < 9'd8);)这个信号有效则会使地址线由0开始自加1(else if(wr_done && neg_rdack) addr <=addr+1'b1;)//neg_rdack是sdram_rd_ack有效后产生的脉冲同时送到SDRAM地址线(此状态完成一次后,进入等待状态IDEL,重新判断当前信息,如果满足,再次进入此状态,不满足此状态要求,进入其他状态)(sdram_addr_r <= {4'b0010, //A10=1,设置写完成允许预充电sys_addr[8:0] //列地址 };)也就是说每次这个状态来临时,SDRAM地址线会更新加1。相比于写数据的时候,读数据的时候,地址是连续的,相当于遍历一遍所有地址。每次SDRAM地址线更新后,SDRAM的数据总线上的数据就会更新。把此数据传递给串口发送模块(else if((work_state == `W_RD) &(cnt_clk >=9'd0) & (cnt_clk < 9'd8)) sdr_dout <= sdram_data; )发给电脑上位机(关于串口发送模块,自行补脑)

本文出自 “Hi,jiashuo!” 博客,请务必保留此出处http://jiashuo.blog.51cto.com/10830673/1707384
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: