1宇整、seq相關(guān)的phase機(jī)制
首先你需明確的是UVM的框架下瓶佳,消耗時(shí)間的task的執(zhí)行都在在uvm_component底下的objection的機(jī)制來(lái)實(shí)現(xiàn)的。也就是說(shuō)phase的機(jī)制跟uvm_component是緊密相關(guān)的鳞青。
uvm_sequence是一個(gè)uvm_object的類(lèi)霸饲,uvm_sequencer是一個(gè)uvm_component的類(lèi)为朋。
seq需要掛載在seqr上執(zhí)行。
run_time_phase.svh
在前面我們講過(guò)UVM_PHASE的機(jī)制厚脉,在execute函數(shù)的地方有對(duì)uvm_sequencer_base類(lèi)型的做處理习寸。
- start_phase_sequence(phase):處理default_sequencer
- 這里先做個(gè)遺留,到底這里是什么從外面獲得default_sequencer的器仗。
方法一:利用default_sequence啟動(dòng)seq
也只有在用default_sequence的方式啟動(dòng)seq的時(shí)候融涣,start_phase != null精钮,原因是如果是sqr的時(shí)候在uvm_task_phase.svh里面有介紹,會(huì)自己調(diào)用start_phase_sequence剃斧,里面會(huì)對(duì)seq.set_starting_phase(phase);進(jìn)行set轨香。
前提
對(duì)應(yīng)uvm1.2版本,
或者是my_seq.set_automatic_phase_objection(1);
在start_phase_sequence里面已經(jīng)指定了phase幼东,seq.set_starting_phase(phase);
命令行設(shè)置default_sequencer:
+UVM_SET_DEFAULT_SEQUENCE=uvm_test_top.env.i_agt.sqr,main_phase,case0_sequence
- 第一個(gè)參數(shù)是指定seqr的路徑
- 第二個(gè)參數(shù)是指定要執(zhí)行的phase階段
- 第三個(gè)參數(shù)是指定你的seq
uvm_config_db設(shè)置default_sequencer
uvm_config_db#(uvm_object_wrapper)::set(this, "env.i_agt.sqr.main_phase", "default_sequence", case0_sequence::type_id::get());
function void my_case0::build_phase(uvm_phase phase);
case0_sequence my_seq;
super.build_phase(phase);
my_seq = new("my_seq");
uvm_config_db#(uvm_sequence_base)::set(this,
"env.i_agt.sqr.main_phase",
"default_sequence",
my_seq);
endfunction
super.build_phase到一定不能省略臂容。應(yīng)該跟config_db的get/set相關(guān)的源碼有關(guān),后面再具體分析根蟹!https://www.cnblogs.com/xuqing125/p/15761695.html
這兩個(gè)都要包含的信息其實(shí)跟命令行是一樣的E肌!简逮!
方法二:利用seq.start(seqr)顯示啟動(dòng)
前提:如果想用starting_phase的話球散,需要為其指定,不像default_sequencer那樣散庶,start_phase_sequence(phase)里面已經(jīng)調(diào)用了set_starting_phase
-
利用starting_phase來(lái)啟動(dòng)objection:直接調(diào)用seq.start(seqr)
- 或者將
my_seq.starting_phase=phase
替換成my_seq.set_starting_phase
這種寫(xiě)法蕉堰。 -
利用common的objection機(jī)制:直接調(diào)用seq.start(seqr)
參考UVM_UG:
方法三:利用uvm_do_on系列的宏
`uvm_do系列的宏,我們知道這些宏最終都是調(diào)用的uvm_do_on_pri_with的宏悲龟。uvm_do系列的宏是可以在uvm_sequence_base以及其擴(kuò)展類(lèi)中才能調(diào)用的屋讶!
- 當(dāng)?shù)谝粋€(gè)參數(shù)是sequence類(lèi)型的時(shí)候,會(huì)調(diào)用seq.start,也就是能啟動(dòng)seq须教。
- my_seq.start() -> my_seq.body() -> uvm_do(my_seq_0) -> my_seq_0.start() -> my_seq_0.body()
那么這里自然而言皿渗,我就會(huì)想可以在頂層這樣做嗎?
剛剛?cè)胄械臅r(shí)候轻腺,總會(huì)有這些問(wèn)題乐疆,為什么不能這么做的?
首先宏是啥意思约计?在代碼編譯的時(shí)候诀拭,宏會(huì)依次展開(kāi),所以create_item/start_item/finish_item都會(huì)暴露出來(lái)煤蚌,由于你是在uvm_sequencer中調(diào)用的耕挨,根據(jù)擴(kuò)展關(guān)系细卧,是找不到create_item/start_item/finish_item這些東西的啊,同學(xué)M舱肌L懊怼!翰苫!
create_item/start_item/finish_item是在uvm_sequence_base里面定義的止邮。
也就是說(shuō)uvm_do系列的宏是可以在uvm_sequence_base以及其擴(kuò)展類(lèi)中才能調(diào)用的!
小結(jié):從本質(zhì)上講奏窑,seq的啟動(dòng)都是調(diào)用了uvm_squence_base的start函數(shù)导披。
下面簡(jiǎn)單來(lái)看一下;uvm_sequence_base::start(sqr)的源碼:
- 設(shè)置m_sequencer和p_sequencer
- 注冊(cè)m_sequencer和sequence埃唯,將seq_id sqr_id等關(guān)聯(lián)起來(lái)
- pre_start/pre_body/body/post_body/post_start,是一些callback函數(shù)撩匕。
- parent_sequence也有pre_do/mid_do/post_do的callback函數(shù),但這些很不常用墨叛。
- 重點(diǎn)關(guān)注body()的override就行止毕。
- m_sequence_exiting()將sequence從arb_sequence_q[]中刪除。
真正sequence的跟driver交互的東西就是在body()里面實(shí)現(xiàn)的漠趁。