• 正文
  • 相關推薦
申請入駐 產(chǎn)業(yè)圖譜

CPU驗證環(huán)境關鍵機制

06/23 19:06
352
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

1. 前言

本文記錄CPU驗證環(huán)境中一些基本但重要的機制,包括驗證環(huán)境中的編譯CPU啟動配置、Tube機制和Testcase結(jié)束機制

2. 編譯

CPU驗證環(huán)境編譯分為軟件編譯和硬件編譯。因為CPU的Core會去memory中取指令去執(zhí)行,而這些指令需要我們提前生成好,并后門放在memory中取,這些指令的集合通常使用hex格式的文件存儲,軟件編譯就是將C語言或匯編語言轉(zhuǎn)換為二進制指令碼,并存儲在hex格式文件中。硬件編譯是將RTL和UVM驗證環(huán)境一同編譯起來,形成一個驗證環(huán)境的骨架,軟件編譯的hex文件依托于硬件編譯產(chǎn)生的平臺。編譯環(huán)境如圖1所示。

 

圖1 編譯環(huán)境

 

2.1 軟件編譯

 

軟件編譯通常使用makefile來管理的。makefile調(diào)用各CPU的子makefile去生成各個CPU的hex文件。步驟如圖2所示。

 

圖2 軟件編譯流程

 

確定軟件編譯環(huán)境(編譯器、編譯選項、編譯文件和目錄)

將文件編譯成.o格式的文件

確定link方式(link器、link選項、規(guī)則、文件)

將.o文件link成elf文件

將elf文件轉(zhuǎn)成hex文件

 

 

2.2 硬件編譯

 

硬件編譯就是使用Xcelium/Questasim/VCS對SystemVerilog代碼進行編譯、細分和開啟仿真的過程。在如今普遍使用UVM的環(huán)境中,會形成一個UVM樹,使用uvm_test來啟動仿真。

 

在仿真開始時,驗證環(huán)境會使用后門加載軟件編譯的hex文件到對應的DDR/SRAM/ROM里。根據(jù)加載到memory類型的不同,通常還有不同的方式:

 

如果memory是真實RTL,可以使用SystemVerilog語法的$readmemh將hex數(shù)據(jù)從后門填充到真實DDR/RAM/ROM里。

如果memory是虛擬RAM,通常用虛擬RAM提供的函數(shù)將hex數(shù)據(jù)從后門填充進去。

 

3. CPU啟動配置

3.1 確定PC初始值

 

CPU啟動最關鍵的要確定PC值,PC值決定了CPU從哪里開始取值并執(zhí)行。

 

對于ARM Cortex-A來說,初始PC是放在RVBAR(Reset Vector Base Address Register

寄存器中,RVBAR寄存器是RO類型的,也就是實現(xiàn)就定義好的了。在IP驗證中,通常force這個寄存器的值來控制CPU啟動PC值。在SoC驗證中,如果RVBAR為0,那么會提前在0地址處放置跳轉(zhuǎn)指令(BL),將Cortex-A CPU的PC跳轉(zhuǎn)到真正的啟動地址去執(zhí)行。

 

對于ARM Cortex-M來說,沒有RVBAR寄存器,在復位后會查詢中斷向量表并進入reset中斷函數(shù)執(zhí)行,因此在reset中斷函數(shù)里可以控制PC跳轉(zhuǎn)到真正的啟動地址。中斷向量表一般存放在ROM中,Cortex-M CPU在boot的過程中可以讀取它的內(nèi)容。

 

 

3.2 Cortex-A啟動流程

 

Cortex-A啟動流程通常按以下步驟進行:

 

通用寄存器值、堆棧指針、link指針和狀態(tài)寄存器全部初始化為0;

關掉Trap功能;

設置VBAR(Vector Base Address Register),使它指向中斷向量表;

初始化堆棧指針,內(nèi)容來自scatter file指定的;

使能NEON和初始化相關寄存器為0;(包括使能其它想要打開的特性)

創(chuàng)建頁表,配置TTBR/TCR/MAIR等;

使能cache和MMU;

使能中斷;

進入main主程序,完成主要操作;

進入WFI;

 

通常步驟1~8以及步驟10在CPU驗證中是固定的流程,不需要反復寫,大部分驗證人員只需要在步驟9的main()函數(shù)中完成想要驗證的功能。

 

 

3.3 Cortex-M啟動流程

 

Cortex-M啟動流程通常按以下步驟進行:

 

復位后,進入reset_handler,初始化通用寄存器為0;

調(diào)用系統(tǒng)初始化函數(shù)去配置UART、配置MPU等等;

進入C庫的啟動函數(shù)__main,完成一些初始化工作,像設置棧指針、初始化全局變量等,之后調(diào)用用戶編寫的main()函數(shù);

進入main主程序,完成主要操作;

進入WFI;

 

類似Cortex-A,步驟1~4以及步驟5在CPU驗證中是固定的流程,不需要反復寫,大部分驗證人員只需要在步驟4的main()函數(shù)中完成想要驗證的功能。

 

4. Tube機制

SystemVerilog代碼可以使用$display()等內(nèi)置的系統(tǒng)函數(shù)很方便的將信息打印到log上,但是C語言就不好弄。

 

常用的方法是Tube機制,把將要打印的字符串寫到UART口上,UART上對接的組件會一直監(jiān)控出現(xiàn)在UART口上的二進制數(shù)據(jù),并把它們轉(zhuǎn)成ASIIC碼,然后調(diào)用SystemVerilog的$display()函數(shù)打印到log上。

 

總得來說,還是借用了SystemVerilog的系統(tǒng)函數(shù)來打印的。

 

5. Testcase結(jié)束機制

對于只使用SystemVerilog和UVM環(huán)境的驗證同學可能有疑問,Testcase結(jié)束不就很簡單嗎,直接調(diào)用$stop或drop_objection就ok了。但對于包含CPU運行的環(huán)境來說就不一樣了,CPU執(zhí)行的是C語言,從Memory中取值執(zhí)行,驗證環(huán)境不好監(jiān)控它是否執(zhí)行完畢,這就需要CPU發(fā)出一些可以被驗證環(huán)境捕捉到的信號,用于表示CPU執(zhí)行的狀態(tài)。

 

一種常用的方法是CPU在執(zhí)行完之后,往UART口寫某些特定字符。UART口連接的監(jiān)控組件如果解析到這些字符,將字符含義傳達給驗證環(huán)境。

 

同理,如果有多個CPU,那么需要UART監(jiān)控多個CPU都往UART寫完某些字符后,再使用event或全局變量等觸發(fā)一個事件,UVM等到這個事件,再執(zhí)行相應動作。

 

相關推薦

登錄即可解鎖
  • 海量技術文章
  • 設計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄