17 UVM Agent

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 接口。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的UVM代理(Agent)的示例,它包含了顺序生成器(Sequencer)、驱动程序(Driver)和监控器(Monitor): ```verilog class my_agent extends uvm_agent; `uvm_component_utils(my_agent) // Declare sequencer, driver, and monitor instances my_sequencer sequencer; my_driver driver; my_monitor monitor; // Override the build_phase to create and connect components virtual function void build_phase(uvm_phase phase); super.build_phase(phase); // Create sequencer, driver, and monitor instances sequencer = my_sequencer::type_id::create("sequencer", this); driver = my_driver::type_id::create("driver", this); monitor = my_monitor::type_id::create("monitor", this); // Connect components using analysis ports and exports sequencer.seq_item_port.connect(driver.seq_item_export); monitor.analysis_port.connect(scoreboard.analysis_export); endfunction endclass ``` 在上面的示例中,`my_agent`是一个UVM代理,它包含了顺序生成器、驱动程序和监控器。在`build_phase`中,代理创建了顺序生成器(`sequencer`)、驱动程序(`driver`)和监控器(`monitor`)的实例,并使用分析端口和导出端口进行连接。 通过将顺序生成器的`seq_item_port`与驱动程序的`seq_item_export`连接,可以在代理中启动事务生成并将事务发送给驱动程序。通过将监控器的`analysis_port`与评分板(`scoreboard`)的`analysis_export`连接,可以将监测到的事务发送到评分板进行检查。 以上是一个简单的UVM代理示例,它展示了如何在UVM中创建和连接顺序生成器、驱动程序和监控器。具体实现中,你需要根据你的需求进行适当的修改和扩展,并添加其他必要的组件和连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值