在验证中,可能会有如下一个需求。
-
有两个sequencer,各自需要接收一个包。但是接收的包类型不一样。
-
期望环境只有一个sequence,该sequence,同时发送两个包,给对应的两个sequencer
对于这样的需求,如何在uvm中实现了?
对于这个问题,就需要用到如下知识点:
-
virtual sequencer
-
`uvm_do_on宏的使用
首先实现一个virtual sequencer,在这个virtual sequencer中,例化上述所需的sequencer。如下代码所示:
class virtual_sequencer extends uvm_sequencer; `uvm_component_utils(virtual_sequencer) my_sequencer ifu_sqr; // sequencerA my_sequencer lsu_sqr; // sequencerB function new(string name="virtual_sqr", uvm_component parent); super.new(name, parent); endfunction: new endclass: virtual_sequencer
在env的build_phase,例化该sequencer。代码如下所示:
function void my_env::build_phase(uvm_phase phase); // TODO Auto-generated function stub super.build_phase(phase); ifu_agt = my_agent::type_id::create("ifu_agt", this); lsu_agt = my_agent::type_id::create("lsu_agt", this); vir_sqr = virtual_sequencer::type_id::create("vir_sqr", this); // set the sequence uvm_config_db#(uvm_object_wrapper)::set(this, "vir_sqr.main_phase", "default_sequence", my_sequence::type_id::get() ); endfunction : build_phase
在env的connect_phase,连接ifu_sqr,lsu_sqr的实例。代码如下所示:
function void my_env::connect_phase(uvm_pkg::uvm_phase phase); // TODO Auto-generated function stub super.connect_phase(phase); vir_sqr.ifu_sqr = ifu_agt.my_sqr; vir_sqr.lsu_sqr = lsu_agt.my_sqr; endfunction : connect_phase
注意,这里的赋值,不能在env的build_phase中进行。因为在build_phase中,ifu_agt和lsu_agt都没有执行过build_phase函数,内部的结构还没有建立,如果在build_phase中赋值的话,那么vir_sqr.ifu_sqr和vir_sqr.lsu_sqr都是空指针。
在sequence中的body中,实现如下代码:
fork begin // send ifu ifu_trans i_trans; repeat(10) begin i_trans = new(); i_trans.randomize(); `uvm_info("sequence1","begin send i_trans", UVM_LOW) `uvm_do_on(i_trans, p_sequencer.ifu_sqr) `uvm_info("sequence1","after send i_trans", UVM_LOW) end end begin // send lsu lsu_trans l_trans; repeat(10) begin l_trans = new(); l_trans.randomize(); `uvm_info("sequence2","begin send l_trans", UVM_LOW) `uvm_do_on(l_trans, p_sequencer.lsu_sqr) `uvm_info("sequence2","after send l_trans", UVM_LOW) end end join
通过以上的实现,就可以在一个sequence中,发送两个包,每个包发送到对应的 sequencer上。通过使用`uvm_do_on,将transaction,发送到指定的sequencer上。然后通过p_sequencer引用到使用该sequence的sequencer上,然后就可以得到想发送的sequencer。
除了`uvm_do_on这个宏,还有`uvm_do_on_with宏,该宏只是多了一个约束transaction的参数。