PLL(Phase Locked Loop): 为锁相回路或锁相环,用来统一整合时脉讯号,使内存能正确的存取资料。PLL用于振荡器中的反馈技术。 许多电子设备要正常工作,通常需要外部的输入信号与内部的振荡信号同步,利 用锁相环路就可以实现这个目的。
功能:VCO有一个初始的振荡频率,通过设置两个DIV的分频系数可以达到PLL分频或倍频的效果。
FPGA的PLL IP核配置步骤如下
在IP核中查找pll,选择
FINISH结束PLL的设置。
50HZ分频为25,75,100;
控制led程序;此段程序为顶层;
module PLL_LED( Clk, Rst_n, LED ); input Clk; input Rst_n; output [3:0]LED; wire c0; //25M wire c1; //75M wire c2; //100M wire locked; pll pll( .rst(~Rst_n), .refclk(Clk), .outclk_0(c0), .outclk_1(c1), .outclk_2(c2), .locked(locked) ); counter #( .CNT_MAX(25'd24_999_999) ) counter0( .Clk(c0), .Rst_n(Rst_n), .led(LED[0]) ); counter #( .CNT_MAX(25'd24_999_999) ) counter1( .Clk(c1), .Rst_n(Rst_n), .led(LED[1]) ); counter #( .CNT_MAX(25'd24_999_999) ) counter2( .Clk(c2), .Rst_n(Rst_n), .led(LED[2]) ); counter #( .CNT_MAX(25'd24_999_999) ) counter3( .Clk(Clk), .Rst_n(Rst_n), .led(LED[3]) ); endmodule 计数器程序 module counter( Clk, Rst_n, led ); input Clk; //系统时钟 input Rst_n; //全局复位,低电平复位 output reg led; //led输出 reg [24:0]cnt; //定义计数器寄存器 parameter CNT_MAX = 25'd24_999_999; //计数器计数进程 always@(posedge Clk or negedge Rst_n) if(Rst_n == 1'b0) cnt <= 25'd0; else if(cnt == CNT_MAX) cnt <= 25'd0; else cnt <= cnt + 1'b1; //led输出控制进程 always@(posedge Clk or negedge Rst_n) if(Rst_n == 1'b0) led <= 1'b1; else if(cnt == CNT_MAX) led <= ~led; else led <= led; endmodule
编写正确的testbench
`timescale 1ns/1ps `define clk_period 20 module pll_tb; //source define reg areset; reg Clk; //probe define wire c0; wire c1; wire c2; wire locked; //instant user module pll pll( .rst(areset), .refclk(Clk), .outclk_0(c0), .outclk_1(c1), .outclk_2(c2), .locked(locked) ); //generater clock initial Clk = 1; always #(`clk_period/2)Clk = ~Clk; initial begin areset = 1'b1; #(`clk_period * 100 + 1); areset = 1'b0; #(`clk_period * 200 + 1); $stop; end endmodule
图中可以看出PLL设置成功;
观察led程序
`timescale 1ns/1ps `define clk_period 20 module PLL_LED_tb; //source define reg Clk; reg Rst_n; //probe define wire [3:0]LED; //instant user module PLL_LED PLL_LED( .Clk(Clk), .Rst_n(Rst_n), .LED(LED) ); defparam PLL_LED.counter0.CNT_MAX = 24; defparam PLL_LED.counter1.CNT_MAX = 24; defparam PLL_LED.counter2.CNT_MAX = 24; defparam PLL_LED.counter3.CNT_MAX = 24; //generater clock initial Clk = 1; always #(`clk_period/2)Clk = ~Clk; initial begin Rst_n = 1'b0; #(`clk_period * 20 + 1); Rst_n = 1'b1; #(`clk_period * 2000); $stop; end endmodule
分配引脚
锁相环相关知识可参考博客:
具体讲解: