写在前面的话
梦翼师兄经常告诉大家,FPGA最明显的优势就是它的速度。那么本节,梦翼师兄和大家一起来学习FPGA片内时钟管理单元PLL(锁相环)的应用。利用锁相环,我们可以在一个很宽广的范围内实现任意的分频和倍频。使用锁相环,可以有效的减少我们在时钟发生部分的代码量,同时更重要的,利用锁相环的“全局时钟树”,可以保证很好的时钟质量。
项目需求
我们使用锁相环生成两路时钟,一路为25MHz,另外一路为100MHz。通过这种方式我们可以学会利用锁相环实现分频和倍频的基本操作。
操作步骤
启动Quartus15.0在界面的右侧的IP Catalog的搜索中键入pll,然后双击【ALTPLL】
选择语言为Verilog,给IP起一个名字,这里把它叫做my_pll
点击【ok】以后,界面将会进入pll设置向导中,键入我们的输入时钟频率(晶振或者外部时钟),然后点击【NEXT】
我们把【areset】和【locked】打勾(areset:锁相环的高电平复位信号。locked:当锁相环的输出稳定之后,locked会变成高电平),然后点击【NEXT】
一直点击【NEXT】,直到出现如下界面
选择【Enter output clock freqquency】键入我们想要输出的时钟频率,然后点击NEXT
选择使用第二个时钟,键入我们想要的时钟频率。
一直点击【NEXT】,直到出现如下界面,然后选择my_pll_inst.v(这个文件中是调用IP核的端口),点击【Finish】
顶层架构设计
在ip核的设置向导中,我们了解了锁相环的端口,绘制出如下的架构图:
端口描述
端口名 |
端口说明 |
clk |
输入时钟 |
areset |
高电平有效的复位 |
Clk_25M |
25MHz的时钟输出 |
Clk_100M |
100MHz的时钟输出 |
locked |
时钟稳定信号 |
代码解释
调用锁相环模块的代码:
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function: 锁相环的应用 *****************************************************/ 01 module pll ( 02 clk, //输入时钟 03 areset, //复位信号 04 clk_25M, //25M的时钟输出 05 clk_100M, //100M的时钟输出 06 locked //时钟稳定信号 07 ); 08 //系统输入 09 input clk; //输入时钟 10 input areset; //复位信号 11 //系统输出 12 output clk_25M; //25M的时钟输出 13 output clk_100M; //100M的时钟输出 14 output locked; //时钟稳定信号 15 // 调用IP核 16 my_pll my_pll_inst ( 17 .areset ( areset ), //复位信号 18 .inclk0 ( clk ), //系统时钟输入 19 .c0 ( clk_100M ), //100M的时钟输出 20 .c1 ( clk_25M ), //25M的时钟输出 21 .locked ( locked ) //时钟稳定信号 22 ); 23 24 endmodule |
本模块中只是简单的调用了pll的IP核,主要目的是让大家学会如何调用IP核。
仿真代码如下:
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function: 锁相环模块的测试 *****************************************************/ 01 `timescale 1ns/1ps //时间单位和精度定义 02 03 module pll_tb; 04 05 //系统输入 06 reg clk; //输入时钟 07 reg areset; //复位信号 08 //系统输出 09 wire clk_25M; //25M的时钟输出 10 wire clk_100M; //100M的时钟输出 11 wire locked; //时钟稳定信号 12 13 initial begin 14 clk = 1; 15 areset = 0; 16 end 17 18 always # 10 clk = ~clk; //50MHz时钟 19 20 pll pll( 21 .clk(clk), //输入时钟 22 .areset(areset), //复位信号 23 .clk_25M(clk_25M), //25M的时钟输出 24 .clk_100M(clk_100M), //100M的时钟输出 25 .locked(locked) //时钟稳定信号 26 ); 27 28 29 endmodule |
仿真结果分析
当输出的时钟稳定之后,locked(时钟稳定信号)信号由低变高。输出的两路时钟中,一路为20MHz,一路为100MHz,与我们的设计要求一样,证明我们的操作和代码都是正确的。