来源:qingxuanxx/sv_uvm_axi_notes · Copyright (c) 2026 qingxuanxx。按 MIT 许可 引用;内容版本:aa3213b。本站调整标题、栏目导航与阅读链接。

返回 UVM 学习笔记目录 · 下一章

第 1 章 · UVM 概念与验证方法学

核心结论:UVM 不是一种新的编程语言,而是一套用 SystemVerilog 实现的通用验证方法学和类库。它帮助验证工程师统一验证平台的结构、组件通信、测试组织和复用方式。

记忆主线:需求说明书 -> 特性列表 -> 设计与验证并行实现 -> 对比 DUT 行为 -> 定位并修正问题;SystemVerilog 提供语言能力,UVM 提供组织这些能力的方法。


1.0 本章定位

第 1 章不急着讲 UVM 类、宏和 phase,而是先回答三个问题:

  1. 为什么现代 IC 项目必须进行专门的验证?
  2. 为什么有了 SystemVerilog 还需要验证方法学?
  3. 为什么在多种方法学中选择 UVM?

本章属于 UVM 学习的“地图章节”。 它不直接教我们搭建验证平台,却决定了后续知识应该放在什么位置理解。

本章主题要回答的问题
验证流程验证在 IC 开发过程中处于什么位置
验证语言Verilog、SystemC、SystemVerilog 各有什么特点
方法学为什么只掌握语言还不够
UVM 选择UVM 相比 VMM、OVM 有什么优势
学习价值验证工程师和设计工程师分别能获得什么

学习提示:本章出现的许多术语会在后续章节变成具体代码。现在先记住它们解决什么问题,不必提前死记 API。

与教材目录的对应关系

本笔记为了方便零基础阅读,把教材 1.1 中的几个主题拆开讲,但内容没有省略:

教材小节本笔记位置
1.1.1 验证在现代 IC 流程中的位置1.2
1.1.2 验证的语言1.3
1.1.3 何谓方法学1.4、1.5
1.1.4 为什么是 UVM1.6
1.1.5 UVM 的发展史1.7
1.2.1 验证工程师1.8.1
1.2.2 设计工程师1.8.2

零基础阅读提示

  • 这一章先建立地图,不要求会写 UVM 代码。
  • 看到 driver、monitor、scoreboard 时,先把它们理解成“发送者、观察者、裁判”。
  • 看到 transaction 时,先理解成“一次完整的数据包或总线操作”。
  • 看到方法学时,理解成“大家约定用同一种方式搭平台”,而不是新的语法。
  • 第一次阅读只要能说清楚“为什么需要 UVM”就足够,历史版本和组织名称以后再记。

1.1 UVM 是什么(🟡 中)

1.1.1 一句话定义(🟡 中)

UVM 的全称是 Universal Verification Methodology,即“通用验证方法学”。 可以从两个角度理解它:

角度对 UVM 的理解
使用者角度一套可直接使用和扩展的 SystemVerilog 类库
工程角度一套组织验证平台、测试用例和验证流程的规范

UVM 不是:

  • 新的硬件描述语言。
  • RTL 设计语言的替代品。
  • 自动发现所有 bug 的工具。
  • 不需要验证计划就能使用的万能框架。
  • 一套只属于某家 EDA 厂商的私有库。

UVM 是:

  • 建立在 SystemVerilog 之上的验证类库。
  • 多家 EDA 厂商共同支持的行业方法学。
  • 对验证平台常见问题的标准化解决方案。
  • 提高组件复用性和测试组织效率的工程框架。
  • 从 OVM、VMM 等方法学演化而来的统一方案。

关系式:SystemVerilog 是语言基础,UVM 是基于该语言实现的方法学库。


1.2 验证在现代 IC 流程中的位置(🟢 低)

1.2.1 从需求到特性列表(🟢 低)

现代 IC 前端开发通常从需求说明书开始。 需求说明书描述产品希望实现什么,但通常还不够具体,不能直接写成 RTL 或测试平台。 工程团队需要把需求进一步细化成特性列表。 特性列表是设计和验证共同工作的起点。

文档主要内容主要使用者
需求说明书产品目标、用户需求、总体功能产品与项目团队
特性列表可实现、可检查的功能条目设计与验证团队
设计规格说明书架构、接口、时序、资源和异常处理设计工程师
验证规格说明书平台结构、测试方法、检查方法和完备性验证工程师

特性列表必须尽量做到:

  • 每条特性含义明确。
  • 可以被设计实现。
  • 可以被验证检查。
  • 正常行为和异常行为都有说明。
  • 输入条件和预期输出尽量清晰。

如果特性本身含糊,设计和验证可能各自形成不同理解。 这时即使 RTL 与测试平台都“按自己的理解正确”,两者仍会不一致。

1.2.2 设计与验证并行展开(🟢 低)

特性列表确定后,设计和验证进入并行路径。

flowchart TD
    A[需求说明书] --> B[特性列表]
    B --> C[设计规格说明书]
    B --> D[验证规格说明书]
    C --> E[Verilog RTL 实现]
    D --> F[SystemVerilog/UVM 验证平台]
    E --> G{DUT 行为与预期一致吗}
    F --> G
    G -- 是 --> H[当前验证目标完成]
    G -- 否 --> I[定位设计或验证问题]
    I --> E
    I --> F

这里最重要的不是工具名称,而是设计与验证都源于同一份特性列表。

设计路径验证路径
把特性转换为 RTL把特性转换为测试与检查
关注如何实现功能关注如何证明功能正确
输出 DUT输出验证平台和测试用例
根据失败结果修正 RTL根据调试结果修正平台或测试

验证不是等设计完全结束后才开始。 验证工程师可以在 RTL 完成前:

  • 阅读需求和特性列表。
  • 参与接口与异常行为评审。
  • 编写验证规格说明书。
  • 规划验证平台架构。
  • 准备参考模型和检查策略。
  • 设计第一批测试用例。

这种并行工作能更早发现规格问题,也能缩短 RTL 完成后的验证时间。

1.2.3 DUT 与 DUV(🟢 低)

DUT 是 Design Under Test 的缩写,表示被测试设计。 DUV 是 Design Under Verification 的缩写,表示被验证设计。 两者在很多语境中可以表示同一对象。 本书统一使用 DUT。

缩写英文中文理解
DUTDesign Under Test被测试设计
DUVDesign Under Verification被验证设计
RTLRegister Transfer Level寄存器传输级描述
ICIntegrated Circuit集成电路

记忆:看到 DUT 时,不要把它局限为整个芯片;一个模块、子系统或完整 SoC 都可以成为 DUT。

1.2.4 验证到底要保证什么(🟢 低)

验证的核心目标是确认从特性列表到 RTL 的转换是否正确。 至少包括以下四类问题。 1. 行为一致性 DUT 在规定输入和状态下的输出,是否符合特性列表和设计规格。 例如:

  • 接口握手是否符合时序要求。
  • 数据变换结果是否正确。
  • 寄存器读写行为是否一致。
  • 状态机跳转是否符合协议。

2. 功能完整性 DUT 是否实现了特性列表中的全部特性。 “已经实现的功能没有出错”不等于“所有功能都已经实现”。 验证既要发现错误实现,也要发现遗漏实现。 3. 异常处理正确性 DUT 遇到异常状况时,反应是否与规格一致。 例如:

  • 非法命令是否被拒绝。
  • 缓冲区溢出是否报告错误。
  • 超时是否产生中断。
  • 校验失败是否丢弃错误数据。
  • 复位期间输出是否进入规定状态。

4. 异常恢复能力 DUT 不仅要识别异常,还要能够回到正常工作状态。 验证应继续追问:

  • 错误标志是否能正确清除?
  • 中断响应后模块能否继续工作?
  • 局部复位后上下文是否符合规格?
  • 异常事务会不会污染后续正常事务?
检查维度关键问题
正确性做出来的功能对不对
完整性要求的功能是否都做了
异常性错误输入下的反应是否正确
稳健性出错后能否恢复并继续工作

关键认识:验证不只是“给输入、看输出”,还要覆盖功能遗漏、异常路径和恢复过程。


1.3 验证语言的发展与选择(🟢 低)

本章重点比较三类基于 Verilog 设计生态的验证方案:

  1. Verilog。
  2. SystemC。
  3. SystemVerilog。

语言选择会影响测试平台的模块化、随机化、参考模型集成和可维护性。

1.3.1 使用 Verilog 验证(🟢 低)

Verilog 首先是一门面向硬件设计的语言。 它也包含一些可以用于验证的语句和结构,例如:

  • initial。
  • task。
  • function。
  • 延时控制。
  • 系统任务。
  • 层次化信号访问。

下面是典型的定向激励示意:

initial begin
    reset_n = 1'b0;              // 先让 DUT 进入复位状态
    req     = 1'b0;              // 复位期间不发送请求
    data    = '0;                // 初始化输入,避免出现 X
    #100;
    reset_n = 1'b1;              // 解除复位
    #20;
    req     = 1'b1;              // 固定时刻发送固定请求
    data    = 32'h1234_5678;      // 激励内容在代码中直接写死
    #10;
    req     = 1'b0;              // 结束本次请求
end

这类测试的优点是过程明确,调试时容易重现。 但是测试行为固定,状态空间主要依靠人工枚举。 Verilog 验证的主要局限

局限直接影响
功能模块化能力有限平台规模增大后难以维护
缺少面向对象机制组件扩展和替换困难
随机化能力不足容易依赖大量定向测试
约束表达能力不足很难高效生成合法又丰富的激励
测试组织不统一不同开发者容易形成完全不同的结构

定向测试用例的特点是:

  • 激励取值固定。
  • 行为顺序固定。
  • 预期路径固定。
  • 重复运行时通常得到相同刺激。

它适合:

  • 基本功能冒烟测试。
  • bug 的最小复现用例。
  • 极少出现的精确边界场景。
  • 上电和复位等固定流程。

它不适合单独承担大规模状态空间验证。 当每一种输入组合和协议行为都需要单独编写测试时,测试数量会迅速膨胀。

本章观点:Verilog 可以完成验证,但面对复杂 IC 时,测试复用和随机化效率会成为明显瓶颈。

1.3.2 使用 SystemC 验证(🟢 低)

SystemC 本质上是一个 C++ 类库。 它特别适合与 C/C++ 算法模型结合。 在图像、音视频、通信算法等设计中,团队常先建立软件参考模型,再实现 RTL。 验证平台需要把 DUT 输出与参考模型输出进行比较。 此时 SystemC 与 C++ 的天然兼容性非常有吸引力。

输入事务
   |--> C/C++ 或 SystemC 参考模型 --> 期望结果
   |
   +--> DUT RTL ------------------> 实际结果
期望结果与实际结果进入比较器,判断 DUT 是否正确。

SystemC 的优势

  • 建立在 C++ 之上。
  • 容易复用已有 C/C++ 算法代码。
  • 适合建立高层次参考模型。
  • 可以描述硬件并发和时间行为。
  • 对算法密集型设计较友好。

SystemC 的代价

  • 需要具备较扎实的 C++ 基础。
  • 指针和对象生命周期增加复杂度。
  • 用户需要关注内存管理。
  • 内存泄漏可能导致长期仿真不稳定。
  • 构造异常和随机测试场景不如 SystemVerilog 直接。
适合场景原因
算法参考模型可直接使用 C/C++ 生态
系统级高层建模抽象层次高、执行速度较好
软硬件协同验证与软件模型衔接自然

不要绝对化:SystemC 并不是“不能做验证”,它的强项与 SystemVerilog 不同,实际项目也可能混合使用两者。

1.3.3 使用 SystemVerilog 验证(🟢 低)

SystemVerilog 是 Verilog 的扩展,能够兼容 Verilog 设计代码。 它在语言层面加入了大量面向验证的能力。 面向对象能力

  • 封装。
  • 继承。
  • 多态。
  • 类与对象。
  • 虚方法。

验证专用能力

  • 受约束随机化 constraint。
  • 功能覆盖率 covergroup。
  • 断言 SVA。
  • 接口 interface。
  • 队列、动态数组和关联数组。
  • 进程间通信机制。

下面只用一个小示意说明受约束随机与固定激励的区别:

class Packet;
    rand bit [7:0]  length;       // 每次 randomize 时可产生新长度
    rand bit [15:0] address;      // 每次可产生新的合法地址
    constraint legal_c {
        length inside {[1:64]};   // 长度只能位于协议允许的范围
        address[1:0] == 2'b00;    // 地址必须按 4 字节对齐
    }
endclass
initial begin
    Packet pkt = new();           // 先创建对象,再调用随机化
    repeat (100) begin
        if (!pkt.randomize())     // 始终检查随机化是否成功
            $error("randomize failed");
        // 此处可以把 pkt 转换成接口信号并发送给 DUT
    end
end

这个例子体现了两点:

  1. 激励可以在合法范围内自动变化。
  2. 约束把“什么样的数据合法”与“如何发送数据”分开。

SystemVerilog 对 Verilog 用户较友好,因为:

  • 基本语法延续 Verilog。
  • 可以直接例化和连接 RTL DUT。
  • 信号级与事务级代码可以共存。
  • 不需要把设计语言和验证语言完全割裂。

1.3.4 SystemVerilog 与 C/C++ 的连接(🟢 低)

SystemVerilog 可以通过 DPI 调用 C/C++ 函数。 DPI 的全称是 Direct Programming Interface。 它适合把已有算法或软件模型接入验证平台。

// 声明外部 C 函数;真正的算法实现在 C/C++ 文件中
import "DPI-C" function int reference_model(
    input int input_data
);
initial begin
    int expected;
    expected = reference_model(100);  // 像调用普通 SV 函数一样调用 C 模型
    $display("expected = %0d", expected);
end

DPI 解决的是语言连接问题。 它本身不负责:

  • 自动建立完整验证平台。
  • 自动同步 DUT 与参考模型。
  • 自动比较期望值和实际值。
  • 自动生成覆盖率目标。

这些仍然需要验证平台架构来组织。 SystemVerilog 还提供 $system,可调用外部可执行程序。

initial begin
    int status;
    // 调用已经编译好的外部程序;返回值可用于判断执行是否成功
    status = $system("./reference_model input.bin output.bin");
    if (status != 0)
        $error("external reference model failed");
end
连接方式适合情况特点
DPI高频函数调用、紧密交互数据可直接通过函数参数传递
$system调用独立工具或离线模型进程边界清晰,常通过文件交换数据

SystemVerilog 自带对象内存管理机制,通常不需要像 C++ 那样手动释放普通类对象。 这降低了验证代码中部分内存管理负担。

1.3.5 三种语言横向比较(🟢 低)

比较项VerilogSystemCSystemVerilog
主要定位RTL 设计C++ 系统级建模RTL 设计与验证
面向对象不具备完整能力具备具备
约束随机弱通常需自行搭建语言原生支持
功能覆盖率缺少原生高级机制依赖库或自建语言原生支持
C/C++ 模型集成较繁琐天然方便可通过 DPI 或 $system
内存管理不是主要问题需关注 C++ 生命周期语言提供自动管理
连接 Verilog DUT直接需要接口连接直接且自然
复杂验证平台可做但维护困难可以实现非常适合

选择语言时不能只看“能不能完成”,还要看:

  • 平台规模扩大后是否容易维护。
  • 测试是否容易随机化。
  • 组件是否容易复用。
  • 算法模型是否容易接入。
  • 团队是否具有相应语言经验。
  • EDA 工具支持是否成熟。

1.4 为什么有了 SystemVerilog 还需要方法学(🟢 低)

1.4.1 语言只提供积木(🟢 低)

SystemVerilog 提供类、随机化、覆盖率、接口等强大机制。 但是语言不会自动告诉开发者如何组合这些机制。 仅使用语言仍要自行决定:

  • 验证平台有哪些组件。
  • 每个组件承担什么职责。
  • 组件之间如何通信。
  • 测试用例如何组织。
  • 哪些部分允许变化。
  • 哪些部分保持稳定。
  • 数据流与控制流如何分离。
  • 寄存器访问如何抽象。
  • 子系统平台如何复用到系统级。

如果每个项目都从头回答这些问题,团队会反复付出架构成本。 如果每位工程师给出不同答案,代码也很难互相复用。 方法学就是对这些反复出现的问题给出一套经过实践的组织方式。

类比:语言提供词汇和语法,方法学提供文章结构和常用表达方式。

1.4.2 平台基本组件问题(🟢 低)

一个完整验证平台通常需要处理以下职责:

职责要解决的问题
激励生成测什么数据和行为
激励驱动如何把事务转换成引脚信号
信号监测如何从接口恢复出事务
结果预测正确结果应该是什么
自动比较DUT 实际结果是否正确
覆盖收集已经测试了哪些功能
配置管理不同测试如何改变平台行为
报告管理信息、警告和错误如何统一输出

这些职责可以全写在一个巨大的 initial 块里,但很快会失去可维护性。 方法学强调职责分离,使每个组件专注于一个清晰任务。

1.4.3 组件通信问题(🟢 低)

平台组件并不是孤立的。 它们需要传递:

  • 输入事务。
  • DUT 监测事务。
  • 期望结果。
  • 配置信息。
  • 控制命令。
  • 状态与统计信息。

如果组件直接读写彼此内部变量,就会形成强耦合。 强耦合会导致:

  • 一个组件修改后影响多个组件。
  • 替换协议或接口变得困难。
  • 子系统环境难以提升到系统级。
  • 测试代码了解过多底层细节。

UVM 在后续章节会提供事务级通信、配置机制等标准方案。 本章只需要记住:方法学不仅规定“有哪些组件”,还规定“组件怎样合作”。

1.4.4 测试用例组织问题(🟢 低)

复杂项目可能包含大量测试场景。 如果每个测试都重新搭建整个平台,会产生严重重复。 合理的测试组织应该做到:

  • 平台结构尽量稳定。
  • 不同测试只替换必要的激励和配置。
  • 公共初始化流程可以复用。
  • 协议行为可以组合。
  • 错误注入可以局部打开。
  • 测试意图容易从代码中看出来。
稳定部分常变化部分
agent、driver、monitor 的结构sequence 和约束
接口连接方式是否打开某种错误注入
scoreboard 基本框架配置参数和工作模式
公共报告机制本次测试的检查重点

方法学的价值之一,就是减少“为了换一个测试场景而复制整个平台”的情况。

1.4.5 数据流与控制流分离(🟢 低)

数据流描述的是事务内容如何在平台中传递。 控制流描述的是何时开始、停止、切换模式或触发某种行为。

类型例子
数据流packet 从发生器传给 driver
数据流monitor 把采集事务送入 scoreboard
控制流复位结束后开始发送事务
控制流达到目标数量后停止测试
控制流在指定阶段打开错误注入

如果两者混在一起,数据组件会知道太多测试流程细节。 分离后,数据处理组件更容易在不同测试和项目中复用。

1.4.6 寄存器解决方案(🟢 低)

现代 DUT 常包含大量可配置寄存器。 直接在每个测试中手写地址和值,会遇到:

  • 地址容易写错。
  • 字段位宽和偏移容易写错。
  • 寄存器版本变化后修改范围很大。
  • 前门访问和后门访问难以统一。
  • 镜像值与 DUT 实际值难以维护。

方法学需要给寄存器提供统一抽象。 UVM 吸收了 VMM 的 RAL 思想,形成标准寄存器模型方案。 这里先记住三个词:

  • Register Model:寄存器模型。
  • RAL:Register Abstraction Layer。
  • 抽象访问:测试尽量使用寄存器名和字段名,而不是裸地址。

预告:寄存器模型是 UVM 相比早期 OVM 更完整的重要部分。

1.4.7 可重用性问题(🟢 低)

复用不是简单地把旧文件复制到新项目。 真正的复用意味着组件在新环境中只需少量修改,甚至无需修改即可工作。 可重用性至少包含三个层次:

层次目标
个人复用当前项目代码能用于下一个项目
团队复用其他工程师能理解并使用该组件
层级复用模块/子系统环境能提升到芯片系统级

影响复用性的常见因素:

  • 是否把接口细节封装在 driver 和 monitor 中。
  • 是否使用配置而不是硬编码路径。
  • 是否把测试意图与底层信号操作分离。
  • 是否提供清晰的事务抽象。
  • 是否避免组件之间的私有依赖。
  • 是否遵守统一的生命周期和通信规范。

UVM 的核心价值不只是“代码少”,更是让代码更容易组合、替换和迁移。


1.5 对“方法学”的三层理解(🟢 低)

1.5.1 第一层:抽象的指导思想(🟢 低)

初次接触方法学时,它容易显得像一个哲学概念。 这种理解并非完全错误,因为方法学确实包含:

  • 如何分解问题。
  • 如何组织系统。
  • 如何处理变化。
  • 如何形成可复用的工程经验。

但只停留在抽象概念上,仍然不能写出验证平台。 学习时需要把问题落实为具体组件、接口和代码。

1.5.2 第二层:一套可以使用的库(🟢 低)

学完基本 UVM 用法后,工程师会发现它首先是一套 SystemVerilog 类库。 方法学要被程序员使用,必须通过代码实现。 从这个层次看,UVM 提供:

  • 基础组件类。
  • 对象与组件的创建机制。
  • 组件生命周期。
  • 事务级通信。
  • sequence 激励机制。
  • factory 替换机制。
  • callback 扩展机制。
  • 寄存器模型。
  • 报告和配置机制。

把 UVM 暂时当成库,有助于降低初学阶段的理解负担。 先学会“怎样使用”,再逐渐理解“为什么这样设计”。

1.5.3 第三层:库背后的工程思想(🟢 低)

有一定项目经验后,会发现方法学不等于类库本身。 类库只是方法学的一种具体实现。 真正重要的是库背后的原则:

  • 关注点分离。
  • 稳定结构与变化行为分离。
  • 高层测试与底层协议分离。
  • 事务抽象与信号细节分离。
  • 组件低耦合。
  • 通过标准接口实现组合。
  • 通过配置和替换实现扩展。

即使熟记所有 UVM API,如果平台结构高度耦合,也没有真正掌握方法学。 反过来,理解这些原则后,面对不同框架也能快速找到共同逻辑。

理解层次典型认识学习重点
第一层方法学是一种抽象思想了解它要解决什么问题
第二层UVM 是一套类库掌握组件和 API 用法
第三层类库承载工程原则理解架构、边界和复用

推荐顺序:初学时先把 UVM 当成库,能搭平台后再回头理解方法学思想。


1.6 为什么选择 UVM(🟢 低)

1.6.1 VMM(🟢 低)

VMM 的全称是 Verification Methodology Manual。 它由 Synopsys 在 2006 年推出。 早期 VMM 是闭源的,后来面对开放方法学竞争而开源。 VMM 的重要特点之一是集成了寄存器抽象层 RAL。

VMM 特点说明
推出者Synopsys
推出时间2006 年
早期状态闭源,后来开源
重要能力RAL 寄存器解决方案

1.6.2 OVM(🟢 低)

OVM 的全称是 Open Verification Methodology。 它由 Cadence 和 Mentor 在 2008 年推出。 OVM 从一开始就是开源方法学。 它引入了功能强大的 factory 机制。 OVM 本身缺少完整集成的寄存器方案。 Cadence 后来推出 RGM 补足寄存器能力,但 RGM 不是 OVM 的内建组成部分,需要额外获取。

OVM 特点说明
推出者Cadence、Mentor
推出时间2008 年
开放性从开始即开源
重要能力factory 机制
主要短板缺少内建寄存器解决方案
后续状态已停止更新,被 UVM 取代

1.6.3 UVM(🟢 低)

UVM 正式版由 Accellera 于 2011 年 2 月推出。 它得到 Synopsys、Mentor 和 Cadence 的共同支持。 UVM 基本继承了 OVM 的平台结构和机制。 同时,它吸收了 VMM 中成熟的寄存器解决方案和部分优秀实现方式。 因此可以把 UVM 的来源简化为:

OVM 的主体结构与 factory 等机制
                 +
VMM 的 RAL 和部分优秀实现
                 |
                 v
                UVM
方法学核心贡献在 UVM 中的体现
OVM开放平台、factory 等主体机制UVM 大量继承 OVM
VMMRAL 寄存器抽象及部分实现经验UVM 纳入寄存器模型
UVM统一并标准化双方优势成为主流通用方法学

1.6.4 判断方法学前景的三个问题(🟢 低)

问题一:EDA 厂商是否支持 验证方法学最终要运行在仿真器和相关 EDA 工具上。 没有主流工具支持,再好的方法也难以进入工程流程。 UVM 得到三大 EDA 厂商的共同支持,这是其成功的重要基础。 厂商支持意味着:

  • 主流仿真器能够编译和运行 UVM。
  • 工具会提供调试、覆盖率和数据库支持。
  • 项目迁移时不必完全绑定单一厂商。
  • UVM 标准和实现更容易持续演进。

问题二:行业是否广泛使用 工具支持只是必要条件,不是充分条件。 一种方法学还必须证明:

  • 方便实际项目使用。
  • 能承受大型平台复杂度。
  • 团队能够招聘到相关人才。
  • 有足够的案例、资料和经验积累。
  • 在不同公司和不同芯片类型中具有适用性。

UVM 已经被大量 IC 公司采用,降低了新团队选择它的风险。 问题三:是否出现更好的统一替代方案 方法学选择具有迁移成本。 只有新方案在工具、生态、工程能力和人才储备上形成明显优势,行业才会大规模迁移。 本书写作时,UVM 是年轻且有活力的主流方法学,没有出现更好的统一替代方案。

决策维度为什么重要
EDA 支持决定能否稳定落地运行
公司采用决定工程实践和人才生态
替代方案决定学习投资是否可持续

方法选择不是只比较语法:标准、工具、生态和工程经验同样重要。


1.7 UVM 的发展历史(🟢 低)

1.7.1 从 OVM 到 UVM(🟢 低)

UVM 的直接前身是 OVM。 2010 年,Accellera 采纳 OVM,并在此基础上推动统一验证方法学。 为了让 OVM 用户提前适应,Accellera 在 2010 年 5 月推出 UVM 1.0 EA。 EA 是 Early Adoption 的缩写,表示早期采用版本。 UVM 1.0 EA 与 OVM 很接近,主要变化之一是把 ovm_* 前缀改为 uvm_*。 这降低了 OVM 用户迁移的认知成本。

1.7.2 版本时间线(🟢 低)

时间版本主要说明
2008 年OVM 发布Mentor 与 Cadence 联合推出
2010 年 5 月UVM 1.0 EA供用户提前适应,整体接近 OVM
2011 年 2 月UVM 1.0正式版本,加入寄存器解决方案
2011 年 6 月UVM 1.1修正 1.0 中大量问题,差异较明显
2011 年 12 月UVM 1.1a1.1 系列迭代
2012 年 5 月UVM 1.1b1.1 系列迭代
2012 年 10 月UVM 1.1c1.1 系列迭代
2013 年 3 月UVM 1.1d本书示例采用的版本

UVM 1.0 UVM 1.0 是备受关注的正式版本。 它纳入了来自 Synopsys 的寄存器解决方案。 由于发布较仓促,该版本存在较多问题。 因此仅四个月后就发布了 UVM 1.1。 UVM 1.1 系列 UVM 1.1 修正了 1.0 的大量问题。 之后的 1.1a、1.1b、1.1c、1.1d 主要是同一系列的持续改进。 本书全部示例基于 UVM 1.1d。

版本意识:阅读代码时要知道教材使用 UVM 1.1d。遇到其他版本文档时,应先确认 API 和默认行为是否有差异。

1.7.3 历史信息应该怎么记(🟢 低)

不需要把每个日期都当成考试式知识死背。 更重要的是理解演化逻辑:

  1. VMM 带来了成熟的寄存器抽象经验。
  2. OVM 带来了开放平台和 factory 等机制。
  3. Accellera 推动标准化与统一。
  4. UVM 汇合主要厂商和既有方法学优势。
  5. UVM 1.1d 是本书代码的版本背景。

简化记忆:

VMM ---- RAL -----------+
                        +--> UVM 1.0 --> UVM 1.1 --> 1.1a/b/c/d
OVM ---- 平台主体 ------+

1.8 学了 UVM 之后能做什么(🟢 低)

1.8.1 对验证工程师的价值(🟢 低)

本书希望验证工程师掌握的不只是几个宏,而是一套完整的建台和扩展能力。 1. 搭建完整 UVM 验证平台 后续将逐步学习:

  • UVM 基础组件。
  • driver、monitor、agent 等平台结构。
  • sequence 机制。
  • factory 机制。
  • callback 机制。
  • register model。
  • 组件连接与通信。
  • 测试启动和运行控制。

2. 建立验证基本常识 验证知识不只存在于 UVM API 中。 工程师还需要理解:

  • 如何从规格提取测试点。
  • 如何设计正常和异常场景。
  • 如何自动检查结果。
  • 如何判断验证是否充分。
  • 如何调试设计问题与平台问题。
  • 如何平衡随机测试与定向测试。

3. 使用高级机制 只会运行固定模板并不等于熟练使用 UVM。 高级使用包括:

  • 灵活组合 sequence。
  • 使用 factory 在不修改原组件的情况下替换类型。
  • 使用 callback 增加局部行为。
  • 通过配置适配不同项目和层级。
  • 在保持平台结构稳定的同时扩展测试。

4. 提高代码复用性 复用要求工程师在编写代码时提前考虑边界。

问题复用目标
下个项目还能用吗跨项目复用
别人能直接用吗跨人员复用
子系统环境能提升吗跨层级复用
下一代产品能继承吗跨版本复用

5. 学会比较多种实现方式 同一个验证需求常常有多种实现方式。 学习 UVM 不能只问“能不能工作”,还应比较:

  • 是否容易理解。
  • 是否容易调试。
  • 是否容易扩展。
  • 是否符合团队规范。
  • 是否破坏复用性。
  • 是否会形成隐藏耦合。

6. 理解 OVM 遗留用法 UVM 从 OVM 演化而来,因此部分代码风格和历史问题与 OVM 有关。 理解这些背景,有助于阅读旧项目和理解某些 API 的设计原因。

1.8.2 对设计工程师的价值(🟢 低)

设计与验证从不同角度处理同一个产品目标。 “验证与设计不分家”强调的是协作,不是职责完全相同。 设计工程师学习验证知识,可以获得以下收益。 1. 写出更容易验证的 RTL 容易验证的设计通常具备:

  • 清晰稳定的接口协议。
  • 明确的复位行为。
  • 可观察的状态和错误信息。
  • 可控制的工作模式。
  • 一致的寄存器语义。
  • 可预测的异常恢复过程。

2. 更快理解验证失败 了解验证平台结构后,设计工程师可以区分:

  • DUT 真实功能错误。
  • 验证激励不合法。
  • checker 期望模型错误。
  • 时序采样位置错误。
  • 配置与设计模式不一致。

这会明显降低设计与验证之间来回传递问题的时间。 3. 更早参与验证规划 设计工程师熟悉验证思路后,可以在规格阶段主动说明:

  • 哪些状态最危险。
  • 哪些异常难以触发。
  • 哪些内部状态需要增强可观察性。
  • 哪些接口行为需要断言。
  • 哪些寄存器副作用容易误解。

4. 快速搭建基本测试 本书从第 2 章开始提供完整 UVM 示例。 设计工程师理解这些基础后,可以结合公司的现有环境建立简单测试。 如果缺少 SystemVerilog 基础,可先学习本书附录 A。

角色学习 UVM 后的直接收益
验证工程师独立搭建、扩展和复用验证平台
设计工程师提升可验证性并加快联合调试
项目团队建立统一术语、平台结构和协作方式

本章总结(1.1-1.2)

学习重点排序

优先级必须掌握
🔴 高UVM 是 SystemVerilog 类库和验证方法学,不是新语言
🔴 高验证要检查正确性、完整性、异常处理和恢复能力
🔴 高语言提供能力,方法学负责平台结构、通信和复用
🟡 中Verilog、SystemC、SystemVerilog 的特点与适用场景
🟢 进阶UVM 继承 OVM 主体并吸收 VMM 的 RAL 等经验

返回 UVM 学习笔记目录 · 下一章