系列文章目录
第一章--DDR3控制器测试--基于Quartus Prime 18.1的EMIF IP核
第二章--DDR3控制器测试--基于Vivado2021.1的MIG核
前言
在之前的工作中,需要在CycloneV FPGA板卡上设计一个基于DDR3存储器的高速视频数据缓存系统,一开始想到的就是调用Quartus Pimre 18.1标准版开发套件提供的DDR3控制器IP核,但是当时并不清楚这个IP核的原理以及接口时序,因此当时设计这个控制器的过程还是蛮坎坷的。
后来,又用到了ZYNQ7035开发板和ArriaV开发板,就想着基于这三个开发板设计并测试一下DDR3控制器,同时记录一下设计的过程,也方便其他朋友参考。实际上,基于ArriaV的DDR3控制器和基于CycloneV的DDR3控制器并没有多大的差别,只不过ArriaV使用的是Quarter Rate模式,而CycloneV使用的是Half Rate模式,区别也只是接口位宽有所不同。所以我们只介绍基于CycloneV的DDR3控制器的设计于仿真调试过程。另外,由于本人的水平和精力有限,文笔方面难免存在错误和疏漏,欢迎各位技术大佬批评指正。
一、硬件平台介绍
关于DDR3存储器的基本工作原理,网上已经有许多博文讲的非常不错,本文不再赘述。如果不清楚DDR3存储器的基本工作原理,可以自行去网上查找相关文章,也可以参考《DDR3标准协议》手册--https://download.csdn.net/download/weixin_45645504/87698679。
此处用于验证DDR3控制器所使用的FPGA板卡硬件详情如下:
1、FPGA芯片型号是CycloneV系列的5CSEBA6U23I7;
2、DDR3 SDRAM型号为IS43TR16256B,生产厂家为ISSI,芯片数据手册--DDR3 SDRAM - Integrated Silicon Solution Inc. (issi.com)。其工作频率最大为666.667MHz,共两片容量为1Gbit大小的DDR3扩展成2Gbit的RANK,两片DDR3存储芯片连接方式如下图1.1所示。
图1.1 两片DDR3芯片扩展示意图
二、EMIF IP核介绍
Altera的外部存储器接口(External Memory Interface,EMIF)解决方案,提供了一系列高速、高效、低延迟的内存接口IP核,能够方便快速地实现FPGA与外部高速存储器之间的访问。EMIF IP核用户手册--External Memory Interface Handbook (intel.com)。FPGA开发者可以利用Quartus Prime软件提供的External Memory Interface IP核快速构建DDR3控制器,以实现FPGA与外部DDR3存储器的数据访存。 Altera的FPGA器件通过External Memory Interface IP核实现了最佳的外部存储器接口性能,该IP核提供了以下组件: 物理层接口(PHY),构建数据路径,并管理FPGA与外部存储器之间的传输时序; 存储器控制器,它实现了所有的存储器命令和协议级的要求; 多端口前端(MPFE)的功能,即允许FPGA内的多个组件共享一个公共内存接口对外部存储器进行访问。如图2.1所示为EMIF IP核原理框图。
图2.1 Altera EMIF IP核原理框图
而且,Altera提供了两种类型的External Memory Interface解决方案,包括:软存储器IP核与硬存储器IP核,究竟是使用软存储器IP核还是硬存储器IP核主要取决于硬件设备。其中,软存储器IP核具有较高的灵活性,可以灵活选择存储器接口的布局布线位置、资源大小和配置,能够满足用户不同的设计需求;而硬IP核则使用更简单、时序性能更加。
图2.2 软存储器IP核与硬存储器IP核的特点
此外,Altera的External Memory Interface解决方案提供的DDR3控制器IP核支持三种不同用户接口数据速率,分别是Full Rate、Half Rate、Quarter Rate。
图2.3 三种不同用户接口数据速率对照表
一般来说,Full Rate情况下需要更小的数据和地址/命令总线宽度比率,然而,由于控制器的核心逻辑运行在一个较高的频率下,此时可能对时序收敛造成困难。因此,Altera建议使用Half Rate或者Quarter Rate的UniPHY IP和控制器实现高速内存接口设计,从而避免时序无法收敛。
三、IP核配置
1、PHY Settings配置 -- 配置IP的PHY参数
图3.1 PHY参数配置
Speed Grade:速度等级,这里指的是FPGA芯片的速度等级,我使用的FPGA芯片型号是5CSEBA6U23I7,所以其速度等级为7;
Memory clock frequency:存储器时钟频率,这个根据DDR3存储器芯片的最大工作频率以工程所需要的速度设置即可;
Rate on Avalon-MM Interface:用户接口数据速率,此处默认只能是Half Rate,这个跟我们使用的FPGA芯片型号有关。
2、Memory Parameter配置 -- 配置DDR3存储器参数
图3.2 Memory Parameter配置
这一个界面主要配置DDR3存储器的硬件参数,例如:芯片厂家、工作频率、数据总线位宽、地址总线位宽、以及模式寄存器配置。这块主要参考我们所使用的DDR3存储器芯片数据手册所给的参数配置就行,但是在芯片厂家下拉选项卡里,没有ISSI选项,因此选择JEDEC就行,因为它是符合JEDEC规定的DDR3 SDRAM标准的。
3、Memory Timing配置 -- 配置DDR3存储器时序参数
图3.3 Memory Timing配置
这些参数需要根据具体使用的DDR3芯片手册中的时序参数配置。
4、Board Settings -- 板级设置
板级设置选项卡主要是用于对板级时序分析时进行微调,以确保信号的完整性,此处由于运行频率相对较低,因此暂时保持默认即可,后续调试阶段如果有问题再做调整。
5、Controller Settings配置 -- 控制器设置
图3.4 Controller Settings配置
Maximum Avalon-MM burst length:Avalon接口的最大突发长度,DDR3存储器的列地址位宽为10,所以最大突发长度为1024(2^10),此处配置为1--1024中的任意一个整数都可以;
Avalon interface address width:默认生成的,这个跟我们配置的PHY Settings中的Rate on Avalon-MM Interface以及Memory Parameter中的Number of chip selects、Row address width和Column address width以及Bank-address width有关具体映射关系如下图3.5所示;
图3.5 用户接口到存储器的地址映射关系
Avalon interface data width:默认生成的,这个跟我们配置的PHY Settings中的Rate on Avalon-MM Interface以及Memory Parameter中数据位宽有关。由于用户接口的时钟频率是存储器IO时钟频率的一半,且存储器时钟为差分时钟--即双边沿传输,因此用户接口的数据传输频率是存储器IO实际传输频率的1/4,而存储器的数据位宽为32bit,故这里生成的用户接口数据位宽为32*4=128,这样才能保证用户接口与存储器IO具有等价的数据传输速率。
Local to Memory Address Mapping:用户接口到存储器的地址映射,这里有三种映射方式,如图3.6所示,主要根据控制器对DDR3的寻址方式的不同进行设置,以保证具有最佳效率。
图3.6 Local to Memory Address Mapping方式
6、Diagnostics配置--诊断功能设置
图3.7 Diagnostics配置
Auto-calibration mode:自动校准模式,此处为了降低Modelsim仿真时长,设置为跳过校准(Skip Calibration),同时勾选Skip Memory Initialization Delays。
配置完IP核后,点击Finish,再点击Generate HDL,等待软件生成DDR3 IP核工程即可。
下表简要对生成的IP核的接口进行了说明,需要注意的是:1)、pll_ref_clk需要是由PLL产生的时钟作为参考时钟输入,而不能是由外部晶振直接提供,否则会在布局布线阶段报错;2)、afi_clk时钟则是由IP核输出给用户逻辑的时钟,也就是说avl interface接口的突发传输需要同步于afi_clk时钟。
表7.1 IP核接口说明
信号名 | 接口类型 | 描述 |
pll_ref_clk | clock | PLL参考时钟输入 |
global_reset_n | reset | 复位PLL和PHY |
soft_reset_n | reset | 复位PHY |
afi_clk | clock | AFI时钟输出,供用户逻辑使用 |
mem interface | conduit | PHY和存储器芯片之间的接口 |
avl interface | avalon-mm-slave | 存储器接口与用户逻辑之间的接口 |
status interface | conduit | 存储器接口状态信号 |
四、IP核仿真 -- Example Design仿真
完成了IP核的配置后,我们会发现这个IP核的用户接口采用的是Avalon-MM Slave接口,因此接下来的工作就是完成设计与之配对的Avalon-MM Master接口。但是,仔细分析之后,我们会发现目前还无法进行下一步工作--这是因为我们还不清楚该Avalon-MM Slave接口的细节信息,比如接口时序、地址是如何映射的。当然,IP核用户手册也给出了Half Rate下的读写传输时序,所以如果大家已经具备Avalon-MM 接口的知识,应该对下面的时序图会很熟悉。
图4.1 Half Rate 读操作时序图
图4.2 Half Rate写操作时序图
通过上面的两个图,我们可以发现,Avalon--MM Slave接口的时序采用的突发传输模式(有avl_size说明是突发传输)。并且图中还给出了Avalon--MM Slave接口(用户接口)、AFI接口以及Memory接口之间的时序关系,但是无法分析出用户接口与存储器接口之间的地址映射关系,IP核用户手册并没有很详细的画出来。别急,我们还有一个好助手来帮助我们--仿真。
在EMIF用户手册卷二的第8章讲到,想要仿真我们的设计需要4个必须的组件:
1、仿真器--EMIF IP所支持的VHDL或Verilog仿真器,例如Modelsim;
2、一个使用EMIF IP核的设计;
3、一个用于发起写操作与读操作的驱动;
4、一个Testbench和一个合适的DDR3存储器仿真模型。
需要注意的是,DDR3存储器仿真模型可以是由DDR3芯片厂家提供的模型,也可以是由Quartus Prime在生成EMIF IP核的时候一起生成的一个遵循DDR3标准的可参数化模型。
仿真的第一种方式是利用Quartus Prime在生成EMIF IP核的时候一起生成的一个Example Design仿真。Quartus Prime在生成DDR3 IP核的同时会生成相应的Example Design工程,方便开发者对设计进行仿真调试。首先对Example Design进行仿真,以验证环境是否设置正确;其次,在仿真环境正确的情况下,对用户逻辑进行仿真,以验证用户逻辑(Avalon-mm-Master)控制是否正确。
按照如下步骤操作,即可快速启动对Example Design的仿真。
1、在IP目录中,默认包含一个Example Design,路径为xx/xx_example_design/simulation,进入此目录后,双击generate_sim_example_design.qpf文件打开Quartus;
2、打开Quartus后,在Tools/Tcl Scripts中运行generate_sim_verilog_example_design.tcl文件,会在simulation/verilog路径下生成仿真所需文件;
3、接下来打开Modelsim,改变工作路径到xx/xx_example_design/simulation/verilog/mentor下,执行命令“do run.do”即可打开Modelsim执行仿真。
4、在Modelsim的sim窗口中,将e0模块下的d0与if0模块加入到wave窗口,以便观测avl interface与mem interface的传输时序。
图4.3 Example Design仿真
从图中可以发现大约仿真运行到204us的时候,完成了初始化和校准过程,然后开始进行读写测试。而且,不难看出的是Avalon-MM Master接口的时序是标准的Avalon-MM总线的突发传输时序:
1、开始一次突发读操作或写操作时,avl_burstbegin会首先拉高一个周期,并且此时不管avl_ready的状态;
2、在Master发起一次写操作时avl_write_req一直拉高,并且在avl_ready拉高的时候avl_write_req才是有效写请求,直到产生了avl_size个周期的有效avl_write_req时,才拉低avl_write_req结束一次写操作;写数据则需要在avl_ready为高的时候更新,否则需要保持不变;
3、在Master发起一次读操作时,avl_read_req只拉高一个有效的avl_ready周期,注意:avl_read_req拉高的时候,一旦avl_ready为高就需要在下一个周期立即拉低avl_read_req,否则会重复读取两次数据;
4、地址则只需要在每次读写的时候给首地址,并且保持到发起下一次操作时才更新就行,需要注意的是,地址每次读写操作的地址计算方式是这样的:addr = addr' + avl_size * 16,addr表示发起第N次突发读/写时的地址,addr'表示发起第N-1次突发读/写时的地址;之所以是这样计算每次突发的起始地址,是因为DDR3内存阵列是以字节(8bit)为单位寻址,而EMIF IP核的Avalon-MM接口的数据位宽是128bit,这两者之间是16倍的关系。
五、工程设计与仿真
基于上述分析,本工程设计的框架结构如下图5.1所示。
图5.1 工程顶层结构图
图5.2 DDR3控制器顶层结构图
完成代码设计后,接下来我们需要对我们的设计进行整体仿真以验证所设计的DDR3控制器功能是否正确。具体操作步骤如下:
1、将IP核提供的示例工程下的ddr3_interface_example_design/simulation/verilog路径下的mentor、submodules文件夹以及ddr3_interface_example_sim.v文件复制到tb目录下;
图5.3 复制Example Design中的文件到自己的工程目录
2、对ddr3_interface_example_sim.v文件进行修改,将原有的example_design的用户逻辑ddr3_interface_example_sim_e0模块例化注释掉,替换为我们自己的模块;
图5.4 修改testbench文件
3、修改mentor文件夹下的msim_setup.tcl文件;
图5.5 修改msim_setup.tcl文件
提示:在第二步中,即使不知道添加哪些文件编译也没有关系,因为缺少这些文件的话Modelsim在编译的时候会报错,根据给出的报错信息找到这些文件并添加到msim_setup.tcl文件中一起编译也可以。
4、修改mentor文件夹下的run.do文件 ,将我们的设计中的几个模块添加到wave窗口,方便观测。
图5.6 修改run.do文件
5、最后,打开Modelsim仿真软件,并进入到工程的tb/mentor目录下,执行do run.do命令即可开始仿真;
图5.7 启动仿真
结论:仿真结果如下图所示,从仿真结果不难看出我们利用EMIF IP核对DDR3从机模型的数据读写功能是正确无误的。而且,最终我们设计的DDR3控制器在视频缓存系统中的表现也是非常稳定的。
图5.8 DDR3控制器读写仿真波形图
六、总结
以上就是今天要讲的内容,本文主要从工程实现的角度简要介绍了EMIF IP核的一些关键信息,以及如何使用Quartus Prime生成的Example Design进行功能仿真,以验证我们自己设计的用户逻辑是否正确,从而加速我们的设计。可以发现,Quartus的DDR3 IP核仿真还是比较麻烦的,尤其是和Vivado相比较而言。后续我会继续介绍在Vivado2021.1中如何对自己设计的基于7Series-MIG核的DDR3控制器进行仿真调试。