zoukankan      html  css  js  c++  java
  • 基于建立/保持时间等的参数化时序分析

    说明

         本文源自作者读研期间的一份作业报告,主要基于建立时间、保持时间等时间约束参数推导时序分析公式,并通过实验进行验证。

         因时间久远,某些实验数据和理论推导可能存在缺失,且难以回忆。若对读者造成理解困难,还请见谅~

         相关实验参见以下两篇文章:

         采用流水线技术实现8位加法器

         Stratix内嵌存储器测试报告

    一  基本概念 

         建立时间(SetUp Time, tsu):触发器在有效时钟沿来到前,其数据输入端的数据必须保持不变的时间;

         保持时间(Hold Time, th):触发器在有效时钟沿来到后,其数据输入端的数据必须保持不变的时间。

         输入信号应提前时钟上升沿(如上升沿有效)tsu时间到达芯片,这个tsu就是建立时间。如果建立时间和/或保持时间不够,数据将不能在这个时钟上升沿被打入触发器。如下图所示:

     

    图1  建立时间与保持时间

         设时钟上升沿位置为t,则数据最短持续时间段为(t – tsu) ~(t + th)。

         补充一点,Quartus里定义tsu、th为:

    tsu =  <pin to register delay> + <micro setup delay> - <clock to destination register delay>

    th  =  <clock to destination register delay> + <micro hold delay> - <pin to register delay>

          可知,对于特定的路径,tsu + th = MicrotSU + MicrotH为常数,这也就是数据最短持续时间。其中,MicrotSU/MicrotH指触发器内部固有建立/保持时间,典型值一般小于1ns。

         注意,文中建立时间和保持时间均针对时钟而言,在进行时序约束时所指的就是这种;而有些书籍中建立时间和保持时间的概念针对信号而言,所指对象不同,分析结论可能完全相反,请勿混淆。

    二  时序分析

    2.1 实验一非流水线加法器

         打开adder_nonpipe.tan.rpt或Processing->Compilation Report时序分析报告,简化如表1所示:

    表1  8位加法器(非流水线/FPGA)时序分析之简表

              Type

         Actual Time

                From

                   To

       From Clock

       To Clock

    Worst-case tsu

    3.391ns

    inb[1]

    tempb[1]

    --

    enable

    Worst-case tco

    8.291ns

    sum[4]~reg0

    sum[4]

    enable

    --

    Worst-case th

    -2.399ns

    ina[2]

    tempa[2]

    --

    enable

    Clock Setup: 'inclk'

    period=2.369ns*

    tempb[0]

    sum[7]~reg0

    enable

    enable

         注:

    1. ..ns* 对应fmax=422.12MHz,实际时钟周期为10ns,占空比为1:1。
    2. tco: from clock "enable" to destination pin "sum[4]" through register "sum[4]~reg0"
    3. tsu取最大值,得数据最前端(ina 8路并不同步);th取绝对值最小者,得数据最末端。

         实际最大建立时间和最小保持时间如表2所示:

    表2  8位加法器(非流水线/FPGA)时序分析之tsu与th

    Actual Maximum tsu

    Actual Minimum th

    From

    To

    第一周期内数据位置

    3.166ns

    -3.056ns

    cin

    tempc

    1.834ns ~ 1.944ns(高)

    3.138ns

     -2.399ns**

    ina[n] (n=0..7)

    tempa[n]

    1.862ns ~ 2.601ns

     3.391ns**

    -2.550ns

    inb[n] (n=0..7)

    tempb[n]

    1.609ns ~ 2.450ns

         注:..ns**为worst-case情况下的tsu/th时间。

         初始化波形如图2所示:

    图2  8位加法器(非流水线/FPGA)时序分析之初始波形

         仿真结果如图3所示:

    图3  8位加法器(非流水线/FPGA)时序分析之仿真图

         注意:

         1.  对于某些输入数据,cin、ina、inb可以更“窄”。如:

              cin:  1.844ns ~ 1.850ns

              ina:  1.948ns ~ 2.601ns

              inb:  1.619ns ~ 2.450ns

         结果也正确,但并不能保证对于所有输入,输出均正确。

         红色ns时间不可越界,时间精度为0.001ns。如cin取1.845ns ~ 1.944ns时,输出不正确。

         所以,对于建立时间/保持时间确定的数据时间段为(t – tsu) ~(t + th),宜宽不宜窄。

         2.  图3中第一个时钟上升沿为5.0ns,下降沿为7.632ns(原时钟下降沿在10ns处)。当时钟下降沿设为7.632ns之前(如7.631ns)时,输出数据正确,但却延迟了两个周期,相当于第二个时钟周期内并未采到数据,直到第二个时钟上升沿到来时才采样输出。不知道为什么会这样。不过,这种脉宽不同的时钟在实际中似乎并无意义。时钟脉宽可以非常窄,但是各个脉宽不同的话,输出不可预料。

    2.2 altsyncram测试实验

         altsyncram宏单元结构如图4所示:

     

    图4  altsyncram宏单元结构

         此处给出宏单元结构,是因为我在做仿真时序分析时,想当然地认为outclk对输入地址和数据采样并输出(读出)。其实图4中清楚地表明,只有inclk上升沿采样锁存读/写地址和数据,经过一段延时后由outclk上升沿触发输出——outclk的功能类似读使能信号!

         时序编译报告如表3所示:

    表3  altsyncram读写测试时序分析之简表

    Type

    Actual Time

    From

    To

    From Clock

    To Clock

    Worst-case tsu

    3.523ns

    addr_a[1]

    porta_address_reg1

    --

    inclk

    Worst-case tco

    7.818ns

    altsyncram|q_a[5]

    q_a[5]

    outclk

    --

    Worst-case th

    -2.346ns

    data_b[7]

    portb_datain_reg0

    --

    inclk

    Clock Setup: 'inclk'

    period=3.438ns*

    porta_datain_reg7

    porta_memory_reg7

    inclk

    inclk

         注:

         1. ..ns* 对应fmax=290.87MHz,实际时钟周期为8ns,占空比为1:1。

         2. tco: from clock "outclk" to destination pin "q_a[*]" through memory "altsyncram0: inst|altsyncram: altsyncram_component|altsyncram_8982: auto_generated|q_a[*]"                                                                                  

         实际最大建立时间和最小保持时间如表4所示:

    表4  altsyncram读写测试时序分析之tsu和th

    Actual Maximum tsu

    Actual Minimum th

    From

    To

    To Clock

     3.523ns**

    -2.626ns

    addr_a[n] (n=0..7)

    porta_address_regn

    inclk

    3.510ns

    -2.400ns

    addr_b[n] (n=0..7)

    portb_address_regn

    inclk

    3.429ns

    -2.605ns

    data_a[n] (n=0..7)

    porta_datain_regn

    inclk

    3.383ns

     -2.346ns**

    data_b[n] (n=0..7)

    portb_datain_regn

    inclk

    2.640ns

    -2.475ns

    wren_a

    porta_we_reg

    inclk

    2.825ns

    -2.660ns

    wren_b

    portb_we_reg

    inclk

         注:..ns**为worst-case情况下的tsu/th时间。

         如前所述,inclk上升沿采样锁存地址和数据,经过一段延时δ后由outclk上升沿触发输出。δ的最小值近似等于电路内部最小时钟周期,即

    δmin = Shortest clock path from clock "inclk" to destination memory(2.875ns)

                + Micro clock to output delay of source(0.420ns)

                + Micro setup delay of destination(0.131ns)

                - smallest clock skew(-0.012ns)

            = 3.438ns

         而从outclk上升沿到输出寄存器输出数据的延时即为tco,即最大延迟为7.818ns(最小延时则为6.906ns)。

         仿真结果如图5所示:

    图5  altsyncram读写测试时序分析之仿真图

         inclk、outclk都是上升沿触发,与持续时间无关(即时钟脉冲可以非常窄)。

         此处未考虑极限情况。其实 tsu、th、tco等参数就描述了所谓的“极限读写”,而tco指示了与时钟触发沿对应的输出(比照输入输出时很有用)。

         分析b路数据。第n个时钟上升沿用inclk_n/outclk_n表示,数据和地址内容用signal_b'x表示(如data_b为2时表示为data_b'2)。时钟有效沿之后δ时间处称为δ临界点。

         当inclk_1来临时,锁入data_b'1和addr_b'1,并在δ临界点之后检测到outclk_2,延时tco时间后输出q_b'1。

         当inclk_2来临时,锁入data_b'3和addr_b'3(注意理解tsu和th),并在δ临界点之后检测到outclk_3。但inclk_3也检测到outclk_3,故更新输出寄存器的输入,并延时tco时间后输出q_b'5。这也意味着要达到连续读写无误,必须在inclk_n的δ临界点之后与inclk_n+1的δ临界点之前这段时间内检测到outclk_n。

         后续数据分析原理同上。注意,时序分析时必须考虑tsu和th,切忌单看波形想当然。

         下面考虑极限读写:

     

    图6  altsyncram极限读写时序示意图

         如图6所示,输入数据a和b的持续时间段为由(t – tsu) ~(t - th)确定。

    T  = tsu_a – th_b

    T' = tsu_a – tsu_b

    head_a2 = t2 – tsu_a

                   = t+ T – tsu_a = t+ tsu_a – th_b – tsu_a

                   = t– th_b

    head_b2 = t2 – tsu_b

                   = t+ tsu_a – th_b - tsu_b = (t– th_b) + (tsu_a – tsu_b)

                   = head_a+ T'

         在T时间内,数据a的前端(head)最靠前,数据b的末端(back)最靠后。当这个head/back分别是所有输入数据的最前/末端时,就得到了极限情况下(Tmax)的时序图。只有满足这个时序要求,才能达到最快速的正确读写。

         极限读写仿真结果如图7所示:

    图7  altsyncram极限读写测试仿真图

         其中inclk、outclk时钟周期均为1.177ns。按“读写周期指连续进行两次读(或写)操作所需要的最小的最短时间间隔”的定义,取1.177ns为写周期。

         仿真波形正确,只是会出现如下警告(影响未知):

         Warning: Found clock high time violation at 6.45 ns on register "|altsyncram_test|altsyncram0: inst|altsyncram:altsyncram_component|altsyncram_8982: auto_generated|q_a[7]~_SIM_0PORT_B_READ_ENABLE"——(这是因为fMAX超过芯片最大工作频率,时钟的high/low电平持续时间不够)

         Warning: Simultaneous write to memory block address 0 at time 6.89 ns in vector source file -- data is invalid in memory block

    三  总结建议

         将时序分析相关概念弄清楚后,结合编译报告中Timing Analyzer项,得到tsu、th、tco等时序参数,再调整波形做仿真试验,将理论分析与实践相比照,互相验证。仿真时可以先做功能仿真(前仿真),其特点是不考虑电路门延迟与线延迟,主要验证电路的功能是否符合设计要求。然后进行时序仿真(后仿真),主要验证是否满足时间约束关系、延时、最大工作频率和消耗的资源等。我在做altsyncram读写测试时,所采用的波形与师兄完全相同,以期重复他的结果。但很快发现,师兄并没有做时序分析,而是“1纳秒1纳秒试出来的”,这种具体的“数字试验”与选用器件密切相关。比如我把inclk时钟周期也设为6ns时,输出与师兄的结果有出入,甚至输出从未写入的值。后来才明白,当周期为6ns时,输入数据无法满足tsu要求而出现亚稳态(Violating the setup or hold time on the address registers could corrupt the memory contents),改为8ns后输出相符。可见不同的器件时序结果有所不同,但其时序关系是一致的。基于这个认识,我在做读写测试时采用“参数化分析”(tsu、th、tco等时序参数)的方法,这样即使更换器件,也不影响分析结论。

         对于延时不明显的简单电路,可以不考虑时序分析。但当涉及多路寄存器时,一般要进行细致的时序分析,以求设计出来的电路满足时序要求。时序分析时要特别注意三点:其一,必须考虑tsu、th、tco及tpd等参数,不要局限于你所看见的仿真波形,要知道存在大延迟时,时钟沿采到的数据很有可能是之前输入的数据!其二,必须对器件电路或程序对应的电路布局有个整体认识,明确各端口信号的关系,这样可以避免很多不该出现的错误。其三,做到前两点后,做极限测试时建议采用“参数化分析”的方法,因为“1纳秒1纳秒试出来的”的结果往往过于依赖环境变量(如所选器件),调整过程也很麻烦,同时也容易造成实践与理解偏差(前者比如RAM的阵列结构决定了地址线高低位的读取有快慢,从而导致特定地址如5'b10000“试”出的时序结果,对于其他地址如5'b00001却不适用;后者就自不待说了)。

    四  附注

         1. 大部分外围器件的读写周期在50ns以上。即便是最快的静态RAM,其读写周期也在8ns左右。而ROM的速度一般远远低于RAM,其访问周期一般为100ns~200ns。

         采用MOS工艺的存储器,存取周期数为数十至数百ns,而双级型RAM存取周期最快可达10ns以下,一般存储周期略大于存取时间,其差别取决于贮存的物理实现细节。

         但对于FPGA内置RAM,读写周期似乎可以达到一两纳秒。

         2. Matlab小程序(便于计算)

     1 clc,clear all;
     2 N = 2;
     3 DataParam = [3.523,2.626; 3.510,2.400; 3.429,2.605; 3.383,2.346; 2.640,2.475; 2.825,2.660];
     4 Interval = max(DataParam(:,1)) - min(DataParam(:,2));
     5 ClkPosedge = max(DataParam(:,1)) + [0:N-1] * Interval;
     6 for idx = 1:N
     7     idx
     8     Clk = ClkPosedge(idx)
     9     DataElapse = ClkPosedge(idx) - DataParam
    10 end
  • 相关阅读:
    hdu 4521 小明系列问题——小明序列(线段树 or DP)
    hdu 1115 Lifting the Stone
    hdu 5476 Explore Track of Point(2015上海网络赛)
    Codeforces 527C Glass Carving
    hdu 4414 Finding crosses
    LA 5135 Mining Your Own Business
    uva 11324 The Largest Clique
    hdu 4288 Coder
    PowerShell随笔3 ---别名
    PowerShell随笔2---初始命令
  • 原文地址:https://www.cnblogs.com/clover-toeic/p/3784272.html
Copyright © 2011-2022 走看看