uvm的config机制举例

 为了增强uvm环境的可复用性,通过外部的参数配置,在环境在创建组件之前就已经实现资源的配置。这些都是通过uvm机制中的uvm_config_db配置类实现的。

可以实现:

  1. 传递virtual interface到验证环境中
  2. 传递变量值,如int型变量,string,enum型变量
  3. 可传递句柄(object),内含多种变量类型,多个组件变量,打包传递
//声明if
interface uvm_config_if;
  logic [31:0] addr;
  logic [31:0] data;
  logic [ 1:0] op;
endinterface

package uvm_config_pkg;
  import uvm_pkg::*;
  `include "uvm_macros.svh"
  //子类句柄
  class config_obj extends uvm_object;
    int comp1_var;
    int comp2_var;//定义cog_obj内容,两个变量var1,var2
    `uvm_object_utils(config_obj)
    function new(string name = "config_obj");//初始化
      super.new(name);
    endfunction
  endclass
  
  class comp2 extends uvm_component;
    int var2;
    virtual uvm_config_if vif;  
    config_obj cfg; 
    `uvm_component_utils(comp2)
    function new(string name = "comp2", uvm_component parent = null);
      super.new(name, parent);
      var2 = 200;//initial var
    endfunction
    function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      if(!uvm_config_db#(virtual uvm_config_if)::get(this, "", "vif", vif))  
    //如果config_db非空,传递config_if类型的指针,从test中get vif到路径this.vif.   
  
      uvm_config_db#(int)::get(this, "", "var2", var2);//变量的传递,get var2到this.var2中
      uvm_config_db#(config_obj)::get(this, "", "cfg", cfg); //obj的传递,封装两个变量     
    endfunction
  endclass

  class uvm_config_test extends uvm_test;
    comp2 c2;//声明c2
    config_obj cfg;//声明 cfg
    `uvm_component_utils(uvm_config_test)
    function new(string name = "uvm_config_test", uvm_component parent = null);
      super.new(name, parent);
    endfunction
    function void build_phase(uvm_phase phase);
      super.build_phase(phase); 
      cfg = config_obj::type_id::create("cfg");
      cfg.comp2_var = 100;//cfg初始配置为var2=100
      uvm_config_db#(config_obj)::set(this, "*", "cfg", cfg);//通过obj传递将cfg值更新:100
      uvm_config_db#(int)::set(this, "c2", "var2", 10);//通过变量传递将var2赋值为10
      c2 = comp2::type_id::create("c2", this);//必须先配置再创建实例
    endfunction
    task run_phase(uvm_phase phase);
      super.run_phase(phase);
      phase.raise_objection(this);
      #1us;
      phase.drop_objection(this);
    endtask
  endclass
endpackage

module uvm_config;

  import uvm_pkg::*;
  `include "uvm_macros.svh"
  import uvm_config_pkg::*;
  
  uvm_config_if if0();

  initial begin
    uvm_config_db#(virtual uvm_config_if)::set(uvm_root::get(), "uvm_test_top.*", "vif", if0);//接口的传递set只在top中可见
    run_test(""); // empty test name
end
endmodule

 config_db内部是通过查找表方式索引变量值的,在test或top中set入变量值/句柄/obj,和当前路径,在底层组件中通过get(路径,变量名)的方式成功获取value。

但是要注意以下几点

1.传递类型必须一致:若定义类型均为父类句柄,传递的却是子类句柄cfg时,子类句柄按照父类句柄传递了,在组件内get到父类句柄类型,却指向子类对象,此时必须要做类型转化,将父类句柄$cast转化为子类句柄,才能传递成功

2.先set,后get,后create

3.*表示通配,如“*comp1”表示当前及以下层次遍历,“*.comp1”表示当前以下层次。

 

你可能感兴趣的:(UVM)