前言

本文摘自《FPGA之道》,作者对于DCM以及PLL的理解算得上是很深入了,平时我们只知道用FPGA提供的一些时钟资源,并没理解为什么的问题?今天我们通过看DCM和PLL的原理来更深入理解类似的时钟管理资源,由于书本年代问题,所以,作者只提了DCM和PLL,其实现在的时钟管理资源已经出现了MMCM等,但万变不离其宗,只是更加强大了而已。

DCM与PLL

在与、或、非门以及触发器等基本数字逻辑单元组成的时序逻辑电路世界里,归根到底,我们是利用时钟来玩转数据,而对于时钟信号本身,我们除了能对其进行整数倍分频以及一些简单的门控处理外,几乎无能为力。但是,时钟信号做为时序逻辑的“心跳”,其重要性是显而易见的,因此,为了弥补数字逻辑基本门电路对时钟信号控制不足的软肋,FPGA中通常都会集成一些PLL或者DCM资源,从而实现对时钟信号更为全面、灵活的掌控。
关于PLL和DCM的基本原理,可以参考【知己知彼篇->FPGA内部资源介绍->时钟处理单元】章节,而本章节将主要针对这两者在FPGA设计中的使用方法来进行详细讨论。

PLL模块基本端口简介

时钟输入、输出端口

时钟输入、输出端口是PLL中最基本的两类端口,分别对应CLKIN和CLKOUT。一个锁相环可以有不止一个CLKIN和多个CLKOUT,不过请注意,同一时刻,只能有一个CLKIN端口被使能,但是可以有多个CLKOUT端口都有时钟信号输出。

关于CLKIN端口,它对接入的时钟信号是有一定要求的:
首先,接入的时钟信号一定要是连续时钟信号,否则PLL会不断的失锁,甚至根本无法到达锁定状态,而当这种情况出现的话,PLL的输出信号的波形也就无法得到保证。
其次,对接入时钟信号的频率是有一定要求的,因为PLL并不是对任意频率的时钟输入都能做到锁定的。这个不同的厂商、不同系列芯片之间的要求可能会有所不同,例如,Xilinx Virtex5 LX110系列FPGA芯片中的PLL就要求CLKIN的范围在19MHz~645MHz之间。
第三,对接入时钟信号的占空比也有一定要求,一般来说,接入时钟信号的占空比越接近于50%越好,不过要求也不是这么严格,因为PLL一般都有一定的容忍度,例如有的PLL在输入时钟信号的占空比在30%~70%之间都能够完成锁定。因此,如果需要操作的时钟信号的占空比和50%偏差比较大,那么使用PLL前需要根据器件手册等来确定是否可以完成锁定。
最后,对于一个PLL来说,它可以处理内部逻辑产生的时钟信号,也可以直接处理外部IO管脚直接引入进来的单端或差分时钟信号,因此需要根据实际情况来完成正确的配置或代码描述。

关于CLKOUT端口,它输出的时钟信号也是有一定限制的:
首先,从PLL的原理结构框图来看,它应该只有一个输出端口,可事实上FPGA内部的PLL模块往往能提供多个输出端口,它是怎么做到的呢?其实很简单,FPGA内部PLL的主体部分也只能输出一个时钟信号,我们可以称其为CLKMID,只不过这个时钟信号并不是直接输出给PLL外部逻辑使用的,而是扇出多路,每路都有一个分频器和移相器,这样就可以产生多个CLKOUT供后续使用。
其次,CLKMID的频率是有一定限制的,否则PLL也会出现不能锁定的情况。这个不同的厂商、不同系列芯片之间的要求可能会有所不同,例如,Xilinx Virtex5 LX110系列FPGA芯片中的PLL就要求CLKMID的范围在400MHz~1000MHz之间。
第三,CLKMID之后各个扇出路径上的分频系数和移相系数都是有一定限制的,因此导致各个CLKOUT之间还是有着一定相关性的。所以如果要实现两个完全不相关的CLKOUT,一般需要使用两个PLL。
第四,由于FPGA内部的时钟树资源或者布线资源等等的承受能力有限,所以对CLKOUT上时钟信号的频率也是有一定要求的,例如,Xilinx Virtex5 LX110系列FPGA芯片中的PLL就要求CLKOUT的范围在3.125MHz~600MHz之间。
最后,CLKOUT的时钟移相精度也是有一定限制的。例如Xilinx Virtex5 LX110系列FPGA芯片中的PLL的VCO能够以45°间隔输出8个相移不同的同频时钟,相当于CLKMID扇出部分的移相器,由于分频计数器本身也可以按照计数器的计数总值来调整其输出时钟的占空比和相位,因此,若分频系数为2,那么CLKOUT能够以22.5°的间隔来移相,若分频系数为3,那么CLKOUT能够以15°的间隔来移相,等等,依此类推。

时钟反馈端口

时钟反馈端口包括两部分,CLKFBOUT和CLKFBIN,只有将这两个端口连接起来,才能建立PLL中实现锁定的反馈回路。而反馈回路又直接决定了CLKMID的相位(频率的事情PLL内部已经搞定了,我们无需在这里画蛇添足),因此,通常反馈网络的搭建又有三种模式:外部反馈、内部经由全局时钟树反馈、内部直连反馈。
默认情况下,PLL的反馈网络模式为内部经由全局时钟树反馈,这是因为CLKOUT如果是给内部时序逻辑使用,那么它是要先上全局时钟树的,而为了抵消全局时钟树的群延迟,保证CLKOUT到达各个触发器后的相位也能够跟输入CLKIN保持一致,就必须在反馈网络中也加入一个全局时钟树的延迟。如下图所示为Xilinx公司锁相环的经由全局时钟树反馈网路模式:
FPGA之道(49)DCM与PLL_级联
上图中,由PLL的特性可知,A与B的相位会被锁定为一致;若设置CLKOUT0的相移为0°,那么C与D的相位也一致;由于同样经过了一个BUFG的延迟,则E和B的相位也一致。因此,A与E的相位一致,所以CLKIN完全和CLKOUT的相位一致,保证了0相移。
不过上述反馈模式会消耗一个全局时钟树的资源,因此,如果后续时序逻辑并不关心CLKOUT的相位,那么请选则内部直连反馈模式。
如果CLKOUT是给FPGA片外使用,又或者出于什么别的目的或用途,我们也可以通过FPGA芯片外部路径来完成反馈网络的连接,即外部反馈模式。注意,此时需要板级的电路支持。
最后,反馈网络的搭建形式是非常灵活的,上面介绍的仅仅是三种基本方式,在使用中,需要根据实际需求来设计合适的反馈网络。

PLL锁定指示端口

PLL中的CLKMID针对CLKIN完成一次锁定是需要一定时间的,当然了,只要CLKIN满足PLL的输入要求,这个时间会很短。但是,CLKOUT不稳定的时期总是或长或短的存在着,这很有可能会对CLKOUT所掌控的时钟域产生不好的影响。因此,通常情况下,必须在CLKOUT达到稳定后对其掌控的时钟域进行复位操作。而复位操作需要关心的问题也就是CLKOUT是否达到了稳定,这个可以通过PLL给出的LOCKED端口来进行判断。
对于LOCKED端口,当FPGA芯片上电后或者PLL被复位后,将会处于无效状态,一般输出逻辑0;当PLL完成锁定后,将会处于有效状态,一般输出逻辑1。

PLL复位端口

有些情况下,PLL一旦失锁是无法自行恢复的,因此,重置功能是必须的。当PLL遇到一些特殊情况或需求,例如输入时钟频率大范围跳动或者PLL配置更改时,可以通过PLL提供的RESET端口来主动对其进行复位操作,以保证PLL的输出能够尽快达到我们的预期。不过请注意,复位之后的CLKOUT必然会出现一段不稳定期,这时就需要用到上面刚刚介绍的LOCKED端口。

PLL配置端口

对于PLL模块,我们只能通过HDL语言来调用,而无法通过HDL语言来创造,因为PLL所做的事情,已经超出了数字逻辑的理论范围。而当我们使用PLL的时候,一般都是先通过软件工具完成其的具体配置后,才能生成可供HDL调用的、功能确定的PLL模块。可是有时候固定功能的PLL不能满足实际的需求,因此,有些PLL还提供了一系列配置端口,用来动态地修改PLL内部的一些参数寄存器,从而完成对PLL的实时重新配置。

DCM模块基本端口简介

时钟输入端口

时钟输入端口是整个DCM模块中最重要、最基本的输入。一般来说,一个DCM只有一个时钟输入端口,即CLKIN端口,它对接入的时钟信号是有一定要求的:
首先,接入的时钟信号一定要是连续时钟信号,否则DCM会不断的失锁,甚至根本无法到达锁定状态,而当这种情况出现的话,DCM的输出信号的波形也就无法得到保证。
其次,对接入时钟信号的频率是有一定要求的,因为DCM并不是对任意频率的时钟输入都能做到锁定的。相对于PLL,DCM对接入时钟的频率要求更为复杂、苛刻,这点将在介绍时钟输出端口的时候一并介绍。
第三,对接入时钟信号的占空比也有一定要求,一般来说,接入时钟信号的占空比越接近于50%越好,不过要求也不是这么严格,因为DCM一般也有一定的容忍度,例如有的DCM在输入时钟信号的占空比在40%~60%之间都能够完成锁定。因此,如果需要操作的时钟信号的占空比和50%偏差比较大,那么使用DCM前需要根据器件手册等来确定是否可以完成锁定。
最后,对于一个DCM来说,它可以处理内部逻辑产生的时钟信号,也可以直接处理外部IO管脚直接引入进来的单端或差分时钟信号,因此需要根据实际情况来完成正确的配置或代码描述。

时钟输出端口
DCM中的时钟属性
在介绍DCM的时钟输出端口之前,我们需要先来了解一下DCM中的时钟属性。
DCM中的时钟信号具有两大属性:DLL_FREQUENCY_MODE、DFS_FREQUENCY_MODE,它们的取值范围均为二值集合{LOW,HIGH}。由于Xilinx公司并没有公布DCM的一些技术细节,因此我们只能猜测DLL_FREQUENCY_MODE属性旨在保证输出时钟与输入时钟之间具有可控的相位关系;而DFS_FREQUENCY_MODE属性旨在保证输出时钟与输入时钟之间具有可控的倍数关系。在接下来的讨论中,我们可以看到,这两个属性对于DCM的使用至关重要,稍有不慎,便会产生问题。

时钟输出端口分类

DCM共有两大类时钟输出端口,它们分别与DCM中的两大时钟属性对应。
对应DLL_FREQUENCY_MODE的时钟端口介绍如下:
CLK0:CLKIN的零相移输出;
CLK90:CLKIN的90°相移输出;
CLK180:CLKIN的180°相移输出;
CLK270:CLKIN的270°相移输出;
CLKDV:CLKIN的零相移分频输出,分频系数在有限个大于1.5的数据集合内可选,该数据集合为整数或者小数部分为0.5的实数集合;
CLK2X:CLKIN的两倍频零相移输出;
CLK2X180:CLKIN的两倍频180°相移输出;
CLKFX:CLKIN的F倍频零相移输出,其中F=M/D,M和D均为整数,且要保证CLKFX的频率在合适的范围内(见下文);
CLKFX180:CLKIN的F倍频180°相移输出。
对应DFS_FREQUENCY_MODE的时钟端口为:
CLKFX:CLKIN的F倍频输出,其中F=M/D,M和D均为整数,且要保证CLKFX的频率在合适的范围内(见下文);
CLKFX180:CLKFX的180°相移输出。
对比这两类时钟输出端口,我们发现它们都包含了CLKFX、CLKFX180两个端口,这至少说明一点,那就是这两个端口既可以工作在DLL模式下,也可工作在DFS模式下。不过仔细观察就会发现,在这两种模式下,CLKFX、CLKFX180的端口说明并不相同。对应DFS_FREQUENCY_MODE属性的说明中,仅仅强调了倍频以及相对于自身的180°相移,并没有涉及到任何与CLKIN相位之间关系的说明。由此可见,DLL模式的锁相功能是可以关闭的,一旦DLL锁相功能被关闭,那么将只有CLKFX、CLKFX180两个端口可用,并且无法保证这两个端口输出时钟与CLKIN之间的相位关系。事实上,DCM的反馈回路是否存在正是控制DLL模式是否关闭的方法。

时钟属性与输入、输出时钟频率的关系

不同芯片系列之间,频率范围可能会有一定的出入,不过使用原理是类似的。这里以Xilinx Virtex5 LX110系列的FPGA芯片中的DCM为例来进行介绍。
当断开DCM的反馈回路,那么DCM将仅工作在DFS模式下,此时仅有CLKFX、CLKFX180两个端口可用,那么,此时输入、输出时钟的频率与DFS_FREQUENCY_MODE之间的对应关系为:

DFS_FREQUENCY_MODE CLKIN (MHz) CLKFX\CLKFX180 (MHz)
LOW 1~140 32~140
HIGH 25~350 140~350

通过上表可以看出,要确定DFS_FREQUENCY_MODE到底为LOW还是HIGH,必须从CLKFX来判断,因为CLKIN的范围有重叠部分。
当连接上DCM的反馈回路,并且不使用CLKFX、CLKFX180两个端口时,DCM将工作在DLL模式下,那么,此时输入、输出时钟的频率与DLL_FREQUENCY_MODE之间的对应关系为:

DLL_FREQUENCY_MODE CLKIN(MHz) CLK0\90\180\270(MHz) CLK2X\CLK2X180(MHz)
LOW 32~120 32~120 64~240
HIGH 120~450 120~450 240~450

通过上表可以看出,可以通过CLKIN来判断出DLL_FREQUENCY_MODE的取值。不过需要注意的是,CLK2X的输出上限与CLK0是一样的,因此当CLKIN的频率高于225MHz时,该DCM的CLK2X、CLK2X180两个端口是不能使用的。
当连接上DCM的反馈回路,且使用了CLKFX、CLKFX180两个端口时,那么DCM将同时工作于DFS、DLL兼容模式下,此时,CLK0、CLK90、CLK180、CLK270、CLK2X、CLK2X180这些端口与CLKIN之间的频率关系不会改变,但是CLKFX、CLKFX180与CLKIN之间的关系会受到DLL与DFS模式的同时约束而发生一些调整。此时它们与DFS_FREQUENCY_MODE对应关系如下表:

DFS_FREQUENCY_MODE CLKIN(MHz) CLKFX\CLKFX180 (MHz)
LOW 32~140 32~140
HIGH 32~350 140~350
通过上表,我们可以看出,CLKIN必须大于32MHz,因为DLL模式开启,同时,CLKFX又必须小于350MHz,因为DFS模式输出的限制。

时钟输出的微调相移

通过前面的介绍,我们可以推断出,如果要调相,那么就必须开启DLL模式。结合之前对输出端口的介绍,可以发现本身输出端口中已经包含了一些调相操作,例如CLK0、CLK90、CLK180、CLK270分别对应CLKIN的0°、90°、180°、270°相移。不过这些调相比较粗略,为了得到更加精确的相位调整,DCM还提供了微调相移技术,介绍如下。
微调相移是以CLKIN为参考基准的,并且是同时作用于所有输出时钟端口的。例如CLKIN为100MHz,即周期为10ns,若微调36°,那么所有时钟输出端口都会统一延迟1ns(36°/360°* 10ns)。
通常来说,微调的精度可以达到1/256个CLKIN的时钟周期,因此其微调精度还是比较高的。DCM的微调可分为五种模式,可通过设置CLKOUT_PHASE_SHIFT属性来实现,分别介绍如下:
NONE:默认模式,表示不做微调;
FIXED:固定微调模式,即微调相位为预先设置好的固定度数;
VARIABLE_POSITIVE:正数动态调整,即微调相位可以动态改变,取值范围为一个正数范围,例如0~179;
VARIABLE_CENTER:居中动态调整,即微调相位可以动态改变,取值范围是一个以0为中心的区间,例如-79~79;
DIRECT:方向动态调整,即微调相位可以动态改变,但改变的方式不是以设定微调值来实现,而是通过微调有效加方向输入端口实现。当微调有效时,若方向输入端口为1时,则微调相位自增1,否则微调相位自减1。注意,此模式的微调相位取值范围与VARIABLE_POSITIVE范围相同。

时钟反馈端口

DCM的时钟反馈端口为CLKFB,只有将待反馈的时钟信号从这个端口反馈进来,DLL才能完成对输出时钟的相位控制。与PLL不同,DCM的反馈网络并不是必须的,因此DCM反馈网络通常有三种模式:无反馈、外部反馈、内部反馈。
默认情况下,DCM的反馈网络模式为内部反馈,即各个时钟输出端口的相位是可控的。此时的反馈网络组成为CLK0连接到CLKFB。由于CLK0默认为已经通过BUFG连接到了全局时钟树上,因此可以确保CLK0所控制的时钟域内部每一个触发器的时钟相位与CLKIN保持很高的一致性,其原理与PLL的内部经由全局时钟树反馈一样。如果CLK0没有使用BUFG,又或者反馈给CLKFB的为进入全局时钟树前的CLK0,那么DCM的所有输出的相位调整将失去意义。
如果DCM的输出是给FPGA片外使用,又或者出于什么别的目的或用途,我们也可以通过FPGA芯片外部路径来完成反馈网络的连接,即外部反馈模式。注意,此时需要板级的电路支持。
如果只关心CLKFX、CLKFX180的频率,而不关心它们与CLKIN之间的相位关系的话,则可以不连接CLKFB管脚,即无反馈模式。此时牺牲了相位的控制但是却可以换取DCM低频输入范围的扩展。
最后,反馈网络的搭建形式是非常灵活的,上面介绍的仅仅是三种基本方式,在使用中,需要根据实际需求来设计合适的反馈网络。

DCM锁定指示端口

DCM完成一次对CLKIN频率或者相位的锁定是需要一定时间的,当然了,只要CLKIN满足DCM的输入要求,这个时间会很短。但是,各个时钟输出端的不稳定时期总是或长或短的存在着,这很有可能会对它们所掌控的时钟域产生不好的影响。因此,通常情况下,必须在各个被使用到得时钟输出端都达到稳定后,对其各自掌控的时钟域进行复位操作。而复位操作需要关心的问题也就是时钟的输出是否达到了稳定,而这个可以通过DCM给出的LOCKED端口来进行判断。
对于LOCKED端口,当FPGA芯片上电后或者DCM被复位后,将会处于无效状态,一般输出逻辑0;当DCM完成锁定后,将会处于有效状态,一般输出逻辑1。

DCM复位端口

有些情况下,DCM一旦失锁是无法自行恢复的,因此,重置功能是必须的。当DCM遇到一些特殊情况或需求,例如输入时钟频率大范围跳动或者DCM配置更改时,可以通过DCM提供的RESET端口来主动对其进行复位操作,以保证DCM的输出能够尽快达到我们的预期。不过请注意,复位之后的各个时钟输出端口必然会出现一段不稳定期,这时就需要用到上面刚刚介绍的LOCKED端口。

DCM配置端口

对于DCM模块,我们只能通过HDL语言来调用,而无法通过HDL语言来创造,因为DCM所做的事情,已经超出了常规数字逻辑的理论范围。而当我们使用DCM的时候,一般都是先通过软件工具完成其的具体配置后,才能生成可供HDL调用的、功能确定的DCM模块。可是有时候固定功能的DCM不能满足实际的需求,因此,有些DCM还提供了一系列配置端口,用来修改DCM内部的一些参数寄存器,从而完成对DCM的重新配置,例如时钟输出的动态微调移相功能(参考【时钟输出端口->时钟输出的微调相移】小节)。

应用场合

时钟倍频

时钟倍频,即我们希望以某一时钟信号为基础,来创造出比其频率更高的新的时钟信号。
时钟倍频是最常见也是最基本的时钟信号处理需求,PLL和DCM均可以很好的完成这类工作。
PLL和DCM不仅可以做整数倍的倍频,例如2倍频、3倍频等等;也可以做分数倍的倍频,例如1.5倍频、2.33倍频等等;更一般的来说,对于凡是可以写成
Fout = (M/N) * Fin, (M、N均为有限范围的正整数,且M≥N)
且Fout、Fin均在允许频率范围内的倍频情况,PLL和DCM均能够轻松完成该倍频需求。
不过由于PLL和DCM输入、输出时钟信号的频率范围、占空比等要求可能会有所出入,因此如果一片FPGA芯片上既有PLL也有DCM的话,请根据它们的数据手册来选取更合适的那个。除此以外,如果同时需要输出多个倍频系数不一样的时钟,那么优先选择PLL,因为DCM仅有一个CLKFX端口输出的倍频系数是独立可调的。

时钟分频

时钟分频,即我们希望以某一时钟信号为基础,来创造出比其频率更低的新的时钟信号。
通过恰当的时序逻辑电路也能完成对时钟信号的分频,例如如下代码就完成了对CLKIN的3分频操作,占空比约为67%:
-- VHDL example	
process(CLKIN)
begin
	if(CLKIN'event and CLKIN = '1')then
		if(counter = 2)then
			counter <= (others => '0');
		else
			counter <= counter + 1;
		end if;
	end if;
end process;	
CLKOUT <= '1' when counter > 0 else '0';

// Verilog example
always@(posedge CLKIN)
begin
	if(counter == 2)
		counter <= (others => '0');
	else
		counter <= counter + 1'b1;
end
assign CLKOUT = (counter > 0) ? 1'b1 : 1'b0;

能否通过时序逻辑做出来占空比为50%的3分频操作呢?从逻辑上来说是可以的,思路类似如下代码:

-- VHDL example	
process(CLKIN)
begin
	if(CLKIN'event and CLKIN = '1')then
		if(counter = 2)then
			counter <= (others => '0');
		else
			counter <= counter + 1;
		end if;
	end if;
end process;
process(CLKIN)
begin
	if(CLKIN'event and CLKIN = '0')then
		fraction <= counter(0);
	end if;
end process;
realCounter <= counter & fraction;
CLKOUT <= '1' when realCounter > 2 else '0';

// Verilog example
always@(posedge CLKIN)
begin
	if(counter == 2)
		counter <= (others => '0');
	else
		counter <= counter + 1'b1;
end
always@(negedge CLKIN)
begin
	fraction <= counter[0];
end
assign realCounter = {counter, fraction};
assign CLKOUT = (realCounter > 2) ? 1'b1 : 1'b0;

不过为了得到较好的时钟信号,必须还要对计数器counter进行格雷码化,来去除比较时所可能产生的毛刺。但是如果考虑到门延迟和线延迟,上述代码产生的CLKOUT的占空比也不可能精确等于50%。
采用与上例类似的思路,我们可以得到小数位为0.5的分数分频。因为同时使用CLKIN的上升沿与下降沿,所得到的最小可控时间精度为0.5个TCLKIN,因此CLKOUT的周期可以为N+0.5(N为正整数)个TCLKIN,因此CLKOUT的频率可以为CLKIN的N+0.5分频。但是,无论如何,我们都无法通过时序逻辑得到小数部分不为0.5的CLK分频,因为CLKOUT的周期不为N+0.5个TCLKIN,就为N个TCLKIN。
由此可见,时序逻辑实现分频的能力还是比较有限的,并且对于小数部分为0.5的分数分频,由于延迟以及跨时钟域的原因,要想保证分频后时钟信号的稳定性也是比较令人头痛的一件事。
时钟分频也是最常见的一类时钟信号处理需求,相比于时序逻辑,PLL和DCM均可以更好的完成这类工作。
PLL和DCM不仅可以做整数的分频,例如2分频、3分频等等;也可以做分数的倍频,例如1.5分频、2.33分频等等;更一般的来说,对于凡是可以写成
Fout = (M/N) * Fin, (M、N均为有限范围的正整数,且M≤N)
且Fout、Fin均在允许频率范围内的分频情况,PLL和DCM均能够轻松完成该分频需求。
不过由于PLL和DCM输入、输出时钟信号的频率范围、占空比等要求可能会有所出入,因此如果一片FPGA芯片上既有PLL也有DCM的话,请根据它们的数据手册来选取更合适的那个。除此以外,如果同时需要输出多个分频系数不一样的时钟,那么优先选择PLL,因为DCM仅有一个CLKFX端口输出的分频系数是独立可调的,而CLKDV端口也只能做到N+0.5(N为正整数)分频。

大范围频率合成

时钟信号的倍频和分频可以统称为频率合成。通过之前的讨论可以发现,无论是PLL还是DCM,都能对时钟信号完成很好的频率合成工作,但是,当要求更大范围的频率合成时,单独的PLL或者DCM就显得还差那么一点。
首先,需要说明一下,更大范围的频率合成并不是指CLKOUT的最低、最高频率范围得到扩大,而是指可合成的频率数量更多了。因为受到PLL和DCM时钟输出端口的频率范围制约,无论如何我们是不可能产生出超出这个制约范围的频率,但是对于一个固定频率的CLKIN来说,PLL或者DCM所能给出的频率合成情况是有限的,也就是说CLKOUT可取的频点是离散的、有限的,如果能够在CLKOUT的频率制约范围内获得更多的离散频率点,也是对频率合成范围的增大。
频率合成的公式可以概括如下:
Fout = (M/N) * Fin, (M、N均为有限范围的正整数)
如果对之前讲的内容还有印象的话,应该知道这个公式还有一个隐含的限制,即如果令Fmid = M * Fin,那么Fmid的频率范围是有限制的(如果对于Altera公司的分数锁相环,M的值也可以不为整数)。
现在假设,Fin = 100MHz,M、N的取值范围均为132,Fmid的取值范围为500MHz1000MHz,若要求Fout = 210MHz,该怎么实现?
由于Fout = (21/10) * Fin,因为21和10已经互质,所以M只能为21、N只能为10,可是此时Fmid = 2100Mhz,大于允许的取值上限,故使用单个PLL或者DCM是无法实现本例要求的。
因此为了解决这类问题,扩展可取离散频点的数目,我们可以采用PLL、DCM的级联来实现大范围的频率合成,级联的方式可以为PLL+DCM、PLL+PLL、DCM+DCM,当然也可以是更高阶的级联。
那么,针对之前这种情况,我们可以先使用一个PLL或DCM,做
Fout1 = (7/10) * Fin = 70MHz,
再使用一个PLL或DCM做
Fout = (9/3) * Fout1 = 210MHz,
这样便可解决单PLL或DCM不可解决的问题,达到扩展频率合成范围的目的。

时钟去抖

时钟去抖,即去除时钟信号本身的一些不稳定性,例如相位的不稳定性、占空比的不稳定性以及频率的不稳定性。
如果时钟信号本身的质量不是非常良好,那么必然导致其所控制时钟域时序逻辑性能的下降,而当这种下降比较严重时,就会导致FPGA设计行为的错误。因此,为了保证时序逻辑的正常工作,我们往往期望控制该时钟域的时钟信号的质量能够尽量的好,时钟波形能够尽量趋近于理想的无抖动的波形信号。可是现实情况往往不尽如人意,通常情况下,外部的时钟源总会或多或少的存在着一些不稳定因素,而当FPGA设计的时间需求比较紧时或者碰到一些对相位非常敏感的算法(例如,QAM调制的星座图绘制等)时,这些时钟上的不稳定因素往往会对FPGA设计造成比较致命的打击。因此,迫切需要一种能够对时钟信号进行矫正的方法来解决上述问题。
在FPGA的资源中,PLL可以很好的完成对时钟的去抖工作,只要CLKIN的变化不至于让CLKOUT失锁,那么CLKOUT就能输出比CLKIN稳定得多的时钟波形,这主要也是因为PLL中具有一个低通滤波器的结构。而DCM不具有时钟去抖效果,因为其原理归根结底还是利用一些数字的方法,而数字的方法对于通过其的电信号是没有原理性的滤波效果的。

时钟移相

时钟移相,即我们希望以某一时钟信号为基础,来创造出与其相位有一定偏差的新的时钟信号。
时钟移相也是一类最基本的时钟信号处理需求,PLL和DCM均可以完成这类工作。
时钟移相技术通常用于同步接口的设计,相对来说,PLL的移相精度比较粗,一般只能达到CLKMID的1/8周期。而DCM的移相精度相对来说比较高,一般能够达到CLKIN的1/256周期。由此可见,只有当倍频系数M的取值等于32时,PLL的移相精度才可能和DCM一样,而这已经几乎是PLL的极限了。
因此,如果对移相的精度要求不是很高时,PLL和DCM都是可以的;而当对移相的精度要求比较高时,应该采用DCM,若此时能够保证倍频系数M的取值比较大,则也可以考虑使用PLL。

去抖+高精移相

只有PLL才能完成时钟的去抖,只有DCM才能完成精度较高的时钟移相,因此,如果需要同时对一个时钟信号进行去抖和高精度移相操作,就必须同时使用PLL和DCM两个模块,而它们之间的级联方式可以是PLL+DCM,也可以是DCM+PLL,即可以先去抖再移相,也可以先移相再去抖。例如下图:
FPGA之道(49)DCM与PLL_取值_02
FPGA之道(49)DCM与PLL_数据_03

时钟去延迟

时钟去延迟,即我们希望以某一时钟信号为基础,在另一个地方创造出一个和其频率、相位一摸一样的新的时钟信号。
也许你会疑惑,既然频率、相位都没有改变,那么就将原来的时钟信号直接拿过来用就好了呗,为什么还需要创造一个新的呢?其实不然,任何从外部时钟源引入的时钟信号,由于输入管脚的传输延迟、时钟树的传输延迟等等,导致当它传递到相应的内部触发器或者再次传到FPGA片外的器件时,相位相比于外部时钟源已经产生了比较大的偏移。而如果使用这个时钟的FPGA内部或外部资源,需要采集与该外部时钟同源的数据时,那么这个偏移就很可能会影响整个系统的正常工作,那么此时,时钟去延迟技术就非常的必要。
时钟去延迟其实就是时钟移相功能中0°相移的一个特殊应用。因此PLL和DCM都能很好的完成它。
我们可以参考【本篇->编程思路->DCM与PLL->PLL模块基本端口简介】小节中介绍时钟反馈端口时的那个例子来理解时钟去延迟的原理。不过需要注意的是,如果是针对外部时钟来去延迟的,那么就必须从专门的全局时钟管脚引入该时钟信号。因为从原理上来说,由于布局布线的不确定性,PLL和DCM都无法预先知道从芯片管脚到它们的时钟输入端到底有多长的传输路径,因此它们都无法预先被设置为可以补偿这段延迟的状态。而且锁相功能一旦做好,要想再改变0°相移的初始状态,恐怕就得需要硬件上的变动了。故只有当时钟信号是从全局时钟管脚引入的时候,FPGA厂商才可以将这个路径设计成为固定的长度,并让PLL或者DCM的硬件设计能够考虑到这段延迟,从而能够完成补偿,得到与外部时钟源频率和相位都精确一样的新时钟信号。以Xilinx的FPGA芯片为例,从全局时钟管脚引入的时钟信号,可以通过IBUFG的方式连入PLL或DCM的时钟输入端;而从普通引脚引入的时钟信号,则只能通过IBUF的方式连入PLL或DCM的时钟输入端。一般有些资料上会说IBUFG带来的时间延迟为0,所以才能保证管脚处和PLL或DCM的时钟输入端处的时钟信号相位一致,其实究其本质,IBUFG肯定是有延迟的,只不过在设计PLL或DCM时已经从硬件上补偿了这部分延迟,所以才让我们有IBUFG是0延迟的错觉。
下图就是一个利用PLL实现外部时钟信号穿越FPGA芯片前、后相位0延迟的例子:
FPGA之道(49)DCM与PLL_级联_04

时钟源切换

时钟源切换,即我们希望每次从多个时钟信号中选出一个做为参考基础,来创造出新的时钟信号。
时钟切换的情况也是比较常碰到的时钟处理需求,如果仅仅是需要切换时钟,那么多路选择器就可以完成这个功能,可是切换的目的是为了选择一个时钟作为参考基础来创造出新的时钟,那么就必须用到PLL或DCM。
PLL一般本身就会支持多个时钟信号的输入,然后通过选择信号来决定到底使能哪个时钟输入端;而DCM往往仅有一个时钟输入端,因此需要再结合多路选择器和额外的控制信号来实现。若备选的时钟数量较多,则无论是PLL还是DCM,都需要借助额外的逻辑。
要想真正实现时钟源的切换,其实比较复杂,远非加一些多路复用器或者控制逻辑就能够完成的,有些时候甚至是不可能实现的,原因如下:
对于PLL模块来说,即使待切换的若干个时钟源的频率范围全部满足CLKIN的需求,但是如果有谁无法满足初始PLL配置时的CLKMID或者CLKOUT的范围要求,那么切换了之后PLL将无法正常工作。
对于DCM模块来说,情况就更加复杂了。要保证多个时钟源能够正常的切换,首先要保证这些个时钟如果独立用DCM处理时,DCM的DLL_FREQUENCY_MODE和DFS_FREQUENCY_MODE两个属性的取值必须完全一致;其次再保证这些待切换的时钟以及输出端口使用对DLL模式的开启或关闭要求是否一致;最后才是去确保对应当前属性值时,CLKIN、CLKMID、CLKOUT的频率取值范围是否满足相应的范围需求。
例如,当使用DCM做时钟去延迟时,如果需要进行时钟源切换,那么若待切换时钟源中有100MHz和200MHz同时存在时,由于其对应的DLL_FREQUENCY_MODE分别为LOW和HIGH,因此无法成功切换。
时钟源切换的一个扩展问题就是即使PLL或者DCM仅有一个时钟输入端,但若该时钟源的频率可跳变,那么PLL或DCM是否能够继续正常工作?其分析方法是一样的。

动态配置

动态可配置,即我们希望以某一时钟信号为基础,来创造出新的时钟信号,而该新的时钟信号的频率或者相位等,要求是动态可调整的,而不是每次修改都需要重新编译一次FPGA设计。
目前FPGA芯片中集成的PLL或者DCM资源,基本上都是支持动态配置的。
动态配置在有些情况下是非常有效的,例如当我们的FPGA设计需要根据一个固定的时钟信号去采样一个或多个与其同频、但不同相位的不固定时钟信号的时钟域所产生的数据时,就必须针对每个不固定的时钟域产生一个可用的时钟,这时PLL和DCM的动态配置功能就可以发挥非常重要的作用。
由于动态配置功能并不太常用,因此各个FPGA厂商虽然给出了配置端口的介绍和说明,但却没有详细公布PLL或DCM内部控制寄存器的地址、功能以及修改方法,因此如果需要在自己的FPGA设计中加入动态配置的功能,最好和相关的技术支持部门取得联系,并获得相应的寄存器说明及修改资料。