UVM has provided field automation mechanism, UVM can use built-in functions, such as print, clone, copy ...., today to talk about my problems with the copy function.
class cfg1 extends uvm_object;
int id;
....
endclass
===============================================================
class cfg2 extends uvm_object;
int id;
cfg1 sub_cfg;
function new(string name = "cfg");
super.new(name);
sub_cfg = cfg1::type_id::create("sub_cfg");
endfunction
endclass
===============================================================
class ref extends uvm_component;
...
cfg2 o_cfg;
cfg1 s_cfg;
virtual function void build_phase(uvm_phase phase)
super.build_phase(phase);
if(!uvm_config_db#(cfg2)::get(this,$sformatf("o_cfg2"),"cfg",o_cfg))
`uvm_fatal(...)
s_cfg = o_cfg.sub_cfg;//保存了sub_cfg的handle
endfunction
endclass
The class cfg2 embodiment comprises a variable int and a cfg1 the object, if the updated CFG2 run_phase copy function call:
o_cfg_ary = cfg2::type_id::create("o_cfg_ary");
o_cfg_ary.sub_cfg.id = 2;
o_cfg.copy(o_cfg_ary);
After o_cfg update, ref still get the original value! ! ! !
root cause:
copy function is a deep copy , so the object cfg2 in the copying sub_cfg reallocate memory space, i.e., handle address changes.
PS: Copy function copies only use field automation registered variables and Object .
In general build_phase using Config_db transfer handle , once passed on, if the middle handle changes, in above example would want to use copy function change ID (guaranteed handle address change, only update content) , but o_cfg .sub_cfg the handle address generating change, and the ref holds sub_cfg handle the address resulting in the need to obtain handle of the class get to the handle is still pointing to the original memory space .
1. If the ref is employed by sub_cfg o_cfg.sub_cfg.id, copy function does not influence (even o_cfg.sub_cfg the handle does not affect the change of the address );
2. If the ref in "s_cfg = o_cfg.sub_cfg" saved sub_cfg handle the address , but o_cfg.sub_cfg the handle address changes, sub_cfg can not point to the newly allocated space, will not get the value after the update;
solution:
o_cfg_ary = cfg2::type_id::create("o_cfg_ary");
o_cfg_ary.sub_cfg.id = 2;
o_cfg.copy(o_cfg_ary);
o_cfg.sub_cfg.copy(o_cfg_ary.sub_cfg);//递归调用copy函数