設計正變得日益復雜,越來越多的設計包含了處理器 - 甚至包含多個處理器。由于處理器是設計不可分割的一部分,因此我們必須驗證在處理器上運行的軟件與設計的其它部分之間的交互,這一點非常重要。軟件對當今系統(tǒng)的運作至關(guān)重要,因而在實驗室中原型芯片完成之前,對硬件/軟件邊界的驗證和確認不容出現(xiàn)任何延遲。至少,驗證團隊必須完成這項任務,并且自行承擔風險。相信我們都聽說過一些嚴重錯誤的場景,例如,團隊在實驗室中發(fā)現(xiàn),處理器的總線與設計的連接順序接反了,或者處理器從低功耗模式下再無法上電啟動。
硬件/軟件逐步細化
一個顯而易見的解決方案就是在傳統(tǒng)的驗證流程中,圍繞硬件/軟件邊界進行更多驗證。但是,我們無法直接從以硬件為中心的驗證,轉(zhuǎn)變?yōu)閲L試運行整個應用程序堆棧。運行大量的軟件而存在的復雜性及生成的大量調(diào)試日志,讓追蹤簡單錯誤也會變得非常復雜。
一種高效的方法是在最簡單的驗證環(huán)境中進行所有可行的驗證,該環(huán)境讓我們能夠執(zhí)行目標功能,并且具有最高的可見性,最大程度減少與測試意圖不相關(guān)的工作。
在本文中,我們將討論涉及到寄存器訪問驗證的簡單示例。驗證處理器是否能夠正確寫入和讀取 IP 寄存器,是非常關(guān)鍵的集成驗證任務。即便是簡單的 SoC,也包含數(shù)以百計的寄存器,因而創(chuàng)建測試來驗證處理器是否能夠讀取和寫入所有寄存器將會是非常耗時的工作。
圖 1 - 簡單的 SoC
圖 1 顯示了簡單的 SoC,它搭載了閃存、DDR 存儲器、緊耦合存儲器以及 UART 和 DMA 引擎,它們的寄存器通過低速外設總線來訪問。
雖然最終目標是驗證在處理器上運行的代碼是否能夠訪問 IP 寄存器,但我們可以首先從基于 UVM 的驗證開始,更加集中驗證某一部分。在UVM 中率先驗證存儲器子系統(tǒng)后,我們在嵌入式處理器上調(diào)通軟件時將更有信心。使用 Mentor 的 Questa inFact 便攜式激勵工具,可讓我們將同一測試的目標重定向到 UVM 和嵌入式軟件環(huán)境,從而節(jié)省測試開發(fā)時間。
使用圖形描述寄存器
Questa inFact 使用了基于圖形的聲明輸入描述,可提供約束編程的功能,增強以迭代方式指定決策的能力。當需要對訪問寄存器的規(guī)定約束時,以迭代方式進行決策的能力非常有幫助。
首先,我們要捕獲存儲器測試操作的核心屬性:地址、訪問范圍大小、寫入數(shù)據(jù)、寫入掩碼。寫入掩碼指定了在進行檢查時應該讀取/寫入哪些位,而必須忽略哪些位。
圖 2 - 核心寄存器訪問結(jié)構(gòu)體
action 是指要在目標驗證環(huán)境中執(zhí)行的操作的單位。在下文中,我們將了解更改 body 操作的實施如何讓我們輕松地將寄存器訪問測試的目標重定向到 UVM 和嵌入式軟件環(huán)境。
圖 2 顯示的寄存器訪問描述符不包括系統(tǒng)中的 IP 的任何詳細信息。接下來,我們需要添加這些限制。我們的 DMA 引擎(來自 opencores.org 的 Wishbone DMA Core)包括一系列的核心寄存器,還有通道描述符寄存器陣列。使用基于圖形的描述,我們能夠以迭代方式描述寄存器地址。
圖 3 - DMA 寄存器地址選擇
圖3的圖形描述顯示了選擇 DMA 寄存器地址的過程:
· 選擇核心寄存器或通道控制寄存器陣列 (dma_reg)
· 如果選擇通道控制寄存器
o 選擇哪個通道 (dma_ch)
o 選擇哪個通道寄存器被作為目標 (dma_ch_reg)
圖 4 - DMA 寄存器地址選擇規(guī)則
圖 4 顯示了此過程的文字描述。
圖 5 - DMA 寄存器地址選擇約束
用于指定在約束中編碼的寄存器地址和寫入掩碼的更詳細約束顯示在圖 5 中。請注意,此約束標記為“dynamic”(動態(tài)),這意味著在圖形范圍內(nèi),它只有在激活之后才會應用 – 在這種情況下,我們已經(jīng)決定訪問 DMA 寄存器。雖然這些約束是手動創(chuàng)建的,但它們也可從機器可讀取的寄存器描述生成,例如 IP-XACT、SystemRDL 等。
圖 6 - 簡單 SoC 寄存器訪問圖形
整合寄存器訪問圖形的 DMA、UART 和 TCM 部分之后,可獲得圖 6 中顯示的圖形。我們可以將它視為流程圖:首先,我們決定要訪問哪個 IP,然后基于選定的 IP 來決定圖形分支,并且做出特定的選擇。例如,最左側(cè)的圖形分支包含 DMA 特定的決策。
定向測試
即便是小型 SoC,也有超過 250 個寄存器,而常規(guī)的 SoC 的寄存器數(shù)量甚至還會超出很多倍。我們必須確保能夠訪問所有這些寄存器,并通過某種隨機順序進行訪問。我們還可能希望集中測試某一部分 – 例如,僅測試 UART 寄存器。
Questa inFact 允許結(jié)合使用約束和圖形覆蓋率目標,將測試重點放在要實現(xiàn)的目標上。約束指定允許生成哪些測試,而覆蓋率目標則側(cè)重于系統(tǒng)性生成某些測試。例如,我們可以使用約束來指定 UART 當前尚不能進行測試。使用覆蓋率目標可指定某個特定測試的重點是 DMA 引擎,但在實現(xiàn)該目標之后,可將目標定向到其他可用 IP。
圖 7 - 將 DMA 作為重點的覆蓋目標
圖 7 中顯示的覆蓋率目標(藍色陰影區(qū)域)將當前測試活動的重點集中于 DMA 寄存器上。Questa inFact 將生成測試,按照偽隨機順序,系統(tǒng)地訪問 DMA 寄存器,然后生成對 DMA、UART、TCM 的混合訪問。
映射到 UVM 環(huán)境
截止目前,我們創(chuàng)建的寄存器訪問測試的描述都是獨立于任何驗證環(huán)境的。我們現(xiàn)在必須提供一點膠接邏輯,將我們的測試圖形連接到子系統(tǒng)級驗證環(huán)境。
圖 8 - 子系統(tǒng)級驗證環(huán)境
在 UVM 子系統(tǒng)級環(huán)境中,我們使用總線功能模型 (BFM) 取代了處理器的 RTL 模型,以便通過互連訪問寄存器。寄存器測試圖形封裝在將通過 BFM 訪問寄存器的 UVM 虛擬序列 (virtual sequence) 中。
基本“CPU”虛擬序列提供通過類 API 對 BFM 的訪問,它支持不同大小的讀取和寫入。我們添加了特定的“memcheck”序列,它在“do_memcheck”任務內(nèi)部執(zhí)行寫入、回讀和檢查,如圖 9 所示。
圖 9 - UVM do_memcheck 任務
將寄存器測試圖形連接到虛擬序列中的 do_memcheck 任務所需的映射信息收集在一個文件中 – 在本例中該文件為 target.rseg。映射信息顯示在圖 10 中。
圖 10 - UVM 序列目標映射
映射信息指定:
· 圖形應該封裝在從 or1k_memcheck_vseq 擴展的類中
· 在 UVM 環(huán)境中,應該使用 or1k_memcheck_c 類來代表 or1k_soc_regacc 結(jié)構(gòu)體。
· 當 or1k_soc_regacc 內(nèi)部的“body”操作執(zhí)行時,應調(diào)用 do_memcheck 任務。
只需這幾行代碼,我們就能在 UVM 環(huán)境中運行寄存器測試圖形。這讓我們能夠使用標準的 UVM 和 SystemVerilog 調(diào)試工具,驗證寄存器連接的基本信息,并對任何問題進行調(diào)試。
映射到嵌入式軟件
當然,驗證確認 BFM 能夠訪問寄存器存儲器,并不一定確保處理器也能夠訪問。因此,在處理器上以與嵌入式軟件相同的方式,來運行寄存器訪問測試,仍然非常重要。這種最簡單的完整 SoC 驗證環(huán)境如圖 11 中所示。
圖 11 - 軟件驅(qū)動的驗證環(huán)境
在本例中,我們將創(chuàng)建以 C 語言編寫的一系列測試,使用處理器寫入和回讀寄存器。我們的測試將使用 do_memcheck 函數(shù)來執(zhí)行實際的寫入、回讀和檢查。此函數(shù)如圖 12 所示。
圖 12 - 嵌入式軟件 do_memcheck 函數(shù)
與在 UVM 環(huán)境中相同,我們需要指定圖形如何映射到嵌入式軟件環(huán)境。映射信息顯示在圖 13 中。
圖 13 - 嵌入式軟件映射
映射信息指定以下內(nèi)容:
· 必須包括頭文件 or1k_memcheck.h。此文件聲明 do_memcheck 函數(shù)。
· 每次 body 操作執(zhí)行時,必須調(diào)用函數(shù) do_memcheck,傳遞 addr、size、wr_data 和 wr_mask 字段的值。
生成 C 測試
我們已經(jīng)介紹了要執(zhí)行的寄存器測試的基于圖形的模型,我們在如何生成一系列特定測試方面具有很大靈活性。圖 14 顯示了生成的測試的一個示例。在本例中,我們允許 inFact 將目標定向到所有三個 IP,但限制該測試只能通過圖形進行五次迭代。
圖 14 - 示例寄存器測試
正如您看到的那樣,生成的測試是定向測試,在生成過程中,inFact 填充了隨機值。雖然特定測試在每次運行時始終執(zhí)行相同的操作,但我們可以重新生成測試,每次在回歸運行時使用不同的種子,從而在回歸運行中實現(xiàn)更多隨機性。
為了實現(xiàn)對上文所述的寄存器訪問目標的覆蓋率,我們需要生成更多針對性的測試。由于所有這些測試都是從單個描述模型生成的,因此我們可以簡單地更改測試生成程序的選項,以便在以下兩種方式之間切換:運行很多測試,每個測試都對 do_memcheck 進行少數(shù)幾次調(diào)用;或者運行少數(shù)幾次測試,每次測試都對 do_memcheck 進行很多次調(diào)用。我們還可以簡單地調(diào)節(jié)覆蓋率目標,例如,生成一系列測試,僅將重點放在 DMA 寄存器測試上。
總結(jié)
采用步進式方法來驗證嵌入式處理器與設計其他部分的IP之間的交互,可在驗證流程中及早發(fā)現(xiàn)錯誤,以便最簡單地進行調(diào)試和糾正,從而節(jié)省時間。使用便攜式激勵,可從描述的測試意圖著手,生成高質(zhì)量的測試,并將目標重定向到多個環(huán)境。這樣可以應對步進式方法的主要挑戰(zhàn),即它需要大量的重復工作,在多個位置執(zhí)行測試意圖,另外還需要使用低效率的定向測試,創(chuàng)建嵌入式軟件測試。在本文中,我們看到對 SoC 寄存器的測試意圖的單個描述如何能夠輕松將目標定向到 UVM 和嵌入式軟件環(huán)境,作為 SoC 集成測試的一部分。我們還看到了如何使用 Mentor 的 Questa inFact 便攜式激勵工具,對此測試意圖進行描述,并將目標定向到特定環(huán)境。
下一次當您開始計劃 SoC 集成測試時,應該考慮到便攜式激勵和步進式測試方法如何讓您的驗證流程受益!