UVM验证入门(5)-Phase机制

77 阅读8分钟

1. 概述

1.1 定义与目的

  UVM Phase是UVM验证方法学的核心调度机制,它将验证平台的构建、运行和清理过程划分为多个有序的阶段。每个phase都有特定的职责和执行顺序,确保验证环境的各个组件能够协调工作。

1.2 主要作用

  • 同步机制:保证所有组件在同一阶段完成相应操作
  • 自动化流程:自动调用各phase方法,减少手动控制
  • 标准化:提供统一的验证环境生命周期管理

2. Phase的分类

2.1 按执行方式分类

  • 函数Phase:同步执行,不消耗仿真时间
    • 包括:build_phase, connect_phase等
    • 特点:快速执行,无时间延迟
  • 任务Phase:异步执行,可消耗仿真时间
    • 包括:run_phase, reset_phase等
    • 特点:可包含延时语句,支持并发执行

2.2 按功能范畴分类

  • 构建阶段:环境组建和连接
  • 运行阶段:测试用例执行
  • 清理阶段:结果收集和报告

3. 所有Phase详解

在这里插入图片描述

3.1 构建阶段

build_phase

  • 功能:组件实例化和配置
  • 执行顺序:自顶向下(父组件→子组件)
  • 典型操作:创建子组件、获取配置

  build_phase在验证环境为常用的phase,如下为举例:

class my_driver extends uvm_driver;
    `uvm_component_utils(my_driver)
    virtual interface my_if vif;
    int driver_id;
    
    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        // 获取虚拟接口
        if (!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
            `uvm_error("NOVIF", "Virtual interface not set")
        // 获取配置参数
        if (!uvm_config_db#(int)::get(this, "", "driver_id", driver_id))
            driver_id = 0;
        // 创建子组件
        seq_item_port = new("seq_item_port", this);
    endfunction
endclass

connect_phase

  • 功能:组件间端口连接
  • 执行顺序:自底向上(子组件→父组件)
  • 典型操作:TLM端口连接、analysis port连接

  connect_phase在验证环境为常用的phase,如下为举例:

class my_env extends uvm_env;
    my_agent agent;
    my_scoreboard sb;
    
    function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
        // 连接 monitor 到 scoreboard
        agent.monitor.item_collected_port.connect(sb.item_fifo.analysis_export);
        // TLM 连接
        agent.driver.seq_item_port.connect(agent.sequencer.seq_item_export);
    endfunction
endclass

end_of_elaboration_phase

  • 功能:最终环境调整
  • 执行顺序:自底向上
  • 典型操作:环境完整性检查、最终配置

  在验证环境常在此phase打印验证环境的拓扑结构,如下为举例:

    function void test_case::end_of_elaboration_phase(uvm_phase phase);
        `uvm_info("test_case","test_case end_of_elaboration_phase called!",UVM_LOW)
        uvm_root::get().print_topology();
    endfunction

在这里插入图片描述

3.2 启动阶段

start_of_simulation_phase

  • 功能:仿真开始前准备
  • 执行顺序:自底向上
  • 典型操作:打印初始状态、设置初始值

3.3 运行阶段

核心任务Phase

  • run_phase:主要的测试逻辑执行
    • 与12个标准run phase并行执行
    • 通常用于实现主要测试场景

  run_phase在验证环境为常用的phase,如下为举例:

class my_driver extends uvm_driver;
    task run_phase(uvm_phase phase);
        phase.raise_objection(this);
        `uvm_info("DRIVER", "Driver run_phase started", UVM_MEDIUM)
        
        forever begin
            seq_item_port.get_next_item(req);
            drive_transaction(req);
            seq_item_port.item_done();
        end
        
        phase.drop_objection(this);
    endtask
    
    task drive_transaction(my_transaction tr);
        // 驱动信号到 DUT
        vif.valid <= 1'b1;
        vif.data <= tr.data;
        @(posedge vif.clk);
        vif.valid <= 1'b0;
    endtask
endclass

12个动态Phase

pre_reset_phase

  • 功能:复位开始前的准备工作
  • 典型操作:确保时钟稳定、保存复位前状态、初始化复位监控

reset_phase

  • 功能:执行复位操作
  • 典型操作:断言复位信号、验证复位状态、检查寄存器复位值

post_reset_phase

  • 功能:复位结束后的清理工作
  • 典型操作:释放复位信号、验证复位释放、准备配置阶段

pre_configure_phase

  • 功能:配置开始前的准备工作
  • 典型操作:准备配置数据、验证配置环境、初始化配置序列

configure_phase

  • 功能:执行系统配置
  • 典型操作:配置寄存器、设置工作模式、验证配置结果

post_configure_phase

  • 功能:配置结束后的清理工作
  • 典型操作:验证配置完整性、检查系统状态、准备主测试阶段

pre_main_phase

  • 功能:主测试开始前的准备工作
  • 典型操作:初始化测试序列、设置激励参数、启动监控组件

main_phase

  • 功能:执行主要测试功能
  • 典型操作:运行测试场景、生成业务流量、执行功能验证

post_main_phase

  • 功能:主测试结束后的清理工作
  • 典型操作:完成未决事务、停止激励生成、收集最终数据

pre_shutdown_phase

  • 功能:关闭开始前的准备工作
  • 典型操作:初始化关闭流程、保存关键信息、准备资源清理

shutdown_phase

  • 功能:执行系统关闭操作
  • 典型操作:停止所有进程、执行安全关闭、验证关闭状态

post_shutdown_phase

  • 功能:关闭结束后的最终工作
  • 典型操作:验证完全关闭、执行最终检查、准备仿真结束

4. Phase的执行机制

4.1 执行顺序规则

  • 自顶向下:build_phase(父→子)、final_phase
  • 自底向上:除build_phase和final_phase的phase
  • 同级组件:无固定顺序,不应依赖执行顺序

  通过一个简单的验证环境来说明,验证环境框图如下: 在这里插入图片描述

在这里插入图片描述

  上图红色框内为build_phase的顺序,可以看出顺序为test_case1->my_env->my_agent->my_driver,base_sequencer,从上层到下层;蓝色框内为connect_phase,顺序为:my_driver,base_sequencer->my_agent->my_env->test_case1。

4.2 任务Phase的并行性

  • 所有任务phase并行执行
  • run_phase与12个标准run phase同时运行
  • 需要通过phase_ready_to_end机制协调结束

  phase_ready_to_end 是 UVM 中一个高级的 objection 控制机制,用于在 phase 准备结束但尚未结束时进行最后的协调和清理。

4.3 phase跳转

  • 使用jump()方法可在特定条件下跳转phase
  • 谨慎使用,可能破坏验证环境稳定性
phase.jump(target_phase);

限制条件

  • 只能在任务 phase 中调用
  • 不能跳转到已经执行过的 phase 组
  • 不能跳转到其他 domain 的 phase
  • 需要所有相关组件都支持跳转

  如下为一个phase跳转举例,在main_phase中判断是否需要再次进行复位,如果需要,跳转到reset_phase再执行一次。

 task test_case1::reset_phase(uvm_phase phase);
        `uvm_info("test_case1", "test_case1 reset_phase called!",UVM_LOW)
        phase.raise_objection(this);
        `uvm_info("test_case1", "Applying system reset", UVM_MEDIUM)
        #100; // 模拟复位时间
        `uvm_info("test_case1", "Reset completed", UVM_MEDIUM)
        phase.drop_objection(this);
    endtask

    task test_case1::main_phase(uvm_phase phase);
        phase.raise_objection(this);

        `uvm_info("test_case1", "test_case1 main_phase called!",UVM_LOW)
        `uvm_info("test_case1", "Starting main operations", UVM_MEDIUM)
        #200;
        if (!need_second_reset) begin
            need_second_reset = 1;
            `uvm_warning("MAIN", "Detected condition requiring second reset - jumping to reset_phase")

            // 关键跳转代码
            phase.drop_objection(this);
            phase.jump(uvm_reset_phase::get());
            return; // 跳转后立即退出当前 phase
        end

        `uvm_info("test_case1", "Continuing normal operation after second reset", UVM_MEDIUM)
        phase.raise_objection(this);

    endtask

在这里插入图片描述

5. Objection 机制

5.1 核心概念

  Objection 机制控制任务 Phase 的执行时间,防止仿真提前结束。

virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);  // 开始保护
    #100;  // 执行任务
    phase.drop_objection(this);   // 结束保护
endtask

5.2 使用位置

  • Test 中:控制整个测试生命周期
  • Sequence 中:控制序列执行时间
  • 避免在:Driver、Monitor、Scoreboard 中使用
// Test 中控制
virtual task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    main_seq.start(sequencer);  // 启动序列
    phase.drop_objection(this);
endtask

5.3 一个比喻说明objection机制

  把 UVM Phase 比作一场会议:

  • raise_objection -> 有人举手:"我还有话要说"
  • drop_objection ,> 放下手:"我说完了"
  • Phase 结束 -> 当所有人都放下手时,会议结束

如果有人一直举着手不放下,会议就永远无法结束!

// 就像这样:
virtual task meeting(uvm_phase phase);
    phase.raise_objection(this);    //  举手发言
    present_my_ideas();             // 发表观点  
    phase.drop_objection(this);     //  放下手结束
endtask

  这样既保证了每个人都能充分发言,又能在完成后及时结束会议。

6. Phase的调试方法

# 查看phase执行详情
+UVM_PHASE_TRACE
+UVM_OBJECTION_TRACE

6.1 +UVM_PHASE_TRACE

作用:开启 UVM Phase 执行的详细跟踪信息

输出内容

  • 每个 Phase 的开始和结束时间
  • Phase 执行的层次结构
  • Phase 跳转和状态变化
  • 执行顺序和依赖关系

使用场景

  • 调试 Phase 执行顺序问题
  • 分析 Phase 跳转行为
  • 理解 UVM 调度机制

示例输出: UVM_INFOuvm_phase.svh(1403) @ 0: reporter [PH/TRC/SCHEDULED] Phase 'common.build' (id=190) Scheduled from phase common UVM_INFO uvm_phase.svh(1124) @ 0: reporter [PH/TRC/STRT] Phase 'common.build' (id=190) Starting phase UVM_INFOuvm_phase.svh(1381) @ 0: reporter [PH/TRC/DONE] Phase 'common.build' (id=190) Completed phase

6.2 +UVM_OBJECTION_TRACE

作用:开启 Objection 机制的详细跟踪信息

输出内容

  • Objection 的提起和丢弃时间点
  • Objection 计数器的变化
  • 关联的组件和描述信息
  • Phase 结束的条件判断

使用场景

  • 调试仿真挂起问题
  • 分析 Objection 使用是否正确
  • 追踪 Objection 生命周期

示例输出: UVM_INFO @ 400000: main_objection [OBJTN_TRC] Object uvm_test_top raised 1 objection(s): count=1 total=1 UVM_INFO @ 400000: main_objection [OBJTN_TRC] Object uvm_top added 1 objection(s) to its total (raised from source object uvm_test_top): count=0 total=1 UVM_INFO @ 700000: main_objection [OBJTN_TRC] Object uvm_test_top dropped 1 objection(s): count=0 total=0 UVM_INFO @ 700000: main_objection [OBJTN_TRC] Object uvm_test_top all_dropped 1 objection(s): count=0 total=0 UVM_INFO @ 700000: main_objection [OBJTN_TRC] Object uvm_top subtracted 1 objection(s) from its total (dropped from source object uvm_test_top): count=0 total=0 UVM_INFO @ 700000: main_objection [OBJTN_TRC] Object uvm_top subtracted 1 objection(s) from its total (all_dropped from source object uvm_test_top): count=0 total=0

上一篇:UVM验证入门(4)-TLM1.0 下一篇:UVM验证入门(6)-config_db机制

参考文档:UVM_Cl ass_Reference_Manual_1.0.pdf