UVM的断言assert详谈
assertion分为两种:立即断言和并发断言,对于立即断言是比较简单的,可以理解为对某个信号进行判断,如果不符合预期打印错误信息。
而并发断言的构成:seq ->property ->assert 。 seq即简单的判断语句,常用的方式为 |-> 和 |=>,前者是条件正确后立刻判断后面的语句,|=>则需要前面判断条件正确后,一个cycle再进行判断,当然也可以通过##来指定具体需要的时间周期。
对property和assert不妨这么看,property其实就是一个函数,只不过这个函数里面调用的都是sequence和其它property,而assert其实就是调用这个函数的语句。
关于property有下面一些比较细碎的知识点值得指出来:
1.就像一个函数,property里面可以调用其它property,并且可以用if else等简单语句来组织不同property之间的关系。一个property里面可以调用其它task function。
2.DUT里面也是可以用assertion的。
3.property里面对结果的取反用not而不是~。
在uvm中对assertion提供了一些简单好用的语句,如下:
rose fell stable sample就是字面意思,很好理解的,下面这个图讲得很清楚了,它们存在的意义就在于是对电平敏感的普通sequence表达的一种补充。
past(,n)指的是判断在目前这个时钟沿前面n个周期的时钟沿的情况 and or很好理解,但他们只要求sequence正确就完事了,而intersect则是在and的基础上,还要求俩sequence的结束时间也要一致,不然就报错。由此可以联想一下,如果我们要指定两个sequence的结束时间差出去某个周期该怎么半呢,也好办,只要在某一个sequence后面加上##n 1就可以了。所以过一个简单intersect实际上是彻底实现了对两个sequence结束时间的各种约束。
断言在设计中的存在,可以让设计本身更加透明,类似白盒。而在vip中使用断言,比如在fifo中加入空读满写断言,作为一个公共ip,很多地方都会调用vip,通过自检的断言,方便快速定位。
sequence s1;
a ##1 b ##1 c;
endsequence
以上seq主要描述信号和信号之间的时序关系, a为高,下一拍b为高,再下一拍c为高。
property p1;
s1;
endproperty
以上对seq s1进行封装;
property a1;
@(posedge clk) fifo_full|-> (fifo_wr == 1`b0);
endproperty;
以上实例表示每个时钟上升沿进行check,如果fifo_full并且(fifo_wr==1'b0)不满足,则断言失败,就是写满了,然而只写在这里并不会调用,需要写明assert才会真实的起作用;
assert property(a1);
bind关键字的使用:
·ifdef SVA
bind qma qma_sva qma_sva_inst(.*);
·endif
对应参数说明:
1.qma 类似verilog代码中的module,这个是他的模块名,并不是例化名;
2.qma_sva是单独写的断言module,也是模块名;
3.qma_sva_inst是你例化这个断言模块所使用的例化名;
4.:(.)括号里面的意思是例化的时候直接将相同名字的连起来,这句话实现的是你在原先写的qma
模块里面例化了一个名字为qma_sva_inst的qma_sva模块;后面的(.),如果你名字不一样应该是要自己手动写一遍的。
常见函数:
常用语法:
disable iff的用法:
property a;
@(posedge clk)
disable iff(reset)
a|->b;
endproperty
即:如果reset信号为高,则停止检查