UVM实战书籍再复习

 1、clone和copy

clone,

1)只能用于uvm_object类型,不能用于component类型。因为一旦使用component克隆,parent参数无法指定。

2)用于分配一块内存空间,并把另一个实例复制到这块新的内存空间。两个指向不同的空间。克隆=new+copy

3)通常使用:$cast(a2,a1.clone()), a1.clone()是一个父类句柄指向A的子类对象。

copy

1)可以用于object,也可以用于component。在使用copy前,目标实例必须已经用new分配好空间,指定好parent。clone = new + copy

2、打印信息的冗余度排名:越往下越不会打印

UVM_NONE

UVM_LOW

UVM_MEDIUM

UVM_HIGH

UVM_FULL

UVM_DEBUG

3、get_full_name

4、config_db

uvm_config_db#(int)::set(this,"env.i_agt.drv","……",100);

1、第一个参数和第二个参数组成目标路径,第一个参数必须是一个component实例的指针。在top_tb中set函数第一个参数为null = uvm_root::get(),即uvm_top。

2、只有set没有get的场景

1)原本需要进行get的component,在build_phase下调用super.build_phase(),会自动调用get语句。2)接收方组件必须`uvm_component_utils(component)宏注册,并且把传递过来的参数用uvm_filed_int(pre_num)注册。3)set函数的第三个参数必须要与gey函数中变量名字相一致。

config_db传递的是句柄,只要它发生改变之后,另外一端就能检测到

3、跨层次多重设置

发信人的优先级高(靠近根节点的优先级高),时间的优先级低。

5、TLM通信 (1)考虑谁是发起者,2)是否阻塞)

避免使用全局变量的方式实现两个组件的通信。

1)put,get都使用了一种回调的机制

nonblocking_put : imp端,定义can_put/try_put 两个function

blocking:imp端,定义put/get的task,如果不能执行,就阻塞

2)analysis_port:一对多的通信,广播通信,没有阻塞和非阻塞的概念

1、imp端需要写write函数

2、一个component内部有多个imp,用宏`uvm_analysis_imp_decl(_monitor)声明后,在定义function void write_monitor(my_transaction tr);是function,因为它是广播没有阻塞和非阻塞的概念。

3)使用FIFO通信,收发双发都能成为主动方,且不需要写回调函数。

6、phase机制

1、深度优先,同一层次按照实例名的字典序排名

2、对于不同的component,他们的run_phase,自下而上启动,并行执行。对于不同的component,十二个动态运行的phase并行执行,但只有所有的component的main_phase执行完毕后,才会进行post_main_phase,可以理解为不同组件下的动态运行phase是同步开启的。

3、从整个验证平台的角度来说 ,只有所有component的run_phase和post_shutdown_phase都完成才能进入extract_phase。

4、只有build_phase需要加super.build_phase()

5、对于同一个componet,动态运行的phase有objection raise,run_phase就不会结束

6、对于不同componet(整个验证与环境),只要一个component的有objection被raise,其他的component都会继续执行。

7、sequence中可以在body task中 raise-objection

starting_phase.raise_objection(this);

因为当seq挂载在seqr上相当于调用seqr的raise_objection

7、sequenc机制

sequence的启动:

1)在不同的测试用例中,将不同的seq设置成seqr的main_phase的default_sequence。seqr执行到main_phase有default_sequence就启动sequence。

//component的build phase阶段使用default_sequence启动sequence
//default_sequence要使用config_db,而build_phase一般用于config_db配置信息及变量的实例化
virtual function void build_phase(uvm_phase phase);
	super.build_phase(phase);
	uvm_config_db#(uvm_objection_wrapper) ::set(this,
												"i_agt.sqr.main_phase",
												"default_sequence",
											  my_sequence::type_id::get());
	endfunction

defalut_sequence使用时,有时候使用uvm_sequence_base,有时候使用uvm_object_wrapper?

//component的main phase阶段用seq.start(i_agt.sqr)启动sequence
task my_env::main_phase(uvm_phase phase)
	my_sequence seq;
	phase.raise_objection(this);//手动启动的时候需要将seq的starting_phase赋值
	seq = my_sequence::type_id::creat("seq");
	seq.start(i_agt.sqr);
	phase.drop_objection(this)
endtask

 set的第一个参数和第二个参数构成了sequencer的路径。由于除了main_phase外,还存在其它任务phase,如configure_phase、reset_phase等,所以必须指定是那个phase,从而使sequencer知道在哪个phase启动这个sequence。第三个和第四个参数,以及uvm_cofig_db#( uvm_object_wrapper)中为什么是uvm_object_wrapper而不是uvm_sequence或者其它,则纯粹是由于UVM的规定,用户在使用时照做即可。

通常config_db都是成对出现的,有set就有相应的get。但是在这里不需要再sequencer中手工写一些get相关的代码,UVM已经做好了这些,读者无需再把时间花在这上面。

default_seq:不需要get
————————————————
版权声明:本文为CSDN博主「谷公子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/W1Z1Q/article/details/100865789

控制objection的地方:

objection的raise和drop可以有两个地方,分别:

1)手工启动模式下:在组件的main_phase中,调用phase的raise和drop objection。即上面的代码段

2)手工启动模式下:将seq.starting_phase指向当前所在phase,然后在seq中通过starting_phase调用

 3)default_sequence下:不需要手动将sequence的starting_phase指向组件的phase,只需要在seq中调用。

可以在sequence中使用starting_phase进行提起和撤销objection,只有将sequence作为sequencer的某动态运行phase的default_sequence时,其starting_phase才不为null,通过seq来raise和drop objection。

default_sequence的作用?_沧月九流的博客-CSDN博客_default_sequence

UVM中启动sequence的方法_谷公子的博客-CSDN博客_uvm启动sequence的方法

2)sequence的嵌套,sequence中实现了各个item包的发包顺序。

3)p_sequencer 和 m_sequencer

m_sequencer指向的是当前seq挂载的seqr的对象,但是他是uvm_sequence_base类型,是一个父类句柄。相当于是一个父类句柄指向了一个子类对象,所以有时候无法访问到子类对象中特有的内容。然后我们就可以通过声明宏p_declare(my_seqr),uvm就相当于帮我们声明了一个子类对象,并且用$cast(p,m),这时候p_seqr也就指向了当前seq挂载的seqr上面,并且是子类句柄指向子类对象,就可以访问my_seqr的所有内容,尤其是my_seqr是virtual seqr时,可以访问内部的子seqr。

4)sequence之间的同步

①简单同步:uvm_event , config_db(传递参数?)

②复杂同步:在virtual seq中对所有的seq做统一调度,然后通过virtual seqr做一个路由,传递到各个子seqr上进行。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值