自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(81)
  • 收藏
  • 关注

原创 UVM 约束块 Constraint:随机不是乱来,让激励符合协议规则

约束块是随机验证中最容易写出 bug 的地方之一。是否存在硬约束冲突?(所有硬约束必须同时可满足)动态数组大小是否有明确约束?是否正确处理了变量依赖?dist权重是否符合预期分布?soft约束是否有存在的必要,是否会被意外覆盖?随机化失败是否被 assert 捕获?使用关闭某个约束,观察随机化是否恢复,以定位冲突。使用动态覆盖约束,快速测试假设。打印随机化结果,用统计方法验证分布。记住:约束是随机验证的“法律”,它规定了合法激励的边界。

2026-09-02 10:00:00 553

原创 UVM 事务级 Transaction:验证平台流通的“数据货币”

transaction 是整个验证平台的“血管”,数据通过它流动。字段清晰、完整:能够完整描述一次操作的所有必要信息,不多不少。约束合理、有目的性:约束不仅为了合法,还要引导功能覆盖率。自动化完备:字段自动化宏齐全,方便调试。文档注释充分:每个字段的含义、约束的意义都应注释。记住:验证平台的优劣,很大程度上取决于 transaction 的定义质量。一个模糊、缺失字段或约束混乱的 transaction,会让后续的 sequence、driver、scoreboard 都跟着混乱。

2026-09-01 10:00:00 506

原创 UVM 调试宏:`uvm_info` 的使用与节制

uvm_info。

2026-08-31 10:00:00 830

原创 UVM 报告宏:`uvm_info / warning / error / fatal` 的使用艺术

ID:消息标识符,用于分类和过滤。建议使用有意义的字符串,如"DRV""SB""CFG"。MSG:消息内容,通常使用$sformatf格式化。VERBOSITY(仅uvm_info):冗余度级别,决定消息是否显示。:可选,通常由宏自动填充,也可以手动指定。uvm_info是唯一的带冗余度参数的宏,其余三个宏始终显示,不受 verbosity 阈值影响(但可能受其他过滤条件影响)。uvm_info必带有意义的 ID,例如模块名_组件名,方便按 ID 过滤。uvm_error必须包含足够的上下文。

2026-08-30 06:37:44 305

原创 UVM Message 严重级别:从被屏蔽的 Info 到高效调试

在调试时全局显示所有 info 消息,让所有组件的行为都暴露出来。:将日志重定向到文件,避免终端刷屏且方便事后分析。统一消息 ID 命名规范,例如模块名_组件名,这样可以通过 ID 快速过滤。在关键代码路径中使用适当的冗余度:日常运行用,深入调试时用。在 test 的或中集中设置消息策略,保持环境一致性。善用,例如让 error 不仅计数还可以退出仿真,或让 warning 也计数,根据项目需求定制。记住:掌握 UVM 消息机制,你就能在调试中事半功倍,而不是在日志的海洋中迷茫。

2026-08-29 10:00:00 330

原创 UVM Objection 最佳实践:集中管理,避免仿真挂死

driver 不许 raise/drop objection,只允许 sequence(尤其是顶层 vseq)持有 objection。这条规则简单、有效,能大幅提升平台稳定性。额外建议:在 test 层设置全局 drain_time,确保所有事务完成后再结束。使用而非phase参数,因为 sequence 的body没有 phase 参数,是专门为 sequence 提供的。调试 objection 时,使用或打印当前 phase 状态,快速定位哪个组件还持有 objection。UVM 提供了。

2026-08-28 10:00:00 604

原创 UVM Topdown Phase vs Bottomup Phase:组件树中的执行顺序

build_phase top-down(父 → 子)connect_phase bottom-up(子 → 父)run_phase 并行(所有组件同时)reset_phase 顺序(先 reset,后 configure,再 main,最后 shutdown)main_phase重点:function phase 中,build 父先子后,connect 子先父后;task phase 中,run_phase 与子阶段并行,子阶段之间顺序执行。在复杂环境中,善用uvm_info。

2026-08-27 10:00:00 969

原创 UVM Reset 与 Reset_Phase:在激励开始前,给 DUT 一个干净的世界

无论如何,建议所有需要等待复位完成的组件(如 driver、monitor、scoreboard)都在自己的 reset_phase 中等待复位释放,并在确认后 drop objection。也就是说,在 reset_phase 中,只要有任何组件 raise 了 objection,该阶段就不会结束,直到所有 objection 被 drop。:它是 run 阶段中的第一个子阶段,让所有组件在统一的时间点完成复位,然后再进入后续的 configure、main 等阶段。可能永远不会触发,导致仿真挂起。

2026-08-26 10:00:00 406

原创 UVM 句柄与对象:为什么 reg_model 在 env 但 vsequencer 有句柄?

利用句柄传递,我们只需创建一个配置对象,通过 config_db 或直接赋值传递句柄,所有组件看到的是同一份配置,修改时也能实时同步。这样 vsequencer 就拥有了这些 sequencer 的“通讯录”,可以指挥它们,但并没有拥有这些 sequencer 的所有权(对象仍然由各自的 agent 管理)。当你彻底理解“句柄是指向对象的引用”后,UVM 环境中的对象创建、组件连接、配置共享都会变得清晰透明。)根源都在于对句柄的误解。中创建子组件,并通常将子组件的句柄保存在自己的成员变量中。

2026-08-25 10:00:00 309

原创 UVM 虚拟序列 vsequence 与 vsequencer:SOC 验证的“调度艺术”

endclassendclassendclassforkjoinendtaskendclass声明了的类型,使其拥有m_cpu_sqr和m_dma_sqr成员。fork/join确保两个子 sequence 并行执行,并在两者都结束后才继续。子 sequence 在 real sequencer 上执行,它们可以独立产生各自的激励。

2026-08-24 10:00:00 601

原创 UVM Sequence Library:让随机回归自动奔跑的“序列容器”

在验证回归中,我们经常需要覆盖大量场景。如果为每一个场景手写一个单独的 sequence 并创建对应的 test case,工作量巨大且维护困难。比如需要验证总线在各种读写混合、错误注入、随机延迟等组合下的行为,可能组合出成百上千个用例。UVM 提供了一种更高效的方案:。它像一个“序列容器”,将多个 sequence 注册进去,然后在运行时根据选择模式自动随机挑选要执行的 sequence。这样,我们只需启动一个 sequence library,就能在回归中自动运行多种激励组合,大大减少了手写 test

2026-08-23 10:00:00 672

原创 UVM 回调 Callback:不改源码,优雅插入自定义行为

回调是一种设计模式:在程序的某个执行点上,调用一个由外部注册的函数或对象的方法,从而允许外部代码扩展或改变程序的行为。在 UVM 中,回调被实现为从基类派生的类,其中定义了一些虚方法(钩子函数)。你可以在组件的关键位置调用来触发所有已注册的回调钩子。重点:回调的核心思想是“预留接口,延迟实现”。平台开发者负责在合适的位置放置钩子调用,测试编写者负责提供具体的回调实现,并通过add()注册到目标组件上。首先,从派生一个回调类,声明需要插入的钩子方法。

2026-08-22 10:00:00 882

原创 UVM 字段自动化 Field Automation:让打印、复制、比较自动化

当我们在调试时想要打印一个 transaction 的内容,或者需要比较两个 transaction 是否相等(比如 scoreboard 中比对 expected 和 actual),又或者需要复制一个 transaction 时,如果每个字段都手动编写逻辑,不仅代码冗长,而且极易遗漏,一旦新增字段,所有相关函数都要同步修改。每个字段宏会在内部将字段的类型、偏移、名称和标志信息记录下来,UVM 在运行时通过反射机制访问这些字段,从而实现通用方法。的字段),失败时打印详细的差异信息,极大地方便了调试。

2026-08-21 10:00:00 610

原创 UVM 工厂 Factory 与 Override:复用与灵活性的基石

假设我们有一个基础的my_driver,现在要创建一个带错误注入的派生类。// 基础 driver...endclass// 错误注入 driver...// 在发送正常事务后,偶尔插入错误事务endtaskendclass。

2026-08-20 10:00:00 682

原创 UVM config_db set/get:全局配置的“邮局系统”

是一个基于的参数化类,用于在 UVM 环境的不同组件之间共享配置信息。它本质上是一个全局的配置数据库,以键值对的形式存储数据,支持按层次路径进行检索。

2026-08-19 10:00:00 468

原创 UVM Env 与 Agent (Active / Passive):灵活复用的组件化设计

在 IP 级,DUT 是单个模块,所有接口都需要被驱动和监测。在 IP 级验证中,一个 UART、SPI 或 DMA 模块通常是完整的 DUT,验证环境需要为其提供激励(由 driver 驱动总线),同时也要监测其输出(monitor 采样),因此环境中的 agent 必须。这样,同一个 agent 类可以在 IP 级作为主动激励源,在 SOC 级变为被动观察者,实现“一次编写,到处复用”。当项目从 IP 级走向 SOC 级,我们不需要重写 agent,只需改一行配置,就能让环境适应新的验证层次。

2026-08-18 10:00:00 879

原创 UVM Subscriber:一个订阅者,多种用途

Analysis port 的广播是并发执行的,多个 subscriber 的。

2026-08-17 10:00:00 515

原创 UVM Scoreboard 与 in_order / algorithm:从 FIFO 到乱序比对的进化

Scoreboard 是验证平台的比对中心,它不产生激励,也不驱动 DUT,只负责接收事务并进行比对。Expected 事务:来自参考模型、序列生成器或其他预测源。Actual 事务:来自 DUT 输出 monitor 的观测结果。比对通过则代表 DUT 行为符合预期,失败则报错。Scoreboard 通常使用接收来自 analysis port 的事务。当内置比较器不满足需求(例如需要同时比对多个字段、进行更深层的检查、处理特殊协议),验证工程师会自己实现 scoreboard。从继承。

2026-08-16 10:00:00 873

原创 UVM Monitor 与 Analysis Port:观察者与广播站

如果 monitor 使用阻塞端口,那么当某个 subscriber(如 scoreboard)处理缓慢时,monitor 会被阻塞,可能错过后续事务的采样,甚至干扰仿真时序。当它识别到一个完整的事务(例如一次总线读写、一个数据包)发生时,它会创建一个 transaction 对象,将接口上的信号采样进去,然后通过 analysis port 发送出去。它像一名安静的观察者,从不主动改变 DUT 的任何信号,只是被动地采样接口上的事务,然后通过。DUT 的输入输出、内部状态,并将观察结果传递给检查组件。

2026-08-15 10:00:00 833

原创 UVM Driver 与 BFM:从 Transaction 到真实波形的最后一公里

/ BFM 写任务// 等待 hready 为高while (!hready);// 可添加若干周期延迟endtask// BFM 读任务while (!hready);endtask经过多个项目的锤炼,我发现验证平台中最能体现架构设计能力的就是 BFM 与 driver 的解耦。一套高度可配置的 BFM,覆盖完整的总线协议,带有随机延迟、错误注入、响应等待等特性。一个极简的 driver,只负责“搬运” transaction,不包含任何时序细节。

2026-08-14 10:00:00 808

原创 UVM Adapter:寄存器模型与总线的“翻译官”

标准协议 VIP(AHB, AXI, APB 等):通常商业 VIP 会附带内置的 adapter,只需在环境中实例化并连接map与predictor即可。但要小心 VIP 版本差异,可能需要对默认 adapter 进行少量定制。自研总线或非标准接口:必须从头编写 adapter。这时,上面的示例模板可直接复用,重点是根据你自己的 transaction 字段修改映射关系。多总线 SoC 环境:可能存在多个 adapter,分别对应不同的map(如 AHB map, AXI map)。

2026-08-13 10:00:00 981

原创 UVM predict 函数:镜像值同步的“幕后推手”

如果你们使用的是自主开发的总线或非标准协议,没有现成的 VIP,就需要按照上面第 3 节的代码示例,自行实现 adapter 和 predictor。核心工作是bus2reg函数,它必须能准确提取 transaction 中的地址、数据、读写方向,并正确填入结构体中。重点:自定义 predictor 时,务必保证 monitor 发出 transaction 的时间与总线实际时序严格对齐,避免“未完成的写”被提前 predict,造成镜像值错误。镜像值同步看似细小,却是 RAL 能否正确工作的基石。

2026-08-12 10:00:00 542

原创 UVM frontdoor vs backdoor:两条路,两种使命

Frontdoor 和 backdoor 如同验证工程师的两只手:一只手长而有力,稳定可靠,负责重活和正式工作(frontdoor);另一只手短小灵活,用于快速完成辅助任务和探索不可见区域(backdoor)。所有自动比对和 scoreboard,一律使用 frontdoor 采集的寄存器值,绝不能用 backdoor 结果代替。backdoor 主要用于初始化和 debug,在回归测试中尽量减少对 backdoor 的依赖,或者对 backdoor 操作增加明确约束和审核。

2026-08-11 10:00:00 636

原创 UVM RAL 基础:让寄存器验证从手工操作变为面向对象

RAL 是验证工程师的重要分水岭。它不单是会用几个 API,而是要求你深刻理解对象建模、总线适配、同步机制和域级权限。熟练掌握 RAL 后,寄存器验证的效率可以提升数倍,并且能为后续的 formality 检查、固件协同仿真打下坚实基础。不要完全手写 RAL 模型,务必使用工具或脚本生成。生成代码保证了格式一致性,避免了手写偏移、位段配置错误。唯一需要人工编写的通常是和转换函数,这部分需要深入理解总线的具体传输时序。把 RAL 当做验证环境的基础设施,一次投入,持续受益。

2026-08-10 10:00:00 712

原创 UVM virtual sequencer 与 virtual sequence:从“各自为战”到“统一调度”

Virtual Sequencer —— 调度席只负责持有 real sequencer 的句柄,不生产 item,不运行 sequence。Virtual Sequence —— 调度员在 body 里通过拿到调度席上所有生产线的引用,编排它们在时间上的启动、等待、并行与串行关系。Real Sequencer —— 生产线真实干活,将 item 交给 driver 产生波形。掌握这组概念并牢记它们的分工,可以让复杂的多接口激励场景变得干净、可维护。

2026-08-09 07:20:57 470

原创 UVM sequencer 仲裁:SEQ_ARB

总而言之,UVM sequencer 仲裁不是什么高深玄学,而是一套规整的调度策略。理解它,用好它,可以让我们的多路激励调度更贴近真实硬件行为,也让随机测试的覆盖率和有效性再上一个台阶。

2026-08-08 10:00:00 359

原创 UVM sequence 执行流程

在 UVM 验证环境里,sequence 是“交易生成器”,但写好一个 sequence 之后,它究竟是怎么跑起来的?调用了之后,UVM 内部经历了哪些“仪式”和“暗箱操作”?start()

2026-08-07 10:00:00 907

原创 VCS仿真与UVM类型覆盖

在《UVM实战》的第八章看到了uvm_set_type_override的用法,但是目前接触的并不多,于是了解了一下这个功能的相关作用以及优势。的验证层级来说,通常几个场景相近的tc会使用相同的cfg配置,而这个时候如果新建多个tc会导致tc文件的冗余,更简洁优雅的方式是通过使用同一个。这种工作方式的优点在于,对于。可以减少冗余文件的产生。

2026-08-06 10:00:00 553

原创 UVM验证环境中的Checker

在UVM验证环境中,Checker(检查器)通常由多个互补组件协同构成,常见的包括。三者分别从时序/控制、配置空间和数据通路三个层面进行校验,共同提升验证的完备性。下面分别介绍各自的定位、适用场景及注意事项。

2026-08-05 10:00:00 552

原创 UVM验证环境中多通道并行处理架构设计总结

本文摘要:针对多通道验证场景,推荐采用多个独立RM实例而非单RM多线程方案(150字) 核心建议: 架构选择:8个独立物理通道应实例化8个RM,相比单RM多线程方案具有代码简洁、调试友好、线程安全等优势 同步机制:通过中央sync_bus组件实现跨RM同步,避免直接耦合,保持组件独立性 状态机设计:抽象事务级状态而非复制RTL编码,采用"通道状态+全局仲裁"两级架构 连接原则:物理通道与验证组件严格一一对应,通过TLM通信替代物理驱动 关键优势:该方案在可维护性、调试效率和场景覆盖度上显著优于传统多线程方案

2026-08-04 10:00:00 517

原创 UVM sequencer 与 sequence 关系

99% 的验证场景,直接用就够了。只有在需要精细控制 item 的创建时机、随机化与发送分离、或者实现复杂调度时,才需要手工拆成→ 随机化 →。1 个 sequencer 配 1 个 driver 是 UVM 的默认设计。如果需要在多个接口之间协调激励,就用来调度多个底层 sequencer。sequence 写剧本 → sequencer 当调度员 → driver 当执行者。各司其职,验证平台才能跑得顺畅。

2026-08-03 10:00:00 752

原创 UVM TLM 2.0

95% 的场景,就够了。FIFO 配阻塞 + 非阻塞混用,反而容易把自己绕晕。:点对点阻塞/非阻塞通信,适合 sequencer↔driver、producer↔consumer 等一对一的场景。:本质是,支持write()广播写入,适合 monitor → scoreboard / coverage collector 这种一对多的场景。默认无界(unbounded),不用担心满的问题。我的建议除非你明确需要非阻塞的try_put()try_get(),否则。

2026-08-02 10:00:00 531

原创 Git 分支操作与恢复完整记录

用户在 GitLab 上进行分支操作,经历了从合并代码 → 代码混乱 → 恢复代码 → 重置分支 → 修正上游绑定 → 成功推送的完整过程。是一个临时指针,会被多次覆盖,不一定指向合并前的状态。找到目标提交哈希值,或直接强制同步远程分支。将本地分支强制重置为远程同事分支的最新状态。推送成功后,本地分支和远程分支完全同步,结果:代码混乱,误删了同事的代码。(主分支),不是自己的远程分支!用户 Git 版本较旧,不支持。origin/分支名。

2026-08-01 10:00:00 296

原创 UVM验证环境中`while(1)`与仿真结束机制总结

UVM仿真结束机制与while(1)循环处理指南 UVM验证环境中,各组件(Driver、Monitor等)的while(1)循环不会阻碍仿真正常结束,核心机制如下: Objection机制:仅由sequence/test控制raise/drop,其他组件严禁干预; 隐式线程终止:objection归零后,UVM自动执行disable fork终止所有子线程; 时间推进:循环内必须包含@(posedge clk)等时间语句。 关键实践: 序列使用try-finally确保objection释放 推荐实现"毒

2026-07-31 10:00:00 497

原创 UVM TLM 1.0

99% 的场景,你只需要就够了。putget是 TLM 1.0 的“原子操作”,但它们阻塞特性容易影响仿真效率,且点对点模式扩展性差。实际工程中,Monitor 到 Scoreboard 用,Scoreboard 内部用实现write()方法,既简单又高效。transport虽然强大,但仅在寄存器后门读写、或者需要同步请求-响应的特殊场景下才会用到,普通验证工程师一年都碰不上几次。最后一句忠告理解putgettransport的原理,对看懂 UVM 源码和底层机制大有裨益;但写环境时,拥抱。

2026-07-30 10:00:00 484

原创 UVM Objection 机制:原理说明与工程实践规范

集中权限:objection 的 raise 与 drop 操作应集中于 test 层或顶层 virtual sequence,driver、monitor、scoreboard 等底层组件不参与 phase 控制,各司其职。配对检查:编码时须确保每一条 raise 调用都存在明确且可执行到的 drop 调用,建议通过代码走查或静态检查工具加以保障。职责分离:底层组件仅负责协议驱动、数据采集与比对检查,phase 的生命周期管理交由测试调度层统一把控。

2026-07-29 10:00:00 605

原创 UVM phase 机制

分工明确,各司其职只 create——创建对象,配置参数只 wire——连接端口,绑定 TLMrun_phase只 drive——启动激励,控制仿真结束phase 是 UVM 调度的核心,理解它就理解了 UVM 的一半。

2026-07-28 10:00:00 308

原创 UVM 组件 vs 对象

动”用 object,“静”用 component。所有在仿真中流动、变化、最终销毁的数据(transaction、配置)都是object;所有组成环境骨架、贯穿整个仿真、等待并消耗时间的结构(driver、monitor、scoreboard)都是component。下次再创建类时,先问自己一句:它需要run_phase吗?需要 parent 吗?回答不出?那它多半是个 object。

2026-07-27 10:00:00 663

原创 UVM 虚拟序列直接修改子序列非 rand 变量:可行性与设计权衡

维度直接修改非rand变量推荐方式(配置对象 / config_db / rand)可行性✅ 语法允许,运行正常✅ 同样可行封装性❌ 极差,内部暴露✅ 良好,接口明确耦合度❌ 高耦合,难以维护✅ 低耦合,易于替换扩展性❌ 修改内部影响外部✅ 内部变化不影响外部UVM 风格❌ 反模式✅ 符合 UVM 设计哲学结论:虽然直接修改子序列的非rand变量在技术上是可行的,但为了构建健壮、可维护、可重用的 UVM 验证环境,应坚决避免此做法,而采用配置对象、或随机化约束等标准机制。

2026-07-26 07:58:50 168

原创 回调注册代码的最佳放置位置

这虽然意味着 TC 代码会多出一行显式的注册调用,但换来的却是极高的自由度——每个 TC 可以根据自身场景,注册完全不同的回调子类(例如只注错一次、连续注错三次、随机间隔注错,甚至基于当前波特率动态计算错误时机)。对比将注册隐藏在 Agent 内部的做法,这种显式性大幅降低了代码阅读的心智负担,也使得仿真日志中的回调触发行为更容易被追溯和定位。)和条件判断分支,这反而将原本简单的注错逻辑拖入配置管理的泥潭,违背了“封装即简化”的初衷,最终使 Agent 的职责变得臃肿而模糊。

2026-07-25 10:00:00 478

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除