本原创文章由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注明出处(www.meyesemi.com)
1.实验简介
实验目的:
了解 PLL IP 的基本使用方法。
实验环境: Window11 PDS2022.2-SP6.4
芯片型号: PG2L50H-484
2.实验原理
2.1. PLL 介绍
锁相环作为一种反馈控制电路,其特点是利用外部输入的参考信号来控制环路内部震荡信号的频率和相位。因为锁相环可以实现输出信号频率对输入信号频率的自动跟踪,所以锁相环通常用于闭环跟踪电路。锁相环在工作的过程中,当输出信号的频率与输入信号的频率相等时,输出电压与输入电压保持固定的相位差值,即输出电压与输入电压的相位被锁住,这就是锁相环名称的由来。
锁相环拥有强大的性能,可以对输入到 FPGA 的时钟信号进行任意分频、倍频、 相位调整、占空比调整,从而输出一个期望时钟;除此之外,在一些复杂的工程中, 哪怕我们不需要修改任何时钟参数,也常常会使用 PLL 来优化时钟抖动,以此得到一个更为稳定的时钟信号。正是因为 PLL 的这些性能都是我们在实际设计中所需要的,并且是通过编写代码无法实现的,所以 PLL IP 核才会成为程序设计中最常用 IP 核之一。 PLL IP 是紫光同创基于 PLL 及时钟网络资源设计的 IP,通过不同的参数配置,可实 现时钟信号的调频、调相、同步、频率综合等功能。
2.2. IP 配置
首先点击快捷工具栏的“IP”图标,进入 IP 例化设置
![]()
然后在 IP 目录处选择 PLL,在 Instance name 处为本次实例化的 IP 取一个名字,接着点击 Customise 进入 IP 配置页面。操作示意图如下:
![]()
PLL 的使用可选择 Basic 和 Advanced 两种模式,Advanced 模式下 PLL 的内部参数配置完全开放,需要自己填写输入分频系数、输出分频系数、占空比、相位、反馈分频系数等才能正确配置。Basic 模式下用户无需关心 PLL 的内部参数配置,只需输入期望的频率值、相位值、占空比等,IP 将自动计算,得到最佳的配置参数。如果没有特殊应用,建议使用 Basic 模式配置 PLL。本次实验我们选择 Basic Configuration。

接下来进行基础配置:
在 Public Configurations 一栏将输入时钟频率设置为 25MHZ。
在 Clockout0 Configurations 选项卡下,勾选使能 clkout0,将输出频率设置为 50MHZ。
在 Clockout1 Configurations 选项卡下,勾选使能 clkout1,将输出频率设置为 100MHZ。
在 Clockout2 Configurations 选项卡下,勾选使能 clkout2,将输出频率设置为 100MHZ,并设置相位偏移为 180 度。
其他选项可以使用默认设置,若有其他需求可以查阅 IP 手册了解,本实验我们暂介绍 IP 基本的使用方法:
![]()
点击左上角 generate 生成 IP。
![]()
3.代码设计
模块接口列表如下所示:
表 1- 3- 1 PLL IP 使用实验模块接口表
| 端口 |
I/O |
位宽 |
描述 |
|---|
| sys_clk |
input |
1 |
系统时钟 |
| clkout0 |
output |
1 |
54MHZ 时钟 |
| clkout1 |
output |
1 |
81MHZ 时钟 |
| clkout2 |
output |
1 |
81MHZ 时钟,相位偏移 180 度 |
| lock |
output |
1 |
时钟锁定信号,当为高电平时, 代表 IP 核输出时钟稳定 |
PLL_TEST 顶层代码:
module PLL_TEST(
input sys_clk ,
output clkout0 ,
output clkout1 ,
output clkout2 ,
output lock
);
PLL PLL_U0 (
.clkout0 (clkout0 ), // output
.clkout1 (clkout1 ), // output
.clkout2 (clkout2 ), // output
.lock (lock ), // output
.clkin1 (sys_clk ) // input
);
endmodule
![]()
该模块的功能是例化 PLL IP 核,功能简单,在此不做说明。
PLL_tb 测试代码:
timescale 1ns / 1ps
module PLL_tb();
reg sys_clk ;
wire clkout0 ;
wire clkout1 ;
wire clkout2 ;
wire lock ;
initial
begin
#2
sys_clk <= 0 ;
end
parameter CLK_FREQ = 25;
always # ( 1000/CLK_FREQ/2 ) sys_clk = ~sys_clk ;
PLL_TEST u_PLL_TEST(
.sys_clk (sys_clk ),
.clkout0 (clkout0 ),
.clkout1 (clkout1 ),
.clkout2 (clkout2 ),
.lock (lock )
);
endmodule
![]()
timescale 定义了模块仿真的时间单位和时间精度。时间单位是 1 纳秒,精度是 1 皮秒。
initial 块负责初始化系统时钟。在仿真启动后的 2 纳秒,系统时钟 sys_clk 被设置为 0。这是为了在仿真开始时定义一个已知的初始状态。
代码定义了一个时钟频率参数 CLK_FREQ 为 25 MHz,并使用一个 always 块来翻转系统时钟信号。always 块中的逻辑使得 sys_clk 每 40 纳秒翻转一次,从而生成一个 25MHz 的方波时钟信号。这种时钟信号用于驱动被测试的 PLL_TEST 模块。
最后,将测试平台的各个信号连接到 PLL_TEST 模块。这包括将生成的系统时钟 sys_clk 连接到 PLL_TEST 的时钟输入端,并将 PLL_TEST 的输出信号 clkout0、clkout1、 clkout2 和 lock 使用 wire 引出观察。
4.PDS 与 Modelsim 联合仿真
PDS 支持与 Modelsim 或 QuestaSim 等第三方仿真器的联合仿真,而 Modelsim 是较为常用的仿真器,使用 PDS 与 Modelsim 来进行联合仿真。
接下来选择 Project->Project Setting,打开工程设置,准备设置联合仿真。
![]()
选择 Simulation 选项卡,红框 1 选择刚才编译生成的仿真库的路径,红框 2 选择 Modelsim 的启动路径,之后点击 OK。
右键仿真的文件,选择 Run Behavior Simulation 开始行为仿真。
![]()
运行后会自动打开 Modelsim。并执行仿真,如果没有任何报错,则表示成功。如果出现错误,请检测 PDS 与 Modelsim 的配置。
![]()
5.实验现象
点击 Wave 观察 PLL 输出信号:
![]()
使用标尺测量 clkout0,发现其一个时钟周期是 20ns,也就是 50MHZ。
![]()
可以看到 clkout1 的时钟频率是 100MHZ,且和 clkout2 相位偏差 180°,符合设置。需要注意 PLL 的输出时钟应该在时钟锁定信号 lock 有效之后才能使用,lock 信号拉高之前输出 的时钟是不确定的。