4. 配置UVM组件的层次结构
任务目标
在UVM验证环境中,组件之间的配置传递依赖正确的层次路径。本案例通过 uvm_config_db 设置组件的层次路径与参数,使目标组件能够正确获取配置,并验证配置机制的有效性。
环境依赖
- UVM-1.2 或更高版本(推荐 UVM-1.2)
- 仿真器:VCS、QuestaSim 或任何支持 UVM 的仿真工具
实现方案
构建一个最小验证环境:顶层 test 通过 uvm_config_db::set 向下层 env 和 agent 传递配置对象与参数。env 和 agent 在 build_phase 中通过 uvm_config_db::get 获取配置,并打印获取结果以验证层次路径正确。
关键完整代码
```systemverilog
// 文件: config_hierarchy_test.sv
`include "uvm_macros.svh"
import uvm_pkg::*;
// 配置对象:包含一个整型参数
class my_config extends uvm_object;
`uvm_object_utils(my_config)
int data = 0;
function new(string name = "my_config");
super.new(name);
endfunction
endclass
// 组件:agent(位于 env 之下)
class my_agent extends uvm_component;
`uvm_component_utils(my_agent)
my_config cfg;
int local_data;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(my_config)::get(this, "", "agent_cfg", cfg))
`uvm_fatal("GET_FAIL", "agent 无法获取配置")
else
`uvm_info("GET_OK", $sformatf("agent 获取配置成功, data=%0d", cfg.data), UVM_LOW)
// 获取整型参数
if (!uvm_config_db#(int)::get(this, "", "local_param", local_data))
`uvm_fatal("GET_FAIL", "agent 无法获取整型参数")
else
`uvm_info("GET_OK", $sformatf("agent 获取整型参数=%0d", local_data), UVM_LOW)
endfunction
endclass
// 组件:env(位于 test 之下)
class my_env extends uvm_component;
`uvm_component_utils(my_env)
my_agent agent;
my_config cfg;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// 从 test 获取配置
if (!uvm_config_db#(my_config)::get(this, "", "env_cfg", cfg))
`uvm_fatal("GET_FAIL", "env 无法获取配置")
else
`uvm_info("GET_OK", $sformatf("env 获取配置成功, data=%0d", cfg.data), UVM_LOW)
// 创建 agent 并传递配置
agent = my_agent::type_id::create("agent", this);
uvm_config_db#(my_config)::set(this, "agent", "agent_cfg", cfg);
uvm_config_db#(int)::set(this, "agent", "local_param", cfg.data * 2);
endfunction
endclass
// 测试:顶层入口
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_env env;
my_config cfg;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// 创建配置对象并设置值
cfg = my_config::type_id::create("cfg");
cfg.data = 42;
// 在 test 层设置配置
uvm_config_db#(my_config)::set(this, "env", "env_cfg", cfg);
// 创建 env
env = my_env::type_id::create("env", 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);
phase.raise_objection(this);
#100;
phase.drop_objection(this);
endtask
endclass
// 顶层模块
module top;
initial begin
run_test("my_test");
end
endmodule
```
运行方式
```bash
# 使用 QuestaSim 示例
vlib work
vlog +incdir+$UVM_HOME/src $UVM_HOME/src/uvm_pkg.sv config_hierarchy_test.sv
vsim -c -do "run -all; quit" work.top
```
验证方法与判定标准
- 观察输出:仿真日志中应依次出现
env 获取配置成功, data=42和agent 获取配置成功, data=42,以及agent 获取整型参数=84。 - 层次结构确认:
uvm_top.print_topology()打印的拓扑中应包含uvm_test_top.env.agent路径。 - 通过条件:无
GET_FAIL致命错误,且上述三条GET_OK信息全部打印,说明 config_db 的层次路径设置正确,参数传递成功。
关键点说明
- 路径匹配规则:
set中的第二个参数是相对于第一个参数(组件句柄)的路径。例如set(this, "env", "env_cfg", cfg)表示在this(test)的env子组件处设置env_cfg,而get中的this指向 env 自身,空字符串表示从当前组件查找。 - 类型匹配:
set与get必须使用相同的参数类型(如my_config或int),否则获取失败。 - 传递时机:父组件的
set必须在子组件build_phase执行之前完成。本案例中 test 在创建 env 之前先set,env 在创建 agent 之前先set,保证了时序正确。