无论任何一个对象对数据进行了修改,整个测试环境看到的数据都会变化。因此引入了MOOCOW(Manual Obligatory Object Copy On Write)机制,如果我们希望对transaction中的数据进行操作就需要强制拷贝一个备份,并在自己的世界里进行修改。
function string convert2string();
string s;
s = $sformatf("A: %2h B: %2h op: %s",
A, B, op.name());
return s;
endfunction : convert2string
uvm_object类和其子类都包含copy()函数和clone()函数,其中copy函数拷贝一个对象的数据至另一个同类型对象,clone函数返回数据完全一致的同类型的对象;copy是将数据拷贝一份,clone是返回一个新的对象。???还是有疑问,两种是否共享内存空间
function void do_copy(uvm_object rhs);
command_transaction copied_transaction_h;
if(rhs == null)
`uvm_fatal("COMMAND TRANSACTION", "Tried to copy from a null pointer")
if(!$cast(copied_transaction_h,rhs))
`uvm_fatal("COMMAND TRANSACTION", "Tried to copy wrong type.")
super.do_copy(rhs); // copy all parent class data
A = copied_transaction_h.A;
B = copied_transaction_h.B;
op = copied_transaction_h.op;
endfunction : do_copy
function command_transaction clone_me();
command_transaction clone;
uvm_object tmp;
tmp = this.clone(); //通过clone函数,我们得到的是一个新的对象,具有独立的存储空间
$cast(clone, tmp);
return clone; //函数的返回值是新的对象,和this具有不同的存储空间,但是包含完全一致的数据
endfunction : clone_me
class add_test extends random_test;
`uvm_component_utils(add_test);
function void build_phase(uvm_phase phase);
command_transaction::type_id::set_type_override(add_transaction::get_type());
super.build_phase(phase);
endfunction : build_phase
function new (string name, uvm_component parent);
super.new(name,parent);
endfunction : new
endclass
function uvm_object_wrapper uvm_object::get_type();
uvm_report_error("NOTYPID", "get_type not implemented in derived class.", UVM_NONE);
return null;
endfunction
uvm_config_db #(uvm_object_wrapper)::set(this, "m_env.rst_agent.rst_seqr.reset_phase", "default_sequence", reset_sequence::get_type() );
typedef class uvm_report_object;
typedef class uvm_object_wrapper; //uvm_object_wrapper=class
typedef class uvm_objection;
typedef class uvm_component;
typedef bit[31:0] uint;
uvm_object.sv中对于clone的定义
// clone
// -----
function uvm_object uvm_object::clone();
uvm_object tmp;
tmp = this.create(get_name());
if(tmp == null)
uvm_report_warning("CRFLD", $sformatf("The create method failed for %s, object cannot be cloned", get_name()), UVM_NONE);
else
tmp.copy(this);
return(tmp);
endfunction
这个用法经常在driver/monitor中使用;
这里的rsp和req都是item;
class my_driver extends uvm_driver
...
task run_phase(uvm_phase phase)
seq_item_port.try_next_item(req);
$cast(rsp, req.clone()) //把req.clone()然后给rsp,这样rsp和req就是独立的了;
endtask
【数字IC前端】UVM常见问题系列
create()方法用于构造一个对象。
copy()方法用于将一个对象复制到另一个对象。
clone()方法同时完成对象的创建和复制。
SV中的shallow copy 和 deep
如果在SV中要deep copy的话,就得为所有包含的类都准备好copy函数,既容易出错,工作量又大。好消息是UVM已经内建了copy以及clone操作,可以将你从手写copy中解放出来,我们会在后续的文章中讲解其中的细节,
参考:
The uvm primer ch21
sv copy