I've been confused for a while about how copy and clone method works in UVM.
The confusion is about whether clone = create+deep copy?
In my code, when I used clone method, it was not deep copy by default. I've to explicitly write do_copy method.
Today I spent some time to explore about it and found the answer.
Please note that if you implement do_copy in your derived object, clone will have deep copy else it only copies the fields mentioned in `uvm_object_utils*.
Here is the mimicking behavior of copy and clone method of UVM
The confusion is about whether clone = create+deep copy?
In my code, when I used clone method, it was not deep copy by default. I've to explicitly write do_copy method.
Today I spent some time to explore about it and found the answer.
Please note that if you implement do_copy in your derived object, clone will have deep copy else it only copies the fields mentioned in `uvm_object_utils*.
Here is the mimicking behavior of copy and clone method of UVM
typedef base_class; typedef derived_class; function base_class create(); derived_class tmp; tmp = new(); return tmp; endfunction class base_class; int A = 7; virtual function do_copy(base_class rhs); endfunction virtual function copy(base_class rhs); do_copy(rhs); endfunction virtual function base_class clone(); base_class base; base = create(); base.copy(this); return (base); endfunction endclass class derived_class extends base_class; int A = 5; function do_copy(base_class rhs); derived_class derived; $cast(derived,rhs); super.do_copy(rhs); A = derived.A; endfunction endclass module test(); derived_class d1,d2,d3; initial begin d1 = new(); d1.A = 10; d3 = new(); d3.copy(d1); $cast(d2,d1.clone()); $display("A in d1 is %0d",d1.A); $display("A in d2 is %0d",d2.A); $display("A in d3 is %0d",d3.A); d1.A = 20; $display("A in d1 is %0d",d1.A); $display("A in d2 is %0d",d2.A); $display("A in d3 is %0d",d3.A); endendmodule
Output :
A in d1 is 10 A in d2 is 10 A in d3 is 10 A in d1 is 20 A in d2 is 10A in d3 is 10
There are two function used here copy and clone.copy : d3.copy(d1); which is simply deep copy of d1 to d3. It works as below.1. d3 calls copy function which is defined in base_class.
2. copy function calls do_copy, as do_copy is virtual method, always latest definition of function will be executed. There is only one implementation of a virtual method per class hierarchy, and it is always the one in the latest derived class. So do_copy from "derived class" will be called.clone : $cast(d2,d1.clone()); This method works as below.1. d1.clone() calls definition of clone from base class.
2. clone calls create method which, returns handle of type derived_class.
3. A child class handle can be directly assign to base class.
4. base.copy(this); This is basically deep copy of this(here d1) to base.5. So clone method return class variable of type "base_class" which we need to cast in derived_class, then only we can access member of class.
If you have noticed, here there is one dilemma.
base.copy(this); calls copy function from base class , which call do_copy of derived class. So in turn do_copy is called from handle of object of type base_class. So how in do_copy it can access variable A, since it is not defined in base_class.Reason is that "A" is being used by do_copy function which is in derived class. So context of A will be derived_class.
No comments:
Post a Comment