EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
FPGA重点知识13条,助你构建完整“逻辑观”之二8、FPGA时钟系统
8 }" `7 N- [/ r# k( N8 D) t1. FPGA的全局时钟是什么?3 m5 U! J+ s0 D
FPGA的全局时钟应该是从晶振分出来的,最原始的频率。其他需要的各种频率都是在这个基础上利用PLL或者其他分频手段得到的。* c7 t2 H& T* D2 V$ k5 c2 O+ y: }
( U6 e8 O) k1 Z2 X
2. 全局时钟和BUFG:- i- ?! e6 V: U/ T
BUFG,输入为固定管脚,输出为H型全铜全局高速网络,这样抖动和到任意触发器的延时差最小,这个也就是FPGA做同步设计可以不需要做后仿真的原因。
/ }9 U/ I0 b3 `7 r, b F- J- O: n, b
' L1 h. {6 N7 i全局时钟:今天我们从另一个角度来看一下时钟的概念:时钟是D触发器的重要组成部分,一个有效边沿使得D触发器进行一次工作。而更多的时候,D触发器保持住上次的值。对于D触发器来说,可以将输入信号和时钟作比较。也许你会问,这么比较有什么意义。首先看我们比较得出什么东西:
+ @% d u( |# h w3 \7 I
. Z, ]- \3 c* B( h. r翻转率:R=Dr/Crx100%2 c0 S' W6 x* u
1 Y1 m; L9 e5 z+ ?/ _
就是D触发器改变一次值与时钟有效沿个数的比值。
' s. M7 N: O+ T
+ f5 o- h/ a; [0 ?# j举例:你写了一个来一个时钟有效沿就取一次反的电路,那么他的翻转率就是100%,翻转率和你的FPGA的功率有很大关系,翻转率越高,FPGA功率越高。
" a5 A" [1 ?5 d- o! O# R8 C8 w) A
e# R8 E$ W+ O5 R3. 全局时钟不够用是什么意思? N: d/ D T& F
因为全局时钟需要驱动很多模块,所以全局时钟引脚需要有很大的驱动能力,FPGA一般都有一些专门的引脚用于作为全局时钟用,他们的驱动能力比较强。但是如果这些引脚用完了,就只能用一般的引脚了,而他们的驱动能力不强,有可能不能满足你的时序要求。(驱动能力小的,产生的延迟会大一些)+ u! Y+ a, n( g( W$ S- n0 @$ |9 T
( q2 K4 B- b( S
理论上,FPGA的任意一个管脚都可以作为时钟输入端口,但是FPGA专门设计了全局时钟,全局时钟总线是一条专用总线,到达片内各部分触发器的时间最短,所以用全局时钟芯片工作最可靠,但是如果你设计的时候时钟太多,FPGA上的全局时钟管脚用完了就出现不够用的情况。9 g) T# j: E& I/ H1 `5 I, s
$ r/ p& W* m4 }3 n/ h6 H% u4. 什么是第二全局时钟? u# E+ A2 l+ M2 @. v( \$ y6 ^$ F
比如我有一个同步使能信号,连接到FPGA内部80%的资源(但不是时钟),这个时候,你的信号走线到达各个D触发器的延迟差很大,或者翻转率比较大的时候(>40%),这个时候你就需要使用第二全局时钟资源。7 h6 ?4 F5 E% O+ ^) ?. ^
! g: @" K! b+ [ h+ n: l/ u8 R
第二全局时钟资源的驱动能力和时钟抖动延迟等指标仅次于全局时钟信号。第二全局时钟资源其实是通过片内的高速行列总线来实现的,而不像全局时钟总线是一条专用总线。第二全局时钟总线是通过软件布线得到的,所以硬指标肯定是拼不过全局时钟总线。特别是当你在已经有80%以上的布线率的情况下,可能会出现约束第二全局时钟资源失败的情况。1 e; W+ X# Z2 ^8 h2 ~1 _
2 ?+ O; e7 {# k& p
5.CCLK:% ^5 Y* p0 x' \6 ? b9 E$ l. ?2 j
CCLK:FPGA同步配置时钟。如果配置模式为主模式,则该时钟由FPGA器件生成,并输出;如果配置模式为从模式,则该时钟由外部提供;
/ B* J) Q# l/ ]9 G) f9 M! H- X
+ T$ S- w" H2 m& |9 e. ?: Z当所配置的数据存放在PROM中,即通过PROM来配置器件时,必须选择CCLK时钟;8 U: @- g. c% M" L1 t, E
: h C. {/ D& j+ SUSER CLOCK:用户定义的配置时钟信号,该配置时钟目前很少采用;
3 N' c7 g9 B5 i1 U- m5 J! g* h+ _* f* z: M' d K
JTAG CLOCK:JTAG模式的配置时钟,该时钟提供给内部的JTAG控制逻辑。
' F. I% y$ v: d" J5 B" Q1 T% x2 ?! a; p7 ?4 F
默认值为:CCLK
: z9 n/ ?" T: J6 O- z3 p! z* ?% G, j, S, H! l" q
6. CCLK是怎么产生的:
' g% c! Q/ a" A$ d/ nCCLK的产生根据配置模式不同而不同,如果设置为Master模式,则由内部的震荡电路产生,作为外部ROM的工作时钟,默认为6MHZ,可通过配置选项设置;如果设置为Slave模式,则由计算机(或其他下载设备)提供,作为芯片内部下载电路的工作时钟;在JTAG模式情况下,CCLK不输出,此时芯片内部下载电路时钟由内部震荡电路提供,TCK仅用作边界扫描相关电路时钟。1 f8 r/ C$ R2 ^, l- u1 j
8 E- I9 P9 M& m补充:FPGA的主配置模式中,CCLK信号是如何产生的?
1 O; f- Y Q7 j1 S9 h: k$ C# b7 z0 z
9 h: {# D, m2 t9 f% W) tCCLK是由FPGA内部一个晶振电路产生的,同时ISE的软件在生成BIT流文件时,有个CCLK CONFIG选项,这个选项只有在时钟为CCLK时才可以起作用,可以在4-60MHz选择,可以控制CCLK的频率。
% H3 d2 g! r: g1 a' H在主从模式配置,配置数据的前60个字节导入FPGA之前,CCLK一直是2.5MHz,接下来由于前60个配置字节的作用,CCLK改为CONFIG设定的频率,直到结束,一般CONFIG默认的频率是4MHz.
( l6 r1 n8 A5 k m* {* J6 ~5 w. u. Z- f+ @' y+ @
7. FPGA中全局时钟怎么用啊?是把时钟接到FPGA的全局时钟输入引脚后,就起到全局时钟的作用了,还是在编译时需要制定某个时钟为全局时钟阿?
3 c; `) @. F( s, H+ M+ h$ a; C' K, b! f: x; r
其实全局时钟的使用关键在你的代码… 如果你的代码中只用了一个时钟作为所有的或者大部分触发器的时钟,编译器自然会把它编译为全局时钟。当然硬件连接上还是用全局时钟引脚较好,尤其是带PLL的,不是所有的全局时钟脚都能用PLL。7 D# E, Z6 w9 I
5 f0 o6 z7 K V无沦是用离散逻辑、可编程逻辑,还是用全定制硅器件实现的任何数字设计,为了成功地操作,可靠的时钟是非常关键的。设计不良的时钟在极限的温度、电压或制造工艺的偏差情况下将导致错误的行为,并且调试困难、花销很大。 在设计PLD/FPGA时通常采用几种时钟类型。时钟可分为如下四种类型:全局时钟、门控时钟、多级逻辑时钟和波动式时钟。多时钟系统能够包括上述四种时钟类型的任意组合。
' f1 @5 s8 y, {7 J( f' n8 {0 N+ L. l/ y
1.全局时钟7 s6 [4 ?/ w0 j5 [8 N: v
对于一个设计项目来说,全局时钟(或同步时钟)是最简单和最可预测的时钟。在PLD/FPGA设计中最好的时钟方案是:由专用的全局时钟输入引脚驱动的单个主时钟去钟控设计项目中的每一个触发器。只要可能就应尽量在设计项目中采用全局时钟。PLD/FPGA都具有专门的全局时钟引脚,它直接连到器件中的每一个寄存器。这种全局时钟提供器件中最短的时钟到输出的延时。# d) h3 A, [/ B$ a: X# f7 E1 e/ e$ h
) f# a) N1 q8 C' f+ }# z图1 示出全局时钟的实例。图1 定时波形示出触发器的数据输入D[1..3]应遵守建立时间和保持时间的约束条件。建立和保持时间的数值在PLD数据手册中给出,也可用软件的定时分析器计算出来。如果在应用中不能满足建立和保持时间的要求,则必须用时钟同步输入信号(参看下一章“异步输入”)。5 @# }3 P$ j0 c: W' G; a
* g" c5 r2 ?$ _* I/ Y& S5 S& o5 W: i. u3 L2 d5 d
图1 全局时钟 ) M5 a! y0 G9 y% M, b
(最好的方法是用全局时钟引脚去钟控PLD内的每一个寄存器,于是数据只要遵守相对时钟的建立时间tsu和保持时间th) , \1 g& T( @2 F, n/ U8 k2 u
7 J" o) a9 H7 q c8 J2.门控时钟
$ W' s; p* e0 Q) Y- F' {/ i1 D) B$ [在许多应用中,整个设计项目都采用外部的全局时钟是不可能或不实际的。PLD具有乘积项逻辑阵列时钟(即时钟是由逻辑产生的),允许任意函数单独地钟控各个触发器。然而,当你用阵列时钟时,应仔细地分析时钟函数,以避免毛刺。
4 }8 ]5 {6 d$ X; P# ?/ M o* A# ~5 T# v/ V% C" ]% ^+ x1 m
通常用阵列时钟构成门控时钟。门控时钟常常同微处理器接口有关,用地址线去控制写脉冲。然而,每当用组合函数钟控触发器时,通常都存在着门控时钟。如果符合下述条件,门控时钟可以象全局时钟一样可靠地工作:
+ a; [6 u& G8 _1.驱动时钟的逻辑必须只包含一个“与”门或一个“或”门。如果采用任何附加逻在某些工作状态下,会出现竞争产生的毛刺。3 i( l$ u, Q) W% }! d
/ h8 H' D; Y5 b$ N0 e3 A( D# {" H
2.逻辑门的一个输入作为实际的时钟,而该逻辑门的所有其它输入必须当成地址或控制线,它们遵守相对于时钟的建立和保持时间的约束。5 C+ p2 M/ ^1 W3 _
( E6 T& d) R$ M+ U. [) x, }& {+ ?! X图2和图3 是可靠的门控时钟的实例。在 图2 中,用一个“与”门产生门控时钟,在 图3 中,用一个“或”门产生门控时钟。在这两个实例中,引脚nWR和nWE考虑为时钟引脚,引脚ADD[o..3]是地址引脚,两个触发器的数据是信号D[1..n]经随机逻辑产生的。
2 E1 W/ X g7 O3 \" C
$ ]% ]5 t1 f7 d' p7 t( r0 O9 R4 c6 ]( G6 N
图2 “与”门门控时钟 5 I% t8 w# i; t n
7 k; A' l8 r( p3 |8 [$ i! Q) r+ K$ V" q* Y* }
图3 “或”门门控时钟 # K- \" c) o7 \0 W* a9 Z" `
# o% U6 A N0 h6 t! ?图2和图3 的波形图显示出有关的建立时间和保持时间的要求。这两个设计项目的地址线必须在时钟保持有效的整个期间内保持稳定(nWR和nWE是低电平有效)。如果地址线在规定的时间内未保持稳定,则在时钟上会出现毛刺,造成触发器发生错误的状态变化。另一方面,数据引脚D[1..n]只要求在nWR和nWE的有效边沿处满足标准的建立和保持时间的规定。( s! g" E8 s) J" g# y# H" O
+ L: p, N' ]2 y( F* m3 K
我们往往可以将门控时钟转换成全局时钟以改善设计项目的可靠性。图4 示出如何用全局时钟重新设计 图2 的电路。地址线在控制D触发器的使能输入,许多PLD设计软件,如MAX+PLUSII软件都提供这种带使能端的D触发器。当ENA为高电平时,D输入端的值被钟控到触发器中:当ENA为低电平时,维持现在的状态。
" C u! z" {& p! @. w' m& s+ J
% x5 `7 ^9 V+ d/ [4 O
图4 “与”门门控时钟转化成全局时钟
8 m' Y9 g# ` _, }: X8 @5 y: V: X/ e# f O
图4 中重新设计的电路的定时波形表明地址线不需要在nWR有效的整个期间内保持稳定;而只要求它们和数据引脚一样符合同样的建立和保持时间,这样对地址线的要求就少很多。
. J4 t* V' _# Z; m+ } u. n5 M7 \7 v- j5 X6 w6 z
图 给出一个不可靠的门控时钟的例子。3位同步加法计数器的RCO输出用来钟控触发器。然而,计数器给出的多个输入起到时钟的作用,这违反了可靠门控时钟所需的条件之一。在产生RCO信号的触发器中,没有一个能考虑为实际的时钟线,这是因为所有触发器在几乎相同的时刻发生翻转。而我们并不能保证在PLD/FPGA内部QA,QB,QC到D触发器的布线长短一致,因此,如 图5 的时间波形所示,在器从3计到4时,RCO线上会出现毛刺(假设QC到D触发器的路径较短,即QC的输出先翻转)。
! _6 Q7 f6 }" K: F) G
' a0 ]- L0 O" V0 `4 ?. }" r" ] ]. L9 E" t7 ^/ @5 L
图5 不可靠的门控时钟
3 `: M: G2 {; h0 S" l(定时波形示出在计数器从3到4改变时,RCO信号如何出现毛刺的)
: w0 R1 n6 q' v
' ^4 l1 k1 j5 Y0 Z4 E3 Z/ [图6 给出一种可靠的全局钟控的电路,它是图5不可靠计数器电路的改进,RCO控制D触发器的使能输入。这个改进不需要增加PLD的逻辑单元。
" s) J. I) }/ e0 \9 D
+ u2 e& V- K3 A* p% }; s" V8 v1 F
图6 不可靠的门控时钟转换为全局时钟 9 d/ R4 y: S |% `$ [1 G
(这个电路等效于图5电路,但却可靠的多) " G& {5 t+ `5 M, i' S& j
8 `0 M2 m8 j7 Y: S3 ~7 D9 t6 e
3.多级逻辑时钟
9 t8 _9 c" z2 R$ e/ y& p! y: L当产生门控时钟的组合逻辑超过一级(即超过单个的“与”门或“或”门)时,证设计项目的可靠性变得很困难。即使样机或仿真结果没有显示出静态险象,但实际上仍然可能存在着危险。通常,我们不应该用多级组合逻辑去钟控PLD设计中的触发器。) e$ Z1 V" z# i2 {4 Y
3 m. C' ?# U1 u: \0 @图7给出一个含有险象的多级时钟的例子。时钟是由SEL引脚控制的多路选择器输出的。多路选择器的输入是时钟(CLK)和该时钟的2分频(DIV2)。由图7 的定时波形图看出,在两个时钟均为逻辑1的情况下,当SEL线的状态改变时,存在静态险象。险象的程度取决于工作的条件。 多级逻辑的险象是可以去除的。例如,你可以插入“冗余逻辑”到设计项目中。然而,PLD/FPGA编译器在逻辑综合时会去掉这些冗余逻辑,使得验证险象是否真正被去除变得困难了。为此,必须应寻求其它方法来实现电路的功能。
\3 f2 L, ~. p* b6 O
5 e2 S) z' j4 I& C% u R图8给出图7电路的一种单级时钟的替代方案。图中SEL引脚和DIV2信号用于使能D触发器的使能输入端,而不是用于该触发器的时钟引脚。采用这个电路并不需要附加PLD的逻辑单元,工作却可靠多了。 不同的系统需要采用不同的方法去除多级时钟,并没有固定的模式。
+ j* b$ I8 R4 `
7 T* b% _; I! h3 M! u
/ `4 q% ?& \/ G3 H
2 z- _1 y, K/ ~3 H; k, Z, {
4 _% N0 \( s1 c& P- } Y图7 无静态险象的多级时钟
) z. K" h! C o(这个电路逻辑上等效于图7,但却可靠的多)
) E; h W3 N+ q, S5 `7 q+ H9 K6 ], D8 E4 J9 U7 s
4.行波时钟
; g @0 N }: D: @) P0 h另一种流行的时钟电路是采用行波时钟,即一个触发器的输出用作另一个触发器的时钟输入。如果仔细地设计,行波时钟可以象全局时钟一样地可靠工作。然而,行波时钟使得与电路有关的定时计算变得很复杂。行波时钟在行波链上各触发器的时钟之间产生较大的时间偏移,并且会超出最坏情况下的建立时间、保持时间和电路中时钟到输出的延时,使系统的实际速度下降。
3 f; d* d9 o+ y t J# u# T) d) G2 L( y
用计数翻转型触发器构成异步计数器时常采用行波时钟,一个触发器的输出钟控下一个触发器的输入,参看图9 同步计数器通常是代替异步计数器的更好方案,这是因为两者需要同样多的宏单元而同步计数器有较快的时钟到输出的时间。图10 给出具有全局时钟的同步计数器,它和 图9 功能相同,用了同样多的逻辑单元实现,却有较快的时钟到输出的时间。几乎所有PLD开发软件都提供多种多样的同步计数器。
, {# h, V: z) P+ c& \% O) T3 s
3 D8 }/ O! d s! I, b1 Y8 p; t* H
图9 行波时钟
$ D5 d: V! o9 \$ r# `9 b
/ w7 c% ]8 J z6 w5 d- @ |. U% Z: x( M( _
图10 行波时钟转换成全局时钟 ' t9 s v$ Y, I1 | C4 R5 f
(这个3位计数器是图9异步计数器的替代电路,它用了同样的3个宏单元,但有更短的时钟到输出的延时)
$ }: i# q/ z% K! T& m7 C; ]3 W# [: y
5. 多时钟系统
P% M/ T. H+ ~许多系统要求在同一个PLD内采用多时钟。最常见的例子是两个异步微处理器器之间的接口,或微处理器和异步通信通道的接口。由于两个时钟信号之间要求一定的建立和保持时间,所以,上述应用引进了附加的定时约束条件。它们也会要求将某些异步信号同步化。
" \' Z/ c; l& x
5 v9 F3 w8 h' }0 a图11 给出一个多时钟系统的实例。CLK_A用以钟控REG_A,CLK_B用于钟控REG_B,由于REG_A驱动着进入REG_B的组合逻辑,故CLK_A的上升沿相对于CLK_B的上升沿有建立时间和保持时间的要求。由于REG_B不驱动馈到REG_A的逻辑,CLK_B的上升沿相对于CLK_A没有建立时间的要求。此外,由于时钟的下降沿不影响触发器的状态,所以CLK_A和CLK_B的下降沿之间没有时间上的要求。, 如图4,2.II所示,电路中有两个独立的时钟,可是,在它们之间的建立时间和保持时间的要求是不能保证的。在这种情况下,必须将电路同步化。图12 给出REG_A的值(如何在使用前)同CLK_B同步化。新的触发器REG_C由GLK_B触控,保证REG_G的输出符合REG_B的建立时间。然而,这个方法使输出延时了一个时钟周期。4 z& n5 `: p2 _/ ~
3 Z5 _5 w/ M& J4 q/ r5 F {
, a! z4 S+ _0 j+ ]" S6 ]图ll 多时钟系统
) m" E# ~! G' v: J8 D(定时波形示出CLK_A的上升沿相对于CLK_B的上升沿有建立时间和保持时间的约束条件)
2 W- E, c! ?0 U* x7 V- W! }3 w' u0 w; N, Y+ N6 D1 Q1 n
8 ~# i% s6 B/ c- `5 i( H7 g
图12 具有同步寄存器输出的多时钟系统 # V. E$ u p, t. i
(如果CLK_A和CLK_B是相互独立的,则REG—A的输出必须在它馈送到1REG_B之前,用REG_C同步化)
- ~ w" a) q- S% G5 f% U! @# C$ ]1 ~" q4 Y/ m0 O
在许多应用中只将异步信号同步化还是不够的,当系统中有两个或两个以上非同源时钟的时候,数据的建立和保持时间很难得到保证,我们将面临复杂的时间问题。最好的方法是将所有非同源时钟同步化。使用PLD内部的锁项环(PLL或DLL)是一个效果很好的方法,但不是所有PLD都带有PLL、DLL,而且带有PLL功能的芯片大多价格昂贵,所以除非有特殊要求,一般场合可以不使用带PLL的PLD。 这时我们需要使用带使能端的D触发器,并引入一个高频时钟。
. X. e* N4 N% [. {: }% ~9 A% g; L) Y; q7 P3 T
) z! |) K7 H8 m" b5 X# p P) S% }) m
图13 不同源时钟 z. d# t4 _; Q9 C8 p8 w
& C6 \. F; `8 B g0 T
如图13所示,系统有两个不同源时钟,一个为3MHz,一个为5MHz,不同的触发器使用不同的时钟。为了系统稳定,我们引入一个20MHz时钟,将3M和5M时钟同步化,如图15所示。 20M的高频时钟将作为系统时钟,输入到所有触发器的的时钟端。3M_EN 和5M_EN将控制所有触发器的使能端。即原来接3M时钟的触发器,接20M时钟,同时3M_EN 将控制该触发器使能 ,原接5M时钟的触发器,也接20M时钟,同时5M_EN 将控制该触发器使能。 这样我们就可以将任何非同源时钟同步化。% j, N( P1 Z+ ? o
( v M2 @8 [9 D/ ]5 y( ?
" H$ E( ~( b* N4 C
图13 同步化任意非同源时钟 0 ?- ?7 n7 h% s$ _& y
(一个DFF和后面非门,与门构成时钟上升沿检测电路) 8 e3 q# p$ e8 J
' Q0 m3 V; E6 f. g5 b另外,异步信号输入总是无法满足数据的建立保持时间,容易使系统进入亚稳态,所以也建议设计者把所有异步输入都先经过双触发器进行同步化。
/ t4 ^$ Z. o& z: A) o1 b. M/ e! O& N6 {3 R6 S6 @6 v* w
) W# Q. y! g0 j. r4 ^, |8 q5 h
异步时钟同步化0 v/ y0 V' h) u0 P
通过双触发器接口,异步信号输入总是无法满足数据的建立保持时间,所以建议大家把所有异步输入都先经过双触发器进行同步化。如图所示,时钟域clk_s传给时钟域clk_d的数据经过了双触发器的同步处理,相同的,时钟域clk_d经双触发器传给时钟域clk_s的数据
& d! c4 `6 A1 T9 f2 y% h$ Y2 ]' P0 X! T. q- a, J
通过高频时钟同步化,当在单个系统中有两个或两个以上非同源时钟的时候,数据的建立和保持时间很难得到保证,我们将面临复杂的时间问题,最好的方法是将所有非同源时钟同步化:选用一个频率是它们的时钟频率公倍数的高频主时钟将他们进行同步。# Q, n8 L/ E5 M9 v9 e: H
# h6 S+ q/ Z" e3 A" _( I# j+ r
假设系统有两个不同源时钟,一个为3MHz,一个为5MHz,不同的触发器使用不同的时钟。为了系统稳定,假设我们引入一个20MHz时钟。
+ O8 z; k+ t. s$ o1 T5 h7 E8 C8 q2 y0 v. R
4 \0 O: A. I& R$ B* u; X8 Z2 |
( e8 J- r) l# q# }, T+ t2 ^用modelsim仿真后得到的时序图如图所示
/ l, P/ z& B5 y3 V3 }" e* F4 n9 a2 n4 h, \
" {$ J* O. @4 ]( Q- i, V
$ u, f6 b/ I' t' P: q( v2 e9、如何确定时序约束数值
: X2 `& ?" e0 D6 \' f( EFPGA工程的功能框图如图所示。上电初始,FPGA需要通过IIC接口协议对摄像头模块进行寄存器初始化配置。这个初始化的基本参数,如初始化地址和数据存储在一个预先配置好的FPGA内嵌ROM中。在初始化配置完成后,摄像头就能够持续输出RGB标准的视频数据流,FPGA通过对其相应的时钟、行频和场频进行检测,从而一帧一帧的实时采集图像数据。
9 Q j5 g9 b$ W8 r6 Q% P1 ]
3 y, `0 G [3 F/ q( p; Y, r采集到的视频数据先通过一个FIFO,将原本25MHz频率下同步的数据流转换到100MHz频率下。接着讲这个数据再送入写SDRAM缓存的FIFO中,最终这个FIFO每满160个数据就会将其写入SDRAM的相应地址中。在另一侧,使用另一个异步FIFO将SDRAM缓存的图像数据送个LCD驱动模块。LCD驱动模块不断的读出新的现实图像,并且驱动3.5寸液晶屏工作。6 C5 F4 K0 c F4 F: U3 ~
( v W+ g; J9 p
" }0 V9 Y$ t9 P1 _
5 S- W$ w& V3 J W- {由于这个工程是移植过来的,SDRAM的时序约束已经添加好并且很好的收敛了。但是,新增加的CMOS sensor的接口也需要做相应的时序约束。下面我们就来探讨下它的时序该如何做约束。: a+ K3 T* ~/ K. b6 T7 w: g0 i& a
" c' m% Z$ l- Q9 A% ]" e6 o先看看CMOS Sensor的datasheet中提供的时序波形和相应的建立、保持时间要求。波形如图所示。
0 r$ p7 O' M, Q3 C# Q
! ?7 |, [4 j1 H) V: t5 b
) X9 I( W& y, l& X
' y0 F+ G# \5 \% u波形中出现的时间参数定义如下表所示。5 K J: b4 D1 H7 V1 h
, c+ a2 P o: l
& K( }4 A$ v, `% Y( O
i" W$ c7 Z7 n- @7 H/ ]我们可以简单分析下这个datasheet中提供的时序波形和参数提供了一些什么样的有用信息。我们重点关注PCLK和D[7:0]的关系,HREF其实也可以归类到D[7:0]中一起分析,他们的时序关系基本是一致的(如果存在偏差,也可以忽略不计)。这个波形实际上表达的是从Sensor的芯片封装管脚上输出的PCLK和D[7:0]的关系。而在理想状况下,经过PCB走线将这组信号连接到其他的芯片上(如CPU或FPGA),若尽可能保持走线长度,在其他芯片的管脚上,PCLK和D[7:0]的关系基本还是不变的。那么,对于采集端来说,用PCLK的上升沿去锁存D[7:0]就变得理所当然了。而对于FPGA而言,从它的管脚到寄存器传输路径上总归是有延时存在的,那么PCLK和D[7:0]之间肯定不会是理想的对齐关系。而我们现在关心的是,相对于理想的对齐关系,PCLK和D[7:0]之间可以存在多大的相位偏差(最终可能会以一个延时时间范围来表示)。在时序图中,Tsu和Th虽然是PCLK和D[7:0]在Sensor内部必须保证的建立时间和保持时间关系,但它同样是Sensor的输出管脚上,必须得到保证的基本时序关系。因此,我们可以认为:理想相位关系情况下,PCLK上升沿之前的Tsu时间(即15ns)到上升沿后的Th时间(即8ns)内,D[7:0]是稳定不变的。同样的,理想情况下,PCLK的上升沿处于D[7:0]两次数据变化的中央。换句话说,在D[7:0]保持当前状态的情况下,PCLK上升沿实际上在理想位置的Tsu时间和Th时间内都是允许的。请大家记住这一点,下面我们需要利用这个信息对在FPGA内部的PCLK和D[7:0]信号进行时序约束。
7 \$ K; u' U7 d- L
0 k. q2 T# y. p4 j2 }
% `& T7 a. d; [% ^- m0 \+ d" S% E7 C8 E* j D& q3 x* m
OK,明确了PCLK和D[7:0]之间应该保持的关系后,我们再来看看他们从CMOS Sensor的管脚输出后,到最终在FPGA内部的寄存器进行采样锁存,这整个路径上的各种“艰难险阻”(延时)。1 u& B) s Z6 _; _
) s: `: O# U$ y/ D
; F! X' q2 O: \
/ C3 e; p% h% I' F4 I% V) E在这个路径分析中,我们不去考虑CMOS Sensor内部的时序关系,我们只关心它的输出管脚上的信号。先看时钟PCLK的路径延时,在PCB上的走线延时为Tcpcb,在FPGA内部,从进入FPGA的管脚到寄存器的时钟输入端口的延时为Tcl。再看数据D[7:0]的延时,在PCB上的走线延时为Tdpcb,在FPGA内部的管脚到寄存器输入端口延时为Tp2r。而FPGA的寄存器同样有建立时间Tsu和保持时间Th要求,也必须在整个路径的传输时序中予以考虑。2 M M. R; s* H( ?# p1 H* |1 b7 p
, h+ r) r# ?/ k/ O" ]: p
2 L2 S u g9 Z5 }另外,从前面的分析,我们得到了PCLK和D[7:0]之间应该满足的关系。那么,为了保证PCLK和D[7:0]稳定考虑的得到传输,我们可以得到这样一个基本的关系必须满足:) f0 }, p$ _' I2 ~! i
) O. h, f) m, z1 G
对于建立时间,有:+ A, H; i. Y, x% X' z! C; k
6 k* E" \( k) H" Z0 qLaunch edge + Tdpcb + Tp2r + Tsu < latch edge + Tcpcb + Tcl
6 _2 {- C0 ?4 p6 e2 I& H7 J8 b
对于保持时间,有:; a" _) l N& }9 L7 @
6 N5 `+ H2 Z1 O, T) BLaunch edge + Tdpcb + Tr2p < latch edge + Tcpcb + Tcl – Th6 q. E6 ~; Y; I* m* b
' Z1 z. Z% c1 h7 F5 y
关于launch edge和latch edge,对于我们当前的设计,如下图所示。7 h c5 Q1 X- e
' N$ v* ^. ]8 n2 \! G/ ~
, ^0 n) I0 r& S( o. v2 b
1 n7 p1 e' T3 k. {. |! o在对这个FPGA的input接口的时序进行分析和约束之前,我们先来看看Altera官方是如何分析此类管脚的时序。3 b ]1 P4 Z/ ^
, c9 D4 r8 x& K& l9 u
- `2 @# d( M, s) c: q! V3 U$ I6 V8 U6 `; Y/ m4 R7 H% H& J
具体问题具体分析,我们当前的工程,状况和理想模型略有区别。实际上在上面这个模型的源寄存器端的很多信息都不用详细分析,因为我们获得的波形是来自于Sensor芯片的管脚。同理,我们可以得到input delay的计算公式如下。: F5 {0 ]0 F+ S- J# J
% J* O3 e3 Y+ h ?4 J) dInput max delay = (0 – Tcpcb_min) + Tco_max + Tdpcb_max7 C9 K% u7 k( J/ |- x3 q2 Q
: Z3 _1 A# b6 y' Q$ c+ t9 |Input min delay = (0 – Tcpcb_max) + Tco_min + Tdpcb_min
2 n: D5 R3 x- N) j, P) s( b' f8 y$ D' Q: W: @- B% {- R
在这两个公式中,参数Tco是前面我们还未曾提到的,下面我们就要分析下如何得到这个参数。Tco指的是理想情况下数据在源寄存器被源时钟锁存后,经过多长时间输入到管脚上。前面我们已经得到了PCLK和D[7:0]之间的关系,其实从已知的关系中,我们不难推断出Tco_max和Tco_min,如图所示。若PCLK的时钟周期为Tpclk,则:" |! W8 {; c! p: M
' e: y: D9 o r4 d- |1 b, VTco_max = Tpclk – Tsu
$ p( u# s6 i3 Z3 o3 C- E3 ~; H+ j/ M1 v, {+ q, q
Tco_min = Th( G+ |" s7 d# H# D
# K. F: y6 |* t, m在我们采样的CMOS Sensor图像中,PCLK频率为12.5MHz,即80ns。因此,我们可以计算到:- e }! D; |: A
9 d# k/ J" L$ S# \3 K. RTco_max = 80ns – 15ns = 65ns0 ~! ~1 j' t2 p9 ?. R9 ^
% g- x; g' B5 K4 zTco_min = 8ns
7 _! p1 ^& n1 a* F; L! E+ l1 n9 y& |% d# v: t6 \7 Q/ O
d, a6 W& K: r( i1 d% C7 W9 R, Y# x
我们再看看PCB的走线情况,算算余下和PCB走线有关的延时。1 s0 c( k# w! d/ S, b
2 y- W4 T' s+ v' p! `9 E7 a* f: o如图所示,这是PCLK和D[7:0]在SF-CY3核心板上的走线。: r' L' {/ S# z( q* v
; V9 ]* x$ X/ T
5 E D! u- I4 c u% x5 S
, p- v* p0 I* B3 P+ r0 `1 W如图所示,这是PCLK和D[7:0]在SF-SENSOR子板上的走线,在这个板子上的走线由匹配电阻分两个部分。
0 [6 A# O) X" u3 k2 }" H9 }5 T$ d# m" n f7 @! J, q
- Y2 y: \4 n6 @% N1 f* o" V: i* P: r; l% J1 K) u
根据前面的走线长度,我们可以换算一下相应的走线延时,如下表所示。因此,我们可以得到,Tcpcb_max = 0.35ns,Tcpcb_min = 0.35ns,Tdpcb_max = 0.36ns,Tdpcb_min = 0.31ns。
g1 C! I7 m- `& u u8 k
4 ~! w# D+ K' k# \9 f9 O/ x0 X1 s( R1 n5 x
9 j( e6 l* I) s8 p* q2 r) e2 U. `% p, O5 g1 X/ Y& F- P- Z9 A8 _
$ ?. R* r8 D. H' G
) N! x$ a7 n% r6 g: i9 C
将上面得到的具体数值都代入公式,得到:
( U {" C6 V. N/ b3 }; C: j# x$ ~4 g# j; v8 {; t. l! D; @
Input max delay = (0 – 0.35ns) + 65ns + 0.36ns = 65.01ns8 \6 G. w; O4 X! d
$ Y+ t& I! ~! c
Input min delay = (0 – 0.35ns) + 8ns + 0.31ns = 7.96ns
! r. U2 p; [8 @, T% p5 H. u" o. z2 ]9 U4 ~) J# E( F+ S+ A
加上一些余量,我们可以去input max delay = 66ns,input min delay = 7ns。
]2 Z) h6 B- V3 {1 v; a0 Z
0 i4 Q. O: N! C& F下面我们来添加时序约束,打开TimeQuest,点击菜单栏的ContraintsàCreat Clock,做如下设置。) D/ P" W" u2 U$ L6 B
$ @7 \' m, | {+ ]) z9 Y6 C
! w; P# o" y* C1 `$ H$ N. [0 } r9 y4 }6 B1 S2 L
点击ContraintsàSet Maximum Delay,对vdb[0] vdb[1] vdb[2] vdb[3] vdb[4] vdb[5] vdb[6] vdb[7] vhref的set_max_delay做如下设置。( j; i8 z* C# E' y% M" _! }9 [0 J9 t
8 y& L6 d+ B: [, }( x: p
7 H+ O, e* R& F" m8 W# y" O) {2 o: } i4 y9 {
点击ContraintsàSet Minimum Delay,对vdb[0] vdb[1] vdb[2] vdb[3] vdb[4] vdb[5] vdb[6] vdb[7] vhref的set_min_delay做如下设置。
. }- }) A# O3 ?) ]. b. K, m9 w5 R0 H+ d. k( W* B [
[! |3 y1 B! H& t9 c7 S( q
$ ~: ~4 S- E2 o @5 Q f约束完成后,参照前面章节Update Timing Netlist并且Write SDC File…,接着就可以重新编译整个工程,再来看看这个时序分析的报告。在报告中,数据的建立时间有9-13ns的余量,而保持时间也都有7-11ns的余量,可谓余量充足。' |; _7 N& s! X. _0 C r
1 E6 j' N' c8 T* w8 X# a a1 Y' e) V2 N
# \! U# h6 J; T6 E, @
, C# |3 P) A# c# k$ g$ H B/ X8 l
6 U) N+ M t4 r. X/ k
! i6 }# E# [5 z& N6 r1 ?( B另外,我们也可以专门找一条路径出来,看看它的具体时序路径的分析。vd[0]这条数据线的建立时间报告中,66ns的input max delay出现在了Data Arrival Path中。9 `3 z! K" z+ A6 w2 D
& n+ m% @" M P8 w. ]7 r- w
& d- F6 ?$ [+ e4 h: D) W: L1 r+ `7 x
而在vd[0]的保持时间报告中,7ns的input min delay则出现在了Data Arrival Path中。
* i& u. Q Y5 d+ X# Q+ J, @; m5 l( R& p( w! }4 q+ N& `1 _2 |
1 U, ~8 Q2 t4 o& q+ W
8 Y6 }8 F' |9 i& s( D' `( n! _
' I6 J L2 l- v6 x% I |