PFGA PLL(锁相环)
将较低频率的片外芯片倍频得到较高的频率时钟信号。
锁相环的一大作用就是对输入时钟进行分频和倍频,以得到更高或更低频率的时钟信号,以供逻辑电路使用。还可以对同一PLL生成的多个时钟的相位进行控制,以保证两个时钟域的逻辑工作时有确定的时间差。(两个或多个时钟的上升沿有时间差)
PLL内部电路
N:预分频单元,产生FREF参考时钟传输到频率检测电路PFD,PFD产生的信号传输到ChargePump产生电压信号,控制VCO压控振荡器产生时钟信号FVCO经过M倍频传回到PFD中。环路不断调整达到动态平衡。
PLL仿真
使用IP核生成PLL,生成25M、75M、100MHZ时钟信号
`timescale 1ns/1ns
`define Clk_period 20
module pll_tb;
reg areset;
reg Clk;
wire c0;
wire c1;
wire c2;
wire locked;
pll pll0(
.areset(areset), //复位信号 高电平处于复位状态
.inclk0(Clk), //时钟信号
.c0(c0),
.c1(c1),
.c2(c2),
.locked(locked) //稳定信号 若为1则动态平衡完成可以输出稳定时钟
);
initial Clk =1;
always #(`Clk_period/2) Clk =~Clk;
initial begin
areset = 1;
#(`Clk_period*100+1);
areset = 0;
#(`Clk_period*200+1);
$stop;
end
endmodule
PLL控制4路LED
PLL控制4路LED以不同频率亮灭
count模块
module count(
Clk,
Rst_n,
high
);
input Clk;
input Rst_n;
output reg high;
reg [24:0]count;
parameter count_max = 25'd24_999_999; //50MHZ计算为500ms
always @(posedge Clk or negedge Rst_n) //计数
if(!Rst_n)
count <= 25'b0;
else if(count == count_max)
count <= 25'b0;
else count <= count + 1'b1;
always @(posedge Clk or negedge Rst_n) //计数满输出反转
if(!Rst_n)
high <= 1'b0;
else if(count == count_max)
high <= ~high;
else high <= high;
endmodule
count模块仿真
`timescale 1ns/1ns
`define Clk_period 20
module count_tb;
reg Clk;
reg Rst_n;
wire back_high;
count #(
.count_max (25'd24_999)
)
count0(
.Clk(Clk),
.Rst_n(Rst_n),
.high(back_high)
);
initial Clk = 1;
always #(`Clk_period/2) Clk = ~Clk;
initial begin
Rst_n = 0;
#(`Clk_period*5);
Rst_n = 1 ;
#(`Clk_period*10000);
$stop;
end
endmodule
0.5ms反转一次
pll_control模块
将不同频率的时钟发送到count模块中。
module pll_control(
Clk,
Rst_n,
Led
);
input Clk;
input Rst_n;
output [3:0]Led;
reg areset;
wire c0;
wire c1;
wire c2;
wire locked;
pll pll0(
.areset(~Rst_n), //复位信号 高电平处于复位状态
.inclk0(Clk),
.c0(c0),
.c1(c1),
.c2(c2),
.locked(locked) //稳定信号 若为1则动态平衡完成可以输出稳定时钟
);
count #( .count_max(25'd24_999_99)
)
count0(
.Clk(Clk),
.Rst_n(Rst_n),
.high(Led[0])
);
count #( .count_max(25'd24_999_99)
)
count1(
.Clk(c0),
.Rst_n(Rst_n),
.high(Led[1])
);
count #( .count_max(25'd24_999_99)
)
count2(
.Clk(c1),
.Rst_n(Rst_n),
.high(Led[2])
);
count #( .count_max(25'd24_999_99)
)
count3(
.Clk(c2),
.Rst_n(Rst_n),
.high(Led[3])
);
endmodule
pll_control仿真
`timescale 1ns/1ns
`define Clk_period 20
module pll_control_tb;
reg Clk;
reg Rst_n;
wire [3:0]Led;
pll_control pll_control0(
.Clk(Clk),
.Rst_n(Rst_n),
.Led(Led)
);
defparam pll_control0.count0.count_max = 249;
defparam pll_control0.count1.count_max = 249;
defparam pll_control0.count2.count_max = 249;
defparam pll_control0.count3.count_max = 249;
initial Clk =1;
always #(`Clk_period/2) Clk =~Clk;
initial begin
Rst_n=0;
#(`Clk_period*5);
Rst_n=1;
#(`Clk_period*1000);
$stop;
end
endmodule
4路led以不同时间反转。驱动时钟频率越高,闪烁速度越快。