3. 学习UVM的核心组件

文章目录

  • 前言
  • [一、UVM 核心组件详解](#一、UVM 核心组件详解)
    • [1. uvm_component](#1. uvm_component)
    • [2. uvm_object](#2. uvm_object)
    • [3. uvm_driver](#3. uvm_driver)
    • [4. uvm_monitor](#4. uvm_monitor)
    • [5. uvm_agent](#5. uvm_agent)
    • [6. uvm_sequencer](#6. uvm_sequencer)
    • [7. uvm_sequence](#7. uvm_sequence)
    • [8. uvm_sequence_item](#8. uvm_sequence_item)
    • [9. uvm_scoreboard](#9. uvm_scoreboard)
    • [10. uvm_env](#10. uvm_env)
    • [11. uvm_test](#11. uvm_test)
  • 二、相互关系
  • 三、综合示例

前言

UVM(Universal Verification Methodology)是一种广泛应用于硬件验证领域的标准方法学,旨在提高验证流程的可重用性和可扩展性。UVM 提供了一套预定义的类和方法,用于创建模块化、可重用的验证环境。


一、UVM 核心组件详解

UVM(Universal Verification Methodology)是一种广泛应用于硬件验证领域的标准方法学,旨在提高验证流程的可重用性和可扩展性。UVM 提供了一套预定义的类和方法,用于创建模块化、可重用的验证环境。以下是一些核心组件及其作用和相互关系的详细介绍:

1. uvm_component

uvm_component 是 UVM 中所有组件的基类,如 uvm_driver、uvm_monitor、uvm_agent、uvm_scoreboard 等。它支持层次结构、相位机制和报告机制。

  • 层次结构:每个 uvm_component 实例都是 UVM 树形结构的节点,可以有多个子节点。
  • 相位机制:组件可以参与 UVM 的相位机制,组织仿真过程中的不同阶段,如构建、连接、运行和清理。
  • 报告机制:组件可以使用 UVM 的消息基础设施报告事件、警告和错误。

定义示例:

c 复制代码
class my_component extends uvm_component;
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
	virtual function void build_phase(uvm_phase phase);
        // 构建组件
    endfunction
	virtual function void connect_phase(uvm_phase phase);
        // 连接组件
    endfunction
endclass

2. uvm_object

uvm_object 是 UVM 中所有对象的基类,提供了字段自动化机制和身份鉴别方法。

  • 字段自动化:提供 print、copy、pack 等方法。
  • 身份鉴别:提供 get_name、get_type_name、get_full_name 等方法。

定义示例:

c 复制代码
class my_object extends uvm_object;
    function new(string name = "my_object");
        super.new(name);
    endfunction
	virtual function void do_print(uvm_printer printer);
        // 自定义打印方法
    endfunction
endclass

3. uvm_driver

uvm_driver 负责将事务驱动到 DUT(Design Under Test)的接口上。它通常从 uvm_sequencer 获取事务,并将其转换为 DUT 可以理解的信号。

定义示例:

c 复制代码
class my_driver extends uvm_driver #(my_transaction);
    virtual my_interface vif;
	function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
	virtual task run_phase(uvm_phase phase);
        forever begin
            seq_item_port.get_next_item(req);
            // 对 req 进行处理,发送事务到 DUT
            vif.signal = req.data;
            seq_item_port.item_done();
        end
    endtask
endclass

4. uvm_monitor

uvm_monitor 负责监视 DUT 的接口,并将事务捕获到事务对象中。它通常将捕获的事务发送到 uvm_scoreboard 或其他组件进行进一步处理。

定义示例:

c 复制代码
class my_monitor extends uvm_monitor;
    uvm_analysis_port #(my_transaction) item_collected_port;
    virtual my_interface vif;
	function new(string name, uvm_component parent);
        super.new(name, parent);
        item_collected_port = new("item_collected_port", this);
    endfunction
	virtual task run_phase(uvm_phase phase);
        forever begin
            // 监视 DUT 的接口并捕获事务
            my_transaction trans = my_transaction::type_id::create("trans");
            trans.data = vif.signal;
            item_collected_port.write(trans);
        end
    endtask
endclass

5. uvm_agent

uvm_agent 是一个组合组件,通常包含一个 uvm_driver、一个 uvm_monitor 和一个 uvm_sequencer。它负责管理这些组件的交互,提供一个完整的验证接口。

定义示例:

c 复制代码
class my_agent extends uvm_agent;
    my_driver m_driver;
    my_sequencer m_sequencer;
    my_monitor m_monitor;
	function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
	virtual function void build_phase(uvm_phase phase);
        m_driver = my_driver::type_id::create("m_driver", this);
        m_sequencer = my_sequencer::type_id::create("m_sequencer", this);
        m_monitor = my_monitor::type_id::create("m_monitor", this);
    endfunction
	virtual function void connect_phase(uvm_phase phase);
        m_driver.seq_item_port.connect(m_sequencer.seq_item_export);
    endfunction
endclass

6. uvm_sequencer

uvm_sequencer 负责管理事务的生成和发送。它从 uvm_sequence 获取事务,并将其发送到 uvm_driver。

定义示例:

c 复制代码
class my_sequencer extends uvm_sequencer #(my_transaction);
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
endclass

7. uvm_sequence

uvm_sequence 用于生成事务序列。它可以生成单个事务或多个事务的序列,并将它们发送到 uvm_sequencer。

定义示例:

c 复制代码
class my_sequence extends uvm_sequence #(my_transaction);
    function new(string name = "my_sequence");
        super.new(name);
    endfunction
	virtual task body();
        `uvm_info(get_type_name(), "Executing my_sequence", UVM_LOW)
        // 创建和发送事务
        my_transaction trans = my_transaction::type_id::create("trans");
        start_item(trans);
        trans.randomize();
        finish_item(trans);
    endtask
endclass

8. uvm_sequence_item

uvm_sequence_item 是所有事务的基类。它定义了事务的基本结构和方法,可以被 uvm_sequence 和 uvm_driver 使用。

定义示例:

c 复制代码
class my_transaction extends uvm_sequence_item;
    rand int data;
function new(string name = "my_transaction");
        super.new(name);
    endfunction
virtual function void do_print(uvm_printer printer);
        printer.print_field_int("data", data, $bits(data));
    endfunction
endclass

9. uvm_scoreboard

uvm_scoreboard 用于验证 DUT 的行为是否正确。它通常接收来自 uvm_monitor 的事务,并进行比较和验证。

定义示例:

c 复制代码
class my_scoreboard extends uvm_scoreboard;
    uvm_analysis_imp #(my_transaction, my_scoreboard) item_collected_export;
	function new(string name, uvm_component parent);
        super.new(name, parent);
        item_collected_export = new("item_collected_export", this);
    endfunction
	virtual function void write(my_transaction t);
        // 处理接收到的事务
        `uvm_info(get_type_name(), "Received transaction", UVM_LOW)
    endfunction
endclass

10. uvm_env

uvm_env 是验证环境的顶层组件,通常包含多个 uvm_agent、uvm_scoreboard 和其他组件。它负责管理整个验证环境的构建和运行。

定义示例:

c 复制代码
class my_env extends uvm_env;
    my_agent m_agent;
    my_scoreboard m_scoreboard;
	function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
	virtual function void build_phase(uvm_phase phase);
        m_agent = my_agent::type_id::create("m_agent", this);
        m_scoreboard = my_scoreboard::type_id::create("m_scoreboard", this);
    endfunction
	virtual function void connect_phase(uvm_phase phase);
        // 连接 agent 和 scoreboard
        m_agent.m_monitor.item_collected_port.connect(m_scoreboard.item_collected_export);
    endfunction
endclass

11. uvm_test

uvm_test 是测试用例的顶层组件,通常包含一个 uvm_env 和多个 uvm_sequence。它负责启动验证过程,并管理测试的运行。

定义示例:

c 复制代码
class my_test extends uvm_test;
    my_env m_env;
function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
virtual function void build_phase(uvm_phase phase);
        m_env = my_env::type_id::create("m_env", this);
    endfunction
virtual task run_phase(uvm_phase phase);
        my_sequence seq = my_sequence::type_id::create("seq");
        phase.raise_objection(this);
        seq.start(m_env.m_agent.m_sequencer);
        phase.drop_objection(this);
    endtask
endclass

二、相互关系

  • uvm_test:作为测试的入口点,创建和配置 uvm_env 和 uvm_sequence。
  • uvm_env:管理验证环境中的多个 uvm_agent、uvm_scoreboard 和其他组件。
  • uvm_agent:包含 uvm_driver、uvm_monitor 和 uvm_sequencer,负责驱动和监视 DUT 的接口。
  • uvm_driver:从 uvm_sequencer 获取事务并驱动到 DUT。
  • uvm_monitor:监视 DUT 的接口并捕获事务,发送到 uvm_scoreboard。
  • uvm_sequencer:管理事务的生成和发送,从 uvm_sequence 获取事务。
  • uvm_sequence:生成事务序列,发送到 uvm_sequencer。
  • uvm_sequence_item:定义事务的基本结构和方法。
  • uvm_scoreboard:验证 DUT 的行为是否正确,接收来自 uvm_monitor 的事务。

相互关系

  1. uvm_test:
    ○ 包含 uvm_env:管理验证环境。
    ○ 包含 uvm_sequence:管理测试序列。
    ○ 启动验证过程:通过 run_phase 方法启动测试。
  2. uvm_env:
    ○ 包含多个 uvm_agent:管理多个验证接口。
    ○ 包含 uvm_scoreboard:验证 DUT 的行为。
    ○ 配置组件间通信:通过 connect_phase 方法连接组件。
  3. uvm_agent:
    ○ 包含 uvm_driver:驱动事务到 DUT。
    ○ 包含 uvm_monitor:监视 DUT 的接口。
    ○ 包含 uvm_sequencer:管理事务序列。
    ○ 连接组件:通过 connect_phase 方法连接 uvm_driver 和 uvm_sequencer。
  4. uvm_driver:
    ○ 从 uvm_sequencer 获取事务:通过 seq_item_port 获取事务。
    ○ 驱动事务到 DUT:将事务转换为 DUT 可以理解的信号。
    5. uvm_monitor:
    ○ 监视 DUT 的接口:捕获 DUT 的信号并转换为事务对象。
    ○ 发送事务:将捕获的事务发送到 uvm_scoreboard 或其他组件。
  5. uvm_sequencer:
    ○ 从 uvm_sequence 获取事务:通过 start_item 和 finish_item 方法获取事务。
    ○ 发送事务到 uvm_driver:通过 seq_item_port 发送事务。
  6. uvm_sequence:
    ○ 生成事务序列:通过 start_item 和 finish_item 方法生成事务。
    ○ 发送事务到 uvm_sequencer:通过 start 方法启动序列。
  7. uvm_sequence_item:
    ○ 定义事务结构:提供事务的基本字段和方法。
    ○ 支持字段自动化:提供 print、copy、pack 等方法。
  8. uvm_scoreboard:
    ○ 接收事务:通过 uvm_analysis_port 接收事务。
    ○ 比较和验证:比较接收到的事务和参考模型的数据,判断 DUT 是否正确工作。
  9. uvm_object:
    ○ 字段自动化:提供 print、copy、pack 等方法。
    ○ 身份鉴别:提供 get_name、get_type_name、get_full_name 等方法。

三、综合示例

以下是一个综合示例,展示了如何使用这些核心组件构建一个简单的验证环境:

c 复制代码
// my_transaction.sv
class my_transaction extends uvm_object;
    rand int data;
    rand bit [31:0] address;
	function new(string name = "my_transaction");
        super.new(name);
    endfunction
	constraint c_data { data > 0; }
    constraint c_address { address < 1024; }
	virtual function void do_print(uvm_printer printer);
        super.do_print(printer);
        printer.print_field_int("data", data, $bits(data));
        printer.print_field_int("address", address, $bits(address));
    endfunction
endclass
c 复制代码
// my_driver.sv
class my_driver extends uvm_driver#(my_transaction);
    virtual my_if vif;
	function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
	virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        if (!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
            `uvm_fatal("NOVIF", "Cannot get virtual interface")
    endfunction
	virtual task run_phase(uvm_phase phase);
        forever begin
            seq_item_port.get_next_item(req);
            vif.data = req.data;
            vif.address = req.address;
            seq_item_port.item_done();
        end
    endtask
endclass
c 复制代码
// my_monitor.sv
class my_monitor extends uvm_monitor;
    virtual my_if vif;
    uvm_analysis_port#(my_transaction) analysis_port;
	function new(string name, uvm_component parent);
        super.new(name, parent);
        analysis_port = new("analysis_port", this);
    endfunction
	virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        if (!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
            `uvm_fatal("NOVIF", "Cannot get virtual interface")
    endfunction
	virtual task run_phase(uvm_phase phase);
        forever begin
            my_transaction trans = new();
            trans.data = vif.data;
            trans.address = vif.address;
            analysis_port.write(trans);
        end
    endtask
endclass
c 复制代码
// my_sequencer.sv
class my_sequencer extends uvm_sequencer#(my_transaction);
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
endclass
c 复制代码
// my_agent.sv
class my_agent extends uvm_agent;
    my_driver driver;
    my_monitor monitor;
    my_sequencer sequencer;
	function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
	virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        driver = my_driver::type_id::create("driver", this);
        monitor = my_monitor::type_id::create("monitor", this);
        sequencer = my_sequencer::type_id::create("sequencer", this);
    endfunction
	virtual function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
        driver.seq_item_port.connect(sequencer.seq_item_export);
    endfunction
endclass
c 复制代码
// my_scoreboard.sv
class my_scoreboard extends uvm_scoreboard;
    uvm_tlm_fifo#(my_transaction) exp_fifo;
    uvm_tlm_fifo#(my_transaction) act_fifo;
	function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
	virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        exp_fifo = new("exp_fifo", this);
        act_fifo = new("act_fifo", this);
    endfunction
	virtual task run_phase(uvm_phase phase);
        my_transaction exp_trans, act_trans;
        forever begin
            exp_fifo.get(exp_trans);
            act_fifo.get(act_trans);
            if (exp_trans != act_trans) begin
                `uvm_error("SB", "Transaction mismatch")
            end
        end
    endtask
endclass
c 复制代码
// my_env.sv
class my_env extends uvm_env;
    my_agent agent;
    my_scoreboard scoreboard;
	function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
	virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        agent = my_agent::type_id::create("agent", this);
        scoreboard = my_scoreboard::type_id::create("scoreboard", this);
    endfunction
	virtual function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
        agent.monitor.analysis_port.connect(scoreboard.exp_fifo.analysis_export);
    endfunction
endclass
c 复制代码
// my_test.sv
class my_test extends uvm_test;
    my_env env;
	function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
	virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        env = my_env::type_id::create("env", this);
    endfunction
	virtual task run_phase(uvm_phase phase);
        my_sequence seq = my_sequence::type_id::create("seq");
        seq.start(env.agent.sequencer);
    endtask
endclass
相关推荐
西岸行者4 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意4 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码4 天前
嵌入式学习路线
学习
毛小茛4 天前
计算机系统概论——校验码
学习
babe小鑫4 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms4 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下4 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。4 天前
2026.2.25监控学习
学习
im_AMBER4 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习