FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
登录
首页-技术文章/快讯-技术分享-正文

SystemVerilog仿真:2026年用UVM寄存器模型加速FPGA验证的实践

二牛学FPGA二牛学FPGA
技术分享
7小时前
0
0
4

Quick Start

  • 准备环境:安装 Vivado 2025.2(含 Xsim)或 Questa 2024.3,确认 UVM 1.2 库已集成。
  • 创建工程:在 Vivado 中新建 RTL 工程,添加 DUT(如 AXI-Lite 从设备寄存器文件)。
  • 生成寄存器模型:使用 ralgenUVM 自带的 uvm_reg_gen 从 XML 描述生成寄存器模型类。
  • 编写 UVM 测试平台:创建 env、agent、sequencer、driver 和 monitor,集成寄存器模型。
  • 实现寄存器序列:编写 UVM 寄存器序列(reg_sequence),调用 read()/write() 方法读写 DUT 寄存器。
  • 运行仿真:执行 vsim -c -sv_lib uvm_dpi -do "run -all"(Questa)或 Vivado 仿真器直接运行。
  • 验证结果:检查日志中寄存器读写返回的预期值,确认无 UVM_ERROR。

前置条件与环境

项目推荐值说明替代方案
器件/板卡Xilinx Artix-7 XC7A35T验证用,含 AXI-Lite 接口任何支持 AXI 的 FPGA
EDA 版本Vivado 2025.2含 Xsim 仿真器与 UVM 1.2 支持Questa 2024.3 / VCS 2024.06
仿真器Xsim (Vivado) 或 Questa需支持 UVM 1.2 标准VCS / Riviera-PRO
时钟/复位100 MHz 时钟,异步低有效复位DUT 主时钟与复位根据 DUT 调整
接口依赖AXI-Lite 从接口寄存器模型通过 AXI-Lite 驱动 DUTAPB / Wishbone
约束文件XDC 约束(时序/引脚)仅上板时需要,仿真阶段可选仿真用 SDF 反标
UVM 库路径$UVM_HOME/uvm-1.2环境变量指向 UVM 源文件内嵌于 EDA 工具

目标与验收标准

完成以下任务即视为成功:

  • 功能点:UVM 寄存器模型能正确读写 DUT 中所有已映射寄存器(至少 8 个),包括只读、读写、只写类型。
  • 性能指标:单次寄存器读写延迟 ≤ 10 个时钟周期(AXI-Lite 总线延迟)。
  • 资源/Fmax:仿真阶段不关注资源;上板时寄存器模型不占用 FPGA 资源(纯仿真模型)。
  • 验收方式:仿真日志无 UVM_ERROR / UVM_FATAL,且最终寄存器镜像值与 DUT 内部值一致(通过后门访问比对)。

实施步骤

阶段一:工程结构与寄存器描述

创建 UVM 验证工程目录结构:

uvm_reg_model_demo/
├── rtl/
│   └── axi_lite_slave.v
├── tb/
│   ├── top_tb.sv
│   └── dut_wrapper.sv
├── reg_model/
│   ├── reg_block.sv
│   └── reg_map.xml
├── sequences/
│   └── reg_seq_lib.sv
└── sim/
    └── run.do

逐行说明

  • 第 1 行:工程根目录,所有文件组织在此。
  • 第 2–3 行:RTL 源文件,DUT 为 AXI-Lite 从设备。
  • 第 4–6 行:测试平台顶层与封装。
  • 第 7–9 行:寄存器模型源文件,包含 UVM 寄存器块和 XML 描述。
  • 第 10–11 行:UVM 序列库。
  • 第 12–13 行:仿真运行脚本。

阶段二:关键模块实现

编写寄存器描述 XML(reg_map.xml):

<?xml version="1.0" encoding="UTF-8"?>
<register_map>
  <reg_block name="ctrl_block" base_addr="32'h0000">
    <register name="ctrl_reg" offset="32'h00" size="32" access="rw">
      <field name="enable" bit_offset="0" width="1" access="rw" />
      <field name="mode" bit_offset="4" width="2" access="rw" />
    </register>
    <register name="status_reg" offset="32'h04" size="32" access="ro">
      <field name="ready" bit_offset="0" width="1" access="ro" />
    </register>
  </reg_block>
</register_map>

逐行说明

  • 第 1 行:XML 声明,指定版本与编码。
  • 第 2 行:根元素 register_map,包含所有寄存器块。
  • 第 3 行:定义寄存器块 ctrl_block,基地址 0x0000。
  • 第 4 行:定义寄存器 ctrl_reg,偏移 0x00,32 位,读写属性。
  • 第 5 行:域 enable,位 0,宽度 1,读写。
  • 第 6 行:域 mode,位 4–5,宽度 2,读写。
  • 第 7 行:定义寄存器 status_reg,偏移 0x04,32 位,只读。
  • 第 8 行:域 ready,位 0,宽度 1,只读。

使用 ralgen 生成 UVM 寄存器模型:

ralgen -l sv -t ctrl_block -o reg_block.sv reg_map.xml

逐行说明

  • ralgen:UVM 提供的寄存器模型生成器。
  • -l sv:输出 SystemVerilog 代码。
  • -t ctrl_block:指定顶层寄存器块名称。
  • -o reg_block.sv:输出文件。
  • reg_map.xml:输入 XML 描述。

阶段三:UVM 测试平台集成

编写寄存器序列(reg_seq_lib.sv):

class reg_write_read_seq extends uvm_reg_sequence;
  `uvm_object_utils(reg_write_read_seq)

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

  virtual task body();
    uvm_status_e status;
    uvm_reg_data_t data;

    // 写 ctrl_reg 为 0x13
    model.ctrl_block.ctrl_reg.write(status, 32'h13, .parent(this));
    // 读回验证
    model.ctrl_block.ctrl_reg.read(status, data, .parent(this));
    `uvm_info("REG_TEST", $sformatf("ctrl_reg read back: 0x%0h", data), UVM_LOW)

    // 读 status_reg
    model.ctrl_block.status_reg.read(status, data, .parent(this));
    `uvm_info("REG_TEST", $sformatf("status_reg read back: 0x%0h", data), UVM_LOW)
  endtask
endclass

逐行说明

  • 第 1 行:定义序列类,继承自 uvm_reg_sequence,提供寄存器操作能力。
  • 第 2 行:注册到 UVM 工厂,支持自动创建。
  • 第 4–6 行:构造函数,调用父类构造函数。
  • 第 8 行:body 任务,序列执行入口。
  • 第 9–10 行:声明状态变量和数据变量,用于读写操作。
  • 第 13 行:调用寄存器模型的 write 方法,写入 0x13 到 ctrl_reg。
  • 第 15 行:调用 read 方法读回,存入 data。
  • 第 16 行:打印读回值,用于验证。
  • 第 18–19 行:读取 status_reg 并打印。

阶段四:时序/CDC/约束

仿真阶段无需时序约束,但需确保 UVM 时钟与 DUT 时钟同步。在 top_tb.sv 中生成时钟:

initial begin
  clk = 0;
  forever #5 clk = ~clk; // 100 MHz
end

逐行说明

  • 第 1 行:initial 块,仿真开始执行一次。
  • 第 2 行:初始 clk 为 0。
  • 第 3 行:每 5 ns 翻转一次,周期 10 ns,频率 100 MHz。

阶段五:验证与仿真

编写仿真运行脚本(run.do):

vlib work
vlog -sv +incdir+../rtl ../rtl/axi_lite_slave.v
vlog -sv +incdir+../tb ../tb/top_tb.sv
vlog -sv +incdir+../reg_model ../reg_model/reg_block.sv
vlog -sv +incdir+../sequences ../sequences/reg_seq_lib.sv
vsim -c -sv_lib uvm_dpi work.top_tb
log -r /*
run -all

逐行说明

  • 第 1 行:创建 work 库。
  • 第 2–5 行:编译所有源文件,包含搜索路径。
  • 第 6 行:启动仿真,加载 UVM DPI 库。
  • 第 7 行:记录所有信号波形。
  • 第 8 行:运行仿真直到结束。

常见坑与排查

  • 坑 1:寄存器模型未正确连接到 DUT。检查 adapter 是否正确转换总线事务。排查:在 monitor 中打印 AXI 总线信号,确认地址/数据匹配。
  • 坑 2:XML 描述与 RTL 不一致。例如偏移地址或位宽错误。排查:对比 RTL 中寄存器地址映射与 XML,确保完全一致。
  • 坑 3:UVM 序列未启动。检查 test 中是否调用了 sequence.start()。排查:在 test 的 run_phase 中添加启动代码。

原理与设计说明

为什么使用 UVM 寄存器模型

传统 FPGA 验证中,寄存器读写通常通过直接驱动总线信号完成,代码冗余且难以维护。UVM 寄存器模型提供了抽象层,将寄存器操作封装为方法调用(read/write),自动处理地址映射、位域访问和总线协议转换。关键 trade-off 如下:

  • 资源 vs Fmax:寄存器模型仅存在于仿真环境中,不消耗 FPGA 资源,不影响 Fmax。
  • 吞吐 vs 延迟:模型通过 adapter 将抽象操作转换为总线事务,单次读写延迟取决于总线协议(如 AXI-Lite 通常 2–10 时钟周期)。
  • 易用性 vs 可移植性:UVM 寄存器模型标准化后,可跨项目复用,但学习曲线较陡。对于小型 FPGA 验证,可直接使用总线函数(如 AXI VIP)代替。

寄存器模型内部机制

UVM 寄存器模型由 uvm_reg_block、uvm_reg、uvm_reg_field 分层组成。每个寄存器通过 adapter 与总线接口通信。adapter 负责将 read()/write() 调用转换为具体总线事务(如 AXI-Lite 的 AR/ADDR/DATA 信号)。后门访问(backdoor)则直接通过 DPI-C 或 HDL 路径修改内部寄存器,用于快速比对。

验证与结果

指标测量值(示例)测量条件
Fmax(仿真)不适用(仿真无频率)
资源(仿真)0 LUT / 0 FF(模型纯软件)
单次写延迟6 时钟周期AXI-Lite,100 MHz
单次读延迟7 时钟周期AXI-Lite,100 MHz
后门访问延迟0 仿真时间DPI-C 直接修改
UVM_ERROR 数量0全寄存器读写测试

以上结果为示例值,以实际工程与数据手册为准。

故障排查(Troubleshooting)

  • 现象:仿真无输出 → 原因:序列未启动。检查 test 中是否调用 sequence.start()。修复:在 run_phase 中添加启动代码。
  • 现象:寄存器读回全 X → 原因:DUT 未复位。修复:在 top_tb 中施加复位信号。
  • 现象:UVM_FATAL:reg_model not built → 原因:寄存器模型未在 env 中创建。修复:在 env 的 build_phase 中调用 model.build()。
  • 现象:总线事务未触发 → 原因:adapter 未正确连接。修复:检查 adapter 的 reg2bus() 和 bus2reg() 实现。
  • 现象:后门访问失败 → 原因:未设置 backdoor 路径。修复:在寄存器模型中调用 add_hdl_path()。
  • 现象:仿真运行极慢 → 原因:UVM 打印级别过低。修复:设置 UVM_VERBOSITY 为 UVM_MEDIUM。
  • 现象:寄存器写入值未生效 → 原因:DUT 的 AXI-Lite 接口未正确实现写响应。修复:检查 DUT 的 BVALID 和 BREADY 握手。
  • 现象:XML 生成失败 → 原因:XML 格式错误。修复:使用 XML 验证工具检查。

扩展与下一步

  • 参数化寄存器模型:通过宏或参数支持不同地址映射,提高复用性。
  • 带宽提升:将 AXI-Lite 升级为 AXI4-Full,支持 burst 传输,减少寄存器访问延迟。
  • 跨平台移植:将 UVM 测试平台移植到 VCS 或 Riviera-PRO,需调整 DPI 库路径。
  • 加入断言与覆盖:在寄存器模型中加入 SVA 断言,监控非法访问;添加覆盖组收集寄存器访问覆盖率。
  • 形式验证:使用 JasperGold 或 VC Formal 对寄存器读写协议进行形式化验证,确保无死锁。

参考与信息来源

  • Accellera UVM 1.2 标准文档 (IEEE 1800.2-2020)
  • Xilinx Vivado Design Suite User Guide: UVM Simulation (UG900)
  • Mentor Graphics Questa UVM User's Manual
  • SystemVerilog 3.1a 语言参考手册 (LRM)

技术附录

术语表

  • UVM:Universal Verification Methodology,通用验证方法学。
  • 寄存器模型:UVM 中用于抽象 DUT 寄存器的类层次结构。
  • Adapter:将寄存器模型操作转换为总线事务的组件。
  • 后门访问:通过 DPI-C 或 HDL 路径直接读写寄存器,不通过总线。

检查清单

    <ul
标签:
本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/41910.html
二牛学FPGA

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
1.01K19.98W4.02W3.67W
分享:
成电国芯FPGA赛事课即将上线
SystemVerilog仿真:2026年用UVM寄存器模型加速FPGA验证的实践
SystemVerilog仿真:2026年用UVM寄存器模型加速FPGA验证的实践上一篇
FPGA入门实践指南:从Verilog到时序收敛(2026年Q2)下一篇
FPGA入门实践指南:从Verilog到时序收敛(2026年Q2)
相关文章
总数:1.05K
FPGA 端侧 AI 推理中的模型量化与加速实践指南

FPGA 端侧 AI 推理中的模型量化与加速实践指南

QuickStart(快速上手)本指南面向希望在FPGA端侧设备上…
技术分享
13天前
0
0
28
0
FPGA项目实战:基于Verilog的简易CPU设计与仿真验证

FPGA项目实战:基于Verilog的简易CPU设计与仿真验证

本指南旨在引导读者完成一个基于Verilog的简易CPU(中央处理器)核…
技术分享
17天前
0
0
31
0
FPGA AI推理加速器设计指南:支持动态稀疏性与混合精度计算的硬件架构实现

FPGA AI推理加速器设计指南:支持动态稀疏性与混合精度计算的硬件架构实现

本文档旨在为FPGA硬件工程师提供一套完整的、可落地的硬件架构方案,用于…
技术分享
25天前
0
0
38
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容