virtual sequence 的使用
实现sequence之间同步的最好的方式就是使用virtual sequence。从字面上理解,即虚拟的sequence。虚拟的意思就是它根本就不发送transaction,它只是控制其他的sequence,起统一调度的作用。
如图所示,为了使用virtual sequence,一般需要一个virtual sequencer。virtual sequencer里面包含指向其他真实sequencer的指针:
在base_test中,实例化vsqr,并将相应的sequencer赋值给vsqr中的sequencer的指针:
在virtual sequene中则可以使用uvm_do_on系列宏来发送transaction:
在case0_vseq中,先使用uvm_do_on_with在p_sequencer.sqr0上发送一个最长包,当其发送完毕后,再启动drv0_seq和 drv1_seq。这里的drv0_seq和drv1_seq非常简单,两者之间不需要为同步做任何事情。
在使用uvm_do_on宏的情况下,虽然seq0是在case0_vseq中启动,但是它最终会被交给p_sequencer.p_sqr0,也即env0.i_agt.sqr 而不是v_sqr。这个就是virtual sequence和virtual sequencer中virtual的来源。它们各自并不产生transaction,而只是控制其他的sequence为相应的sequencer产生transaction。virtual sequence和virtual sequencer只是起一个调度的作用。由于根本不直接产生 transaction,所以virtual sequence和virtual sequencer在定义时根本无需指明要发送的transaction数据类型。
假如验证平台中的sequencer有多个,如10个,那么就需要写10个uvm_config_db语句,这是一件很令人厌烦的事情。使用virtual sequence后可以将这10句只压缩成一句:
objection控制
当virtual sequence存在时,尤其是virtual sequence中又可以启动其他的virtual sequence时,有 三个地方可以控制objection:一是普通的sequence,二是中间层的virtual sequence,三是最顶层的 virtual sequence。那么应该在何处控制objection来最终控制验证平台的关闭呢? 一般来说,只在最顶层的virtual sequence中控制objection。因为virtual sequence是起统一调度作用的,这种统一调度不只体现 在transaction上,也应该体现在objection的控制上。在验证平台中使用objection时,经常会出现没有按照预期结束仿真的情况。这 种情况下就需要层层地查找哪里有objection被提起了,哪里有objection被撤销了。虽然可以通过objection调试手段来辅助进行,但它终归是一件比较麻烦的事情。如果大家约定俗成都只在最顶层的virtual sequence中控制objection,那么在遇到这样 的问题时,只查找最顶层的virtual sequence即可,从而大大提高效率。