sdram_core.v
可以根据datasheet查到时序要求,如tRP(pre-charge即完成预充电需要等待的时间),tRFC(完成自动刷新需要等待的时间),tMRD(完成寄存器配置需要等待的时间),tRCD(active即完成激活需要等待的时间),tCL(从发出读命令到第一个数据出现在数据总线上需要等待得时间),tWR(数据写入完成需要等待的时间)
SDR_BA_WIDTH 即bank地址宽度,SDR_ROW_WIDTH 即行地址宽度
SDR_COL_WIDTH 即列地址宽度,SDR_DQ_WIDTH 即数据宽度
SDR_DQM_WIDTH 即数据掩码宽度,APP_ADDR_WIDTH 上层模块发出的地址宽度
APP_BURST_WIDTH 突发长度宽度
wr_burst_req,wr_burst_data,wr_burst_len,wr_burst_addr,由mem_test模块输出给sdram_core模块,wr_burst_finish,wr_burst_data_req,是由sdram_core模块输出给mem_test模块。
rd_burst_req,rd_burst_len,rd_burst_addr均由mem_test模块输出给sdram_core模块,
rd_burst_data,rd_burst_data_valid,rd_burst_finish均由sdram_core模块输出给mem_test模块。
这里wr_burst_len和rd_burst_len是指mem_test模块输出给sdram_core模块的连续突发长度,这里的突发长度不是指SDRAM的burst_len(由输入模式寄存器命令中,设置addr),而是指对sdram_core下达连续读写长度。
sdram_cke,sdram_cs_n,sdram_ras_n,sdram_cas_n,sdram_we_n,sdram_ba,sdram_addr,sdram_dqm,sdram_dq是直接连接到SDRAM外部器件的信号。
根据时序图可以看出state设置原因
read_flag是当state进入到S_TRCD,需要根据这个标识信号(read_flag)来决定进入S_READ还是S_WRITE,而read_flag是由write_burst_req/read_burst_req决定。
done_200us是200us延时结束的标志信号。
sdram_ref_req是state==S_IDLE时进入S_AR的触发信号,sdram_ref_ack是结束7p5us(7.5us)计数器的触发信号。
sdr_dq_oe是决定sdr_dq是输入数据还是输出数据。
wr_burst_data_req_d0;wr_burst_data_req_d1是wr_burst_data_req的2级缓存,用来抓取边沿跳变,rd_burst_data_valid_d0/rd_burst_data_valid_d1同理。
end_trp,end_trfc,end_tmrd,end_trcd,end_tcl,end_twr是完成相应命令之后等待时间结束的标志信号。
end_rdburst,end_twrite是指完成mem_test设置的突发读写长度。
sdram_cke置1,表示输入SDRAM的clk一直有效。
sdram_dqm={SDR_DQM_WIDTH{1’b0}},表示不屏蔽任何数据。
sdr_dq_oe是一个决定sdr_dq这个接口是输入数据还是输出数据的信号。
read_flag是一个决定地址总线上是rd_burst_addr还是wr_burst_addr。
将ras_n_r,cas_n_r,we_n_r寄存器中的值赋给sdram_ras_n,sdram_cas_n,sdram_we_n。
建模了cnt_200us和cnt_7p5us两个计数器,200us:用来做初始化中刚上电时的延时,主要是让输入到SDRAM中的时钟达到稳定状态,7.5us:64ms内要完成8192次刷新,以防止数据丢失(即每7.5us刷新一次)。
assign sdram_ref_ack=(state==S_AR);即当状态进入S_AR时sdram_ref_ack置1,然后停止自动刷新申请。
200us(NOP)→Pre Charge→TRP(预充电等待时间)→Auto Refresh→TRF1(自动刷新等待时间)→Auto Refresh→TRF2(自动刷新等待时间)→Mode Register Set→TMRD(模式寄存器等待时间)→Init Done(初始化结束)
上述为整个初始化过程
wr_burst_data_req由1到0的瞬间wr_burst_finish置1。
rd_burst_data_valid由1到0的瞬间rd_burst_finish置1。
这两个信号标志着mem_test模块发出wr_burst_len长度的数据写完,以及rd_burst_len长度的数据读完。
初始化完成后,进入S_IDLE,当sdram_ref_req有效时,进入S_AR(自动刷新状态);当wr_burst_req或者rd_burst_req有效时,系统进入S_ACTIVE(激活状态)。当rd_burst_req有效时read_flag置1,wr_burst_req有效时read_flag置0,用来S_ACTIVE后选择进入S_READ还是S_WRITE。
读:
S_ACTIVE→TRCD(激活等待时间)→S_READ→CL(读命令被获取到数据出现在数据总线上间隔的时间)→S_RD(完成read_burst_len长度数据的读,该突发长度是由上层设置的,并不是通过模式寄存器配置SDRAM的突发长度)→S_PRE(预充电,复位行地址)→S_TRP(预充电等待时间)→S_IDLE
写:
S_ACTIVE→TRCD(激活等待时间)→S_WRITE→S_WD(完成write_burst_len长度数据的写)→Twr(数据写入时间等待时间)→S_PRE→S_TRP→S_IDLE
自动刷新:
S_AR→S_TRFC(自动刷新等待时间)
wr_burst_data_req是向mem_test模块输入的数据请求信号。数据请求信号前于写命令一个时钟,有利于写命令发出时,数据出现在总线上。如在激活等待时间时,如果read_flag信号为0,发出数据请求信号;当进入S_WRITE状态时,如果wr_burst_len长度大于1(即由mem_test输出的写突发数据长度),继续发送数据请求信号,一个时钟后,进入S_WD,继续判断wr_burst_len,然后输出wr_burst_data_req。
rd_burst_data_valid是数据有效信号,当进入S_RD状态即进入了读取数据状态,超过tCL(即读命令有效到数据出现需要等待的时间)出现的数据有效。
cnt_clk_r是时钟计数器,cnt_rst_n是时钟计数器的复位信号。
cnt_clk_r起到时钟记录的作用,用以与定义的参数做比较,以判断是否延时达到预定的时长,而每次end,触发复位信号,清空时钟计数器,从而使该计数器可以重复使用。
当进入S_WRITE或者S_WD,将sdr_dq_oe使能信号置1,使sdr_dq输出要写入的数据,否则设置为高阻状态,有利于读数据的输入。(这种inout的IO口要充分利用这种描述)
对应的操作输出相应的命令,数据和地址。