打工人日报#20251110
PLL
使用开发板输出 4 个不同频率或相位的时钟,四个时钟分别为一个倍频时钟
(100MHz),一个倍频后相位偏移 180 度的时钟(100MHz),一个与系统时钟相同的时钟(50MHz)和
一个分频时钟(25MHz),并在 Vivado 中进行仿真以验证结果,最后生成比特流文件并下载到开发板上,
使用示波器来测量时钟的频率是否正确。
打开"IP Catalog"窗口后,在搜索栏中输入"clock"关键字

"Component Name"一栏可以设置该 IP 元件的名称
第一个"Clocking Options"选项卡中
"Clock Monitor"用来监控时钟是否停止、故障和频率变化。
"Primitive"选项用于选择是使用 MMCM 还是 PLL 来完成时钟需求
"Clocking Featurs"用来设置时钟的特征,包括 Frequency Synthesis(频率合成)、Minimize Power(最小化功率)、Phase Alignment(相位校准)、Dynamic Reconfig(动态重配置)、Safe Clock Startup(安全时钟启动)等,其中 Spread Spectrum(扩频)和 Dynamic Phase Shift(动态相移)是使用 MMCM 时才能够设置的特征,
"Jitter Optimization"用于抖动优化,可选 Balanced(平衡)、Minimize Output Jitter(最小化输出抖动)或 Maximize Input Jitter filtering(最大化输入抖动滤波)等优化方式
"Dynamic Reconfig Interface Options"用于选择动态重构接口,只有在设置时钟的特征时勾选动态重构选项后方可进行配置。
"Input Clock Information"下的表格用于设置输入时钟的信息
第一列"Input Clock(输入时钟)"中 Primary(主要,即主时钟)是必要的,Secondary(次要,即副时钟)是可选是否使用的,若使用了副时钟则会引入一个时钟选择信号(clk_in_sel),主副时钟不是同时生效的,可以通过控制 clk_in_sel 的高低电平来选择使用哪一个时钟,当 clk_in_sel 为 1时选择主时钟,当 clk_in_sel 为 0 时选择副时钟。
第二列"Port Name(端口名称)"可以对输入时钟的端口进行命名,这
第三列"lnput Frequency(输入频率)"可以设置输入信号的时钟频率,单位为 MHz,主时钟可配置的输
入时钟范围(19MHz~800MHz)可以在其后面的方块中进行查看;副时钟可配置的时钟输入范围会随着主
时钟的频率而有所改变,具体范围同样可以在其后面的方块中进行查看。
第四列"Jitter Options(抖动选项)"有 UI(百分比)和 PS(皮秒)两种表示单位可选。
第五列"lnput Jitter(输入抖动)"为设置时钟上升沿和下降沿的时间,例如输入时钟为 50MHz,Jitter
Options 选择 UI,lnput Jitter 输入 0.01,择上升沿和下降沿的时间不超过 0.2ns(20ns*1%),若此时将 UI
改为 PS,则 0.01 会自动变成 200(0.2ns=200ps)。
第六列"Source(来源)"中有四种选项
- "Single ended clock capable pin(支持单端时钟引脚)",当输入的时钟来自于单端时钟引脚时,
需要选择这个。 - "Differential clock capable pin(支持差分时钟引脚)",当输入的时钟来自于差分时钟引脚时,需
要选择这个。 - "Global buffer(全局缓冲器)",输入时钟只要在全局时钟网络上,就需要选择这个。
- "No buffer(无缓冲器)",输入时钟必须经过全局时钟缓冲器(BUFG),才可以选择这个。

切换至"Output Clocks"选项卡
The phase is calculated relative to the active input clock 表格用于设置输出时钟的路数(一个 PLL IP核最多可输出六路不同频率的时钟信号)及参数
"Output Clock"为设置输出时钟的路数,因为我们需要输出四路时钟,所以勾选前 4 个时钟
"Port Name"为设置时钟的名字,这里我们可以保持默认的命名
"Output Freq(MHz)"为设置输出时钟的频率,这里我们要对"Requested(即理想值)"进行设置,我们将四路时钟的输出频率分别设为 100、100、50 和 25,设置完理想值后,我们就可以在"Actual"下看到其对应的实际输出频率
Phase (degrees)"为设置时钟的相位偏移,第二路100MHz 的时钟输出信号的相位偏移设置为 180
"Duty cycle"为占空比,正常情况下如果没有特殊要求的话,占空比一般都是设置为 50%,
"Drives"为驱动器类型,有五种驱动器类型可选:
BUFG 是全局缓冲器,如果时钟信号要走全局时钟网络,必须通过 BUFG 来驱动,BUFG 可以驱动所有的 CLB,RAM,IOB。
BUFH 是区域水平缓冲器,BUFH 可以驱动其水平区域内的所有 CLB,RAM,IOB
BUFGCE 是带有时钟使能端的全局缓冲器,它有一个输入端 I、一个使能端 CE 和一个输出端 O。只有当 BUFGCE 的使能端 CE 有效(高电平)时,BUFGCE 才有输出。
BUFHCE 是带有时钟使能端的区域水平缓冲器,
No buffer 即无缓冲器,当输出时钟无需挂在全局时钟网络上时,可以选择无缓冲区
"Max Freq of buffer"为缓冲器的最大频率,选取的 BUFG 缓冲器支持的最大输出频率为 628.141MHz
USE CLOCK SEQUENCING(使用时钟排序),当在第一个选项卡上启用安全时钟启动功能时,Use Clock Sequence 表处于活动状态,可用于配置每个已启用时钟的序列号。在此模式下,只允许 BUFGCE作为时钟输出的驱动程序。
Clocking Feedback(时钟反馈),用于设置时钟信号的来源是片上还是片外,是自动控制还是
用户控制,当自动控制片外的时钟时,还需要配置时钟信号的传递方式是单端还是差分
Enable Optional lnputs/Outputs for MMCM/PLL(启用 MMCM/PLL 的可选输入/输出),其中 reset
(复位)和 power_down(休眠)为输入信号,locked(锁定)、clkfbstopped(指示信号,表示反馈时钟是
否丢失)和 input_clk_stopped(指示信号,表示所选输入时钟不再切换)为输出信号
Reset Type(复位类型),用于设置复位信号是高电平有效还是低电平有效


来到"Port Renaming"选项卡
"Port Renaming"选项卡主要是对一些控制信号(复位信号以外的信号)的重命名

MMCM Setting"选项卡展示了对整个 PLL 的最终配置参数,不建议更改,所以这一步保持默认即可

"Summary"选项卡是对前面所有配置的一个总结,在检查没问题后我们点击"OK"按钮

弹出了"Generate Output Products"窗口,我们直接点击"Generate"即可


可以在"Design Runs"窗口的"Out-of-Context Module Runs"一栏中看到该 IP 核对应的 run
"clk_wiz_0_synth_1"

ip_clk_wiz.v
csharp
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2025/09/24 12:39:55
// Design Name:
// Module Name: ip_clk_wiz
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
// 该模块用于通过PLL(锁相环)IP核生成不同频率和相位的时钟信号。
// 输入系统时钟和复位信号,输出100MHz、100MHz(相位偏移180度)、50MHz和25MHz的时钟信号。
//
// Dependencies:
// 依赖于名为clk_wiz_0的PLL IP核。
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ip_clk_wiz (
// 输入信号
input sys_clk, // 系统时钟,作为PLL的输入时钟源
input sys_rst_n, // 系统复位,低电平有效,用于复位PLL IP核
// 输出信号
output clk_100m, // 100Mhz时钟频率
output clk_100m_180deg, // 100Mhz时钟频率,相位偏移180度
output clk_50m, // 50Mhz时钟频率
output clk_25m // 25Mhz时钟频率
);
// wire定义
wire locked; // 用于指示PLL是否锁定的信号,高电平表示PLL已锁定
// PLL IP核的例化
clk_wiz_0 clk_wiz_0 (
// Clock out ports
.clk_out1(clk_100m), // 输出100MHz时钟信号
.clk_out2(clk_100m_180deg), // 输出100MHz且相位偏移180度的时钟信号
.clk_out3(clk_50m), // 输出50MHz时钟信号
.clk_out4(clk_25m), // 输出25MHz时钟信号
// Status and control signals
.reset(~sys_rst_n), // 输入复位信号,由于PLL的复位信号可能是高电平有效,这里对sys_rst_n取反
.locked(locked), // 输出锁定信号,指示PLL是否已成功锁定
// Clock in ports
.clk_in1(sys_clk) // 输入系统时钟作为PLL的时钟输入
);
endmodule


逻辑分析仪查看波形

添加仿真文件
tb_ip_clk_wiz.v
csharp
`timescale 1ns / 1ps //仿真单位/仿真精度
module tb_ip_clk_wiz();
//parameter define
parameter CLK_PERIOD = 20; //时钟周期 20ns
//reg define
reg sys_clk;
reg sys_rst_n;
//wire define
wire clk_100m;
wire clk_100m_180deg;
wire clk_50m;
wire clk_25m;
//信号初始化
initial begin
sys_clk = 1'b0;
sys_rst_n = 1'b0;
#200
sys_rst_n = 1'b1;
end
//产生时钟
always #(CLK_PERIOD/2) sys_clk = ~sys_clk;
ip_clk_wiz u_ip_clk_wiz(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n ),
.clk_100m (clk_100m ),
.clk_100m_180deg (clk_100m_180deg),
.clk_50m (clk_50m ),
.clk_25m (clk_25m )
);
endmodule



仿真结果

阅读
《晚熟的人》
红唇绿嘴
