较常用的9个phase
run_phase和12个phase是task,其他的是function
上面的,写了run_phase就不用写main_phase了
使用raise_objcction机制和drop_objection机制标签来让phase机制同步运行。(问:为什么phase机制能够同步进行?)
在实际运行当中,DUT可能还没处理完数据就又传进来数据了,则这时候需要set_drain_time(this,time)去延迟一下时间。
上面这句话的意思是延迟1us后再结束本次UVM。
下面的是time_out的修改运行时间机制:
默认9200s结束控制UVM的运行总时间,其中.timeout()里面设置这次运行时间,写在top顶层文件里面。
一般来说9200秒够用。
使用phase.jump在driver.sv文件或者monitor.sv文件里面进行跳转。可跳前,可跳后,比如main_phase跳reset_phase,main_phase直接跳shutdown_phase。
如下:
Assertion
断言assertion有助于提高效率,定位报错,在property里面写判断时序的语句,用assert来断言。
上面的意思是sequence配合.ended语句判断是否全部符合条件,验证人员编写端口的assertion。
|—>同一个时钟沿触发后面的句子
|=>下一个时钟沿触发后面的句子
判断“|”前面的request是否为高电平,然后触发后面的sequence。
这里的【1:4】的意思是在时序1到4之间的时序里acknowledge都必须是1,否则报错。
这里如果用RTL来写,至少要10行,所以SV的验证方法学很重要。类似于一个while(True):
do something
assertion是一门非常重要的技术,对于时序的断言非常有效。
SV里面的sequence是针对时序状态的。
而UVM里面的sequence是一个在task body()函数里面写rand激励,写响应的,transaction确定好数据格式,sequencer将激励送给driver解析,再利用interface送到DUT,最后用befor_monitor和after_monitor查看scoreboard。
从左到右执行,##1 表示慢1拍,##【2:5】表示在2到5个延迟拍里。【*3】表示某时序重复三次,
有and、or、first_match、.ended等关键字用法。
进行采样,用于时序相关判断语句的使用。
通过采样时序,得到reg1的式子,这是sequence关键字的用处之一。
sequence是针对时序状态组合的关键字,一串带“#”的句子,是写时序的,写在assertion里的,是在property写的。
call_back的讲解和使用,其用于注入error和function coverage
如果不用callback,要写很多的class。如下:
具体的实施方法如下:
第一步:在component里注册一个callback。
入口函数pre_send task和post_send task。
第二步:申明call_back的class。
申明两个空壳子的pre_send和post_send的virtual task。
第三步:重写task函数
第四步:将error的call_back传递“::add”传递进去。
举例
在下面test.v文件里面找到了两个callback: