• IP 核之 MMCM/PLL 实验


            PLL 的英文全称是 Phase Locked Loop,即锁相环,是一种反馈控制电路。PLL 对时钟网络进行系统级 的时钟管理和偏移控制,具有时钟倍频、分频、相位偏移和可编程占空比的功能。Xilinx 7 系列器件中的时 钟资源包含了时钟管理单元 CMT,每个 CMT 由一个 MMCM 和一个 PLL 组成。对于一个简单的设计来说, FPGA 整个系统使用一个时钟或者通过编写代码的方式对时钟进行分频是可以完成的,但是对于稍微复杂一 点的系统来说,系统中往往需要使用多个时钟和时钟相位的偏移,且通过编写代码输出的时钟无法实现时 钟的倍频,因此学习 Xilinx MMCM/PLL IP 核的使用方法是我们学习 FPGA 的一个重要内容。

            1、MMCM/PLL IP 核简介

            锁相环作为一种反馈控制电路,其特点是利用外部输入的参考信号控制环路内部震荡信号的频率和相位。因为锁相环可以实现输出信号频率对输入信号频率的自动跟踪,所以锁相环通常用于闭环跟踪电路。锁相环在工作的过程中,当输出信号的频率与输入信号的频率相等时,输出电压与输入电压保持固定的相位差值,即输出电压与输入电压的相位被锁住,这就是锁相环名称的由来。Xilinx 7 系列器件中具有时钟管理单元 CMT 时钟资源,xc7z020 芯片内部有 4 个 CMT,xc7z010 芯片内部有 2 个 CMT,为设备提供强大的系统时钟管理以及高速 I/O 通信的能力。时钟管理单元 CMT 的总体框图如下图所示。

             MMCM/PLL 的参考时钟输入可以是 IBUFG(CC)即具有时钟能力的 IO 输入、区域时钟 BUFR、全局时 钟 BUFGGT 收发器输出时钟、行时钟 BUFH 以及本地布线(不推荐使用本地布线来驱动时钟资源)。在 最多的情况下,MMCM/PLL 的参考时钟输入都是来自 IBUFG(CC)即具有时钟能力的 IO 输入,本实验也是 如此。MMCM/PLL 的输出可以驱动全局时钟 BUFG 和行时钟 BUFH 等等。BUFG 能够驱动整个器件内部的 PL 侧通用逻辑的所有时序单元的时钟端口。BUFG/BUFH/CMT 在一个时钟区域内的连接框图如下图所示。

            在本实验中,读者可以简单地理解为:外部时钟连接到具有时钟能力的输入引脚 CCIO(Clock-CapableInput),进入 MMCM/PLL,产生不同频率和不同相位的时钟信号,然后驱动全局时钟资源 BUFG。但是要进行更深入的 FPGA 开发,就必须理解器件的时钟资源架构。有关 Xilinx 时钟资源和 CMT 的更详细信息,读者后期可以花一些时间和精力去学习一下 Xilinx 官方的手册文档“UG472,7 Series FPGAs Clocking Resources User Guide”里的介绍。
            MMCM 和 PLL 的总体框图如下图所示。

             其中 MMCM 的功能是 PLL 的超集,其具有比 PLL 更强大的相移功能。MMCM 主要用于驱动器件逻辑(CLBDSPRAM 等)的时钟。PLL 主要用于为内存接口生成所需的时钟信号,但也具有与器件逻辑的连接,因此如果需要额外的功能,它们可以用作额外的时钟资源。

             PLL 由以下几部分组成:前置分频计数器(D 计数器)、相位-频率检测器(PFD,Phase-Frequency Detector)电路,电荷泵(Charge Pump)、环路滤波器(Loop Filter)、压控振荡器(VCO,Voltage Controlled Oscillator)、反馈乘法器计数器(M 计数器)和后置分频计数器(O1-O6 计数器)。

            在工作时,PFD 检测其参考频率(FREF)和反馈信号(Feedback)之间的相位差和频率差,控制电荷泵和环路滤波器将相位差转换为控制电压;VCO 根据不同的控制电压产生不同的震荡频率,从而影响 Feedback信号的相位和频率。在 FREF 和 Feedback 信号具有相同的相位和频率之后,就认为 PLL 处于锁相的状态。
    在反馈路径中插入M计数器会使VCO的震荡频率是FREF信号频率的M倍,FREF信号等于输入时钟(FIN)除以预缩放计数器(D)。参考频率用以下方程描述:FREF= FIN/D,VCO 输出频率为 FVCO= FIN*M/D,PLL的输出频率为 FOUT=(FIN*M)/(N*O)。
            Xilinx 提供了用于实现时钟功能的 IP 核 Clocking Wizard,该 IP 核能够根据用户的时钟需求自动配置器件内部的 CMT 及时钟资源,以实现用户的时钟需求。在这里我们主要讲解的是如何使用该 IP 核,有关该IP 核的更详细介绍,读者可以参阅 Xilinx 官方的手册文档“PG065,Clocking Wizard v6.0 LogiCORE IP Product Guide”。

            2、 实验任务

             本节实验任务是使用 Zynq 开发板输出 4 个不同时钟频率或相位的时钟,并在 Vivado 中进行仿真以验证结果,最后生成比特流文件并将下载到开发板上,使用示波器来测量时钟的频率。

            3、硬件设计

            本实验将 Clocking Wizard IP 核产生的 4 个时钟 100MHz 100MHz_180deg 50MHz 25MHz ,连接 到开发板的 J3 扩展口 IO 上(靠近 ATK-MODULE 接口),分别是第 29 31 33 35 号脚。扩展口原理图 如下图所示:

             本实验中,各端口信号的管脚分配如下表所示:

             对应的 XDC 约束语句如下所示:

    1. set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
    2. set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
    3. set_property -dict {PACKAGE_PIN B19 IOSTANDARD LVCMOS33} [get_ports clk_100m]
    4. set_property -dict {PACKAGE_PIN C20 IOSTANDARD LVCMOS33} [get_ports clk_100m_180deg]
    5. set_property -dict {PACKAGE_PIN P19 IOSTANDARD LVCMOS33} [get_ports clk_50m]
    6. set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports clk_25m]

            4、 程序设计

            我们首先创建一个空的工程,工程名为“ip_clk_wiz ”。接下来添加 PLL IP 核。在 Vivado 软件的左侧 “Flow Navigator ”栏中单击“ IP Catalog ”,“ IP Catalog ”按钮以及单击后弹出的“ IP Catalog ”窗口如下图所示。

            打开“IP Catalog” 窗口后,在搜索栏中输入 “clock” 关键字,可以看到 Vivado 已经自动查找出了与关键字匹配的 IP 核名称,如下图所示。

             我们双击“FPGA Features and Design”→“Clocking”下的“Clocking Wizard”,弹出“Customize IP” 窗口,如下图所示。

            接下来就是配置 IP 核的时钟参数。最上面的“Component Name”一栏设置该 IP 元件的名称,这里保 持默认即可。在第一个“Clocking Options”选项卡中,“Primitive”选项用于选择是使用 MMCM 还是 PLL 来输 出不同的时钟,对于我们的本次实验来说,MMCM PLL 都可以完成,这里我们可以保持默认选择 MMCM。 需要修改的是最下面的“Input Clock Information”一栏,把“Primary”时钟的输入频率修改为我们开发板的核心板上的晶振频率 50MHz,其他的设置保持默认即可,如下图所示。

             接下来切换至“Output Clocks”选项卡,在“Output Clock”选项卡中,勾选前 4 个时钟,并且将其“Output Freq(MHz)”分别设置为 1001005025,注意,第 2 100MHz 时钟的相移“Phase(degrees)”一栏要设置为 180。其他设置保持默认即可,如下图所示。、

             “Port Renaming”选项卡主要是对一些控制信号的重命名。这里我们只用到了锁定指示 locked 信号,其名称保持默认即可,如下图所示。

             “MMCM Setting”选项卡展示了对整个 MMCM/PLL 的最终配置参数,这些参数都是根据之前用户输入的时钟需求由 Vivado 来自动配置,Vivado 已经对参数进行了最优的配置,在绝大多数情况下都不需要用户对它们进行更改,也不建议更改,所以这一步保持默认即可,如下图所示。

             最后的“Summary”选项卡是对前面所有配置的一个总结,在这里我们直接点击“OK”按钮即可,如下图所示。

            接着就弹出了“Genarate Output Products”窗口,我们直接点击“Generate”即可,如下图所示。 

            之后我们就可以在“Design Run ”窗口的“ Out-of-Context Module Runs ”一栏中出现了该 IP 核对应的 run“ clk_wiz_0_synth_1”,其综合过程独立于顶层设计的综合,所以在我们可以看到其正在综合,如下图所示。

            在其Out-of-Context 综合的过程中,我们就可以开始编写代码了。首先打开 IP 核的例化模板,在“ Source ” 窗口中的“IP Sources ”选项卡中,依次用鼠标单击展开“ IP -“clk_wiz_0”- Instantitation Template ”,我 们可以看到“clk_wiz.veo ”文件,它是由 IP 核自动生成的只读的 verilog 例化模板文件,双击就可以打开它, 在例化时钟 IP 核模块的时钟,可以直接从这里拷贝,如下图所示。

             我们接下来创建一个 verilog 源文件,其名称为 ip_clk_wiz.v,代码如下:

    1. module ip_clk_wiz(
    2. input sys_clk , //系统时钟
    3. input sys_rst_n , //系统复位,低电平有效
    4. //输出时钟
    5. output clk_100m , //100Mhz时钟频率
    6. output clk_100m_180deg, //100Mhz时钟频率,相位偏移180度
    7. output clk_50m , //50Mhz时钟频率
    8. output clk_25m //25Mhz时钟频率
    9. );
    10. //wire define
    11. wire locked;
    12. //*****************************************************
    13. //** main code
    14. //*****************************************************
    15. //MMCM/PLL IP核的例化
    16. clk_wiz_0 clk_wiz_0
    17. (
    18. // Clock out ports
    19. .clk_out1_100m (clk_100m), // output clk_out1_100m
    20. .clk_out2_100m_180 (clk_100m_180deg), // output clk_out2_100m_180
    21. .clk_out3_50m (clk_50m), // output clk_out3_50m
    22. .clk_out4_25m (clk_25m), // output clk_out4_25m
    23. // Status and control signals
    24. .reset (~sys_rst_n), // input reset
    25. .locked (locked), // output locked
    26. // Clock in ports
    27. .clk_in1 (sys_clk) // input clk_in1
    28. );
    29. endmodule

             程序中例化了 clk_wiz_0,把 FPGA 的系统时钟 50Mhz 连接到 clk_wiz_0 clk_in1,系统复位信号连接到 clk_wiz_0 reset,由于时钟 IP 核默认是高电平复位,而输入的系统复位信号 sys_rst_n 是低电平复位,因此要对系统复位信号进行取反。clk_wiz_0 输出的 4 个时钟信号直接连接到顶层端口的四个时钟输出信号。

            我们接下来先对代码进行仿真,TestBench 代码如下:
    1. `timescale 1ns / 1ps
    2. module tb_ip_clk_wiz();
    3. reg sys_clk;
    4. reg sys_rst_n;
    5. wire clk_100m;
    6. wire clk_100m_180deg;
    7. wire clk_50m;
    8. wire clk_25m;
    9. always #10 sys_clk = ~sys_clk;
    10. initial begin
    11. sys_clk = 1'b0;
    12. sys_rst_n = 1'b0;
    13. #200
    14. sys_rst_n = 1'b1;
    15. end
    16. ip_clk_wiz u_ip_clk_wiz(
    17. .sys_clk (sys_clk ),
    18. .sys_rst_n (sys_rst_n ),
    19. .clk_100m (clk_100m ),
    20. .clk_100m_180deg (clk_100m_180deg),
    21. .clk_50m (clk_50m ),
    22. .clk_25m (clk_25m )
    23. );
    24. endmodule

            对模块进行仿真的方法这里不再赘述,仿真后得到的波形如下图所示:

             由上图可知,locked 信号拉高之后,锁相环开始输出 4 个稳定的时钟。clk_100m clk_100m_180deg 周期都为 10ns,即时钟频率都为 100Mhz,但两个时钟相位偏移 180 度,所以这两个时钟刚好反相;clk_50m 周期为 20ns,时钟频率为 50Mhzclk_25m 周期为 40ns,时钟频率为 25Mhz。也就是说,我们创建的锁相环从仿真结果上来看是正确的。

            5、 下载验证

            编译工程并生成比特流.bit 文件后,此时把将下载器一端连接电脑,另一端与开发板上的 JTAG 下载口连接,连接电源线,并打开开发板的电源开关。
    点击 Vivado 左侧“ Flow Navigator ”窗口最下面的“ Open Hardware Manager ”,如果此时 Vivado 软件识别到下载器,则点击“Hardware” 窗口中“ Progam Device ”下载程序,在弹出的界面中选择“ Program ”下载程序。
            程序下载完成后,接下来我们使用示波器测量开发板 J3 扩展口的第 29 31 33 35 号脚。示波器测 试依次为 B19(100MHz )、C20( 100MHz_180 )、P19( 50MHz )和 N18( 25MHz )。如下图所示:

             此时在示波器上就可以观察到时钟的波形图。下图为使用示波器测量扩展口第 35 号脚(N18)所显示的波形。

             由上图可知,示波器测量出的时钟频率为 25Mhz,跟仿真结果是一样的,其它三个扩展口输出的时钟大家可以测试一下,这里不再贴出其它扩展口的波形图。、

    ip_clk_wiz

  • 相关阅读:
    2023-2028年中国六氟化钨市场发展态势及投资建议报告
    代码随想录算法训练营 动态规划part14
    复现一次循环和两次循环
    OpenCV Series : Slope + Radian + Degree
    使用 Linux 15 年后,我重新回到 Windows:感觉非常糟糕
    静态HTML CSS网站制作成品 简单的学生网页作业代码【带视频演示】
    方程组线性化方法和牛顿迭代法基础
    Springboot简单功能示例-6 使用加密数据源并配置日志
    nnunetv2训练报错 ValueError: mmap length is greater than file size
    医美健康这类在医疗行业的推广要怎么做?
  • 原文地址:https://blog.csdn.net/weixin_52804129/article/details/126090963