寫入和讀取寄存器是控制和查詢大多數IP行為的主要方式。由于基本寄存器對設計的正確操作有直接影響,因此,寄存器測試是設計驗證和啟動時看似簡單但很重要的一環。在IP級別,必須驗證寄存器的正確實現——可以從IP塊上的接口訪問它們。在子系統級,驗證對寄存器的訪問有助于確認已根據規范實現了互連網絡和地址解碼。在SoC級別,驗證對寄存器的訪問可以確認處理器字節順序與互連實現是否匹配,并且引導代碼正確配置存儲器管理單元(MMU),使得IP寄存器對處理器可見。
在本文中,我們將探討通過Portable Stimulus Standard(PSS)的portable stimulus,如何利用寄存器模型中捕獲的信息來自動創建塊、子系統和SoC寄存器訪問測試。
UVM(Universal Verification Methodology,通用驗證方法學)提供了一個寄存器模型,用于對寄存器空間進行建模 - 可用的寄存器、字段及其屬性,如地址、可訪問性和復位值。UVM庫還提供內置的定向序列,它們遍歷UVM寄存器模型并檢查寄存器的復位值,并通過修改和檢查所有讀/寫寄存器字段來確認寄存器是否可訪問。這些內置測試在IP級別非常有用,可以確認單個IP塊內的寄存器是否已正確實現。
然而,嘗試在子系統級重用這些測試序列變得很困難,因為子系統中存在寄存器的數量以及內置UVM序列是期望測試設計中的每個寄存器的定向序列的情況。嘗試在SoC級別重用這些內置測試序列也很困難,因為內置序列是在SystemVerilog中實現的自檢序列。為了在SoC的嵌入式處理器上運行,我們需要使用裸機C或匯編語言。
通過使用portable stimulus對測試意圖進行建模,我們可以靈活地將測試空間劃分為多個較小的測試單元。我們還可以通過在C或匯編語言中創建嵌入式軟件測試來獲得針對SoC級別測試的靈活性。
portable stimulus可將測試中的兩個元素分開,這兩個元素通常在定向測試中合并。測試意圖是測試內容的高級設計,測試實現是執行該測試的機制。
在測試寄存器模型的情況下,我們的測試意圖類似于以下內容:
從寄存器塊中選擇一個寄存器
從寄存器中選擇讀/寫字段
在該字段中選擇一個要測試的位
上述測試意圖與我們是否驗證塊、子系統或SoC級設計無關。它也與SystemVerilog環境還是嵌入式軟件環境無關。

暫時忽略適當的約束,我們測試單個寄存器的測試意圖由上面的PSS代碼捕獲:
有一個reg_id字段來捕獲我們正在測試的寄存器
有一個flip_bit字段來捕獲我們希望測試的寄存器中的哪個位
有一個reg_addr字段來捕獲內存映射中字段的地址
現在,如果沒有將此測試意圖連接到特定測試環境的測試實現,我們的測試意圖就毫無價值。理想情況下,可以考慮用portable stimulus來設計我們的測試實現。這樣做可以讓我們設計一個可在所有環境中使用的通用API。例如,可以指定名為testbit的方法在所有環境中都可用,并且此方法將測試修改指定位的能力。這種功能的功能原型如下所示。

在SystemVerilog IP或子系統級環境中,我們可以將此方法實現為UVM序列中的任務。下面顯示的SystemVerilog任務使用內存訪問API來讀寫內存,并通過以下方式實現寄存器位測試操作:
讀取寄存器的當前值
取消寄存器的目標位,并寫入新的寄存器值
讀回寄存器地址,并檢查該位是否保留其值

在上面顯示的示例中,如果遇到錯誤,可以繼續運行,這是UVM測試的典型特征。但是,嵌入式軟件環境具有不同的約束。

上面的示例顯示了嵌入式處理器的testbit函數的可能實現。如您所見,該方法與SystemVerilog版本非常相似,但具體情況不同。最大的區別是:在這種情況下,假設如果寄存器位測試失敗,我們將結束整個測試。
分離測試意圖和測試實現是portable stimulus的核心要素,并且是使測試意圖在各種環境中輕松重新定位的關鍵。
我們已經研究了使用PSS捕獲測試意圖和測試實現,以進行寄存器測試的方法,下面簡單地看看我們的UVM寄存器模型是如何形成的。出于本示例的目的,看一下圖1中非常簡單的子系統,該子系統有一個處理器、兩個以太網控制器和兩個DMA引擎。

在塊級別驗證以太網和DMA控制器時,為其創建了UVM寄存器模型。這些UVM寄存器模型可以手工創建,但更有可能是使用寄存器創建工具創建的,如圖2所示。

寄存器創建工具接受各種標準(IP-XACT,SystemRDL)和非標準(例如,CSV)格式的寄存器規范,并可生成該寄存器規范的各種視圖。生成寄存器模型的RTL實現可節省設計實現的時間,生成UVM寄存器模型可縮短啟動測試平臺的時間。在所有情況下,確保一切都與高級寄存器規范保持一致可以節省大量時間。
當達到子系統級別時,寄存器創建工具可以幫助我們為整個子系統組裝寄存器模型?;蛘撸覀兛梢院唵蔚夭捎脝为毜膲K級寄存器模型并組裝子系統級寄存器模型。下面的代碼匯集了以太網和DMA控制器寄存器模型中的子系統級寄存器模型。如您所見,不需要太多代碼。


設計中可用的寄存器及其地址
這些寄存器中的字段和任何訪問限制
令人驚訝的是寄存器的數量累積的速度很快,當我們為兩個以太網控制器和兩個DMA控制器創建寄存器模型時,有989個帶可測試字段的寄存器。試想一下完整的SoC包含多少寄存器!
現在我們已經捕獲了子系統或SoC級寄存器模型,如何繼續創建寄存器訪問測試呢?首先,需要創建寄存器訪問測試意圖的PSS模型。然后,我們需要將測試意圖連接到具有測試實現的特定驗證環境。
以前,我們查看了寄存器訪問測試的核心測試意圖:選擇一個寄存器,并在該寄存器中進行測試。當然,這種高級測試意圖必須基于正在測試的設計中的寄存器來約束。好消息是我們已經捕獲了在寄存器模型中生成這些約束所需的所有信息。
在某些情況下,我們的寄存器創建工具可能能夠直接創建PSS寄存器測試作為其輸出之一。如果沒有,那么自動創建測試意圖的一種方法是:運行SystemVerilog代碼,該代碼遍歷UVM寄存器模型并寫出我們的PSS寄存器測試意圖。下面的代碼顯示了一個UVM測試,它調用名為regmodel2pss的類來創建PSS測試意圖。

其結果是形成了一個portable stimulus描述,即捕獲我們的子系統寄存器映射的寄存器測試意圖。下面顯示的代碼是PSS組件的第一部分和為測試寄存器模型而創建的操作。

我們的操作(其名稱來自寄存器塊名稱)聲明了三個rand字段:reg_id字段包含目標寄存器的ID,范圍介于0和寄存器數減1之間;flip_bit字段指定要測試的寄存器位,該字段以及寄存器地址將根據寄存器ID進行約束。
上面自動創建的約束將確保我們的操作根據被測試的寄存器產生有效的寄存器地址和flip_bit。

除了自動創建約束外,還可以自動創建PSS覆蓋模型,以確保已覆蓋寄存器中的所有寄存器和所有位。
一旦擁有核心寄存器測試意圖,我們需要將其集成到頂級PSS場景中。雖然核心寄存器測試意圖是從寄存器模型自動派生的,但我們的頂級寄存器測試場景卻是手工創建的。

上圖顯示了測試場景,它構建在編碼測試意圖的核心操作之上。根據PSS的要求,測試場景封裝在頂層組件中。我們在頂級組件中創建了一個register-test組件(subsys_reg_block_c)的實例,因為我們將使用該組件中的操作。在頂級操作(my_subsys_regtest_a)中,創建了一個名為testbit的subsys_reg_block_regs_a操作實例,此操作內部是register-test字段和covergroup的實例。在頂級操作中,運行100次testbit,這意味著每次測試運行時,將測試100個寄存器位。
頂級測試場景實際上并沒有做任何事情,因為缺少測試實現。幸運的是,PSS允許我們輕松地在測試實現中進行分層,而無需更改核心描述 - 在本例中為subsys_reg_block_regs_a操作。

上圖顯示了利用PSS程序接口的SystemVerilog測試實現描述。聲明外部函數的簽名,并從操作的exec塊調用該函數。這種測試實現方式適用于所有支持可調用過程的環境,如C,C ++,SystemVerilog等。
在多數情況下,對SoC的裸機嵌入式軟件測試將用C語言編寫。但是,如果需要創建匯編語言測試呢?幸運的是,PSS也提供了相應的方法!

在上面討論的測試實現中,我們使用PSS 目標模板 exec塊來指定必須生成的匯編代碼片段(在這種情況下為RISC-V)以測試寄存器位。大括號(例如,{{reg_addr}})用于引用PSS模型中字段的當前值,并將該值替換為生成的代碼。用匯編語言進行測試實現肯定有它的局限性,但是當需要特定技術時,PSS就有可能實現。
既然有測試意圖和測試實現來測試對寄存器的訪問,我們就可以開始運行測試了。在UVM環境中,PSS為我們提供了預生成定向測試或運行PSS求解器引擎,以及模擬的靈活性。這兩種方法都有其優點和缺點。一方面,定向測試很容易理解。

例如,上面的UVM序列非常容易理解,并且總是完全相同。但是,我們希望測試能夠在運行不同的“種子”時略微不同。而且,我們希望能夠在回歸中運行的不同模擬中輕松劃分成千上萬的寄存器測試。這就是使用與模擬一起運行的PSS求解器引擎真正有用的地方。使用不同種子運行相同的序列會導致不同的行為,而像Questa?inFact這樣的PSS工具提供了專用功能,可以在回歸中運行的模擬中動態分區測試。

如果能夠在裸機軟件環境中使用C,我們就可以使用testbit函數實現和PSS程序接口來生成C測試代碼,如上所示。

但是,如果需要使用程序集,我們可以使用target-template exec塊測試實現來生成完全獨立的測試。該測試的片段測試了兩個寄存器/位組合。
寄存器測試是從IP到子系統,再到SoC級別的所有環境中非常有用的“煙霧”測試。雖然UVM庫中的內置寄存器測試序列主要用于IP級別,但在PSS模型中捕獲寄存器測試意圖使得寄存器測試功能可從IP移植到SoC級別,并且在控制哪些寄存器方面提供更大的靈活性。
寄存器生成工具的輸入文件和生成的UVM寄存器模型都包含足夠的信息來自動創建portable stimulus測試意圖。這使得寄存器生成工具很容易添加對portable stimulus測試的支持。它還可以很容易地從現有UVM寄存器模型中獲取portable stimulus測試,無論它們是如何創建的。
因此,portable stimulus不僅適用于最難的測試,它還可以像看似簡單的測試任務一樣輕松高效地應用,例如注冊訪問測試,它可以提供可移植性,從而減少重復工作。
學習園地