1. 混合信号验证为什么非要上 MSDV
1.1 全模拟仿真撑不住的时候,就得换思路
做混合信号芯片验证的朋友应该都有过这种体验:一个 SOC 里面塞了 LDO、PLL、ADC、DAC、温度传感器,再加上一堆数字逻辑。如果按照传统做法,把模拟模块用晶体管级网表跑一遍 full-spice 仿真,再把数字部分也用 spice 一起带进去——理论上没问题,实际上根本跑不动。规模稍微上点量级,比如一个带 12-bit SAR ADC 的电源管理芯片,全模拟仿真跑一次典型场景就要十几个小时甚至几天,验证周期根本耗不起。
MSDV(Mixed-Signal Design Verification)解决的就是这个矛盾。它的核心思路,不是让模拟部分和数字部分都在同一个精度下仿真,而是把数字功能验证放在首位,模拟模块通过 RNM(Real Number Modeling)转化成能在数字仿真器里跑的行为模型。数字验证工程师保住自己的验证效率,模拟工程师保留对关键模拟指标的仿真精度,两边通过统一的验证平台协作。
这个方案不是替代模拟仿真,而是把验证分成了两个层次。模拟模块本身的性能指标,比如 PSRR、THD、offset,仍然要在晶体管级仿真里确认;但芯片级的功能验证,比如寄存器配置、状态机跳转、上下电时序、中断响应,就完全可以在 MSDV 平台上跑。两者叠加,才是完整的验证收敛。
1.2 MSDV 到底是怎么把模拟和数字拉通的
MSDV 的典型架构就是标题里提到的 Verilog-on-Top。意思是 testbench 顶层是 Verilog 写的,整个芯片的 DUT 也被抽象成 Verilog 模块,模拟模块在顶层网表里以实例的形式挂进去。关键点在于:模拟模块的真实电路并不会直接出现在这张数字网表里,而是用一个 RNM 模型文件代替。仿真器在跑的时候,遇到模拟模块实例,就调用对应的 RNM 模型来计算端口上的电压电流关系。
这样一来,整个验证环境的电气行为核心就是数字事件驱动仿真,RNM 模型产生的模拟量被抽象成 real 类型变量,只保留功能和时序特性,丢掉模拟波形细节。举个例子,一个 LDO 的线性调整率,RNM 模型不会真的去解 MOSFET 的平方率方程,但会保证一个事实:输入电压在某个范围内变化,输出保持在额定值附近,瞬态响应时间也被近似建模。
这种方式带来的好处很直接:仿真速度能比混合信号联合仿真快几十倍,同时验证平台可以由纯数字团队维护,不需要每个做验证的人都精通 spice 和模拟电路。你只需要理解模型的端口含义、精度限制、适用边界,就能跑通整个芯片级验证。
2. RNM 抽象:把模拟信号“数字化”建模
2.1 RNM 本质是什么,和真实模拟信号差在哪
RNM 是 Real Number Modeling 的缩写,直译是实数建模。之所以叫“实数”,是因为它用 Verilog 的 real 类型变量来表达连续变化的物理量,比如电压、电流、电荷。对比一下:数字信号是 0/1/X/Z 四态,模拟信号理论上无限精度,RNM 恰好站在中间——有“连续值”,但只在数字仿真器的离散时间步长上更新。
打个比方,RNM 模型里的电压,就像你手机上的实时天气温度。你以为它是每时每刻都在变化的连续量,实际上你看到的每分钟刷新一次的数据,是一个采样过程。刷新频率够高,观察到的温度曲线就够平滑;如果刷新频率太低,就会漏掉过程中的尖峰和毛刺。RNM 模型同样如此,它的时间精度取决于模型内部的事件触发机制,而不是真正意义上的连续时间求解。
所以 RNM 和 spice 模型相比是有信息损失的。晶体管模型能算出 3.3V 电源在负载突变时 10ns 内的过冲尖峰,RNM 模型如果没写这个事件,仿真结果就是平的。这也是为什么 MSDV 平台的验证方案一定要把模拟指标验证和功能验证分开,RNM 模型只负责功能验证层面。
2.2 VDN 与 UDN 两种建模风格怎么选
RNM 建模在实现上有两种典型风格:VDN(Value-Driven Network,值驱动网络)和 UDN(Update-Driven Network,事件驱动网络)。
VDN 的特点是所有模块的端口值在每个仿真时间步都重新计算,不依赖事件调度。优点是好写、好调试,仿真初值处理简单,适合大多数功能验证场景。缺点是仿真器在每个时间点都做全量更新,时间步特别小的时候,仿真速度会下降,而且容易出现大量无意义的微小更新。
UDN 则更接近真实模拟电路的行为方式,模块只在输入端发生变化时才被触发计算,输出值更新后,如果满足事件触发条件,再继续传播。这种风格效率更高,因为不是每个模块每时每刻都在算;但写模型的复杂度明显增加,必须处理好初值、初始化事件、自触发等边界条件,否则很容易出现某个输出一直不更新的问题。
选型上,我个人的经验是:系统级功能验证用 VDN 起步,等模型调稳定了,对性能有明确瓶颈再转向 UDN。不要一上来就写 UDN,Debug 代价高出来不是一点半点。
2.3 手写一个简单的 RNM 模型示例
这里拿一个最简单的 LDO 模型来做说明,功能是 3.3V 输入转 1.8V 输出,带过流保护,输出电流限制在 100mA。模型只保留三个行为特征:线性稳压、负载调整率、过流折返。
module ldo_rnm #( parameter real VOUT_NOM = 1.8, parameter real VIN_MIN = 2.0, parameter real I_LIMIT = 0.1, parameter real R_OUT = 1.0 ) ( input real vin, input real i_load, output real vout ); real vout_int; real vout_reg; always @* begin if (vin < VIN_MIN) begin // 输入欠压,输出跟着输入走 vout_int = 0; end else begin // 正常稳压输出 vout_int = VOUT_NOM - i_load * R_OUT; // 过流保护 if (i_load > I_LIMIT) vout_int = 0; end vout = vout_int; end endmodule这段代码简化了瞬态响应、启动斜坡和温度特性,但已经能表达 RNM 建模的核心思想:用 verilog 的 real 端口传递连续量,用 always 块模拟模块行为,对外部激励产生合理响应。实际项目中,ADC、PLL、DAC 的 RNM 模型比这个复杂得多,但基本结构是一样的:输入激励、内部状态、输出响应。
3. Verilog-on-Top 架构:testbench 和 DUT 怎么搭
3.1 为什么 Testbench 顶层要用 Verilog
很多从模拟背景转过来的工程师会问一个问题:顶层用 Verilog 而不是 Verilog-AMS,优势在哪里?答案其实很实际。从工具链角度看,数字验证的编译、仿真、覆盖率收集、形式化验证工具都围绕 Verilog 生态展开,用 Verilog 做顶层可以无缝接入这些工具;而 AMS 仿真器的使用场景受限,调度复杂,仿真成本高。
从团队协作角度看,数字验证工程师是验证工作的主力,让他们维护一个纯 Verilog 平台显然比让他们去学 AMS 建模语言靠谱得多。模拟工程师只需要交付 RNM 模型文件,约好端口定义和精度约束,剩下的都是数字团队能搞定的活。
Verilog-on-Top 还有一层含义:整个系统的例化层级、连接关系都体现在 Verilog 网表里,模拟模块被当成一个黑盒实例。这让网表管理愈加清晰,如果是跑后仿,也方便在这个网表的基础上替换成带有具体延迟参数的版本。
3.2 模拟实例怎么挂进数字网表
写 Verilog-on-Top 的网表,关键在模拟模块的实例化方式。由于 RNM 模型本身就是 Verilog 模块,实例化方式和纯数字 IP 基本没有区别,你要做的是端口映射,以及确保模拟端口连接到的信号类型是 real 而不是 wire/logic。
这里容易踩坑的点在于:一个 12-bit DAC 的输出应该是 real 类型表示电压值,如果你在 top 网表里定义成 wire [11:0],那整个连接语义就错了。所以写 top 之前,模拟工程师和数字工程师必须对齐一份端口定义表,明确哪些端口是数字总线、哪些端口是 real 模拟量、哪些端口是双向的。
还有个容易被忽略的点是电源域。RNM 模型内部要不要处理 VDD/GND 端口,取决于模型抽象粒度。粗粒度场景下,模型默认电源正常,不显式处理电源脚;细粒度场景下,模型需要监控 VDD 跌落并产生 reset 行为。两种做法都对,但必须在项目启动时约定好,否则验证团队拿到模型以后,不知道顶层网表需不需要把电源网络连进去,很容易出现模型悬空的情况。
3.3 边界连接和接口模块的处理经验
数字信号和模拟信号在 top 网表里连接,经常需要做显式转换。你可以在 RNM 模型内部完成转换,也可以在模型外挂一个接口模块(connect module)。我的建议是,连接逻辑尽量放到模型内部,让顶层网表看起来更接近真实芯片的端口连接关系。否则顶层网表会堆满各种转换单元,后仿调试的时候找信号要翻半天。如果你用的是 Cadence Xcelium 跑 MSDV,connect rule 的配置可以在仿真命令里指定,也可以写在 config 文件里。具体配置项的选择(比如 real 到 logic 的阈值电平是 0.8V 还是 1.2V)会影响仿真精度,最好由模拟团队提供数值。
4. 从 RNM 模型到一份能跑的网表
4.1 网表种类太多,先分清仿真网表和 PCB 网表
说到“网表”这个词,不同岗位的人各说各话,我遇到过太多次因为网表概念不统一导致的沟通事故。做仿真的工程师说的网表,通常是指描述电路连接关系的 SPICE 网表或者 Verilog 网表,里面的内容是晶体管、电阻、电容、门级单元、模块实例。而做 PCB 的工程师说的网表,是从 OrCAD Capture 原理图导出的、给 Allegro PCB Designer 用的网表,里面是元器件位号、封装、网络名。同一个词,两种场景。
在 MSDV 流程里,“模型怎么落地成一份能跑的网表”这句话,我认为包含两层含义:第一层是仿真网表的生成,即 RNM 模型如何参与编译、链接、迭代,最终变成一个可仿真的 netlist;第二层是版图/PCB 网表的落地,即模拟模块的真实拓扑结构如何映射到最终物理版图或者 PCB 原理图上。很多人忽略了第二层,导致验证跑通了,但实际电路根本做不到模型假设的性能指标,问题就在这一步。
4.2 从模型到仿真网表的落地流程
RNM 模型本身不能直接跑后仿,需要经过一系列处理才能变成一个可执行的仿真网表。第一步是编译,用仿真器的编译命令把 RNM 模型文件和 Verilog testbench 一起编译成可执行代码,Xcelium 里对应的是 xmvlog / xmelab,VCS 里对应的是 vlogan / vcs。这一步检查的是语法、端口连接、类型匹配,编译过了不代表功能对,只是基础关卡。
第二步是连接电源和地,为模型提供运行条件。很多 RNM 模型为了简化,内部不使用全局电源网络,但如果你要验证上下电时序,就必须给模型增加一个状态变量来模拟内部逻辑是否被供电,再在模型外部显式连接电源信号。我做过一个 PMIC 验证项目,模型初次跑上电测试,发现某些模块的输出在电源还没起来时就有值,查了半天发现模型把电源依赖关系写死在 initial 块里了,初始化阶段就默认 VDD 正常。
第三步是参数注入。RNM 模型通常大量使用 parameter,比如 LDO 的输出电压值、ADC 的参考电压、DAC 的满幅输出。这些参数在模型里给的是默认值,实际项目必须通过顶层网表的 defparam 或实例化参数传入。参数传错是典型的低级错误,比如把 LDO 的 1.8V 写成了 18.0,仿真结果看起来像是欠压故障,排查的时候要把参数打印出来对照设计规格。
第四步是混仿配置。如果你的平台需要在某些场景调用真实模拟模型,比如特定模块的精度验证,就需要配置 Co-Simulation 接口,把数字仿真器和模拟 solver 耦合起来。这一步要额外关注时间和事件的同步精度,否则数字侧的时间步和模拟侧的时间步不匹配,会导致接口处出现毛刺或不收敛。
4.3 OrCAD 导出网表与 Allegro 导入网表的实操要点
这部分切入 PCB 设计中网表落地的高频痛点。从 OrCAD Capture 导出网表到 Allegro 导入网表,整个流程如果没跑顺,会出现元件丢失、网络对不上、封装不匹配等各种问题。我整理几个最关键的实操要点。
第一步,在 OrCAD 原理图设计完成后,选择 Tools/Create Netlist,在弹出的对话框里选择 Allegro 选项。注意这里不要选成 Other 格式,否则导出的网表 Allegro 认不了。导出时勾选 “Create PCB Editor Netlist”,工具会生成三个文件:pstchip.dat、pstxnet.dat、pstxprt.dat,这三个文件就是要交给 Allegro 的网表文件。
第二步,打开 Allegro PCB Designer,执行 File/Import/Logic,在弹出的对话框里选择网表来源是 “Capture”,再把路径指向刚才生成文件的目录。很多人卡在这一步,提示找不到网表,多半是路径里包含中文或者空格,Allegro 对这类路径兼容性很差。我会先建议把整个工程放到纯英文无空格的路径下再试一次。
第三步,导入完成后,在 Allegro 的 Command 窗口输入tools create symbols,让 Allegro 根据网表自动创建需要的封装符号。如果封装库路径配置不正确,这一步会报错,说明你的封装库没有覆盖到全部元件。
实操中我碰到最多的坑就是:OrCAD 原理图里用的封装名和 Allegro 库里的封装名不一致。要么是多了个空格,要么是大小写差异,都会导致导入失败。解决方案是在 OrCAD 原理图中统一封装命名规范,最好用数字和字母标准的组合,比如C0402、R0603,不要用cap_0402、res_0603这类混搭命名。这个规律,如果你用 Allegro 做过多层板,估计也踩过。
5. 常见问题排查与实操心得
5.1 RNM 模型仿真遇到 NaN 和不收敛
RNM 模型跑仿真跑出 NaN(Not a Number),是混合信号验证里最容易让人抓狂的问题,因为 NaN 出现在波形图里就是一整片红色,根本看不出原因。我遇到过的典型场景是:ADC 模型在复位释放瞬间,采样逻辑读取到一个未初始化的 real 变量,参与运算后直接污染后面所有结果。
解决办法有几步:第一,要仔细做代码 review 检查所有 real 变量的初始化路径。在 module 的 initial 块里对所有 real 状态变量赋初值,不要依赖默认值。第二,在模型入口处加保护,如果输入是 NaN 或者无穷大,就直接将输出置为安全值,阻断污染传播。第三,仿真器配置打开浮点异常检测,Xcelium 有-ams_nan_handler选项,VCS 也有对应的浮点陷阱开关,可以帮你把报错定位到具体 rb 表达式和仿真的时间戳。
5.2 Connect Rule 配置不当导致精度丢失
Verilog-on-Top 网表里,real 信号和 bit 信号交界处需要 connect rule 来确定转换规则。一个典型错误是:把真实的模拟电压连接到数字模块输入时,connect rule 的阈值电平设置过高或过低,导致数字模块一直读到错误逻辑值。
比如 1.8V 的 IO 电压接到数字模块,数字模块的输入阈值是 0.63V/0.9V,如果你在 connect module 里设置的逻辑高阈值是 1.2V,那么一个实际 1.1V 的输出电平在数字域会被判定为 0,逻辑直接出错。这个问题的解决要点一定是由模拟工程师提供真实的接口电平参数,不要凭感觉估。
另外,connect rule 中还要注意时间延迟。真实电路从模拟信号跳变到数字逻辑稳定需要一定建立时间,connect rule 里不设置 delay,仿真器默认零延迟,会忽略真实世界中存在的时序边界。如果验证目标是时序收敛和时序裕量,这个细节必须体现。
5.3 仿真效率优化与回归集合理念
MSDV 平台的验证效率是它最大的卖点,但前提是你不能把所有场景都放在同一套仿真精度下。我的建议是把验证场景分为三层:第一层是开关级功能验证,使用纯 RNM 模型,跑最快的仿真配置;第二层是接口级验证,在关键模拟模块与数字交互的边界上开启部分真实模拟模型,用于发现接口协议问题;第三层是全精度验证,在 tapeout 前跑有限的关键场景,例如上下电、时钟切换、校准流程。
效率优化的另一个技巧是有选择地降低采样频率。RNM 模型里如果存在高频振荡更新,仿真周期会被拖得很长。此时要认真审视模型中是否存在高频自激振荡的写法,比如在一个小时间常数反馈环路上,每次更新都会产生新事件,导致事件队列爆满。我建议把这类环路的时间常数适当降低,或者直接改成按固定时间步更新,性能立刻有改善。
5.4 一份能跑的网表,最终是怎么验收的
最后聊一个经常被忽视的问题:模型和网表验收什么才算合格。只跑通一个 testbench 就叫能跑,那远远不够。我们团队在项目里定了四条验收标准:第一,RNM 模型行为必须和规格书逐条对照,可以通过编写行为断言来自动检查;第二,模型在典型测试向量下的功耗和时序指标与晶体管级仿真结果的偏差要在设定阈值以内,通常我们用 5% 作为标杆;第三,测试平台要跑完整回归集,不能只跑到冒烟测试通过;第四,网表必须由独立于建模工程师的另一名成员完成代码 review,重点检查端口映射和参数传递。
这套标准不是为了流程而流程,而是我们吃了太多亏之后总结的底线。模型和网表越是接近真实电路,后期后仿发现问题的概率就越低,修 bug 的成本也就越低。反过来说,如果在这层偷了懒,等芯片回来再发现功能问题,那时候花费的代价就是指数级的,这种痛苦相信做过几个 tapeout 项目的朋友都深有体会。
6. 写在最后的一点个人经验
这些年从纯模拟验证转到 MSDV 平台,最深的体会是:混合信号验证不是模拟工程师的事,也不是数字工程师单方面能搞定的,而是两边真正坐到一条板凳上,把建模规范、接口定义、验收标准全部提前对齐。RNM 模型写起来不难,难的是让整个团队都信任这个模型,愿意在关键节点上依赖它的结果。
我自己到了项目后期,一定会做的一件事是:把整个 MSDV testbench 里用到的所有模型版本、参数配置、关键仿真 seed 全部记录下来,形成一个可回溯的验证配置清单。这样一旦回归中出了异常,能快速定位是模型本身改动引起的,还是测试向量变化引起的。别看这件事不起眼,关键时刻能帮你节省整整一天的 debug 时间。
另外一个很现实的经验,就是要把模型维护当成交付物来管理,而不是一次性用完就扔。RNM 模型的生命周期贯穿整个项目,从早期架构验证到中后期后仿,甚至到硅片回来后做debug,都会反复用到。一个模块的模型可能要在不同项目里复用,如果一开始就做好命名规范、参数注释和版本记录,后面你会省下大量重复劳动。
希望这篇关于 MSDV、RNM、Verilog-on-Top 到网表落地的经验分享,能帮你少走一些我踩过的弯路。如果你们团队正在搭建混合信号验证环境,建议从一个小模块开始试点,跑通整个流程,再逐步铺开到全芯片。慢慢来,比较快。