Timequest共包括13條限制指令(從timequest工具constrants下拉菜單可選的限制指令,實際不止這麼多),分别是:
Creat clock
Creat generated clock
Set clock lantency
Set clock uncertainty
Set clock groups
Remove clocks
Set input delay
Set output delay
Set false path
Set multicycle path
Set muximum delay
Set minimum delay
Set muximum skew
各個限制指令說明
2.1 Create_clock
兩個作用:(page73)
1,限制從外部進入FPGA的時鐘。
2,建立虛拟時鐘,虛拟時鐘是指外部IC晶片用到的時鐘,它們不是FPGA内部的時鐘域。Create_clock不能用于限制FPGA内部的時鐘。(page74)在限制指令都是添加在SDC檔案裡面,是以們得先建立一個SDC檔案,通過timequest的cronstraints下拉菜單的generated SDC file選項可以生成。而我添加每一條指令都是通過quartus 的Edit下拉菜單insert constraint選項添加的。
我們選擇通過quartus 的Edit下拉菜單insert constraint選項添加Create_clock限制指令,彈出如圖11的會話框,Clock name 指你想限制的時鐘名稱,任意起,不過最好根據自己設計的子產品起,便于分析閱讀,不然時鐘多了,自己都不知道哪個時鐘是哪個子產品的。
Period 限制時鐘的周期
Rising 指時鐘上升沿的開始時間
Falling 指時鐘下降沿的開始時間
圖11
Targets 指你想限制的哪個FPGA 管腳。
SDC command就是要添加到SDC檔案裡面的限制指令。
通過圖11會話框的選項添加到SDC的限制指令如圖39行。
2.2 Creat generated clock
Create_generated_clock的作用:(page74)
1,限制PLL。(限制指令derive_pll_clocks)
2,同步輸出時鐘,限制FPGA晶片輸出到外部的時鐘。
3,時鐘多路複用器(clock muxes)
4,ripple clocks,該時鐘是FPGA内部一個寄存器的輸出做為另一個寄存器的時鐘,如通過計數産生的時鐘,源寄存器需要一個已經産生的時鐘,不然ripple clock将不會限制成功。
我們選擇通過quartus 的Edit下拉菜單insert constraint選項添加Create_clock限制指令,彈出如圖12的會話框
圖12 Create_generated_clock
Sorce 源時鐘,指輸入時鐘,用于給被限制時鐘提供時鐘源,這個時鐘往往是已經存在的時鐘,如由之前的Create_clock産生的時鐘。
Divide by 對源時鐘分頻
Phase 對源時鐘進行相移
Multiply by 對源時鐘倍頻
Offset 對源時鐘進行偏移,這裡是偏移多少個ns,而項移是偏移多少度
Duty cycle 占空比
圖12的會話框表示對管腳ext1_clk進行了限制,它的源時鐘是clk,限制後的名字是 ext1_clk。
與圖12對應的限制指令:
create_generated_clock -name ext1_clk -source [get_ports {CLK}] [get_ports {ext1_clk}]
當然,設計者根據自己的需求來進行限制,是否需要分頻、相移等。
2.3 set_clock_latency
該限制指令用于闆級的時鐘延遲,用于對FPGA輸入時鐘、外部虛拟時鐘(如外部IC的時鐘)以及回報時鐘(指某個時鐘從FPGA晶片輸出然後又回到FPGA晶片)的限制。(page86)
如圖13所示的latency type選項,set_clock_latency分為early和late之分。
圖13 set_clock_latency
Set_clock_latency限制指令有late和early之分,late指最大時鐘延遲,early指最小時鐘延遲。當進行setup slack分析時,由于set slack=data required time - data arrived time,是以late的延時會加到data arrived time裡面,對源寄存器時鐘進行延時,early的延時會加到data required time裡面,對目的寄存器時鐘進行延時;在進行hold slack分析時,由于hold slack = data arrived time - data required time裡面,是以early的延時會加到data arrived time裡面,對源寄存器時鐘進行延時,late的延時會加到data required time裡面,對目的寄存器時鐘進行延時。
上面這樣分析的目的是為了分析在最糟糕情況是否滿足時序限制。 而值得注意的是late與early內插補點會添加到clock pessimism 裡面。如下圖:這裡late的值我設定的是3ns,eraly的值我設定的是1ns,上圖是沒有添加Set_clock_latency限制指令的報告,下圖是添加了Set_clock_latency限制指令的報告,然後觀察source latency和clock pessimism的值。
圖14 未添加Set_clock_latency
圖15 添加了Set_clock_latency
2.4 Set_clock_uncertainty
限制指令set_clock_uncertainty針對時鐘出現的抖動(jitter),clock skew進行的限制。(page86)
圖16 Set_clock_uncertainty會話框
通過會話框可以知道,該限制指令是對一個時鐘到另一個時鐘uncertainty的限制。另外,通過derive_clock_uncertainty指令也可以對時鐘uncertainty進行限制,實際上用這個限制指令會更好,因為用這個限制指令不需要設計者去算uncertainty是多少,而set_clock_uncertainty限制指令則需要自己去算,如下圖:
圖17
注意,不是所有的FPGA都支援jitter分析的,有些FPGA系列晶片不支援derive_clock_uncertainty指令。比如cyclone ii系列就不支援。如果不能使用derive_clock_uncertainty指令的話,那麼我們要怎麼來知道時鐘抖動資訊然後做出正确的限制就很重要了。
建議一般用derive_clock_uncertainty限制指令對時鐘的uncertainty進行限制。
由于我們能在set input delay和set output delay計算公式中添加clk skew資訊,以及通過set clock latency添加時鐘延遲資訊,加上Set_clock_uncertainty限制指令,這3種限制都能對clk skew進行限制,是以我們在添加限制指令時,不要重複添加clk skew限制。
2.5 set_clock_groups
對于有多個時鐘的設計中,可以用這個限制把相關的時鐘分成一個組,與其它不相關的時鐘區分開。這樣也避免timequest對相關的異步時鐘進行時序分析而帶來不必要的麻煩。比如我們如果用pll産生了大量的異步時鐘,而且這些時鐘不完全相關,那麼我們就需要通過這些限制把pll産生的時鐘輸出分組。
圖 18
如圖18,這個限制指令把時鐘分成了兩組,ext1_clk和ext1_clk_r是一組,clk、ext_div2和ext2_clk是一組,這樣限制過後,timequest隻對這兩個組内的時鐘域進行分析,兩個組間的時鐘路徑将不會分析。
2.6 set_input_delay
set_input_delay是對外部IC輸入到FPGA管腳的限制,這個限制指令中的延遲資訊需要設計者告訴timequest。
圖19
如圖19,外部IC時鐘是ext1_clk,input delay options選項中maximum用于setup slack分析,minimum用于hold slack分析,圖19下面76行和77行是通過set_input_delay會話框添加的限制指令,這兩條限制指令表示從外部IC到FPGA輸入管腳Din[3:0]的最大延時是4ns,最小延時是2ns,外部IC時鐘是ext1_clk。
會話框中的add delay選項用于說明有另外的外部寄存器連接配接到端口,通常用于對雙倍速率接口的限制。
對于雙倍速率接口的1/O限制通常這樣:
set_input_delay -clock ext_clk -max 0.5 [get_ports {ddr_data[*]}]
set_input_delay -clock ext_clk -min -0.5 [get_ports {ddr_data[*]}]
set_input_delay -clock ext_clk -max 0.5 [get_ports {ddr_data[*]}] -clock_fall -add_delay
set_input_delay -clock ext_clk -min -0.5 [get_ports {ddr_data[*]}]-clock_fall -add_delay
這個限制告訴我們每一個ddr_data端口都是被兩個外部的寄存器驅動,一個是在ext_clk的上升沿鎖存,另一個是在ext_clk的下降沿鎖存,如果每沒有在最後兩行添加-add delay的話,最後兩行就會把開始兩行的限制覆寫掉,timequest也會報出警告。
2.7 set_output_delay
這個指令限制FPGA輸出到IC的延遲,其它都與set_input_delay一樣,不再多說。
圖20
如圖20,82到85行表示FPGA輸出管腳Dout2[3:0]和Dout1[3:0]到時鐘為ext2_clk的外部IC輸入的最大延遲是4ns,最小延遲是2ns。
2.8 set false path
Set_false_path,該限制指令是告訴timequest不要分析某個路徑或者是某組路徑。
圖 21
如圖21,該限制告訴timequest不要分析時鐘域clk到ext_div2之間的路徑。設計者在用該限制指令時一定要知道自己在做什麼,如果某些路徑本身是不存在的,但是timequest在分析時把兩個不相關的時鐘域聯系了在一起并且這些路徑不滿足時序要求,如果設計者不知道的話,有可能會一直去糾結自己邏輯的問題或者是通過其它方式讓這些路徑滿足時序要求,但是這樣做不是正确的,我們應該用set false path限制指令把這些路徑給屏蔽掉,這樣做就不會出現錯誤了。
2.9 set_multicycle_path
當兩個寄存器間的資料傳輸在一個周期内沒法完成時,我們可以通過該限制指令來改變他的建立關系值和保持關系值讓其滿足時序要求。
圖22
首先我們看一下會話框,analysis type中setup影響setup relationship值,而hold影響hold relationship值,reference clock中的start和end選項指以哪個時鐘周期來算setup relationship和hold relationship的值。
然後我們再來看看setup和hold是如何影響setup relationship值和hold relationship值的:
圖23
Case1是在預設情況下的setup relationship值和hold relationship值,預設情況下 -setup的值是1和 -hold 的值是0, Case2我們把setup的值該為2,然後可以看到setup relationship值和hold relationship值都各自增加了10ns。從圖中可以看到,hold relationship的值要随着setup值的改變而改變,有如下公式:
setup relationship = default_setup_relationship + (MC_setup_value – 1) * clk_period (on timequest_user_guide page 50)
Holdrelationship = default_hold_relationship + (MC_setup_value – 1) * clk_period
可是我們可以發現,如果隻通過setup值來改變setup relationship的值,而hold relationship值也跟着發生了改變,這樣hold 分析可能不滿足時序要求,接下來就講講analysis type中hold選項的作用。
圖24
看圖24,case1 的setup值為4、hold值為0時setup relationship和hold relationship的值分别從預設的10ns和0ns變成了40ns和30ns,我們再看後面3中情況,setup值保持不變,hold值從1增加到3的時候,setup relationship值一直保持不變,而hold relationship的值從30ns變成了0ns。從結果看得出這樣的結論:随着hold值的增加,setup relationship保持不變,而hold relationship的值一直減小。
通過以上分析我們可以得出以下公式:
1) analysis type是setup且reference clock是start
setup relationship = default_setup_relationship + ((MC_setup_value – 1) * launch_clk_period)
Holdrelationship = default_hold_relationship + (MC_setup_value – 1) * launch_clk_period
2) analysis type是setup且reference clock是end
setup relationship = default_setup_relationship + ((MC_setup_value – 1) * latch_clk_period)
Holdrelationship = default_hold_relationship + (MC_setup_value – 1) * latch_clk_period
3) analysis type是hold且reference clock是start
hold relationship = default_hold_relationship - (MC_hold_value * launch_clk_period)
4) analysis type是hold且reference clock是end
hold relationship = default_hold_relationship - (MC_hold_value * latch_clk_period)
特别說明:用該限制指令限制時,如某個路徑在一個時鐘周期内無法滿足時序要求,然後通過該限制指令讓這個路徑在3個時鐘周期内完成,比如讓setup relationship和hold relationship的值從預設的10ns和0ns變成了30ns和0ns,雖然通過限制讓自己的設計滿足了時序要求,但是我們要明白邏輯并不會這樣做,我們需要修改邏輯讓以前在一個時鐘周期内完成的操作現在通過3個時鐘周期來完成,這樣我們就完成了通過限制來知道邏輯問題出現在哪個地方,然後通過修改邏輯讓其滿足時序要求。
下面2張圖是限制前後限制後的比較。Setup值是2。
圖25 限制前
圖26 限制後
從圖25和圖26可以setup relationship和slack的值的變化。
2.10 set muximum delay和set minimum delay
set_max_delay 影響setup relationship,set_min_delay影響hold relationship;用set_max_delay和set_min_delay存在2個危險:第一,一旦用這2個限制,下降沿采集将被忽略;第二,經過pll相移後的時鐘,使用這2個限制後,相移将被忽略。
建議不要使用這2個指令對I/O進行限制。對I/O的限制,建議用set_input_delay/set_output_delay。set_max_delay和set_min_delay會直接将setup relationship和hold relationship的值限制成設定的值,而其它延時造成setup relationship和hold relationship的改變将無效