phase機制介紹
UVM中的phase,按照其是否消耗仿真時間($time打印出的時間)的特性,可以分成兩大類,一類是function phase,如 build_phase、connect_phase等,這些phase都不耗費仿真時間,通過函數來實現;另外一類是task phase,如run_phase等,它們耗費 仿真時間,通過任務來實現。給DUT施加激勵、監測DUT的輸出都是在這些phase中完成的。在下圖中,灰色背景所示的是task phase,其他為function phase。
image-20240228151228432
上面的所有phase都是按順序自上而下自動執行。
class my_case0 extends base_test; string tID = get_type_name(); virtual function void build_phase(uvm_phase phase); super.build_phase(phase); `uvm_info(tID, "build_phase is executed", UVM_LOW) endfunction virtual function void start_of_simulation_phase(uvm_phase phase); super.start_of_simulation_phase(phase); `uvm_info(tID, "start_of_simulation_phase is executed", UVM_LOW) endfunction virtual task run_phase(uvm_phase phase); `uvm_info(tID, "run_phase is executed", UVM_LOW) endtask virtual task pre_reset_phase(uvm_phase phase); `uvm_info(tID, "pre_reset_phase is executed", UVM_LOW) endtask virtual task post_shutdown_phase(uvm_phase phase); `uvm_info(tID, "post_shutdown_phase is executed", UVM_LOW) endtask virtual function void extract_phase(uvm_phase phase); super.extract_phase(phase); `uvm_info(tID, "extract_phase is executed", UVM_LOW) virtual function void final_phase(uvm_phase phase); super.final_phase(phase); `uvm_info(tID, "final_phase is executed", UVM_LOW) endfunction endclass
運行上述代碼,可以看到各phase被依次執行。
需要注意的一點是就是run_phase和右邊的12個phase,是并列關系,而不是說run_phase包含右邊的12個phase,它們是并行運行的,它們的順序大致如下:
fork begin run_phase(); end begin pre_reset_phase(); reset_phase(); post_reset_phase(); pre_configure_phase(); configure_phase(); post_configure_phase(); pre_main_phase(); main_phase(); post_main_phase(); pre_shutdown_phase(); shutdown_phase(); post_shutdown_phase(); end join
UVM提供了如此多的phase,在一般的應用中,無論是function phase還是task phase都不會將它們全部用上。使用頻率最高的 是build_phase、connect_phase和main_phase。這么多phase除了方便驗證人員將不同的代碼寫在不同的phase外,還有利于其他驗證 方法學向UVM遷移。一般的驗證方法學都會把仿真分成不同的階段,但是這些階段的劃分通常沒有UVM分得這么多、這么細 致。所以一般來說,當其他驗證方法學向UVM遷移的時候,總能找到一個phase來對應原來方法學中的仿真階段,這為遷移提供 了便利。
Phase的執行順序
build_phase是按照自上而下的順序執行的,在下圖中,先執行uvm_test_top的build_phase,再執行env的build_phase。
除了build_phase,所有不耗費仿真時間的phase都是自下而上執行的,對于connect_phase即先執行driver和monitor的connect_phase,再執行agent的connect_phase。
image-20240228151306612
看到這里,很多同學可能就有三個疑惑。
對于i_agt、mdl、scb、o_agt這幾個兄弟關系的component,執行順序是什么樣的?
每個component里面都有build_phase和main_phase,是按component執行還是按phase的順序執行?
那幾個task phase,是會消耗仿真時間的,是按照什么樣的順序執行的?
Answer:
無論是自上而下還是自下而上,都只適應于UVM樹中有直系關系的component。對于同一層次的、具有兄弟關系的 component,如driver與monitor,它們是按照字典的順序執行的,這里的字典序的排序 依據new時指定的名字。假如monitor在new時指定的名字為aaa,而driver的名字為bbb,那么將會先執行monitor的build_phase。反之 若monitor為mon,driver為drv,那么將會先執行driver的build_phase。
我們本節提到的bulid_phase、connect_phase、run_phase這些都是時間的概念,而上面這個圖中各個component的關系是空間的概念。在執行時,先把各個component中的build_phase執行完,再執行各個component的connect_phase,再執行各個component的run_phase。
類似run_phase、main_phase等task_phase也都是按照自下而上的順序執行的。但是與前面function phase自下而上執行不同的是,這種task phase是耗費時間的,所以它并不是等到“下面”的phase(如driver的run_phase)執行完才執行“上面”的phase(如agent 的run_phase),而是將這些run_phase通過fork…join_none的形式全部啟動。所以,更準確的說法是自下而上的啟動,同時在運行。
但一般我們的環境中,只有driver和monitor里面會有run_phase或者main_phase的定義,像agent這種封裝類的component,不會定義task_phase。
對于同一component來說,其12個run-time的phase是順序執行的,但是它們也僅僅是順序執行,并不是說前面一個phase執行完 就立即執行后一個phase。以main_phase和post_main_phase為例,對于A component來說,其main_phase在0時刻開始執行,100時刻 執行完畢;對于B component來說,其main_phase在0時刻開始執行,200時刻執行完畢;此時整個驗證平臺的main_phase才執行完畢,接下來執行post_main_phase,即A和B的post_main_phase都是在200時刻開始執 行。假設A的post_main_phase執行完畢需要300個時間單位,而B只需要200個時間單位,無論是A或者B,其后續都沒有其他耗時 間的phase了,整個驗證平臺會在500時刻關閉。
可以看到對于A來說,main_phase在100時刻結束,其post_main_phase在200時刻開始執行。在100~200時刻,A處于等待B的 狀態,除了等待不做任何事情。B的post_main_phase在400時刻結束,之后就處于等待A的狀態。
這個過程如下圖所示:
image-20240228151317829
無論從A還是B的角度來看,都存在一段空白等待時間。但是從整個驗證平臺的角度來看,各個task phase之間是沒有任何空白的。
除了兄弟關系的component,還有一種叔侄關系的component,如my_scoreboard與my_driver,從樹的層次結構上 來說,scoreboard級別是高于driver的,但是,這兩者build_phase的執行順序其實也是不確定的。這兩者的執行順序除了上節提到的 字典序外,還用到了圖論中樹的遍歷方式:廣度優先或是深度優先。
UVM中采用的是深度優先的原則,在UVM的樹形圖中,scoreboard及driver的build_phase的執行順序,i_agt實例化時名字為“i_agt”, 而scb為“scb”,那么i_agt的build_phase先執行,在執行完畢后,接下來執行driver、monitor及sequencer的build_phase。當全部執行完 畢后再執行scoreboard的build_phase。
常用的三個phase
我們上面也講過bulid_phase、connect_phase和run_phase是三個最常用的phase,那這三個phase的具體作用是什么?應該如何使用?
run_phase也經常會用main_phase代替。
build_phase
主要用來實例化組件,即創建對象。uvm_component對其做的最重要的事情就是自動獲取通過config_db::set設置的參數。
connect_phase
run_phase
所有的數據處理,都在run_phase中。
審核編輯:劉清
-
UVM
+關注
關注
0文章
182瀏覽量
19167 -
TLM
+關注
關注
1文章
32瀏覽量
24749 -
DUT
+關注
關注
0文章
189瀏覽量
12373
原文標題:UVM手把手教程系列(二)Phase機制介紹
文章出處:【微信號:傅里葉的貓,微信公眾號:傅里葉的貓】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論