UVM基础-Phase机制(三)

4.1 domain的基本概念

phase机制解决了验证环境在不同组件之间做到动态同步,让所有组件一同进入某个phase,并且等待所有组件都投票完成,再进入下一阶段。那么想象一下,有没有一种场景是需要两个组件之间phase的运行是异步的,或者说某几个组件之间运行是异步的。比如在某个大型的验证环境中,存在多个驱动的agent,而每个agent之间又相对独立,也就是说,每个agent中的driver独立做复位,解复位,配置,驱动等动作,那么如果没有一个机制能够做到agent之间的组件phase运行在异步情况,那么将会是这样的:以两个driver为例

 

两个agent内部的driver组件同时进入同一个动态运行的phase,这个由phase机制保证,那么如果想要做到两个agent之间phase运行异步,也就是在每个agent内部,driver和monitor的phase运行是同步的,但是agent之间phase运行异步,互补干扰,那么就要引入domain的概念,将其中一个agent加入到新的domain中,注意此处要递归加入,也就是将agent的成员变量全部加入进去,这样就可以做到和其他agent的phase运行异步,如下图所示:

 

       实际上,这个功能并不太常用,因为引入新的domain会增大与原有机制相互协调的影响,尤其是新建的验证环境,这样做往往会引入组件之间配合的异常,比如新加入的domain先走完,此时DUT的输出截至,而影响到后级模块的输入,导致其他domain工作在异常情况下。这个功能多用于DUT之间相互解耦,模块与模块之间无强依赖关系,但是这种场景下,一般会分两个模块分别做单元验证,而不是用一套环境,通过domain的方式将两者拼接起来,从而增加整体调试的工作量。

4.2 domain的用法

       domain的用法较为简单,只需要在需要加入新domain的组件中声明一个变量,叫uvm_domain,然后在build_phase中实例化,然后在connect_phase中调用set_domain(new_domain)即可,new_domain是用uvm_domain声明的domain名字。

       set_domain有两个参数,一个是uvm_domain类型的变量,也就是当前加入的domain变量名,另一个是hierarchy,表示是否递归加入新domain,也就是说,如果配置了第二个参数为1,uvm会将当前组件层级下,所有的节点一直到数根节点,全部加入到声明的新domain中。举个实例,在agent中:

1.	class my_agent extends uvm_agent;
2.	        my_driver drv;
3.	        my_monitor mon;
4.	        my_sequencer sqr;
5.	
6.	        uvm_domain new_domain;
7.	......
8.	        `uvm_component_utils(my_agent);
9.	        extern function void new(string name="my_agent", uvm_component parent);
10.	        extern virtual function void build_phase(uvm_phase phase);
11.	        extern virtual function void connect_phase(uvm_phase phase);
12.	.....
13.	endclass
14.	
15.	function void my_agent::new(string name = "my_agent", uvm_component parent);
16.	         super.new(name, parent);
17.	endfunction:new
18.	
19.	function void my_agent::build_phase(uvm_phase phase);
20.	          super.build_phase(phase);
21.	          drv = my_driver::type_id::create("drv", this);
22.	          mon = my_monitor::type_id::create("mon", this);
23.	          sqr = my_sequencer::type_id::create("sqr", this);
24.	          new_domain = new("new_domain");
25.	endfunction:build_phase
26.	
27.	function void my_agent::connect_phase(uvm_phase phase);
28.	          super.connect_phase(phase);
29.	          drv.seq_item_port.connect(sqr.seq_item_export);
30.	          set_domain(new_domain, 1);
31.	endfunction:connect_phase

        一般在build_phase中实例化new_domain,在connect_phase中进行set_domain,因为set_domain需要传递的形参new_domain要首先进行实例化,然后设定当前层级往下的所有组件都加入到new_domain,hier参数为1。一般情况下,如果想将环境的某个分支,比如env,往下所有的组件都加入新domain,那么就要在最顶层进行设定。设定之后,当前层级往下的所有层级,phase运行与原始domain的组件phase运行异步。

总结一下:

  • domain用于将组件的phase运行机制独立出来,实现单独的运行,domain可递归设置(hier=1)
  • domain的用法为在需要异步的组件中声明uvm_domain,然后在build_phase中实例化,在connect_phase中调用set_domain函数,将实例化的uvm_domain名传给set_domain的参数。
  • set_domain(uvm_domain,hier)有两个参数,第一个参数为想要加入的uvm_domain实例化名字,第二个参数表示是否递归加入,如果hier配置为1,那么会将当前节点往下所有的组件,都加入到新domain。设定之后,组件和其他domain的组件phase运行会异步,互不干扰。
  • 一般会在顶层的组件中set_domain。
  • 设置新的domain会带来环境调试的难度,使用domain要慎重。
  • 在domain中使用phase跳转函数,phase.jump,只会在当前domain中进行跳转,不会影响其他domain的运行,该功能更需慎用。

参考资料:《UVM实战》 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值