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,保证了时序正确。