FPGA設計之時序約束---常用指令與流程

約束流程

	說到FPGA時序約束的流程,不同的公司可能有些不一樣。反正條條大路通羅馬,找到一種適合自己的就行了。從系統上來看,同步時序約束可以分爲系統同步與源同步兩大類。簡單點來說,系統同步是指FPGA與外部器件共用外部時鐘;源同步(SDR,DDR)即時鐘與數據一起從上游器件發送過來的情況。在設計當中,我們遇到的絕大部分都是針對源同步的時序約束問題。所以下文講述的主要是針對源同步的時序約束。
根據網絡上收集的資料以及結合自己的使用習慣,我比較趨向於下面的約束流程方式:時序約束一共包含以下幾個步驟:時鐘約束、IO約束以及時序例外。這幾個步驟應該可以解決我們設計當中絕大多數情況下的時序約束問題。
	1.首先約束時鐘。輸入時鐘,輸出時鐘。從種類 來看不外乎以下幾種:單端輸入時鐘、差分輸入時鐘、GT或恢復時鐘(例如LVDS信號恢復出來的時鐘)、PLL產生的時鐘以及自己產生的門控時鐘。
	2.IO約束。只有等待內部時鐘完全通過後,再配置input delay和output delays,告知FPGA外部端口的數據時序關係。
	3.時序例外。在約束完時鐘以及IO後,還是有時序違例的時候,注意檢查一下是否有時序例外的情況,例如多週期時鐘路徑、異步時鐘、常量、以及互斥時鐘路徑等等。

常用指令

下面我們就根據約束的流程來介紹一下每個步驟中的常用指令。

時鐘約束

常用指令:Create_clock、Create_generated_clock、derive pll_clocks、create_virtual_clock。

對時鐘的約束,首先要明確,我們要約束的時鐘有哪些,然後針對不同的時鐘進行約束。下面針對不同類型的時鐘,對其約束的指令作簡要分析。

單端輸入時鐘:


圖1   單端輸入時鐘約束

這裏用到了create_clock,一開始不熟悉語法的同學可以通過Timequest 的GUI界面或者Templete裏面的模板裏找到該指令。

差分輸入時鐘:

差分輸入時鐘,只需約束P端輸入時鐘即可,方法同上。

PLL產生的時鐘:

針對PLL產生的時鐘一般有兩種方式。一種是通過derive pll_clocks即可,PLL會根據所設定的參數,自行約束輸出時鐘。這樣做的好處就是,指令少,當PLL煽出的時鐘比較多的時候,很有優勢,不利的地方在於,PLL生產的時鐘名字命名不可把控,區分度不明顯,不利於後續的引用。所以我比較趨向於後面一種方式,是通過Create_clock、Create_generated_clock這兩條指令完成。


圖2   PLL生成的時鐘約束


首先用create_clock指令對輸入的時鐘clk_in進行約束,然後通過create_generated_clock指令對PLL的輸出時鐘進行約束,這裏PLL的輸出時鐘只是做了90°的相位偏移,頻率不變。有童鞋可能會問,如果要倍頻或者分頻呢?該怎樣寫?說實話,一開始學的時候,我也記不得指令的格式。在這裏,再一次強調,在初學的時候,沒有必要去糾結語法。很多時候,約束的時候,只需標明用到的約束信息出來即可,再退一步講,可以通過GUI界面產生相應的指令,你需要做的是明確相關的參數,知道怎麼填就行啦,重點是理解時序約束的流程、應該怎麼去約束纔是重點。

GT或恢復的時鐘

GT或恢復的時鐘(例如高速串口過來恢復出來的時鐘)針對這種情況,一般都是FPGA內部用IP核恢復出來時鍾,約束格式同上。


圖3   GT或者恢復時鐘的約束

自己分頻的時鐘

(不建議這種方法,推薦PLL來產生,如果非要這樣做,務必添加約束)


圖4   自己生成的時鐘

虛擬時鐘create_virtual_clock

官網上的手冊推薦在IO約束的時候,使用虛擬時鐘,尤其是在約束輸入延遲的時候。虛擬時鐘表徵的是上游器件內部用於輸出數據的時鐘(從另一個角度考慮,它表徵的類似SDR模式中第一級D觸發器的時鐘)。通過約束告訴FPGA 的Input_Clock(實際上是Clock_Out)和虛擬時鐘(數據)的相位關係。FPGA根據參數Input_delay在佈線時進行調整使得佈線滿足時序要求。


圖5   虛擬時鐘關係

我們分邊沿對齊和中心對齊兩種模式對輸入進行約束,對於邊沿對齊的信號,我們通常會將其輸入引腳輸入值專用的PLL輸入口,進行90°相移。約束如下所示:注意在對齊模式下,圖6中對clk_in進行約束時不需要進行額外的移相,而僅對clock(經過PLL後的輸出時鐘)進行移相90°。


圖6   邊沿對齊輸入時鐘約束

create_clock-name virtual_clock -period 10

create_clock-name input_clock -period 10 [get_ports clock_in]

create_generated_clock-name plus_90_degrees -source [get_pins PLL|inclk[0]] -phase 90


對於中心對齊模式,其輸入時序模型如圖7所示,其約束圖下方所示。一般而言,對於中心對齊模式,我們FPGA內部不會使用專門的鎖相環對齊進行移相操作,但若依然使用PLL,上述邊沿對齊對PLL的約束方法依然有效。但對clk_in的約束依然要表現出和virtual clock的相位關係。


圖7   中心對齊輸入時序約束

create_clock -namevirtual_clock -period 10

create_clock -nameinput_clock -period 10 [get_ports clock_in] -waveform {2.5 7.5}

IO約束

IO的約束主要是指input_delay與output_delay這兩種,編譯軟件(ISE/Quartus)是個很強大而又很傻的工具,在設計的時候,你務必要告訴他在FPGA外部的信號時序關係,他才能夠知道怎麼去優化內部的時序,以滿足時序設計要求。

Set Input_delay

從輸入來看,無非有以下兩種情況:SDR與DDR。

SDR是指,數據只在時鐘的上升沿更新,而DDR是時鐘的上升沿與下降沿都會更新。按照時鐘與數據對齊方式來劃分,又可以分爲沿對齊與中心對齊兩種。對於輸入延遲的獲取,一般來說有以下三種途徑:文中直接給出Tco、Tdata等參數;通過查閱上級器件的數據手冊;通過示波器來實測。查上游的器件手冊(主要看Tsu 與Th),那麼可以推算出,FPGA輸入延遲的最值,爲了方便描述,這裏設定時鐘與數據在PCB上的傳輸延遲一致:

Input delay max = T – Tsu;

Input delay min = Th;

當時鍾與數據到達FPGA的延時不一致時,計算公式如下:

  Input_delay_min = Th_min+ (T_data_max -T_clk_min)

 Input_delay_max = T-Tsu_max+ (T_data_min -T_clk_max)

其中T_data是數據延時,T_clk是時鐘延時,由此可見在PCB佈線的時候,務必讓時鐘與數據的走線儘可能等長。這樣不容易導致時序違例現象。(這個公式無論是中心對齊或者邊沿對齊都適用,只不過中心對齊與邊沿對齊他們的建立時間和保持時間計算不一樣而已,稍後說明。)       其中T爲FPGA用於採集上游器件發送過來的數據時鐘。又或者直接通過示波器觀察時鐘與數據的延遲關係。有些情況,例如給定了相關數值的話(Tco ,data_delay等數值),可以直接算出輸入延遲。跟上一篇計算數據到達時間裏一樣,這裏就不展開論述。


圖8   SDR中心對齊的輸入輸出延遲最值

 

圖9   SDR邊沿對齊的輸入輸出最值

回顧一下Tsu與Th的定義。setuptime :數據要能夠被Latch Edge正確鎖存,必須要在Latch Edge 到達之前保持穩定,這個提前到達的最少時間量,就是建立時間。

Hold time : 數據要能夠被LatchEdge正確鎖存,除了在Latch Edge到達之前提前準備好以外,還必須在Latch Edge到達後,保持穩定一段時間。這段保持穩定的時間,就是Hold time。圖中DVW是指數據有效值寬度,圖5中心對齊的情況下很好理解。對於圖6中提到的邊沿對齊情況,我覺得可以這麼理解,在計算Tsu的時候,都是Latch時刻減去數據穩定起始沿時刻;而Th是數據穩定終止沿時刻減去Latch時刻。這麼一算,不難可以得到在邊沿對齊的情況下,保持時間Th爲負的。代入公式可得,邊沿對齊的情況下,input_delay_max=保持時間=-Th(這裏的Th僅爲數值,不帶符號)。


圖10輸入延遲約束

圖10中,左邊是通過查閱上游器件數據手冊得到的數據,右邊的是用示波器測量得到的數據。



注:在對DDR的約束中,記得時鐘下降沿約束的時候加上-clock_fall-add_delay;上面列舉的例程中,原著中都沒有用到虛擬時鐘,但是官網手冊中也只是推薦使用,並沒有說一定要用虛擬時鐘。看個人喜好吧,如果要用虛擬時鐘,可以這樣約束,後續會列舉一個完整的例子。


Set output_delay

輸出延時的分析與輸入延時類似。這裏設定時鐘與數據在PCB上的傳輸延遲一致:

 output delay max =  Tsu;

 output delay min = -Th;

當時鍾與數據到達FPGA的延時不一致時,計算公式如下:

  Output_delay_min= -Th_max + (Tdata_min-Tclk_max)

 Output_delay_max=Tsu_max + (Tdata_max-Tclk_min)

其中,T_data是數據延遲;T_clk爲時鐘的延遲。


         上述是DDR中心對齊輸出的輸出延遲約束。


上述是DDR邊沿對齊輸出的輸出延遲約束。

SDR的輸出約束方式類似,這裏就不在累贅了。

 時序例外

時序例外一般用在clock與IO都約束後,還是不滿足時序要求的情況下。主要包括以下幾種情況:

1.多週期set_milticycle_path

(不推薦)

2.不需要檢測路徑(常見,重要)set_false_path

  3.常量與僞常量

4. 互斥的路徑

5.異步時鐘(這種情況下,務必要確保邏輯上對異步時鐘域的信號做了處理,例如打兩拍,FIFO等手段處理

5.組合電路延時,即邏輯不經過任何時鐘處理就輸出的情況。

個人比較取向與set_false_path與set_clock_groups-exclusive。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章