UVM验证入门(2)-uvm常用类的继承关系

1.概述

UVM(Universal Verification Methodology)采用基于类的面向对象编程,通过清晰的继承关系构建了一个层次化的验证框架。理解这些继承关系对于掌握UVM至关重要,它帮助我们:

  • 正确选择基类来派生用户自定义类
  • 理解各类的功能边界和适用场景
  • 构建可重用、可维护的验证环境
  • 充分利用UVM框架提供的自动化功能

如下图,描绘了常用类的继承关系。

2. 根基类:uvm_void与uvm_object

2.1 uvm_void - 所有UVM类的抽象根基

uvm_void类是一个纯粹的抽象基类,没有任何成员变量或方法,用户自定义的类基本上不会直接继承于此类。

systemverilog 复制代码
virtual class uvm_void;
endclass

2.2 uvm_object - 数据实体的核心基类

核心功能特性:

  • 字段自动化:uvm_field_*宏支持自动复制、比较、打印
  • 工厂模式:支持类型重载和对象创建
  • 对象方法:提供copy()、clone()、compare()、print()等
systemverilog 复制代码
virtual class uvm_object extends uvm_void;

2.2.1 copy()方法

复制对象内容,目标对象需先存在,copy()方法为浅复制

systemverilog 复制代码
// 使用示例
my_transaction src_tr, dst_tr;

src_tr = my_transaction::type_id::create("src_tr");
dst_tr = my_transaction::type_id::create("dst_tr");

// 随机化源对象
assert(src_tr.randomize() with { data == 8'hFF; addr == 4'hA; });

// 复制对象
dst_tr.copy(src_tr);

// 验证复制结果
if (dst_tr.data == src_tr.data && dst_tr.addr == src_tr.addr) 
    `uvm_info("COPY", "Copy successful", UVM_LOW)

2.2.2 clone()方法

创建对象的完整副本,返回新对象,clone()方法为浅复制

systemverilog 复制代码
// 使用示例
module clone_example;
    import uvm_pkg::*;
    `include "uvm_macros.svh"
    
    initial begin
        my_transaction src_tr, dst_tr;
        
        // 创建并随机化源对象
        src_tr = my_transaction::type_id::create("src_tr");
        assert(src_tr.randomize() with { data == 8'hFF; addr == 4'hA; });
        
        `uvm_info("SOURCE", $sformatf("Source: data=0x%0h, addr=0x%0h", 
                                     src_tr.data, src_tr.addr), UVM_LOW)
        
        // 使用clone创建副本 - 一行代码完成创建和复制
        dst_tr = src_tr.clone();
        
        `uvm_info("CLONE", $sformatf("Clone: data=0x%0h, addr=0x%0h", 
                                    dst_tr.data, dst_tr.addr), UVM_LOW)
        
        // 验证复制结果
        if (dst_tr.data == src_tr.data && dst_tr.addr == src_tr.addr) 
            `uvm_info("CLONE", "Clone successful", UVM_LOW)
        
        // 修改克隆对象,验证原始对象不受影响
        dst_tr.data = 8'hAA;
        dst_tr.addr = 4'h5;
        
        `uvm_info("AFTER MODIFY", 
            $sformatf("Source: data=0x%0h, addr=0x%0h\nClone: data=0x%0h, addr=0x%0h",
                     src_tr.data, src_tr.addr, dst_tr.data, dst_tr.addr), UVM_LOW)
    end
endmodule

2.2.3 compare()方法

比较两个对象是否相等

systemverilog 复制代码
// 使用示例
my_transaction tr1, tr2;

tr1 = my_transaction::type_id::create("tr1");
tr2 = my_transaction::type_id::create("tr2");

assert(tr1.randomize() with { data == 8'hAA; });
assert(tr2.randomize() with { data == 8'hAA; });

if (tr1.compare(tr2))
    `uvm_info("COMPARE", "Objects are equal", UVM_LOW)
else
    `uvm_warning("COMPARE", "Objects differ")

2.2.4 print()和sprint()方法

格式化输出对象内容

systemverilog 复制代码
// 使用示例
my_transaction tr = my_transaction::type_id::create("tr");
assert(tr.randomize());

// 方法1: 使用 print()
tr.print();  // 自动格式化输出,无返回值

// 方法2: 使用 convert2string()
`uvm_info("PRINT", tr.convert2string(), UVM_LOW)

// 方法3: 使用 sprint(),返回字符串
string obj_str = tr.sprint();
$display("Object as string: %s", obj_str);

3. 核心组件类:uvm_component及其派生类详解

3.1 uvm_component - 验证组件的根基

核心特性:

  • phase机制:参与build、connect、run、report等UVM phase
  • 层次结构:具有父子关系的固定硬件层级
  • 配置机制:支持uvm_config_db配置
  • 工厂注册:支持组件重载

3.2 关键组件应用场景

3.2.1 uvm_driver - 信号驱动者

继承关系:uvm_void->umv_object->uvm_report_object->uvm_component->uvm_driver。 应用场景:

  • 将抽象的事务级数据转换为具体的信号时序
  • 实现特定协议的总线驱动
  • 控制 DUT 的输入信号时序
systemverilog 复制代码
class bus_driver extends uvm_driver #(bus_transaction);
    `uvm_component_utils(bus_driver)
    
    virtual bus_interface vif;
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
    
    task run_phase(uvm_phase phase);
        forever begin
            seq_item_port.get_next_item(req);
            drive_transaction(req);
            seq_item_port.item_done();
        end
    endtask
    
    task drive_transaction(bus_transaction trans);
        // 协议具体的驱动逻辑
        vif.addr <= trans.addr;
        vif.data <= trans.data;
        vif.valid <= 1'b1;
        @(posedge vif.clk);
        wait(vif.ready);
        vif.valid <= 1'b0;
    endtask
endclass

3.2.2 uvm_monitor - 接口监视器

继承关系:uvm_void->umv_object->uvm_report_object->uvm_component->uvm_monitor。 应用场景:

  • 监测 DUT 接口信号变化
  • 采集事务数据并发送给其他组件
  • 协议检查和错误检测
systemverilog 复制代码
class bus_monitor extends uvm_monitor;
    `uvm_component_utils(bus_monitor)
    
    uvm_analysis_port #(bus_transaction) ap;
    virtual bus_interface vif;
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
        ap = new("ap", this);
    endfunction
    
    task run_phase(uvm_phase phase);
        forever begin
            bus_transaction trans;
            @(posedge vif.clk);
            if(vif.valid && vif.ready) begin
                trans = bus_transaction::type_id::create("trans");
                trans.addr = vif.addr;
                trans.data = vif.data;
                ap.write(trans);  // 发送采集到的事务
            end
        end
    endtask
endclass

3.2.3 uvm_sequencer - 序列调度器

继承关系:uvm_void->umv_object->uvm_report_object->uvm_component->uvm_sequencer_base->uvm_sequencer_param_base0>uvm_sequencer。 应用场景:

  • 调度和控制测试序列的执行
  • 管理多个序列的优先级和仲裁
  • 提供序列的重用和组合
systemverilog 复制代码
class bus_sequencer extends uvm_sequencer #(bus_transaction);
    `uvm_component_utils(bus_sequencer)
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
endclass

// 使用示例
class test_seq extends uvm_sequence #(bus_transaction);
    `uvm_object_utils(test_seq)
    
    task body();
        bus_transaction trans;
        repeat(10) begin
            trans = bus_transaction::type_id::create("trans");
            assert(trans.randomize());
            `uvm_send(trans)
        end
    endtask
endclass

3.2.4 uvm_agent - 组件容器

继承关系:uvm_void->umv_object->uvm_report_object->uvm_component->uvm_agent。 应用场景:

  • 封装相关的 driver、monitor、sequencer
  • 支持主动和被动两种模式
  • 提供模块级的验证组件重用
systemverilog 复制代码
class bus_agent extends uvm_agent;
    `uvm_component_utils(bus_agent)
    
    bus_driver     driver;
    bus_sequencer  sequencer;
    bus_monitor    monitor;
    uvm_analysis_port #(bus_transaction) ap;
    
    uvm_active_passive_enum is_active = UVM_ACTIVE;
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
    
    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        monitor = bus_monitor::type_id::create("monitor", this);
        ap = monitor.ap;
        
        if(is_active == UVM_ACTIVE) begin
            driver = bus_driver::type_id::create("driver", this);
            sequencer = bus_sequencer::type_id::create("sequencer", this);
        end
    endfunction
    
    function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
        if(is_active == UVM_ACTIVE) begin
            driver.seq_item_port.connect(sequencer.seq_item_export);
        end
    endfunction
endclass

3.2.5 uvm_env - 验证环境

继承关系:uvm_void->umv_object->uvm_report_object->uvm_component->uvm_env。 应用场景:

  • 集成多个 agent 和其他验证组件
  • 配置整个验证环境的参数
  • 管理组件间的连接关系
systemverilog 复制代码
class bus_env extends uvm_env;
    `uvm_component_utils(bus_env)
    
    bus_agent       agent;
    bus_scoreboard  scoreboard;
    bus_coverage    coverage;
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
    
    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        agent = bus_agent::type_id::create("agent", this);
        scoreboard = bus_scoreboard::type_id::create("scoreboard", this);
        coverage = bus_coverage::type_id::create("coverage", this);
    endfunction
    
    function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
        agent.ap.connect(scoreboard.analysis_export);
        agent.ap.connect(coverage.analysis_export);
    endfunction
endclass

3.2.6 uvm_test - 测试用例

继承关系:uvm_void->umv_object->uvm_report_object->uvm_component->uvm_test。 应用场景:

  • 定义具体的测试场景和激励
  • 配置验证环境参数
  • 控制测试的启动和结束
systemverilog 复制代码
class read_write_test extends uvm_test;
    `uvm_component_utils(read_write_test)
    
    bus_env env;
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
    
    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        env = bus_env::type_id::create("env", this);
        
        // 配置测试参数
        uvm_config_db#(uvm_active_passive_enum)::set(
            this, "env.agent", "is_active", UVM_ACTIVE);
    endfunction
    
    task run_phase(uvm_phase phase);
        read_write_sequence seq;
        phase.raise_objection(this);
        seq = read_write_sequence::type_id::create("seq");
        seq.start(env.agent.sequencer);
        phase.drop_objection(this);
    endtask
endclass

3.2.7 uvm_scoreboard - 数据检查器

继承关系:uvm_void->umv_object->uvm_report_object->uvm_component->uvm_scoreboard。 应用场景:

  • 比较 DUT 输出与预期结果
  • 统计测试通过率和错误信息
  • 提供功能正确性验证
systemverilog 复制代码
class bus_scoreboard extends uvm_scoreboard;
    `uvm_component_utils(bus_scoreboard)
    
    uvm_analysis_imp #(bus_transaction, bus_scoreboard) analysis_export;
    
    // 预期结果队列
    bus_transaction expected_queue[$];
    int error_count = 0;
    int total_count = 0;
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
        analysis_export = new("analysis_export", this);
    endfunction
    
    function void write(bus_transaction trans);
        bus_transaction expected;
        total_count++;
        
        if(expected_queue.size() > 0) begin
            expected = expected_queue.pop_front();
            if(!trans.compare(expected)) begin
                error_count++;
                `uvm_error("SCOREBOARD", 
                    $sformatf("Data mismatch! Expected: %0h, Got: %0h", 
                    expected.data, trans.data))
            end
        end
    endfunction
    
    function void report_phase(uvm_phase phase);
        `uvm_info("SCOREBOARD",
            $sformatf("Test Summary: Total=%0d, Errors=%0d, Pass Rate=%.2f%%",
            total_count, error_count, 
            (total_count-error_count)*100.0/total_count), UVM_LOW)
    endfunction
endclass

3.2.8 uvm_subscriber - 数据订阅者

继承关系:uvm_void->umv_object->uvm_report_object->uvm_component->uvm_subscriber。 应用场景:

  • 收集功能覆盖率数据
  • 统计事务特征分布
  • 性能分析和监控
systemverilog 复制代码
class bus_coverage extends uvm_subscriber #(bus_transaction);
    `uvm_component_utils(bus_coverage)
    
    bus_transaction cov_trans;
    
    covergroup bus_cg;
        addr_cp: coverpoint cov_trans.addr {
            bins low    = {[0:32'h0000_FFFF]};
            bins mid    = {[32'h0001_0000:32'hFFFF_0000]};
            bins high   = {[32'hFFFF_0001:32'hFFFF_FFFF]};
        }
        data_cp: coverpoint cov_trans.data {
            bins zero   = {0};
            bins small  = {[1:255]};
            bins large  = {[256:32'hFFFF_FFFF]};
        }
        rw_cp: coverpoint cov_trans.rw;
    endgroup
    
    function new(string name, uvm_component parent);
        super.new(name, parent);
        bus_cg = new;
    endfunction
    
    function void write(bus_transaction t);
        cov_trans = t;
        bus_cg.sample();
    endfunction
    
    function void report_phase(uvm_phase phase);
        `uvm_info("COVERAGE", 
            $sformatf("Functional Coverage: %.2f%%", 
            bus_cg.get_inst_coverage()), UVM_LOW)
    endfunction
endclass

4. 事务与序列的继承关系

4.1 transaction

用户自定义的事务transaction继承自uvm_sequence_item类。继承关系:uvm_void->umv_object->uvm_transaction->uvm_sequence_item->user_transaction。 应用场景:

  • 数据建模:transaction用于建模在验证组件之间传递的数据项。例如,一个总线读写操作、一个网络数据包或一个存储器访问都可以建模为一个transaction。
  • 随机激励生成:transaction通常包含随机字段和约束,用于生成随机的激励数据。
  • 数据记录和比较:transaction可以记录仿真的输入和输出,并用于比较预期和实际结果。
  • 功能覆盖:transaction中的字段可以用来定义功能覆盖点,以衡量测试的完整性。
systemverilog 复制代码
class bus_transaction extends uvm_sequence_item;
   rand bit [31:0] addr;
   rand bit [31:0] data;
   rand bit        read_write; // 0为读,1为写

   `uvm_object_utils_begin(bus_transaction)
      `uvm_field_int(addr, UVM_ALL_ON)
      `uvm_field_int(data, UVM_ALL_ON)
      `uvm_field_int(read_write, UVM_ALL_ON)
   `uvm_object_utils_end

   constraint addr_c { addr inside {[0:32'h1000]}; }
   constraint data_c { data inside {[0:32'hFFFF]}; }

   function new(string name = "bus_transaction");
      super.new(name);
   endfunction
endclass

4.2 sequence

用户自定义的序列sequence继承自uvm_sequence类。继承关系:uvm_void->umv_object->uvm_transaction->uvm_sequence_item->uvm_sequence_base->uvm_sequence->user_sequence。 应用场景:

  • 测试场景生成:sequence用于生成特定的测试场景,例如连续读写、错误注入、特定模式的数据传输等。
  • 激励控制:sequence可以控制激励的时序、数量和类型,从而创建复杂的测试序列。
  • 重用和组合:简单的sequence可以组合成更复杂的sequence,提高代码的重用性。
  • 同步和协调:sequence可以同步多个sequencer,协调多个接口的激励生成。
systemverilog 复制代码
class simple_read_write_sequence extends uvm_sequence #(bus_transaction);
   `uvm_object_utils(simple_read_write_sequence)

   function new(string name = "simple_read_write_sequence");
      super.new(name);
   endfunction

   virtual task body();
      bus_transaction trans;

      // 写操作
      trans = bus_transaction::type_id::create("trans");
      start_item(trans);
      assert(trans.randomize() with { read_write == 1; });
      finish_item(trans);

      // 读操作
      trans = bus_transaction::type_id::create("trans");
      start_item(trans);
      assert(trans.randomize() with { read_write == 0; });
      finish_item(trans);
   endtask
endclass

5. 实用工具类:配置、回调等辅助类的继承关系

5.1 配置管理类

uvm_config_db用于验证环境的配置,其继承于uvm_resource_db这个模板类,继承关系:uvm_resource_db->uvm_config_db。

systemverilog 复制代码
class uvm_config_db #(type T=int) extends uvm_resource_db #(T);
    // 提供set()/get()静态方法
endclass
uvm_resource_db - 底层资源管理

class uvm_resource_db #(type T=uvm_object);
    // 隐式继承自SystemVerilog的object类
endclass

5.2 回调机制类

用户自定义的回调类继承自uvm_callback类,继承关系:uvm_void->umv_object->uvm_callback->user_callback。

systemverilog 复制代码
class uvm_callback extends uvm_object;
    // 支持前置/后置回调方法
endclass
应用示例:

class driver_callback extends uvm_callback;
    virtual task pre_tx(ref transaction tr);
        // 错误注入、延迟控制等
    endtask
endclass

6. 总结

本文主要阐述了UVM(Universal Verification Methodology)中关键类的继承关系,为理解和构建高效的验证环境提供了坚实的基础。通过清晰的层次化分类,为后续的学习提供重要的参考。

上一篇:UVM验证入门(1)-uvm是什么 下一篇:UVM验证入门(3)-factory工厂机制

参考文档:UVM_Cl ass_Reference_Manual_1.0.pdf

相关推荐
二狗就是我4 小时前
YOLOv5 移植 RK3588 踩坑记录
嵌入式
编程墨客1 天前
基于ESP8266的智能桌面天气站
嵌入式·diy
csdn_aspnet2 天前
嵌入式赋能生活的各个领域
嵌入式·生活
s1ckrain3 天前
数字逻辑笔记—绪论
笔记·嵌入式
闲猿类4 天前
嵌入式第九天学习
linux·c语言·学习·算法·嵌入式
SundayBear4 天前
嵌入式操作系统进阶C语言
c语言·开发语言·嵌入式
一枝小雨4 天前
单片机内存布局管理:sct分散加载详解
stm32·单片机·嵌入式·编译链接·sct分散加载·单片机内存布局
飞凌嵌入式4 天前
飞凌嵌入式RK3568开发板的TFTP烧写文件系统指南
linux·嵌入式硬件·嵌入式
SundayBear5 天前
C语言复杂类型声明完全解析:从右左原则到工程实践
c语言·开发语言·数据结构·嵌入式