广告

原创 时序

2012-11-19 19:15 275 0 分类: FPGA/CPLD

在开篇前先推荐两篇文档,一篇是altera的官方文档 Appling Multicycle Execptions in the TimeQuest Timing Analyzer ,另一篇是riple兄很早之前推荐过的Multicycles -Exception Between Two Synchronous Clock,这两篇都是关于多周期约束很好的上手文档,虽然可以快速上手解决当务之急,但事后不免还会有些疑惑。TimeQuest中的多周期约束语法的设置选项有:基于setup(建立时间)的个数,基于hold(保持时间)的个数,start模式和end模式,如下所示。

set_multicycle_path -setup -start from [get_clocks {clk_s}] to [get_clocks {clk_r}] 2

set_multicycle_path -hold -end from [get_clocks {clk_s}] to [get_clocks {clk_r}] 2

但在使用过程中,为什么有时只设置基于建立时间的多周期个数就可以了?而为什么有时建立时间和保持时间的多周期个数都要设置?保持时间设置和建立时间设置存在什么依赖关系?为什么会有start和end两种模式,分别在什么情况下使用?我们是TimeQuest的用户,用户使用产品时只会去关心自己的需求,而用户成千上万,需求也千奇百怪,产品设计者为了满足所有用户,必须提高产品的通用性,最简单的方法就是增加选项模式,当一个需求简单的用户使用这个通用产品时,面对多重的选择和模式,往往会无从下手,因为根本就不知道这些选项设置的作用,自然就会产生上述的那些为什么。要解答这些为什么,我们可以试着换位思考,从TimeQuest设计者的角度出发,如何设计多周期约束的语法规则?

明确设计目的

先来看看一个最常见的发送接收波形如图一所示,A时刻发送的数据B时刻锁存,launch(发送)边沿和latch(锁存)边沿间隔为一个时钟周期。

1

图一

这种情况下,建立时间和保持时间裕量为

setup slack = (current latch edge - current launch edge ) + Tskew - (Tdelay + Tco + Tsu)

= T + Tskew - (Tdelay + Tco + Tsu)

hold slack = Tdelay + Tco - (Th + previous latch edge - current launch edge)

= Tdelay + Tco - Th

其中Tskew是时钟偏斜,Tdelay为传输延迟,Tco为源寄存器的输出延迟,Tsu和Th为寄存器需要的建立保持时间。

如果接收波形整体延迟一个时钟周期,如图二所示,latch边沿改变了,A时刻发送的数据C时刻锁存,B时刻发送的数据D时刻锁存。

2

图二

此时,我们期望的建立时间和保持时间裕量为

setup slack = (current latch edge - current launch edge ) + Tskew - (Tdelay + Tco + Tsu)

= 2*T + Tskew - (Tdelay + Tco + Tsu)

hold slack = Tdelay + Tco - (Th + previout latch edge - current launch edge)

= Tdelay+Tco - (T+Th)

和前一种情况比较,建立时间裕量宽裕了一个周期,保持时间裕量缩紧了一个周期,但TimeQuest并不知道latch边沿变了,如果不进行多周期约束,仍按照前一种情况的裕量去约束,结果就会使得建立时间多了没必要的裕量,而保持时间的裕量可能不足。所谓的多周期是相对单周期而言的,launch和latch默认间隔为单周期,当launch和latch间隔为多个周期时,就需要用到多周期约束了,一个完整的时序分析路径是由Tskew、Tco、Tdelay、Tsu、Th以及launch时刻和latch时刻等共同决定的,后两项会随着用户不同的需求而改变,TimeQuest无法自动获得,所以多周期约束语法规则设计的目的就是准确的告诉TimeQuest波形何时launch何时latch,进行适当的建立保持约束。

明确TimeQuest的需求

我们已经知道了TimeQuest无法自己获取launch时刻和latch时刻,必须由用户提供,那么TimeQuest具体需要哪些信息才能完全了解发送接收波形呢?

举一个典型的多周期波形,如图三所示,A时刻发送的数据B时刻锁存,B时刻发送的数据C时刻锁存,A为current launch,B即为current latch又是next launch,C是next latch。

3

图三

图三的发送接收关系,我们可以表示为下面几个式子:

current latch - current launch = 2个时钟周期

current latch - next launch = 0个时钟周期

previous latch - current launch = 0个时钟周期

由于波形的周期性,后两个表达式是完全等效的,图二的发送接收关系同样可以表示为:

current latch - current launch = 2个时钟周期

current latch - next launch = 1个时钟周期

previous latch - current launch = 1个时钟周期

将这几个表达式推广到更多不同的例子,会发现只要知道了current launch、current latch、next launch和previous latch就能确定任何形式的发送接收波形,因此TimeQuest只需获得这四个量,也就清楚波形的真实情况了。

明确用户的需求

假设用户的波形如图二所示,相比常见的图一单周期波形,建立时间宽裕了一个周期,而保持时间紧缩了一个周期,作为用户,其实并不关心current launch、current latch、next launch和previous latch这些量,只会关注如何把变化了的建立保持关系告知TimeQuest,让其在该放松的地方放宽约束,该紧缩的地方加强约束。

 

整合TimeQuest和用户的需求

多周期约束的作用是让TimeQuest明晰发送接收波形的真实状态,放宽或缩紧建立和保持时间约束,其中TimeQuest期望从用户那得到current launch、current latch、next launch和previous latch这些量,而用户希望告诉TimeQuest真实的建立保持关系。要将用户的诉求准确的转化为TimeQuest的需求,设计者需在两者中做出权衡,所以在多周期语法规则的设定上,不能完全偏袒某一方,双方都要有些取舍。

在语法的选词上,设计者倾向于用户,使用了通俗易懂的setup和hold,表示建立时间和保持时间对应的宽松周期个数,比如下面的语句表示建立时间宽松2个周期,保持时间宽松1个周期。

set_multicycle_path -setup -end from [get_clocks {clk_s}] to [get_clocks {clk_r}] 2

set_multicycle_path -hold -end from [get_clocks {clk_s}] to [get_clocks {clk_r}] 1

宽松的周期个数是要相对默认路径而言的,为了准确的将setup和hold宽松个数准确的转化为current launch、current latch、next launch和previous latch这些量,设计者制定了倾向于TimeQuest的语法规则,用于默认情况下的current launch,current latch,next launch和next latch的定位。

分析默认的建立时间路径规则。TimeQuest先以一个launch边沿为基准定为current launch,再向后寻找距此边沿最近的一个latch边沿定为current latch,并将两者的setup个数定为1个周期。

图四红色线条为发送和接收波形无相移时默认的建立时间路径。

4

图四

图五红色线条为发送和接收波形存在相移时默认的建立时间路径,虽然A和B间距不满一个周期,但TimeQuest为了方便处理,仍将此时的setup定为1个周期。

5

图五

由于默认的建立时间路径setup已被设为1一个周期了,如要宽松1个周期,须在默认的基础上再叠加1个周期,置setup = 2,current latch才会往后移动一个周期,如上图蓝色线所示,结合默认分析规则和setup的个数,TimeQuest就可以定位current launch和current latch。

分析默认的保持时间路径规则。保持时间的检查路径会有两条,一条是current launch到previous latch,另一条是next launch到current latch,当current launch和current latch确定后,TimeQuest会基于单周期分析,默认current launch的后一个时钟为next launch,current latch的前一个时钟为previous latch,并将两条保持时间路径的默认hold个数都设为0,如图六所示。

6

图六

如保持时间宽松1个周期,如图七所示,previous latch会向前移动一个周期,由于波形的周期性,next launch也会向后移动一个周期。

7

图七

结合setup和hold个数以及单周期分析准则,TimeQuest可以知晓previous latch和next launch。由上分析可得,保持时间默认路径是相对current launch和current latch而定的,和建立时间路径存在着间隔单周期的依赖关系,会随着建立时间路径变化而改变。回到开篇的一个疑问:为什么有时只要基于建立时间设置多周期个数就可以了,因为setup设定后,保持路径也会相应改变,如果此时刚好满足用户需求,就不用再设置hold了。

至此,依据设计者制定的规则,已经可以将用户提供的setup和hold周期个数转换为TimeQuest想要的launch和latch信息了,虽然规则不算最直观,但考虑到要满足所有用户的需求,通用性已然成为设计的首要目标(规则越简单,通用性越强,在分析setup,hold时默认基于单周期的分析法则真的不能再简单了),而用户体验在FPGA这个垄断性的行业,苦逼的工程师们真的不要奢望太多。

消除不确定性

上述所举例子的发送接收波形的频率都是相同的,如果频率不同,现有的语法规则就可能出现不确定问题了,如图八所示。

8

图八

仍按照默认的setup路径分析方法,先找一个launch边沿为基准,再去确定之后最近的latch边沿,但会发现存在两个基准,launch边沿A和B对应的最近的latch边沿都是C,launch A到latch C以及launch B到latch C的setup值都为1个周期,此时,TimeQuest无法确定用户波形到底是哪一种。

为了消除歧义,换另一种分析方法,先找一个latch边沿为基准,再确定之前最近的launch边沿,这样current launch和current latch的关系就一一对应了,如图九所示。

9

图九

两种方法的区别在于基准的选择。根据基准的不同,设计者创造了两种模式start和end,start模式参考的基准是latch边沿,end模式参考的是launch边沿,对于同频波形,不存在不确定性,无所谓使用哪种模式,当发送频率比接收频率快一倍以上时需用start模式,同理,当接收频率比发送波形快一倍以上时使用end模式。

综上,经过一个产品设计的大致思考流程(明确产品目标---> 整合用户需求 -----> 准确表达需求)后,我对TimeQuest多周期约束有了更深的认识,不仅知其然,而且知其所以然。其中基于单周期的分析规则对我也有些启发,规则如此简单,但的确能满足要求,当时在分析默认的保持时间路径时,我自己也尝试着想了些规则,但都是从方便用户的角度出发,忽视了TimeQuest的需求,不仅复杂,通用性还不好,可见对需求挖掘的深浅直接影响着产品的复杂度。

从用户角度出发,追求用户体验,这些道理经常被耳提面令,但工欲善其事,必先利其器,在开发过程遇到的一些开发工具的问题,我们可以尝试下换位思考,从设计者的角度出发,往往除了能解决开发工具的疑惑,还能收获一些其他设计者好的思路并应用到自己的设计中。
最后再无力的吐槽一句:一边使用着用户体验极差的开发工具,一边却想着开发用户体验极佳的产品,真的有点为难工程师们了。(TimeQuest,我不是在说你,你已经很不错了)

 

广告

文章评论 0条评论)

登录后参与讨论
相关推荐阅读
570051168_482666829 2012-11-19 19:18
按键消抖
-- Filename ﹕ SW_DEBOUNCE.vhd -- Author ﹕ wuhouhang -- Description ﹕ 三个独立按键控制LED灯亮灭 library IE...
我要评论
0
0
广告
关闭 热点推荐上一条 /1 下一条