浅拷贝可以使用列表自带的copy()函数(如list.copy()),或者使用copy模块的copy()函数。深拷贝只能使用copy模块的deep copy(),所以使用前要导入:from copy import deepcopy
如果拷贝的对象里的元素只有值,没有引用,那浅拷贝和深拷贝没有差别,都会将原有对象复制一份,产生一个新对象,对新对象里的值进行修改不会影响原有对象,新对象和原对象完全分离开。
如果拷贝的对象里的元素包含引用(像一个列表里储存着另一个列表,存的就是另一个列表的引用),那浅拷贝和深拷贝是不同的,浅拷贝虽然将原有对象复制一份,但是依然保存的是引用,所以对新对象里的引用里的值进行修改,依然会改变原对象里的列表的值,新对象和原对象完全分离开并没有完全分离开。而深拷贝则不同,它会将原对象里的引用也新创建一个,即新建一个列表,然后放的是新列表的引用,这样就可以将新对象和原对象完全分离开。
在SV中经常用到的copy主要有三种:句柄copy,深copy和浅copy;
句柄复制
只复制句柄,相当于两个句柄指向同一个对象,永远都只有一个对象。
handle copy 代码:
- class A;
- int j=5;
- endclass
-
- class B;
- int i=3;
- A a=new;
- endclass
-
- program example;
- initial begin
- B b1=new;
- B b2;//重点注意句柄的声明必须都在前面,new可以在任意位置
- b1.i=11;
- b1.a.j=22;
- $display("====b1 initialization====");
- $display("i=%0d",b1.i);
- $display("j=%0d",b1.a.j);
-
- b2=new;
- b2.i=33;
- b2.a.j=44;
- $display("====b1 initialization====");
- $display("i=%0d",b2.i);
- $display("j=%0d",b2.a.j);
-
- b2=b1;
- $display("====b2 copy b1 handle====");
- $display("i=%0d",b2.i);
- $display("j=%0d",b2.a.j);
-
- end
- endprogram
handle copy 仿真结果:

b2 copy b1的句柄 ,两个句柄都指向b1的对象,所显示的内容是一样的。
=================================================================
浅拷贝:
浅拷贝时,只copy成员变量的句柄,而不会拷贝句柄所指向的对象中的内容;
shallow copy代码:
- class A;
- int j=5;
- endclass
-
- class B;
- int i=3;
- A a=new;
- endclass
- //shallow copy
- program example;
- initial begin
- B b1=new;
- B b2;//重点注意句柄的声明必须都在前面,new可以在任意位置
- b1.i=11;
- b1.a.j=22;
- $display("====b1 initialization====");
- $display("i=%0d",b1.i);
- $display("j=%0d",b1.a.j);
-
- b2=new b1;
- b2.i=33;
- b2.a.j=44;
- $display("====b2 shallow copy b1====");
- $display("i=%0d",b1.i);
- $display("j=%0d",b1.a.j);
- $display("i=%0d",b2.i);
- $display("j=%0d",b2.a.j);
-
- end
- endprogram
shallow copy 仿真结果:
很明显,更改了b2句柄指向的B中的i,和b2句柄指向的B中a句柄指向的对象的元素j。
最后b1中的i没有发生任何变化。但是b1对象a的j也跟着b2变化。
===============================================================
深拷贝
深拷贝时,不仅仅会拷贝当前的对象的成员变量,还会拷贝实例中的句柄的对象内容,即进行深层次的复制
deep copy 代码:
- class A;
- int j=5;
- endclass
-
- class B;
- int i=3;
- A a=new;
-
- function deep_copy(B temp);
- this.i=temp.i;
- this.a.j=temp.a.j;
- endfunction
- endclass
- //deep copy
- program example;
- initial begin
- B b1=new;
- B b2=new;//重点注意句柄的声明必须都在前面,new可以在任意位置
- b1.i=11;
- b1.a.j=22;
- $display("====b1 initialization====");
- $display("i=%0d",b1.i);
- $display("j=%0d",b1.a.j);
-
- b2.deep_copy(b1) ;
- b2.i=33;
- b2.a.j=44;
- $display("====b2 deep copy b1====");
- $display("i=%0d",b1.i);
- $display("j=%0d",b1.a.j);
- $display("i=%0d",b2.i);
- $display("j=%0d",b2.a.j);
-
- end
- endprogram
deep copy仿真结果:

深拷贝需要自己定义
更改了b2句柄指向的B中的i,和b2句柄指向的B中a句柄指向的对象的元素j。
最后b1中的i和b1对象a的j没有发生任何变化。