SystemVerilog 浅拷贝,你一定要知道的事

106 篇文章 10 订阅

从标题来看,内容与SystemVerilog的拷贝有关,既然是拷贝,为什么叫浅拷贝呢 ?本文来聊一聊什么是SystemVerilog的浅拷贝,其现象是什么,并且举例说明我们应该如何使用它。

什么是浅拷贝 ?

浅拷贝,英文名为 shallow copy,顾名思义,copy是浅层次的,不彻底的。一言以蔽之:对象的拷贝,对于SystemVerilog 常用的数据类型(例如int型)则会正常拷贝,对于class数据类型,拷贝则只是copy其引用。

为了很好的说明浅拷贝,举个栗子

  1. class p2s_tr,有成员变量 int data.
    在这里插入图片描述
  2. class p2s_item,内含p2s_tr,即其中例化了 p2s_tr.
    在这里插入图片描述
  3. 在sequence中,做了如下步骤:
    1)create p2s_item,其名字为 req,并打印其内容
    2)create p2s_item,其名字为 req_copy,将req 的内容复制给 req_copy,并打印其内容(复制语句为下图中第31行,req_copy = new req)
    3)修改 req 的内容,然后分别打印 req 与 req_copy 的内容,观察有什么变化
    在这里插入图片描述
    仿真结果如下图所示:
    在这里插入图片描述
    可以看出,req 的原始内容与 copy 后的 req_copy的内容相同,可见 copy已经成功了,且容易造成假象,copy后的数据属于自己拥有,不受原始数据的影响,即如果原始数据被修改,那么copy后的数据不会被影响,真的是这样吗?

接下来,修改 req.data/req.addr/req.read/req.write以及req.tr.data,然后再次打印 req 的内容以及 req_copy的内容。仿真结果看出,除了 req_copy.tr.data 随着 req.tr.data被改变之外,其他变量都不受影响。

为什么会这样呢 ?

这个现象就是 SystemVerilog的浅拷贝造成的。由于 p2s_tr 包含在 p2s_item 中(暂且称 p2s_tr 为 p2s_item的内部类),即一个类中包含另一个类的句柄,那么在拷贝时,其实只拷贝了内部类的引用,也就是其句柄,并不会将内部类的成员变量一并拷贝。

这样会有什么问题呢?

由于是浅拷贝,如果修改原始数据,那么会影响到 copy的数据。(例子中 req.tr.data被修改后,req_copy.tr.data 同样被修改了,因为此时 req.tr 与 req_copy.tr 其实引用的同一个对象)。如果在验证的过程中用到了SV的拷贝,这一点一定要格外注意,否则容易出现非常奇怪且异常隐秘的问题,难以debug。

那么我们应该怎么做呢?

如果非要使用 SV 的 copy ,那么建议每个对象使用自己的存储空间,即不要使用浅拷贝。如何将一个或者多个内部类再次拷贝使其拥有自己的存储空间,需要用户自己去维护。
如果内部类较少的情况下,可以手动的去copy。如果内部类较多的情况下,需要编写递归函数,通过递归函数将内部类一一地 create 出来,然后将需要 copy 的类复制过来。

原文

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值