文章目录
- 前言
- 浅拷贝(shallow copy)
- 深复制 (deep_copy)
- UVM中实现深复制的方法
前言
本文通过实际代码编译介绍了sv中浅复制和深复制的区别
浅拷贝(shallow copy)
先给出实际代码
module shallow_copy();
class A;
integer j = 5;
endclass
class B;
integer i =1;
A a;
function new();
this.a=new();
endfunction
endclass
B b1,b2;
initial begin
integer test;
b1=new();//创建一个B的对象
b2=new b1;//复制b1对象
b2.i=10;//改变b2中i的值
b2.a.j=50;//改变b2中a.j的值
test=b1.i;
$display( "test is %d",test);
test=b2.i;
$display("test is %d", test);
test=b1.a.j;
$display( "test is %d",test);
end
endmodule
由代码可以看出,我们首先创建了三个类A,B,C,其中,B声明了两个变量,且通过new函数的二次执行,创建了一个新对象b2,它内部的属性均复制自b1中的内容,这种复制方式即浅复制。然后在类B中,又声明了类A的一个变量a,并为其创建对象。
编译仿真结果如下:
可以看到,从b2中改变i的值,并不会影响b1所指的对象空间,相当于复制以后,b2所指的是一个新的对象。但是,当b1中含有对象时,即文中的a,此时通过浅复制并不会复制一个新的对象a出来,因此在b2中改变a.j的值,也会影响b1中a.j的值,所以j变为了50。
示意图如下:
深复制 (deep_copy)
为了实现深度复制,其中每一个数据成员 (包括嵌套的对象)都要被复制,一般情况下需要自定义copy函数。
为前文例子实现深复制的代码如下:
module deep_copy();
class A;
integer j = 5;
endclass
class B;
integer i =1;
A a;
function new();
this.a=new();
endfunction
function B deep_copy();
B b=new();
b.i=this.i;
b.a.j=this.a.j;
return b;
endfunction
endclass
B b1,b2;
initial begin
integer test;
b1=new();
b2=b1.deep_copy;
b2.i=10;
b2.a.j=50;
test=b1.i;
$display( "test is %d",test);
test=b2.i;
$display("test is %d", test);
test=b1.a.j;
$display( "test is %d",test);
test=b2.a.j;
$display( "test is %d",test);
end
endmodule
如上可见,我们自定义了一个deep_copy函数,通过自定义函数,可以实现为类中其他类传递进来的变量创建空间。
仿真结果如下:
可以看到,通过自定义函数deep_copy,b2同意创建了一个对象,b2中改变j的值,不会影响b1中的值,所以b1.a.j和b2.a.j分别为5和50
UVM中实现深复制的方法
通过调用do_copy实现,do_copy方法是由copy方法调用的用户定义钩子函数。派生类应重写此方法以在复制操作中包含其字段。实现必须调用super.do_copy,并且在复制之前必须将rhs参数强制转换为 rhs_ 类型。
do_copy函数的uvm源码如下,使用时需要按照图中方式定义。