数字电路中,时钟是整个电路最重要、最特殊的信号。
第一, 系统内大部分器件的动作都是在时钟的跳变沿上进行, 这就要求时钟信号时延差要非常小, 否则就可能造成时序逻辑状态出错.
第二, 时钟信号通常是系统中频率最高的信号.
第三, 时钟信号通常是负载最重的信号, 所以要合理分配负载。出于这样的考虑在FPGA这类可编程器件内部一般都设有数量不等的专门用于系统时钟驱动的全局时钟网络。这类网络的特点是:一、负载能力特别强, 任何一个全局时钟驱动线都可以驱动芯片内部的触发器; 二是时延差特别小; 三是时钟信号波形畸变小, 工作可靠性好。
clock tree synthesis是asic设计中的一步,它的目的是使时钟尽量在同一时刻去驱动所有的触发器,这也就是所说的同步电路,这里的同一时刻是要求时钟到所有触发器的相位相同,因为有的触发器离clk源端比较远,需要好多个周期才能到。这里就出现了一个问题,如果只靠连线的话根本无法保证时钟到达触发器的相位相同,于是就可以加入buffer,buffer也就是偶数个反相器,他能够缩短延时,于是通过加入的buffer的数目和类型来调整延时使得时钟到达触发器的相位相同,从而实现同步功能,当然插入buffer还有个功能就是增大驱动能力,如果不这样仅靠时钟源是无法驱动如此之多的触发器的。再说到fpga,fpga是由许多的逻辑单元构成的,逻辑单元包括门、查找表、和触发器,即它的触发器已经做好了,也就是说在出厂之前,FPGA内部元件之间的连线已经完全固定,我们的编程也只是在此基础上选择哪些相连、哪些断开罢了。FPGA并不能通过动态插入buffer的方法来实现时钟到达触发器的相位相同。也就是说时钟树结构已经被预先布好了,我们所能做的也就是在此基础上利用各种资源来对时钟进行处理,如分频、倍频、门控时钟。所以fpga谈不上时钟树,只能说是时钟管理。FPGA有些特性不比asic。逻辑单元比standard cell慢,所以一般FPGA跑得比实际慢很多。另外fpga有专用时钟树,不比asic随便长,所以FPGA使用量大了,可能会有hold(信号保持时间)问题。
DCM概述
DCM内部是DLL(Delay Lock Loop(?)结构,对时钟偏移量的调节是通过长的延时线形成的。DCM的参数里有一个PHASESHIFT(相移),可以从0变到255。所以我们可以假设内部结构里从clkin到clk_1x之间应该有256根延时线(实际上,由于对不同频率的时钟都可以从0变到255,延时线的真正数目应该比这个大得多)。DCM总会把输入时钟clkin和反馈时钟clkfb相比较,如果它们的延时差不等于所设置的PHASESHIFT,DCM就会改变在clkin和clk_1x之间的延时线数目,直到相等为止。这个从不等到相等所花的时间,就是输出时钟锁定的时间,相等以后,lock_flag标识才会升高。
当DCM发现clkin和clkfb位相差不等于PHASESHIFT的时候,却去调节clk_1x和clkin之间延时,所以如果clk_1x和clkfb不相关的话,那就永远也不能锁定了。呵呵。
如何使用DCM
DCM一般和BUFG配合使用,要加上BUFG,应该是为了增强时钟的驱动能力。DCM的一般使用方法是,将其输出clk_1x接在BUFG的输入引脚上,BUFG的输出引脚反馈回来接在DCM的反馈时钟脚CLKFB上。另外,在FPGA里,只有BUFG的输出引脚接在时钟网络上,所以一般来说你可以不使用DCM,但你一定会使用BUFG。有些兄弟总喜欢直接将外部输入的时钟驱动内部的寄存器,其实这个时候虽然你没有明显地例化BUFG,但工具会自动给你加上的。
使用DCM可以消除时钟skew
使用DCM可以消除时钟skew。这个东西一直是我以前所没有想清楚的,时钟从DCM输出开始走线到寄存器,这段skew的时间总是存在的,为什么用DCM就可以消除呢?直到有一天忽然豁然开朗,才明白其原委。对高手来说,也许是极为easy的事情,但也许有些朋友并不一定了解,所以写出来和大家共享。
为说明方便起见,我们将BUFG的输出引脚叫做clk_o,从clk_o走全局时钟布线到寄存器时叫做clk_o_reg,从clk_o走线到DCM的反馈引脚CLKFB上时叫clkfb,如图所示。实际上clk_o, clk_o_reg, clkfb全部是用导线连在一起的。所谓时钟skew,指的就是clk_o到clk_o_reg之间的延时。如果打开FPGA_Editor看底层的结构,就可以发现虽然DCM和BUFG离得很近,但是从clk_o到clkfb却绕了很长一段才走回来,从而导致从clk_o到clk_o_reg和clkfb的延时大致相等。总之就是clk_o_reg和clkfb的相位应该相等。所以当DCM调节clkin和clkfb的相位相等时,实际上就调节了clkin和clk_o_reg相等。而至于clk_1x和clk_o的相位必然是超前于clkin, clkfb, clk_o_reg的,而clk_1x和clk_o之间的延时就很明显,就是经过那个BUFG的延迟时间。
对时钟skew的进一步讨论
最后,说一说时钟skew的概念。时钟skew实际上指的是时钟驱动不同的寄存器时,由于寄存器之间可能会隔得比较远,所以时钟到达不同的寄存器的时间可能会不一样,这个时间差称为时钟skew。这种时钟skew可以通过时钟树来解决,也就是使时钟布线形成一种树状结构,使得时钟到每一个寄存器的距离是一样的。很多FPGA芯片里就布了这样的时钟树结构。也就是说,在这种芯片里,时钟skew基本上是不存在的。
说到这里,似乎有了一个矛盾,既然时钟skew的问题用时钟树就解决了,那么为什么还需要DCM+BUFG来解决这个问题?另外,既然时钟skew指的时时钟驱动不同寄存器之间的延时,那么上面所说的clk_o到clk_o_reg岂非不能称为时钟skew?
先说后一个问题。在一块FPGA内部,时钟skew问题确实已经被FPGA的时钟方案树解决,在这个前提下clk_o到clk_o_reg充其量只能叫做时钟延时,而不能称之为时钟skew。可惜的是FPGA的设计不可能永远只在内部做事情,它必然和外部交换数据。例如从外部传过来一个32位的数据以及随路时钟,数据和随路时钟之间满足建立保持时间关系(Setup Hold time),你如何将这32位的数据接收进来?如果你不使用DCM,直接将clkin接在BUFG的输入引脚上,那么从你的clk_o_reg就必然和clkin之间有个延时,那么你的clk_o_reg还能保持和进来的数据之间的建立保持关系吗?显然不能。相反,如果你采用了DCM,接上反馈时钟,那么clk_o_reg和clkin同相,就可以利用它去锁存进来的数据。可见,DCM+BUFG的方案就是为了解决这个问题。而这个时候clk_o到clk_o_reg的延时,我们可以看到做内部寄存器和其他芯片传过来的数据之间的时钟skew。
由此,我们可以得出一个推论,从晶振出来的时钟作为FPGA的系统时钟时,我们可以不经过DCM,而直接接到BUFG上就可以,因为我们并不在意从clkin到clk_o_reg的这段延时。
目前,大型设计一般推荐使用同步时序电路。同步时序电路基于时钟触发沿设计,对时钟的周期、占空比、延时和抖动提出了更高的要求。为了满足同步时序设计的要求,一般在FPGA设计中采用全局时钟资源驱动设计的主时钟,以达到最低的时钟抖动和延迟。 FPGA全局时钟资源一般使用全铜层工艺实现,并设计了专用时钟缓冲与驱动结构,从而使全局时钟到达芯片内部的所有可配置单元(CLB)、I/O单元(IOB)和选择性块RAM(Block Select RAM)的时延和抖动都为最小。为了适应复杂设计的需要,Xilinx的FPGA中集成的专用时钟资源与数字延迟锁相环(DLL)的数目不断增加,最新的Virtex II器件最多可以提供16个全局时钟输入端口和8个数字时钟管理模块(DCM)。
与全局时钟资源相关的原语常用的与全局时钟资源相关的Xilinx器件原语包括:IBUFG、IBUFGDS、BUFG、BUFGP、BUFGCE、BUFGMUX、BUFGDLL和DCM等,如图1所示。
1. IBUFG即输入全局缓冲,是与专用全局时钟输入管脚相连接的首级全局缓冲。所有从全局时钟管脚输入的信号必须经过IBUF元,否则在布局布线时会报错。IBUFG支持AGP、CTT、GTL、GTLP、HSTL、LVCMOS、LVDCI、LVDS、LVPECL、LVTTL、PCI、PCIX和SSTL等多种格式的IO标准。
2. IBUFGDS是IBUFG的差分形式,当信号从一对差分全局时钟管脚输入时,必须使用IBUFGDS作为全局时钟输入缓冲。IBUFG支持BLVDS、LDT、LVDSEXT、LVDS、LVPECL和ULVDS等多种格式的IO标准。
3. BUFG是全局缓冲,它的输入是IBUFG的输出,BUFG的输出到达FPGA内部的IOB、CLB、选择性块RAM的时钟延迟和抖动最小。
4. BUFGCE是带有时钟使能端的全局缓冲。它有一个输入I、一个使能端CE和一个输出端O。只有当BUFGCE的使能端CE有效(高电平)时,BUFGCE才有输出。
5. BUFGMUX是全局时钟选择缓冲,它有I0和I1两个输入,一个控制端S,一个输出端O。当S为低电平时输出时钟为I0,反之为I1。需要指出的是BUFGMUX的应用十分灵活,I0和I1两个输入时钟甚至可以为异步关系。
6. BUFGP相当于IBUG加上BUFG。
7. BUFGDLL是全局缓冲延迟锁相环,相当于BUFG与DLL的结合。BUFGDLL在早期设计中经常使用,用以完成全局时钟的同步和驱动等功能。随着数字时钟管理单元(DCM)的日益完善,目前BUFGDLL的应用已经逐渐被DCM所取代。
8. DCM即数字时钟管理单元,主要完成时钟的同步、移相、分频、倍频和去抖动等。DCM与全局时钟有着密不可分的联系,为了达到最小的延迟和抖动,几乎所有的DCM应用都要使用全局缓冲资源。DCM可以用Xilinx ISE软件中的Architecture Wizard直接生成。
全局时钟资源的使用方法 全局时钟资源的使用方法(五种)
1:IBUFG + BUFG的使用方法:
IBUFG后面连接BUFG的方法是最基本的全局时钟资源使用方法,由于IBUFG组合BUFG相当于BUFGP,所以在这种使用方法也称为BUFGP方法。
2. IBUFGDS + BUFG的使用方法:
当输入时钟信号为差分信号时,需要使用IBUFGDS代替IBUFG。
3. IBUFG + DCM + BUFG的使用方法:
这种使用方法最灵活,对全局时钟的控制更加有效。通过DCM模块不仅仅能对时钟进行同步、移相、分频和倍频等变换,而且可以使全局时钟的输出达到无抖动延迟。
4. Logic + BUFG的使用方法:
BUFG不但可以驱动IBUFG的输出,还可以驱动其它普通信号的输出。当某个信号(时钟、使能、快速路径)的扇出非常大,并且要求抖动延迟最小时,可以使用BUFG驱动该信号,使该信号利用全局时钟资源。但需要注意的是,普通IO的输入或普通片内信号进入全局时钟布线层需要一个固有的延时,一般在10ns左右,即普通IO和普通片内信号从输入到BUFG输出有一个约10ns左右的固有延时,但是BUFG的输出到片内所有单元(IOB、CLB、选择性块RAM)的延时可以忽略不计为“0”ns。
5. Logic + DCM + BUFG的使用方法:
DCM同样也可以控制并变换普通时钟信号,即DCM的输入也可以是普通片内信号。使用全局时钟资源的注意事项 全局时钟资源必须满足的重要原则是:使用IBUFG或IBUFGDS的充分必要条件是信号从专用全局时钟管脚输入。换言之,当某个信号从全局时钟管脚输入,不论它是否为时钟信号,都必须使用IBUFG或IBUFGDS;如果对某个信号使用了IBUFG或IBUFGDS硬件原语,则这个信号必定是从全局时钟管脚输入的。如果违反了这条原则,那么在布局布线时会报错。这条规则的使用是由FPGA的内部结构决定的:IBUFG和IBUFGDS的输入端仅仅与芯片的专用全局时钟输入管脚有物理连接,与普通IO和其它内部CLB等没有物理连接。 另外,由于BUFGP相当于IBUFG和BUFG的组合,所以BUFGP的使用也必须遵循上述的原则。
全局时钟资源的例化方法
全局时钟资源的例化方法大致可分为两种:
一是在程序中直接例化全局时钟资源;
二是通过综合阶段约束或者实现阶段约束实现对全局时钟资源的使用;
第一种方法比较简单,用户只需按照前面讲述的5种全局时钟资源的基本使用方法编写代码或者绘制原理图即可。
第二方法是通过综合阶段约束或实现阶段的约束完成对全局时钟资源的调用,这种方法根据综合工具和布局布线工具的不同而异。
片内时钟设计
Xilinx可编程逻辑器件的全局时钟为时钟分配树的结构,如下图所示。
图 可编程逻辑器件的时钟分配树结构
FPGA内部的时钟分为多个区域(某些高端的FPGA)或分为4个象限(某些低端的FPGA),在这个区域或象限内有特定多的时钟能够驱动寄存器和RAM的时钟端。另外,在树干上有专用的时钟线将进入这些区域和象限的时钟连接起来。
1.全局时钟树和全局时钟缓冲器
全局时钟网络是一个很长且扇出也很大的网络,所以一定不是最短的路径。它会有相对较大的延时,其优点在于Skew很小。即通过全局时钟网络到FPGA内部的各种资源时,时钟沿同时到达。这样对于一个同步的系统,时序的计算和分析会很容易。
FPGA的全局时钟路径需要专用时钟驱动器,如图1中的全局时钟缓冲器Global Clockbuffer(BUFG),时钟信号只有经过BUFG之后才可以驱动全局时钟网络。
BUFG的例化请参考Xilinx的ISE设计工具内包含的《器件库指南》。这里需要指出的是IBUFG和BUFG不同,IBUFG是全局时钟的引脚的缓冲器,是和其他普通管脚的IBUF对应的;而BUFG是内部的全局时钟的缓冲器。
2.数字时钟管理器(DCM)和模拟锁相环(PLL)
DOM和PLL都可以用来做频率合成和相位调整,目前在Xilinx高端的Virtex-5中才有PLL,DOM是一直都存在于Xilinx高低端的FPGA中的。
(1)DOM和PLL都有其工作的时钟频率的范围,应参考具体器件的手册决定是否可以采
用DOM和PLL。
(2)注意DOM的phase shift为所有的DOM的输出均增加一定的相位偏移。
(3)DOM及PLL的级联,无论采用何种级联方式,注意复位电路的设计,原则就是要在DOM或PLL的输入时钟稳定之后给出该DOM或PLL的复位脉冲。
3.片内时钟设计时需注意的几个方面
(1)所有的时钟尽量都要使用全局的时钟树资源,如果全局时钟资源不够,需要用到长线资源或本地走线资源的话,多留意时序报告中的clock skew,注意保持时间(hold time)问题。
(2)通常情况下尽量使用内部的DCM及PLL等来产生各种频率的时钟,避免使用内部逻辑生成的时钟,因为它们可能引起设计中的功能和时序问题。由组合逻辑产生的时钟会引入毛刺造成功能问题,而引入的延迟则会导致时序问题。如果用组合逻辑的输出作为时钟信号或异步复位信号,那么在设计中就会出现毛刺。在同步设计中,寄存器输入数据的毛刺是很正常的,对设计没有什么影响。然而时钟输入(或寄存器异步输入)上的毛刺或脉冲则会导致严重的后果,窄毛刺可能违反了寄存器的最小脉冲宽带要求。如果当毛刺到达时钟输入时寄存器的输入数据正在变化,则无法满足建立和保持时序要求。即使设计没有违反时序需求,寄存器输出也可能会出现变化,造成设计中其他部分的功能不正常。用于生成内部时钟的组合逻辑也会增加时钟线的延迟,在一些设计中时钟线上的逻辑延迟可能会造成时钟偏移大于两个寄存器之间的数据通道的长度,从而造成hold time违反的问题。
如果一定需要由内部逻辑来生成时钟信号的话,必须采用寄存器输出。同时为了减小时钟域上的时钟偏移,应把生成的时钟指定到FPGA一个高扇出和低Skew的时钟分配树上,即为该输出信号分配全局时钟缓冲器(BUFG)或第2全局时钟资源来实现。
(3)在逻辑设计时经常将主时钟分频,以产生所需的各种频率的时钟信号。对这种需求,建议一定要采用DOM或PLL,以保证时钟信号的稳定。如果采用逻辑来实现分频器,则一定要采用同步寄存器来实现。
(4)在FPGA设计中选择时钟信号时,如果器件中存在BUFGMUX缓冲器,一定采用BUFGMUX来实现,这样可以避免产生时钟信号的毛刺;对于没有BUFGMUX的器件,需要采用同步和复位控制电路来实现,避免毛刺产生。