UVM的seq/vseq、seqr/vseqr、intf/virtual_intf

seq负责激励的产生。激励的产生通常是在seq中调用randomize()函数实现,要求在item类中声明的变量在需要随机化时要声明rand/randc,不加rand的变量无法随机化产生。不能在类的构造函数里随机化对象,因为在随机化之前可能需要打开或关闭约束、改变权重、甚至添加新的约束。构造函数用来初始化变量,不能在这里调用randomize函数。

seq用`uvm_object_utils宏注册,一般还会声明seq_cfg,在body中会get seq_cfg(一般是在testbase中set),有new函数和定义随机函数,随机函数供在body中调用。

48 task my_env::main_phase(uvm_phase phase);
49     my_sequence seq;
50     phase.raise_objection(this);
51     seq = my_sequence::type_id::create("seq");
52     seq.start(i_agt.sqr);
53     phase.drop_objection(this);
54 endtask

seq的启动方式:

1)uvm_seq中有start函数,用来启动seq。start的参数是一个seqr的指针,指明了seq产生的item交给哪个seqr。

2)default_seq启动seq。使用default_seq替代了手动启动seq相关语句即seq.start。注意上述手动启动是放在一对objection里,若只使用default_seq,如何提起和撤销objection?上述objection是phase的函数,而这些phase属于component?(只有uvm_component类才支持phase机制)。在uvm_seq中有变量starting_phase,sequencer在启动default_sequence时,会自动执行以下操作。component中phase=seq中starting_phase,原先的phase.raise_objection就可以用starting_phase.raise_objection来代替。在body中会get seq_cfg(一般是在testbase中set),

task my_sequencer::main_phase(uvm_phase phase);
…
seq.starting_phase = phase;
seq.start(this);
…
endtask

 因此,可以在sequence中使用starting_phase进行提起和撤销objection:提起和撤销一般发生在seq的pre_body和post_body。UVM的设计哲学就是全部由sequence来控制激励的生成,因此一般情况下只在sequence中控制objection。objection主要用来控制仿真何时结束,因此一般主要面向耗时类phase,而不是function_phase。

default_seq一定是用来帮助virtual_seq?不是的。对于任意seq设置给seqr都行。

产生item有两种方式:

1)通过`uvm_do宏产生item并发送到seqr。uvm_do宏做三件事情,item实例化,随机化,发送给seqr,三个动作封装在宏里。mid_do完成item的随机化,属finish_item。send_request将item发送出去,属finish_item。

sequencer.wait_for_grant(prior) (task) \ start_item \
parent_seq.pre_do(1)            (task) /             \
                                                      `uvm_do* macros
parent_seq.mid_do(item)         (func)\              /
sequencer.send_request(item)    (func) \finish_item /
sequencer.wait_for_item_done()  (task) /
parent_seq.post_do(item)        (func)/

2)不使用宏产生transaction的方式要依赖于两个任务:start_item和finish_item。需要将item实例化、随机化、发送分开处理。在使用这两个任务前,必须要先实例化transaction 后才可以调用这两个任务。实例化和随机化需放在finish_item之前,start_itme之前之后都可以。随机化必须在实例化后,否则没有空间存储随机数据。

tr = new("tr");
start_item(tr);
finish_item(tr);

上述代码中并没有对tr进行随机化。可以在transaction实例化后、finish_item调用前对其进行随机化。实例化也可以通过`uvm_creat(tr)。再通过`uvm_send宏发出。

uvm_do宏产生item,交给seqr,driver从seqr取走这个item后,uvm_do并不会立即执行下一次的产生发送item的动作,而是要等待driver的seq_item_done信号。

vseq:virtual_seq用于实现不同seq之间的同步。当DUV有多个输入输出口时,需要产生不同的激励,即不同的item,就需要多个seq产生(一个seq产生一种item)。

seqr:是一个管道,将seq产生的激励发送给driver。当driver通过get_next_item从seqr获取item时,seqr保留一份刚发出去的item,若driver没有收到,seqr会将保留的这份再发出去。(get动作中fifo内部缓存会少一个item,此刻seqr好像没有少,用peek_next_item好像更合适。)seqr通过item_done判断driver是否收到item,进而决定是否发出去下一个item。driver负责激励的驱动。在driver中首先从seqr中获取seq产生的item,将driver和seqr连接,uvm_driver内建有seq_item_port成员变量,uvm_seqr内建有seq_item_export成员变量。在agent的connect_phase中将二者连接起来,drv.seq_item_port.connect(seqr.seq_item_export)。在driver中通过get_next_item任务向seqr申请新的item。driver中的get_next_item,drive_item及item_done都是放在无限循环里的。因为driver只负责驱动item,并不产生。只要有item,就驱动。所以必须做成无限循环形式。

class my_seqr extends uvm_sequencer #(my_item);

 一种seqr也只能传递一种item,在定义时候的参数就已经决定。

vseqr:virtual sequencer里面包含指向其他真实sequencer的指针。virtual sequence和virtual sequencer。它们各自并不产生transaction,而只是控制其他的sequence为相应的sequencer产生transaction。virtual sequence和virtual sequencer只是起一个调度的作用。由于根本不直接产生 transaction,所以virtual sequence和virtual sequencer在定义时根本无需指明要发送的transaction数据类型。

intf:是连接验证平台和DUV的接口。产生的激励通过driver驱动到intf传递到DUV,DUV吃激励后的输出通过intf传递到mon进而到scb。在类中如driver、mon都不能声明intf,intf只能在tb_top的module中使用,可以在类中声明virtual_intf。使用virtual_intf消除了绝对路径。

本文章参考《UVM实战》、《芯片验证漫游指南》等资料整理而成,仅作学习心得交流,如果涉及侵权烦请请告知,我将第一时间处理。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值