Vivado使用技巧(34):路徑分割現象
上文提到,進行最小/最大延遲約束時,set_max_delay和set_min_delay命令要設定-from和-to選項。但是如果起點和終點設定的不合理(具體見第33篇),便會導致出現路徑分割(Path Segmentation)。
非法的起點
下面舉一個例子說明,如果-from設定了一個非法的起點,時序引擎會阻止經過該節點的時序的傳遞,從而這個“非法的”起點變得“合法”。如下圖:
FD1單元中唯一合法的起點只有C埠,即“set_max_delay 5 -from [get_pins FD1/C]”。但如果將起點設定為Q埠,時許引擎便會阻止通過C->Q的時序弧,從而Q變成了一個合法的起點。這個阻止時序傳遞並建立一個合法起點的過程便是路徑分割
路徑分割並不是一個好的現象,它會影響到最大和最小延遲分析,以及所有經過這些節點的時序約束。如下圖所示:
對於以Q為起點的路徑,啟動時鐘不會考慮時鐘插入延遲。但是在路徑終點處(FD2/D)仍會計算插入延遲,這就可能導致比較大的時鐘斜率。總之,應該儘量避免出現路徑分割現象,如果不得不必須使用也要非常小心。如果出現了路徑分割,Vivado會提示一個嚴重警告。
路徑分割會導致該路徑上沒有保持時間需求,如果需要的話,可以使用set_min_delay命令為該路徑設定一個保持時間需求(在沒有用-datapath_only的情況下)。一般來說,路徑分割總是能避免的,比如上例中,如果只是不想考慮時鐘斜率而把FD1/Q作為起點,完全可以用-datapath_only選項達到此目的:
set_max_delay 5 -from [get_pins FD1/C] -datapath_only
非法的終點
與上例相同,如果-to設定了一個非法的終點,時序引擎會阻止該節點之後的傳遞,從而這個“非法的”終點變得“合法”。如下圖:
如果約束為“set_max_delay 5 -to [get_pins LUTA/O]”,LUTA/O作為組合邏輯單元的資料輸出管腳並不是一個合法的終點。但是時序引擎會阻止LUTA/O之後的傳遞,使其成為一個合法終點。
所有經過LUTA/O的時序路徑的建立和保持都會受到影響。從上圖看到,計算時只會考慮從REGA/C到LUTA/O之間的時鐘插入延遲,這同樣也會導致比較大的斜率。
路徑分割的影響
再次舉例強調一下路徑分割的缺點,由於路徑分割會阻止時序弧的傳遞,所有經過這些節點的路徑都會受到影響,如下圖:
假設在LUTA/O和REGB/D之間設定了最大延遲“set_max_delay 6 -from [get_pins LUTA/O] -to [get_pins REGB/D]”,如上圖藍線。
由於LUTA/O是一個非法的起點,發生了路徑分割,所有從LUTA/I*到LUTA/O之間的時序弧都被打斷。儘管上面設定的最大延遲約束可以起作用,但是其它經過此節點的路徑(REGA/C到REGC/D;REGA/C到REGB/D)由於路徑分割的影響也被打斷了。
路徑分割與時序異常
第33篇中也簡單提到過set_max_delay約束會被set_clock_groups約束替代的問題。當發生路徑分割時,可能會導致感覺上時序異常的優先順序發生了改變,但事實上並非如此。考慮如下兩個約束:
#情景1
set_max_delay <ns> -datapath_only -from <instance> to <instance>
#情景2
set_max_delay <ns> -datapath_only -from <pin> to <pin | instance>
第一個情景中,-from和-to提供例項名稱,set_max_delay約束總會被set_clock_groups -asynchronous約束替代。這是因為在給出例項的情況下,Vivado總會優先選擇合法的起點。
第二個情景中,如果-from提供的管腳名稱導致路徑分割現象出現,此時set_max_delay約束不會被set_clock_groups -asynchronous約束替代。這是因為路徑分割將該管腳名稱強制作為路徑起點,Vivado無需自己選擇,導致set_max_delay不會被set_clock_groups覆蓋。