目录
2.引入virtual sequence和virtual sequencer
2.在virtual sequence中控制objection
1.在sequence中获得参数(围绕seq是uvm_object展开)
6.5 virtual sequence的使用
1.怎么样解决不同drv发送的控制?
1.使用全局变量
缺点:①不建议使用全局变量②频繁反复切换实现过于繁琐
2.引入virtual sequence和virtual sequencer
不同drv的控制,本质上是seq--->sqr--->drv的控制,控制整个链条最后也就控制了drv.
引入virtual sequence(后续简称v_seq):为什么是virtual呢?换句话说actual又做了什么呢?
参考6.5.2代码清单6-68,这个actual_seq就使用了uvm_do,这也就意味着产生了transaction(详见《UVM实战卷Ⅰ》学习笔记 第二章 一个简单的UVM验证平台(3)_IC-V的博客-CSDN博客uvm_do实现了什么?)而virtual也就意味着没有产生transaction.结合之前seq的嵌套和代码6-72,你就会发现v_seq其中嵌套了actual_seq,对其中的seq做调度.
引入virtual_sequencer,seq中实现了调度,sqr/drv各自有2个(两个env),结合之前讲的怎么访问sqr中的变量,于是想起构造v_sqr,讲actual_sqr的句柄在v_sqr中声明,这样v_sqr也是调度作用,后续寄存器模型也会在其中.
另外尤其注意一点,这里在v_sqr中声明的句柄,要和各个env.agt中的真正的sqr连接.再者,由于引入v_sqr,使default_sequence启动只出现一次就可以.
2.在virtual sequence中控制objection
截止目前体现了virtual sequence两个作用:
1.调度seq 2.控制objection
6.6 在sequence中使用config_db
1.在sequence中获得参数(围绕seq是uvm_object展开)
uvm_config_db#(int)::set(this."env.i_agt.sqr.*","count",9)
①很重要的一点seq作为uvm_object,并不能和之前一样利用UVM树形的层次路径进行传递,而是会把挂载的sqr作为接口(如果在v_sqr中启动,那就应该是v_sqr),接入其中开始传递
②seq的例化常发生,其名字不可确定,因此这里用了通配符
uvm_config_db#(int)::set(null.get_full_name(),"count",count)
①这里的null边体现了UVM树形结构唯一根的作用,即uvm_root::get()=uvm_top.(详见3.2.2)
6.7 response的使用
1.put_response和item_done()
两者都会返回rsp给到seq,item_done()会出发seq中的$finish(经常被封装,看不到此函数,但是标志着seq的结束).
item_done()只能在只有一个rsp的情况下使用
2.response handler
分开了发送transaction部分也就是uvm_do和get rsp部分,使用rsp handler不需要再用get_response(rsp),注意rsp_handler返回的是uvm_sequence_item,需要$cast.
这里底层逻辑没理解清楚.
3.另类的response
有两点基础:
1.uvm_do发送完数据之后,其transaction指针是刚发送至drv的指针
2.代码中的frm_drv是在transaction中已经定义好的成员变量
这里相当于是一次简单的信息传递,增强可读性
6.8 sequence library
一系列seq的集合,本质也可以作为一个seq.
其可以根据特定算法随机选择注册本身包含的seq,并在body中执行.
1.sequence library三步曲:①声明transaction类型②调用init_sequence_library③调用uvm_sequence_library_utils注册
2.selection_modle可以选择lib中seq执行算法
3.*_random_count选择执行次数
4.专门的cfg可以合并2和3点的设置过程,启动seq后例化lib也可以直接对lib的成员变量赋值