SystemVerilog中的Shallow Copy

描述

SystemVerilog中的句柄赋值对象复制的概念是有区别的。

 

PCI p1;
p1 = new;
PCI p2;
p2 = p1; //class assignment

 

经过上面的代码执行后,“p1”和 “p2” 最终指向的还是同一个内存空间,也就是说他们指向的是同一个对象实例。

如果你希望将p1的内容原封不同地复制到p2,他们就得是两个不同的对象实例,即指向不同的内存空间。

 

 PCI p1;
 p1 = new;
 PCI p2;
 p2 = new p1; //shallow copy

 

在上面的例子中,“p2”是一个新的对象实例,其中所有属性值都复制自“p1.”

这在概念上称为“shallow copy”,这是相对于“deep copy”而言的,具体的区别我们后面的文章会介绍。

shallow copy会复制对象中所有的属性,包括类中其他的对象句柄,注意只能复制类中的对象句柄,而不能复制类中其他的对象实例。

代码

在上图中,我们声明了一个类“PCI” 和2个类句柄“p1” 和“p2”。 

我们实例化“p1”,如上图所示分配的物理地址空间是0xffff,属性addr和data的初始值都是0。

然后别分别赋值addr为‘h12,data为‘h56。

shallow copy p1到p2,会分配一个新的物理地址空间0xf0f0。并且将p1中的“addr”和“data”复制给p2。

 

p2 = new p1;

 

我们改变p2中addr为34,data为78。因为是不同的对象实例,所以p2不会影响到p1。

假如我们想要复制的类中还有一个类对象,情况会怎样?

 

module class_TOP( );
 class PCIChild;
 logic [7:0] burstC;
 function new (logic [7:0] burst);
 burstC = burst;
 endfunction
 endclass : PCIChild
 
 class PCITop;
 logic [31:0] addrTop;
 logic [31:0] dataTop;
 PCIChild PCIc;
 task PCIM(logic [31:0] addr, logic [31:0] data, logic 
[7:0] burst);
 PCIc = new(burst); //instantiate PCIc
 addrTop = addr;
 dataTop = data;
 endtask
 
 function void disp (string instName);
 $display("[%s] addr = %h data = %h burst=%h", instName, 
addrTop, dataTop, PCIc.burstC);
 endfunction
 
 endclass : PCITop
 
 PCITop PCI1, PCI2;
 
 initial begin;
 PCI1 = new;
 PCI1.PCIM(32'h 0000_00f, 32'h f0f0_f0f0, 8'h12);
 PCI1.disp("PCI1");
 PCI2 = new PCI1; //Shallow copy of PCI1 into PCI2
 PCI2.disp("PCI2"); //copied content displayed
 PCI2.addrTop = 32'h1234_5678;
 PCI2.dataTop = 32'h5678_abcd;
 PCI2.PCIc.burstC = 8'h 9a;
 PCI2.disp("PCI2");
 PCI1.disp("PCI1");
 end
 endmodule

 

仿真log:

 

[PCI1] addr = 000000ff data = f0f0f0f0 burst=12
[PCI2] addr = 000000ff data = f0f0f0f0 burst=12
[PCI2] addr = 12345678 data = 5678abcd burst=9a
[PCI1] addr = 000000ff data = f0f0f0f0 burst=9a
 V C S S i m u l a t i o n R e p o r t

 

在上面的例子中,我们声明了一个名为PCIChild的类,其中含有属性“burstC”。
我们还声明了一个叫做PCITop的类,它有两个属性“addrTop”和“dataTop”。

我们在类PCITop中声明类型为PCIChild的变量PCIc并在任务“PCIM”中实例化。

因此,PCIc现在拥有一个PCIChild类型的对象句柄。

后面我们声明两个类型为PCITop的变量“PCI1”和“PCI2”,并实例化PCI1。然后我们将PCI1的shallow copy到PCI2中(PCI2 = new PCI1;)。

在打印的log中我们可以发现PCI2中“addrTop”和“dataTop”修改不会反映到PCI1,而对PCI2中对象PCIc的修改会反映到PCI1。

 

PCI2.PCIc.burstC = 8'h 9a;

 

这是因为shallow copy只复制了类中的对象句柄,而没有为对象PCI2.PCIc再次分配内存空间。

  审核编辑:汤梓红
 
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分