芯片驗證調試手冊 -- 驗證疑難點工作錦囊

劉斌 著

買這商品的人也買了...

商品描述

資深芯片驗證專家劉斌(路桑)圍繞目前芯片功能驗證的主流方法―動態仿真面臨的日常問題展開分析和討論。
根據驗證工程師在仿真工作中容易遇到的技術疑難點,
本書內容在邏輯上分為SystemVerilog疑難點、UVM 疑難點和Testbench 疑難點三部分。
作者精心收集了上百個問題,給出翔實的參考用例,指導讀者解決實際問題。
在這本實踐性很強的書中,作者期望能夠將作者與諸多工程師基於常見問題的交流進行總結,
以易讀易用的組織結構呈現給讀者,目的是幫助芯片驗證工程師更有效地處理技術疑難點,加快芯片驗證的調試過程。

作者簡介

劉斌(路桑)
畢業於西安交通大學微電子專業,瑞典皇家理工學院芯片設計專業碩士。
擁有超過50,000名驗證從業訂閱者的路科驗證創始人,主持國內前沿的芯片驗證架構規劃和方法學研究,
擔任過數款十億門級通信芯片的驗證經理,目前獨立從事芯片驗證技術諮詢。
同時在西安電子科技大學長期客座授課,以及開展芯片驗證職業在線教育為業界輸送大量人才。
著有《芯片驗證漫遊指南》。
可通過bin.liu@rockeric.com與作者取得聯繫。

目錄大綱

第1章 什麼是疑難點?

第2章 SystemVerilog疑難點集合
2.1 數據使用
2.1.1 組合型數組和非組合型數組怎麼區分?
2.1.2 組合型數組和非組合型數組如何做賦值?
2.1.3 在使用enum或struct時添加typedef與否的差別是什麼?
2.1.4 什麼是靜態變數和動態變數?
2.1.5 struct和struct packed區別在哪裡?
2.1.6 關聯數組的散列存儲表示什麼?
2.1.7 如何將隊列插入到另外一個隊列中?
2.1.8 隊列在賦值時使用操作符{},那麼它屬於組合型嗎?
2.1.9 數組的選取可以用兩個變數作為索引邊界嗎?
2.1.10 parameter、localparam和const有什麼聯繫和差別?
2.1.11 多維數組的聲明和使用,哪種方式更合適呢?

2.2 操作符使用
2.2.1 {}操作符的使用場景有哪些?
2.2.2 條件賦值符?:和條件語句if-else的執行結果一致嗎?
2.2.3 if和iff的應用場景分別有哪些?
2.2.4 使用foreach在輪循數組時按照什麼順序呢?
2.2.5 運算符的優先順序是否有必要記憶呢?
2.2.6 assign連續賦值可以賦值給logic(var)類型嗎?
2.2.7 ::和.這兩個符號使用起來有哪些區別?

2.3 模塊、介面與方法
2.3.1 module中的方法在聲明時是否要添加automatic?
2.3.2 interface在何處需要使用virtual來聲明呢?
2.3.3 initial和always的執行順序是否與代碼位置有關?
2.3.4 interface的modport和clocking block如何使用?
2.3.5 module和interface之間可以相互例化嗎?
2.3.6 方法的參數默認方向該如何辨別?
2.3.7 return的使用場景有哪些?
2.3.8 task與function的聯繫和差別在哪裡?
2.3.9 方法的參數默認值該如何使用?
2.3.10 方法中參數方向inout和ref有什麼差別?
2.3.11 module和interface中的變數聲明必須放置在頭部位置嗎?
2.3.12 如何例化和傳遞多個相同類型的介面?
2.3.13 使用while和forever語句時需要注意什麼?
2.3.14 系統函數和內建方法有什麼區別?
2.3.15 介面和模塊的聯繫和差別是什麼?
2.3.16 program和module的聯繫和差別是什麼?
2.3.17 多個線程在模擬調度中是如何在不同的域之間執行和切換的?
2.3.18 時鐘塊在使用時需要注意哪些地方?
2.3.19 如何連接和驅動雙向埠信號?

2.4 類的使用
2.4.1 類的成員變數在聲明時或在new函數中初始化有何區別?
2.4.2 new函數與其他函數有哪些不同?
2.4.3 關鍵詞new的使用場景有哪些?
2.4.4 對象佔用的空間什麼時候會被回收?
2.4.5 this的使用場景有哪些?
2.4.6 對象拷貝的種類如何劃分?
2.4.7 this和super有什麼聯繫和差別?
2.4.8 子類成員如何覆蓋父類成員?
2.4.9 子類句柄和父類句柄的類型如何轉換?
2.4.10 為什麼父類句柄經常需要轉換為子類句柄?
2.4.11 虛方法聲明和不聲明的區別是什麼?
2.4.12 虛方法的描述符virtual應該在哪裡聲明?
2.4.13 句柄一旦不指向對象,該對象就被回收了嗎?
2.4.14 什麼時候該使用local和protected?
2.4.15 class和virtual class的區別是什麼?
2.4.16 virtual修飾符在哪些場景中會用到?
2.4.17 子類能夠使用與父類相同名稱但不同參數的方法嗎?
2.4.18 使用參數類或者介面時要注意哪些?

2.5 隨機約束使用
2.5.1 rand描述符可用於哪些變數類型?
2.5.2 數組使用rand聲明會發生什麼?
2.5.3 句柄使用rand聲明會發生什麼?
2.5.4 rand和randc的區別在哪裡?
2.5.5 內嵌約束中的local::表示什麼?
2.5.6 是否可以利用動態數組對變數值的範圍進行約束?
2.5.7 多個軟約束在隨機化時有衝突是否可以解決?
2.5.8 結構體是否可對其成員使用rand描述符?
2.5.9 如何隨機化對象的多個成員且使每次數據不重複?
2.5.10 子類會繼承還是覆蓋父類的約束?

2.6 覆蓋率應用
2.6.1 covergroup的採樣事件如何指定?
2.6.2 covergroup如何對變數進行採樣?
2.6.3 是否可對covergroup中的不同coverpoint指定採樣條件?
2.6.4 covergroup在哪裡定義和例化更合適?
2.6.5 如果covergroup中的bins沒有被採樣,可能有哪些原因?
2.6.6 如何減少不關心的cross bins採樣數據?

2.7 線程應用
2.7.1 semaphore使用時需要初始化嗎?
2.7.2 mailbox使用時需要例化嗎?
2.7.3 fork-join_none開闢的線程在外部任務退出后也會結束嗎?
2.7.4 父線程和子線程之間的執行關係是什麼?
2.7.5 disable fork和disable statement有什麼差別?
2.7.6 嵌套的fork有沒有可能被disable fork誤傷呢?
2.7.7 使用for配合fork-join_none觸

第3章UVM疑難點集合
3.1 UVM機制
3.1.1 是否所有的UVM對像都應該用工廠創建呢?
3.1.2 工廠創建uvm_object是否需要為其指定parent?
3.1.3 為什麼建議配置放在對象創建之前?
3.1.4 UVM環境中進入new()和build_phase()有什麼區別?
3.1.5 在創建組件時採用new()有什麼影響?
3.1.6 UVM配置類的參數修改應該發生在什麼時間?
3.1.7 UVM的消息嚴重等級是否可以屏蔽或修改觸發動作?
3.1.8 UVM的消息嚴重等級是否可以修改?
3.1.9 通過uvm_config_db可以完成哪些數據類型的配置?
3.1.10 使用uvm_config_db時傳遞的參數類型是否需要保持一致?
3.1.11 如何設置timeout時間防止仿真超時?
3.1.12 set_drain_time()的作用是什麼?
3.1.13 組件的phase方法中繼承父類的phase方法是在做什麼?
3.1.14 如何控制UVM最後打印的消息格式?
3.1.15 配置對象的層次為什麼應與驗證環境的層次相同?
3.1.16 uvm_config_db和uvm_resource_db在使用時有什麼區別?
3.1.17 在繼承UVM某些參數類時是否需要指定參數類型?
3.1.18 UVM中的註冊類有重名時會發生什麼?
3.1.19 為什麼在build_phase中訪問更低層次的組件會失敗呢?
3.1.20 在UVM中是否可跨層次調用某些組件的方法?
3.1.21 在使用uvm_config_db時要注意什麼?

3.2 通信與同步
3.2.1 event和uvm_event的聯繫和區別是什麼?
3.2.2 sequencer和driver的類型參數REQ/RSP需要保持一致嗎?
3.2.3 TLM FIFO的方法是否可以直接調用?
3.2.4 為什麼uvm_object類型不能例化TLM端口?
3.2.5 UVM回調函數類的使用特點有哪些?
3.2.6 uvm_event應從哪裡例化和獲取?
3.2.7 TLM端口為什麼沒有註冊過呢?

3.3 測試序列
3.3.1 m_sequencer和p_sequencer有什麼區別?
3.3.2 為什麼不建議在sequence中使用pre_body()和post_body()?
3.3.3 sequence如何通過uvm_config_db獲得配置的變量?
3.3.4 start()和`uvm_do_on()有何區別?
3.3.5 uvm_sequence_library的作用是什麼?
3.3.6 配置default_sequence和調用sequence::start()是否可同時進行?
3.3.7 一些sequence調用raise_objection()的目的是什麼?
3.3.8 每一個sequence都需要調用raise_objection()嗎?
3.3.9 set_automatic_phase_objection()使用起來方便嗎?
3.3.10 如何終止一個正在執行的sequence?
3.3.11 發送sequence和sequence item的優先級問題是什麼?
3.3.12 為什麼sequence通過get_response()可以得到正確的response?
3.3.13通過uvm_config_db::set()或start()掛載sequence有哪些聯繫和差別?
3.3.14 通過uvm_config_db掛載default sequence需要注意什麼?
3.3.15 為什麼不建議使用default_sequence掛載頂層序列呢?
3.3.16 uvm_sequence::start()掛載的sequencer什麼情況下需要指定?
3.3.17 virtual sequence需要獲得某些信號和狀態應該如何實現?
3.3.18 怎麼讓sequence感知coverage的增長並及時停止呢?

3.4 寄存器模型
3.4.1 寄存器模型驗證常見的測試點有哪些?
3.4.2 使用set_auto_predict()和predictor更新寄存器有什麼區別?
3.4.3 如何對寄存器的某些域進行讀/寫操作?
3.4.4 uvm_reg_filed::configure()中的參數volatile的作用是什麼?
3.4.5 uvm_reg的回調函數{pre,post}_{write,read}的用途是什麼?
3.4.6 與uvm_reg_cbs相關的回調函數的用處是什麼?
3.4.7 adapter中的provides_responses屬性的作用是什麼?
3.4.8 多個uvm_reg_block和uvm_reg_map的關係如何影響對寄存器的訪問?
3.4.9 如果並行利用RGM對寄存器做讀/寫可能出現什麼問題?
3.4.10 寄存器模型結構是否支持多個top RGM?
3.4.11 uvm_reg_map的數據位寬如果與總線不同需要做什麼處理?
3.4.12 uvm_reg_map的數據位寬如果與子一級不同需要做什麼處理?
3.4.13 寄存器模型的鏡像值和期望值什麼情況下相等或不相等?
3.4.14 uvm_reg的讀/寫動作在發起後沒有結束的原因可能是什麼?

第4章Testbench疑難點集合
4.1 編譯與導入
4.1.1 package中可以定義什麼類型?
4.1.2 library和package怎麼區分?
4.1.3 文件中出現typedef class X是什麼意思?
4.1.4 `include和import的差別在哪裡?
4.1.5 `include應該在哪裡使用?
4.1.6 應該怎麼理解域(scope)呢?
4.1.7 在系統驗證階段如何避免反复編譯以節省時間?
4.1.8 如何解決和避免類重名或模塊重名的問題?

4.2 驗證組件實現
4.2.1 監測器採樣數據需要注意哪些?
4.2.2 模塊中的信號可以強制賦值和監測嗎?
4.2.3 如何對設計層次中的某個實例進行侵入式賦值?
4.2.4 如何在仿真結束時打印一些測試總結信息?
4.2.5 為什麼有時無法在sequence或test中使用force語句?
4.2.6 為什麼寄存器模型機構應與驗證環境層次保持一致?
4.2.7 為什麼建議執行任務時各組件統一使用run_phase或main_phase?
4.2.8 如何更新driver的驅動行為?
4.2.9 force和$hdl_xmr_force、uvm_hdl_force等命令有什麼差別?

4.3 測試平台控制
4.3.1 如何將覆蓋率數據信息與測試用例關聯?
4.3.2 系統驗證如何實現C用例和UVM用例之間的互動?
4.3.3 系統驗證時測試用例有誤,是否可以避免重新仿真而只做局部修改?
4.3.4 如何在仿真過程中更好地控制驗證環境的結構和行為?
4.3.5 不同目標具備不同timescale是否合適?
4.3.6 能否對其他組件執行的raise objection強行操作drop objection?
4.3.7 如何在回歸測試中減少冗餘的測試用例?
4.3.8 驗證環境遇到reset時如何協調各驗證組件?
4.3.9 仿真出現錯誤信息時如何讓仿真停止?
4.3.10 Verilog如何實現在相同結構中採用不同設計模塊?
4.3.11 仿真器如何實現在相同的結構中採用不同的設計模塊?