7.2 uvm_resource_db in UVM

uvm_resource_db是一个类型参数化 type-parameterized的类,它是资源数据库顶部的一个方便层(convenience layer)。这个便利层简化了对低级数据库的访问,并且没有添加新功能。因此,uvm_resource_db不是从uvm_resource类派生的。
以下uvm_resource_db类的代码段取自uvm源代码。

class uvm_resource_db #(type T=uvm_object);

  typedef uvm_resource #(T) rsrc_t;

  protected function new();
  endfunction

  static function rsrc_t get_by_name(string scope, string name,
                                     bit rpterr=1);
    return rsrc_t::get_by_name(scope, name, rpterr);
  endfunction
  static function void set(input string scope, input string name,
                           T val, input uvm_object accessor = null);
    rsrc_t rsrc = new(name, scope);
    rsrc.write(val, accessor);
    rsrc.set();
    ...    
    ...
  endfunction

  ...
  ...
endclass

注:

  1. 这个uvm_resource_db类未实例化
  2. 它使用一组静态函数来操作资源和资源池。因此,必须使用范围解析操作符( ::)来调用它们。

        例如:uvm_resource_db #(整数)::设置(…);

     3. 如果+UVM_RESOURCE_DB_TRACE作为命令行参数提供,它会打印所有资源数据库的访问(写入和读取)。

1. uvm_resource_db methods

所有函数都是下表中提到的静态函数

7.2 uvm_resource_db in UVM_第1张图片

2. uvm_resource_db example

在下面的示例中,control位存储在数据库中,作为在component_B中为my_component创建对象的启用条件(enable condition)。

名为“control”、类型为bit的新资源将从测试用例添加到资源池中。

uvm_resource_db #(bit)::set("*", "control", 1, this);

//where,
//string scope = “*”;
//string name = “control”;
//T val = 1;
//uvm_object accessor =  this;

//In component_B, 
if(!uvm_resource_db #(bit)::read_by_name(get_full_name(), "control", ctrl))
  `uvm_fatal(get_type_name(), "read_by_name failed for resource in this scope");

使用read_by_name静态函数检索资源,该函数在名称为“control”的数据库中查找。如果read_by_name在数据库中找不到“control”字符串名,将报告致命错误。尽管致命检查不是强制性的,但建议将其用于调试目的。一旦表中的查找成功,存储在资源数据库中的值就会在局部变量ctrl中更新。此控制位用于控制my_component对象的创建。

`include "uvm_macros.svh"
import uvm_pkg::*;

class component_A #(parameter ID_WIDTH = 8) extends uvm_component;
  bit [ID_WIDTH-1:0] id;
  `uvm_component_param_utils(component_A #(ID_WIDTH))
  
  function new(string name = "component_A", uvm_component parent = null);
    super.new(name, parent);
    id = 1;
  endfunction
  
  function display();
    `uvm_info(get_type_name(), $sformatf("inside component_A: id = %0d", id), UVM_LOW);
  endfunction
endclass

class mycomponent #(parameter ID_WIDTH = 8) extends uvm_component;
  bit [ID_WIDTH-1:0] id;
  `uvm_component_param_utils(mycomponent #(ID_WIDTH))
  
  function new(string name = "mycomponent", uvm_component parent = null);
    super.new(name, parent);
    id = 2;
  endfunction
  
  function display();
    `uvm_info(get_type_name(), $sformatf("inside mycomponent: id = %0d", id), UVM_LOW);
  endfunction
endclass

class component_B #(int ID_WIDTH = 8) extends component_A #(ID_WIDTH);
  bit ctrl;
  bit [ID_WIDTH-1:0] id;
  mycomponent #(8) my_comp;
  `uvm_component_param_utils(component_B #(ID_WIDTH))
  
  function new(string name = "component_B", uvm_component parent = null);
    super.new(name, parent);
    id = 3;
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    if(!uvm_resource_db #(bit)::read_by_name(get_full_name(), "control", ctrl))
      `uvm_fatal(get_type_name(), "read_by_name failed for resource in this scope");
    if(ctrl)  my_comp = mycomponent #(8)::type_id::create("my_comp", this);
    
  endfunction
  
  function display();
    `uvm_info(get_type_name(), $sformatf("inside component_B: id = %0d, ctrl = %0d", id, ctrl), UVM_LOW);
    if(ctrl) void'(my_comp.display());
  endfunction
endclass

class my_test extends uvm_test;
  bit control;
  `uvm_component_utils(my_test)
  component_A #(32) comp_A;
  component_B #(16) comp_B;
  
  function new(string name = "my_test", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    comp_A = component_A #(32)::type_id::create("comp_A", this);
    comp_B = component_B #(16)::type_id::create("comp_B", this);
    
    uvm_resource_db #(bit)::set("*", "control", 1, this);
  endfunction
   
  function void end_of_elaboration_phase(uvm_phase phase);
    super.end_of_elaboration_phase(phase);
    uvm_top.print_topology();
  endfunction
  
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    void'(comp_A.display());
    void'(comp_B.display());
  endtask
endclass

module tb_top;
  initial begin
    run_test("my_test");
  end
endmodule

Output:

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  my_test        -     @1809
  comp_A      uvm_component  -     @1876
  comp_B      uvm_component  -     @1907
    my_comp   uvm_component  -     @1954
----------------------------------------

UVM_INFO testbench.sv(14) @ 0: uvm_test_top.comp_A [uvm_component] inside component_A: id = 1
UVM_INFO testbench.sv(52) @ 0: uvm_test_top.comp_B [uvm_component] inside component_B: id = 3, ctrl = 1
UVM_INFO testbench.sv(28) @ 0: uvm_test_top.comp_B.my_comp [uvm_component] inside mycomponent: id = 2

你可能感兴趣的:(UVM,UVM)