Cyclone V GX开发板的第一轮使用试用已经结束一段时间了,笔者发现在论坛里和群里的网友对C5内嵌的硬核内存控制器(Hard Memory Controller)表现出浓厚的兴趣。这篇补充的应用笔记加深了之前对HMC的讨论,并且给出详细的例化步骤,期望能够给新上手HMC的同行提供一些基础的参考。
一、关于HMC再多说几句
1. 不是所有的Cyclone V器件都内置HMC。编号F(Feature)系列有,而B(Base)系列没有。使用者可以根据需求灵活选择。在根本不需要外接内存的应用场合,可以选择B系列。两个系列管脚兼容。
2. 不是每个速度等级的Cyclone V的HMC都能跑到400MHz(以DDR3为例)。C8速度等级的官方标称频率是333MHz。
3. 每个HMC最多支持40bit的内存位宽。在HMC模式下,这40bit的划分为32bit数据加8bitCRC。在软核模式下,这40bit可以全部分给数据,但硬核模式下不行。设计者在计算带宽时需要加以考虑。
4. Cyclone V系列片内最多有两个HMC,如果需要更多的HMC,可以考虑Arria V。
5. HMC的PHY ref PLL不是随便一个CLK IN就可以,在原理图设计阶段要考虑好。
二、例化步骤
本文皆用DDR3作为实例。例化DDR3 HMC无非有两种方式,直接例化和在Qsys中例化。下面以直接例化为例,详细说明例化步骤。
1. 用Mega Wizard选择DDR3 SDRAM Controller with Uniphy
2. 在右侧的预制栏内选择内存,开发板的话选择MICRON MT41J128M16HA-15E.
3. 在弹出的界面中,首先设置PHY SETTING。选中Enable Hard External Memory Interface。Speed Grade选择7. MemoryClock freq选择400MHz。PLL ref clk的频率根据开发板的实际连接选择,这里是125MHz。Avalone MM接口选择Full Rate,HMC不支持Half Rate。Enable AFI half rate clock可以不勾选,生成的afi_half_clk没有钟输出。提前说一下,如果采用SMC,那么最常用的钟就是afi_clk了,在半速率模式下,这个钟的频率是内存频率的一半,比如内存工作在300MHz,afi_clk就是150MHz;如果是全速率的话,afi_clk是300MHz,这时候可以启用afi_half_clk。需要注意的是,在HMC模式下,afi_clk和afi_half_clk两个钟基本不用。因为afi_clk在这里是400MHz,FPGA内部逻辑达不到这个速度,即使一半200MHz也达不到。解决方法后文会说。
4. 切换到下一个TAB,Memory Parameter。Total interface width可以改成32.
5. Memory Timing和BoardSettings保持默认
6. Controller Setting中,如果是在Qsys中例化,选中Generatepower-of-2 data bus width。在Multiple Port Front End选栏中,更改Port0的设置,Width =64。
7. 生成IP核。顶层文件看似复杂,但是条理非常清楚。
hmc (
input wire pll_ref_clk, //接参考时钟
input wire global_reset_n, //低电平复位
input wire soft_reset_n, //低电平复位,但是不复位PLL
outputwire afi_clk, // 400MHz钟,与内存频率相同,不使用
outputwire afi_half_clk, //没有输出,不使用
outputwire afi_reset_n, //低电平复位
//接下来以mem开头的信号都是接内存芯片的信号,在FPGA上有固定的管脚,这里省略
mem_*// 省略介绍
//接下来以avl开头的信号是AvalonMM 总线,这里省略介绍
avl_*// 省略介绍
//接下来是MPFE的FIFO时钟和复位信号
input wire mp_cmd_clk_0_clk,//接Avalone MM时钟域的钟,可以和afi钟不同
input wire mp_cmd_reset_n_0_reset_n, //接Avalone MM时钟域的复位
input wire mp_rfifo_clk_0_clk, //接Avalone MM时钟域的钟,可以和afi钟不同
input wire mp_rfifo_reset_n_0_reset_n, //接Avalone MM时钟域的复位
input wire mp_wfifo_clk_0_clk, //接Avalone MM时钟域的钟,可以和afi钟不同
input wire mp_wfifo_reset_n_0_reset_n, //接Avalone MM时钟域的复位
//状态信号
outputwire local_init_done, //初始化成功
outputwire local_cal_success, //校准成功
outputwire local_cal_fail, //校准失败
//OCT信号
input wire oct_rzqin //接100欧姆电阻,供校准使用
);
三、MPFE的使用
通过上面的例化步骤,尤其是最后一步,已经可以看到MPFE的身影了。MPFE的原理和构成可以参考EMI Book,我理解它的作用有两个:
1. 跨时钟域
MPFE内部有F0~F3三组硬核FIFO,每组64bit位宽。这些FIFO提供了跨时钟域功能。在本次例子中,内存数据位宽32bit,工作在全速率模式下,本地接口位宽选择为64bit。由F0这个FIFO组来实现时钟域跨越。所以可以用100MHz的用户逻辑时钟驱动F0的一边,另一边自动由afi_clk驱动。因为是硬核FIFO,所以能达到比较高的速率。
2. 提供多个端口,并进行仲裁
在Number of ports中总共可以选择6个端口,每一个端口相当于单独的Avalon MM总线端口。比如把端口数量调整为2,那么生成的顶层文件中avl部分会变成avl*_0和avl_*_1,相当于多出来一个Avalon MM接口。不同端口的逻辑优先级可以在例化时设定。
四、调试功能
在例化过程中默认加入调试模块,可以配合System Console来读取初始化和校准信息,以及更多的信息。如果在下载后发现local_init_done为低,local_cal_fail为高,可以使用Quartus II TOOL菜单下的EMI Toolkit进行调试。具体的操作在EMI Book里。
五、总结
HMC的优点很多,高效率、低功耗和多端口等等。在初期,可能文档和例程都在不断丰富之中,所以使用者可能会遇到各种各样的困难。建议可以先调通SMC,验证PCB设计没有问题,然后再调试HMC,以求获得最高的内存带宽。