Vivado使用技巧(33):時序異常
時序異常
英文名為Timing Exception,可以認為是時序例外或時序異常(本系列文章 的稱法),“例外”或“異常”是指這部分時序的分析與大多數常規時序分析不同。下表給出了Vivado支援的時序異常命令及功能:
命令 | 功能 |
---|---|
set_multicycle_path | 設定路徑上從起點到終點傳遞資料需要的時鐘週期數 |
set_false_path | 指示設計中的某條邏輯路徑不進行時序分析 |
set_max_delay、set_min_delay | 設定最小與最大路徑延遲值,會重寫預設的建立與保持約束 |
set_case_analysis | 使用埠或管腳上的邏輯常量或邏輯轉換進行時序分析,以限制訊號在設計間的傳遞 |
Vivado不支援即時分析有矛盾的時序異常,需要執行report_exceptions進行完整的分析,報告所有時序異常。多週期路徑的情況有很多,比較複雜,單獨放在第35篇中講述。本文介紹其餘三種時序異常的相關知識。
虛假路徑false path
某些在拓撲結構上看存在於設計中的路徑,但是沒有工作或者不需要被計時,便被稱作虛假路徑。虛假路徑在時序分析過程中應該被忽略不計。下面這些情況都屬於虛假路徑:
- 在有雙同步器邏輯的地方有時鐘域交叉
- 可能只在上電時寫入一次的暫存器
- 復位或測試邏輯
- 非同步分散式RAM的寫埠於非同步讀時鐘之間的路徑
舉個具體的例子加深對虛假路徑的理解,如下圖:
兩個多路選擇器MUX控制兩個暫存器間的資料傳輸,但是兩個MUX採用同一個選擇訊號。仔細分析會發現,無論如何Q端資料都無法傳遞到D端。雖然結構圖上看起來Q和D之間存在一條路徑,但是沒有起到任何功能,因此應該定義為虛假路徑。
為何要在時序分析中移除掉虛假路徑?理由如下:
- 減少執行時間:工具不需要為這些虛假路徑計時和做優化,可以減少很多執行時間。
- 增加結果質量:移除虛假路徑可以極大增加結果質量QOR(Quality of Results)。綜合、佈局和優化設計的質量很大程度上受到時序問題的影響,因為工具總會嘗試解決這些問題,包含虛假路徑會導致不理想的結果(比如工具將過多注意力放在解決虛假路徑的時序違背上,而忽視了真正需要解決的問題)。
虛假路徑由set_false_path命令定義,該命令模板如下:
set_false_path [-setup] [-hold] [-from <node_list>] [-to <node_list>] [-through <node_list>]
幾個節點列表選項的含義如下:
- -from:一組合法的起點列表,包括時鐘物件、時序元素的時鐘管腳、輸入主埠或雙向主埠。
- -to:一組合法的終點列表,包括時鐘物件、時序元素的資料輸入管腳、輸出主埠或雙向主埠。
- -through:一組合法的管腳或埠,注意節點的順序很重要。如果約束中僅使用了-through,沒有使用-from和-to選項,Vivado會從時序分析中移除所有通過該列表的路徑,使用時要特別小心。
下面給出幾個定義虛假路徑的例子:
#-through的順序表示路徑穿過節點的順序,因此下面是兩條不同的約束
set_false_path -through cell1/pin1 -through cell2/pin2
set_false_path -through cell2/pin2 -through cell1/pin1
#上圖中的虛假路徑應該用下面這條命令約束
set_false_path -through [get_pins MUX1/a0] -through [get_pins MUX2/a1]
#使用-through而不用-from和-to的好處是可以確保所有通過此節點的路徑都會被移除,而不用考慮起點和終點
#移除復位埠到所有暫存器間的時序路徑
set_false_path -from [get_port reset] -to [all_registers]
#禁用兩個非同步時鐘域間的時序路徑,從CLKA到CLKB
set_false_path -from [get_clocks CLKA] -to [get_clocks CLKB]
#注意,上述命令並沒有禁用從CLKB到CLKA的路徑,還需要補充如下約束
set_false_path -from [get_clocks CLKB] -to [get_clocks CLKA]
從最後一個例子可知,我們需要雙向地禁用時序路徑,但是如果設計中有多個非同步時鐘域,編寫起來就非常麻煩。不知道您是否還記得第31篇中講過的時鐘約束方法,這種情況最好其實應該使用set_clock_groups設定不同的非同步時鐘組。
上面還說到了非同步分散式RAM的情況,這裡也舉一個約束例子。假設一個非同步雙口分散式RAM,其寫操作於RAM時鐘同步,但是讀操作是非同步的,這種情況下應該在寫和讀時鐘間設定一個虛假路徑。約束如下:
#在RAM前的寫暫存器和RAM後的讀暫存器間設定虛假路徑
set_false_path -from [get_cells <write_registers>] -to [get_cells <read_registers>]
個例分析
設計中,某些訊號在特定模式中為常數值,比如:(1).某些測試訊號不會變換,直接連線在VSS或VDD上;(2).某些訊號上電後便不再發生變化;(3).如果設計有多種功能模式,某些訊號在部分模式下為活躍狀態,但在其它模式下為不活躍狀態。這些情況便屬於“個例分析”。
我們必須告訴靜態時序分析引擎,哪些訊號為常數值,從而減少分析範圍、執行時間和內部佔用率,並且不必報告那些不工作的和不相關的路徑。通常,設計者使用set_case_analysis命令將訊號(管腳和埠)申明為不活躍狀態。該命令的語法如下 :
set_case_analysis <value> <pins or ports objects>
引數值value可以是0、1、zero、one、rise、rising、fall或falling。作用物件可以是埠(port)、子單元(英文名為leaf cell)的管腳或層次模組的管腳。下面舉兩個例子加強對這種時序異常的理解。
第一個例子如下圖,clock_sel是一個時鐘選擇器,通過選擇管腳s對兩個輸入時鐘clk_1和clk_2進行選擇輸出:
如果我們只希望分析一種個例,比如只分析選擇clk_2時的情況。通過將 s管腳設定為常數即可只把clk_2傳遞到輸出埠o。約束如下:
set_clock -name -clk_1 -period 10.0 [get_pins clock_sel/I0]
set_clock -name -clk_2 -period 15.0 [get_pins clock_sel/I1]
set_case_analysis 1 {get_pins clock_sel/S}
對某一管腳設定了個例分析,會導致禁用經過該管腳的路徑上的時序分析,也不會報告相關資訊。第二個例子如下圖,BUFG_GT有一個動態時鐘分頻控制管腳DIV[2:0],由其它邏輯驅動而不是直接連線到VCC/GND:
預設情況下,Vivado會假設輸出時鐘的最壞可能情況,即1分頻(相當於不分頻,此時頻率最高)。然而如果設計中根本不會出現DIV取1的情況,這就成了過度約束。為了更合理地約束設計,我們可以對DIV[2:0]匯流排進行個例分析約束,比如可能出現的最差情況為DIV取3,約束如下:
set_case_analysis 0 {get_pins bufg_gt_pclk/DIV[0]}
set_case_analysis 1 {get_pins bufg_gt_pclk/DIV[1]}
set_case_analysis 0 {get_pins bufg_gt_pclk/DIV[2]}
最小/最大延遲
最大延遲約束set_max_delay用於改寫路徑的預設建立時間(或恢復時間)需求;最小延遲約束set_min_delay用於改寫路徑的預設保持時間(或移除時間)。兩條約束命令的語法模板如下:
set_max_delay <delay> [-datapath_only] [-from <node_list>] [-to <node_list>] [-through <node_list>]
set_min_delay <delay> [-from <node_list>] [-to <node_list>] [-through <node_list>]
-from、-to和-through和虛假路徑中的用法相同。set_max_delay命令中如果新增了-datapath_only,那麼計算裕量時便不會考慮時鐘斜率。使用最小/最大延遲約束要注意如下三點:
- 路徑上僅設定最大延遲約束(不使用-datapath_only選項),不會修改該路徑上的最小延遲需求,保持時間檢查仍採用預設值,相反也成立。但如果加入了-datapath_only,就會導致該路徑上的保持時間需求被忽略。
- 通常輸入埠到第一級暫存器間的約束用set_input_delay命令;最後一級暫存器到輸出埠之間的約束用set_output_delay命令(詳情見第32篇)。但輸入埠到輸出埠之間的純組合邏輯路徑可以用set_max_delay和set_min_delay命令進行約束(通常稱為in-to-out I/O路徑)。
- 某些非同步訊號間沒有時鐘關係,但是需要最大延遲約束。比如我們通常用set_clock_groups劃分兩個非同步時鐘域,但有時我們需要確保兩個時鐘域之間的路徑延遲不要太高。這種情況下,我們就要用set_max_delay和set_false_path的命令組合(因為set_clock_groups的優先順序更高,會取代set_max_delay,因此不能和其一塊使用)。
另外在約束最小延遲和最大延遲時,如果-from和-to中的節點選擇不合理,會出現路徑分割(Path Segmentation)現象。第34篇給出了路徑分割的具體例項及說明。
禁用Timing Arcs
最後再介紹一種時序異常的特例:Timing Arcs,字面翻譯為時序弧,之所以沒有單獨列為一種時序異常,是因為它與其它時序異常有著千絲萬縷的關係。其實很多情況下計時器為了處理一些特殊情況會自動禁用某些時序弧,比如:
- 組合邏輯反饋環不能被正確地計時(因此也不推薦使用),計時器會通過禁用環內的某條時序弧來打破環路。
- 據前文所述,預設情況下MUX的所有輸入資料都會傳遞埠,但是個例分析時將MUX的選擇訊號設為常數值,此時僅有一個資料輸入埠會傳遞到輸出埠。其實這正是由計時器打斷了其它資料埠到輸出埠間的時序弧實現的。
Vivado提供了set_disable_timing命令,可以人為打斷一個單元輸入埠到輸出埠之間的時序弧。考慮如下應用情況:
- 比如對於上面第一個例子的情況,可以人工設定打斷組合反饋環中的哪條時序弧,而不是讓工具自動完成。
- 假設有多個時鐘同時到達LUT的輸入管腳,但是隻能有一個時鐘傳遞到LUT的輸出埠。此時需要打斷與其它時鐘相關的時序弧。
當禁用了時序弧後,通過該時序弧的所有時序路徑都不會在時序分析中報告。因此使用時要額外小心,避免禁用了必要的時序弧,導致隱藏的時序違背或時序問題使設計在硬體中不能正常工作。set_disable_timing的語法及示例如下:
#語法,-from和-to只能設定為庫單元的管腳名稱(不是設計管腳名稱)
set_disable_timing [-from <arg>] [-to <arg>] [-quiet] [-verbose] <objects>
#禁用所有基於LUTRAM的非同步FIFO的WCLK到O之間的時序弧
set_disable_timing -from WCLK -to O [get_cells inst_fifo_gen/ gdm.dm/gpr1.dout_i_reg[*]]
#指定物件的所有以O管腳為終點的時序弧都被禁用
set_disable_timing -to O <objects>
#指定物件的所有以WCLK管腳為起點的時序弧都被禁用
set_disable_timing -from WCLK <objects>
#指定物件內的所有時序弧都被禁用
set_disable_timing <objects>
使用report_disable_timing命令可以檢視所有自動禁用和手動禁用了的時序弧。注意這個列表可能會非常大,最好加上-file選項儲存結果到檔案中檢視。
相關文章
- Vivado使用技巧(30):使用時序約束嚮導
- Vivado使用技巧(19):使用Vivado Simulator
- Vivado使用技巧(31):時鐘的約束方法
- Vivado使用技巧(27):RAM編寫技巧
- Vivado使用技巧(26):HDL編寫技巧
- Vivado使用技巧(17):建立IBIS模型模型
- Vivado使用技巧(6):Messages視窗管理
- Vivado使用技巧(29):約束功能概述
- Vivado使用技巧(20):Waveform功能詳解ORM
- Vivado使用技巧(18):模擬功能概述
- Vivado使用技巧(25):Block Synthesis技術BloC
- [譯] 時間順序的價格異常檢測
- Vivado使用技巧(9):COE檔案使用方法
- vivado無工程生成韌體及時序報告
- Vivado使用技巧(4):查詢功能詳解
- Vivado使用技巧(3):Force Up-to-Date功能
- Vivado使用技巧(11):設定FPGA配置模式FPGA模式
- Vivado使用技巧(8):Core Container打包IP核AI
- Vivado使用技巧(34):路徑分割現象
- Vivado使用技巧(28):支援的Verilog語法
- Vivado使用技巧(5):屬性編輯器的使用
- 課時33:異常處理:你不可能總是對的2
- Vivado使用技巧(16):SSN轉換噪聲分析
- Vivado使用技巧(14):IO規劃方法詳解
- Vivado使用技巧(23):綜合執行與OOC
- Vivado使用技巧(21):模擬中的Debug特性
- IDEA小技巧:Debug時如何優雅地製造異常?Idea
- Vivado使用技巧(15):DRC設計規則檢查
- Vivado使用技巧(13):CSV檔案定義IO Ports
- Vivado使用技巧(32):IO延遲的約束方法
- 自動化時序異常檢測的可擴充套件通用框架套件框架
- Vivado使用技巧(7):使用IP核自帶Testbench進行模擬
- 兩種異常(CPU異常、使用者模擬異常)的收集
- python自定義異常,使用raise引發異常PythonAI
- MVC使用異常過濾器處理異常MVC過濾器
- Flask開發技巧之異常處理Flask
- Vivado使用技巧(10):編輯與改寫IP核原始檔
- Vivado使用技巧(24):HDL/XDC中設定綜合屬性