一、前言
很多FPGA的板载时钟(板载晶振提供)不是普通的单端时钟信号,而是差分时钟信号,比如我正在使用的genesys2开发板。
此时我们就不能像使用普通时钟信号一样直接使用差分时钟信号,而是需要使用IBUFGDS
(xilinx 原语)或者PLL
将差分信号转换成单端信号。
PLL
之所以也可以用来将差分时钟转换成单端时钟,是因为我们可以设置其输入时钟的source为Differential clock capable pin
,也即告诉PLL
输入时钟差分时钟。其实PLL
也是在自己内部调用IBUFGDS
来实现信号转换的。如果你只是想单纯的转换成单端时钟,那么直接设置输出频率等于输入频率即可,否则你也可以直接实现分频操作。
下面就以一个对差分时钟进行分频的例子来验证上面所说的话。
二、差分时钟分频方法
由以上叙述我们不难发现,对差分时钟进行分频有两种方式,分别是:
- 第一种方式是先使用
IBUFGDS
将差分时钟转换成单端时钟,然后送入PLL
进行分频。此时PLL
的输入时钟的source选择单端时钟即可。 - 第二种方式是直接使用
PLL
同时完成差分信号到单端时钟的转换和分频。
三、程序设计
1、方式一
module test(
input clk_p,
input clk_n,
output led
);
wire clk;
wire locked;
IBUFGDS clk_inst (
.O(clk),
.I(clk_p),
.IB(clk_n)
);
clk_wiz_0 diff_2_single
(
.clk_out1(clk_out1),
.reset(1'b0),
.locked(locked),
.clk_in1(clk)
);
reg [3:0] count = 0;
assign led = count[3];
always @ (posedge(clk_out1))
begin
if(locked)
count <= count + 1;
end
endmodule
2、方式二
module test(
input clk_p,
input clk_n,
output led
);
wire locked;
clk_wiz_0 diff_2_single
(
.clk_out1(clk_out1),
.reset(1'b0),
.locked(locked),
.clk_in1_p(clk_p),
.clk_in1_n(clk_n)
);
reg [3:0] count = 0;
assign led = count[3];
always @ (posedge(clk_out1))
begin
if(locked)
count <= count + 1;
end
endmodule