本文如果有錯,歡迎留言更正;此外,轉載請標明出處 http://www.cnblogs.com/IClearner/ ,作者:IC_learner
之前講了基本的時序路徑約束,現在我們來看一下其他的約束,然后通過實戰來講解一些其他的約束。實戰中也沒有前面的“理論”中的約束類型,但是可以通過實戰來了解其他的約束。本文的具體內容是:
·多時鍾同步約束
·門控時鍾的約束
(實戰:)
·正負邊沿觸發器的約束
·輸入輸出延時的非默認約束
·輸入輸出有多個路徑驅動(類似多時鍾同步)
1、多時鍾同步的時序約束
前面的講了基本的時序路徑約束,也就是那些約束是基於類似下面電路類型的:
模塊前后的時鍾是同一個,因此輸入輸出邏輯的路徑延時約束也變得簡單。下面我們來對多時鍾同步設計的時序路徑進行約束,多時鍾電路的模型如下所示:
我們要綜合的模塊的時鍾是CLKC,但是前后模塊的時鍾不一定是CLKC,但是前后模塊的時鍾跟CLKC是來源於同一個時鍾的,比如說經過鎖相環分頻或者倍頻,這里拿分頻來舉例,比如說CLKA、 CLKB、CLKC、CLKD、CLKE都是由同一個時鍾CLK經過分頻得來,如下圖所示:
(雖然上面說是同步電路,但是在傳統上看,上面的電路不算是同步時鍾,因為他們的相位沒有固定的關系;但是在這里,我們“假裝”它們是同步時鍾,因為理論上,是由同一個時鍾分頻得來的,在理想情況下,我們是可以知道它們的相位關系的)
在我們要綜合的電路中,只有一個時鍾端口CLKC,即只有CLKC時鍾驅動要綜合電路中的寄存器。其他的時鍾CLKA,CLKB,CLKD和CLKE在我們要綜合的電路中並沒有對應的時鍾端口。因此,它們並不驅動要綜合電路中的任何寄存器。它們主要用於為輸入/輸出端口延時作約束,可能會出現一個端口有多個約束的情況。
下面我們根據上面的例子作多時鍾的同步設計約束,也就是為下面的電路類型做約束:
CLKC在要綜合的設計中有對應的輸入端口,其定義與單時鍾時一樣,即:
create_clock -period 20 [get_ports CLKC]
由於CLKA,CLKD和CLKE在要綜合的設計中沒有對應的輸入端口,因此需要使用虛擬(virtual)時鍾。虛擬時鍾在設計里並不驅動觸發任何的寄存器,它主要用於說明相對於時鍾的I/O端口延遲,DC將根據這些約束,決定設計中最嚴格的約束。建立虛擬時鍾的格式如下:
上面定義了名字為VCLK的虛擬時鍾,周期為20ns。因為虛擬時鍾不驅動設計中的任何寄存器,設計中沒有其對應的輸入端口。所以定義中沒有源端口或引腳。由於虛擬時鍾沒有對應的時鍾端口,我們必須給它一個名字。與一般時鍾一樣,虛擬時鍾是DC的內存里已定義的時鍾物體(設計對象),它(們)不驅動(觸發)當前設計中的任何寄存器。用作為輸入/輸出端口設置延遲。
例如,對於下面輸入端口電路:
對應的約束為:
由於是直接知道了外部的約束,因此可以直接約束。注意最后一條那里,這里的輸入路徑的對比時鍾是CLKA,而不是我們要綜合的模塊時鍾CLKC了,此外這里的路徑約束是對於輸入端口IN1而言,因此要具體給出輸入端口的名字,而不能用[get_ports $ALL_IN_EXCEPT_CLK]這樣的了,而是要具體到某些端口了。
其輸入端口的時序關系如下圖所示:
如波形圖所示,要綜合電路的輸入部分邏輯N的延時必須滿足:
20 - 5.5 - Tsetup和10 -5.5 - Tsetup兩個等式中最嚴格的情況,也就是滿足:10 -5.5 - Tsetup
(輸入部分邏輯N的延時Tn滿足:20ns = 5.5ns + Tn + Tsu +Tuncertainty和10ns =5.5ns + Tn + Tsu+Tuncertainty中最嚴格的,Tuncertainty在這里為0)由於是輸入端口,數據是從CLKA時鍾域傳到CLKC時鍾域,因此是從CLKA出發,也就是說數據從CLKA上升沿開始(時刻0),然后CLKC的下一個上升沿到來的時刻(時刻20)捕獲數據,因此留給輸入邏輯的延時是20 - 5.5 - Tsetup;CLKA下一個上升沿(時刻30ns處)又傳輸數據過來,而這時相對於CLKA的下一個CLKC上升沿在40ns處捕獲數據,因此留給輸入邏輯的延時是10 -5.5 - Tsetup;這兩個延時必須同時滿足,故滿足10 -5.5 - Tsetup。
例如對於下面的輸出端口電路:
創建的虛擬時鍾和對應的約束為:
第二條set_output_delay命令里,使用了-add_delay選項,意思時輸出端口OUT1有多個約束,如果不加選項-add_delay,第二個set_output_delay命令將覆蓋(取代)第一條set_output_delay命令,這時,輸出端口OUT1只有一個約束,就達不到我們的預期要的約束了。
時鍾CLKD的頻率為75MHz(300MHz/4),為了計算時鍾周期,我們需要用實數來得到時鍾的周期。要注意的是[expr 1/75*1000]與[expr 1.0/75*1000]得到的結果是不一樣的,前者是0,后者不為0的實數。
上面輸出端口電路的約束對應的時序關系如下圖所示:
要綜合電路的輸出部分S必須滿足:Ts<10-4.5和Ts<6.7-2.5中最嚴格的要求,也就是Ts<6.7-2.5。
(Ts滿足:10ns = Ts + Tuncertainty + 4.5ns和6.7ns=Ts+Tuncertainty+2.5ns中最嚴格的)
與前面的類似,只不過這里是數據輸出端口,CLKC的上升沿是數據發送沿,CLKD和CLKE是數據接收端,因此都是從CLKC出發。比如CLKC分別從0時刻和20時刻出發,到CLKD或者CLKE的上升沿結束,跟前面同理,由此也可以得出最嚴格的延時約束是Ts<6.7-2.5。
由此可見,綜合時,DC計算出所有時鍾的公共基本周期(common base period),計算出每個可能的數據發送/數據接收時間,按最嚴格的情況對電路進行綜合。這樣可以保證得到的結果能滿足所有的要求(約束),達到設計目標。
2、門控時鍾的時序約束
門控時鍾(gated clock)是進行低功耗電路設計的一種有效和常用方法。下圖是門控時鍾的一個例子:
門控時鍾有理想的,也有有問題的情況,如下圖所示:
從上面的電路圖和波形圖中,很容可以看出時鍾的控制邊沿為上升沿,門控使能信號在邏輯高電平起作用(被激活)。如果門控使能信號Cgate在時鍾上升沿之前沒有變化(從有效變成無效或者從無效變成有效),而是上升沿過后,門控信號才發生變化,這時門控電路的輸出會產生毛刺(glitches)。
關於門控制時鍾的使能信號電路模型和時序關系圖如下所示:
對應的門控時鍾約束為:
需要說明的是,DC能自動辨認門控時鍾電路。綜合時,DC將根據上述的約束在門控時鍾電路中增加/刪除邏輯以滿足門控使能信號的建立和保持時間要求。
關於門控時鍾,下面進行簡單敘述。有兩種門控時鍾單元,一種是無鎖存器(latch free)門控時鍾單元,另一種是基於鎖存器(latch based)門控時鍾單元。前面的例子中的門控時鍾單元是無鎖存器的門控單元。基於鎖存器門控時鍾單元的結構如下圖所示:
這種電路結構的行為表現好像一個主從(master-slave)寄存器,它在時鍾的上升沿捕獲門控使能信號。這種結構的門控時鍾單元的輸出如下所示:
我們可以看到基於鎖存器門控時鍾單元不產生毛刺,因此我們建議大家使用這種門控時鍾電路。但是無論使用哪種門控時鍾,都會使其驅動的寄存器時鍾引腳信號不能由輸入端直接控制,從而降低了電路的測試覆蓋率,這是要注意的(關於什么是測試覆蓋率,請參考有關書籍)。
3、實戰
本次的實戰是進行其他選項的時序約束,下面直接來實戰吧,不廢話了:
設計原理圖:
設計規范:
①准備還相關的設計源文件、編寫.synopsys_dc.setu相關的配置文件
這一步跟前面章節的步驟類似,這里不再詳述。
②在前面相關章節的約束基礎上,根據設計規則進行書寫相關的約束條件:
-->首先這個時鍾名字為my_clk,占空比為40%(高電平占40%),沒有偏移(這里的偏移是offset,而不是skew),因此之前創建時鍾的約束可以改為:
create_clock -period 3.0 -name my_clk -waveform {0 1.2} [get_ports clk]
其他的時鍾約束需要把clk改成my_clk,然后在進行其他的輸入輸出等延時約束時,需要注意其對應的時鍾改為my_clk。
-->附加的輸入延時約束:
這里的輸入延時約束是在之前的輸入延時約束的基礎上附加的,我們先來看看這個約束的要求:
1.sel端口的數據也由附加的寄存器F4提供,在F4的時鍾下降沿觸發之后,數據到達sel端口的時間不超過420ps。
2.時鍾信號從時鍾源到F4的時鍾端口有600ps的延時(包括外部的source 延時 和 內部的network延時)。
根據上面兩點,我們可以這么約束:
set_input_delay -max 1.02 -clock my_clk -add_delay -clock_fall -network_latency_included -source_latency_included [get_ports sel]
怎么理解這句約束呢?我們先來看一下set_input_delay -max 這個命令的約束選項:
首先是420ps的延時,這是直接給出了外部的延時;然后呢,又有時鍾信號的延時600ps,因此我們這個附加的輸入延時總量為420ps+600ps = 1.02ns。這里由於是附加的約束條件,因此需要加上-add_delay的選項;由於是下降沿觸發,因此需要-clock_fall的選項;最后需要指明這延時不是添加在輸入延時上面的,而是包含在本身的時鍾延時上面的。
-->附加的輸出延時約束:
首先1.那里的意思是說輸出端口out1的數據被F5寄存器捕獲;在F5的下降沿到來之前,數據必須不晚於260ps到達out1端口,如下圖所示:
情況a是符合要求的,而情況b是不符合要求的。
然后是2.那里,意思是F5的network延時有500ps;當沒有這個延時要求的時候,我們在下降沿附加的外部延時約束就是260ps,但是由於這500ps的延時,導致了下降沿推后,如下圖所示:
這個時候,外部延時的約束就是260-500=240ps了,也就是說,模塊內部的組合邏輯增加了240ps的時間延時余量,具體的約束如下所示:
set_output_delay -max -0.24 -clock my_clk -add_delay -clock_fall -network_latency_included [get_ports out1]
-->最后是輸入端負載的約束,每個輸入端口都扇出到另外兩個子模塊(除了clk),每個子模塊在內部驅動相當於3個bufbd1(輸入引腳I)緩沖器,然后要求給輸入端約束這個外部的電容負載;我們得到的約束如下所示:
set all_in_ex_clk [remove_from_collection [all_inputs] [get_ports clk]]
set_load [expr 6 * {[load_of cb13fs120_tsmc_max/bufbd1/I]}] $all_in_ex_clk
③啟動DC,進行讀入設計前的檢查
跟前面章節步驟一樣,不再詳述。
④讀入設計與讀入后的檢查
跟前面章節步驟一樣,不再詳述。
⑤進行約束設計與檢查是否正確約束上
跟前面章節步驟一樣,不再詳述。
⑥進行綜合和綜合后檢查
跟前面章節步驟一樣,不再詳述。
⑦寫出相關的報告或者文件
跟前面章節步驟一樣,不再詳述。