基于VMM驗證方法學的MCU驗證環(huán)境
4.2 指令數(shù)據(jù)包以及Scenario Generator
在VMM環(huán)境中,所有的數(shù)據(jù)都是擴展vmm_data得到,在這里首先對指令分類,相同格式的指令皆為同一類型,具體部分分類表格如表1中所示。
分類的依據(jù)在于指令格式,例如對從工作寄存器Rn到A的操作,或是從直接地址Rx到A的操作,這樣可以通過約束一個種類來隨機化指令格式,生成指令格式以后可以根據(jù)指令格式來填入相應的隨機值。首先就是約束指令格式對應的指令,代碼如:
constraint add_mode_decide_kind{
(addr_mode==RN_A) -> kind inside {MOV, ADD, ADDC, SUBB, XCH, ANL, ORL, XRL};
(addr_mode==RX_A) -> kind inside {MOV, ADD, ADDC, SUBB, XCH, ANL, ORL, XRL};
…………}
然后約束對應的寄存器地址,立即數(shù),相對地址等,代碼如:
constraint inst_valid{
di_x inside {[0:255]};
reg_y inside {[0:255]};
reg_i inside {0, 1};
reg_n inside {[0: 7]};
…。}
得到了指令的格式,隨機得到指令,指令參數(shù),在以上約束下就可以生成一條符合語法的指令。通過在TestCase中約束指令格式,或是地址數(shù)據(jù)就可以在TestCase中控制Generator生成的指令,通過變換隨機種子就可以生成不同類型的指令集合。
使用宏定義對數(shù)據(jù)類擴展就可以得到數(shù)據(jù)類的Generator和Channel:
`vmm_channel(inst)
`vmm_scenario_gen(inst, “inst”)
每次scenario Generator生成一條指令,并且通過channel傳遞給Driver??梢詫⒁幌盗屑s束做為一個scenario,這樣可以控制指令與指令之間的關系,將一系列scenario合并可以生成更多的隨機組合,例如:
$void(scenario_kind) == R0_OP -> {
foreach(items[i]){
items[i].addr_mode inside {0,1,2,4,5,6,7,8,10,11,12,13,14,21,22,23,24,26,27,28=};
items[i].reg_x inside {0};
items[i].reg_n inside {0};
items[i].reg_i inside {0};
}
}
驗證這里能夠做到盡可能大量重復地測試某些指令的集合,以便將一些邊緣情況測到,例如實際應用上會反復使用累加器或是反復調(diào)用R0-R7,都可以通過約束來實現(xiàn)。大量隨機的代碼測試下,可以給出更邊緣的TestCase,盡可能地測試到一些邊緣情況。
4.3 Driver
這里Driver實現(xiàn)了Transactor的功能,除了實現(xiàn)將asm代碼匯編,將16進制代碼讀入ROM模型中,還要調(diào)用MCU的C模型并產(chǎn)生結果,供后續(xù)ScoreBoard對比。
由于匯編器需要將所有指令代碼讀入進行統(tǒng)一匯編,由Generator生成的所有指令代碼在Driver中會被寫入asm文件,通過DPI調(diào)用一個匯編的 C function來處理這個asm文件,生成一個HEX 代碼文件,Driver可以讀入這個HEX 代碼,并且寫入一個用SystemVerilog實現(xiàn)的ROM模型中,另外通過DPI調(diào)用一個C的MCU仿真器,可以實時寫出每一條指令MCU的SFR、 RAM狀態(tài),同樣這些狀態(tài)都保留在單獨的文件中,以作為ScoreBoard的輸入。
因為MCU的指令組合可以說是無法測全的,真正的測試往往要發(fā)生在應用代碼測試上,Driver除了可以接受從channel中得到的指令,也可以直接從外部文件得到asm代碼或是16進制代碼,這樣已有的MCU測試代碼或是應用程序都可以在這個環(huán)境中直接調(diào)用。此外,中斷的外部輸入也有隨機的數(shù)據(jù)灌入,外部端口的輸入數(shù)據(jù)也是在指令數(shù)據(jù)包中產(chǎn)生,并且由TestCase控制的。MCU工作方式的特殊性,導致Driver相對于驗證環(huán)境較為獨立,與驗證環(huán)境的接口都是磁盤文件。
4.4 C模型
環(huán)境中使用兩個C模型:匯編器和仿真器,將asm代碼匯編成為16進制代碼,并仿真16進制代碼。通過DPI調(diào)用C函數(shù)如下:
import “DPI” function void asmb_r(string in_file, string out_file);
import “DPI” function void siml(int run_for_n_ins, string in_file2, string in_file1, string in_file, string out_file, string out_file2, string out_file3, string out_file4);
如Driver所示,輸入輸出都是磁盤文件。匯編器通過查表將指令翻譯成16進制代碼,對于變量將用哈希表實現(xiàn),通過查表替換,插入校驗碼,最后得出的16進制代碼,作為MCU的C模型仿真輸入,并且由Driver的ROM模型讀入。
仿真器輸入16進制代碼,通過先解碼16進制代碼,然后逐條執(zhí)行代碼,所有memory都是在C中實現(xiàn),每個指令分別調(diào)用相應的函數(shù),此外還有相應的中斷函數(shù)處理中斷,在每一條指令后寫出SFR,Internal RAM以及External RAM中的值到磁盤文件中,以作為RTL仿真的參照,C模型的結果直接影響整個驗證的準確性,因為RTL是由時鐘驅(qū)動,而C模型是不帶時序關系,有些指令的執(zhí)行結果需要根據(jù)時序做部分調(diào)整,調(diào)整模型在驗證中占去較多資源。
4.5 memory模型
MCU外圍連接了四個外部memory,包括Internal SFR、Internal RAM、External SFR以及External RAM。在驗證MCU時,memory中的值就可以保證MCU的工作狀態(tài),因此在驗證中,MCU的外部memory都是用SystemVerilog實現(xiàn)的行為模型,除了通過interface io來響應MCU的讀寫要求之外,還有數(shù)據(jù)通道通往ScoreBoard,這里每個MCU時鐘都會將memory值記錄下來送往ScoreBoard,由于Internal SFR、Internal RAM、External SFR僅有128 byte,數(shù)據(jù)量較小,可以每個時鐘周期來檢查,但對于External RAM有64k byte,對比或是傳輸都比較耗費資源。另外,對External RAM的操作并不多,這里實現(xiàn)的是在Testcases中約束對于External RAM的地址都為低256 byte,這樣可以有效地控制數(shù)據(jù)量并且在每個時鐘周期檢查memory狀態(tài),另外一種可選方式是每隔一定數(shù)量的指令來對比External RAM的值,同樣對仿真影響較小。
4.6 ScoreBoard
ScoreBoard收集到從各個memory傳遞過來的memory值,因此對應一塊memory就會有一塊ScoreBoard,對比通過讀取 MCU 的C模型寫出的memory狀態(tài)值,由于MCU模型寫出的值是每條指令執(zhí)行之后的值而memory傳遞過來的數(shù)據(jù)為每個時鐘周期,這里 ScoreBoard不但要負責解讀C模型寫出的參照memory結果文件,通過參照將確認每個指令執(zhí)行時鐘周期長度,然后從memory模型傳遞過來的數(shù)據(jù)中選取該指令執(zhí)行之后一個時鐘周期的數(shù)據(jù)與參照數(shù)據(jù)進行對比,考慮到部分數(shù)據(jù)會有延遲,ScoreBoard在對比時,不僅僅考慮當前比較時間點上的數(shù)據(jù),如果對比失敗,ScoreBoard的自檢會進入子線程,繼續(xù)讀取memory傳遞過來的數(shù)據(jù),考慮到MCU支持指令延遲操作最多8個時鐘周期,如果在后續(xù)16個周期內(nèi)得到正確的值,ScoreBoard會認為結果正確,并且中止子線程返還檢查成功標志。
評論