UVM拥有一个内部数据库表,我们可以将数值存储在指定名称下,后续可由其他测试平台组件检索。uvm_config_db类在uvm_resource_db基础上提供便捷接口,用于简化uvm_component实例的基本交互方式。需注意所有函数均为静态函数,必须使用::作用域运算符调用。
这种配置数据库允许我们在不同名称下存储各种配置设置,可在不修改实际测试平台代码的情况下按需配置测试平台组件。例如,若要启用某个agent的功能覆盖度收集,我们只需指定该agent路径,并将配置数据库中某个变量值设为1。该agent可检查此变量值,若发现已启用则开始收集覆盖度数据。
set()
static function void set ( uvm_component cntxt,
string inst_name,
string field_name,
T value);
使用类的静态函数uvm_config_db
在配置数据库中设置变量。在以下示例中,set()
函数将在路径uvm_test_top.m_env.m_apb_agent
处设置一个名为cov_enable
的变量,其值为1。
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()
将为 cntxt
中的 inst_name
创建或更新 field_name
的配置设置。该设置以 cntxt
为基准,其完整作用域为 {cntxt, ".", inst_name}
。若 cntxt
为空,则获取信息的完整作用域将由 inst_name
提供。
// 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);
请注意,在最后一个例子中,cntxt
是this
,它将被替换为当前组件的路径,在本例中即"uvm_test_top.m_env.m_apb_agent"。如上所述,完整作用域将变为"uvm_test_top.m_env.m_apb_agent.*"。
get()
static function bit get ( uvm_component cntxt,
string inst_name,
string field_name,
inout T value);
使用此静态函数从配置数据库中获取给定字段名field_name
的变量值。请注意,仅当作用域条件为真时才会返回值。例如,如果您曾在作用域uvm_test_top.m_env.m_func_cov
下通过字段名m_cfg
设置过变量,那么您必须提供相同的作用域或符合该表达式条件的作用域,才能检索该字段名下的值。其中cntxt
是起始搜索路径,与inst_name
拼接后构成完整作用域。
// 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);
exists()
static function bit exists ( uvm_component cntxt,
string inst_name,
string field_name,
bit spell_chk);
检查从组件cntxt
起始,在inst_name
中是否存在字段field_name
的值。若在指定作用域中该字段不存在,函数将返回零值。当预期该字段应存在于数据库中时,可将参数spell_chk
设为1以启用拼写检查功能。
// 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)
wait_modified()
static task wait_modified ( uvm_component cntxt,
string inst_name,
string field_name);
使用此任务将阻止执行后续语句,直到在范围 {cntxt.inst_name} 中指定的 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
Convenience tasks
以下是参数化版本的uvm_config_db
的几个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;