文章目录
sequence介绍
本文代码参考自《UVM实战》
sequence不属于验证平台的任何一部分,它与sequencer之间有密切的联系。sequence中封装着激励数据transaction,是一个uvm_object,使用uvm_object_utils宏注册到factory中。而sequencer是一个uvm_component。每一个sequence都应该派生自uvm_sequence,并且在定义时指定要产生的transaction的类型,这里是my_transaction。每一个sequence都有一个body任务,当一个sequence启动之后,会自动执行body中的代码。
sequence 向sequencer发送transaction
`uvm_do方式发送
`uvm_do宏是UVM中的一个常用宏,它的作用是:1. 创建一个transaction的实例;2. 随机化此实例;3. 将其发送给sequencer
直接发送
通过start_item和finish_item来产生transaction,随机化过程可以放在start_item和finish_item中。如下所示:
virtual task body();
…
13 repeat (10) begin
14 tr = new("tr");
15 assert(tr.randomize() with {tr.pload.size == 200;});
16 start_item(tr);
17 finish_item(tr);
18 end
启动方式
1. 通过start启动
start任务的参数是一个sequencer指针,如果不指明此指针,则sequence不知道将产生的transaction交给哪个sequencer。同时,在启动sequence的时候需要注意提起和撤销objection。
task my_sequencer::main_phase(uvm_phase phase);
my_sequence seq;
phase.raise_objection(this);
seq = my_sequence::type_id::create("seq");
seq.start(this);
phase.drop_objection(this);
endtask
2. 使用default_sequence
在test或者env组件中的build_phase设置如下代码即可:
virtual function void build_phase(uvm_phase phase);
20 super.build_phase(phase);
…
30 uvm_config_db#(uvm_object_wrapper)::set(this,
31 "i_agt.sqr.main_phase",
32 "default_sequence",
33 my_sequence::type_id::get());
34
35 endfunction
set中第二个参数为相对于第一个参数的相对路径,由于上述代码第一个参数被设置为了this,所以第二个参数中就不需要uvm_test_top了。
如在top_tb中启动的话,set中路径就应该为
uvm_config_db#(uvm_object_wrapper)::set(null,//top_tb不是一个类,不能使用this指针
"uvm_test_top.i_agt.sqr.main_phase",
"default_sequence",
my_sequence::type_id::get());
在default_sequence中提起objection的方法是通过starting_phase,它的类型是uvm_phase。
virtual task body();
12 if(starting_phase != null)
13 starting_phase.raise_objection(this);
14 repeat (10) begin
15 `uvm_do(m_trans)
16 end
17 #1000;
18 if(starting_phase != null)
19 starting_phase.drop_objection(this);