【学习记录丨UVM】1.6代理人agent

《UVM白皮书》关于agent的介绍

driver和monitor处理同一协议,uvm中通常将二者封装在一起,成为一个agent。

一、一个agent示例

class my_agent extends uvm_agent;
  my_driver  drv;
  my-monitor mon;

  `uvm_component_utils(my_agent)

  function new(string name="my_agent",uvm_component parent);//书上这里没有写name=“xx”
    super.new(name,parent);
  endfunction

  extern virtual function void build_phase(uvm_phase phase);
  extern virtual function void connect_phase(uvm_phase phase);
endclass
      
function void my_agent::build_phase(uvm_phase phase);
  super.build_phase(phase);

  if(is_active == UVM_ACTIVE)begin//is_active是uvm_agent的一个成员变量
    drv = my_driver::type_id::create("drv",this);
  end

  mon = my_monitor::type_id::create("mon",this);
endfunction

function void my_agent::connect_phase(uvm_phase phase);
  super.connect_phase(phase);
endfunction
  1. my_agent派生自uvm_agent,是uvm_component.所以用uvm_component_utils进行factory机制注册。;
  2. function new函数书上这里没有加上name=“my_agent”,跟前边一致可以加上;
  3. 组件的实例化是在build_phase中完成的。
  4. 这里出现了is_active,接下来将对其进行简单介绍:

二、uvm_agent的成员变量is_active

上边my_agent示例中driver的实例化出现了if条件判断。 

  if(is_active == UVM_ACTIVE)begin//is_active是uvm_agent的一个成员变量
    drv = my_driver::type_id::create("drv",this);
  end

1. is_active是哪里来的?

is_active是在UVM库中uvm_agent源文件中声明的一个成员变量。所有派生自uvm_agent的agent组件都自动继承了这个成员变量,无需再声明,可以直接使用。

2. is_active怎么使用?

UVM中is_active的值有两个,一个是UVM_ACTIVE(该值=1),另一个是UVM_PASSIVE(该值=0)。 is_active在UVM中的默认值是UVM_ACTIVE也就是1。我们在使用的时候,可以改变is_active的值进行期望的操作。

3.is_active的值在哪里修改?

is_active的值在实例化agent组件的时候可以进行修改。 一般会在env的build_phase中进行agent的实例化,也在这里进行is_active值的修改,后文将会进行介绍。

4.is_active在本文例子中是什么作用?

agent一般封装了driver和monitor组件,因为二者一般是“成对”的,“有一致性”,方便我们后续验证平台的搭建,也会使得UVM树形组织结构更加清晰。

但是有时候我们并不需要都把driver实例化,比如说agent只用于检测DUT输出端口,这并不需要我们为DUT提供激励,那也就没必要实例化driver。

那我们就可以根据成员变量is_active的值,加入条件判断,通过改变is_active的值来根据需要选择是否在实例化当前agent时用driver组件。

三、实例化agent

在加入容器类env时,我们直接在env中实例化了driver和monitor;但是现在我们已经用agent对driver和monitor进行了封装。那我们直接实例化agent就行了。

这里怎么理解呢? 我们可以想成:env是一个菜篮子,driver和monitor是一对物品1和2,我们现在把这对物品装在袋子agent里。 现在我们把袋子agent放在篮子env中就大功告成了。————(比喻可能不恰当。。能理解就好,别再被我的比喻绕晕了。。。)

1. 在env中例化agent的示例

class my_env extends uvm_env;
  my_agent  i_agt;//新增
  my_agent  o_agt;//例化两个agent

  ·uvm_component_utils(my_env)
  function new(string name="my_env",uvm_component parent);
    super.new(name,parent);
  endfunction

 virtual function void build_phase(uvm_phase phase);//在build_phase中进行实例化
    super.build_phase(phase);
    i_agt = my_agent::type_id::create("i_agt",this);
    o_agt = my_agent::type_id::create("o_agt",this);//实例化agent
    i_agt.is_active = UVM_ACTIVE;
    o_agt.is_active = UVM_PASSIVE;//指定实例化的agent的成员变量is_active的值
  endfunction
endclass

示例中o_agt.is_active = UVM_PASSIVE;结合my_agent说明在组件o_agt中不用实例化driver了。

2. 此时的UVM树形结构 

agent内封装driver和monitor之后,验证平台的层次结构更加清晰了。如下所示。

3. top_tb中config_db#set路径索引 

随着验证平台层次结构的变化,组件的路径索引也将发生变化。通过config_db机制连接top_tb和driver/monitor的interface的set函数也需要改变其第2个参数(路径索引)。

应该改为:

initial begin
 uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.i_agt.drv", "vif", input_if);
 uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.i_agt.mon", "vif", input_if);
 uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.o_agt.mon", "vif", output_if);
end

注意!!!

这里我们用到了两个接口,一个是i_agt和DUT之间的input_if,另外一个是o_agt和DUT之间的output_if。要注意路径索引的对应关系。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值