uvm实战-学习笔记 下载本文

注意用 starting_phase的判断。

给main_phase设置drain_time。所谓drain_time,就是main_phase结束之后经过drain_time时间以后再进入post_main_phase。

在test的main_phase task中使用set_drain_time函数:

objection的调试

simv +UVM_OBJECTION_TRACE

5.3章节介绍了domain,我觉得基本不会用这个吧?

第6章 UVM中的sequence

sequencer将sequence传递给driver. 引入sequence,带来的变化: 1) uvm_transaction的派生类变成uvm_sequence_item的派生类 2) 需要sequencer

3) driver main_phase有变化

4) 启动sequence(一般在case的build_phase中) 上述变化反映到代码中,如图 6.1.2章节的示例代码

下图中有两种方法实现my_sequencer

sequence的启动方式(3种):

1)在case的main_phase中: 注意要设置cseq的staring_phase。 我觉得书上6-5代码清单里有两个地方写的不合理,一个是start的参数应该是sqr的路径,另外是少了设置starting_phase

2)注意在case的build_phase中

3)更推荐用下面这种方式:

sequence被启动后,会自动执行sequence的body task(以及 pre_body mid_body post_body)

在同一个sequencer上可以启动多个sequence,因为启动了多个,所以不能设置default_sequnce了,需要用上面第一种方法来启动sequence. --------- 但是sequence的嵌套可以解决这个问题(上层sequence做default_sequence 6.4章节)

sequence可以用uvm_do_pri uvm_do_pri_with等macro来设置优先级priority, 当一个sequencer上有多个sequence的时候,这个优先级就有意义了。

优先级就带来sequencer的仲裁算法。默认的仲裁算法是SEQ_ARB_FIFO(杨哥遵循陷入先出顺序,不考虑优先级),所以设置优先级以后,需要改变仲裁算法。 在case的main_phase中调函数set_arbitration()

前面提到的“嵌套sequence”也可以像上面这样来设置仲裁算法。

sequencer的操作:

lock() grab() 获取独占权。 unlock() ungrab() 释放独占权

is_relevant() 设置sequence有效和无效。返回值1 有效,返回值0无效

wait_for_relevant() 当sequencer发现启动的所有sequence都无效的时候,会自动调wat_for_relevant() task。 在wait_for_relevant() task中,必须使sequence无效的条件清除。 is_relevant() 和 wait_for_relevant() 如果需要的话,一般是成对重载。

6.3 sequence相关macro及实现

最重要的是uvm_do系列宏,尤其是在引入virtual sequencer以后uvm_do_on系列宏用的会很多。

`uvm_do_on_pri_with(SEQ_OR_ITEM,SEQR,PRIORITY,CONSTRAINTS) uvm_do系列macro都是来源于这个最长的macro

除了uvm_do系列macro之外,还可以用uvm_create + uvm_send。 使用uvm_create + uvm_send的优势是可以在两个macro之间加一些赋值操作等,当然也可以把约束随机加在这里。 uvm_create是实例化transaction,uvm_send是把transaction发送出去。

uvm_rand_send uvm_rand_send_pri uvm_rand_send_with uvm_rand_send_pri_with与uvm_do 系列macro类似

start_item和finish_item 上述macro的实际实现函数-------- 我觉得我们代码里应该不会用这两个函数。

task pre_do(bit is_item)

function void mid_do(uvm_sequence_item this_item) function void post_do(uvm_sequence_item this_item) 注意上述task/function的参数。 mid_do和post_do因为参数是基类对象,函数重载里可能需要做$cast.