先做小结:它封装了从transaction实例化到发送的一系列操作。
接下来回答几个问题:
问题一:如何理解uvm_do系列宏?
问题二:uvm_do与start_item有什么区别和联系?
首先回答问题一:如何理解uvm_do系列宏?
此系列一共有8个(do系列和do_on系列各4个),其实这8个系列宏最底层都是uvm_do_on_pri_with这个宏,其他7个都是对他的4个参数做了不同的固化后而形成,先看看他的参数定义。
`uvm_do_on_pri_with(SEQ_OR_ITEM, SEQR, PRIORITY, CONSTRAINTS)
参数一:产生的数据类型,可以是sequence或者transaction(sequence_item)。
参数二:
sequencer
的指针,即在哪个sequencer上启动。
参数三:优先级。
参数四:约束条件。
那么uvm_do宏其实就是
`uvm_do_on_pri_with(SEQ_OR_ITEM, m_sequencer, -1, {}) 。
当在
sequence
中使用
uvm_do
等宏时,其默认的
sequencer
就是此
sequence
启动时为其指定的
sequencer
,
sequence
将这个sequencer
的指针放在其成员变量
m_sequencer中。也相当于`uvm_do_on(tr, this.m_sequencer)。
接着回答问题二:和start_item的关系?
我们知道启动sequence还可以通过
start_item
和
finish_item的方式,在使用这两个任务前,必须要先实例化transaction后才可以调用这两个任务:
virtual task body();
repeat(10) begin
tr = new("tr");
assert(tr.randomize() with {tr.pload.size == 200;});
start_item(tr);
finish_item(tr);
end
endtask
注:tr的随机化
也可以放在
start_item
之后、
finish_item
之前,但是要在new之后。
将上述第3-6行的代码封装起来,就是一个uvm_do宏干的事情了。包括了创建、实例化、随机化、启动、发送、结束。
之前提到uvm_do宏的第一个参数除了可以输transaction外还可以是sequence,那么如何使用呢。
当第一个参数是
transaction 时,它
调用
start_item
和
finish_item
;当第一个参数是
sequence
时,它调用此
sequence
的
start
任务(嵌套sequence)。
注意:除了uvm_do宏外,uvm_send宏、uvm_rand_send宏、uvm_create宏,其第一个参数都可以是sequence的指针。唯一例外的是start_item与finish_item,这两个任务的参数必须是transaction的指针。