基于Vivado MIG IP核的DDR3控制器(DDR3_CONTROL)
一、前言
由于DDR3的控制时序相当复杂,为了方便用户开发DDR3的读写应用程序,Xilinx官方就提供了一个MIG(Memory Interface Generator) IP核,它可以为用户生成一个DDR3控制器。该控制器结构如下:
它提供了用户接口(左侧),内部会将用户接口接收到的时序转换成DDR3所需的真正时序,并通过物理端(右侧)的接口连接到DDR3。由于用户接口的时序比较简单,因此该控制器就隐藏了极其复杂的DDR3的控制时序,让用户只需要按照用户端的时序来操作就可以对DDR3进行相应的读写。
二、MIG IP核配置
1、第一步:查找IP核
2、第二步:
- ① 创建一个设计
- ② IP核命名
- ③ MIG 中控制器的个数,取决于你想控制几个存储器,它生成多组接口用于控制不同的存储器。我们只需要控制一个DDR3,所以这里选择选择 1 即可。
- ④ 是否启用AXI4接口,默认是使用的app接口。
3、第三步:选择以下器件型号,就代表生成的IP不止支持之前已经选择的器件型号,还兼容下面选择的器件型号。
4、第四步:选择内存类型为DDR3
5、第五步:DDR3控制器选项设置
- ① 时钟频率,即ddr3的工作频率,由MIG提供给ddr3,也即第一张图中的ddr_ck的频率。
- ② MIG会在用户端提供一个ui_clk(第一张图左端的clk信号,用户发送和接收数据等操作都是在该时钟域下进行的)供用户使用,这里的4:1指的就是①中设置的时钟频率:ui_clk的频率,所以此时ui_clk的频率是200MHZ。
- ③ 选择DDR3存储器的型号。
- ④ DDR3的工作电压。
- ⑤ DDR3的数据位宽。
- ⑥ 选择是否使用数据掩码。
- ⑦ 选择Normal时,允许内存控制器将命令重新排序到内存,以获得尽可能高的效率。选择Strict则强制控制器按照收到的确切顺序执行命令。
6、第六步:DDR3选项设置
- ① 选择输入给MIG的时钟频率,该时钟是MIG的源时钟,也是有了它才能生成上面说的DDR3的工作时钟ddr_ck和用户时钟ui_clk。我给MIG输入的时钟是开发板上的板载差分时钟,频率是200MHZ,所以这里选择5000ps。
- ② 读突发类型选择为连续模式。
- ③ 内存地址映射类型,正常使用选择第二个即可。
7、第七步:
- ① 选择提供给MIG的输入时钟的类型,这里选择是差分类型,因为前面提到我输入给MIG的时钟是板载的差分时钟信号。
- ② 参考时钟选择使用系统时钟,也即200MHZ的差分时钟。在MIG中使用了idealy,odelay,idelayctrl原句,idelayctrl原句需要提供一个ref_clk作为基准。
- ③ 系统复位极性选择低电平有效。
8、第八步:选择终端电阻的阻抗为50欧姆,这是由核心板的硬件设计决定的
9、第九步:引脚分配
对DDR控制器进行管脚分配,在这里我们选择 Fixed Pine Out,通过读取XDC文件中的引脚分配信息给DDR3分配引脚。
在这一界面中,选择 Read XDC/UCF为控制器分配引脚,在弹出界面选择我们为用户提供的引脚分配的XDC文件。读取完XDC文件后,点击Validate就可以验证管脚分配是否合理。
接下来后面一路点击OK或者Next就可以生成所需的IP核了。
三、引脚说明
生成的IP核DDR3_CONTROL
会有两组接口:
- 一组是
Memory interface ports
,它连接到DDR3,无需用户来操作,只需要连接好就行; - 另一组是
Application interface ports
,它是用户端的接口,供用户直接操作的。
前面说过,MIG会将从Application interface ports
接收到的信号在内部进行时序转换,变成直接控制DDR的时序,由Memory interface ports
输出给DDR3,这个逻辑一定要清楚。
下面打开IP核DDR3_CONTROL
的例化模板,介绍下各个端口的作用:
想必大家都看到了有以下两个端口,这就对应了我们在第七步①中设置的MIG IP核的输入时钟为差分信号。
.sys_clk_p (sys_clk_p),//系统的差分时钟
.sys_clk_n (sys_clk_n),
各个端口具体是啥意思,已经在注释中写清楚了,至于更加详细的时序,之后有机会再说吧!!!
四、总结
注意上面有四处黄色高亮的内容,分别是涉及到的四种不同的时钟信号,一定要区分开这几个时钟。
1、关于DDR3的介绍可以参考下面的文章:
2、关于使用MIG IP核对DDR3进行读写的案例,以及用户端读写时序的分析,可以参考以下几篇文章: