17 UVM Agent

2023-12-29 15:49:14

agent是保存并连接driver,monitor和sequencer实例的容器。agent基于协议或接口要求开发结构化层次结构。

uvm_agent class declaration:

virtual class uvm_agent extends uvm_component

User-defined class declaration:

class <agent_name> extends uvm_agent;

1 uvm_agent class hierarchy

2 How to create a UVM agent??

  1. 创建一个从 uvm_agent 扩展的用户定义agent类,并将其注册到工厂中。
  2. 在 build_phase 中,实例化driver,monitor和sequencer如果它是active的。如果它是passive agent,则只实例化monitor。
  3. 在 connect_phase 中,连接driver和sequencer组件。

3 Types of Agent

There are two types of agents

  1. Active agent
  2. Passive agent

3.1 Active Agent

active agent驱动激励给DUT,实例化三个component:driver,monitor和sequencer。

3.2 Passive Agent

passive agent不驱动激励给DUT。它只实例化monitor。它被用作覆盖率coverage采样接口和checker检查的目的。

3.3 How to configure the agent as an active or passive agent?

agent通常在UVM env环境类里例化。因此,它在env里或者其他实例化agent的component里使用配置参数 is_active对agent进行配置。

set_config_int("<path_to_agent>", "is_active", UVM_ACTIVE);
set_config_int("<path_to_agent>", "is_active", UVM_PASSIVE);

注:默认情况下,所有agent被配置为UVM_ACTIVE。?

3.3.1 Code snippet to configure agent type with set_config_int
// Env Code
class env extends uvm_agent;
  a_agent agt_a; // Active agent
  p_agent agt_p; // Passive agent
  `uvm_component_utils(env)
  
  function new(string name = "env", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    
    agt_a = a_agent::type_id::create("agt_a", this);
    agt_p = p_agent::type_id::create("agt_p", this);
    set_config_int("agt_p", "is_active", UVM_PASSIVE); // Configure p_agent as passive agent
  endfunction
endclass

Output:

UVM_WARNING /xcelium20.09/tools/methodology/UVM/CDNS-1.2/sv/src/base/uvm_component.svh(3061) @ 0: uvm_test_top.env_o [UVM/CFG/SET/DPR] get/set_config_* API has been deprecated. Use uvm_config_db instead.
UVM_INFO agent.sv(16) @ 0: uvm_test_top.env_o.agt_a [agt_a] This is Active agent
UVM_INFO agent.sv(40) @ 0: uvm_test_top.env_o.agt_p [agt_p] This is Passive agent
UVM_INFO /xcelium20.09/tools/methodology/UVM/CDNS-1.2/sv/src/base/uvm_root.svh(605) @ 0: reporter [UVMTOP] UVM testbench topology:
--------------------------------------------------------------
Name                       Type                    Size  Value
--------------------------------------------------------------
uvm_test_top               base_test               -     @1835
  env_o                    env                     -     @1902
    agt_a                  a_agent                 -     @1933
      drv                  driver                  -     @1996
        rsp_port           uvm_analysis_port       -     @2117
        seq_item_port      uvm_seq_item_pull_port  -     @2065
      mon_A                monitor_A               -     @2002
      seqr                 sequencer               -     @2150
        rsp_export         uvm_analysis_export     -     @2210
        seq_item_export    uvm_seq_item_pull_imp   -     @2770
        arbitration_queue  array                   0     -    
        lock_queue         array                   0     -    
        num_last_reqs      integral                32    'd1  
        num_last_rsps      integral                32    'd1  
    agt_p                  p_agent                 -     @1966
      mon_B                monitor_B               -     @2860
--------------------------------------------------------------

uvm1.2已经弃用set_config_int方法了。如果你用uvm1.2运行代码,会出现下面的UVM_WARNING。

UVM_WARNING: uvm_test_top.env_o [UVM/CFG/SET/DPR] get/set_config_* API has been deprecated.
Use uvm_config_db instead.
3.3.2 Code snippet to configure agent type with uvm_config_db
// Env code
class env extends uvm_agent;
  a_agent agt_a; // Active agent
  p_agent agt_p; // Passive agent
  `uvm_component_utils(env)
  
  function new(string name = "env", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    
    agt_a = a_agent::type_id::create("agt_a", this);
    agt_p = p_agent::type_id::create("agt_p", this);
    uvm_config_db #(uvm_active_passive_enum)::set(this, "agt_p", "is_active", UVM_PASSIVE);
  endfunction
endclass

Output:

UVM_INFO agent.sv(16) @ 0: uvm_test_top.env_o.agt_a [agt_a] This is Active agent
UVM_INFO agent.sv(40) @ 0: uvm_test_top.env_o.agt_p [agt_p] This is Passive agent
UVM_INFO /xcelium20.09/tools/methodology/UVM/CDNS-1.2/sv/src/base/uvm_root.svh(605) @ 0: reporter [UVMTOP] UVM testbench topology:
--------------------------------------------------------------
Name                       Type                    Size  Value
--------------------------------------------------------------
uvm_test_top               base_test               -     @1838
  env_o                    env                     -     @1905
    agt_a                  a_agent                 -     @1936
      drv                  driver                  -     @1999
        rsp_port           uvm_analysis_port       -     @2117
        seq_item_port      uvm_seq_item_pull_port  -     @2065
      mon_A                monitor_A               -     @1873
      seqr                 sequencer               -     @2150
        rsp_export         uvm_analysis_export     -     @2210
        seq_item_export    uvm_seq_item_pull_imp   -     @2770
        arbitration_queue  array                   0     -    
        lock_queue         array                   0     -    
        num_last_reqs      integral                32    'd1  
        num_last_rsps      integral                32    'd1  
    agt_p                  p_agent                 -     @1969
      mon_B                monitor_B               -     @2859
--------------------------------------------------------------

?

3.4 How does the user-defined agent know whether it is an active or passive agent?

get_is_active()函数被用来查找agent的类型。如果是active agent,会实例化driver,sequencer。而monitor实例和agent type无关。即,monitor总是会被实例化。

get_is_active()函数会返回一个uvm_active_passive_enum类型的枚举变量UVM_ACTIVE或者UVM_PASSIVE。

3.4.1 Active Agent example
class a_agent extends uvm_agent;
  driver drv;
  sequencer seqr;
  monitor_A mon_A;
  `uvm_component_utils(a_agent)
  
  function new(string name = "a_agent", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    if(get_is_active() == UVM_ACTIVE) begin
      drv = driver::type_id::create("drv", this);
      seqr = sequencer::type_id::create("seqr", this);
      `uvm_info(get_name(), "This is Active agent", UVM_LOW);
    end
    mon_A = monitor_A::type_id::create("mon_A", this);
  endfunction
  
  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    if(get_is_active() == UVM_ACTIVE)
      drv.seq_item_port.connect(seqr.seq_item_export);
  endfunction
endclass
3.4.2 Passive Agent example
class p_agent extends uvm_agent;
  monitor_B mon_B;
  `uvm_component_utils(p_agent)
  
  function new(string name = "p_agent", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    if(get_is_active() == UVM_PASSIVE) begin
      mon_B = monitor_B::type_id::create("mon_B", this);
      `uvm_info(get_name(), "This is Passive agent", UVM_LOW);
    end
  endfunction
endclass

4 How an agent build a structural hierarchy with various protocols?

(Agent如何使用各种协议构建结构层次结构)

根据协议接口,将激励驱动至 DUT。因此,通过为不同的协议接口设置不同的agent,提供了构建结构层次结构的灵活性。

例如:

在下图中,

  1. agent_ahb 特定于 AHB 接口。
  2. agent_axi 特定于 AXI 接口。
  3. agent_apb 特定于 APB 接口。

文章来源:https://blog.csdn.net/Bonnie_89/article/details/135286710
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。