DC學習(5)基本時序約束


參考http://www.cnblogs.com/IClearner/p/6624722.html,寫得很好

一:時序約束

1:分類

  時鍾的約束(寄存器-寄存器之間的路徑約束),輸入延時的約束,輸出延時的約束

2:時序約束對電路的要求

  綜合工具現在不能很好地支持異步電路,甚至不支持異步電路;

  single clock,single cycle,單個時鍾,單延觸發,不要一會posedge,一會negdege

3:同步電路常見結構

  

  具體路徑如下圖

  

  起點定義:

    輸入端口;(input port)

    觸發器或寄存器的時鍾引腳

  輸出端口:

    輸出端口;

    時序器件的除時鍾引腳外的所有輸入引腳

  如在下面這個電路圖中:

  

  有4條路徑:

      *從輸入端口A到FF1的D端口

      *從FF1的CLK端到FF2的D端

      *從FF2的CLK端到輸出端口out1

      *從輸入端口A到輸出端口out1

   路徑的特性是存在延時,也就是說,路徑1、2、3、4都存在有延時,延時最長的一條路徑稱為關鍵路徑。一般情況下,路徑1、2、3是最常見的,路徑4比較少見。

二:常見的時序路徑約束

1:建立時間,保持時間,亞穩態

  *建立時間: 時鍾有效沿到來之前的某段時間內,數據必須穩定,否則觸發器鎖存不住數據,這段時間稱為建立時間,用Tsetup或者Tsu表示

  *保持時間:   時鍾有效沿到來之后的某段時間內,數據也必須穩定,否則觸發器鎖存不住數據。這段時間稱為保持時間,用Thold或者Th表示

  

  在第二個時鍾上升沿的時候,要鎖存住輸入端D的高電平,D1是滿足了建立時間和保持時間的情況;而D2則是建立時間沒有滿足,因此不能成功鎖存住輸入的高電平;D3保持時間不滿足,也不能成功鎖存輸入的高電平。

  *亞穩態:每個觸發器都有其規定的建立(setup)和保持(hold)時間參數,該參數存放在由半導體廠商所提供的工藝庫中。假如觸發器由時鍾的上升沿觸發,在這個時間參數內,輸入信號是不允許發生變化的。否則在信號的建立或保持時間中對其采樣,得到的結果是不可預知的,有可能是0或者1,即亞穩態。

2:路徑2寄存器到寄存器間的約束(從FF1的CLK端到FF2的D端)

     為什么要約束時序路徑?是為了滿足寄存器的建立時間和保持時間。對於路徑2,數據從FF1的D端口傳輸到FF2的D端口,主要需要經歷觸發器的翻轉時間/轉換延時、寄存器與寄存器之間的組合邏輯延時、連線延時這些種延時。因為數據是隨着時鍾的節拍一拍一拍往后傳的,因此這里的寄存器與寄存器之間的路徑約束,就是對時鍾的建模,或者是說對時鍾的約束。下面進行說明

  為了滿足FF2建立時間的要求,也就是數據從FF1的CLK端口到達FF2的D端口再加上FF2的建立時間,不能超過時鍾周期;也就是說(觸發器的翻轉時間/轉換延時、寄存器與寄存器之間的組合邏輯延時、連線延時這些種延時)不能過大。例如:

  *為滿足建立時間的需求:現在的節拍(0ns這一時刻)到來后,數據(比如高電平)從FF1的D端傳來,經過組合邏輯,在下一個節拍(20ns時刻)的時候傳到FF2的D端,更新FF2的數據(0ns時,FF2保存的是低電平),如紅色箭頭所示;由於延時過大,在下一個節拍帶來時刻(20ns時刻),數據(高電平)還在組合邏輯那里,如綠色箭頭,導致FF2的D端數據不能更新,或者滿足不了建立時間,由此可能引起鎖存錯誤。通過對時鍾建模,DC就知道了這條路徑運行的最大延時,就會選擇合適的單元來滿足這些延時的約束。如果DC選來選去,發現最牛逼的單元得到的電路延時還是很大,無法滿足FF2的建立時間要求,DC就會報錯。這個時候,你就要進行修改設計了(比如修改約束或者修改代碼)。

  *為滿足保持時間的需求:也就是數據經過上面的延時(觸發器的翻轉時間/轉換延時、寄存器與寄存器之間的組合邏輯延時、連線延時)之后到達FF2的D端的時間,不能小於某個值。也就是說,這些延時也不能太小。舉個極端的例子說,在0ns的時候,觸發器有效沿到來,FF1和FF2都要更新下數據,FF1准備鎖存高電平,FF2准備鎖存低電平;由於FF1反應很快,電路延時很小,FF1寄存住的高電平很快就會傳到FF2的D端口,高電平就會沖掉FF2要鎖存的低電平(也就是FF2的D端口低電平還沒有穩定,違反了保持時間),也就是說會導致低電平對FF2的保持時間不能得到滿足,導致FF2更新數據失敗,要鎖存住的低電平可能就產生亞穩態。因此就有傳輸延時需要大於FF2的保持時間

  此外,我們由此也可以知道,保持時間的分析比建立時間的分析提前一個時鍾周期沿,也就是說在0ns時候傳輸數據,建立時間是在下一個時鍾上升沿(20ns時刻)進行檢查FF2的D端口數據是否穩定(若不穩定,就違反了建立時間),而保持時間是在發送數據的同一時刻(也就是0ns時刻)檢查FF2的D端口數據是否穩定(如果不穩定,就違反了保持時間);關於保持時間的分析比建立時間的分析提前一個時鍾周期沿這一點需要注意。

  然而,保持時間一般是能夠滿足的,也就是傳輸延時一般是大於觸發器的保持時間的,即使滿足不了,在后端版圖設計的時候,也可以有修改措施(比如路徑加緩沖器增加延時)。因此我們在約束的時候,我們一般不關注保持時間,而是注重建立時間。

  *時鍾約束

  寄存器與寄存器間的延時小於時鍾周期減去建立時間,即:2 path delay <= Clock Period - Tsetup

  定義時鍾周期的命令為:create_clock。例如:create_clock -period 10 [get_ports clk] 

  定義時鍾時(虛擬時鍾除外,虛擬時鍾在后面說),我們必須定義時鍾周期(也就是-period這個選項)和時鍾源(端口或引腳)(也就是設計中的clk),也可以加上一些可選項(option)來定義時鍾的占空因數(duty cycle),偏移(offset/skew)和時鍾名( clock name),我們可以通過man create_clock 來查看命令的相關選項。

  一旦定義了時鍾,對於寄存器之間的路徑,我們已經做了約束。我們可以用report_clock命令來查看所定義的時鍾以及其屬性。如果我們需要使用時鍾的兩個沿(上升沿和下降沿),時鍾的占空因數將影響時序的約束。

  然而單單定義一個時鍾周期進行約束寄存器與寄存器之間的路徑很顯然是過於理想的,需要再添加其他的時鍾屬性,在添加之前,需要知道時鍾的偏移(skew)、抖動(jitter)、轉換時間(transition)、延時(latency)這幾個概念或者這幾個時鍾的屬性。

 3:路徑1輸入端口A到寄存器D端的約束

  

  這里討論的是模塊前后使用的是同一個時鍾CLK,如果使用不同時鍾,那么約束就不同了。

  

  在上圖中,CLK時鍾上升沿,通過外部電路的寄存器FF1發送數據經過輸入端口A傳輸到要綜合的電路,在下一個時鍾的上升沿被內部寄存器FF2接收。它們之間的時序圖如下圖所示:

  

  對於我們要綜合的模塊,DC綜合輸入的組合邏輯,也就是上面的電路N,得到它的延時是Tn,但是這個Tn是否滿足要求呢(比如觸發器建立時間的要求)?在進行約束1之前,DC是不知道的,因此我們通過約束這條路徑,也就是告訴DC外部的延時是多少,比如Tclk-q + Tm,在約束了時鍾之后,DC就會計算這條路徑留給電路N的延時是多少,也就是,然后DC就拿Tclk-(Tclk-q+Tm)和Tn+Tsetup相比較,如果Tn較大(Tn+Tsetup>Tclk-(Tclk-q+Tm)),那么DC就會進行優化,使Tn減少,如果Tn還是過大,DC就會報錯。因此我們要進行輸入端口的約束,告訴外部電路的延時是多少,以便DC約束輸入的組合邏輯。

  如果我們已知輸入端口的外部延遲(假設為4 ns,包括翻轉延時和外部的邏輯延時),就很容易計算出留給綜合電路輸入端到寄存器N的最大允許延遲。

  

  DC中,用set_input_delay命令約束輸入路徑的延遲

  set_input_delay -max 4 -clock CLK [get_ports A]

  我們指定外部邏輯用了多少時間,DC計算還有多少時間留給內部邏輯。在這條命令中,外部邏輯用了4 ns,對於時鍾周期為10 ns的電路,內部邏輯的最大延遲為10 - 4 - Tsetup  =  6 。

  例如:對於下面的電路。

  

  輸入端口延時的約束為

  creat_clock -period 20 [get_ports CLK]

  set_input_delay -max 7.4 -clock CLK [get_ports A]

  對應的時序圖如下所示:

  

  如果觸發器U1的建立時間為1ns,則N邏輯允許的最大延遲為:

  20-7.4-1=11.6ns

  上面是沒有考慮不確定因素情況,當考慮不確定因素時,則有:

  當有抖動和偏移的時候(假設不確定時間為U),如果觸發器U1的建立時間為1ns,外部輸入延時為D(包括前級寄存器翻轉和組合邏輯的延時),則N邏輯允許的最大延遲S為:

  20-D-U-1=S,同樣可以得到外部輸入的延時為:20-U-1-S=D

   當輸入的組合邏輯有多個輸入端口時,如下圖所示:

  

  則可以用下面命令對除時鍾以外的所有輸入端口設置約束:

  set_input_delay -max 3.5 -clock CLK [romove_from_collection [all_inputs] [get_ports CLK]];#表示從所有輸入端口中除掉時鍾CLK。 

4:路徑3,寄存器到輸出端口的約束

  

  

  clk時鍾上升沿通過內部電路的寄存器FF2發送數據經要綜合的電路S,到達輸出端口B,在下一個時鍾的上升沿被到達外部寄存器的FF2接收。他們之間的時序關系如下圖。

  

  當我們已知外部電路的延遲(假設為5.4ns),就可以很容易計算出留給要綜合電路輸出端口的最大延遲,如下圖所示:

  

  在DC中,用set_output_delay命令來約束輸出路徑的延遲,對於上面的電路,有

  set_output_delay -max 5.4 -clock CLK [get_ports B]

  內部邏輯最大延遲為:Tclk_q+Ts=Tclk-5.4

5:輸入路徑延時與輸出路徑延時的實際情況

  進行SOC設計時,由於電路比較大,需要對設計進行划分,在一個設計團隊中,每個設計者負責一個或幾個模塊。設計者往往並不知道每個模塊的外部輸入延遲和/或外部輸出的建立要求(這些要求或許在設計規格書里面寫有,或許沒有,當沒有的時候設計者就不知道了),如下圖所示:

  

  這時,我們可以通過建立時間預算(Time Budget),為輸入/輸出端口設置時序的約束,也就是先預置這些延時,大家先商量好(或者設計規格書聲明好)。但是預置多少才合適呢?就有下面的基本原則了:

  DC要求我們對所有的時間路徑作約束,而不應該在綜合時還留有未加約束的路徑。我們可以假設輸人和輸出的內部電路僅僅用了時鍾周期的40%。如果設計中所有的模塊都按這種假定設置對輸人/輸出進行約束,將還有20%時鍾周期的時間作為富余量( Margin),富余量中包括寄存器FF1的延遲和FF2的建立時間,即:富余量=20%時鍾周期 -  Tclk-q  -  Tsetup

 如下圖所示:

     

  舉個例子說,對於前面的電路,就要按照這么一個比例進行設置:

     

  對應的約束為:

  create_clock  -period  10  [get-ports CLK]

  set_input_delay  -max   6  -clock  CLK   [all_inputs]

  remove_input_delay  [get ports CLK]  ;#時鍾不需要輸入延遲的約束

  set_output_delay  -max   6  -clock CLK  [all-outputs]

5:路徑4的約束

   路徑4是組合邏輯的路徑,組合邏輯的約束可能需要虛擬時鍾的概念。組合邏輯可能有兩種中情況,一種是前面電路中的路徑4:

   

  

  模塊里面有輸入端口到輸出端口的組合邏輯外,也有時序邏輯,也就是模塊里面有時鍾,那么就可以對於路徑4,就下面的電路模型進行約束:

         

  組合邏輯部分F的延時Tf就等於時鍾周期T-Tinput_delay-Toutput_delay,時鍾周期減去兩端,就得到了中間的延時約束了,對於上面的模型,可以這樣約束為:

  set_input_delay  0.4  -clock  CLK  -add_delay [get_ports B]

  set_output_delay    0.2  -clock  CLK  -add_delay [get_ports D]

  set_max_delay   $CLK_PERIOD  -from [get_ports B]  -to  [get_ports D]

  當然,最后一句的約束可有可無。對於多時鍾的同步約束,只需要修改相應的延時和時鍾就可以了,可以參考前面的多時鍾同步時序約束那里。

6:純組合邏輯,內部沒有時鍾

  用到虛擬時鍾的概念,create_clock -name VCLK -period 2   ;#指定一個虛擬時鍾名稱。

三:其他

1:當輸入延時不同時,第二個輸入延時命令會覆蓋第一個輸入延時命令

  

 

四:實戰

1:啟動DC,

  list_designs ;#打開當前設計

  remove_design -hierarchy;#移除設計

  

2:讀verilog(analyze - elaborate)

   analyze -format verilog ./rtl/TOP.v

  elaborate architecture verilog TOP

3:檢查設計

  link

  check_design

3 :輸入約束條件(在這里是在dc_shell里一個一個設置,實際會新建一個約束文件,讀約束文件source file.con)

  *在添加約束之前,使用reset_design清除前面存留的約束。

  *添加時鍾頻率:create_clock -period 2 [get_ports Clk]

  *添加輸入端口延時

  

  *添加輸出端口延時

  

  3.1:若寫的是腳本約束,檢查語法命令:shell腳本下   dcprocheck  ./script/file.con

4:檢查所有路徑是否約束

  check_timing

  出現error則有路徑沒有約束完

5:編譯

  compile 

6:綜合后的檢查(檢查不通過的需要優化,這里只作為一般流程,沒有進行優化)

  report_constraint -all  (查看是否違規)

  report_timing (查看時序報告)

  report_area (查看面積情況)

 

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM