实现方法:
构建一个带有长延迟的闭合反相器可以获得一个自激振荡的输出信号。如图1所示。
产生自激振荡需要满足两个条件,一个是要有足够长的延迟链,另一个是要有反相器逻辑。足够长的延迟链可以通过FPGA的内建延迟逻辑或者非门链条组成,对于Altera公司的FPGA而言,内部延迟单元为LCELL,将若干LCELL串联即可组成延迟链。其Verilog HDL描述为;
wire [WIDTH:0] gcBufChain /*synthesis syn_keep=1*/;
assign gcBufChain[0] = ~gcBufChain[WIDTH];
assign dout = gcBufChain[0];
genvar j;
generate
for (j = 0; j < WIDTH; j = j + 1)
begin: dc_loop
LCELL AlteraBuf (.in(gcBufChain[j]), .out(gcBufChain[j+1]));
end
endgenerate
注意,为了防止编译器对延迟链的优化,必须在定义处注明synthesis syn_keep=1, 否则编译器会按照逻辑将其优化为直连线,无法起到延迟的效果。链的长度WIDTH需要指明,WIDTH设置过大,会导致延迟链过长,输出信号可能不稳定(Skew大),过小则会导致无法起振,根据经验,可以先取一较大值,保证起振。之后减小,获得相应的时钟频率。
实验采用Altera DE4平台,器件为Stratix IV EP4SGX530KH40C2,WIDTH与自激振荡频率对应值如下:
LCELLs
TimeQuest估算延迟链延迟
实际延迟
Freq
32
13.727
18.9833
26.34 Mhz
64
26.908
37.147
13.46 Mhz
128
53.498
73.148
6.84 Mhz
256
107.785
144.550
3.34 Mhz
通过调节延迟链的LCELL个数可以对输出频率进行调节。虽然可以通过时序逻辑分析软件对延迟进行预估计,但准确度并不高,因此,建议采用实测调整。
上述时钟产生的方法可以获得较低频率的时钟信号,然而大多数FPGA设计需要更高的时钟,为了获得高频稳定的时钟源,需要借助FPGA内部的PLL对时钟信号进行琐相跟踪。通过MegaCore向导可以订制一个ALTPLL锁相环,在输入时钟信号频率上填写实测的自激振荡频率,在输出频率上可以自行计算。本实验对128LCELLs产生的6.84Mhz信号进行倍分频,获得512Mhz的时钟。由于高频时钟不容易测量,因此将此时钟用来更新计数器,计数器实现64分频。由于PLL需要从外部时钟输入PIN直接引入,因此需要将原先的输出dout与时钟输入端dclk在硬件上连接。从而将其作为输入时钟。
// Quartus II Verilog Template
// Unsigned Adder
module delay
#(parameter WIDTH = 128)
(
output dout,
input dclk,
output dpllout,
output dpllp,
output lock
);
wire [WIDTH:0] gcBufChain /*synthesis syn_keep=1*/;
reg [5:0] counter;
assign gcBufChain[0] = ~gcBufChain[WIDTH];
assign dout = gcBufChain[0];
genvar j;
generate
for (j = 0; j < WIDTH; j = j + 1)
begin: dc_loop
LCELL AlteraBuf (.in(gcBufChain[j]), .out(gcBufChain[j+1]));
end
endgenerate
always @(posedge dpllout)
begin
counter <= counter + 1;
end
PLL pllclk(.inclk0(dclk), .c0(dpllout), .locked(lock));
assign dpllp = counter[5];
endmodule
可以从示波器上观测到稳定的8Mhz的方波信号,同时也可观察到PLL锁定指示高电平(有效)。
总结:当外部晶振无法正常工作时,可以尝试采用通过组合逻辑延迟产生的自激振荡作为时钟。然而要注意的是,某些低端器件,如Cyclone II,输出的信号可能稳定性不高,Skew较大,高端器件性能较为稳定。