第6讲 PLL和ROM的IP核使用
学习目的:
(1) 熟悉Altera FPGA的PLL的四种工作模式,同时掌握锁相环的工作原理;
(2) 掌握PLL IP核的配置过程及使用方法;
(3) 掌握ROM IP核的配置过程及初始化方法,学会用MATLAB产生mif文件来初始化ROM。
学习过程:
【PLL的四种模式】
① PLL的源同步模式
特点:在PLL的作用下,从输入管脚到寄存器,时钟信号与数据信号的相位差一直保持不变,即:从最开始PLL参考时钟源从输入管脚引入,数据源从data管脚引入,它们两的相位差与时钟信号和数据信号达到寄存器端时刻的相位差是相同的。因此,这种一般在做端口或接口的时候使用(如:FPGA与其他外部芯片端口对端口通信时需要用到这种模式)。
图1 源同步模式
② PLL的零补偿模式
特点:因PLL对时钟信号没有补偿调节,故到达寄存器端的时钟信号和输出给FPGA外部使用的时钟信号都没能保持相位差的一致性。因此,这种模式一般不被使用。
图2 零补偿模式
③ 普通模式
特点:在PLL的作用下,PLL时钟源输入管脚处的时钟信号与寄存器端的时钟信号保持相位一致,而与PLL输出给FPGA外部用的时钟信号的相位则不一致,后者与前两者存在一些相位差。因此,这种模式可用在FPGA内部,但一般不将时钟输出给FPGA外部使用。
图3 普通模式
④ 零延时缓冲模式
特点:它与普通模式恰好相反,在PLL的作用下,PLL时钟源输入管脚处的时钟信号与PLL输出给FPGA外部使用的时钟信号保持相位一致,而与寄存器端的时钟信号存在相位差。因此,这种模式一般用作FPGA给外部送时钟信号用。
图4 零延时缓冲模式
PLL一般不设置复位(应取消areset和自动复位),复位容易造成失锁;
PLL一般要设置locked输出端,用于调试的时候查看PLL是否失锁。
【PLL的基本原理】
图5 锁相环PLL的原理框图
图6 锁相环的工作原理示意图
如图5所示,PLL由DIV(分频器)、PD/FD(鉴相器/鉴频器)、LF(低通滤波器)以及VCO(压控振荡器)等部分组成,PLL Ref是锁相环的参考输入时钟信号,VCO有一个初始的振荡频率,通过设置两个DIV的分频系数可以达到PLL分频或倍频的效果。FPGA的PLL IP核配置步骤如下:
① 建工程,然后创建一个定制型的IP宏模块:
图7 步骤①
图8步骤①
② 在I/O中选择ALTPLL,指定IP核输出文件的存放路径和名称,同时在quartus_prj目录下创建ipcore_dir文件夹,用于存放IP核输出文件(ISE会自动创建这个文件夹,但quartus不会自动创建它)。
图9步骤②
③ 配置PLL的速度等级、输入参考时钟的频率、工作模式等参数(速度等级的数值越大,则速度越慢;输入参考时钟频率设为50MHz,工作模式设为普通模式):
图10 步骤③
④ 取消异步复位的配置:
图11 步骤④
⑤ 默认操作:
图12 步骤⑤
⑥ 设置clk c0、clk c1、clk c2(设置PLL输出信号的参数):
图13 clk c0的设置(2倍频、零相移、50%占空比)
图14 clk c1的设置(2分频、零相移、50%占空比)
图15 clk c2的设置(50MHz、相移180°、50%占空比)
⑦ 默认操作、选择要生成的.v例化文件(去掉pll1_bb.v选项、勾选pll1_inst.v选项):
图16
图17
图18 设置产生pll1_inst.v例化文件
图19 将IP宏文件加入到当前工程中
⑧ IP核的例化(将产生的例化文件pll1_inst.v中的内容拷贝到顶层模块ex_ipcore.v中去,并修改信号名称)
⑨ 编写顶层模块ex_ipcore.v中的代码(注意IP核模块的输出信号只能声明为wire型,不能声明为reg型,如:此例中的oclk0、locked等)
⑩ 编写测试脚本和run.do文件
Testbench文件:
run.do文件:
⑪ 添加altera_mf仿真库文件
在仿真工程目录下新建文件夹altera_lib,然后从quartus的安装目录D:\Quartus II12.1\altera\quartus\eda\sim_lib下拷贝altera_mf.v文件到刚新建的文件夹下(C:\Users\Administrator\Desktop\FPGA_EX_self\PLL-ROM-RAM\sim\altera_lib)。
⑫ 新建Modelsim工程,然后进行仿真
⑬ 仿真结果
图20 仿真波形图
由图20可知,oclk0的频率为100 MHz,是sclk的两倍;oclk1的频率为25 MHz,是sclk的1/2;oclk2的频率为50 MHz,与sclk正好反相(相移180°)。有此可见,它们与PLL设置中情况一致,达到了设计的目的。
【注意】因为布线用线质量的不同(PLL用的是金线),所以不建议使用自己写的计数器进行分频,只建议使用PLL分频倍频。
【ROM】
ROM的用途:数据缓存(即:跨时钟域的处理)。
① 新建ROM IP核,输出文件命名为rom_8x256:
图21 新建ROM的IP核
② 配置ROM的IP核模块的参数:
图22 配置ROM IP核模块的参数
如图22所示,设置输出位宽为8bit,设置存储深度为256,M4K是ROM的一个基本存储单元,可以用FPGA芯片的Embedded Memory数(单位:Kbits)除以4得出该FPGA芯片内部包含多少个M4K的Memory,这里设置ROM存储块的类型为auto。可以设置为双时钟的方式(写入是一个时钟,输出是另外一个独立的时钟,用于跨时钟域操作)。
③ 在ROM的q端加寄存器,可提高电路的时序质量和频率
图23 在q端加寄存器
图24 加寄存器的效果
【在q端加寄存器能提高电路的频率】如图24所示,在中间加了寄存器之后,截断两级电路之间的延迟(10ns)为5ns+5ns,原来的电路延迟为10ns,能跑的最高频率为100MHz,而延迟截断后最高频率能达到200 MHz。
④ 新建一个.hex文件或者.mif文件,将其设置为ROM的初始化文件
图25 新建mif文件
图26 填写mif文件中的数据并保存
图27 设置mif文件为ROM的初始化文件
.mif文件中的内容:
.hex文件中的内容:
对比分析mif文件和hex文件的内部内容可知,mif更加条理清晰、容易用MATLAB产生。故通常采用mif文件来初始化ROM。
⑤ 设置生成例化文件rom_8x256_inst.v,并添加生成的IP文件到工程中
图28 设置生成例化文件
⑥ 在顶层模块ex_ipcore.v文件中添加rom_8x256_inst.v的例化内容,并修改ex_ipcore.v(例化、修改信号端口名称、添加ROM的地址控制)、tb_ex_ipcore.v(修改例化语句)以及run.do(添加编译rom_8x256.v文件的语句)中的代码。
ex_ipcore.v文件:
tb_ex_ipcore.v文件:
run.do文件:
⑦ 运行仿真
第一次运行仿真时,波形中odata没有出来数据,一直都是0,查看Modelsim的编译结果可知,有如下警告提示:
图29 编译警告
【解释】因为rom_8x256.v这个文件中有altsyncram_component.init_file = "rom_8x256.mif"这句话,modelsim编译时会自动地去sim的根目录下找rom_8x256.mif文件,可是该文件只在PLL-ROM-RAM\quartus_prj\ipcore_dir有,故需要将这个mif文件拷贝到sim的根目录下去(否则,modelsim无法用mif文件初始化ROM)。
图30 仿真结果图
由图30可知,odata有了数据产生,并且较地址rom_addr有两个时钟周期的延迟,是由于在ROM的输出端加了寄存器造成的,与当初的设想是一致的。
【用MATLAB产生mif文件】
① 在当前工程目录下新建matlab_sim文件夹,然后将miffile.m文件拷贝到该文件夹中(miffile.m文件的目的是实现miffile(filename,var,width,depth)函数),方便MATLAB程序调用;
② 打开MATLAB,并切换MATLAB的工作目录到matlab_sim文件夹下;
③ 新建一个MATLAB脚本,命名为gen_mif,并保存到matlab_sim文件夹下;
④ 编写MATLAB的程序代码:
⑤ 运行gen_mif.m文件后,发现在matlab_sim文件夹下生成了一个rom_8x256.mif文件,其内容如下(与用quartus生成的mif文件基本一致):
⑥ 将生成的rom_8x256.mif文件拷贝到sim文件夹和ex_6\quartus_prj\ipcore_dir目录下,替换掉原来的rom_8x256.mif文件,然后重新运行仿真,仿真结果如图31和图32所示:
图31 用MATLAB产生mif文件初始化ROM的仿真图1
图32 用MATLAB产生mif文件初始化ROM的仿真图2
由图31和图32可知,ROM的数据范围为0~255,与mif文件中的数据一致。