1. X 態是什么?
Verilog 和 SV 定義了四種邏輯狀態:0,1,Z 及 X:
0 為低電平;
1 為高電平;
Z 為高阻態,可以理解為電路上的引腳懸空;
X 為不定態、亞穩態,可能為 0 可能為 1 也可能為 Z,常見于未復位的寄存器、鎖存器或 Memory。
其中,X 只有在仿真時存在,真實電路中不存在。若仿真過程中出現了 X 態,表明該處存在潛在的設計風險,其有可能會掩蓋 RTL Bug。
2. X 態是由什么引起的?
RTL 仿真、門仿真及低功耗仿真中均有可能出現 X 態。X 態出現的原因大致總結如下:
未初始化。未初始化的四態變量,比如 logic、wire、reg、integer、time 變量;未初始化的寄存器、鎖存器,在被復位或有確定的值被鎖定之前,保持 X 態。
輸入信號未連接。外部輸入信號未設置初值(尤其 DFT 信號)時為 Z,Z 在模塊內部經過數字邏輯后變 X 態。
信號多驅或總線爭用。SV 中允許將多個輸入驅動到同一 net 類型上,多多個驅動存在沖突時,net 即表現為 X 態。
操作結果不定導致的 X 態。
位選擇或數組索引超范圍返回 X 態。
邏輯門輸出的 X 態。SV 自帶原語或用戶自定義原語 (UDP) 支持四態操作,當這些邏輯門輸入為 X 或 Z 時,輸出 X。
后仿 setup 或 hold time 不滿足,存在 timing violation,使用 notifier 將輸出變為 X 態。若只看 timing violation 不輸出 X,則添加 vcs 編譯選項 +no_notifier。
主動引入的 X 態。設計人為引入的 X 態,比如在 case 分支中,對于 don’t care 的默認狀態中賦值為 X 態;驗證平臺引入的 X 態,比如存在四態變量 wire a, assign a = ‘bx。
寄存器或鎖存器掉電后上電。在低功耗仿真中,若無特別設置,即便在 0 時刻對寄存器或鎖存器進行了初始化,當其所在的 Power Domain 掉電后重新上電,其仍然為 X 態未初始化狀態,需要在 upf 中設置 reinit。
若 RTL 仿真沒問題,但門仿出現 X 態,可能為以下原因:
信號的輸入輸出方向聲明錯誤
控制信號出現 X 態
3. X 態有什么危害?
所謂 X 態傳播,是指 X 態作為觸發/控制條件或邏輯輸入時,引起其他邏輯輸出為 X 態。不同情況下 X 態危害情況不同:
若 X 態僅僅是存在,完全不傳播,其沒什么危害;
若 X 態出現傳播,且電路中針對該 X 態傳播做了保護,這種有限的 X 態傳播也沒有危害;
若 X 態出現傳播但電路中針沒有針對該 X 態傳播進行保護,那么該 X 態傳播可能會影響到芯片的正常工作。
4. 如何避免 X 態的產生?
確保引起 X 態的條件不成立即可避免 X 態產生,簡單列幾條:
使用二態變量。
設計上進行復位操作,控制通路寄存器必選帶復位,數據通路寄存器可以不帶復位。
驗證 TB 中接口輸入信號賦初值。
仿真時利用 initreg 及 initmem 選項對 reg 和 Memory 進行初始化。
RTL model 中添加針對 X 的 assertion,以及時發現 X 態并消除。
if-else 及 case 中使用確定寫法,或使用 assign+表達式代替if-else及 case。
4.1 if-else/case Vs. assign
RTL 仿真中,if-else/case 及 assign 對 X 態有不同的行為,如下:
if(x) 會默認 x=0,走 else 分支,不傳播 X 態。
case(x),若存在 default 分支,則走 default 分支,否則不會匹配到任何分支。
assign c = sel ? a : b; sel=x,輸出 X,從而將 X 態傳播出去。
也就是說,if-else 和 case 不能傳遞 X 態,無法暴露 X 態傳播問題,這就導致無法在仿真時去發現 X 態相關的 Bug。相比之下,assign + 條件表達式的方式能夠傳遞 X 態。此外,if-else/case 為帶有優先級的選擇電路,不利于時序和面積,建議使用 assign 代替 if-else 和 case。
有人有疑問:if-else/case 不傳播 X 態,assign 傳播 X 態,為什么還要用 assign?——我們不希望出現 X 態,但我們更不希望由于 RTL 寫法原因而掩蓋 X 態。使用 assign,能夠及時暴露 X 態問題,從而避免 X 態被掩蓋所導致的問題。
5. 兩種 X 態模型:X-optimism 和 X-pessimism
在對待 X 態問題上有兩種模型:
X-optimism,樂觀派,其認為 X 態不會被傳播。若檢測到邏輯輸出為 X 態,將 X 轉換為 0 或 1。
X-pessimism,悲觀派,其認為 X 態會一直被傳播下去。若檢測到邏輯輸入存在 X,即便輸出結果是確定的,也要輸出 X,從而將 X 態傳播出去。
在仿真階段,RTL 仿真對 X 態過于樂觀,RTL 仿真時往往忽略 X 態并賦一個確定的值,從而無法檢測到 X 態傳播所引發的問題;門仿更接近硬件行為,會暴露出 X 傳播問題。
6. 如何檢測 X 態傳播?
從設計角度,我們希望電路的邏輯輸出都是確定的,以避免非預期的功能缺陷。從驗證角度,我們不喜歡 X 態,但我們希望能夠發現并評估電路中所有可能存在的 X 態,尤其是能夠傳播的 X 態。
前文提到,RTL 仿真往往對 X 態過于樂觀,在門仿階段才會暴露出 X 態傳播問題。相較于 RTL 仿真,門仿的 netlist 易讀性差、仿真速度慢且難以 Debug。鑒于此,vcs 提供了一種 Shift-Left 方案,通過在編譯仿真選項中添加 -xprop 相關選項即可在 RTL 仿真階段對 X 傳播進行檢查。
6.1 Merge Mode 介紹
vcs xprop 檢查有 3 種模式,按照從樂觀到悲觀的順序,分別為:vmerge -> tmerge -> xmerge。其中:
vmerge mode,對待 X 態最為樂觀,遵守 Verilog 或 VHDL 規定的 X 態處理規則,不存在 X 態傳播問題。
tmerge mode,處于樂觀與悲觀之間,接近實際硬件行為或門仿,X 態傳播一段路徑后終結。
xmerge mode,對待 X 態最為悲觀,比門仿還悲觀,X 態會一直傳播下去。
不同 Merge Mode 時的 X 態傳播情況如下表所示:
說到底,-xprop=tmerge/vmerge 是為了擴散 X 態傳播,把不傳播不定態的情形,強制傳播出去,從而盡早暴露 bug。
6.2 xprop 命令使用
一般來講,可以在編譯或仿真任一階段指定 -xprop 選項即可開啟 xprop 檢測。
-xprop 示例用法如下:
vcs?xprop[=tmerge|xmerge|xprop_config_file]
其中,xprop_config_file 用以針對特定 instance 進行特定模式的 xprop 監測或開關特定 instance 的 xprop 檢測,其示例用法如下:
tree{top} instance{top.A}{xpropOn}; instance{top.B}{xpropOff}; module{C}{xpropOff}; merge=tmerge;
使能 xprop 后發現的 X 態不一定都是 Bug,或者設計已經針對 xprop 做了保護。這種情況下,可以采用 -xprop=xprop_config_file 對不同模塊施以不同的 xprop mode。
注意事項
-xprop 一般不能跟 +vcs+initreg+0/1/random 同時使用,因為 +vcs+initreg+0/1/random 會把 Verilog 的變量、寄存器及 Memory 初始值設置為 0 或 1 等非 X 狀態,這樣就測不到初始 X 態了。
若未指定 -xprop,默認為 vmerge,即默認不存在 X 態傳播問題,也不進行檢查。
若定義了 -xprop 但未指定具體模式,默認為 tmerge,即采用接近真實電路的 X 態傳播模式并進行檢查。
6.3 xprop 報告查看
vcs 在編譯、仿真兩個階段均提供了相關手段來檢查相關 instance 的 xprop 開關情況:
若在編譯階段使能了 xprop,編譯完成之后會生成一個 xprop.log 來報告 if/case 狀態、always 邊沿觸發等條件的 xprop 檢查開關情況。
simv 仿真階段添加仿真選項 -report=xprop[+exit] 能生成 xprop_config.report,便于在仿真后對 xprop 檢查情況進行確認。若采用 -report=xprop+exit,在檢測完 xprop 狀態情況后后立即終止仿真。
7. 什么階段進行 xprop 檢測?
X 態傳播不能不做,但也不宜早做。一方面,在驗證初期調 datapath 或 sanity 期間,我們并不想看到太多 X 態傳播,我們希望對待 X 態傳播更樂觀一點;另一方面,帶有 xprop 的仿真為 4 態仿真,毫無疑問,4 態仿真比不帶 xprop 的 2 態仿真更慢。
那么應該在什么階段開啟 xprop 檢測呢?以下是推薦的方案:
RTL 仿真前期不開啟 xprop,以盡快調通 sanity/smoke case 及主要 datapath。
RTL 仿真后期建議開啟 xprop,提前排除部分 X 態。
網表中沒有 always 塊,xprop 對門仿不起作用。門仿的一大作用就是排除 X 態傳播導致的芯片功能問題,尤其是控制通路上的 X 態傳播。
8. 如何用 Verdi Trace X?Trace 到什么地方停止?
我們說的 Trace X 是指追蹤 X 態產生的源頭。利用 Verdi 能夠自動追蹤組合邏輯、鎖存器、觸發器等的 X 態傳播的源頭。Verdi Trace X 有兩種途徑:一種是在 Verdi GUI 內 Trace,一種是直接利用 Verdi 的 traceX 工具直接 Trace。
8.1 Verdi GUI 內 Trace
若 X 態出現傳播,通常能在波形里找到很多 X 態信號。多個 X 態的源頭,此時我們可以選擇其中一個信號進行跟蹤。
假設在波形中已經發現了 X 態,該如何 Trace X 呢?兩種常用方式:
8.1.1 手動 Trace X
把出現 X 態的信號 A 拖到 nWave 窗口
nWave 窗口 Cursor 點在 X 態信號 0/1 -> X 跳變沿的地方
在源代碼窗口左鍵雙擊該信號 A,追蹤其 Driver
檢查 A 的 Driver (控制信號、觸發條件、邏輯輸入等) 是否存在 X 態
重復以上步驟,直到找到 X 態產生的源頭
8.1.2 自動 Trace X
把出現 X 態信號 A 拖到 nWave 窗口
nWave 窗口Cursor 點在 X 態信號 0/1 -> X 跳變沿的地方
nWave 窗口右鍵單擊該信號的波形,或源代碼窗口右鍵單擊該信號
選擇 Trace X,彈出 Trace X Settings 窗口
窗口勾選所需的 Trace X 相關設置。默認 View Options 為 Flow View,此處我們也可以改為 nWave View
左鍵單擊 Trace,開始 Trace X,Trace 結果一方面顯示在 Flow/nWave 窗口內,一方面顯示在 tTraceXRst 窗口內(Note 提示 X 的大致出現原因)
8.2 Verdi 的 traceX 工具
除了在 GUI 內進行 X 態追蹤,Verdi 還提供了 traceX 工具來追蹤 X 態。traceX 用法如下:
設置變量打開 traceX 工具,setenv VERDI_TRACEX_ENABLE
采用以下命令追蹤 X 態
未提供 X 態信號列表:traceX -lca -ssf xxx.fsdb
提供了 X 態信號列表:traceX -lca -ssf xxx.fsdb -signal_file signal.list若需要手段加載 database,還需要添加選項 -dbdir simv.daidir
查看 trx_report.txt 查看 Trace 結果
9. X 態怎么處理?
如果 X 態沒有傳播,無需處理。
如果 X 態發生傳播,但后續有 X 態保護電路,無需處理。
如果 X 態發生傳播,且后續沒有 X 態保護電路,需要從根源上消除 X 態。
10. 其他注意事項
assertion 中應規避 X -> 0/1 形成的跳變沿
審核編輯:劉清
-
仿真器
+關注
關注
14文章
1019瀏覽量
83934 -
vhdl
+關注
關注
30文章
817瀏覽量
128335 -
鎖存器
+關注
關注
8文章
908瀏覽量
41642 -
RTL
+關注
關注
1文章
385瀏覽量
59947 -
DFT
+關注
關注
2文章
231瀏覽量
22834
原文標題:X態及基于VCS的X-Propagation檢測
文章出處:【微信號:數字ICer,微信公眾號:數字ICer】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論