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再次分配内存空间。
全部0条评论
快来发表一下你的评论吧 !