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
注:
- 这个uvm_resource_db类未实例化
- 它使用一组静态函数来操作资源和资源池。因此,必须使用范围解析操作符( ::)来调用它们。
例如:uvm_resource_db #(整数)::设置(…);
3. 如果+UVM_RESOURCE_DB_TRACE作为命令行参数提供,它会打印所有资源数据库的访问(写入和读取)。
1. uvm_resource_db methods
所有函数都是下表中提到的静态函数
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