sv中句柄复制,浅拷贝深拷贝详解以及clone函数

目录

一、sv中类,声明,例化,初始化的概念

二、类的句柄复制

三、类的浅拷贝

四、类的深拷贝

 五、 clone函数

今天在写验证环境的时候碰到一处自定义的copy函数,对其中的transaction哪里需要初始化理解出现偏差,因此查看整理了sv中关于对象得赋值以及copy的各种操作,总结如下

一、sv中类,声明,例化,初始化的概念

  • 首先在sv中你可以创建一个class类,类中可以含有变量以及方法,也可以引用别的class类;
  • 类需要声明和例化才能正常使用该类对应的对象,声明是声明一个变量,其中保存类对象的句柄。
  • 例化是通过构造函数,创建对象,分配内存空间,并将声明的句柄指向这段内存空间。
  • 初始化主要指的是一些变量,数组的初始化

二、类的句柄复制

类在声明时只是指定了一个指针句柄给变量,因此此时没有实体对象,当句柄指向另一个句柄指向的对象时,便构成了句柄复制,此时并未创建实体对象,举例代码如下

class a;
    bit a = 1;
endclass

class b;
    a a_1;
    bit b = 0;
endclass

b b_1 b_2;
initial begin
    b_1 = new();
    b_2 = b_1; //此时b_2未创建对象,指向b_1对象,b_2中只能看到b_1中变量b,而且b_1改变 b_2也随 
                之改变,因为他们指的是同一个对象 
    b_1.b = 1;
    $display("b_2.b = %0d,b_2.a_1.a = %0d",b_2.b,b_2.a_1.a);

end

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
result:b_2.b = 1,b_2.a_1.a = 1             


三、类的浅拷贝

深拷贝和浅拷贝都是指拷贝一个对象,而不是句柄复制中的句柄。浅拷贝时,只会拷贝对象中的 成员变量句柄,而不会拷贝句柄所指向的对象中的内容;深拷贝时,不仅仅会拷贝当前对象的成员变量,还会拷贝实例中的句柄的对象内容,即进行深层次的复制直接代码举例:

module tb;
class trans1;
    int A = 1,B = 2;
 endclass
  
 class trans2;
    int A1 = 3,B1 = 4;
    trans1 a = new(); // trans2 里边套一个trans1
endclass
 
 initial begin
    trans2 b = new();
   // 浅拷贝 
    trans2 d = new b; // d浅拷贝b,只会拷贝b中的变量和a的句柄。
    d.A1 = 23;        // 更改d句柄指向的trans中的元素
    d.a.A = 21;       // 更改d句柄指向的trans中a句柄指向的对象的元素
    #20;
    $display("d.A1 = %0d , d.a.A = %0d",d.A1,d.a.A);
    $display("b.A1 = %0d , b.a.A = %0d",b.A1,b.a.A);
  end 
endmodule
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
results:d.A1 = 23 ,d.a.A = 21   b.A1 = 3 , b.a.A = 21

可以看到,得出以下结论:

  • 浅拷贝创建了另一个对象,类中的数据都被复制放到另一个对象中,与原来对象无关
  • 而类中的引用并没有创建新对象,两个引用类的句柄指向同一个对象,共享改变

四、类的深拷贝

深拷贝需要自己定义copy方法并调用

class Transaction;
      bit [31:0] addr,crc,data[8];
      statistics stats;
      static int count=0;
      int id;

      function new;
           stats=new();
           id=count++;
      endfunction

      function Transaction copy;
          copy=new();
          copy.addr=addr;
          copy.data=data;
          copy.crc=crc;
          copy.stats=stats.copy();
          id=count++;
      endfunction
endclass 

Transaction src,dst;
   initial begin
     src=new();
     src.stats.startT=42;
     dst=src.copy();
     dst.stats.startT=96;
     $display(src.stats.startT);
   end

 五、 clone函数

注意:类的多态,父类和子类同名函数必须保持(函数名一致,参数类型一致,返回类型一致)。

父类clone()是产生一个父类对象,子类clone()产生一个子类对象。

父类与子类clone()的返回值都是父类句柄!因此有时需要$cast()

  class trans;
    bit[31:0] data[];
    int pkt_id;
    int data_nidles;
    int pkt_nidles;
    bit rsp;
 
    function trans clone(trans t = null);  //传进来的都是父类句柄
      if(t == null)   t = new();
      t.data = data;
      t.pkt_id = pkt_id;
      t.data_nidles = data_nidles;
      t.pkt_nidles = pkt_nidles;
      t.rsp = rsp;
      return t;
    endfunction
  endclass
  class chnl_trans extends trans;
    int ch_id; // new member in child class
 
 
//clone function-1
    function trans clone(trans t = null); //传进来的都是父类句柄
      chnl_trans ct;
      if(t == null) 
        ct = new();
      else
        void'($cast(ct, t)); //为了父类句柄指向子类对象,将父类句柄转化为子类句柄
      ct.data = data;
      ct.pkt_id = pkt_id;
      ct.data_nidles = data_nidles;
      ct.pkt_nidles = pkt_nidles;
      ct.rsp = rsp;
      ct.ch_id = ch_id; // new member
      return ct;
 initial begin: member_override
    trans t1, t2;
    chnl_trans ct1, ct2;
    wait(b_member_override == 1); $display("b_member_override process block started");
    ct1 = new();
    ct1.pkt_id = 200;
    ct1.ch_id = 2;
    // t1 pointed to ct1's trans class data base t1-->ct1
    t1 = ct1;
 
    // t2 copied ct1's trans class data base t2--->ct1返回的子类
    t2 = ct1.clone();
    void'($cast(ct2, t2));//ct2 --->t2--->ct1返回的子类
    $display("hahah ct1.pkt_id=%d",ct2.pkt_id);
    $display("hahah ct2.ch_id =%d",ct2.ch_id);

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值