目录
前言
1 经验总结
1.1 总结1:
1.2 总结2:
1.3 总结3 :
1.4 总结4:DDR4 MIG时钟
1.5 总结5 :DDR4 SDRAM芯片与FPGA管脚绑定
2、vivado工程文件夹结构
2.1、新建vivado工程时的文件夹结构
2.2、新建USR_DESIGN文件夹
2.3、添加tb_top
2.4、添加仿真模型
3、DDR3仿真图
4、板卡测试
4.1、DDR4 MIG配置
4.2、MIG实例化
4.3、DDR4读写测试
本文仅对DDR4 SDRAM IP的 example design 工程进行了仿真。后续仿真,参考下面的流程,可以搭建自己的仿真平台。
这里说明一下,FPGA比较大的IP Xilinx或者Quartus软件应该都会有该IP使用的示例工程,也就是example design,不会打开example design的童鞋们可以百度看看。
本文是基于example design 工程,所以想要工程的童鞋打开ISE或vivado软件,generate MIG IP,然后打开example design即可。
关于DDR IP MIG配置界面里 Memory Address Map顺序做一些简要说明,一般情况下建议Memory Address Map顺顺序按照默认的设置,APP_ADDR[29:0]按从0到最大深度寻址即可,即将DDR SDRAM作为一个寻址位宽为ADDR[29:0]缓存使用即可。
首先,FPGA DDR3 MIG IP默认的Memory Address Map顺序是BANK--ROW--COL,该顺序对应的是APP_ADDR[29:0]。
其次,FPGA DDR4 MIG IP默认的Memory Address Map顺序是ROW--COL--BANK,该顺序对应的是APP_ADDR[29:0]。
如果将Memory Address Map顺序调整的话,比如将DDR4 MIG Memory Address Map顺序调整为BANK--ROW--COL,这样会导致APP_RD_DATA/APP_RD_DVLD回读的速率下降到100MHZ(每10ns一个有效512位宽的数据)。若DDR4 MIG Memory Address Map按照默认顺序BANK--ROW--COL,访问地址递增的情况下,平均APP_RD_DATA/APP_RD_DVLD回读的速率接近用户时钟300MHZ.
仿真平台一般由下面几个模块构成:仿真平台TB_TOP、被测模块FPGA_TOP、仿真模型sim_model。
在例化DDR IP core时,DDR 端建议按下图圈起部分样式书写代码,这样处理的目的是方便代码适配不同类型的DDR芯片,使该端口代码模板具有更广的通用性。
按照上述端口代码,在进行管脚绑定时,XDC文件可以如下图所示。需要注意,在上图中 C0_DDR4_bg 等信号端口输出形式,
方式一:
output [ 0:0] C0_DDR4_bg ,//( o) [ 8]
//与下面形式作对比
方式二:
output C0_DDR4_bg ,//( o) [ 8]
这两种不同的形式,定义的 C0_DDR4_bg 信号类型是不一样的,从而在写XDC文件管脚绑定的方式也是不一样的,区别如下图所示。
板卡测试时,遇到几个问题:
(1)FPGA逻辑下载到板卡后,vivado软件提示 MIG status:CAL FAIL.
导致这个问题的原因:可能是ILA观察数据位宽太宽了/深度太大,解决方式是将观察数据波形不设置为trriger,减小波形深度,从而减小布线和资源;或者是由c0_ddr4_app_wdf_rdy恒为0问题引起的MIG初始化失败。
(2)MIG初始化成功后,c0_ddr4_app_wdf_rdy恒为0.
上面俩个问题,可能是下面代码137行引起的。因此在做逻辑时,需要等 c0_init_calib_complete & c0_ddr4_app_rdy & c0_ddr4_app_wdf_rdy 同时有效后,再启动DDR4读写访问测试。
DDR4读写测试逻辑,可以参考这篇文章DDR4读写测试(二):基本读写测试 - 知乎,他的这篇文章中的代码我经过仿真验证是没有问题,但下板测试时出现DDR返回的RD_DATA与RD_DATA_DVLD存在差拍关系,具体原因不清楚。在文后附上我写的测试代码。
DDR3 MIG IP的系统时钟(sys_clk)可以是单端/差分,但该时钟必须从FPGA管脚输入,之后直接接入DDR3 MIG IP,而不是使用PLL产生的时钟来作为sys_clk给MIG IP核。
DDR4 MIG IP的系统时钟(sys_clk)可以是单端/差分,但该时钟必须从FPGA GCIO 差分 管脚输入。
关于时钟,详细看看下图圈起来的部分!
在generate 一个DDR4 IP core后,打开example design 工程,里面会有Xilinx提供的一个DDR4与FPGA之间的管脚绑定参考 example_design.xdc ,可以直接使用。
VIVADO软件 XDC管脚绑定参考示例。
在ug575-ultrascale-pkg-pinout 文档里可以查看FPGA 的有哪些HP BANK,以及哪些HP BANK在相同列。需要注意,相同列的HP BANK 中的 DDR4 MIG才可以公用一个差分系统时钟SYS_CLK转成单端后提供给多个MIG。
举例,若HP BANK 66-68,每个BANK中使用一个DDR4 MIG 来控制外部DDR4 SDRAM,则这三个MIG可以共用一个差分转单端的时钟作为SYS_CLK。
问题:由于APP_RDY可能会突然拉低,导致cmd_en有效,但下一拍APP_RDY已经拉低,会导致当前地址的读写访问没有被MIG接收。
解决方式:参考example代码,cmd_en比APP_RDY晚一拍,在cmd_en & app_rdy同时有效时,再改变访问地址;同时,
现象:向DDR SDRAM地址空间0-f写入数据0-f,从0地址回读8个数据为0-7,但从1地址回读8个数据也是0-7.也即 列地址bit0-bit2 起不到寻址作用。
原理如下:DDR3/DDR4 关于Burst = 8 是类似原理。
首先是列地址bit0-bit2,是不用于DDR 寻址。
Column Address的A2,A1,A0三位被用于Burst Order功能,并且A3也被用于Burst Type功能。由于一般情况,我们采用的都是顺序读写模式(即{A2,A1,A0}={0,0,0}),所以此时的A3的取值并无直接影响。
可能原因:若工程路径比较深,下载文件在默认路径下也比较深,会显示下图所示的问题现象。
解决方式1:尝试将bit文件夹路径减少试试。
解决方式2: 有可能是给MIG的时钟存在问题,该时钟可能不存在。可以尝试使用MIG的PLL输出一个USR时钟,使用该时钟简单产生一个flag信号,使用ILA观察该FLAG信号的有无,从而确定MIG的时钟是否存在。
使用vivado软件,新建一个vivado工程时该软件会自动生成几个文件夹,在使用IP Catalog新建一个IP并添加入工程后,文件夹结构如下。
在工程文件夹根目录下,新建usr_design文件夹,用于存放该自己设计的该工程的.v文件,便于后期查找文件及修改。
将该文件夹里的文件添加入vivado工程中,此时vivado软件会自动将该usr_design文件夹复制到project_1.srcs-sources_1-imports文件路径下。
需要注意:在修改usr_design文件夹里的.v文件时,vivado工程里的对应.v文件代码并没有被修改。因为vivado软件直接显示的代码文件是存储在projet_1.srcs--sources_1--imports--usr_design文件夹里。
tb_top.v文件存放在工程根目录下的usr_design文件夹里,将该文件添加到vivado工程里。之后,vivado软件会自动将该tb_top文件复制到project_1.srcs-sim_1-imports-usr_design文件夹里。
首先,点击被仿真的IP,open in example design,将example design工程文件夹里的imports文件夹 复制到sim_1-imports文件夹路径下。
example design工程文件夹里的imports文件夹里包含仿真模型所需的全部文件。
添加仿真模型的时候,选择添加文件夹,然后刷新工程。vivado软件会自动扫描该文件夹里的全部文件,识别出仿真模型。
使用软件版本ISE14.7 FPGA型号K7325T 对DDR3 MIG IP的example工程在modelsim里进行仿真。
(1)打开modelsim,将modelsim工作路径切换到MIG IP SIM文件夹所在路径\ipcore_dir\ddrmig\example_design\sim
(2)Transcript界面输入do sim.do
(3)中断仿真,添加观察模块信号(sim_tb_top---u_ip_top---u_ddrmig);
(4)Restart ,RUN 100ms,等待20分钟左右,可以看到仿真波形。
下图是使用vivado软件多K7325T DDR3 MIG IP example design工程进行仿真,可以看到MIG回读的数据并非是连续的。
上面modelsim以及vivado对DDR SDRAM仿真,MIG配置的是BANK ROW COL的顺序,该访问顺序导致上面的仿真波形回读数据不是连续的。
在FPGA MIG相同的配置下,仅修改为ROW COL BANK的默认顺序,回读数据波形就是连续的。
进一步分析:
可以对比进行DDR4 MIG IP example design进行仿真。
组1:MIG初始化完成之后,给MIG发连续的读请求,连续的访问地址app_addr[29:0]=0、8、16.....,MIG配置为BANK ROW COL的顺序
组2:MIG初始化完成之后,给MIG发连续的读请求,连续的访问地址app_addr[29:0]=0、8、16.....,MIG配置为ROW COL BANK 的默认顺序
组3:MIG初始化完成之后,给MIG发连续的读请求,连续的访问地址app_addr[29:0]恒为0、0、0.....,MIG配置为BANK ROW COL的顺序
组4:MIG初始化完成之后,给MIG发连续的读请求,连续的访问地址app_addr[29:0]恒为0、0、0.....,MIG配置为ROW COL BANK 的默认顺序
对比两组回读数据,可以发现组2回读的数据是连续的,组1、组3、组4回读数据也是不连续的。
说明:建议遵守Xilinx 推荐的MIG默认设置BANK ROW COL的顺序,app_addr[29:0]的寻址按从0到最大深度值即可。至于哪一种(BANK/ROW/COL)排列方式、DDR SDRAM传输数据效率最高,这里没有结论。
核心思想:
(1)用状态机实现对DDR4 SDRAM的循环读写访问,便于使用ila观察波形。
在IDLE状态下,检测 c0_init_calib_complete & app_rdy & app_wdf_rdy 信号是否为1,若满足条件进入WR_DDR状态。
若不满足 c0_init_calib_complete & app_rdy & app_wdf_rdy条件就读写访问DDR4 SDRAM,会引起几个问题。现象是:程序下载入FPGA后,vivado提示MIG status:CAL FAIL.或者app_wdf_rdy出现恒0情况,或者app_rd_data与app_rd_data_valid出现差1拍的关系。
(2)在WR_DDR状态下,检测 app_rdy & app_wdf_rdy 是否为1.若满足条件,执行DDR4 SDRAM写访问功能,可以指定写访问数据个数。给SDRAM发app_en/app_cmd/app_addr/app_wdf_wren/app_wdf_data。
(3)在RD_DDR状态下,检测 app_rdy 是否为1.若满足条件,执行DDR4 SDRAM读访问功能。
(4)在其他状态下,app_en/app_wdf_wren,以及相关计数器为0.
测试代码示例:
参考博文
DDR4读写测试(一):MIG IP核配置 - 知乎
DDR3的亲戚DDR4--依旧是跑仿真 - 知乎
译文: DDR4 SDRAM - Understanding the Basics(下) - 知乎
https://blog.csdn.net/XiaoQingCaiGeGe/article/details/105768447
ddr3调试经验分享(五)——KC705_MIG时钟清单
DDR扫盲——关于Prefetch与Burst的深入讨论