您现在的位置是:首页 >技术教程 >vivado中的FPGA时钟管理单元PLL学习记录网站首页技术教程

vivado中的FPGA时钟管理单元PLL学习记录

LessIsMore/ 2024-06-19 12:01:02
简介vivado中的FPGA时钟管理单元PLL学习记录

CMT简介

FPGA中时钟管理模块(CMT)包括PLL和MMCM,用于将时钟倍频(比如输入时钟25M,我们要产生50M时钟)、分频(在不影响系统功能的前提下,较低的工作时钟,能够降低系统功耗)、改变相位偏移或占空比等。
当需要上板时,由于板上晶振时钟固定,所以其他频率的时钟产生就要用到PLL或者MMCM。两者类似,MMCM可以完成PLL的所有功能外加一些高级功能。

其中具体的一些时钟域,BUFG等时钟资源介绍,以及FPGA中的PLL和MMCM介绍可参考时钟IP核(MMCM PLL)、RAM 和 FIFO 实验-哔哩哔哩(待学)

这里只介绍PLL锁相环。

一、PLL IP的使用

1、ip调用

如果只是调用ip的话,知道怎样使用即可
vivado中的调用及上板测试可以参考:
FPGA实战(五)时钟IP核(MMCM PLL)

基本就是调用ip,然后设置一个输入时钟一个输出时钟;注意其中有一个locked信号,当locked信号拉高的时候代表锁相环输出信号已经稳定
locked信号常被用于复位信号

2、生成的频率限制

另外,时钟管理IP核并不能产生任意频率的时钟信号。 产生的时钟信号与输入之间仅能是M/N的关系,其中M、N必须是整数(在原理部分会介绍)。

二、PLL实现原理

PLL组成:
在这里插入图片描述

锁相环是一种以消除频率误差为目的的反馈控制电路。原理是利用相位误差消除频率误差,所以当电路平衡时,会有剩余相位误差,但频率误差为0
具体推导:
在这里插入图片描述
也可以参考一文弄懂锁相环(PLL)的工作原理及应用
终止最终达到的效果就是输入输出有相位差(VCO需要一定的电压驱动它到正确的频率,所以一定有相差)但是频率相等,就如下图所示。
在这里插入图片描述

那对于分频是怎样实现的呢?
如下图,插入分频模块即可,这样就可以实现输出/输出=N/M, N M为整数。
在这里插入图片描述
图片来自锁相环的工作原理

三、使用过程中的问题

我只使用锁相环对板子就行了简单的分频,基于PYNQ-Z2板子,从125M到50M,写了一个灯亮灭的程序,等locked信号稳定后才计数。
程序如下:

module led(
(* MARK_DEBUG="true" *)input sys_clk,
input clk_restn,
output reg[3:0] led
    );
    reg[31:0] timer_cnt;
    (* MARK_DEBUG="true" *)wire clk;
    (* MARK_DEBUG="true" *)wire locked_out;
  /*  
    initial begin
       led<=0;
       timer_cnt<=0;
    end
    */
   clk_wiz_0 clk_wiz
   (
    // Clock out ports
    .clk_out1(clk),     // output clk_out1
    // Status and control signals
    .reset(clk_restn), // input resetn
   // Clock in ports
    .clk_in1(sys_clk),      // input clk_in1
    .locked(locked_out));       // output locked

      always@(posedge clk) begin
        if((locked_out==1) && (timer_cnt>=32'd49999999))begin
        //if(timer_cnt>=32'd4999)begin
            led<=~led;
            timer_cnt<=0;
        end
        else if(locked_out==1)begin
            led<=led;
            timer_cnt<=timer_cnt+1;
        end
        else begin
            led<=led;
            timer_cnt<=0;
        end
    end
endmodule

我设置的是1s亮1s灭,但是实际上板出现的问题是1s亮2s灭或者2s灭1s亮,肉眼可见的有问题。
上板抓信号发现locked信号拉高之后还会拉低,不是一直拉高,这就导致拉低时计数清零,拉高又重新计数,时长就变长了。
最后发现问题是板子有问题,换了板子就正确了。应该是原来板子晶振有问题,会周期性不稳定,导致PLL的locked信号周期性拉低拉高。

程序注意事项

上述程序也有一些问题,这里记录一下:
1、initial块不要写在要综合的代码中,因为它不可综合,用复位来设置初值
2、clk是分频出来的,最好后面模块也给复位,不然如果PLL出错后面clk控制的就都没办法控制了
3、locked_out==1这样写是没问题的,如果板子时钟没问题就是拉高之后不会拉低了。也确实要等始终稳定locked_out=1再进行操作。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。