過去一兩年,可攜式激勵(Portable Stimulus)已成為驗證社群的熱門話題,但是,與大部份的「新」概念一樣,它是從已經發展成熟的工具與方法學演進而來的。

例如,多年來,利用像Questa inFact這類繪圖式激勵自動化工具,使得不同抽象層級具有共通的激勵模型。高階合成(HLS),亦即把SystemC/C++合成至暫存器傳輸級(RTL),已成熟運用多年,大部份使用者都能混合利用自行開發的環境或C語言測試來執行C層級的功能驗證。雖然HLS現在能夠支援非常大型的階層式設計,但是,市場日益需要一套驗證方法學,能夠為SystemC/C++提供高效能且可實際應用的約束性隨機激勵,以便能在C層級達成覆蓋率收斂,然後再重新複製相同的激勵,以測試並通過合成的RTL。

本文將闡述一套方法學,其中,激勵模型能夠被定義(以及修正),以達成C++ HLS DUT的100%程式碼覆蓋,然後再重新使用於合成RTL的SystemVerilog或UVM測試台。針對真正共通的模型,還可能在兩個環境中保持隨機穩定性,因此在其中一個環境中發現的問題,可以在另一個環境中進行除錯。

簡介

十年前,電子系統級(ESL)設計方法學曾風行一時,有許多的語言選項宣稱可同時提升設計與驗證的抽象層級,例如C/C++、SystemC和SystemVerilog。雖然C/SystemC是擷取硬體與系統建模最常用的語言,但SystemVerilog已使先進驗證所需的特性標準化,像是約束隨機激勵與功能驗證覆蓋。

同時,許多使用者一直在尋找更有效率的方式來描述激勵,特別是能夠從精簡描述自動化擴展成涵蓋各種驗證情境(scenario)的方式,並提升此產生過程的效率。

Questa inFact提供了這樣的功能,利用規則/圖形式方法,並使用軟體測試的技巧及增強硬體驗證的功能。由於規則式模型獨立於特定語言(它可應用於至少七種不同的HVL環境),它一直是一套可攜式激勵解決方案。

HLS使用者通常認為,移轉至C++/SystemC設計方式的主要效益在於驗證效能,從而使其執行更多測試。然而,可為先進驗證功能提供SystemVerilog的C環境並沒有一定的標準,例如隨機/自動化激勵建模等。可攜式激勵解決方案能提供此強大功能,除了保有為C-based模擬環境建立激勵模型的優勢之外,還能在RTL包含於SystemVerilog中時再予以利用,反之亦然。

常見的激勵模型

規則式激勵模型,如預期地是從主要的頂層規則檔案中逐層建立。此檔案通常與預設樣板、以及一個或更多的模組級規則片段檔案差異不大。頂層規則檔案宣告主要的rule_graph,為圖形模型命名,並依照所選的程式碼架構,而且僅需要包含匯入定義此激勵細節的必備規則片段檔案。

圖1的範例顯示了四個不同的檔案,其中兩個——test_data_C.rulestest_data_SV.rules,均定義了稱為test_data_gen的圖形物件。這兩種頂層規則檔案對應至圖形元件,是實際激勵模型的特定語言包裝介面(wrapper)。也就是說,inFact自動產生器將分別建立稱為test_data_C的C++類別(class),以及稱為test_data_SV的SV類別,二者將定義規則圖形模型test_data_gen。

20180223_Mentor_TA31P1 圖1:階層式規則程式碼架構

這兩個頂層規則檔案會匯入規則片段檔案的共同階層,以明確地定義其行為。透過把所有規則階層的定義放在共同檔案中,編譯過的圖形模型就會有完全一致的行為。

test_data_C.規則檔案還有一個額外的建構,它的屬性在於為程式碼產生特定的語言需求。在此範例中,它指定了要在聲明中加入的所需程式碼,以便能產生C++類別定義檔案。該語言支援能被用來客製化產生HVL檔案的其他屬性,而不會對底層的圖形模型帶來影響。

test_data_gen.rseg檔案定義了圖形可產生的情境規則,在此範例中,只是簡單地迴圈至test_data物件的內容隨機化,如圖2所示。

20180223_Mentor_TA31P2 圖2:test_data_gen規則圖形

註:情境規則可包含多個物件,可以是相同物件型態或是多個不同型態的用例,以及其他的圖形拓樸建構。

test_data物件本身,在inFact規則語言中被宣告為struct,可在個別的規則片段檔案中加以定義,以達成模組化與重複使用的目的。struct有額外的階層,定義了稱為packedArray0和packedArray1的其他struct,從而反映C++測試台中待測物(DUT)激勵所定義與使用的C++ struct。

這是此方法學的另一個重要關鍵,亦即,擁有相同名稱與階層的規則圖形參考物件,以及使用的資料型態,能被映射至相對應的C++和SV型態。由於inFact語言允許所有的變數都能定義位元寬度,因此可讓我們鎖定Mentor演算法的位元準確(bit-accurate)資料型態以及SystemC資料型態。

在此例中,測試資料物件的格式是從C++測試台取得的,它基於建置了一個可配置乘法累加功能的C模型。因此,建立此方法學的第一個步驟是決定哪一個DUT輸入會透過圖形模型及其位元寬度加以隨機化,以及收集這些訊息到測試資料struct或類別中。在此範例,packedArray0包含10位元數值的8單元固定大小陣列,packedArray1包含7位元數值的類似陣列。在這些資料中增加的是一個稱為num_col的4位元數量。用於這些struct的資料型態是利用Mentor AlgorithmicC位元準確資料型態來定義,可讓設計以任意的精密度來建模。

雖然這是從C++測試台開始,還需要在SystemVerilog環境中有類似的物件。圖3所示為此物件的SystemVerilog和C++版本。

20180223_Mentor_TA31P3 圖3:SystemVerilog和C++的測試資料型態

就像inFact模型一樣,SystemVerilog模型包含一般代數的約束條件,而且還能利用傳統的SystemVerilog .randomize()呼叫程式進行隨機化。如果inFact圖形一定要執行隨機化,這就不需要了。

註:在此簡單範例中的唯一限制是把num_col的數值設定在1到8之間,但inFact語言支援所有SystemVerilog中常用的限制運算元,只有微小的語法差別。另一個好處是,對於熟悉SystemVerilog語法的工程師來說,有現成的公用程式可用來建立或更新來自SystemVerilog的inFact圖形模型。

在C測試台中執行

一旦測試資料物件定義好了,要把可攜式激勵模型整合到C測試台就很簡單了。如上所述,C++類別是從共同的規則模型自動建立的,此類別有一個內建方法,對應至規則語言中定義的interfacetest_data_gen.rseg檔案宣告此介面稱為fill,它能在test_data型態的任何用例上運作。這可在稱為ifc_fill的HVL物件中產生一個方法、任務或功能,簡單前置於ifc

此方法、任務或功能會採用一個參數,處理對應至相同名稱的HVL物件——亦即test_data類別或之前所示的struct。

因此,此整合機制只是很簡單地建構一個包含可攜式激勵模型的類別用例,然後呼叫其ifc_fill方法到測試台test_data容器(container)。圖4為C++測試台的摘錄程式碼,其中建立了到test_data struct¬¬——td_h以及到包含inFact模型——td_gen_h的類型,後者的建構呼叫程式定義了用例名稱,以供inFact內部使用。此inFact用例名稱很重要,我們稍後會討論。

20180223_Mentor_TA31P4 圖4:C++測試台的程式碼片段

在C++測試迴圈中,能看到ifc_fill方法的呼叫程式,接下來是把td_h struct用例的內容指定給本地的變數——這些變數會被用在C函數,亦即此平台中的DUT。

此架構與利用SystemVerilog隨機類型或序列項目和.randomize(),或SystemC/SCV類別方法相比,差異並不大。唯一的不同在於執行隨機化的模型是inFact圖形模型。

在此階段,inFact可攜式激勵模型帶來的價值在於它可隨機化多個數值,而且還能遵循這些數值定義的約束條件或它們的關係。

考慮覆蓋率

inFact模型的附加價值是,在激勵模型上的其他輸入類型能夠被強制取代,這稱為覆蓋率策略(coverage strategy)。此策略與SystemVerilog covergroup非常類似,它定義了使用者感興趣的變數,這些數值所需的bin,以及這些變數間的相互關係(cross)。差別在於,隨機化過程的輸入改變了隨機分佈,能夠有效地覆蓋此策略的目標。

在此範例中,衡量的覆蓋率指標並不是功能覆蓋率的覆蓋點/交叉,而是程式碼覆蓋率,這在C/C++環境中更為常見(雖然功能覆蓋率也可被導入)。顧名思義,覆蓋策略中定義的目標應該是預期策略能達到較高的程式碼覆蓋,或是將重心放在其他策略中未涵蓋的範圍。

由於此範例中的DUT——乘法器——非常簡單,因此簡單的策略便已足夠。inFact工具組包含多個公用程式,能從各種輸入建立覆蓋率策略,包括預先定義型態的自動化策略、利用CSV檔案或試算表的自訂策略,以及圖形編輯器。在此範例中,能利用自動化策略,分別針對每個獨立的激勵變數,亦即彼此間沒有交叉。對於test_data階層(包含每個陣列單元)中的每個變數來說,公用程式可確定所有的合法數值,採用約束分析,並將它們分開至定義好的bin。此範例共指定了128個bin,這意味著,陣列中每個7位元單元的所有coeff數值都會被覆蓋。若需要,遠端的edge-bins(範圍中最高與最低的個別數值)能被相加,而在此範例中,更大的數量——10位元資料數值——在兩個極值的每端都會建立兩個單一數值的bin。

如同預期,在完成執行自動化策略後,可取得非常好的程式碼覆蓋率結果——達到100%(原來的單純隨機測試方法結果約低20%),如圖5所示。

20180223_Mentor_TA31P5 圖5:程式碼覆蓋結果

註:能夠使C++來源達到100%的程式碼覆蓋率是很重要的,才能為利用相同激勵從HLS合成的RTL輕鬆實現覆蓋率收斂。這是因為除錯C++覆蓋率問題,比從HLS除錯RTL輸出更簡單。

可攜式激勵具備隨機穩定性

雖然取得高的程式碼覆蓋率很好,但本文重點在於說明,激勵模型以及一或更多的相關覆蓋率策略如何在一個環境中被建立,然後重覆用於另一個環境中。inFact激勵模型的種子(seed)能被使用者所定義,或僅簡單地從原始執行輸出至一個檔案。

此包含SystemVerilog版本的模型能被用於SV測試台中,以便能以C版本相同的方式來驅動RTL DUT,亦即簡單地用例化包含它的SV類別物件,然後再利用它的內建任務——ifc_fill,隨機化SystemVerilog test_data別的內容,如圖6所示。

20180223_Mentor_TA31P6 圖6:SystemVerilog測試台程式碼摘錄

在此範例,用於test_data類別的封包陣列需要被重新改變格式,才能符合寬reg物件,在此範例中是DUT輸入,但這很簡單,只需利用串連運算子——{arrEl[0], ... , arrEl[N]},便可達成。

在此範例中,覆蓋率的狀態能透過策略中的內建功能——allCoverageGoalsHaveBeenMet()查詢,並將其作為一個修飾詞,為測試產生新的輸入或定義迴圈的退出條件。

當執行SystemVerilog測試台時,RTL DUT產生的程式碼覆蓋也很高,若一直執行到覆蓋策略完成,此範例為97.11%,如圖7所示。

20180223_Mentor_TA31P7 圖7:RTL程式碼覆蓋結果

雖然此範例很簡單,但它顯示了Questa inFact工具套件中提供的共同可攜式激勵模型之重複使用性。當然,對於DUT的RTL版本來說,還可能需要其他的測試,才能處理合成後RTL的行為。這是因為HLS過程中增加了不存在於untimed C++的結構,像是介面協定、控制FSM以及時脈和重設邏輯。然而,藉由利用inFact可攜式激勵模型,可在C++實現100%的覆蓋率收斂。我們可以確保,當執行RTL驗證時,可得到設計功能的相同覆蓋率。這只是簡單地增加額外的測試,以覆蓋HLS增加的部份。

建立更複雜的場景

任何以規則為基準的模型數量都能以此方式來建立,並運用在另一個環境中。例如,建立新的情境可以透過增加新的部份規則來產生兩個測試資料物件的用例——td1td2,並在系列規則中的相同fill介面使用它們。這能建立覆蓋率策略,以達成test_data中某個欄位的過渡覆蓋率,如num_col變數。圖8所示為此新的規則圖形,以及在td1td2num_col變數的選用,以作為交叉覆蓋的目標欄位。

20180223_Mentor_TA31P8 圖8:具備兩個測試資料用例的情境

此方法學的另一個優點是,C和SystemVerilog測試台不需要改變,因為它們能繼續呼叫ifc_fill方法/任務,毋須知道在激勵模型中每個隨機化是不同的物件。

另一個可能性是建立不同的test_data特殊化物件,透過給予每個用例額外的約束條件,強制讓此情境中的特殊序列必須遵循。再次強調,只要每個用例採用相同的介面,便不需要修改測試台。

總結

可攜式激勵解決方案有助於把先進的驗證功能帶到基於C的高階驗證環境中,並在不同抽象層級的激勵模型與覆蓋資訊中重覆使用。

這對高階合成使用者特別有幫助,因為他們對C語言設計更為熟悉,如果透過種子式隨機穩定性,建立的激勵可在兩個環境中相互對映,他們便會發現在此層級來開發完整的激勵模型會更簡單。對於HLS使用者,可攜式激勵能為他們提供基於標準的方法學,以便能快速、可預測地完成從C到RTL的覆蓋率收斂。