PLL IP核简介
PLL
(
Phase Locked Loop
,即锁相环)是最常用的
IP
核之一,其性能强大,可以对输入到 FPGA
的时钟信号进行任意分频、倍频、相位调整、占空比调整,从而输出一个期望时钟。
Altera
中的
PLL
是模拟锁相环,和数字锁相环不同的是模拟锁相环的优点是输出的稳定度高、相位连续可调、延时连续可调;缺点是当温度过高或者电磁辐射过强时会失锁。
PLL基本工作原理

PLL结构模型示意图
1
、首先需要参考时钟(
ref_clk
)通过鉴频(
FD
)鉴相器(
PD
)和需要比较的时钟频率进行较,我们以频率调整为例,
如果参考时钟频率等于需要比较的时钟频率则鉴频鉴相器输出为 0,如果参考时钟频率大于需要比较的时钟频率则鉴频鉴相器输出一个变大的成正比的值,如果参考时钟频率小于需要比较的时钟频率则鉴频鉴相器输出一个变小的正比的值。
2
、鉴频鉴相器的输出连接到环路滤波器(
LF
)上,用于控制噪声的带宽,滤掉高频噪声,使之稳定在一个值,起到将带有噪声的波形变平滑的作用。如果鉴频鉴相器之前的波形抖动比较大,经过环路滤波器后抖动就会变小,趋近于信号的平均值。
3
、经过环路滤波器的输出连接到压控振荡器(
VCO
)上,环路滤波器输出的电压以控制 VCO
输出频率的大小,环路滤波器输出的电压越大
VCO
输出的频率越高,然后将这个频率信号连接到鉴频鉴相器作为需要比较的频率。
如果
ref_clk
参考时钟输入的频率和需要比较的时钟频率不相等,该系统最终实现的就是让它们逐渐相等并稳定下来。如果 ref_clk
参考时钟的频率是
50MHz
,经过整个闭环反馈系统后,锁相环对外输出的时钟频率 pll_out
也是
50MHz
。
PLL倍频
倍频是在
VCO
后直接加一级分频器,我们知道 ref_clk
参考时钟输入的频率和需要比较的时钟频率经过闭环反馈系统后最终会保持频率相等,而在需要比较的时钟之前加入分频器,就会使进入分频器之前的信号频率为需要比较的时钟频率的倍数,VCO
后输出的
pll_out
信号频率就是
ref_clk
参考时钟倍频后的结果。

PLL分频
分频是在
ref_clk
参考时钟后加一级分频器,这样需要比较的时钟频率就始终和 ref_clk
参考时钟分频后的频率相等,在
VCO
后输出的 pll_out
信号就是
ref_clk
参考时钟分频后的结果。

PLL基本配置

以上我们分别将
c0
、
c1
、
c2
、
c3 的输出设置为输入时钟的 2
倍频、输入时钟的
2
分频、输入时钟相移
90
°、输入时钟占空比变为 20%
,然后通过仿真进行对比。
PLL IP核的调用
配置完IP核后会生成pll_ip.ppf pll_ip.qip pll_ip.v pll_ip_inst.v四个文件,其中pll_ip_inst.v代码如下:
pll_ip pll_ip_inst (
.inclk0 ( inclk0_sig ),
.c0 ( c0_sig ),
.c1 ( c1_sig ),
.c2 ( c2_sig ),
.c3 ( c3_sig ),
.locked ( locked_sig )
);
以下是实例化PLL IP核并应用的代码编写
module pll
(
input wire sys_clk, //系统时钟50MHz
input wire sys_rst_n,
output wire clk_mul_2, //系统时钟经过 2 倍频后的时钟
output wire clk_div, //系统时钟经过 2 分频后的时钟
output wire clk_pha_90, //系统时钟经过相移 90°后的时钟
output wire clk_duc_20, //系统时钟变为占空比为 20%的时钟
output reg [1:0] cnt,
output wire locked //检测锁相环是否已经锁定,只有该信号为高时输出的时钟才是稳定的
);
pll_ip pll_ip_inst (
.inclk0 ( sys_clk ),
.c0 ( clk_mul_2 ),
.c1 ( clk_div ),
.c2 ( clk_pha_90 ),
.c3 ( clk_duc_20 ),
.locked ( locked )
);
always@(posedge clk_div or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt <= 2'd0;
else
cnt <= cnt + 1'b1;
endmodule
PLL IP核的仿真
`timescale 1ns/1ns
module tb_pll();
reg sys_clk;
wire clk_mul_2;
wire clk_div;
wire clk_pha_90;
wire clk_duc_20;
wire locked;
//初始化系统时钟
initial sys_clk = 1'b1;
//sys_clk:模拟系统时钟,每 10ns 电平翻转一次,周期为 20ns,频率为 50MHz
always #10 sys_clk = ~sys_clk;
pll pll_inst
(
.sys_clk (sys_clk),
.clk_mul_2 (clk_mul_2),
.clk_div (clk_div),
.clk_pha_90(clk_pha_90),
.clk_duc_20(clk_duc_20),
.locked (locked)
);
endmodule
然后将编写好的仿真文件添加到工程中,进行仿真,查看波形。