systemverilog中浅复制和深复制的具体用法

systemverilog中浅复制和深复制的具体用法

做IC 验证进行transaction比对时,发现曾经验证通过的module总是发生mismatch的情况,这是不应该发生的情况,因为这个module曾经已经验证通过并且RTL已经稳定,bench也很稳定,但是出现了mismatch的情况。最后经过debug发现两种不同写法的代码会导致不同的结果:

(1)new_tr = new tr--->这种写法验证能够通过;

(2)new_tr.copy(tr) 或者 $cast(new_tr,tr.clone()) --->这种写法出现mismatch;

注:在bench传递transaction的handle时,因为一个transaction的handle往往会在多处引用,因此小编在拿到handle的时候通常会自己维护一份,以防别人通过handle修改了原本的内容,我认为这是一种良好的风格,推荐大家这样做。

基于此,维护自己的transaction时,使用的uvm的copy()或者clone()方法,即第(2)种写法,总是出现mismatch的情况,后来采用systemverilog的复制方法,即第(1)种写法,仿真可以通过,这是为什么呢?难道uvm的copy()方法和clone()方法有问题?

其实并不是,uvm的copy()和clone()方法是很好用的方法,并没有问题。通过上面掌握的信息进行进一步的定位和debug,终于发现了问题的根源所在:

原来transaction class里面,filed_automation里面漏掉了一个字段,有一个property并没有放在field_automation里面,导致copy()以及clone()时该字段并不会进行copy和clone而永远是其data type的默认值,例如,我有一个property int sa不在field_automation,copy或者clone时不会将其正确的数值copy过来,导致该字段永远是int类型的默认值,也就是0,这是导致mismatch的根本原因。

鉴于此,推荐大家将transaction class的所有的property都加入field_automation,这样使用uvm的copy(),clone()以及compare()等方法时才会有效。如果说int sa就是不想让它进行复制,那么就不需要加入field_automation了吗?推荐大家依然加入field_automation,可以如下书写:`uvm_field_int(sa, UVM_ALL_ON | UVM_NOCOPY) ---该字段不会复制

那么:如下的两种写法各有什么区别呢?

(1)new_tr = new tr;

(2)new_tr.copy(tr) 或者 $cast(new_tr,tr.clone()) ;

第(1)种写法是sv的shallow copy,所谓的shallow copy就是如果一个class种包含另外一个class的handle,那么copy的时候只会copy被包含class的handle,而其中的成员变量不会copy,只是默认值。

第(2)种方法是UVM的method,在使用copy()方法之前一定要将transaction create出来,否则会报错,而使用clone()方法之前不需要将transaction create出来,简单来说,clone() = create() + copy()