在現代IC設計流程中,當設計人員根據設計規格說明書完成RTL代碼之后,驗證人員開始驗證這些代碼(通常稱其為DUT,Design Under Test)。驗證工作主要保證從設計規格說明書到RTL轉變的正確性,它包括但不限於以下幾點:
-
DUT的行為表現是否與設計規格說明書中的要求一致
-
DUT是否實現了設計規格說明書中的所有功能
-
DUT對於異常狀況的反應是否與設計規格說明書中的一致
-
DUT是否足夠穩健,能夠從異常狀態恢復到正常的工作模式
圖1 驗證發現DUT中的bug
隨着芯片規模的增大,驗證占整個芯片設計流程的比例越來越大,驗證的工作量已經占到整個SoC研發周期的70%到80%。因此,提高芯片驗證的效率已變得至關重要。快速搭建一個強大、高效、靈活、可擴展性好的驗證平台是芯片成功的關鍵。
1 UVM代表了驗證方法學的發展方向
驗證是服務於設計的,目前來說,主流的設計語言有兩種:Verilog和VHDL。伴隨着IC的發展,涌現出了多種驗證語言,如Vera、e、SystemC、SystemVerilog等。其中,SystemVerilog剛一推出就受到了熱烈歡迎,SystemVerilog是一個Verilog的擴展集,它既完全兼容Verilog,又具有所有面向對象語言的特性:封裝、繼承和多態,同時,還為驗證提供了一些獨有的特性,如產生帶約束(constraint)的隨機激勵。在基於SystemVerilog的驗證方法學中,主要有以下三種:
-
VMM(Verification Methodology Manual),這是Synopsys在2006年推出的; VMM中集成了寄存器解決方案RAL(Register Abstraction Layer)。當OVM出現后,面對OVM的激烈競爭,VMM已經開源
-
OVM(Open Verification Methodology),由Cadence和Mentor於2008年推出;從一開始就是開源的。它引進了factory機制,功能非常強大,但是它里面沒有寄存器解決方案,這是它最大的短板。針對這一情況,Candence推出了RGM,補上了這一短板。只是很遺憾的是,RGM並沒有成為OVM的一部分,要想使用RGM,需要額外下載。現在OVM已經停止更新,完全被UVM代替
-
UVM(Universal Verification Methodology),其正式版是在2011年2月由Accellera推出的,得到了Synopsys、Cadence和Mentor的一致支持。UVM幾乎完全繼承了OVM,同時又采納了Synopsys在VMM中的寄存器解決方案RAL。UVM繼承了OVM和VMM的優點,克服了各自的缺點,代表了驗證方法學的發展方向
圖2 驗證方法學的發展
2 UVM驗證平台的基本組件
UVM是一個以SystemVerilog類庫為主體的驗證平台開發框架,驗證工程師利用其可重用組件可以構建具有標准化層次結構和接口的功能驗證環境。UVM驗證方法學有效結合了測試激勵隨機生成、自測試平台和隨機化約束等方法,它采用最佳框架以實現覆蓋率驅動的驗證,使驗證工程師通過采用高級驗證技術來降低風險,滿足縮短產品上市時間的迫切需求。
UVM是一個庫,在這個庫中,幾乎所有的東西都是使用類(class)來實現的。類是面向對象編程語言中最偉大的發明之一,是面向對象的精髓所在。使用UVM的第一條原則是:驗證平台中所有的組件都應該派生自UVM中的類。當要實現一個功能時,首先應該想到的就是從UVM的某個類派生出一個新的類,類中可以有成員變量,也可以有函數和任務,通過成員變量、函數或任務實現所期望的功能。
圖3 簡單的UVM驗證平台
驗證用於找出DUT中的bug,這個過程通常是把DUT放入一個驗證平台來實現的。上圖描述了一個簡單的UVM驗證平台,下面結合該圖簡要描述UVM驗證平台的基本組件。
-
transaction,派生自uvm_sequence_item,它是一個抽象的概念,用於描述各個組件傳遞的信息,是各個組件傳遞信息的基本數據結構。
-
driver,派生自uvm_driver,用於給DUT施加各種激勵,負責驅動transaction,它本身並不產生transaction
-
monitor, 派生自uvm_monitor,監測DUT的輸入輸出信號。用於收集DUT的端口數據,並將其轉換成transaction交給后續的reference model和scoreboard組件進行處理
-
sequencer,派生自uvm_sequencer,用於檢測仲裁隊列中是否有發送transaction的請求,以及檢測driver是否申請transaction
-
in_agent,派生自uvm_agent,它是一個容器,用於實例化driver、monitor和sequencer
-
out_agent,派生自uvm_agent,它也是一個容器。由於在輸出端口中不需要驅動任何信號,只需要監測信號,所以out_agent中只需要實例化monitor
-
reference model,派生自uvm_component,用於完成和DUT相同的功能,得到預期結果。一般采用高級語言描述,不用可綜合,其輸出被scoreboard接收,用於和DUT輸出相比較
-
scoreboard,派生自umv_scoreboard,根據DUT的輸出來判斷DUT的行為是否與預期相符合,實現將DUT的輸出和reference model的輸出進行比較
-
sequence,派生自uvm_sequence,用於產生transaction,即產生激勵。sequence用於創建transaction的實例,並將其送給sequencer。
在以上各組件中,driver、monitor、sequencer、agent、reference model和scoreboard都是屬於派生自uvm_component的類,它們是驗證平台中的固定組成部分。transaction是派生自uvm_object的類,它是驗證平台中各組件之間傳輸的基本數據結構,一般來說,物理協議中的數據交換都是以幀或者包為單位。sequence也是派生自uvm_object的類,它定義了transaction的產生方式,包括產生帶約束的transaction,它與具體的測試用例相關。
3 UVM中的sequence與測試用例
sequence機制是UVM中最重要的機制之一,它由兩大部分組成:sequence和sequencer。sequence與sequencer之有着密切的聯系,這點從二者的名字就可以看出來。sequence直接與sequencer打交道,當driver向sequencer索要數據時,sequencer會檢查是否有sequence要發送數據,當發現有sequence_item待發送時,會把此sequence_item交給driver。簡言之,sequence用於產生transaction;sequencer則用於承載sequencer產生的transaction並轉交給driver使用。
圖4 UVM中的sequence機制
UVM中引入sequence機制的好處是將激勵從driver中剝離出來,有利於測試平台的重用。通過編寫不同的sequence,實現不同的測試用例。
-
當一個sequence啟動之后,會自動執行task body中的代碼,用於創建transaction
-
sequence中可以產生帶約束的transaction,它與測試用例密切相關
-
sequence中可以嵌套調用其它sequence
-
當一個驗證平台中存在多個sequencer時,通常會采用virtual sequencer來進行調度。virtual sequencer同樣派生自uvm_sequencer,它與一個virtual sequence對應
-
virtual sequence用來統一調度多個sequence,以便與測試用例直接相連,其本身並沒有定義新的sequence。virtual sequence中的task body可以采用fork … join等並行語句來控制多個sequence的行為
隨着驗證的進行,測試用例的數量一直在增加,在增加的過程中,很重要的一點就是保證后增加的測試用例不影響已經建好的測試用例。在UVM中,最常用的方法是在仿真腳本或命令行中通過指定UVM_TEST_NAME來尋找測試用例的名字,創建它的實例並運行。每個UVM測試用例啟動后,都會對應一個完整的UVM樹結構,每顆UVM樹的頂層都是uvm_test_top。
圖5 某測試用例建立的UVM樹
4 UVM驗證平台:案例學習
下圖描述了某SoC系統的UVM驗證平台總體結構框圖。如圖所示,該SoC系統實現的是一個8端口的以太網交換功能,其設計代碼DUT對外的主要引腳包含1組AXI-Lite接口(用於寄存器配置)和8組AXI-Stream接口(用於以太網收發包)。驗證的目的就是DUT實現了預期的交換功能。
圖6 某SoC系統UVM驗證平台總體結構
在該UVM驗證平台中,包含了兩個層次:testbench和testcase。testbench中包含了每個testcase的公有部分。為了與DUT的頂層信號對接,在該SoC系統UVM驗證平台的testbench中,共設計了8個用於收發包的port_i(i=0,1,…,7)和1個用於配置寄存器的axilite。除此之外,testbench中還包含virtual sequencer和scoreboard。在該UVM驗證平台的每個testcase中,都對應兩類trasnaction:一類是與AXI-Lite配置寄存器相關的axi_trans,包含地址、數據和操作類型(讀/寫)三個字段;另一類transaction是與物理層收發包相關的以太網包packet_trans,它包括目的地址、源地址、幀類型、包長度、幀數據、CRC校驗等字段。
-
axilite:與DUT的寄存器配置相關,內部包含driver、monitor和sequencer。其中,driver根據AXI-Lite協議完成axi_trans到AXI-Lite讀寫時序的轉換;monitor監測驗證平台施加給DUT的axi_trans,並將它們傳送給scoreboard;sequencer與配置寄存器的sequence相關聯;
-
port_i(i=0,1,…,7):與每個port的收發包相關,內部包含driver、monitor和sequencer。其中,driver根據AXI-Stream協議完成packet_trans到AXI-Stream讀寫時序的轉換;monitor通過監測DUT的輸入輸出AXI-Stream接口信號,將它們轉換為發送包/接收包的packet_trans,並將它們傳送給scoreboard;sequencer與收發包的sequence相關聯;
-
virtual sequencer:用於調度管理axilite和port_i中的sequencer,內部包含多個sequencer實例。在一個測試用例中,virtual sequencer與一個virtual sequence相關聯;
-
scoreboard:根據axilite中monitor收集的配置信息和各個port_i收集的發包信息,計算出預期的收包信息,再與monitor實際收到的收包信息進行自動對比,輸出對比結果。注意到在該驗證平台中,我們沒有單獨使用reference model,因為我們已經把reference model的功能內嵌到scoreboard之中。
測試用例的編寫與sequence密切相關,每個測試用例對應一個virtual sequence。根據驗證平台的結構,virtual sequence與各sequence的調用關系如圖7所示,它將不同的sequence加載到對應的sequencer實例之上。圖中以cseq_xxx開頭的sequence都與寄存器配置相關,而tseq_xxx開頭的sequence都與發送包相關。在每個測試用例中,一般來說,在發送包之前需要完成相關寄存器的配置,例如配置路由表。
圖7 virtual sequence的調用關系
因此,基於上述UVM驗證平台,編寫測試用例的基本步驟為:
-
創建測試用例的cseq_xxx,通過對axi_trans的地址、數據、操作類型字段施加約束可完成相關寄存器的配置;
-
創建測試用例的tseq_xxx,通過對packet_trans的幀類型、包長度等包格式字段施加約束可以發送特定的包;
-
創建測試用例的virtual sequence,在virtual sequence中進行調度,將sequence加載到具體端口的sequencer實例之上;
-
創建測試用例的測試類(testclass),在testclass中指定它與新創建的virtual sequence的類名相關聯;
-
在仿真腳本中指定UVM_TEST_NAME的值為新創建的testclass類名。啟動仿真,即可對該測試用例進行驗證。
基於UVM驗證方法學可以快速構建層次化、可擴展性強的驗證平台。本文簡要介紹了UVM驗證平台的基本框架和測試用例的編寫步驟,對UVM中的代碼細節並未過多提及。后續將會介紹UVM中的寄存器模型,敬請期待。