在FPGA系统设计中,几乎所有地方都可以用到PLL,也有些地方是非用到PLL不可。
在某些对系统时钟频率没有固定要求的系统中,外部晶振输入的时钟可以直接作为逻辑驱动时钟,也可以通过PLL将该时钟进行降频,以得到较低的工作时钟,在不影响系统功能实现的前提下降低系统功耗。
另外一些应用,则必须在指定频率的时钟信号下才能正常工作,常见于通信协议类应用,如以太网、USB、PCIE等等,在这些应用中,必须使用指定频率的时钟信号,如果没有刚好满足条件的外部时钟源,则必须通过片内PLL生成相应的时钟信号来进行驱动。在某些实时性要求较高的应用中,如数字信号处理,图像处理等等,提高系统工作时钟能够提升系统的性能,这一类应用中,也往往使用PLL进行倍频和分频,以得到较高频率的时钟,用以提升系统整体性能。
再有一个常见的应用就是生成两路频率相同,相位不同的时钟供SDRAM控制器和SDRAM芯片使用。根据SDRAM芯片的工作原理,SDRAM控制器的工作时钟和SDRAM芯片的工作时钟需要保持180°的相位差才能保证正确的读写数据。所以这里就可以使用PLL的相位控制功能来产生两路相位不同的时钟,以分别供控制器和SDRAM芯片使用。
下面我们看一下实用PLL设置不同频率控制led闪烁例程:
//Top.v
modulePLL_LED(
Clk,
Rst_n,
LED
);
inputClk;
inputRst_n;
output[3:0]LED;
wirec0; //25M
wirec1; //75M
wirec2; //100M
wirelocked;
pllpll(
.areset(~Rst_n),
.inclk0(Clk),
.c0(c0),
.c1(c1),
.c2(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
modulecounter(Clk,Rst_n,led);
inputClk; //系统时钟
inputRst_n; //全局复位,低电平复位
outputregled; //led输出
reg[24:0]cnt; //定义计数器寄存器
parameterCNT_MAX=25'd24_999_999;
//计数器计数进程
always@(posedgeClkornegedgeRst_n)
if(Rst_n==1'b0)
cnt<=25'd0;
elseif(cnt==CNT_MAX)
cnt<=25'd0;
else
cnt<=cnt+1'b1;
//led输出控制进程
always@(posedgeClkornegedgeRst_n)
if(Rst_n==1'b0)
led<=1'b1;
elseif(cnt==CNT_MAX)
led<=~led;
else
led<=led;
endmodule
//`tb
`timescale1ns/1ps
`defineclk_period20
modulePLL_LED_tb;
regClk;
regRst_n;
wire[3:0]LED;
PLL_LEDPLL_LED(
.Clk(Clk),
.Rst_n(Rst_n),
.LED(LED)
);
///////////////////
defparamPLL_LED.counter0.CNT_MAX=24;
defparamPLL_LED.counter1.CNT_MAX=24;
defparamPLL_LED.counter2.CNT_MAX=24;
defparamPLL_LED.counter3.CNT_MAX=24;
initialClk=1;
always#(`clk_period/2)Clk=~Clk;
initialbegin
Rst_n=1'b0;
#(`clk_period*20+1);
Rst_n=1'b1;
#(`clk_period*2000);
$stop;
end
endmodule
仿真波形图: