目录
1.概述
为什么要有sequence机制,要将数据输入到平台中怎么输入sequence,sequence,sequencer,driver之间的通信过程又是如何?
首先,无论是sequence还是driver,它们的通话对象都是sequencer。当多个sequence试图挂载到一个sequencer上时,涉及sequencer的仲裁功能,之后会详谈,先略过。重点分析sequencer作为sequence和driver之间的握手桥梁,是如何扮演这个角色的。如图所示
对于sequence而言,无论是flat sequence还是hierarchical sequence,进一步切分的话,流向sequencer的都是sequence item,所以就每个item的成长周期来看,它起始于creat_item(),继而通过start_item()尝试从sequencer获取可以通过的权限。
对于sequencer的仲裁机制和使用方法先略过,而driver一侧一直处于"吃不饱"状态,如果它没有item可以使用,则使用get_next_item()来尝试从sequencer一侧来获取item。
sequencer将通过权限交给某一个sequence前,目标sequence中的item应完成随机化,继而在获取sequencer通过权限之后执行finish_item()。
接下来sequence中的item将通过sequencer到达driver一侧
driver得到新的item后,会提取有效的数据信息,将其驱动到与DUT连接的接口上
完成驱动后,driver应该通过item_done()来告知sequence已完成了数据传送,sequence在获取消息之后,则表示driver与sequence双方完成了这一次的item握手传输。
2.sequence
2.1sequence的启动与执行
举例:一个常见的sequence应包含body()任务,当一个sequence启动后会自动调用body任务
class sequence1 extends uvm_sequence #(my_transaction);
...
virutal task pre_body();
...
endtask
virtual task body();
...
//发送数据
endtask
virtual task post_body();
...
endtask
`uvm_object_utils(sequence1)
endclass
有两种方式可以启动sequence,直接启动(利用start任务),和间接启动(利用default_sequence启动)
sequence1 my_seq;
my_seq=sequence1::type_id::creat("my_seq");
my_seq.start(sequencer);//直接启动
uvm_config_db#(uvm_object_wrapper)::set(this,"env.i_agt.sqr.main_phase",/
"defult_sequence",sequence1::type_id::get());//间接启动
2.2sequence相关宏
1)uvm_do系