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
相关推荐
s_little_monster1 小时前
【Linux】进程地址空间
linux·运维·服务器·经验分享·笔记·学习·学习方法
晓晓暮雨潇潇1 小时前
FPGA开发技能(10)热电偶测温ADS1118方案
fpga开发·verilog·热电偶·ads1118·温度测试方案
程序员林北北2 小时前
【Golang学习之旅】gRPC 与 REST API 的对比及应用
java·开发语言·后端·学习·云原生·golang
蝈蝈ly3 小时前
WPF学习
学习·wpf
L_Whhjjj4 小时前
c语言函数学习
c语言·学习
朝屯暮蒙vi4 小时前
(五)Spring Boot学习——spring security +jwt使用(前后端分离模式)
spring boot·学习·spring·spring security
keep-learner5 小时前
Unity Dots理论学习-5.与ECS相关的概念
学习·unity·游戏引擎·ecs
羊小猪~~5 小时前
MYSQL学习笔记(七):新年第一篇之子查询
数据库·笔记·后端·sql·学习·mysql·考研
siy23336 小时前
[c语言日记]动态规划入门:杨辉三角
c语言·开发语言·笔记·学习·算法·动态规划
bylander6 小时前
【AI学习】DeepSeek为什么强?
人工智能·gpt·学习