[UVM] uvm_create与type_id::create

最近有遇到以下场景:
在sequence中do item 的方法如下,而不是直接用uvm_do:

req = packet::type_id::create("req");
req.randomize();
`uvm_send;

在test中调用set_inst_override_by_type把sequence中的req override;但最终并没有override 成功;如果用uvm_do就可以override;我trace了一下source code发现:

create(object)

static function T create (string        name  = "",
                          uvm_component parent= null,
                          string        contxt= "");
    uvm_object obj;
    uvm_factory f = uvm_factory::get();
    if (contxt == "" && parent != null)//在component背景下可以获取component的hierarchy,无需user传入contxt
      contxt = parent.get_full_name();
    obj = f.create_object_by_type(get(),contxt,name);
    if (!$cast(create, obj)) begin
      string msg;
      msg = {"Factory did not return an object of type '",type_name,
        "'. A component of type '",obj == null ? "null" : obj.get_type_name(),
        "' was returned instead. Name=",name," Parent=",
        parent==null?"null":parent.get_type_name()," contxt=",contxt};
      uvm_report_fatal("FCTTYP", msg, UVM_NONE);
    end
  endfunction

function uvm_object uvm_factory::create_object_by_type (uvm_object_wrapper requested_type,  
                                                        string parent_inst_path="",  
                                                        string name=""); 

  string full_inst_path;

  if (parent_inst_path == "")
    full_inst_path = name;
  else if (name != "")
    full_inst_path = {parent_inst_path,".",name};
  else
    full_inst_path = parent_inst_path;

  m_override_info.delete();

  requested_type = find_override_by_type(requested_type, full_inst_path);

  return requested_type.create_object(name);

endfunction

从create function中看到第三个参数contxt,会传递给create_object_by_type的第二个参数parent_inst_path,而parent_inst_path又会组成full_inst_path用于override找到对应的hierarchy。
但我在用create的时候只传进去一个参数,contxt没有传为null;所以override失败。应该写成下面这样:

req = packet::type_id::create("req",,this.get_full_name());

uvm_create

`define uvm_create_on(SEQ_OR_ITEM, SEQR) \
  begin \
  uvm_object_wrapper w_; \
  w_ = SEQ_OR_ITEM.get_type(); \
  $cast(SEQ_OR_ITEM , create_item(w_, SEQR, `"SEQ_OR_ITEM`"));\
  end

protected function uvm_sequence_item create_item(uvm_object_wrapper type_var, 
                                                   uvm_sequencer_base l_sequencer, string name);

    uvm_factory f_ = uvm_factory::get();
    $cast(create_item,  f_.create_object_by_type( type_var, this.get_full_name(), name ));

    create_item.set_item_context(this, l_sequencer);
  endfunction

uvm_create 实际是调用uvm_create_on,uvm_create_on又会调用create_item; create_item在调用create_object_by_type时把this.get_full_name()传给parent_inst_path,从而可以成功override;

summary

当object 需要inst override
1. 直接使用uvm_do ,uvm_create;
2. 若使用create,注意:如在object背景下则需要把第三个参数contxt 传入object的hierarchy,比如在sequence中do item;在component背景下则不需要。

当component需要inst override
使用uvm_do,uvm_create,create均可,且使用create无需传入第三个参数;

其他方面两者是一样的~~~

猜你喜欢

转载自blog.csdn.net/lbt_dvshare/article/details/81386918
今日推荐