代碼覆蓋率
在本節中,我們將介紹各種覆蓋率度量,這些度量與設計模型的隱式實現覆蓋率空間相關聯。通常,這些度量與設計模型的隱式實現覆蓋空間相關的。通常,這些指標被稱為代碼覆蓋率或結構覆蓋率指標。
優點:
代碼覆蓋率的起源可以追溯到20世紀60年代,是最早為系統軟件測試發明的方法之一[1]。代碼覆蓋率的優點之一是,它自動描述程序的源代碼在測試期間被激活的程度,從而識別源代碼中在測試期間未被激活的結構。與功能覆蓋不同,代碼覆蓋的一個關鍵好處是,創建結構覆蓋率模型是一個自動過程。因此,將代碼覆蓋率集成到現有的仿真流中很容易,並且不需要更改當前的設計或驗證方法。
局限:
在我們題為“什么是覆蓋率”的部分中,為實現成功的測試,我們討論了在仿真過程中必須存在的三個重要條件,他們是:
- testbench必須產生合理的輸入激勵以激活設計錯誤。
- testbench必須產生合理的輸入激勵,將設計錯誤產生的所有影響傳播到輸出端口。
- testbench必須包含一個能夠檢測設計錯誤的監視器,該設計錯誤首先被激活,然后傳遞到一個檢測點。
代碼覆蓋率是對源代碼中在仿真過程中激活的結構的度量。代碼覆蓋率指標的一個限制是,你可能在回歸運行期間實現100%的代碼覆蓋率,這意味着你的testbench提供了激活RTL源代碼中所有結構的激勵,但你的設計中仍然存在缺陷。例如,輸入激勵可能激活了一行包含錯誤的代碼,但testbench沒有生成額外所需的刺激,而這些激勵將bug的影響傳播到testbench中可以檢測到的某個點。事實上,研究人員已經研究了這個問題,並發現如果testbench實現了90%的代碼覆蓋率,那么在模擬運行期間,只有54%的代碼被覆蓋[2]。這意味着一個bug可能存在於一行被標記為已覆蓋的代碼上,但由於沒有足夠的輸入激勵將bug傳播到一個可觀察點,該bug從未被檢測到。
代碼覆蓋范圍的另一個限制是,它沒有提供關於規范書中定義的功能實際被測試的確切指示。例如,你可能會遇到這樣一種情況:你實現了100%的代碼覆蓋率,然后假設您完成了。然而,規范書中定義的功能可能從未經過測試,甚至這些功能可能從未實現過!代碼覆蓋率指標不會幫助您發現這些情況。
即使有這些限制,代碼覆蓋的自動方面使它成為testbench上識別輸入刺激缺陷的相對簡單的方法。在你開始推進高級驗證步驟性能時,它是覆蓋率指標的最佳首選。
代碼覆蓋率指標的類型
翻轉覆蓋率
翻轉覆蓋率是一種代碼覆蓋率指標,用於測量寄存器或導線的每一位翻轉其值的次數。盡管這是一個相對基本的指標,但許多項目都有一個測試要求,即所有端口和寄存器至少必須經歷過0到1和1到0的轉換。
總的來說,如果不仔細關注,檢查一個翻轉覆蓋率分析報告可能會讓人不知所措,也沒有什么價值。例如,翻轉覆蓋通常用於IP塊之間的基本連接檢查。此外,了解許多控制結構(如獨熱碼選擇總線)已完全執行也是有用的。
行覆蓋率
行覆蓋率是一種代碼覆蓋率指標,我們用來確定在仿真期間執行了源代碼的哪些行。行覆蓋率度量報告將有一個與每行源代碼關聯的計數,指示該行已執行的總次數。行執行的計數值不僅可用於識別從未執行過的源代碼行,而且在工程師認為需要最低行執行閾值以實現充分測試時也很有用。
行覆蓋率分析通常表示一個罕見的情形被要求,以激活由於缺少輸入刺激而導致的代碼行未被覆蓋。或者,行覆蓋率分析可能會發現,源代碼的數據和控制流阻止了它,這要么是因為代碼中存在錯誤,要么是因為在某些IP配置下目前不需要死代碼。對於未使用或死代碼,你可以選擇在覆蓋率記錄和報告步驟中排除或過濾此代碼,這允許您只關注相關代碼。
語句覆蓋率
語句覆蓋率是一種代碼覆蓋率指標,我們使用它來識別源代碼中的哪些語句在仿真過程中被執行了。一般來說,大多數工程師發現,語句覆蓋率分析比行覆蓋率更有用,因為一條語句通常跨越多行源代碼,或者一行源代碼上可能出現多條語句。
用於語句覆蓋率分析的度量報告將有一個與每行源代碼關聯的計數,該計數指示語句執行的總次數。該語句執行計數不僅可用於識別從未執行過的源代碼行,而且在工程師認為需要達到最低語句執行閾值以實現充分測試時也很有用。
塊覆蓋率
塊覆蓋率是語句覆蓋率度量的一個變體,用於標識代碼塊是否已被執行。塊被定義為條件語句之間或過程定義內的一組語句,關鍵點是,如果到達該塊,將執行該塊內的所有行。該指標用於避免肆無忌憚的工程師通過簡單地向代碼中添加更多的語句來實現更高的語句覆蓋率。
分支覆蓋率
分支覆蓋率(也稱為決策覆蓋率)是一種代碼覆蓋率度量,它報告在控制結構(例如if、case、while、repeat、forever、for和loop語句)中測試的布爾表達式的計算結果是否被同時計算為true和false。整個布爾表達式被視為一個true或false的斷言,無論它是否包含邏輯and或邏輯or運算符。
表達式覆蓋率
表達式覆蓋率(有時稱為條件覆蓋率)是一種代碼覆蓋率度量,用於確定每個條件的計算結果是否同時為true和false。條件是不包含邏輯運算符的布爾操作數。因此,表達式覆蓋率可以獨立地度量布爾條件。
聚焦表達式覆蓋率
聚焦表達式覆蓋率(FEC),也被稱為修改條件/決策覆蓋(MC/DC),是DO-178B安全關鍵軟件認證標准以及DO-254正式機載電子硬件認證標准經常使用的代碼覆蓋率指標。這一指標比條件和決策覆蓋率更強。DO-178B對MC/DC的正式定義如下:
程序中的每個入口和出口點都至少被調用過一次,決策中的每個條件都至少產生過一次所有可能的結果,程序中的每個決策都至少產生過一次所有可能的結果,並且決策中的每個條件都被證明會獨立地影響決策結果。一個條件被證明是獨立地影響決策結果,是通過它只改變該條件,同時保持所有其他可能的條件不變[3]。
值得一提的是,完全封閉式的聚焦表達式覆蓋率非同小可。
有限狀態機覆蓋率
今天的代碼覆蓋率工具能夠識別RTL源代碼中的有限狀態機。因此,這使得自動提取有限狀態機代碼覆蓋率指標來度量條件成為可能。例如,狀態機的每個狀態進入的次數,狀態機從一個狀態轉換到每個相鄰狀態的次數,甚至是順序arc覆蓋率,以識別狀態訪問轉換。
典型的代碼覆蓋率流程
收集和分析代碼覆蓋率指標的目的是識別當前驗證環境尚未執行的部分源代碼。從項目的角度來看,通常最好等到RTL的實現接近完成,然后才開始認真收集和分析代碼覆蓋率結果。否則,您可能會浪費大量的周期時間,試圖從不斷變化的RTL代碼中理解移動的目標。話雖如此,我們建議您至少在項目周期的早期(即在認真收集覆蓋指標之前)運行一些捕獲覆蓋指標的仿真,以解決覆蓋流程中的任何潛在問題。
從高層次的角度來看,代碼覆蓋流程通常涉及三個主要步驟,包括:
- 檢測RTL代碼以收集覆蓋率范圍
- 運行仿真以捕獲和記錄覆蓋率指標
- 報告並分析覆蓋率結果
分析步驟的一部分是識別覆蓋盲區,並確定覆蓋盲區是否由以下三種情況之一造成:
- 缺少激活未覆蓋代碼所需的輸入激勵
- 設計(或testbench)中的一個缺陷,它阻止輸入激勵激活未覆蓋的代碼
- 某些IP配置未使用的代碼或正常運行條件下預期無法訪問的相關代碼
第一個條件要求你要么編寫額外的定向激勵,要么調整隨機約束,以生成針對未覆蓋代碼的所需輸入激勵。第二個條件顯然要求工程師修復阻止執行未覆蓋代碼的錯誤。第三個條件可以通過設置覆蓋率工具在覆蓋率記錄和報告步驟中排除未使用的或不可達的代碼來解決。正規的工具可以用來自動識別不可到達的代碼,然后自動生成排除文件。