首先要區分一下仿真時間和運行時間:
仿真時間是使用$time函數等到的時間,而運行時間則是CPU的時間。
類繼承層次:
這裏面跟phasing相關的類介紹以下:
1. uvm_phase: 基本的類,定義一個phase的行爲,狀態,內容
2. uvm_domain:phasing的進度節點,表明進度的一個獨立分支
3. uvm_bottemup_phase: 實現bottem up 函數
4. uvm_topdown_phase:實現topdown 函數
5. uvm_task_phase:實現task phase
uvm中的phase,按照其是否消耗仿真時間特性,能夠分紅兩大類:
1. function phase不消耗仿真時間,而function phase也分紅兩大類:
a. 繼承自uvm_bottemup_phase的自下而上的執行function
b. 繼承自uvm_topdown_phase的自上而下執行的function
2. 只有run_phase是task phase,消耗仿真時間的,自上而下啓動,同時在運行。
UVM中同一phase的執行順序:
phase是和uvm_componet相伴相生的一個概念,對於每個uvm_component來講,都有所有的phase,而
驗證平臺中的component是分層次的。
1. UVM使用自上而下執行build_phase,在build_phase中作component的實例化工做,若是在其餘phase實例化一個uvm_component的話,系統會報錯的。若是uvm_object的實例化,則能夠在任何phase完成。
2. 除了build_phase以外,全部的不耗仿真時間的phase都是自下而上執行。
3. 對於同一層次的uvm_component按照new時指定名字的字典順序執行
UVM中的動態運行run_time phase:
1.
UVM把 run_phase又分割成了 12 個小的phase,這 12 個小的 phase各自在執行
順序方面與run_phase徹底相同,即自下而上的啓動,同時運行。這裏有兩個問題,
第一個問題是爲何要分紅小的 phase?第二個問題是這 12 個小的 phase 與
run_phase之間關係如何?
UVM把run_phase又分割成12個小的phase:
1. 爲啥要分紅小phase,精細化控制 reset/configure/main/shutdown是核心
一個大的chip裏面有不少功能性比較獨立的模塊,這些功能性獨立意味着一個模塊A在run的時刻另外一個模塊B能夠不run,也能夠run,B運行不運行和A運行不運行關聯度不大甚至沒有關聯,好比A是隻負責處理髮通路的而B只負責收通路;可是另外一方面,功能性獨立並不意味着什麼都獨立,舉例來講,A模塊和B模塊功能性很獨立,好比A是一個clock generation模塊,B是一個processor模塊,那在A沒有正常work的前提下B是不能正常工做的。
1. 分紅小的phase是爲了實現更加精細的控制,其中核心的四個phase是(reset,configure,main,shutdown),這四個phase模擬了DUT的正常的工做方式
2. 實現跳轉操做
3. 12 個小的 phase之間並非這樣順序執行,而是每當一個小的phase 執行完成的時候要看看其它component的同名的小 phase有沒有執行完,等全部的都執行完後,纔會進入下一個小的phase,也就是說有一個同步的過程。
由此咱們至少能夠提出兩點需求:
(1)能不能讓B的reset phase發生在A的reset phase以後,這樣等待clock都穩定了再對B作reset操做或者release reset操做?
(2)能不能讓A的main phase和B的main phase異步的運行?
上面兩點至少須要用到UVM中的的以下機制:新建一個domain、給不一樣的component設置不一樣的domain、不一樣的domain之間phase的同步和異步。
再如,功能更復雜的tb可能須要新建一個user-defined的phase,讓它在某一須要個時刻點運行,能夠是function性質的或者task性質的。
2. 12個小phase於run_phase之間的關係?
每當一個小的phase執行完成時候,要等到全部component的同名的小phase有沒有執行完,等全部執行完了,才進入下個小phase。
UVM中的objection:
UVM中,經過objection機制來控制驗證平臺的關閉。
在進入到某一phase的時候,UVM會收集此phase提出的全部的objection,而且實時監測全部的objection是否已經drop了,當發現全部的都已經drop後,那麼就會關閉此phase,開始進入下一個phase。當全部的phase都執行完畢後,就會調用$finish來把整個的驗證平臺關掉。
若是想執行一些耗費時間的代碼,那麼至少也要在此phase下raise一次objection。
這個結論只適用於run_time的phase。對於run_phase則不適用。
phase的引入是爲了解決什麼時候結束仿真的問題
上例中,只要把pkt_num設置成要發送的transaction的數量就能夠了。這種設置能夠經過config的形式,讀者能夠參照config機制的相關章節。
另一種方法就如在第一章的例子中那樣,在sequence中把sequencer的objection給raise起來,當sequence完成後,再drop此objection。這種方法相對上一種方法的好處就是沒必要設置要發送的包的數量。不過,這種方法的限制是,此sequence必需要作爲sequencer的某個phase(好比main_phase)的default_sequence,這個一般是比較容易的,通常都使用這種方法。
domain:
domain把兩塊時鐘域隔開,以後兩個時鐘域內的各個動態運行(run_time)的phase就能夠沒必要同步。注意,這裏domain只能把run_time的phase給隔離開來,對於其它的phase,其實仍是同步的,即兩個domain的run_phase依然是同步的,其它的function phase也是同步的。
多domain與單domain的區別主要體如今phase和objection上