ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

UVM验证入门实战:从零搭建可运行Demo环境

UVM验证入门实战:从零搭建可运行Demo环境 1. 项目概述与核心价值最近在后台和社群里经常有刚接触芯片验证或者想转行验证的朋友问我同一个问题“UVM听起来好复杂有没有一个能直接跑起来的例子让我先感受一下整个流程” 确实UVM作为当前芯片验证领域事实上的标准方法学其强大的功能和随之而来的学习曲线常常让初学者望而生畏。看再多的理论书籍都不如亲手把环境搭起来、把测试跑通来得实在。今天我就基于一个经典的UVM验证Demo手把手带你从零开始完成环境的搭建、编译、仿真到结果分析的全过程。这个Demo麻雀虽小五脏俱全涵盖了从最简单的Driver/Sequencer/Agent组件到稍复杂的Scoreboard、寄存器模型Register Model以及虚拟序列Virtual Sequence等核心概念。更重要的是我会提供所有源码并确保你能够一键复现整个流程让你在动手实践中快速建立起对UVM验证环境最直观的认知。这个Demo模拟了一个简化的“计算单元”的验证。这个计算单元DUT, Design Under Test通过一个接口接收操作指令和两个操作数执行加法或乘法运算后输出结果。我们的UVM验证平台Testbench的任务就是自动生成大量的测试激励驱动给这个DUT同时预测DUT的输出并自动比对预测值和实际值最终给出测试是否通过的结论。通过完成这个项目你将清晰地理解一个典型的UVM测试平台由哪些基本“积木”组件构成这些“积木”之间是如何通过TLM事务级建模端口进行“对话”和数据传递的测试用例Test是如何控制整个验证流程的以及最终我们如何通过一个简单的命令让整个庞大的自动化验证机器运转起来。无论你是在校学生、初入行的验证工程师还是其他岗位想了解验证流程的同行这篇指南都将为你提供一个绝佳的起点。2. 环境准备与项目结构解析2.1 工具链选择与安装要跑通一个UVM环境我们离不开三样核心工具仿真器Simulator、编译工具和波形查看器Waveform Viewer。对于新手而言工具的选择和安装往往是第一道坎。这里我推荐一个对个人学习非常友好的组合Modelsim/QuestaSim的免费入门版如Questa Sim Starter Edition搭配Make作为构建工具。为什么选择QuestaSim Starter Edition首先它来自业界主流的EDA厂商Mentor现Siemens EDA其语法支持和调试功能与商业版基本一致能保证我们学习的“原汁原味”。其次这个版本对于小型设计是免费的完全能满足我们这个Demo乃至更复杂一些的学习项目的需求。最后它的安装相对简单在Windows和Linux上都有较好的支持。你可以从Siemens EDA官网注册并下载。安装过程基本上就是“下一步”到底注意安装路径不要有中文和空格。Make工具的作用UVM环境通常包含几十甚至上百个SystemVerilog文件手动编译顺序既繁琐又容易出错。Make工具可以让我们用一条命令make compile自动完成所有文件的编译、排序和链接。在Linux下make通常是自带的。在Windows下如果你安装了QuestaSim其安装目录下的win64文件夹里会有一个vsim.exe但为了使用make命令我强烈建议安装MSYS2或Cygwin来提供一个类Unix的命令行环境或者直接使用Windows 10/11自带的WSLWindows Subsystem for Linux。这能极大简化后续的操作。注意如果你在Windows下使用QuestaSim自带的vsim命令行而不想配置额外环境也可以直接写一个.doTcl脚本文件来执行编译仿真。但为了通用性和可移植性便于日后迁移到Linux服务器本文将以Makefile为例进行讲解。这是工业界更常见的做法。2.2 Demo项目目录结构详解在开始敲命令之前我们先像建筑师看蓝图一样审视一下整个项目的目录结构。一个清晰的结构是项目可维护、可复现的基础。我们的Demo项目结构如下uvm_demo/ ├── Makefile # 自动化编译仿真脚本 ├── rtl/ # 设计代码 (DUT) │ └── simple_alu.sv ├── tb/ # 测试平台代码 │ ├── interface/ # 接口定义 │ │ └── alu_if.sv │ ├── pkg/ # UVM环境包 │ │ └── alu_pkg.sv │ ├── tests/ # 测试用例 │ │ └── base_test.sv │ └── top.sv # 顶层模块连接DUT和TB ├── seq/ # 序列定义 │ └── alu_seq.sv ├── run/ # 运行目录 │ └── alu.f # 文件列表供编译使用 └── waves/ # 波形文件存放目录各目录核心作用解析rtl/: 这里存放我们的“设计”Design也就是待验证的对象DUT。simple_alu.sv是一个极简的算术逻辑单元它就是我们这个验证项目的“靶心”。tb/: 这是验证平台的“大本营”。interface/里定义了DUT与验证平台通信的“管道”虚拟接口pkg/里用uvm_pkg包裹了所有UVM组件如driver,monitor,agent,env等这是UVM推荐的编码风格tests/里定义了具体的测试场景top.sv是系统的“总装配车间”它实例化DUT、接口并将接口传递给UVM环境最后调用run_test()启动一切。seq/: 专门存放序列Sequence文件。序列是生成激励的“剧本”它决定了在什么时间、向DUT发送什么样的数据事务。run/: 这个目录是“作战指挥室”。我们在这里执行make命令。alu.f是一个文本文件里面按正确的依赖顺序列出了所有需要编译的.sv文件路径。Makefile会读取这个文件列表。waves/: 仿真运行时产生的波形文件如.wlf格式会默认放在这里方便管理和查看。这种结构分离了设计、验证平台、脚本和产出物逻辑清晰。当你未来需要验证一个更大的设计时只需要在此基础上扩展例如在rtl/下增加子模块在tb/pkg/下增加新的agent等。2.3 一键复现的关键Makefile解析“一键复现”的魔法就藏在Makefile里。它定义了一系列规则rules告诉系统如何从源代码得到最终结果。下面是我们Demo中Makefile的核心部分解读# 工具和库路径设置需要根据你的安装路径修改 VLOG vlog -work work -sv -l compile.log incdir${UVM_HOME}/src VSIM vsim -c -do run -all; quit -f -l simulate.log WAVE vsim -view wave.wlf # 默认目标执行完整的编译、仿真、查看波形流程 all: clean compile simulate wave # 编译读取文件列表编译所有SystemVerilog文件 compile: ${VLOG} -f alu.f # 仿真启动仿真运行指定的测试用例 simulate: ${VSIM} work.top UVM_TESTNAMEbase_test # 打开波形查看器 wave: ${WAVE} # 清理删除之前编译和仿真产生的中间文件 clean: rm -rf work transcript vsim.wlf wave.wlf compile.log simulate.log关键点说明VLOG和VSIM: 这是QuestaSim的编译和仿真命令。-work work指定编译库名为work。-sv表示使用SystemVerilog语法。incdir${UVM_HOME}/src至关重要它告诉编译器在哪里可以找到UVM库的头文件。你需要设置一个名为UVM_HOME的环境变量指向你的QuestaSim安装目录下的verilog_src/uvm-1.2或类似路径。-f alu.f: 这是实现“一键”的关键。我们不需要在命令行里敲一长串文件只需把所有文件路径写在alu.f里用-f选项指定即可。UVM_TESTNAMEbase_test: 这是传递给仿真器的一个加号参数plusarg是UVM框架规定的。它告诉UVM环境本次仿真要运行哪个测试类Test Class。在这里我们运行的是base_test。你可以通过修改这个参数来运行不同的测试用例而无需重新编译这是UVM的一个强大特性。依赖关系all: clean compile simulate wave这一行定义了当我们输入make或make all时系统要依次执行clean清理、compile编译、simulate仿真、wave看波形这四个动作。这就是“一键”的完整流程。实操前的最后检查请确保已安装QuestaSim并成功设置了UVM_HOME环境变量。将提供的Demo源码包解压并进入uvm_demo/run/目录。用文本编辑器打开Makefile检查VLOG和VSIM命令的路径是否正确如果QuestaSim的vlog和vsim命令已加入系统PATH则通常不需要修改。打开alu.f确认其中的文件路径相对于run/目录是正确的。3. UVM验证平台核心组件深度拆解现在让我们深入“车间”看看构成这个自动化验证平台的各个“精密零件”是如何设计和协同工作的。理解每个组件的作用和它们之间的连接关系是掌握UVM的关键。3.1 设计DUT与接口Interface我们的验证对象simple_alu非常简单但足以演示核心流程。它有一个时钟输入clk一个复位输入rst_n以及操作码op、操作数a和b输出结果result和一个完成信号done。接口alu_if.sv是连接DUT和UVM验证平台的桥梁。在SystemVerilog中接口interface是一种将一组相关信号捆绑在一起的强大结构。对于验证来说它的重要性在于封装性将几十根散乱的信号线打包成一个逻辑对象便于传递和管理。抽象性UVM组件如driver,monitor通过虚拟接口virtual interface指针来操作物理接口这使得验证平台本身是独立于具体信号名的提高了可重用性。同步与采样我们可以在接口内定义时钟块clocking和采样块modport明确规定驱动和采样的时序关系避免竞争冒险。在我们的alu_if.sv中你会看到类似下面的代码interface alu_if (input logic clk); logic rst_n; logic [1:0] op; logic [7:0] a; logic [7:0] b; logic [15:0] result; logic done; // 定义驱动端DRV和监控端MON的视图 modport DRV (clocking drv_cb); modport MON (input result, done, clocking mon_cb); // 定义相对于时钟的驱动和采样时序 clocking drv_cb (posedge clk); default input #1ns output #1ns; output rst_n, op, a, b; endclocking clocking mon_cb (posedge clk); default input #1ns; input result, done; endclocking endinterfaceclocking块定义了信号在时钟沿前后的稳定时间这是编写稳健验证代码的基础。driver会使用drv_cb来驱动信号monitor会使用mon_cb来采样信号。3.2 事务Transaction、序列Sequence与驱动器Driver事务Transaction是验证平台中数据交换的基本单位。你可以把它理解为一封“标准格式的信”。在这封信里封装了一次操作所需的所有信息操作码、操作数A、操作数B、预期的结果等。它定义在alu_pkg.sv中继承自uvm_sequence_item。序列Sequence是写“信”的“剧本”。它决定了在仿真过程中要生成多少封“信”以及每封“信”里的内容是什么。alu_seq.sv中定义了一个随机序列它会在body()任务中使用uvm_do宏随机化并发送多个事务给driver。驱动器Driver是“邮差”。它从sequencer那里拿到“信”事务然后按照物理接口的时序要求将“信”里的内容数据转换成实际的信号电平驱动到DUT的引脚上。driver的核心是一个循环通过seq_item_port.get_next_item(req)请求下一个事务将事务中的数据赋值给虚拟接口vif的对应信号等待DUT处理完成最后调用seq_item_port.item_done()告知序列当前事务已处理完毕。这三者的协作流程是UVM激励生成的核心测试Test启动一个序列Sequence。序列开始执行生成一个随机化的事务Transaction。事务被发送到sequencer的仲裁队列中。driver向sequencer请求事务。sequencer将事务交给driver。driver将事务数据驱动到DUT接口。驱动完成后driver通知sequencersequencer再通知序列可以生成下一个事务。 这个过程通过TLM端口uvm_seq_item_pull_port等自动完成我们只需要在组件中实现好对应的任务get和put即可。3.3 监控器Monitor、代理Agent与计分板Scoreboard激励送进去了我们还得知道DUT的反应对不对。这就是监控器Monitor和计分板Scoreboard的工作。监控器Monitor是一个“观察者”。它不驱动任何信号只默默地监视接口上的活动。当它检测到一次完整的操作例如看到done信号拉高它就会将此时采样到的op、a、b和result打包成一个新的事务通常称为“监测事务”。然后它通过一个分析端口uvm_analysis_port将这个事务“广播”出去。代理Agent是一个“容器”和“管理者”。它根据配置is_active来实例化并连接driver、sequencer和monitor。如果agent是主动的is_active UVM_ACTIVE它就包含这三者用于主动驱动激励。如果是被动的is_active UVM_PASSIVE它就只包含monitor用于监视已有的信号流。这种设计极大地增强了组件的可重用性。计分板Scoreboard是“裁判”。它订阅connect了monitor的分析端口。每当monitor“广播”一个监测到的事务计分板就会收到一份副本。同时计分板也订阅了reference model参考模型本例中可能是一个简单的C函数或SV函数的输出端口。计分板的工作就是比对这两份数据DUT的实际输出和参考模型的预期输出。如果一致则记录成功如果不一致则报告错误uvm_error。在我们的Demo中为了简化参考模型的功能可能直接内嵌在计分板或序列中通过一个predict()函数来计算预期结果。3.4 环境Environment、测试Test与顶层Top环境Environment是验证平台的“生态系统”。它实例化并连接所有agent、scoreboard、virtual sequencer等子组件。env的connect_phase方法就像在组装一台机器确保所有分析端口、TLM端口都正确对接数据流能够畅通无阻。测试Test是验证的“总指挥”。它继承自uvm_test主要做三件事配置Configure在build_phase中它可以设置环境及其子组件的参数例如关闭某个agent的随机化或者设置virtual sequencer使用哪个具体的sequencer。启动序列Start Sequence在run_phase中它创建并启动顶层的virtual sequence从而触发整个激励生成和测试流程。设置超时等可以设置仿真超时时间防止死循环。顶层Top模块是连接SV世界和UVM世界的“边界”。它是一个纯SystemVerilog模块不是类主要职责是生成时钟和复位信号。实例化DUT。实例化物理接口alu_if并将其连接到DUT的端口上。通过uvm_config_db机制将物理接口的指针虚拟接口设置到UVM资源池中供driver和monitor等组件获取。调用run_test(“test_name”)启动UVM世界。这个调用会实例化指定的测试类并触发UVM的相位phase机制自动运行。4. 完整实操流程与命令行执行理论铺垫完毕现在让我们回到命令行亲手让这个验证平台运转起来。请确保你当前的工作目录是uvm_demo/run/。4.1 第一步环境变量设置与编译在运行make之前必须确保系统能找到UVM库。我们通过设置环境变量UVM_HOME来实现。Linux/WSL/Mac:在终端中执行或将此命令加入你的~/.bashrc文件export UVM_HOME/path/to/your/questasim/verilog_src/uvm-1.2请将/path/to/your/questasim替换为你的QuestaSim实际安装路径。Windows (使用MSYS2或类似环境):命令与Linux相同。Windows (使用QuestaSim自带命令行):通常安装程序会设置好如果不确定可以在QuestaSim的安装目录下寻找uvm-1.2文件夹。设置好环境变量后执行编译make compile如果一切顺利你会在终端看到vlog命令逐行编译文件最后提示编译成功并在当前目录生成一个名为work的库文件夹以及compile.log日志文件。如果编译出错请首先检查compile.log文件里面会有详细的错误信息。常见错误包括文件路径错误、UVM_HOME设置不正确、SystemVerilog语法错误等。4.2 第二步运行仿真并观察输出编译成功后运行仿真make simulate或者如果你想运行一个特定的测试假设我们还有一个random_testmake simulate UVM_TESTrandom_test这行命令会启动vsim加载work库运行top模块并指定测试名为base_test。仿真会在后台以命令行模式-c运行执行完所有测试后自动退出quit -f。仿真过程中UVM会打印大量的日志信息到终端和simulate.log文件。请务必仔细阅读这些日志这是你调试和了解测试运行状况的最重要依据。一个成功的仿真其日志结尾通常会看到类似这样的信息UVM_INFO 1050000: reporter [TEST_DONE] ‘base_test’ Test Completed Successfully! UVM_INFO 1050000: reporter [UVM/REPORT/CATCHER]这表示测试正常完成没有发生任何UVM_ERROR或UVM_FATAL。如果看到UVM_ERROR则说明测试中发现了问题可能是计分板比对失败也可能是驱动或监控出现了异常。4.3 第三步查看波形进行调试仿真完成后会生成一个波形数据库文件默认可能是vsim.wlf或wave.wlf。我们可以打开波形查看器来直观地观察信号变化make wave这条命令会打开QuestaSim的图形化波形界面。你需要手动添加信号到波形窗口。通常的操作是在“Objects”窗口中找到top实例展开后找到DUT例如top.dut和接口例如top.alu_if_inst将其中的信号拖拽到波形窗口中。通过观察时钟、复位、操作数、结果以及done信号的关系你可以清晰地看到每一次激励的发送和响应的捕获验证driver和monitor的行为是否符合预期。波形是验证工程师最强大的调试工具之一。5. 源码导读与关键代码剖析“一键运行”很酷但理解每一行代码为什么这样写更重要。让我们深入几个核心文件看看关键代码是如何实现的。5.1 驱动器Driver的核心循环在driver.sv中最重要的部分是run_phase中的循环virtual task run_phase(uvm_phase phase); forever begin seq_item_port.get_next_item(req); // 1. 从sequencer获取下一个事务 drive_transfer(req); // 2. 调用任务将事务驱动到接口 seq_item_port.item_done(); // 3. 告知sequencer当前事务处理完毕 end endtask virtual task drive_transfer(alu_transfer trans); // 等待复位释放或确保在正确的时钟周期开始驱动 (posedge vif.clk iff vif.rst_n 1); // 将事务中的随机化数据通过时钟块驱动到接口上 vif.drv_cb.op trans.op; vif.drv_cb.a trans.a; vif.drv_cb.b trans.b; // 等待DUT处理完成根据DUT特性这里可能是等待done信号 (posedge vif.clk iff vif.drv_cb.done 1); // 可选将DUT的实际输出回写到事务对象中供后续参考 trans.result vif.drv_cb.result; endtask关键点get_next_item和item_done必须成对出现这是UVM序列-驱动器通信协议的要求。驱动时一定要使用接口的时钟块drv_cb进行非阻塞赋值这能保证信号在时钟沿后稳定变化避免时序问题。drive_transfer任务中的等待条件(posedge vif.clk iff ...)需要根据DUT的实际接口协议来精确编写。我们这个Demo的DUT行为简单一个周期就能出结果。对于复杂的协议如AXI这个驱动任务会复杂得多。5.2 监控器Monitor的采样与广播monitor.sv的run_phase同样是一个永久循环但它专注于采样virtual task run_phase(uvm_phase phase); alu_transfer trans; forever begin // 等待一次传输完成例如done信号拉高 (posedge vif.clk iff vif.mon_cb.done 1‘b1); // 创建新的事务对象 trans alu_transfer::type_id::create(“trans”); // 从接口采样数据 trans.op vif.mon_cb.op; trans.a vif.mon_cb.a; trans.b vif.mon_cb.b; trans.result vif.mon_cb.result; // 这是DUT的实际输出 // 可选采样时间戳等信息 trans.begin_time $time; // 通过分析端口将事务广播出去 ap.write(trans); end endtask关键点监控器永远不要驱动接口它只使用mon_cb进行采样阻塞赋值或直接读取。ap.write(trans)是分析端口的标准用法。所有连接到这个端口的组件如scoreboard都会同时收到这个事务的副本。这是一种“发布-订阅”模式非常灵活。5.3 配置数据库uvm_config_db的使用uvm_config_db是UVM中用于在组件间传递配置信息的全局“公告栏”。在top.sv中我们将物理接口设置到数据库中initial begin // 将虚拟接口指针放入config_db供uvm_test及其子组件获取 uvm_config_db#(virtual alu_if)::set(null, “uvm_test_top”, “vif”, alu_if_inst); // 启动UVM测试 run_test(“base_test”); end在driver或monitor的build_phase中它们会获取这个接口virtual function void build_phase(uvm_phase phase); super.build_phase(phase); if(!uvm_config_db#(virtual alu_if)::get(this, “”, “vif”, vif)) begin uvm_fatal(“NOVIF”, “Virtual interface not found for driver”) end endfunction理解set和get的参数set的第二个参数是路径contxt。null和“uvm_test_top”是常用写法表示放在最顶层的资源池所有组件都能看到。get的第二个参数是当前组件的路径“”表示从当前组件的上下文开始查找。第三个参数“vif”是键名必须与set时保持一致。如果get失败返回0通常意味着接口没有正确设置此时用uvm_fatal终止仿真是最佳选择可以立即定位问题。6. 常见问题排查与调试技巧即使按照步骤操作你也可能会遇到一些问题。这里我总结了一些新手常见的“坑”和解决方法。6.1 编译阶段常见错误**错误** Error: (vlog-19) Failed to access library ‘uvm_pkg’ at ‘uvm_pkg’.**原因编译器找不到UVM库。解决确认UVM_HOME环境变量已正确设置并且vlog命令中的incdir${UVM_HOME}/src路径有效。可以尝试在命令行直接echo $UVM_HOME查看或手动输入完整路径试试。错误** Error: Could not find ‘uvm_pkg::uvm_*’ in ‘xxx.sv’.原因文件编译顺序错误。UVM基类库uvm_pkg必须在用户代码之前编译。解决检查alu.f文件列表确保包含UVM库的文件通常不需要手动列出incdir已足够或确保uvm_pkg的路径在incdir中。在Makefile的VLOG命令中UVM的include目录参数必须在最前面。错误** Error: Variable ‘vif’ not found.原因虚拟接口vif没有成功从config_db获取可能是set和get的路径或键名不匹配。解决仔细核对top.sv中set的键名第四个参数和driver/monitor中get的键名是否完全一致大小写敏感。检查get的上下文路径第二个参数是否正确。6.2 仿真运行时常见问题问题仿真立即结束没有运行任何测试。可能原因1run_test(“test_name”)中的测试类名拼写错误或者该测试类没有被正确编译进库。排查检查仿真日志的开头看是否有UVM_FATAL报告找不到测试。确认测试类是否在alu_pkg中被import并且文件被alu.f列表包含。可能原因2driver或monitor中的uvm_fatal触发。排查查看仿真日志找到第一个UVM_FATAL根据其提示信息定位问题。问题仿真挂起Hang不结束。可能原因1driver中的get_next_item和item_done不匹配导致sequencer一直在等待某个事务完成。排查检查driver的run_phase确保每次get_next_item后都有对应的item_done。注意在异常分支如复位也需要调用item_done。可能原因2序列Sequence没有正常结束。例如序列的body()任务是一个无限循环或者结束条件永远达不到。排查检查你的序列代码确保它能在生成一定数量的事务后正常退出。可以使用sequence.start()的count参数或者在序列内使用repeat()循环。可能原因3DUT的响应与driver/monitor的等待条件不匹配。例如driver在等待一个永远不会拉高的done信号。排查查看波形确认DUT在接收到激励后是否按照预期输出了响应信号。对比DUT的接口协议文档和验证组件的代码。问题计分板Scoreboard报告大量比对错误Mismatch。可能原因1参考模型Reference Model的计算逻辑与DUT的RTL实现不一致。这是最理想的情况说明你发现了DUT的Bug排查首先写一个简单的定向测试不随机化手动计算预期结果确认是DUT错还是参考模型错。如果DUT错恭喜你可以提Bug了。可能原因2事务Transaction中的数据在传递过程中被意外修改或者monitor采样时机不对采到了错误的数据。排查在driver驱动后、monitor采样后分别打印事务的内容。也可以在scoreboard的比对函数中将收到的两个事务都打印出来进行仔细比对。查看波形确认monitor采样的时钟沿和数据是否稳定。6.3 调试技巧与心得善用UVM报告机制不要只会用uvm_info。合理使用UVM_WARNING、UVM_ERROR、UVM_FATAL。UVM_ERROR达到一定数量默认是1仿真会自动结束这能防止错误蔓延。在调试初期可以临时提高报告的冗余度UVM_VERBOSITYUVM_HIGH让组件打印更多内部状态信息。波形调试是终极手段当逻辑复杂、日志难以分析时打开波形从出错的时间点往前追溯观察相关信号的变化往往能直观地定位问题。养成在关键事件如事务开始、结束、比对错误处用$display打印时间戳$time的习惯这样可以在波形中快速定位到对应时刻。分步调试法不要试图一次性跑通所有随机测试。先写一个最简单的定向测试Deterministic Test比如只发一个固定的加法操作确保数据通路Driver - DUT - Monitor - Scoreboard是通的。然后再逐步增加随机性和复杂度。理解相位Phase的执行顺序UVM的build_phase、connect_phase、run_phase等是有严格顺序的。确保在build_phase中创建对象和获取配置在connect_phase中连接端口。如果在build_phase中去访问一个在connect_phase才连接的端口必然会导致空指针错误。代码版本管理即使是个人学习项目也强烈建议使用Git。每次做出一个能正常工作的修改后进行一次提交。这样当你把代码改乱了可以轻松回退到上一个稳定版本。这个UVM Demo项目虽然简单但它完整地呈现了一个现代芯片验证平台的骨架和核心工作流程。从环境搭建、组件编码、脚本编写到调试排错你相当于走完了一个迷你版的验证周期。真正的工业级验证平台比这复杂百倍会涉及功能覆盖Coverage、断言Assertion、寄存器模型Register Model自动生成、形式验证Formal等更多内容。但万变不离其宗其核心思想——基于事务的建模、组件的标准化与复用、激励与检查的分离——都已在这次“手把手”的实践中得到了体现。希望你能以此为基础不断探索更广阔的验证世界。如果在复现过程中遇到任何问题欢迎随时在评论区交流我会尽力解答。
返回列表