1. starting_phase是什么?作用是什么?
starting_phase是sequence中的一个变量,uvm_phase类型。sequencer自动将phase传给req变量的startiing_phase。(req指向sequencer发送的sequence),starting_phase用来在sequence中控制验证平台的关闭,只有将此要运行的sequence作为sequencer的某动态运行phase的default_sequence时,其starting_phase才不为null。
在demo_seq文件中部分代码如下:
task pre_body()
if(starting_phase != null)
starting_phase.raise_objection(this);
endtask
task post_body()
if(starting_phase != null)
starting_phase.drop_objection(this);
endtask
seq的body函数在sqr的哪个phase启动,那么seq的staring_phase就等于该phase的值,一般来讲,seq是在sqr.main_phase()中启动的,此时seq的starting_phase会被赋值为main;
如下:
在某个testcase中:
function void testcase0::build_phase(uvm_phase phase);
super.build_phase(phase);
mo_seq = demo_seq::type_id::create("mo_seq");
uvm_config_db#(demo_seq)::set(this,"*.master_sequencer.main_phase","default_sequence",mo_seq);
endfunction : build_phase
那么,在demo_seq中:
task demo_seq::pre_body();
super.pre_body();
if(starting_phase!=null) begin
`uvm_info(get_full_name(),$sformatf("starting_phase=%s",staring_phase.get_name),UVM_MEDIUM);
end
else begin
`uvm_info(get_full_name(),$sformatf("starting_phase is null!!!!")
end
endtask
如此,运行后会在demo_seq的pre_body()打印出”staring_phase=main”的信息。
如果不使用default_sequence的方式启动,则uvm不会为starting_phase自动赋值,需要手动添加赋值语句,如下:
class testcase0 extends base_test;
function new(string name = "test_case0", uvm_component parent = null);
super.new(name,parent);
endfunction
`uvm_component_utils(test_case0)
virtual task main_phase(uvm_phase phase);
demo_seq seq0;
seq0 = new("seq0");
seq0.starting_phase = phase; //手动为seq0中的starting_phase赋值
seq0.start(env.i_agt.sqr);
endtask
endclass
以上是在uvm_1.1版本适用,在uvm1.1中采用default_sequence中会自动给starting_phase进行赋值;
但是uvm1.2starting_phase不在推荐使用,即使使用default_sequence,也不会给starting_phase自动赋值,sequence中starting_phase仍然为null。建议使用手动启动seq的方式,手动赋值。
在uvm_1.2中starting_phase不建议使用,但是这个类依旧存在于uvm,如果想要继续使用,可以调用uvm_1.2如下的方法:uvm_sequence_base::set_automatic_phase_objection;在demo_seq中的new()可以添加如下:
function demo_seq::new(string name="demo_seq");
super.new(name);
set_automatic_phase_objection(1);
endfunction : new
当然,也不一定要在new函数中set,只要是在seq启动之前set均可。
但是上述set_automatic_phase_objection的方式个人不推荐使用,因为如果你的平台环境需要在uvm_1.1和uvm_1.2之间来回切换,而在uvm_1.1中并没有这种方法。
所以个人推荐如下方式:
task testcase0::main_phase(uvm_phase phase)
my_seq_type seq = new("seq");
phase.raise_objection(this);//在testcase0.main_phase中提起,控制seq的启动
seq.start(my_sequencer);
phase.drop_objection(this);//在testcase0.main_phase中关闭,控制seq的关闭
endtask
如此,在uvm_1.1和uvm_1.2中都能兼容且安全的启动并且控制objection。
本文主要参考如下文章:
2.UVM中 sequence中的starting_phase_小汪的IC自习室的博客-CSDN博客_starting_phase