sv和verilog虽然是并行语言,但是对于仿真而言细分到底其实是做不到的,事件发生总是有先后的,所以sv使用了event region,然后为了解决tb和rtl的竞争后来出了program,再后来有了clocking block,验证中常犯的一个错误就是clk和clocking block 的混用,用着用着就把自己搞迷糊了。
那么遇到这种问题时是否有比较好的debug方式,其实是有的,下面介绍一下在verdi中如何查看event sequence,event region。
一 查看event sequence
运行时加入命令:
打开波形,开启event sequence
可以看到对应时刻的event sequence,下图所示的就是代码中第一次赋值的时刻
clk:0->1
a:x->77
b:x->0
虽然在波形上看到三个signal是同一时刻变化的,但是对于sv的仿真来看,他们在执行上是存在先后顺序的
2 查看event region
如果要看到event region,运行时加入命令:
打开波形后开启region mode并打开expand time at cursor:
然后就可以看到event region,同时也可以看event sequence:
图中黄色区域是region active ,执行了阻塞赋值,也即clk的赋值,红色区域是region NBA,执行了非阻塞赋值,也即a和b的赋值。到这里已经把debug的手段理清了,接下来试试各种场景。
- 上述代码中第二个赋值时刻对a_data分别在interface和drv_cb中进行了<=赋值,v_if.a_data的值发生了两次变化:77->99和99->88,后一次是在drv_cb中对v_if.a_data的赋值;drv_cb.a_data的和clk的变化在同一个region,这是因为虽然使用的是<=操作符,但实际是个clocking drive,因为使用了drv_cb,并不是非阻塞赋值
- 如果我们把clk的赋值改为<=,可以看到clk的变化和drv_cb.a_data的赋值不在同一个region了
- clk和clocking block混用的后果,下面这段代码的意图是先一拍赋值88,隔一拍后赋值99,但最终是一拍变成了99,和预期并不一致,这里值得注意的是drv_cb.a_data的两次赋值是发生在不同time slot的active region