最近有遇到以下场景:
在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无需传入第三个参数;
其他方面两者是一样的~~~