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条评论
快来发表一下你的评论吧 !