uvm config_db

1、uvm object 使用config_db。
<1>. uvm_object中通过config_db get得到变量

class my_config extends uvm_object;
    `uvm_object_utils(my_config)
    virtual my_if vif;
    function new(string name = "my_config");
        super.new(name);
        $display("%s", get_full_name());
        if(!uvm_config_db#(virtual my_if)::get(null, get_full_name(), "vif", vif))
        `uvm_fatal("my_config", "please set interface")
     //get函数原型中,第一个参数必须是一个component
所以这里不能使用this指针,只能使用null或者uvm_root

     //通过名字get_full_name()得到,即其实例化时指定的名字
     //使用null时,UVM会自动将其替换为uvm_root::get(),再加上第二个参数get_full_name() ,就可以完整地得到此object的路径 
endfunction
endclass

function void base_test::build_phase(uvm_phase phase);
    …
    cfg = new("cfg");
endfunction

module top_tb;
… 
initial begin
    uvm_config_db#(virtual my_if)::set(null, "cfg", "vif", input_if);
end
//所以,base_test中实例化cfg的名字要与top_tb中config_db::set的路径参数一致。

<2>. uvm_object中通过config_db set变量

class case0_sequence extends uvm_sequence #(my_transaction);
    …
    virtual task pre_body();
      if(uvm_config_db#(int)::get(null, get_full_name(), "count", count))
        `uvm_info("seq0", $sformatf("get count value %0d via config_db", count), UVM_MEDIUM)
      else
        `uvm_error("seq0", "can't get count value!")
      #10000;
      uvm_config_db#(bit)::set(uvm_root::get(), "uvm_test_top.env0.scb","cmp_en", 0);
    //可以set 到uvm_component中。

    ...
    void'(uvm_config_db#(bit)::get(uvm_root::get(), get_full_name(), "first_start", first_start)
    if(first_start)
    `uvm_info("drv0_seq", "this is the first start of the sequence", UVM_MEDIUM)
    else
    `uvm_info("drv0_seq", "this is not the first start of the sequence",UVM_MEDIUM)
    uvm_config_db#(bit)::set(uvm_root::get(), "uvm_test_top.v_sqr.*", "first_start", 0);
    //这个sequence向自己传递了一个参数:first_start。在一次仿真中,当此sequence第一次启动时,其first_start值为1
    //
当后面再次启动时,其first_start0。根据first_start值的不同,可以在body中有不同的行为。
    //由于此sequencevirtual sequence中被启动,所以其get_full_name的结果应该是uvm_test_top.v_sqr.*,而不
uvm_test_top.env0.i_agt.sqr.* 
    endtask
    …
endclass

2、uvm_config_db的方法:

<1> set()方法:所有静态函数和方法在使用时,called using域操作符::

  set 方法设置为静态函数,才实现了set的变量全局可见。

  static function void set (  uvm_component cntxt,
                              string        inst_name,
                              string        field_name,
                              T             value);
 
  virtual function void build_phase (uvm_phase phase);
    ...
    uvm_config_db #(int) :: set (null, "uvm_test_top.m_env.m_apb_agent", "cov_enable", 1);
    ...
  endfunction
  // Set virtual interface handle under name "apb_vif" available to all components below uvm_test_top, indicated by the *
  uvm_config_db #(virtual apb_if) :: set (null, "uvm_test_top.*", "apb_vif", apb_if);   
 
  // Set an int variable to turn on coverage collection for all components under m_apb_agent
  uvm_config_db #(int) :: set (null, "uvm_test_top.m_env.m_apb_agent.*", "cov_enable", 1);
 
  // Consider you are in agent's build_phase then you may achieve the same effect by
  uvm_config_db #(int) :: set (this, "*", "cov_enable", 1);

 <2> get 方法设置为静态函数,才实现了get变量全局可见

  static function bit get (  uvm_component cntxt,
                               string        inst_name,
                               string        field_name,
                       inout   T             value);

// Get virtual interface handle under name "apb_vif" into local virtual interface handle at m_env level
    uvm_config_db #(virtual apb_if) :: get (this, "*", "apb_vif", apb_if);
    
    // Get int variable fails because no int variable found in given scope
    uvm_config_db #(int) :: get (null, "uvm_test_top", "cov_enable", cov_var);

<3> exists() 检查 field_name 在inst_name中是否存在,存在返回1,不存在则返回0

  static function bit exists (  uvm_component cntxt,
                                string        inst_name,
                                string        field_name,
                                bit           spell_chk);
  // Check if interface handle exists at the given scope
  if (! uvm_config_db #(virtual apb_if) :: exists (this, "*", "apb_vif"))
    `uvm_error ("VIF", "Could not find an interface handle", UVM_MEDIUM)

<4>. wait_modified()

block 直到要get的变量有改动
  static task wait_modified ( uvm_component cntxt,
                              string        inst_name,
                              string        field_name);

  class my_agent extends uvm_agent;
 
  virtual task run_phase (uvm_phase phase);
      ...
      // Waits until loopCount variable gets a new value
      uvm_config_db #(int) :: wait_modified (this, "", "loopCount");
    endtask
  endclass
 
  class my_env extends uvm_env;
 
    my_agent m_apb_agent;
 
    virtual task main_phase (uvm_phase phase);
      ...
      // Update loopCount variable in database
      for (int i = 0; i < N; i++) begin
        ...
        uvm_config_db #(int) :: set (this, "m_apb_agent", "loopCount", i);
      end
    endtask
  endclass

<5>. typedef 定义的一些宏

  typedef  uvm_config_db #(uvm_bitstream_t)     uvm_config_int;
  typedef  uvm_config_db #(string)              uvm_config_string;
  typedef  uvm_config_db #(uvm_object)          uvm_config_object;
  typedef  uvm_config_db #(uvm_object_wrappet)  uvm_config_wrapper;
 

 

posted on 2019-04-11 10:55  hematologist  阅读(1017)  评论(0编辑  收藏  举报

导航