本文转载自:FPGA的现今未
Xilinx的DDR控制器——mig core在FPGA的设计中还是一个比较大的话题,刚好最近也在使用这个IP,做一个记录。
首先是生成这个IP,对于7系列的FPGA来说,该IP的参考文档就是Zynq-7000 SoC and 7 Series Devices Memory Interface Solutions v4.2, User Guide (UG586)。
IP生成
在IP catalog中输入“mig”即可找到该IP,双击开始生成。
1、如下图所示:这一页没有啥,直接next。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337301-1.png)
2、这一页也没有什么特别的,在Component Name的地方给你的mig core起一个名字。另外最后一个是问你mig的用户侧接口是否为AXI4接口,对于外接处理器的场景来说,肯定是AXI4接口比较方便,但是如果直接对接user logic,可以不勾选。mig提供了3种接口:AXI4 slave接口、 UI接口和the native接口,如果你不选择AXI4接口,那默认就是UI接口。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337302-2.png)
为什么没有native接口,看下面的图,Memory Control和user之间有一个User interface Block,实现了UI接口和native接口之间的转换,除非你想修改这个控制器,否则就是用UI接口。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337303-3.png)
3、主要是看是否有pin脚兼容的考虑,这里暂时不考虑,直接next。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337304-4.png)
4、选择外存的类型,我们这里用的是DDR3
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337305-5.png)
5、在这一页中,有几个需要注意的地方:
(1)Clock Period:这个就是mig PHY的接口时钟,也就是DDR接口的时钟,如果这里选择了533.33M,我们知道DDR是上下沿采样,那么物理带宽就是533.33*2*颗粒位宽。这个时钟究竟选择多少,一是根据性能的要求评估,二来需要看DDR颗粒的接口速率和FPGA的接口所能支持的速率。
(2)PHY to Controller Clock Ratio:这里有2个选择,2:1和4:1,主要是用户侧的工作时钟和上面PHY的接口时钟之间的比率。这里优先选择4:1,用户侧时钟频率低一些,对整个工程的时序是有利的。当然这里并没有牺牲物理带宽,用户侧用增加位宽来换取了时钟频率的降低。
(3)Data Width,即ddr DQ的位宽,假如使用了4个16bit位宽的颗粒,那这里就填4*16=64bit。
其他选择保留设置就好。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337306-6.png)
6、这一步主要是设置系统时钟,如下图所示,第一个input clock period就是设置系统时钟的频率,这里建议设置为200M即可。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337307-7.jpg)
在最下面有一个memory address mapping selection,这里建议选择ROW-BANK_COLUMN。这个涉及到DDR的读写性能。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337308-8.png)
7、这一页主要是system clock和reference clock的选择。首先系统时钟有3种输入方式,Single-Ended、Differential、No Buffer,单端和差分时钟比较好理解,都是通过外部的管脚输入的,输入的时候如何连接IBUF或者BUFG,可以参考example design的设计即可,NO Buffer模式是由内部的时钟源提供时钟。
参考时钟有4种输入方式:Single-Ended、Differential、No Buffer、Use System Clock,主要当系统时钟在199M到201M的时候,才会出现这个选项,我们前面选择的系统时钟是200M,所以这里选择Use System Clock,这样做的好处是少了一些时钟管脚的输入,简化下设计。
最后就是选择复位的极性,确定是高电平复位还是低电平复位。其他的保持默认设置即可。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337309-9.jpg)
8、这一页不做修改,保持默认设置。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337310-10.jpg)
9、这一页是管脚分配相关,第一个选项是还没有进行管脚分配,第二个选项是已经有管脚分配或者要进行管脚分配并进行验证。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337311-11.jpg)
进入第一个选项以后可以看到如下内容,这里有一个非常好的东西,那就是对管脚分配的一个总体指导或者建议,对于64bit的DQ,数据通路主要分配在bank34和bank32,中间的bank33主要是分配控制信号。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337312-12.jpg)
如果要验证已经完成的管脚分配,有2种方式,第一种就是手动输入,还有就是通过右下角第二个read XDC的方式输入,输入完成后必须通过Validate后才可以进行下一步。如果Validate不通过,需要修改你的管脚分配,直到通过为止。采用这种方式,对于DDR管脚的约束文件已经写入到mig core中,因此整个工程的约束文件中,不需要再对DDR做约束。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337313-13.png)
10、这一页是关于系统信号的管脚分配,主要是系统时钟和参考时钟,由于我们选择的系统时钟是内部时钟,参考时钟又是同系统时钟,所以这里不需要对系统时钟和参考时钟再做分配。剩下的这3个信号可以选择默认设置。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337314-14.jpg)
11、最后一个summary就是对前面设置的总结,供检查前面的设置。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337315-15.png)
关于时钟
在前面生成IP的时候,我们有输入过2个时钟,分别为system clock和ref clock,我们通过下图的时钟架构也可以看出这2个时钟分别是干嘛的。参考时钟为200M,主要用于IDELAYCTRL。系统时钟用于产生mig内部工作所需要的所有时钟。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337316-16.png)
关于这2个时钟,有各种不同的方案,这里介绍2种的方案,这2个方案都有一个共同的原则,就是参考时钟同系统时钟,且系统时钟采用200M。系统时钟的输入分为外部输入和内部输入,如下表所示:方案2相比方案1,不需要外部时钟源。
![](https://cdn.eetrend.com/files/2024-03/%E5%8D%9A%E5%AE%A2/100578993-337317-17.png)