1. 程式人生 > 其它 >我的西皮優學習筆記(三)->模擬常見錯誤及其除錯方法

我的西皮優學習筆記(三)->模擬常見錯誤及其除錯方法

技術標籤:CPU

簡單來說就是除錯bug,因為對於硬體的除錯方法和軟體程式碼來說完全不同,在除錯的過程上也有很大的差距,所以需要學習一些特定的除錯方法

1)功能模擬波形分析

對於模擬波形圖的觀察來說是有一套套路的:

  1. 熟悉待除錯的設計

  2. 找到一個能明確的錯誤點

  3. 沿著設計的邏輯鏈條逆向逐級檢視訊號,直至找到源頭。

    因為我們直接找到的出錯點不一定是造成錯誤的源頭,但是修正錯誤必須解決掉錯誤的源頭,數位電路中各訊號之間的關係是一環扣一環的,是遵循嚴格的邏輯因果關係的,所以從一個錯誤點觸發,沿著邏輯追溯,就一定能找到錯誤的源頭。

一般沒有時序的波形時比較好看的,但在觀察有時序邏輯的電路波形時:

  1. 需要先將電路中的時鐘訊號抓出來,但是要注意不要抓錯時鐘訊號
    1. 因為有的電路並不只一個時鐘訊號
  2. 明確所觀察的時序器件(比如說常見的觸發器或者同步ram),觀察是上升沿觸發的還是下降沿觸發的。然後找到這個錯誤值寫入的那個時鐘上升或者下降沿,然後對生成這個觸發器或者RAM輸入的組合邏輯繼續追查下去,沿著時間軸向前找,一定要找到錯誤值寫入的真正時機。

2)提高波形分析效率的技巧

  1. 給重要的時刻做標記

    第一個是新增標記的按鈕,第二第三個都是能快速跳轉到標記的按鈕

  2. 熟練使用波形縮小、放大的功能

  3. 將關聯訊號分割、分組

    將相關聯的訊號用分割(Divider)和分組(Group)來區分

    比如說可以把同一級流水的訊號分成在同一個組中,建立分割時在你再想加分割空行的位置的上一個訊號處,對訊號右鍵new Divider ,刪除就是點選分割,按Del ,分組也一樣對準備放如一組的訊號選上,然後右鍵New Group 即可

  4. 多位寬訊號用值查詢快速定位

    為找到多位寬訊號某個值的時刻,建議是用值查詢Find value ,右鍵訊號名點選Find value 然後再波形上方會出現與搜尋相關的工具欄,根據提示輸入資料就行

    但是vivado 的Xsim不支援萬用字元,所以只能通過調整查詢工具欄中Matching的方式來實現模糊查詢的功能

3)波形異常類錯誤的除錯

一般錯誤分為以下幾類:

  1. 訊號為Z
  2. 訊號為X
  3. 波形停止
  4. 越沿取樣:上升沿取樣到被取樣資料在上升沿之後的值
  5. 其他:波形怪異,模擬波形圖顯示怪異,與設計的電路功能無關的錯誤

1、訊號為Z

Z 表示高阻,比如電路斷路了,就是顯示高阻

一般造成原因:

  1. RTL 宣告的wire 從未被賦值
  2. 模組呼叫的訊號未連線
    1. input 類介面被呼叫時不允許懸空,但是output 未連線是母模組裡不使用該訊號,可能是人為故意設定的
    2. 如果a是埠未連線,則從0時刻開始就是Z,但是如果是a_r 從一段時間之後才顯示Z是因為a_r 是內部暫存器

解決建議:

  1. RTL 編寫時注意程式碼規範特別是模組呼叫時,按介面順序一一對應
  2. 所以input類介面被呼叫時不允許懸空
  3. 一旦發現一個訊號是Z,向前追蹤產生該訊號的因子訊號,看是哪個是Z,一直追蹤下去直到追蹤到該模組裡的input介面
  4. Z也可能出現在向量訊號的某幾位上,也是一樣的追蹤,有可能是某個介面存在寬度不匹配帶來介面上某些位為Z

2、訊號為X

造成原因:

  1. RTL 裡宣告為reg型的變數,從未被賦值
  2. RTL裡寫成了多驅動的程式碼,有時候也可能導致X、
    1. 多驅動的情況一般會在綜合的時候報出Cirtical warnings ,multi-driven

解決建議:

  1. 一旦發現模擬錯誤來自某個訊號為X,則向前追蹤該訊號的因子訊號,看是哪個為X,一直追蹤下去直到發現某個訊號未賦值,隨後修改
  2. 如果因子訊號都沒有X,可能是多驅動導致的,則進行綜合然後排查Error 和 Cirtical warning
  3. 暫存器型訊號如果沒有復位值,在復位階段其值可能是X,但可能並不會帶來錯誤
  4. X 和 1的運算結構為1,而X和0的運算結果為0

3、波形停止

狀態顯示:模擬停止在某一時刻,無法前進,但是模擬卻嚇死你hi不停的在執行,而造成的原因往往是因為RTL裡面存在組合環路導致的。

wire c_t;
assign c_t = a_r & b_r +c;
assign c = a_r + c_t ;

有些波形停止表示是波形立刻停止,並顯示檢測出fatal,

比如說模擬模擬時迭代次數到了10000 的限制,其實是因為死迴圈模擬組合環的計算,達到次數上限之後自動停止模擬了:

會報錯:

ERROR :[Simulator 45-1] A fatal run_time error was detected ,Simulation cannot continue

組合環路:

​ 就是訊號A的組合邏輯表示式中用到了某個產生因子B ,但是B 的組合邏輯中又用到了A

​ 比如說上面原始碼中c_t 的訊號的勝場用到了c,但是c又用到了c_t 。模擬器是在每個週期內計算該週期的所有表示式,組合邏輯迴圈巢狀,帶來的是模擬器的迴圈計算,導致其無法退出該計算,進而導致了波形停止的現象。

但是並不是所有的組合環路都會導致波形停止,有些非常繞的組合環路(比如跨多個模組形成的組合環路),可能會被工具自動處理掉,但是這樣的處理是由風險的,可能會導致模擬通過,但是上版不過

解決建議:

  1. 發現波形停止,對設計進行綜合
  2. 檢視綜合產生的Error 和 cirtical warning,並嘗試修正,比如說上面的組合環路經過Vivado 的綜合變成了一個多驅動的關鍵警告
  3. 在沒有綜合前,可以使用Vivado 的TCL 命令,report_timing_summary,會檢查組合環路,並爆出檢查結果。但是綜合變成多驅動的warning 可能無法爆出結果