戴 程 李 濤 何星宏
(西安郵電大學電子工程學院 西安 710121)
計算單元是現代計算機發揮強大能力的一個重要基石[1],其可靠性驗證也因此變得十分重要。自從20世紀80年代浮點標準IEEE754[2]提出以來,由浮點格式定義在運算中帶來的復雜邊界情況驗證始終是一項復雜的挑戰[3]。相對簡單的整數運算也同樣伴隨著多種異常情況。本文正是針對這一需求,將浮點整數混合單元作為具體驗證對象,提出一種可靠的驗證方案。
面對當前復雜設計的驗證需求,業界廣泛而又成熟的應對策略是搭建驗證平臺,而本文在基本原型[4]的基礎之上借鑒了Crossgroup(交叉覆蓋組)[4]的思路,將計算任務根據數據類型、運算類型、取值區間、異常數據操作等屬性進行分割,對應每個分割塊建立完整的驗證通道,然后以塊為基本單位在上層進行合適的單項或者組合驗證。這樣在面對具體應用中的差異化設計時,可以靈活的選取調整其中的塊以及添加新的塊。最終形成底層固化若干基本塊及其變化版本,上層直接調用底層基本塊或者由基本快組成的高級塊的形式,這種過程類似于軟件應用程序庫中函數使用的方法。
該設計支持單精度(1.8.23)、單精度擴展精度(1.8.32)、整數3種數據類型。浮點運算支持乘加、乘、加、比較運算,執行一次需要3個時鐘;整數運算支持乘加、乘、加、比較、移位運算,執行一次需要2個時鐘。其整體結構如圖1所示。
整個設計從上至下依次分為3級:第1級完成浮點運算階碼的對階,乘加運算中乘運算全部和加運算一部分;第2級完成剩余部分的加運算以及前導0計算;第3級完成規格化、舍入以及格式化輸出。
設計的核心處理通道實現的是浮點乘加運算(A*B+C),其余運算都是嵌入到主通道之中,共用主通道中的計算資源完成運算,沿著主通道進行數據流動直至產生最終結果。
本論文采用SystemVerilog語言來設計驗證平臺[8],整體驗證結構如圖2所示。

圖2 驗證平臺結構框圖
首先由Driver產生激勵同時傳遞給Reference Model、DUV以及Monitor,其內部可以通過選擇以及控制不同的激勵約束文件(Packet)來對應不同的驗證場景,也就是引言所提到的實現不同的基本塊以及高級塊的思想,同時在Environment配置環境時也有不同的Driver可供選擇,本文實現了3個Driver分別對應3種數據類型。
其次DUV是待驗證的設計,ReferenceModel是用SystemVerilog語言設計的參考模型[9],兩者接收并執行完全相同的激勵,然后輸出結果給Scoreboard;而Monitor用于保留激勵以及ReferenceModel中的關鍵信息,供Scoreboard在結果比較時使用。
再次由Scoreboard接收并綜合這些信息完成結果的比較判定,同時輸出驗證報告,其內容可分為兩部分:本次驗證測試激勵以及執行結果等的統計信息;執行結果或者平臺運行出錯時刻保留的相關信息。
最后在Environment中完成整個環境的配置,保證每種測試塊都擁有一條完整獨立的驗證通道,但是除了必要的獨立部分,其余部分是共用的,這樣可以優化平臺的整體設計。在程序塊Testcase中會完成驗證平臺與DUV的連接以及整個平臺啟動/終止的控制。
若將某個設計所有可能的激勵看做一個激勵空間,在大多數情況下如果想要遍歷這個激勵空間是需要付出難以承受的計算代價以及時間代價,對于運算類設計尤其如此。因此比較切實可行的解決方案是通過約束選取整個激勵空間的一個子空間來表征整個激勵空間,當子空間隨機覆蓋充分時便可以較為充分的認為DUV功能驗證通過。但是這樣并不完備,理由有兩點:一個是選取的子空間畢竟是部分,可能會忽略一些導致問題的激勵;另一個是子空間中隨機化生成激勵的方式通常會出現個別激勵很難覆蓋到的情況,從而引出定向測試來作為必要的補充手段。
定向測試核心在于定向激勵,本文的定向激勵分為浮點、整數兩部分。浮點激勵一部分來自IBM實驗室開發的浮點定向測試包[10],它們擁有特定的格式(見表1),包含操作數與驗證過的結果,通過Python腳本將其轉化為DUV所識別的激勵格式后作為整個平臺初始的校準測試;另一部分是補充激勵,作為隨機測試的補充。整數激勵組成可以類比浮點激勵,只是其校準測試所用激勵是通過人為挑選若干邊界與常規情況產生。

表1 激勵格式解讀(按位置對應)
此外本文還擴展定向激勵部分實現了仿真問題的自動化[11]重現。當執行結果出錯時通過腳本從驗證報告中將錯誤時刻相關信息以及相關數據提取,然后作為新的激勵重新運行仿真來重現目標問題。整個過程自動化進行,極大地方便了問題的仿真調試。
隨機測試是整個測試的核心,在通過約束選取子空間之后,便按照引言所述思路根據數據類型、運算類型、取值區間、異常數據操作等屬性將子空間分割成基本塊、高級塊的形式,每一塊都進行基于功能覆蓋率[13]統計的獨立隨機測試,同時通過定向測試的補充測試加以配合。所有塊都擁有相同的隨機測試流程,具體描述如下。
第一,從激勵約束文件Packet內部約束描述,Packet的選取、多個Packet的控制,Driver的選取等多方面進行靈活配合來產生預期的激勵。
第二,通過使用不同的隨機種子來賦予激勵更強的隨機性。
第三,運行仿真,調試解決錯誤的情況。
第四,進行功能覆蓋率檢查[14]。該項的核心是設計了一系列Covergroup,采集輸入、輸出、部分功能類以及部分設計模塊中的內部關鍵信息,然后通過自動、手動建倉以及交叉倉等方式實現對功能覆蓋率的量化分析,對于隨機化中難以覆蓋的倉將轉到定向測試環節進行補充測試。
第五,根據覆蓋率分析反饋,從激勵約束、隨機種子、Covergroup等多方面進行調整,逐漸實現對子空間的全覆蓋。
第六,按照以上4步反復迭代,直至在Covergroup較為充分的情況下功能覆蓋率達到100%,結束隨機測試。
整個測試分為6項,分別對應3種數據類型的定向與隨機兩類測試。其中隨機測試按照上文提到的多種因素分為不同的測試塊[15]進行測試;定向測試完平臺校準測試、問題重現以及補充測試。具體測試分類及規模如表2所示

表2 測試項目及規模統計
經過不斷調試修正,完成所有測試項目。現摘錄其中單精度運算的測試結果如圖3、圖4所示。

圖3 單精度定向測試報告

圖4 單精度隨機測試報告
本文綜合利用多種測試方法來完成目標設計的功能驗證任務,在此過程中驗證了以劃分基本塊與高級塊的方式將整個驗證任務進行分割并各自驗證的思路。也證明了該思路在應對復雜多樣的運算類設計驗證任務的可行性。
接下的工作中會通過進一步分析不同的運算設計,構建更為豐富的基本塊與高級塊,尋找更為合理的塊間組合方式來應對不同的運算類設計,從而進一步完善和驗證這一驗證思路的有效性。