代码参考的这位老哥的博客快速上手ddr3 ip核
这里使用的为native接口。
MIG的输入输出信号分为两组:
1.Memory interface ports:连接到DDR3,无需用户操作,只需要连接好就行。
2.Application interface ports :用户端的接口,供给用户直接操作。
部分接口的解释说明:
1.ddr3_dqs_n,ddr3_dqs_p:与输入输出对其的信号。
2.命令相关信号.
app_en,app_rdy。当这两个信号同时为高时,命令才能被使用,其中app_en是由用户输出入到控制器,app_rdy是由控制器输出给用户,因此我们在使用时需要控制app_en信号来完成读写。
app_addr
app_cmd
3.写相关信号
app_wdf_wren:写使能,由用户侧输入到控制器。
app_wdf_rdy:接收准备完成,由控制器输出到用户侧。
app_wdf_end:当前时钟为突发写的最后一个时钟,由用户侧输入到控制器。不过好像突发长度为8时,次信号与写使能信号一样?
app_wdf_data
4.读相关信号
app_rd_data :
app_rd_data_valid:读出数据有效信号,由控制器输出到用户侧。
在仿真时,我们着重观察以上信号的波形。
在整体波形中我们可以看到,由MIG输出给用户侧的控制信号app_wdf_rdf在仿真后不久一直处于高电平状态,app_rdy在初始化信号(init_calib_complete)拉高后隔段时间拉高,并不是一直拉高,且间隔时间有长有短,不知道这个和什么有关?
初始化完成且当前状态为写状态时,从地址0开始依次写入数据,每写一个数据,地址加8,突发长度为8.所以一次写入或者读出的数据位宽=DDR3数据位宽x突发长度。这里DDR3数据位宽为16,突发长度为8,因此数据位宽为128.
由状态机控制的计数器依次写入512个数据(0-511)后跳转到等待状态,注意512没有写入,
由状态机控制的等待状态时钟周期为1,即状态读状态,同时地址清零,读计数器在下一周期检测到读状态时依次加1,但此时app_rd_data_valid并没有置高,说明没有读出数据。
过了多个周期后(这个延时周期和什么有关呢?),app_rd_data_valid才被置高,此时开始读出0-511共512个数据。
读出最后一个数据511,但此时命令已为写命令