【问题标题】:How can I create 2 instances of monitors to 2 instance of interfaces如何为 2 个接口实例创建 2 个监视器实例
【发布时间】:2016-08-09 10:42:10
【问题描述】:

我有一个接口类。

我在顶部通过以下方式创建了此接口的 2 个实例:

   //Interface declaration
   pakmx_if_out vif_out[2](clk, rst);
   //Registers the Interface in the configuration block
   //so that other blocks can use it
   uvm_resource_db#(virtual pakmx_if_out)::set(.scope("ifs"), .name("pakmx_if_out0"), .val(vif_out[0]));
   uvm_resource_db#(virtual pakmx_if_out)::set(.scope("ifs"), .name("pakmx_if_out1"), .val(vif_out[1]));

在监视器中,我通过以下方式创建了一个虚拟接口:

   //interface
   virtual pakmx_if_out vif_out;

另外,我在监视器中有一个任务,它访问上述接口的信号。 如何在代理类中创建 2 个监视器实例,以便每个监视器引用不同的接口实例?

我创建了一个监视器实例,在代理的构建阶段和运行阶段连接它:

   //build phase
     function void build_phase(uvm_phase phase);
          super.build_phase(phase);

      agent_ap = new (.name("agent_ap"), .parent(this));

      pm_seqr = pakmx_sequencer::type_id::create(.name("pm_seqr"), .parent(this));
      pm_drvr = pakmx_driver::type_id::create(.name("pm_drvr"), .parent(this));
      pm_mon = pakmx_monitor::type_id::create(.name("pm_mon"), .parent(this));
   endfunction: build_phase

   //connect phase
   function void connect_phase(uvm_phase phase);
      super.connect_phase(phase);

      pm_drvr.seq_item_port.connect(pm_seqr.seq_item_export);
      pm_mon.mon_ap.connect(agent_ap);
   endfunction: connect_phase

【问题讨论】:

    标签: system-verilog uvm


    【解决方案1】:

    uvm_config_db 是一种更好的传递接口的方法,建议使用它而不是 uvm_resource_db。 uvm_config_db 采用实例名称和上下文,我们可以使用它们准确定位哪个块获取配置值。

    //in Monitor 
    
      function void connect_phase ( uvm_phase phase ) ;
          uvm_config_db#(virtual pakmx_if_out)::get(.cntxt (this),.inst_name(""), .field_name("pakmx_if_out"), .value(vif_out));
      end function
    

    在代理中创建了两个监视器实例。由于监视器名称不同,我们将使用这些名称来传递这些监视器的不同接口实例。

    //build phase
    function void build_phase(uvm_phase phase);
    
      super.build_phase(phase);
      //agent_ap = new (.name("agent_ap"), .parent(this));
    
    
      pm_seqr = pakmx_sequencer::type_id::create(.name("pm_seqr"), .parent(this));
      pm_drvr = pakmx_driver::type_id::create(.name("pm_drvr"), .parent(this));
      pm_mon = pakmx_monitor::type_id::create(.name("pm_mon"), .parent(this));
      pm_mon1 = pakmx_monitor::type_id::create(.name("pm_mon1"), .parent(this));
    endfunction: build_phase
    

    来自顶级 TB。

     // from top 
     uvm_config_db#(virtual pakmx_if_out)::set(.cntxt(null), .inst_name("*pm_mon"), .field_name("pakmx_if_out"), .value(vif_out[0]));
     uvm_config_db#(virtual pakmx_if_out)::set(.cntxt(null), .inst_name("*pm_mon1"), .field_name("pakmx_if_out"), .value(vif_out[1]));
    

    这里的 instance_name 用于区分监视器的两个实例。使用“*”将前缀与监视器获得的名称相匹配。我们也可以指定完整/准确的路径。在这种情况下,无需为 config_db 中的实例指定不同的 field_name/name。

    链接解释了 uvm_config_db 的各种细微差别 https://www.synopsys.com/Services/Documents/hierarchical-testbench-configuration-using-uvm.pdf

    另一种解决方案 -

    如果两个接口可以有不同的 field_name。 代理可以获取这两个接口并在连接阶段将其分配给监视器。

    //connect phase
    function void connect_phase(uvm_phase phase);
    
      super.connect_phase(phase);
    
          uvm_config_db#(virtual pakmx_if_out)::get(.cntxt (null),.inst_name(""), .field_name("pakmx_if_out0"), .value(vif_out[0]));
          uvm_config_db#(virtual pakmx_if_out)::get(.cntxt(null), .inst_name(""),.field_name("pakmx_if_out1"), .value(vif_out[1]));
          pm_mon.vif_out = vif_out[0];
          pm_mon1.vif_out = vif_out[1];
    
      pm_drvr.seq_item_port.connect(pm_seqr.seq_item_export);
      pm_mon.mon_ap.connect(agent_ap);
    end function:connect_phase
    

    构建阶段实例化了监视器的两个实例。

    //build phase 
    function void build_phase(uvm_phase phase); super.build_phase(phase);
    
      agent_ap = new (.name("agent_ap"), .parent(this));
    
      pm_seqr = pakmx_sequencer::type_id::create(.name("pm_seqr"), .parent(this));
      pm_drvr = pakmx_driver::type_id::create(.name("pm_drvr"), .parent(this));
      pm_mon = pakmx_monitor::type_id::create(.name("pm_mon"), .parent(this));
      pm_mon1 = pakmx_monitor::type_id::create(.name("pm_mon1"), .parent(this));
    
    endfunction: build_phase
    

    从顶层 tb 。这里不需要给出任何具体的实例或上下文。仍然使用uvm_config_db。

     uvm_config_db#(virtual pakmx_if_out)::set(.cntxt(null), .inst_name(""), .field_name("pakmx_if_out0"), .value(vif_out[0]));
          uvm_config_db#(virtual pakmx_if_out)::set(.cntxt(null), .inst_name(""), .field_name("pakmx_if_out1"), .value(vif_out[1]));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      • 1970-01-01
      • 2023-03-25
      • 2011-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多