1、seq相關的phase機制
首先你需明確的是UVM的框架下,消耗時間的task的執行都在在uvm_component底下的objection的機制來實現的。也就是說phase的機制跟uvm_component是緊密相關的。
uvm_sequence是一個uvm_object的類,uvm_sequencer是一個uvm_component的類。
seq需要掛載在seqr上執行。
run_time_phase.svh
在前面我們講過UVM_PHASE的機制,在execute函數的地方有對uvm_sequencer_base類型的做處理。
- start_phase_sequence(phase):處理default_sequencer
- 這里先做個遺留,到底這里是什么從外面獲得default_sequencer的。
方法一:利用default_sequence啟動seq
也只有在用default_sequence的方式啟動seq的時候,start_phase != null,原因是如果是sqr的時候在uvm_task_phase.svh里面有介紹,會自己調用start_phase_sequence,里面會對seq.set_starting_phase(phase);進行set。
前提
對應uvm1.2版本,
或者是my_seq.set_automatic_phase_objection(1);
在start_phase_sequence里面已經指定了phase,seq.set_starting_phase(phase);
命令行設置default_sequencer:
+UVM_SET_DEFAULT_SEQUENCE=uvm_test_top.env.i_agt.sqr,main_phase,case0_sequence
- 第一個參數是指定seqr的路徑
- 第二個參數是指定要執行的phase階段
- 第三個參數是指定你的seq
uvm_config_db設置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到一定不能省略。應該跟config_db的get/set相關的源碼有關,后面再具體分析!https://www.cnblogs.com/xuqing125/p/15761695.html
-
這兩個都要包含的信息其實跟命令行是一樣的!!!
方法二:利用seq.start(seqr)顯示啟動
前提:如果想用starting_phase的話,需要為其指定,不像default_sequencer那樣,start_phase_sequence(phase)里面已經調用了set_starting_phase
- 利用starting_phase來啟動objection:直接調用seq.start(seqr)
- 或者將
my_seq.starting_phase=phase
替換成my_seq.set_starting_phase
這種寫法。 - 利用common的objection機制:直接調用seq.start(seqr)
參考UVM_UG:
方法三:利用uvm_do_on系列的宏
`uvm_do系列的宏,我們知道這些宏最終都是調用的uvm_do_on_pri_with的宏。uvm_do系列的宏是可以在uvm_sequence_base以及其擴展類中才能調用的!
- 當第一個參數是sequence類型的時候,會調用seq.start,也就是能啟動seq。
- my_seq.start() -> my_seq.body() -> uvm_do(my_seq_0) -> my_seq_0.start() -> my_seq_0.body()
那么這里自然而言,我就會想可以在頂層這樣做嗎?
剛剛入行的時候,總會有這些問題,為什么不能這么做的?
首先宏是啥意思?在代碼編譯的時候,宏會依次展開,所以create_item/start_item/finish_item都會暴露出來,由於你是在uvm_sequencer中調用的,根據擴展關系,是找不到create_item/start_item/finish_item這些東西的啊,同學!!!!
create_item/start_item/finish_item是在uvm_sequence_base里面定義的。
也就是說uvm_do系列的宏是可以在uvm_sequence_base以及其擴展類中才能調用的!
小結:從本質上講,seq的啟動都是調用了uvm_squence_base的start函數。
下面簡單來看一下;uvm_sequence_base::start(sqr)的源碼:
- 設置m_sequencer和p_sequencer
- 注冊m_sequencer和sequence,將seq_id sqr_id等關聯起來
- pre_start/pre_body/body/post_body/post_start,是一些callback函數。
- parent_sequence也有pre_do/mid_do/post_do的callback函數,但這些很不常用。
- 重點關注body()的override就行。
- m_sequence_exiting()將sequence從arb_sequence_q[]中刪除。
真正sequence的跟driver交互的東西就是在body()里面實現的。