3.9 学习UVM中的uvm_env类分为几步?

文章目录

  • 前言
  • [1. 定义](#1. 定义)
  • [2. 核心功能](#2. 核心功能)
  • [3. 适用场景](#3. 适用场景)
  • [4. 使用方法](#4. 使用方法)
  • [5. 完整代码示例](#5. 完整代码示例)
    • [5.1 事务类定义](#5.1 事务类定义)
    • [5.2 Monitor 类定义](#5.2 Monitor 类定义)
    • [5.3 Scoreboard 类定义](#5.3 Scoreboard 类定义)
    • [5.4 Agent 类定义](#5.4 Agent 类定义)
    • [5.5 Env 类定义](#5.5 Env 类定义)
    • [5.6 测试平台](#5.6 测试平台)
  • [6. 代码说明](#6. 代码说明)
  • [7. 总结](#7. 总结)

前言

以下是关于 UVM 中 uvm_env 的详细解释、核心功能、适用场景、使用方法以及一个完整的代码示例:


1. 定义

uvm_env 是 UVM(Universal Verification Methodology)中的一个重要组件类,用于封装验证环境的顶层结构。它是一个容器类,用于组织和管理验证环境中的其他组件(如 uvm_agentuvm_scoreboarduvm_subscriber 等)。uvm_env 是验证环境的最高层次,通常包含多个 uvm_agent 和其他功能组件。

uvm_env 的主要特点:

  • 是验证环境的顶层容器。
  • 封装了验证环境中的所有组件。
  • 支持层次化结构,可以嵌套其他 uvm_env

2. 核心功能

uvm_env 提供了以下核心功能:

  • 组件组织 :将验证环境中的组件(如 uvm_agentuvm_scoreboard 等)组织在一起。
  • 配置管理:通过配置对象(configuration object)配置验证环境的行为。
  • 层次化结构 :支持嵌套其他 uvm_env,构建复杂的验证环境。
  • 测试平台集成 :与 uvm_test 配合使用,构建完整的测试平台。

3. 适用场景

uvm_env 通常用于以下场景:

  • 顶层验证环境:用于构建验证环境的顶层结构。
  • 复杂验证环境 :在复杂的验证环境中,嵌套多个 uvm_env 以管理不同的功能模块。
  • 配置管理:通过配置对象管理验证环境的行为。
  • 组件复用:封装通用的验证环境,便于在不同测试中复用。

4. 使用方法

使用 uvm_env 的步骤如下:

  1. 定义类 :从 uvm_env 派生一个类,并定义其属性和方法。
  2. 构建组件 :在 build_phase 中创建和配置子组件(如 uvm_agentuvm_scoreboard 等)。
  3. 连接组件 :在 connect_phase 中连接子组件的端口和接口。
  4. 配置环境:通过配置对象设置验证环境的行为。
  5. 集成测试 :在 uvm_test 中实例化并运行 uvm_env

5. 完整代码示例

以下是一个完整的代码示例,展示如何使用 uvm_env 构建验证环境。

5.1 事务类定义

c 复制代码
// 定义一个从 uvm_sequence_item 派生的事务类
class my_transaction extends uvm_sequence_item;

  bit [7:0] data;
  bit [3:0] addr;
  bit       valid;

  // 注册类到 UVM 工厂
  `uvm_object_utils(my_transaction)

  // 构造函数
  function new(string name = "my_transaction");
    super.new(name);
  endfunction

  // 实现 print 方法
  virtual function void do_print(uvm_printer printer);
    printer.print_field("data",  this.data,  8);
    printer.print_field("addr",  this.addr,  4);
    printer.print_field("valid", this.valid, 1);
  endfunction

endclass

5.2 Monitor 类定义

c 复制代码
// 定义一个从 uvm_monitor 派生的监控类
class my_monitor extends uvm_monitor;

  // 定义 analysis port
  uvm_analysis_port #(my_transaction) ap;

  // 虚拟接口(用于访问 DUT 信号)
  virtual my_interface vif;

  // 注册类到 UVM 工厂
  `uvm_component_utils(my_monitor)

  // 构造函数
  function new(string name, uvm_component parent);
    super.new(name, parent);
    ap = new("ap", this);
  endfunction

  // 实现 run_phase
  virtual task run_phase(uvm_phase phase);
    forever begin
      my_transaction tx;

      // 等待信号有效
      @(posedge vif.clock iff vif.valid);

      // 创建事务对象
      tx = my_transaction::type_id::create("tx");

      // 捕捉信号并转换为事务
      tx.data  = vif.data;
      tx.addr  = vif.addr;
      tx.valid = vif.valid;

      // 打印事务
      `uvm_info("MONITOR", $sformatf("Captured transaction: data=0x%0h, addr=0x%0h, valid=%b", 
                                    tx.data, tx.addr, tx.valid), UVM_LOW)

      // 通过 analysis port 广播事务
      ap.write(tx);
    end
  endtask

endclass

5.3 Scoreboard 类定义

c 复制代码
// 定义一个从 uvm_scoreboard 派生的记分板类
class my_scoreboard extends uvm_scoreboard;

  // 预期事务队列
  my_transaction expected_queue[$];

  // 注册类到 UVM 工厂
  `uvm_component_utils(my_scoreboard)

  // 构造函数
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  // 实现 write 方法(用于接收事务)
  virtual function void write(my_transaction tx);
    my_transaction expected_tx;

    // 检查预期队列是否为空
    if (expected_queue.size() == 0) begin
      `uvm_error("SCOREBOARD", "Unexpected transaction received")
      return;
    end

    // 获取预期事务
    expected_tx = expected_queue.pop_front();

    // 比较事务
    if (!tx.compare(expected_tx)) begin
      `uvm_error("SCOREBOARD", "Transaction mismatch")
      `uvm_info("SCOREBOARD", $sformatf("Expected: data=0x%0h, addr=0x%0h, valid=%b", 
                                       expected_tx.data, expected_tx.addr, expected_tx.valid), UVM_LOW)
      `uvm_info("SCOREBOARD", $sformatf("Received: data=0x%0h, addr=0x%0h, valid=%b", 
                                       tx.data, tx.addr, tx.valid), UVM_LOW)
    end else begin
      `uvm_info("SCOREBOARD", "Transaction matched", UVM_LOW)
    end
  endfunction

  // 添加预期事务
  function void add_expected(my_transaction tx);
    expected_queue.push_back(tx);
  endfunction

endclass

5.4 Agent 类定义

c 复制代码
// 定义一个从 uvm_agent 派生的 agent 类
class my_agent extends uvm_agent;

  my_monitor    monitor;
  my_scoreboard scoreboard;

  // 注册类到 UVM 工厂
  `uvm_component_utils(my_agent)

  // 构造函数
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  // 构建组件
  virtual function void build_phase(uvm_phase phase);
    monitor    = my_monitor::type_id::create("monitor", this);
    scoreboard = my_scoreboard::type_id::create("scoreboard", this);
  endfunction

  // 连接组件
  virtual function void connect_phase(uvm_phase phase);
    monitor.ap.connect(scoreboard.write);
  endfunction

endclass

5.5 Env 类定义

c 复制代码
// 定义一个从 uvm_env 派生的 env 类
class my_env extends uvm_env;

  my_agent agent;

  // 注册类到 UVM 工厂
  `uvm_component_utils(my_env)

  // 构造函数
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  // 构建组件
  virtual function void build_phase(uvm_phase phase);
    agent = my_agent::type_id::create("agent", this);
  endfunction

endclass

5.6 测试平台

c 复制代码
// 测试平台
module testbench;
  initial begin
    // 创建测试类
    class my_test extends uvm_test;
      my_env env;

      // 注册类到 UVM 工厂
      `uvm_component_utils(my_test)

      // 构造函数
      function new(string name, uvm_component parent);
        super.new(name, parent);
      endfunction

      // 构建组件
      virtual function void build_phase(uvm_phase phase);
        env = my_env::type_id::create("env", this);
      endfunction

      // 运行测试
      virtual task run_phase(uvm_phase phase);
        my_transaction tx;

        phase.raise_objection(this);

        // 添加预期事务
        tx = my_transaction::type_id::create("tx");
        tx.data  = 8'hAA;
        tx.addr  = 4'h1;
        tx.valid = 1;
        env.agent.scoreboard.add_expected(tx);

        #100; // 模拟测试运行时间
        phase.drop_objection(this);
      endtask
    endclass

    // 启动测试
    initial begin
      run_test("my_test");
    end
  end
endmodule

6. 代码说明

  • 事务类my_transaction 定义了事务的属性和方法。
  • Monitor 类my_monitor 监控 DUT 的信号并转换为事务。
  • Scoreboard 类my_scoreboard 接收事务并与预期事务进行比较。
  • Agent 类my_agent 封装了 uvm_monitoruvm_scoreboard
  • Env 类my_env 封装了 uvm_agent,是验证环境的顶层容器。
  • 测试平台my_test 类用于构建和运行测试环境。

7. 总结

uvm_env 是 UVM 中用于构建验证环境顶层结构的关键组件。它封装了验证环境中的所有组件,并支持层次化结构和配置管理。以上示例展示了如何定义和使用 uvm_env,适用于实际的验证场景。

相关推荐
西岸行者2 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意2 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码2 天前
嵌入式学习路线
学习
毛小茛2 天前
计算机系统概论——校验码
学习
babe小鑫2 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms2 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下2 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。2 天前
2026.2.25监控学习
学习
im_AMBER2 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J2 天前
从“Hello World“ 开始 C++
c语言·c++·学习