我如何创建2个监视器实例到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

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

From top-level 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

从顶层开始。这里不需要给出任何特定的实例或上下文。仍然使用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]));

最新更新