本次想和大家继续讨论一些 DDR3 的东西,另外新增 DDR4 的仿真。主要包括,多组关于DDR3 的读写仿真测试,DDR4 逻辑仿真验证的另一种较为简单的方式。
本次读写测试中采用:FPGA硬件平台为Xilinx的评估版KCU116,硬件开发平台为XIlinx的Vivado 2018.3。
当然,为了图个新鲜感,先和大家聊聊关于 DDR4 的东西。关于 DDR4 的 IP 生成过程大家可以参考作者“十二点过九分”的文章,本次实验所生成的IP也是从那边来的。下面给出连接,方便大家查看。
十二点过九分:DDR4读写测试(一):MIG IP核配置zhuanlan.zhihu.com生成好之后,开始我们的仿真过程。本次所采用仿真方式相较于之前 DDR3 采用的方式简单一些。我们打开官方给我们的 example 工程。打开 RTL 视图我们可以看到整个工程的连线方式,通过 example_tb 文件进行读写控制。那么我们就对 example_tb 进行修改,换成我们自己的逻辑便就可以了。为了方便起见,控制逻辑就用我们之前的 ddr3_motive 来代替了并简单的改了一下。需要注意的是地址位宽等需要修改一下。
我们将工程文件替换好后,我们运行仿真,但是在 modelsim 中没有找到我们定义的模块(这也是我之前遇到的问题)。如果跑不起来,我们打开他的仿真文件 sim_tb_top 下的路径 。我们可能会发现,其实 example_top 中依旧是调用的 example_tb 模块。打开 example_top.sv 文件 ,将 文件中 example_tb 例化模块全部替换为 ddr3_motive。(注:也有可能是我自己没操作好,反正替换就完事了---流氓操作,大不了多替换几次--来自菜鸡的无奈,这里我猜测是,是由于我新建了有个工程后,变成了example_top.v文件的缘故)。然后我们运行仿真,就OK了。这个方式也适用于DDR3,省去了自己搭仿真平台的过程。
DDR4仿真结果:
可以看到,在2951ns左右,init_calib_complete信号拉起,表明初始化完成。在3046ns左右,发起了我们第一次写数据和写命令的操作,连续写了5个地址。
在3136ns左右,我们发起读操作,将连续的四个地址中的数据读出,在3139ns左右,可以看到数据成功读出,对于同一地址而言,将读出的数据和写入的数据比对,发现完全一致。
现在我们接着聊聊 DDR3 的读写时序问题,因为对于前两次文章中提到的问题,抱着不甘心的态度,多做了几组测试仿真(今年寒假确实比较长,(●ˇ∀ˇ●))
首先是对于连续的读写:我们可以看到,在官方手册170页左右,写数据控制的时候开头有这么一个词:non back-to-back 。英语比较差,没能理解这个词的意思,后来在看一些论坛社区文章中,讲人话的意思就是——单次读写需要满足时序要求,连续的读写不需要。为此对于连续的读写做了一下对比测试(对于连续读写,没有在手册上找到依据 ≧ ﹏ ≦ )
第一组:写数据延迟命令并满足手册时序要求,可以看到能够正常读取数据
第二组:写数据延迟命令并不满足手册时序要求,可以看到能够正常读取数据
第三组:写数据超前命令,也能正常读取数据
既然都测了这几组,连同单次读写也一起试一下算了,时间慢慢磨吧!
第四组:单次读写,数据提前命令
第五组:单次读写,数据延迟命令
对于第四组和第五组,现在存在疑问。因为是不满足手册 non back-to-back 时序要求的,但是仿真出来,结果也是对的。头大,现在又出现了新的问题。等开学了,上板子测下,看能不能行。对于这点,各位有相关经验的巨佬,帮帮忙,还请解答一下,(●ˇ∀ˇ●)!