調試(Debug),是個非常廣泛的話題,讓我先嘗試給它下個定義:
調試指的是在遇到工程問題的時候,通過一些手段來進一步診斷問題原因,探索解決方法,最終使得系統功能正常運行的必要過程。
調試應該說是任何一個工程師解決問題的必備技能,對于芯片驗證工程師來說更是如此。調試通常沒有固定的章法,不可能按照某一個流程步驟就可以解決所有的工程問題,畢竟在實際環境中遇到的問題千差萬別,可能只是你的某一個命令參數敲錯了,可能是RTL邏輯設計上存在bug,也可能是設計規格(Specification)本身就存在紕漏,等等等等。
盡管調試方法不固定,但調試思想還是很一致的,那就是:盡可能的獲取更多的有效信息,并對這些信息做綜合分析。你細品,比如最常用的導出仿真日志(log)或者波形文件,這些方法本身就是為了獲取更多的有效信息,這些信息能夠幫助我們更好地去了解現在RTL的功能行為,幫助我們進一步對問題進行定位。
回到本文主題,本文要介紹的內容就是調試過程中常用的方法和技巧,這些方法的合理應用可以獲得上面說的有效信息,從而提高我們解決問題的效率。而至于如何做信息的綜合分析,需要根據具體場景和經驗才能完成。
方法1:文件和參數索引的建立
之所以把建立文件和參數的索引也說成是調試方法,是因為在面對一個組件繁雜的驗證環境,或者規模龐大的設計的時候,能夠快速地檢查相對應特性的規格文件、配置文件、宏定義、類型定義、參數配置、類原型、函數原型等信息,極有可能就可以解決掉一些低級的錯誤了。
要快速地找到這些有效信息,一方面依賴于工程師對當前驗證環境和設計配置文件的熟悉程度,另一方面可以借助一些工具來找到它們。后者就是本節所要介紹的內容,下面就直接羅列我工作中最常用的一些工具和命令。
使用ctags掃描工作目錄,建立基于語法元素的索引,配合Vim可以實現語法元素的快速跳轉。
使用meld工具比對目錄或者文件在不同版本之間的差異,功能比gvimdiff強那么一些。
Windows下使用Listary或者Everything軟件來快速查找本地文件,可以參考《芯片工程師必備軟件神器》。
Linux下使用grep命令來篩查文件內容,配合管道符“|”可以實現更多級的篩查。
掌握一兩門腳本,Python、Perl、Shell等都可以,掌握正則表達式,隨手就可以實現一些小功能。
以上提到的工具和命令,都可以在網上找到大量的教程。如果有時間,我再寫一些小的使用Tip放到公眾號上。
方法2:波形的導出和使用
通過波形可以很直觀地看到RTL隨時間變化的所有行為細節,盡管拉波形看信號變化看多了容易眼睛瞎掉,但不得不承認大多數情況下沒有波形的話問題定位會變得寸步難行。波形文件是仿真過程的副產物,它按照一定的格式將每個仿真事件發生時刻的信號和變量狀態記錄下來,并最終以圖形化的方式呈現出來。
波形文件的格式很多,比如VCD、FSDB、VPD、WLF等等。
VCD格式應該說是最通用的波形格式,它是SV標準中定義的一種ASCII文件格式,其全稱是Value Change Dump。VCD包含了所有信號的變化信息,它可以被任何EDA調試工具打開。VCD文件可以在testbench中使用SV的內建任務$dumpfile("name.vcd")和$dumpvar()來導出。
FSDB的全稱是Fast Signal Database,它是原來Novas公司(先被Synopsys收購)的工具Verdi專用的波形格式。在testbench中,可以使用Verilog PLI接口(可以像調用內建函數那樣去調用C/C++函數)調用$fsdbDumpfile("name.fsdb")和$fsdbDumpvars(0, top)去導出。注意,要用著兩個函數需要將Verdi安裝目錄中share/PLI下的相關庫添加到動態鏈接庫路徑($LD_LIBRARY_PATH)中,或者有參數(比如Mentor工具用的-pli)去指定PLI庫的路徑。
VPD是Synopsys自家定義的波形壓縮格式,叫VCD Plus(這個plus是不是有點似曾相識的感覺),在使用Synopsys VCS工具仿真時可以導出VPD波形,同時也可以使用使用配套的波形瀏覽器DVE(Discovery Visual Environment)去打開波形。VPD波形可以在testbench中使用$vcdpluson去導出,在VCS做編譯和仿真的時候需要指定debug能力,比如加參數-debug_all。
WLF的名字就比較單純,叫Wave Log Format,一看就知道是干啥的。WLF格式是Mentor家(現在屬于SIEMENS)定義的,可以由QuestaSim或者ModelSim仿真工具可以生成和加載。如果你用ModelSim做過實驗,當你打開波形界面,它會在工作目錄下自動生成一個WLF文件。另外Mentor的工具還可以使用命令選項-qwavedb并附加一串選項,可以在仿真過程中生成仿真數據庫文件(simulation database),該文件以.db為后綴,可以當成仿真波形被Visualizer調試工具打開。
以上提到的函數調用在參數上具有很大靈活性,可以指定具體要dump波形的RTL層級、scope范圍甚至指定哪些信號。此外還有其他函數可以用來限制波形文件大小、波形dump開關、導出Memory數據等等。
盡管不同格式的波形文件有以上差異,但在應用的時候大部分情況下取決于你有什么EDA工具可以用,另一方面這些波形格式也有工具可以相互轉化。
仿真波形在使用的時候通常有一些技巧,方便問題的定位和重現,下面列舉幾個常用的:
將功能相關的信號分組(group)放在一起,方便做邏輯或協議檢查;
可以將多個信號組合成總線信號,或者進行自定義的邏輯運算;
為被關注的仿真時刻添加標簽(Mark),方便來回觀看;
通過添加標尺可以查看信號事件間距、周期信號頻率、統計信號事件等功能;
將常用的狀態信號、總線信號、某個用例調試用的信號等保存成do文件,即將當前波形界面的元素保存下來,方便波形重現;
每個人看波形的習慣和方式會有不同,找到自己習慣的方式就可以了;
方法3:仿真日志的導出和使用
仿真日志(常說的log文件)通常是我們查看仿真結果會首先打開的文件。該文件中可以包含整個仿真過程中由編譯器和仿真器打印輸出的各種文本信息,比如當前導入了哪些文件、本次編譯和仿真分別用到了哪些參數、當前DUT的頂層是哪一層、仿真過程中不同時刻的關鍵動作和信息、本次仿真的結果和資源開銷等等。
基于文本的仿真日志記錄和對仿真日志的手動分析看起來是比較低級和低效的,特別是當我們看著仿真日志并順著時間軸試圖去將打印數據和RTL行為關聯起來的時候,簡直苦不堪言。盡管如此,仿真日志的導出和使用仍然在某些時刻起到了基礎性的作用,特別是在UVM將report機制構造健全之后,其作用不可忽視。
SystemVerilog本身在打印信息上有好幾個任務可以用:$display, $write, $strobe, $monitor, 這幾個任務的使用上不完全相同。
最常用的是$display,$display可以用來做格式化輸出,格式化方法跟C語言幾乎一致,并且打印完成之后會自動換行。
$write則用的不多,它的功能跟$display很接近,區別在于在打印完成之后不會添加換行符,所以適用于想要在一行里輸出多個信息的場景。
$strobe的打印就比較講究了,通過$strobe打印的變量值是當前仿真時間槽(time slot)中該變量最后的值,比如對變量A做非阻塞賦值(<=)之后跟著用$strobe打印變量值,打印出來的是該變量完成賦值之后的值,而如果用$display則是打印出來該變量賦值完全之前的值。
$monitor的功能就跟它的名字一樣,它相當于是在主線程之外開了一個監控線程。當通過$monitor打印的變量或者表達式發生改變時,打印的功能就會被觸發,看起來就像是一個有了外部中斷能力的$display。
在UVM的框架里,打印信息被賦予了嚴重性等級(severity)和冗雜等級(verbosity),這在信息控制上提供可很大的便利。
Severity分成了INFO、WARNING、ERROR和FATAL,分別使用宏uvm_info、uvm_warning、uvm_error和uvm_fatal來進行信息打印。
Verbosity等級共分為UVM_NONE、UVM_LOW、UVM_MEDIUM、UVM_HIGH、UVM_FULL、UVM_DEBUG六級,表示信息的冗雜程度由低到高。
INFO顧名思義就是簡單的狀態信息打印,這些信息并不是必須的,它的verbosity屬性可以通過uvm_info宏的參數來指定。比如當仿真的verbosity設為UVM_DEBUG時,所有uvm_info信息都會被打印出來,仿真日志會顯得非常冗雜;當仿真的verbosity設為UVM_NONE的時候,只有UVM_NONE屬性的uvm_info信息才會被打印出來,仿真日志就看起來簡潔很多。
WARNING指的是一些警告信息,提示潛在的問題,比如你顯式地調用了某個phase,可能不會影響仿真的繼續,但可能會讓仿真場景不符合預期。WARNING的verbosity默認都是UVM_NONE,因此始終會被打印出來。
ERROR就是一些錯誤信息,錯誤信息的出現不會使得仿真馬上停止,UVM給我們提供了閾值設置,當錯誤信息的數量達到某個值只有仿真就會自己退出。通常UVM_ERROR的信息被打印出來,我們都需要去把它們都解決掉。ERROR的verbosity等級默認都是UVM_NONE,所以也不要想著用verbosity來屏蔽它。
FATAL就是一些致命的錯誤,只要一出現仿真就會馬上退出,這種問題同樣必須解決,不解決你連仿真都跑不完??上攵@類信息同樣verbosity默認是UVM_NONE,始終會被打印出來。
Verbosity的設置出了直接用仿真參數+UVM_VERBOSITY=UVM_DEBUG來配置,UVM還提供了+uvm_set_verbosity這一非常靈活的參數,具體使用方法這里就不做介紹了。UVM出了這套完備的打印信息控制機制之外,還提供了很多調試宏,比如+UVM_CONFIG_DB_TRACE、+UVM_PHASE_TRACE、+UVM_OBJECTION_TRACE等,用來方便用戶從仿真日志中觀測配置數據庫(configuration database)狀態、phase執行狀態和objection狀態等。
總而言之,信息的打印方法有很多,UVM在report機制上也給到了足夠的控制手段,利用好這些方法,仿真日志將是我們調試用例的利器!
方法4:可視化調試
可視化調試主要分為Post-process和Interactive這兩種模式??梢暬{試工具是工程師在定位代碼問題時的有力工具,也是現在驗證工程師主流的調試工具。工具的使用一般可以參考官方的用戶手冊(User Guide),也能夠在官網上找到相應的培訓鏈接和視頻。
常用的可視化調試工具有Synopsys家的Verdi,Siemens家的Visualizer,還有Cadence家的SimVision。對于個人用戶來說,可能沒有辦法去實操體驗,但通常所在公司會購買至少一家的License。三家公司的工具的操作流程和基礎調試功能都差不多,然后又分別有自己調試的獨特功能。
先介紹下后處理調試模式(post-process,即在仿真結束之后再去可視化和處理仿真結果,有些地方會叫做PPE,post-processing environment)的使用,因為這種方式在實際工作中用的比較多。在使用可視化調試工具之前,通常需要將testbench和RTL編譯到同一個數據庫中,該數據庫包含了文件信息、RTL例化層次信息、信號連接關系等等,以供調試工具的追蹤和分析。
如果使用Verdi工具,需要使用VCS在編譯(Compilation=Analysis+Elaboration)的時候,通過加參數-kdb -lca來生成KDB庫(Knowledge Database),其中lca(Limited Customer Availability Features)參數是為了指定工具特性。KDB數據庫格式是Verdi專用的格式,所以KDB庫有時候也可以叫Verdi庫。打開verdi的時候使用命令verdi加參數-elab來選擇該KDB庫。
如果使用Visualizer工具,需要使用Questa/ModelSim在對設計完成編譯(vlog/vcom)之后,使用vopt命令加參數-debug -designfile design.bin來生成.bin文件,同樣該文件格式是Visualizer專用的。打開Visualizer的時候使用命令visualizer加參數-designfile來選擇該bin文件,使用參數-wavefile來選擇db波形文件。
如果使用SimVision工具,需要在仿真階段使用NC仿真器或者XCelium仿真器(具有更高的仿真性能,比如支持多核等)將設計和波形都導出成shm格式。在仿真結束之后,你可以看到名為example.shm的目錄,該目錄下會有兩個文件:.dsn文件和.trn文件,前者包含的是設計的信息(類似于我們上面說的數據庫),后者包含的是波形信息。打開SimVision的時候使用命令simvision直接加example.shm來打開待調試的數據庫。
再看看交互模式(interactive mode),交互模式相對于后處理模式增加了仿真控制的功能,即可以設置仿真斷點、控制仿真的暫停、運行和重啟等,并實時地觀察到信號的行為。交互模式下,上述EDA工具的界面上會多出來一些調試控件。不過這種模式的仿真運行速度比較慢,且在分發和重現代碼行為上不是很友好,所以在實際工作中也用的比較少,除非遇到非常棘手但卻摸不著頭腦的問題。以上提到的幾家工具都支持交互模式調試,操作流程也都差不多,并且跟后處理模式一樣也需要先編譯出來一個數據庫。
如果使用Synopsys家的工具,在設置完必要的環境變量之后,比如VCS_HOME和VERDI_HOME,需要使用VCS命令vcs -kdb -lca -debug_access+all
如果使用Siemens家的工具,同樣在設置完必要的環境變量并使用命令vopt編譯出design.bin文件之后,可以使用命令vsim -visualizer=design.bin -qwavedb=+signal+class -f
如果使用Cadence家的工具,那就相對復雜一點,因為Cadence前前后后有幾個仿真器,比如verilog、ncsim、irun,并且進交互調試模式的方法也比較多樣,但大致可以分兩種:一種是可以通過參數-gui直接開啟帶SimVision的仿真器,另一種方式是單獨啟動SimVision,使用參數-connect host/pid連接到運行在本地或者遠端的仿真上。
以上命令只是展示大概的使用過程,實際應以對應版本的用戶手冊為準哈。當你打開可視化調試工具調試界面之后,有這么幾種常用的調試功能:
通過Hierarchy等窗口瀏覽源代碼的例化層次結構,類繼承關系等;
通過查找Driver和Load來定位信號的傳播通路(這個是用的最多的);
通過Filter來分類查看當前文件包含的輸入輸出信號、參數、變量等;
通過查找來定位某一個module例化出來的所有模塊;
原理圖和狀態機跳轉圖可以有限地幫助你理解代碼行為;
配合波形文件查看各種信號隨時間變化的行為;
調試工具的功能還有很多,具體可以查看各個工具的官方介紹和培訓視頻。
方法5:SVA斷言在調試中的應用
概述:SystemVerilog Assertion(斷言)主要用于驗證設計的行為,并且可以提供功能覆蓋率信息。Assertion可以應用于兩種不同的驗證方法中,一種是在動態仿真中去動態地檢查各個既定屬性(property)是否滿足,另一種測試用于Formal驗證工具去證明設計是否符合規范。
作用:如果你剛接觸,可以把斷言簡單理解成checker或者monitor,它指的是在設計中嵌入一些工程師根據待測特性自行定義的一些屬性,仿真的時候仿真工具會去判斷這些屬性是否成立,以此來判斷某個特性是否實現正確。SVA在本文中作為調試的方法來介紹,就是因為斷言可以幫助我們監測屬性,為我們報出來哪些時刻行為正常、哪些時刻行為異常,且這些行為可以是有時序的!
分類:在SystemVerilog中,斷言大致可以分為兩類:立即斷言(immediate assertion)和并發斷言(concurrent assertion)。立即斷言是基于仿真事件(simulation event)的,當它被執行到的時候就會立即對多定義的屬性做出判斷并給出結果;而并發斷言是基于時鐘的,斷言的評估(evaluate)發生在時鐘邊沿,這也使得并發斷言具有監測的能力,這也是下面要主要介紹的。
結構:斷言的具體實現依賴于更基礎的元素,比如sequence和property。Sequence是最底層的元素,它可以復用和嵌套。Sequence可以用來定義簡單的布爾表達式,也可以用來描述多周期的時序行為。Property則可以實現跟sequence一樣的內容,也可以通過組合不同的sequence來構造更加復雜的時序行為。為了規范化,建議將嵌入的時鐘信號@(posedge clk)放在property這一層,而將sequence跟時鐘獨立開來,方便基礎sequence的復用。
調度:SystemVerilog的仿真基于事件驅動模型,事件的調度機制在SV語言標準中有明確說明。該調度機制將每個仿真時刻(time slot)再劃分成多個region,如下圖所示,每個region都有自己明確的操作。仿真調度算法的確定,可以使得仿真環境跟DUT交互時顯示出同步的效果。其中跟SVA相關的region有Preponed、Observed和Reactive。在Preponed中,SVA會對有關聯的變量完成采樣;在Observed中,多有的property完成評估,即判斷斷言描述是否成立;在Reactive中,執行斷言評估結果需要采取的對應的操作。
應用:斷言的應用主要可以分成四個步驟:1、構造基礎布爾表達式;2、構造sequence序列;3、構造斷言屬性property;4、將屬性代碼插入或綁定(bind)到待測模塊中。SVA提供了一些好用又強大的功能:判斷信號邊沿和狀態、添加延時來構造信號時序行為、支持構造不定周期的時序窗口、判斷過去的信號狀態、支持斷言的邏輯運算等等,本文篇幅顯然是不夠的了。
方法6:軟件調試方法的借鑒和應用
這一節的內容更像是討論,有哪些軟件開發中用到的調試方法,或者問題定位策略是可以借鑒過來應用到芯片驗證中的。
有個前提需要明確的是,硬件仿真始終是基于事件驅動的程序執行過程,盡管仿真調度機制簡潔明了,但往往待測設計規模龐大(具體表現為硬件行為具備并行性質,一個時鐘信號的翻轉事件關聯著成千上萬的信號動作),所以硬件仿真的運行速度會非常的慢,這是跟單純軟件程序的一個顯著區別。
運行速度上的差異帶來了調試方法上的一些不同。軟件調試中交互式的操作非常多,比如解釋執行的腳本(比如Python)不需要編譯就可以馬上得到執行的結果,又比如基于斷點的調試可以非常容易地檢查變量值和堆棧跟蹤。反觀硬件調試,工程師很難快速地知道在哪里設置斷點,往往需要反復的嘗試,這會浪費掉很多時間。因此硬件的調試更多依賴于信息的導出,其形式通常是仿真日志和波形文件。
如何提高硬件調試的交互性可能是軟件調試帶來的啟示,有這么一些不成熟的想法,比如是否可以增加調試信息(代碼、波形和仿真日志)之間的關聯,實現自動化跳轉;是否可以增加工具對代碼的理解或者記錄調試過程來進行自動化分析;是否可以在增量編譯的概念上實現增量仿真;等等等等。
審核編輯:劉清
-
Linux系統
+關注
關注
4文章
594瀏覽量
27441 -
RTL
+關注
關注
1文章
385瀏覽量
59852 -
python
+關注
關注
56文章
4799瀏覽量
84817 -
Verilog語言
+關注
關注
0文章
113瀏覽量
8280 -
DUT
+關注
關注
0文章
189瀏覽量
12419
原文標題:SystemVerilog | 這些Debug調試方法你都知道嗎?
文章出處:【微信號:處芯積律,微信公眾號:處芯積律】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論