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,适用于实际的验证场景。

相关推荐
Shining059616 分钟前
Datawhale AI 夏令营—科大讯飞AI大赛(大模型技术)—让大模型理解表格数据(列车信息表)
人工智能·学习·其他
希望奇迹很安静2 小时前
SSRF_XXE_RCE_反序列化学习
学习·web安全·ctf·渗透测试学习
悦悦子a啊2 小时前
Python之--字典
开发语言·python·学习
kmjyccc2 小时前
生活毫无头绪就毫无头绪吧(7.24)
学习·生活
heyilunv3 小时前
昇思学习营-Deepseek-r1-distill-qwen-1.5b模型开发与适配课程内容和学习心得
学习
胡耀超4 小时前
我们如何写好提示词、发挥LLM能力、写作指南:从认知分析到动态构建的思维方法
人工智能·python·学习·大模型·llm·提示词·八要素思维
waveee1234 小时前
学习嵌入式的第三十一天-数据结构-(2025.7.23)网络协议封装
学习
冷崖5 小时前
Redis缓存策略以及bigkey的学习(九)
redis·学习·缓存
墨染枫5 小时前
pytorch学习笔记-使用DataLoader加载固有Datasets(CIFAR10),使用tensorboard进行可视化
pytorch·笔记·学习
武昌库里写JAVA6 小时前
vue+iview+i18n国际化
java·开发语言·spring boot·学习·课程设计