時序約束是我們對FPGA設(shè)計的要求和期望,例如,我們希望FPGA設(shè)計可以工作在多快的時鐘頻率下等等。因此,在時序分析工具開始對我們的FPGA設(shè)計進行時序分析前,我們必須為其提供相關(guān)的時序約束信息。在【時序分析的原理】章節(jié)中,我們介紹了很多原理性的東西,而在本章節(jié),我們將為大家介紹在解決具體問題時該如何向時序分析工具表述清楚我們的意圖,從而啟動其強大的邏輯錐求解功能來得出我們所關(guān)心的時序分析報告。
當然了,時序分析工具的種類有很多,雖然它們所支持的時序約束語法不盡相同,但主體思想都是一致的。因此,本章節(jié)就以Xilinx集成開發(fā)環(huán)境ISE中自帶的時序分析工具為例,來為大家介紹一些UCF文件中常用的時序約束。(注意,時序分析環(huán)節(jié)僅僅是用來對FPGA設(shè)計的實現(xiàn)進行評估并給出相應(yīng)的結(jié)果報告,它并不會對FPGA設(shè)計進行改變。但如果我們在使用諸如ISE、Quarters這樣的集成開發(fā)環(huán)境時,如果在映射環(huán)節(jié)還沒開始前就添加一些時序約束信息,則這些編譯器每完成一部分布局布線工作,便會調(diào)用相應(yīng)時序分析工具進行一次時序分析,如果發(fā)現(xiàn)分析結(jié)果不符合要求,則會返回重來。像這樣,編譯器經(jīng)過多次反復(fù)努力,力求達到時序約束中的要求,從而給我們一種“時序分析改變FPGA實現(xiàn)”的錯覺。因此,如果你想利用ISE做純粹的時序分析,請使用PCF文件,當然語法也會略有不同。)
時序環(huán)境約束
在【本篇->基本概念介紹->影響延遲的因素->三種工況】中,我們介紹過環(huán)境因素對時序分析的影響。在默認的情況下,ISE自帶的時序分析工具通常會采用最大工況來進行分析,不過我們也可以通過時序環(huán)境約束來定義自己想要的環(huán)境因素,例如:
TEMPERATURE = 85 C;
VOLTAGE = 0.95 V;
分組時序約束
在介紹描述具體情況的時序約束之前,讓我們先來簡單了解一下ISE所提供的一些基本分組時序約束語法,因為即使你的FPGA設(shè)計得再簡單,也總不可能一個元素接一個元素的去添加時序約束吧?如果能夠先建立分組,將有共性的元素劃分到一起,然后再統(tǒng)一添加時序約束,將會極大的簡化我們的工作量。
TNM
TNM是最基本的分組約束語法,其語法定義如下:
{NET|INST|PIN} "net_or_pin_or_inst_name" TNM = [predefined_group] identifier;
可見,TNM的定義起始關(guān)鍵字可以有三種——NET(網(wǎng)絡(luò))、INST(實例)、PIN(端口),其中,NET關(guān)鍵字用來指明網(wǎng)絡(luò)分組,該分組約束會自動包含"net_or_pin_or_inst_name"名稱中指定的那個網(wǎng)絡(luò)名下0000000000000000000000000000000000000000000000游所連接的所有元素;INST關(guān)鍵字用來指明一個實例,為后續(xù)該分組的搜索限制了一個范圍;PIN指的是端口,指明具體某個原語的管腳。
predefined_group是一個可選的參數(shù),不寫明的時候,該分組包含所有可包含的元素;若注明,則該分組只包含[predefined_group]類的元素。針對ISE軟件來說,預(yù)先定義好的分組大概有以下這些:
FFS:觸發(fā)器組;
RAMs:存儲器組;
LATCHES:鎖存器組;
PADS:焊盤組;
HSIOS:高速IO組;
MULTS:乘法器組。
最后identifier指明了該分組的名稱,以供后續(xù)語法在調(diào)用該分組時使用。
TNM_NET
TNM_NET也是一個基本的分組約束語法,其語法定義如下:
{NET|INST} "net_name" TNM_NET = [predefined_group] identifier;
TNM_NET分組定義語法幾乎與TNM是一樣的,除了兩個區(qū)別:
1、TNM_NET只能根據(jù)網(wǎng)絡(luò)來定義分組;
2、TNM_NET指明的網(wǎng)絡(luò)名在選擇分組成員時,可以穿過IBUF、BUFG這樣的原語去往下游擴散,而TNM則不行。因此,通常用TNM_NET來為FPGA芯片的焊盤部分指定分組。
TIMEGRP
TIMEGRP是一個針對分組進行操作的語法關(guān)鍵字,我們可以利用該關(guān)鍵字對分組求并、求差或者指定時鐘邊沿,例如:
TIMEGRP “ffs123” = “ffs1” “ffs2” “ffs3”; #合并三個分組為一個分組
TIMEGRP “G1D2” = “G1” EXCEPT “G2”; #定義一個包含所有屬于"G1"但不屬于"G2"元素的分組
TIMEGRP “group1”=RISING FFS; #基于FFS分組定義一個敏感時鐘上升沿的分組
TIMEGRP “group2”=FALLING FFS; #基于FFS分組定義一個敏感時鐘下降沿的分組
注意,對ISE的時序分析工具來說,在時序約束信息中,對分組名或信號名等名稱使不使用雙引號都是ok的。另外,UCF文件中的注釋符號為“#”。
常用時序約束
對于FPGA設(shè)計來說,常用的時序約束基本上可以被劃分為四種類型,分別介紹如下:
周期約束
周期約束又叫時鐘約束,主要用于給時鐘信號指明相關(guān)約束,使用關(guān)鍵字PERIOD,其基本語法定義如下:
TIMESPEC "TS_name" = PERIOD "TNM_name"{HIGH|LOW} [high_or_low_time] [INPUT_JITTER value];
其中,TIMESPEC "TS_name"為該周期約束定義了一個標示符,可供其他地方調(diào)用。
"TNM_name"指明該周期約束所覆蓋的時序分組。
指明了該周期約束的時鐘周期數(shù)值。
{HIGH|LOW}指明了對應(yīng)時鐘信號在0時刻是以高電平(或上升沿)開始還是以低電平(或下降沿)開始的。
[high_or_low_time]是針對{HIGH|LOW}來說的,指明時鐘信號起始電平的持續(xù)時間,類似占空比的概念,因此也可以用百分數(shù)來表示,意思是起始電平占整個周期的比例。
[INPUT_JITTER value]則指明了對應(yīng)時鐘信號存在一定的輸入jitter。
輸入時鐘周期約束
要對一個被輸入時鐘所驅(qū)動時鐘域進行時序分析,需要先定義一個需要被分析的分組,然后再使用TIMESPEC語法指定并命名一個周期約束,例如:
NET “clk50MHz” TNM_NET = “clkIn”;
TIMESPEC “TS_clkIn” = PERIOD “clkIn” 20.0 ns HIGH 50%;
上例中的第一句分組約束,將所有clk50MHz端口網(wǎng)絡(luò)所連接的元素全部加入到clkIn分組中。而第二句話則指明該時鐘域的時鐘信息,表示定義了一個名為TS_clkIn的周期約束,其內(nèi)容為針對clkIN時序分組,添加了一個周期為20ns、起始電平為高電平、占空比為50%的周期約束。
當然了,除了使用百分比來指電平占空比參數(shù)外,還可直接標明電平持續(xù)時間,例如,上例第二句話又可改寫為:
TIMESPEC “TS_clkIn” = PERIOD “clkIn” 20.0 ns HIGH 10.0 ns;
若該時鐘域的時鐘信號還存在著2ns的jitter,則上例第二句話又可改寫為:
TIMESPEC “TS_clkIn” = PERIOD “clkIn” 20 ns HIGH 50% INPUT_JITTER 2 ns;
內(nèi)部時鐘周期約束
內(nèi)部時鐘周期約束和輸入時鐘周期約束沒有什么本質(zhì)的不同,都是將周期約束加入到對應(yīng)的時鐘網(wǎng)絡(luò)上,不過有一點需要特別注意:
輸入時鐘周期約束針對的是輸入時鐘信號,該時鐘信號是通過FPGA的一個輸入管腳引入FPGA內(nèi)部的,如果我們將該管腳和FPGA頂層實體的輸入端口clk綁定,那么無論是綜合前后、布局布線前后,使用clk這個名稱都能找到對應(yīng)的時鐘網(wǎng)絡(luò),因為關(guān)于這個時鐘輸入端口實在是沒有什么好優(yōu)化和改名的。
但是,若你要約束一個內(nèi)部的時鐘信號,若該信號在HDL文件中的名稱為clk25MHz,若你定義了如下分組約束:
NET “clk25MHz” TNM_NET = “innerClk”;
則時序分析工具在進行分析的時候幾乎會百分之百的報告說找不到這個名稱叫做clk25MHz的網(wǎng)絡(luò),因為它幾乎肯定會被優(yōu)化或改名掉。針對此類情況,通常有三種解決方案:
1、使用ISE自帶時序分析工具的時序約束創(chuàng)建工具創(chuàng)建該時鐘的約束。通常,ISE會分析出其內(nèi)部具有哪幾個時鐘信號,并會給出每一個時鐘信號的源頭網(wǎng)絡(luò)名稱,你可以據(jù)此名稱推測出該網(wǎng)絡(luò)是不是你HDL代碼中類似clk25MHz名稱對應(yīng)的時鐘網(wǎng)絡(luò),然后使用該網(wǎng)絡(luò)名稱創(chuàng)建分組約束。
2、在綜合的時候使用綜合約束中的keep語法,讓clk25MHz這個網(wǎng)絡(luò)名稱不被優(yōu)化掉。
3、查看綜合、轉(zhuǎn)換環(huán)節(jié)后的FPGA設(shè)計網(wǎng)表文件,找到clk25MHz可能對應(yīng)的那個網(wǎng)絡(luò)名稱,然后使用該網(wǎng)絡(luò)名稱創(chuàng)建分組約束。(閱讀網(wǎng)表的過程可能會很痛苦!)
當然了,對于一個驗證團隊來說,對于內(nèi)部時鐘來說,要想添加純時序分析所使用的約束的話,恐怕只有采用方案3了。
關(guān)聯(lián)時鐘周期約束
關(guān)聯(lián)時鐘周期約束主要用來應(yīng)付兩種情況:一、如果兩個時鐘域之間有信息傳遞,且我們想要對此進行時序分析;二、一個時鐘信號本身就是由另一個時鐘信號生成的,兩者之間具有很強的相關(guān)性。
例如,對于一個DCM模塊來說,其輸入來自一個叫做clk50MHz的管腳,我們對該時鐘網(wǎng)絡(luò)進行周期約束如下:
NET “clk50MHz” TNM_NET = “clkIn”;
TIMESPEC “TS_clkIn” = PERIOD " clkIn" 20 ns HIGH 50%;
如果它有一個同相2倍頻的輸出時鐘,對應(yīng)網(wǎng)絡(luò)名稱叫做clk2x,則對此輸出時鐘所驅(qū)動的網(wǎng)絡(luò),我們可以定義時序約束如下:
NET “clk2x” TNM_NET = DCM2xOut;
TIMESPEC TS_DCM2xOut = PERIOD “DCM2xOut” TS_clkIn / 2 HIGH 50%;
而對于該DCM的相移180度的2倍頻輸出時鐘,若其對應(yīng)網(wǎng)絡(luò)名稱叫做clk2x180,則對此輸出時鐘所驅(qū)動的網(wǎng)絡(luò),我們可以定義時序約束如下:
NET " clk2x180" TNM_NET = DCM2x180Out;
TIMESPEC TS_DCM2x180Out = PERIOD “DCM2x180Out” TS_clkIn / 2 PHASE 5 ns HIGH 50%;
差分時鐘周期約束
如果輸入時鐘信號是差分的,那么你只需要給差分中的一個端口加上周期約束即可。為了好理解起見,你應(yīng)該對差分的p端網(wǎng)絡(luò)添加一個和差分時鐘相同的周期約束。
輸入約束
輸入約束主要針對同步輸入接口,亦或是針對虛擬出來的同步輸入接口,通過使用“OFFSET = IN”關(guān)鍵字,來描述輸入數(shù)據(jù)與時鐘之間的關(guān)系。其基本語法定義如下:
[{TIMEGRP|NET} "iobgroup_or_padnet_name"] OFFSET = IN[units] [VALID] {BEFORE|AFTER} "clk_name" [TIMEGRP "group_name"] {HIGH|LOW};
其中,[{TIMEGRP|NET} “iobgroup_or_padnet_name”]可以為該輸入約束指明一個網(wǎng)絡(luò)或者一個分組(注意,這里的網(wǎng)絡(luò)必須是連接到pad的網(wǎng)絡(luò),分組也必須是IO block相關(guān)的分組),若省略不寫,則該約束的作用范圍是全局的(應(yīng)用于所有跟時鐘"clk_name"相關(guān)的輸入端口)。
是一個相對于所依賴時鐘初始邊沿的數(shù)據(jù)到來偏移量。當然了,具體該時鐘的初始邊沿是上升沿還是下降沿,則要追朔到該時鐘相關(guān)的周期約束上,通過該周期約束的使用的是HIGH、LOW關(guān)鍵字中的哪一個來判斷。
[VALID ]給出了數(shù)據(jù)信號的穩(wěn)定周期,即在的基礎(chǔ)上,保持穩(wěn)定時間為。
{BEFORE|AFTER}則指出了該條約束中描述的有效數(shù)據(jù)是應(yīng)該被當前時鐘事件所采集還是應(yīng)該被后續(xù)時鐘事件所采集的。如果使用了BEFORE關(guān)鍵字,則表示數(shù)據(jù)有效開始是以要采集它的時鐘事件為基礎(chǔ),給出一個提前量的;如果使用了AFTER關(guān)鍵字,則表示數(shù)據(jù)有效開始是以前一個時鐘事件為基礎(chǔ),給出一個滯后量的。當然了,本身也可以是負值,而具體使用哪一個關(guān)鍵字,完全看個人的描述習慣,它們之間沒有任何本質(zhì)的不同。
"clk_name"指明了該輸入約束是相對于哪一個時鐘事件的初始邊沿來說的。
[TIMEGRP “group_name”]為該約束指明了一個需要分析的內(nèi)部分組,省略不寫則表示所有跟當前時鐘采集有關(guān)的元素。
{HIGH|LOW}則用來改寫"clk_name"的初始邊沿的,它可以改變周期約束對"clk_name"相關(guān)初始邊沿的設(shè)定,HIGH、LOW分別表示的是將時鐘上升沿、下降沿設(shè)定為0時刻的初始邊沿。
SDR輸入約束
SDR的概念請回顧【程序設(shè)計篇->編程思路->關(guān)于外接接口的編程思路->按時鐘特性分類->同步接口->SDR】小節(jié)。
既然是同步接口,那么我們必須首先為同步時鐘定義一個周期約束,例如:
NET “clk” TNM_NET = clk50MHz;
TIMESPEC TS_clk = PERIOD “clk50MHz” 20 ns HIGH 50%;
那么,下面就可以基于該時鐘來使用“OFFSET = IN”語法表明該SDR接口在輸入的時候數(shù)據(jù)與時鐘之間的關(guān)系。例如:
OFFSET = IN 10 ns VALID 20 ns BEFORE clk;
由于本條語句沒有指名具體的輸入端口,因此它的作用是全局的,即所有跟clk時鐘采集相關(guān)的輸入端口。但是,若不同的數(shù)據(jù)端口與時鐘之間的關(guān)系有所不同的話,則需要單獨為每一個輸入端口指明輸入約束,例如:
NET “dIn<0>” OFFSET = IN 20 ns VALID 20 ns BEFORE “clk”;
NET “dIn<1>” OFFSET = IN 10 ns VALID 20 ns BEFORE “clk”;
如果有多個輸入端口和時鐘信號具有同樣的關(guān)系,則可使用分組的形式去定義輸入約束,例如:
NET “dIn<0>” TNM = dInG;
NET “dIn<1>” TNM = dInG;
TIMEGRP “dInG” OFFSET = IN 20 ns VALID 20 ns BEFORE “clk”;
DDR輸入約束
DDR的概念請回顧【程序設(shè)計篇->編程思路->關(guān)于外接接口的編程思路->按時鐘特性分類->同步接口->DDR】小節(jié)。
類似的,既然是同步接口,那么我們必須首先為同步時鐘定義一個周期約束,例如:
NET “clk” TNM_NET = clk50MHz;
TIMESPEC TS_clk = PERIOD “clk50MHz” 20 ns HIGH 50%;
那么,下面就是一種基于該時鐘來使用“OFFSET = IN”語法表明該DDR接口在輸入的時候數(shù)據(jù)與時鐘之間關(guān)系的方法,例如:
OFFSET = IN 5 ns VALID 10 ns BEFORE “clk” RISING;
OFFSET = IN 5 ns VALID 10 ns BEFORE “clk” FALLING;
這兩行語法說明兩個時鐘邊沿都分別對應(yīng)其所需要采樣數(shù)據(jù)的中間。注意,上例中多了兩個關(guān)鍵字RISING和FALLING,它們不光可以用來指明offset time為5ns,到底是相對于時鐘網(wǎng)絡(luò)clk的上升沿來說還是下降沿來說,更重要的是,它們可以指明,該條輸入約束的作用范圍——RISING代表分析所有在上升沿被采樣的輸入分組,F(xiàn)ALLING代表分析所有在下降沿被采樣的輸入分組。正因為如此,雖然這兩條語句針對的輸入端口都是一樣的,但是它們并沒有被互相覆蓋。例如,如果我們想當然的將RISING、FALLING關(guān)鍵字替換為HIGH、LOW關(guān)鍵字如下:
OFFSET = IN 5 ns VALID 10 ns BEFORE “clk” HIGH; #Wrong for DDR
OFFSET = IN 5 ns VALID 10 ns BEFORE “clk” LOW; #Wrong for DDR
則,由于上述兩條語句針對的都是一樣的分組(所有跟clk相關(guān)的輸入元素),因此誰寫在前面誰就會被后面的語句覆蓋掉。
也正是因為RISING和FALLING這樣的一個分組特性,所以如果在SDR接口中,內(nèi)部邏輯本身是上升沿敏感的,但如果你用FALLING來指明數(shù)據(jù)、時鐘之間的位置關(guān)系,時序分析工具將會告訴你0條路徑、0個端口等等被分析。此時,如果你執(zhí)意要以下降沿來作為參考邊沿的話,請使用LOW關(guān)鍵字。
為DDR接口添加時序約束的另一種方法是使用內(nèi)部分組,例如,為了實現(xiàn)與第一種方法相同的約束,可以先定義兩個分組分別對應(yīng)上升沿敏感的元素和下降沿敏感的元素,然后分別為其指明輸入約束,描述如下:
TIMEGRP “ClkIn_Rising” = RISING “clk50MHz”;
TIMEGRP “ClkIn_Falling” = FALLING “clk50MHz”;
OFFSET = IN 5 ns VALID 10 ns BEFORE clk TIMEGRP ClkIn_Rising;
OFFSET = IN -5 ns VALID 10 ns BEFORE clk TIMEGRP ClkIn_Falling;
為了進一步明確OFFSET語法中前后兩個TIMEGRP用意的不同,下面給出如果要對一個兩位寬的dIn輸入端口添加DDR約束的例子:
NET “dIn<0>” TNM = dInG;
NET “dIn<1>” TNM = dInG;
TIMEGRP “ClkIn_Rising” = RISING “clk50MHz”;
TIMEGRP “ClkIn_Falling” = FALLING “clk50MHz”;
TIMEGRP “dInG” OFFSET = IN 5 ns VALID 10 ns BEFORE clk TIMEGRP ClkIn_Rising;
TIMEGRP “dInG” OFFSET = IN -5 ns VALID 10 ns BEFORE clk TIMEGRP ClkIn_Falling;
MDR輸入約束
MDR的概念請回顧【程序設(shè)計篇->編程思路->關(guān)于外接接口的編程思路->按時鐘特性分類->同步接口->MDR】小節(jié)。
類似的,既然是同步接口,那么我們必須首先為同步時鐘定義一個周期約束,例如:
NET “clk” TNM_NET = clk50MHz;
TIMESPEC TS_clk = PERIOD “clk50MHz” 20 ns HIGH 50%;
由于MDR在實際接收時,往往還是通過SDR或者DDR的模式去進行數(shù)據(jù)接收,因此,如果實際采用的是SDR模式,則我們只需要采樣對一個數(shù)據(jù)即可連續(xù)采集對所有的數(shù)據(jù);而如果實際采用的是DDR模式,則我們只需要采樣對連續(xù)兩個數(shù)據(jù)即可連續(xù)采集對所有的數(shù)據(jù)。
那么,接下來以時鐘數(shù)據(jù)比為1:4,數(shù)據(jù)變化沿對齊時鐘變化沿的MDR為例,看看該如何應(yīng)對其輸入約束的描述:
首先,來看看SDR模式實現(xiàn)MDR采樣。如果內(nèi)部使用DCM(或者PLL),生成一個4倍頻、同相的時鐘信號,網(wǎng)絡(luò)名為clk4x,則我們應(yīng)該首先添加關(guān)于該生成時鐘的周期約束如下:
NET “clk4x” TNM_NET = DCM4xOut;
TIMESPEC TS_ DCM4xOut = PERIOD “DCM4xOut” TS_clk / 4 HIGH 50%;
那么,由于clk4x與clk是相關(guān)時鐘,所以時序分析工具會自動分析其跨時鐘域的問題,故只需要基于clk給出一個數(shù)據(jù)采樣的輸入約束如下即可:
OFFSET = IN 5 ns VALID 5 ns BEFORE clk;
事實上,由于UCF文件是在布局布線前添加給ISE的,因此ISE會在編譯的時候自動為DCM或PLL的輸出生成關(guān)聯(lián)周期約束,所以關(guān)于clk4x的周期約束可省略。
接下來,再看看DDR模式實現(xiàn)MDR采樣。此時,由于具體完成采樣的時鐘并不是clk,所以不能采用【DDR輸入約束】小節(jié)中的方法一。但若要采用方法二,必須建立關(guān)于具體采樣時鐘的兩個邊沿分組。因此,先為DCM的輸出pin腳添加關(guān)聯(lián)時鐘約束如下:
PIN “instance_name/DCM_ADV_INST.CLK2X” TNM_NET = clk100MHz;
TIMESPEC TS_clk100MHz = PERIOD “clk100MHz” TS_clk / 2 HIGH 50%;
然后才能定義DDR采樣時鐘的兩個分組如下:
TIMEGRP “Clk2x_Rising” = RISING “clk100MHz”;
TIMEGRP “Clk2x_Falling” = FALLING “clk100MHz”;
最后,基于clk信號描述連續(xù)的兩個采樣并關(guān)聯(lián)到上述兩個分組中即可:
OFFSET = IN 5 ns VALID 5 ns BEFORE clk TIMEGRP Clk2x_Rising;
OFFSET = IN -5 ns VALID 5 ns BEFORE clk TIMEGRP Clk2x_Falling;
事實上,由于UCF文件是在布局布線前添加給ISE的,因此ISE會在編譯的時候自動為DCM或PLL的輸出生成關(guān)聯(lián)周期約束,所以下面這句話可省略:
TIMESPEC TS_clk100MHz = PERIOD “clk100MHz” TS_clk / 2 HIGH 50%;
差分輸入約束
如果接口的輸入數(shù)據(jù)是差分形式的,那么你需要在創(chuàng)建輸入分組的時候把它們都加進去,然后一起添加輸入約束即可。
組間約束
組間約束通過使用“FROM……TO”關(guān)鍵字,來對兩時序分組之間的延遲給出限制描述。其基本語法定義如下:
TIMESPEC “TS_name”=FROM “group1” TO “group2” [DATAPATHONLY];
其中,
TIMESPEC "TS_name"為該路徑約束定義了一個標示符,可供其他地方調(diào)用。
group1為路徑起始端組。
group2 為路徑目的端組。
指明組間延遲的最大允許范圍。你無須指明最小允許范圍,因為時序分析工具會自動為你報出起始端組和目的端組之間的最大、最小時間差。
[DATAPATHONLY]是可選參數(shù),給出則表示當前組間約束將不考慮時鐘skew、相位差等影響,而只考慮組間的數(shù)據(jù)路徑延遲。
焊盤到焊盤路徑約束
當FPGA設(shè)計中有不可拆解的純組合邏輯接口時,就存在從芯片焊盤到焊盤的時序路徑,此時,焊盤到焊盤的路徑約束就會生效。可以直接使用預(yù)定義組PADS來對所有焊盤到焊盤的路徑進行時序約束,描述如下:
TIMESPEC “TS_P2P” = FROM “PADS” TO “PADS” 20 ns;
此時,DATAPATHONLY關(guān)鍵字有沒有都無所謂,因為焊盤到焊盤本身就是純數(shù)據(jù)路徑延遲。如果要對不同的焊盤之間添加不同的焊盤到焊盤的路徑約束,則需要先創(chuàng)建自定義的起始焊盤組和目的焊盤組,然后再添加約束,例如:
TIMEGRP “dInG” = PADS(“a” “b”);
TIMEGRP “dOutG” = PADS(“c”);
TIMESPEC “TS_AB2C” = FROM “dInG” TO “dOutG” 20 ns;
多周期路徑約束
在周期性約束的作用下,時序分析工具會認為該時鐘域內(nèi)寄存器的輸出在每個時鐘事件的到來都會發(fā)生變化,因此,理想情況下每個寄存器的保持時間均為一個時鐘周期。可有時候,F(xiàn)PGA設(shè)計的功能特征決定前級寄存器需要經(jīng)歷很多個時鐘周期后才會發(fā)生一次變化,這樣一來,如果僅僅對該時鐘域添加周期約束,顯然對這部分電路是過約束了。如果這部分電路的邏輯比較簡單,過約束并不會帶來什么大問題;但如果這部分電路的邏輯比較復(fù)雜,過約束很可能會導(dǎo)致時序分析的時候不通過。因此,為了能夠正確的對這部分邏輯添加時序約束,需要要使用多周期路徑約束,例如如下描述:
NET “clk” TNM_NET = clk50MHz;
TIMESPEC TS_clk50MHz = PERIOD “clk50MHz” 20 ns HIGH 50%;
INST "b1" TNM = gb1;
INST "b2" TNM = gb2;
TIMESPEC TS_MultiPath = FROM gb1 TO gb2 TS_clk50MHz * 2;
在時序約束里,通常更為具體的約束比更為廣泛的約束優(yōu)先級要高,因此,雖然上例在最開始已經(jīng)給所有clk50MHz分組添加了周期約束,但后續(xù)的多周期路徑約束將b1、b2之間的周期約束改為2倍的多周期路徑約束。
跨時鐘域路徑約束
如果兩個時鐘之間并不相關(guān),默認情況下,時序分析工具是不會對這種跨時鐘域情況進行分析的。但當它們之間又確實有著信息傳遞,而你又關(guān)心其間的一些時間延遲時,可以使用跨時鐘域路徑約束。例如如下描述:
NET “clk1” TNM_NET = clkA1;
TIMESPEC TS_clkA1 = PERIOD “clkA1” 20 ns HIGH 50%;
NET “clk2” TNM_NET = clkA2;
TIMESPEC TS_clkA2 = PERIOD “clkA2” 15 ns HIGH 50%;
TIMESPEC TS_CCR = FROM clkA1 TO clkA2 10 ns;
上例中的兩條周期約束描述可省略,寫明只是為了說明這兩個時鐘確實是無關(guān)的。如果只關(guān)心兩個時鐘域之間的數(shù)據(jù)路徑延遲的話,可以將上例中的跨時鐘域路徑約束改為:
TIMESPEC TS_CCR = FROM clkA1 TO clkA2 10 ns DATAPATHONLY;
這樣時序分析工具在分析的時候就不會考慮時鐘skew等因素了,即便clk1、clk2是相關(guān)時鐘。
跨時鐘域忽略約束
如果兩個時鐘之間確實是相關(guān)的,例如DCM或者PLL的多個輸出和它們的輸入、一個時鐘信號的上升沿和下降沿等,但我們又不希望時序分析工具對它們之間進行跨時鐘域分析,此時可以使用跨時鐘域忽略約束。例如如下描述:
NET “clk1” TNM_NET = clkA1;
TIMESPEC TS_clkA1 = PERIOD “clkA1” 20 ns HIGH 50%;
NET “clk2” TNM_NET = clkA2;
TIMESPEC TS_clkA2 = PERIOD “clkA2” TS_clkA1/2 HIGH 50%;
TIMESPEC TS_FastPath = FROM clkA1 TO clkA2 TIG;
上例中,通過在組間約束中使用TIG關(guān)鍵字,可以讓時序分析工具不去分析從clkA1到clkA2的組間延遲。如果希望也不要分析從clkA2到clkA1的組間延遲,則還需要再添加一句描述如下:
TIMESPEC TS_FastPath = FROM clkA2 TO clkA1 TIG;
如果只是希望對兩個時鐘域之間的某一部分信號傳遞進行忽略,則可以先定義分組,然后再使用跨時鐘域忽略約束。承接上例,如果希望忽略clk1時鐘域中的aLock到clk2時鐘域中c之間的跨時鐘域分析,可描述如下:
INST “aLock” TNM = ta;
INST “c” TNM = tc;
TIMESPEC TS_FastPath = FROM ta TO tc TIG;
路徑中間點約束
有時候,你關(guān)心的可能不僅僅是兩個時序分組之間的全部路徑延遲中的最大、最小情況,而是關(guān)心通過某一個中繼點或組的兩個時序分組之間的路徑延遲中的最大、最小情況。此時,可以使用THRU關(guān)鍵字指明該中繼分組。例如如下描述:
NET “a_3_IBUF” TPTHRU = “ta”;
TIMESPEC “TS_P2P” = FROM “PADS” THRU “ta” TO “PADS” 20 ns;
上例只分析那些焊盤到焊盤之間經(jīng)過ta分組的路徑延遲情況。
輸出約束
輸出約束主要針對輸出接口,通過使用“OFFSET = OUT”關(guān)鍵字,實現(xiàn)對輸出接口的一些基本時序要求描述,它的基本語法定義如下:
[{TIMEGRP|NET} “iobgroup_or_padnet_name”] OFFSET = OUT[units] {BEFORE|AFTER} “clk_name” [TIMEGRP “group_name”] {HIGH|LOW};
其中,
[{TIMEGRP|NET} “iobgroup_or_padnet_name”]可以為該輸出約束指明一個網(wǎng)絡(luò)或者一個分組(注意,這里的網(wǎng)絡(luò)必須是連接到pad的網(wǎng)絡(luò),分組也必須是IO block相關(guān)的分組),若省略不寫,則該約束的作用范圍是全局的(應(yīng)用于所有被時鐘"clk_name"相關(guān)的輸出端口)。
"clk_name"指明了該輸出約束是相對于哪一個時鐘事件的初始邊沿來說的,注意,"clk_name"是一個輸入時鐘的名稱,而不是輸出時鐘的名稱,更確切的說,它是該約束所針對輸出端口在FPGA內(nèi)部所連接寄存器的驅(qū)動時鐘。
{BEFORE|AFTER} 、[TIMEGRP “group_name”]、{HIGH|LOW}與輸入約束解釋相同。
可見,ISE的輸出約束不太智能,通過使用“OFFSET = OUT”關(guān)鍵字,只能描述輸出端口相對于其輸出寄存器驅(qū)動時鐘之間的時間延遲是否能夠滿足一些基本要求,因此對于同步輸出接口,ISE自帶的時序分析工具不能直接給出分析結(jié)果。下面就來介紹一下該如何利用時序分析工具間接得到同步輸出端口的時序報告。
直接同步輸出約束
直接同步輸出對應(yīng)于【本篇->時序分析的原理->其他常見邏輯情形的應(yīng)對方法->純輸出接口->純同步輸出接口】小節(jié)中描述的情況。可見,對于此類接口,ISE只能采用該小節(jié)中介紹的第三點方法來進行應(yīng)對。即首先通過功能仿真獲得clk與D信號在理想情況下的關(guān)系,然后再分別獲取clk、D信號實際輸出時的最大、最小延遲,然后人工計算得出針對該同步輸出接口的時序分析結(jié)果。
如果內(nèi)部時鐘的周期約束如下:
NET “innerClk” TNM_NET = innerClk;
TIMESPEC TS_innerClk = PERIOD “innerClk” 20 ns HIGH 50%;
則,對于該同步輸出接口,我們需要先定義針對數(shù)據(jù)D的輸出約束,類似如下:
NET “D<0>” TNM = gDout;
NET “D<1>” TNM = gDout;
NET “D<2>” TNM = gDout;
NET “D<3>” TNM = gDout;
NET “D<4>” TNM = gDout;
NET “D<5>” TNM = gDout;
NET “D<6>” TNM = gDout;
NET “D<7>” TNM = gDout;
TIMEGRP “gDout” OFFSET = OUT 20 ns AFTER “innerClk”;
然后,再參考【組間約束中->焊盤到焊盤路徑約束】小節(jié)中的方法,對innerClk與clk之間進行約束,類似如下:
TIMEGRP “gClkIn” = PADS(“innerClk”);
TIMEGRP “gClkOut” = PADS(“clk”);
TIMESPEC “TS_C2C” = FROM “gClkIn” TO “gClkOut” 20 ns;
這樣,時序分析工具會報出D、clk相對于0時刻innerClk邊沿的最大、最小延遲,最后結(jié)合功能仿真的情況即可人工得出該直接同步輸出接口的時序分析報告。
間接同步輸出約束
間接同步輸出對應(yīng)于【本篇->時序分析的原理->其他常見邏輯情形的應(yīng)對方法->純輸出接口->異步生成同步輸出】小節(jié)中描述的情況。
間接同步輸出與直接同步輸出的應(yīng)對方法類似,唯一的不同就在于輸出時鐘clk相對于innerClk來說也是一個數(shù)據(jù)。因此,只需要將【直接同步輸出約束】小節(jié)中,關(guān)于innerClk與clk之間的組間約束改為輸出約束即可。類似如下:
NET “clk” TNM = gCout;
TIMEGRP “gCout” OFFSET = OUT 20 ns AFTER “innerClk”;
這樣,時序分析工具會報出D、clk相對于0時刻innerClk邊沿的最大、最小延遲,最后結(jié)合功能仿真的情況即可人工得出該間接同步輸出接口的時序分析報告。
差分輸出約束
如果接口的輸出數(shù)據(jù)是差分形式的,那么你需要在創(chuàng)建輸出分組的時候把它們都加進去,然后一起添加輸出約束即可。
審核編輯:湯梓紅
-
FPGA
+關(guān)注
關(guān)注
1630文章
21797瀏覽量
606012 -
時序分析
+關(guān)注
關(guān)注
2文章
127瀏覽量
22617 -
ISE
+關(guān)注
關(guān)注
1文章
102瀏覽量
36713 -
時序約束
+關(guān)注
關(guān)注
1文章
115瀏覽量
13458 -
UCF
+關(guān)注
關(guān)注
0文章
9瀏覽量
9715
原文標題:【科普】常用時序約束介紹之基于ISE的UCF文件語法
文章出處:【微信號:feifeijiehaha,微信公眾號:電路和微電子考研】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論