PLL IP 核简介
锁相环(PLL)作为一种反馈控制电路,其特点是利用外部输入的参考信号来控制环路内部震荡信号的频率和相位。因为锁相环可以实现输出信号频率对输入信号频率的自动跟踪,所以锁相环通常用于闭环跟踪电路。锁相环在工作的过程中,当输出信号的频率与输入信号的频率相等时,输出电压与输入电压保持固定的相位差值,即输出电压与输入电压的相位被锁住,这就是锁相环名称的由来。
锁相环拥有强大的性能,可以对输入到 FPGA 的时钟信号进行任意分频、倍频、相位调整、占空比调整,从而输出一个期望时钟;除此之外,在一些复杂的设计中,哪怕不需要修改任何时钟参数,也常会使用 PLL 来优化时钟抖动,以此得到一个更为稳定的时钟信号。正是因为 PLL 的这些性能都是在实际设计中所需要的,并且是通过编写代码无法实现的,所以 PLL IP 核才会成为程序设计中最常用 IP 核之一。需要注意的是 Xilinx 中的 PLL 是模拟锁相环,其优点是输出的稳定度高、锁定时间较短,相位连续可调;缺点是在极端环境(例如极端高/低温环境,高磁场强度等)下容易失锁。
Xilinx7 系列器件中的时钟资源包含有多个时钟管理单元 CMT(Clock Management Tile),每个 CMT 由一个 MMCM(全称 Mixed-Mode Clock Manager,即混合模式时钟管理)和一个 PLL(全称 Phase Locked Loop,即锁相环)组成, MMCM 和 PLL 各自的含义以及区别如下:
- PLL(锁相环):用来统一整合时钟信号,使高频器件正常工作,如内存的存取数据等。
- MMCM(混合模式时钟管理):是基于 PLL 的新型混合模式时钟管理器,实现了最低的抖动和抖动滤波,为高性能的 FPGA 设计提供更高性能的时钟管理功能。
- MMCM 是在一个 PLL 的基础上加入 DCM 的以进行精细相移,也就是说 MMCM 在 PLL 的基础上加上了相位动态调整功能,又因为 PLL 是模拟电路,而动态调相是数字电路,所以 MMCM 被称为混合模式,MMCM 相对 PLL 的优势就是相位可以动态调整,但 PLL 占用的面积更小,在大部分的设计中使用 MMCM 或者 PLL 来对系统时钟进行分频、倍频和相位偏移都是可以满足设计需求的。
PLL 工作原理
PLL 大致的结构模型如下:
由上图可以看出 PLL 的工作流程如下:
- 通过 PFD(全称:Phase-Frequency Detector,即鉴频鉴相器)对参考时钟(ref_clk)频率和需要比较的时钟频率(即上图中的输出时钟:pll_out)进行对比。
- PFD 的输出连接到 LF(全称:Loop Filter,即环路滤波器)上,用于控制噪声带宽,滤掉高频噪声,使之趋于一个稳定的值,起到将带有噪声的波形变平滑的作用。如果 PFD 之前的波形抖动比较大,经过环路滤波器后抖动就会变小,趋近于信号的平均值。
- 经过 LF 的输出连接到 VCO(全称:Voltage Controlled Oscillator,即压控振荡器)上,LF 输出的电压可以控制 VCO 输出频率的大小,LF 输出的电压越大 VCO 输出的频率越高,然后将这个频率信号连接到 PFD 作为需要比较的频率。
如果参考时钟输入的频率和需要比较的时钟频率不相等,该系统最终实现的就是让它们逐渐相等并稳定下来。例如参考时钟的频率是 50MHz,经过整个闭环反馈系统后,锁相环对外输出的时钟频率也是50MHz。
PLL 分频原理图
PLL 分频原理图如下图所示:
分频是在参考时钟与 PFD 之间加入一级分频器(可称为前置分频器),通过前置分频器 N(N 表示数字)分频后得到一个新的参考时钟,因此需要比较的时钟频率(即 pll_out)就始终是和新的参考时钟频率进行对比的,pll_out 的输出结果也会逐渐与新的参考时钟(ref_clk/N)相等,从而实现了分频的功能。
PLL 倍频原理
PLL 倍频原理图如下图所示:
倍频是在 VCO 与 PFD 之间加入一级分频器(可称为后置分频器),通过后置分频器 M(M 表示数字)分频后得到一个新的需要比较的时钟频率(即 pll_out 分频后的时钟),因为此时与参考时钟频率进行对比的是分频后的输出时钟(pll_out/M),所以此时的输出时钟是参考时钟的 M 倍(pll_out = ref_clk * M),从而实现了倍频的功能。
常用芯片的PLL IP核重要参数
PLL IP 核的使用
打开 PLL IP 核“Customize IP”窗口
- 后点击 Vivado 软件左侧“Flow Navigator”栏中的“IP Catalog”
点击“IP Catalog”后弹出的“IP Catalog”窗口如下图所示
- 在开“IP Catalog”窗口的搜索栏中输入“clock”关键字
- 们双击“FPGA Features and Design”→“Clocking”下的“Clocking Wizard”,弹出“Clocking Wizard” IP核的“Customize IP”
窗口
PLL IP 核的配置
PLL IP核配置界面如下,注意包括工具栏、IP核名称设置、“Clocking Options”选项卡、“Output Clocks”选项卡、“Port Renaming”选项卡、“MMCM Setting”选项卡、“Summary”选项卡
- 工具栏提供了一些IP核的通用操作,如查看手册、查看 版本更新记录、打开 IP 介绍的网页、打开 IP 答疑网页、设置 IP 存储路径、分为 IP 核配置等操作。
- 设置 IP 名称
可以在的“Component Name”一栏可以设置该 IP 元件的名称 - “Clocking Options”选项卡
- “Clock Monitor”用来监控时钟是否停止、故障和频率变化,一般不用,
- “Primitive”选项用于选择是使用 MMCM 还是 PLL 来完成时钟需求,对于大多数设计来说 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”用于选择动态重构接口,只有在设置时钟的特征时勾选Dynamic Reconfig(动态重配置)选项后方可进行配置
- “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,主时钟可配置的输入时钟范围(10MHz~800MHz)可以在其后面的方块中进行查看;副时钟可配置的时钟输入范围会随着主时钟的频率而有所改变,具体范围同样可以在其后面的方块中进行查看。
第四列:“Jitter Options(抖动选项)”有 UI(百分比)和 PS(皮秒)两种表示单位可选。
第五列:“lnput Jitter(输入抖动)”设置时钟上升沿和下降沿的时间。
第六列:“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”进行设置,设置完理想值后,就可以在“Actual”下看到其对应的实际输出频率。
第四列:“Phase (degrees)”为设置时钟的相位偏移,,这里对“Requested”进行设置,设置完理想值后,就可以在“Actual”下看到其对应的相位偏移。
第五列:“Duty cycle”为占空比,正常情况下如果没有特殊要求的话,占空比一般都是设置为 50%。
第六列:“Drives”为驱动器类型,有五种驱动器类型可选,BUFG 是全局缓冲器,如果时钟信号要走全局时钟网络,必须通过 BUFG 来驱动,BUFG 可以驱动所有的 CLB,RAM,IOB;BUFH 是区域水平缓冲器,BUFH 可以驱动其水平区域内的所有 CLB,RAM,IOB;BUFGCE 是带有时钟使能端的全局缓冲器,它有一个输入端 I、一个使能端 CE 和一个输出端 O。只有当 BUFGCE 的使能端 CE 有效(高电平)时,BUFGCE 才有输出;BUFHCE 是带有时钟使能端的区域水平缓冲器,用法与 BUFGCE 类似;No buffer 即无缓冲器,当输出时钟无需挂在全局时钟网络上时,可以选择无缓冲区。
第七列:“Max Freq of buffer”为缓冲器的最大频率,例如选取的 BUFG 缓冲器时支持的最大输出频率为 628.141MHz。 - USE CLOCK SEQUENCING(使用时钟排序),当在“Clocking Options”选项卡中启用Safe Clock Startup(安全时钟启动)时,Use Clock Sequence 表处于活动状态,可用于配置每个已启用时钟的序列号。在启用Safe Clock Startup(安全时钟启动)后只允许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”选项卡
“MMCM Setting”选项卡展示了对整个 PLL 的最终配置参数,这些参数都是由 Vivado 根据之前用户输入的时钟需求来自动配置的,Vivado 已经对参数进行了最优的配置,在绝大多数情况下都不需要用户对它们进行更改,也不建议更改,所以这一步保持默认即可 - “Summary”选项卡
最后的“Summary”选项卡是对前面所有配置的一个总结,在检查没问题后点击“OK”按钮,然后在弹出了“Generate Output Products”窗口,直接点击“Generate”即可完成IP核的生成(对于IP核一般选 OOC 编译方式,这样可以避免修改其他代码后重复编译 IP 核)。
模块设计
本次实验的目的是通过 PLL IP 核输出四路不同频率和相位的时钟,系统框图如下:
开发板的系统时钟为 50MHz,即一个时钟周期为 20ns。100MHz 的时钟一个时钟周期为 10ns;100MHz 相位偏移 180°的时钟就相当于将 100MHz 的时钟的高低电平变化做了一个反相处理;50MHz 的时钟和系统时钟相同;25MHz 的时钟一个时钟周期为 40ns,此外,PLL IP 核还会输出一个时钟锁定信号(locked),所以波形图如下所示:
编写代码
生成 PLL IP 核
PLL IP 核的配置如下:
在检查没问题后点击“OK”按钮,然后在弹出了“Generate Output Products”窗口,直接点击“Generate”即可完成IP核的生成。
编写代码
代码的主要功能就是例化一个 PLL IP 核,其源码如下:
module ip_clk_wiz(
input sys_clk, //系统时钟
input sys_rst_n, //系统复位,低电平有效
output locked, //锁定标志
output clk_100m, //100Mhz 时钟频率
output clk_100m_180deg, //100Mhz 时钟频率,相位偏移 180 度
output clk_50m, //50Mhz 时钟频率
output clk_25m //25Mhz 时钟频率
);
//例化PLL IP核
clk_wiz_0 u_clk_wiz_0_inst0 (
.clk_out1(clk_100m),
.clk_out2(clk_100m_180deg),
.clk_out3(clk_50m),
.clk_out4(clk_25m),
.reset(~sys_rst_n),
.locked(locked),
.clk_in1(sys_clk)
);
endmodule
使用 Vivado 自带仿真器进行仿真
在代码中用到了赛灵思提供的IP核,所以不能直接使用Modelsim进行仿真,需要先导入赛灵思IP核的库以后才能仿真,关于Modelsim仿真的内容后面在介绍。
- 创建仿真测试激励文件tb_ip_clk_wiz.v,文件内容如下:
`timescale 1ns / 1ps //仿真单位/仿真精度
module tb_ip_clk_wiz();
reg sys_clk; //系统时钟
reg sys_rst_n; //系统复位,低电平有效
wire locked; //锁定标志
wire clk_100m; //100Mhz 时钟频率
wire clk_100m_180deg; //100Mhz 时钟频率,相位偏移 180 度
wire clk_50m; //50Mhz 时钟频率
wire clk_25m; //25Mhz 时钟频率
//信号初始化
initial begin
sys_clk = 1'b0;
sys_rst_n = 1'b0;
#200
sys_rst_n = 1'b1;
end
//产生时钟
always #20 sys_clk = ~sys_clk;
//例化需要仿真的IP核
ip_clk_wiz tb_u_ip_clk_wiz_inst0(
.sys_clk(sys_clk), //系统时钟
.sys_rst_n(sys_rst_n), //系统复位,低电平有效
.locked(locked), //锁定标志
.clk_100m(clk_100m), //100Mhz 时钟频率
.clk_100m_180deg(clk_100m_180deg), //100Mhz 时钟频率,相位偏移 180 度
.clk_50m(clk_50m), //50Mhz 时钟频率
.clk_25m(clk_25m) //25Mhz 时钟频率
);
endmodule
-
点击“Sources”窗口中的“+”号(Add Sources 命令),在弹出的窗口中选择“Add or Create Simulation Sources”,然后点击 next。
-
再弹出的界面中点击“Add Files”来将编写好的仿真源文件添加到工程中,步骤如下图所示:
-
完成后点击“Finish”,注意,不要勾选“Scan and add RTL include files into Project”和“Copy sources into Project”两个选项
-
在“Flow Navigator”窗口中点击“Run Simulation”并选择“Run Behavioral Simulation”
-
经过稍许时间的等待,就进入了 Vivado 自带的仿真器界面。
整个界面分4个部分
(1)“Scope”窗口:HDL 设计的层次划分,在“Scope”窗口中可以看到设计的层次结构,当选择了一个“Scope”层次结构中的作用域时,该作用域内的所有 HDL 对象,包括 reg、wire 等都会出现在“Objects”窗口中,然后可以在“Objects”窗口中选择 HDL 对象,并将它们添加到波形查看器中。
(2)“Object”窗口:“Objects”窗口会显示在“Scopes”窗口中选择的范围内的所有 HDL 仿真对象.
(3)波形窗口:用于显示所要观察信号的波形。若要向波形窗口添加单个 HDL 对象或多个 HDL 对象,可以在“Objects”窗口中,右键单击一个或多个对象,然后从下拉菜单中选择“Add to Wave Window”选项。
(4)仿真工具栏:仿真工具栏包含运行各个仿真动作的命令按钮,从左至右依次是 “Restart”将仿真时间重置为零、“Run all”运行仿真、 “Run For”运行特定的一段时间、“Step”按步运行仿真、“Break”暂停当前仿真、 “Relaunch”重新编译仿真源并重新启动仿真。 -
Vivado 自带的仿真器界面中即可完成仿真操作
Vivado 几种仿真模式的差异
Vivado 有如下五种仿真模式:
- “run behavioral simulation”行为级仿真,也是通常说的功能仿真。
- “post-synthesis function simulation”综合后的功能仿真。
- “post-synthesis timing simulation”综合后的时序仿真,和真实运行的时序就相差不远了。
- “post-implementation function simulation”实现后的功能仿真。
- “post-implementation timing simulation”实现后的时序仿真,最接近真实的时序波形。
数字电路设计中一般包括 3 个大的阶段:源代码输入、综合、实现,而电路仿真的切入点也基本与这些阶段相吻合,根据不同的设计阶段,仿真可以分为 RTL 行为级仿真、综合后门级功能仿真、时序仿真,具体描述如下:
- RTL 行为级仿真;在大部分设计中执行的第一个仿真都是 RTL 行为级仿真,这个阶段的仿真可以用来检查代码中的语法
错误以及代码行为的正确性,需要注意是该阶段的仿真是不包含延时信息的,如果没有实例化一些与器件相关的特殊底层元件的话,这个阶段的仿真也可以做到与器件无关。 - 综合后门级功能仿真 (前仿真);一般在设计流程中的第二个仿真是综合后门级功能仿真,绝大多数的综合工具都可以输出标准网表文件和 Verilog 或者 VHDL 网表文件,其中标准网表文件是用来在各个工具之间传递设计数据的,并不能用来做仿真使用,Verilog 或者 VHDL 网表文件是可以用来仿真的,之所以叫门级仿真是因为综合工具给出的仿真网表与生产厂家的器件的底层元件模型对应起来了。
- 时序仿真 (后仿真);在设计流程中的最后一个仿真是时序仿真,布局布线完成以后可以提供一个时序仿真模型,这个模型中除了包含一些器件信息外还会提供了一个 SDF 时序标注文件。
Modelsim 联合仿真
生成 Modelsim 编译仿真库
-
在 Modelsim 安装路径下新建一个文件夹来存放仿真库,这里将其命名为 vivado2020.2_lib
-
打开 Vivado(切记不要开任何工程),点击 Tools 下的 Compile Simulation Libraries(编译仿真库)选项,打开Compile Simulation Libraries 窗口
-
Simulator(仿真器)选择 ModelSim Simulator;Language(语言)可以保持默认选项 all(即 Verilog 与 VHDL 都可以);Library(库)可以保持默认选项 all(即包含 unisim(功能仿真)和 simprim(时序仿真)的库);Famliy(芯片族)默认为 all,选 all 的话编译时间会很长,而且编译出来会很大,所以这里按需勾选即可;
-
Compiled library location(汇编库地址)和 GCC executable path(GCC 可执行路径)都选择我们一开始创建好的 vivado2020.2_lib 文件夹; Simulator executable path(仿真器可执行路径)选到 Modelsim 安装路径下的 win64 文件夹(一般 Vivado 会自动识);完成后点击“Compile”进行编译。
-
编译仿真库的时间较长,需要耐心等待,编译完成后会出现下图所示的信息列表
在 Vivado 中关联 Modelsim
- 点击 Tools 下的 Settings(设置)选项
- 在弹出的“Settings”窗口进行如下设置
切换到“3rd Party Simulators(第三方仿真器)”页面,指定 Modelsim 的 lnstall Paths(软件路径)和 GCC Install Paths(仿真库路径)即可,设置完成后点击“OK”。
联合仿真
- 打开需要仿真的工程,然后点击 Tools 下的 Settings(设置)选项,在 Settings 窗口中选择 Simulation(仿真器)页面,然后在该页面中指定该工程使用什么仿真器进行仿真
Target simulator(目标仿真器)选项中选择 Modelsim Simulation(默认为 Vivado 自带仿真器:Vivado Simulation)
compiled library location(仿真库地址)指定之前创建的 vivado2020.2_lib 文件夹
其余选项保持不变,点击“OK”。 - 在“Flow Navigator”窗口中点击“Run Simulation”并选择“Run Behavioral Simulation”,此时时 Vivado 会自动打开 Modelsim 软件并编译运行
提示:
联合仿真时 Vivado 默认的库是 xli_defaultlib,如果联合仿真时修改了代码,可以在 Modelsim 工程对应的 library 下找到 xli_defaultlib 来进行编译。