8、sequence的进阶应用
嵌套的sequence
假设一个产生CRC错误包的sequence如下:
另外一个产生长包的sequence如下:
现在要写一个新的sequence,它可以交替产生上面的两种包。那么在新的sequence里面可以这样写:
似乎这样写起来显得特别麻烦。产生的两种不同的包中,第一个约束条件有两个,第二个约束条件有三个。但是假如约束条 件有十个呢?如果整个验证平台中有30个测试用例都用到这样的两种包,那就要在这30个测试用例的sequence中加入这些代码,这是一件相当恐怖的事情,而且特别容易出错。既然已经定义好crc_seq和long_seq,那么有没有简单的方法呢?答案是肯定的。这就是嵌套的sequence:
在一个sequence的body中,除了可以使用uvm_do宏产生transaction外,其实还可以启动其他的sequence,即一个sequence内启动另 外一个sequence,直接在新的sequence的body中调用定义好的sequence,从而实现sequence的重用。这个功能是非常强大的。在上面代码中, m_sequencer是case0_sequence在启动后所使用的sequencer的指针。但通常来说并不用这么麻烦,可以使用uvm_do宏来完成这些事情:
uvm_do系列宏中,其第一个参数除了可以是transaction的指针外,还可以是某个sequence的指针。当第一个参数是transaction 时,调用start_item和finish_item;当第一个参数是sequence时,它调用此sequence的start任务。 除了uvm_do宏外,前面介绍的uvm_send宏、uvm_rand_send宏、uvm_create宏,其第一个参数都可以是sequence的指针。唯一例外的是start_item与finish_item,这两个任务的参数必须是transaction的指针。
transaction类型的匹配
一个sequencer只能产生一种类型的transaction,一个sequence如果要想在此sequencer上启动,那么其所产生的transaction的类型 必须是这种transaction或者派生自这种transaction。 如果一个sequence中产生的transaction的类型不是此种transaction,那么将会报错:
嵌套sequence的前提是,在套里面的所有sequence产生的transaction都可以被同一个sequencer所接受。
那么有没有办法将两个截然不同的transaction交给同一个sequencer呢?可以,只是需要将sequencer和driver能够接受的数据类型设置为uvm_sequence_item:
在sequence中可以交替发送my_transaction和your_transaction:
这样带来的问题是,由于driver中接收的数据类型是uvm_sequence_item,如果它要使用my_transaction或者your_transaction中的 成员变量,必须使用cast转换:
p_sequencer的使用
考虑如下一种情况,在sequencer中存在如下成员变量(dmac,smac):
sequence在发送transaction时,必须将目的地址设置 为dmac,源地址设置为smac。现在的问题是,如何在sequence的body中得到这两个变量的值呢?
在实际的验证平台中,用到sequencer中成员变量的情况非常多。UVM考虑到这种情况,内建了一个宏: uvm_declare_p_sequencer(SEQUENCER)。这个宏的本质是声明了一个SEQUENCER类型的成员变量,如在定义sequence时,使 用此宏声明sequencer的类型:
在sequence中可以直接使用成员变量p_sequencer来引用dmac和smac:
问题反馈:
wait_modified: 从0更新到0, 还是会返回;
UVM_SEQ_ARB_WEIGHTED; 仲裁算法;
如随机的threshold为219,那么就选蓝色的包
sequence_library的控制次数是针对sequence的;而不是transaction;
以RANDC为例;是将内部有的sequence排序,然后顺序执行sequence,前一个sequence发完了,才会到下一个sequence;(不会管sequence内部产生多少个包)