1、virtual sequence
当多个sequence需要同步执行时,实现sequence之间同步的最好的方式就是使用virtual sequence。虚拟的sequence。 虚拟的意思就是它不发送transaction, 它只是控制其他的sequence, 起统一调度的作用。
1.1vritual sequencer
为了使用virtual sequence, 一般需要一个virtual sequencer。 virtual sequencer里面包含指向其他真实sequencer的指针。
代码实现:
class my_vsqr extends uvm_sequencer;
`uvm_compoent_utils(my_vsqr) //注册
my_sequencer p_sqr0;//实例化与真实的sequencer相对应的句柄
my_sequencer p_sqr1;
...
function new(string name,uvm_component parent);
super.new(name);
endfunction
endclass
1.2vritual sequence
class vritual_seq extends uvm_sequence;
`uvm_object_utils(vritual_seq)
`uvm_declare_p_sequencer(my_vsqr)//声明一个p_sequencer句柄,使得可以调用vritual sequencer中的变量。
…
virtual task body();//在body函数中处理sequence
my_transaction tr;
drv0_seq seq0;
drv1_seq seq1;
…
`uvm_do_on_with(tr, p_sequencer.p_sqr0, {tr.pload.size == 1500;})//先发一个长数据包
`uvm_info("vseq", "send one longest packet on p_sequencer.p_sqr0", UVM_MEDIUM)
fork//同时发送两个随机数据包
`uvm_do_on(seq0, p_sequencer.p_sqr0);
`uvm_do_on(seq1, p_sequencer.p_sqr1);
join
…
endtask
endclass
1.3test中的设置
class base_test extends uvm_test;
my_env env0;
my_env env1;
my_vsqr v_sqr;
…
endclass
function void base_test::build_phase(uvm_phase phase);
super.build_phase(phase);
env0 = my_env::type_id::create("env0", this);
env1 = my_env::type_id::create("env1", this);
v_sqr = my_vsqr::type_id::create("v_sqr", this);
endfunction
function void base_test::connect_phase(uvm_phase phase);
v_sqr.p_sqr0 = env0.i_agt.sqr;//实际sequencer和虚sequencer建立连接
v_sqr.p_sqr1 = env1.i_agt.sqr;//上同
endfunction
和启动sequence方法一样,有两种方式
第一种,在test的build_phase阶段config_db配置
1//test.sv
uvm_config_db#(uvm_object_wrapper)::set(this,"*v_seqr.main_phase","default_sequence", v_seq::get_type());
第二种方法手动启动sequence,调用start()函数
2//test.sv
virtual task run_phase(uvm_phase phase);
my_sequence v_seq;
phase.raise_objection(this);//raise objection
v_seq = vritual_sequence::type_id::create("v_seq");//实例化sequence
v_seq.start(m_env.v_seqr);//指定vritual_sequencer
phase.drop_objection(this);
endtask