我们是通过uvm_config_db去get到的class句柄,但是当get的值,更换了,module不知道什么时候重新get,所以为了独立,写了下面的文章:
第一部分:定义虚拟类 base_set_cfg
virtual class base_set_cfg extends uvm_object; function new(string name = "base_set_cfg"); super.new(name); endfunction // 纯虚拟函数,子类需要实现 pure virtual function void set_my_cfg(test_cfg cfg); endclass
解释:
base_set_cfg
是一个虚拟类,继承自uvm_object
。- 定义了一个纯虚拟函数
set_my_cfg
,要求子类实现该函数。
第二部分:在module里定义 module_get
类
class module_get extends base_set_cfg; `uvm_object_utils_begin(module_get) `uvm_object_utils_end function new(string name = "module_get"); super.new(name); endfunction function void set_my_cfg(test_cfg cfg); // 实现基类的纯虚拟函数 this.set_my_cfg = cfg; endfunction endclass
解释:
module_get
类继承自base_set_cfg
,并实现了set_my_cfg
方法。- 使用
uvm_object_utils
宏注册该类以便于 UVM 工具的工厂机制。
第三部分:在 module
中通过 uvm_config_db
发送指针
module my_module; initial begin // 在配置数据库中注册 `module_get` 类的实例 uvm_config_db#(base_set_cfg)::set(null, "*", "get_cfg", module_get::type_id::create("module_get")); end endmodule
解释:
- 使用
uvm_config_db#(base_set_cfg)::set
将module_get
的实例注册到配置数据库中。 - 这样,在其他地方可以通过
uvm_config_db
获取到这个实例。
第四部分:在 env
中获取并使用指针
class my_env extends uvm_env; base_set_cfg set_cfg; test_cfg cfg; function void build_phase(uvm_phase phase); super.build_phase(phase); // 从配置数据库中获取 `base_set_cfg` 类型的指针 if (!uvm_config_db#(base_set_cfg)::get(null, get_full_name(), "get_cfg", set_cfg)) begin `uvm_fatal("GET_CFG_FAIL", "Get get_cfg failed") end // 随机化配置 cfg.randomize(); // 调用 `set_my_cfg` 方法 set_cfg.set_my_cfg(cfg); endfunction endclass
解释:
- 在
build_phase
中,使用uvm_config_db#(base_set_cfg)::get
从配置数据库中获取base_set_cfg
的指针。 - 如果获取失败,使用
uvm_fatal
输出错误信息。 - 随机化配置
cfg
,然后通过调用set_my_cfg
方法将cfg
传递给set_cfg
。
总结
- 定义虚拟类
base_set_cfg
,并在其中声明纯虚拟函数set_my_cfg
。 - 定义具体实现类
module_get
,继承自base_set_cfg
并实现set_my_cfg
。 - 在
module
中注册module_get
实例到uvm_config_db
。 - 在
env
中获取base_set_cfg
指针,并使用它来调用set_my_cfg
。
这样,通过 uvm_config_db
可以在不同的组件之间共享配置对象,并根据需要进行操作。