简介:这份资源是面向硬件验证工程师、芯片设计师及半导体设计自动化从业者的 Cadence Xcelium(xrun)操作指南,兼顾初学者与有经验的技术人员。内容从 Linux 环境下的安装检查、单步与多阶段分离仿真、基础 option 应用讲起,深入剖析 xcelium.d 目录作用、shm/db/fsdb 波形文件生成、覆盖率收集策略,以及 Gate Level Simulation 中的 SDF 反标与参数调整,并针对复杂工程常见报错给出 debug 思路。资源包为 1 个 pdf 文件,约 505KB,篇幅紧凑、便于随查随用。目前已有 2050 人学习下载,说明其在验证社区中具备一定认可度。读者可借此快速掌握 xrun 的常用命令与高级特性,理解编译、精化、仿真三阶段的分工,学会用 help 选项定位错误、处理 license 报错,并在实际项目中提高仿真效率与排错准确性。
1. 从一条which xrun开始:这份指南能帮你省下多少试错时间
刚接手一个数字仿真环境,第一反应往往不是写 testbench,而是先确认工具到底装没装、能不能跑。which xrun打印不出路径,后面所有仿真流程都无从谈起。这份 Cadence Xcelium(xrun)操作指南,核心价值就在于把从环境确认、单步仿真、三步分离编译到覆盖率收集、门级仿真、license 排查的完整链路拆成了可复现的命令和参数说明。它适合正在用 Verilog/SystemVerilog 做数字验证的工程师,也适合刚接触 Xcelium、被xcelium.d目录和各类波形格式搞得一头雾水的从业者。我见过太多人卡在xrun的默认重载特性上,以为代码没改就不用重新编译,结果仿真结果对不上,白白浪费一整天。
2. 基础操作:从单步仿真到三步分离的完整命令链
2.1 环境确认与版本检查
拿到一个新环境,先别急着写脚本。第一步永远是确认xrun是否在 PATH 里,以及版本是否匹配项目要求。常见做法是:
which xrun # 打印 xrun 的绝对路径,确认可直接调用 xrun -version # 查看版本信息,核对与项目文档是否一致如果which xrun没有输出,说明环境变量没配好,或者工具根本没装。这时候不要硬试,先找环境管理员确认。xrun -version的输出里会包含版本号和 build 日期,有些老项目对版本敏感,版本不对可能导致 elaborate 阶段报奇怪的错误。
2.2 单步仿真与三步分离
xrun默认是单步仿真,一个命令完成 compile、elaborate、sim 三个阶段:
xrun test.v # 单步完成编译、精化、仿真但实际项目中,单步仿真往往不够用。比如你需要反复调试同一个 testbench,每次只改仿真阶段的参数,这时候三步分离更高效:
xrun -compile test.v # 只做编译,生成中间库文件 xrun -elaborate test.v # 只做精化,生成 snapshot xrun -R # 加载当前目录的 snapshot 并仿真注意:如果在 elaborate 之前没有做 compile,xrun -elaborate会自动执行 compile。xrun -R会在当前目录自动检测 elaborate 生成的 snapshot,load 后进行仿真。这个特性在反复调试时非常实用,但也要小心——如果你换了目录,snapshot 不在当前路径下,-R就会报错找不到。
2.3 基础仿真 option 速查
下面这些 option 是日常仿真里出现频率最高的,建议先混个脸熟:
| option | usage |
|---|---|
-64 | 64bit 模式 |
-sv | 支持 SystemVerilog 语言 |
-access +rwc | 设置访问权限(读、写、可执行) |
-timescale 1ns/1ps | 设置仿真时间精度 |
-f <filename> | 扫描文件,把多个源文件路径写进一个 .f 文件里 |
-top | 指定仿真的顶层模块 |
-l <filename> | 指定仿真 log 的路径和名字,不指定默认为 xrun.log |
-errormax n | 指定 error 数到达 n 时仿真 exit |
-parseinfo include | 将 compile 阶段 include 的信息打印出来 |
-f这个 option 特别值得展开说。当工程里有几十个 .v 文件时,一条条写在命令行里不现实。常见做法是建一个filelist.f,每行写一个文件路径,然后xrun -f filelist.f。注意文件里的路径可以是相对路径,但相对的是你执行 xrun 命令的目录,不是 .f 文件所在的目录。这个坑我踩过,后来统一在 .f 文件里写绝对路径或者用-f时先 cd 到工程根目录。
-errormax在回归测试里很有用。默认情况下,仿真器遇到 error 会继续跑,log 里堆几百条 error 才停。设成-errormax 10,前 10 条 error 就能让你快速定位问题,不用在 log 里大海捞针。
2.4 用 help 快速定位 option 用法
xrun有 1521 个 option,但常用的就那么几十个。遇到不认识的 option,不用翻文档:
xrun -helpargs <option> # 打印指定 option 的作用及用法 xrun -helpall > xrun_all_option.txt # 生成包含所有 option 的 txt 文件 xmhelp <tool name> <tool error> # 查看具体错误类型及原因xmhelp的 tool name 可以是xmvlog、xmelab、xmsim,分别对应 compile、elaborate、sim 三个阶段。比如 log 里出现一个*E开头的错误,直接xmhelp xmsim *E就能看到错误解释和可能的修复方向。这个习惯能帮你省下大量搜索时间。
3. 进阶特性:xcelium.d 目录、波形生成与覆盖率收集
3.1 xcelium.d 目录与默认重载特性
xrun跑完之后,当前目录会多出一个xcelium.d文件夹。这是 compile 阶段生成的 library 和 elaborate 阶段生成的 snapshot 的存放位置。不要手动删它,也不要把它提交到版本控制里。
xrun有一个默认重载特性:如果之前进行过 compile 或 elaborate,xrun会检测代码是否有修改。如果没有修改,默认直接重新载入,跳过编译和精化。这个特性在反复调试时能省时间,但也会带来一个经典翻车场景——你改了代码,但文件时间戳没变(比如从别处拷贝过来),xrun认为没修改,直接载入旧 snapshot,仿真结果自然不对。想强制重新编译,加上-clean:
xrun -clean test.v # 强制重新 compile 和 elaborate查看 snapshot 生成情况可以用xmls,但注意xmls默认查找 32bit 的 snapshot。如果仿真工具是 64bit,查找时需要加上-64:
xmls -64 # 查看 64bit snapshot 列表3.2 波形文件生成:shm、db、fsdb 三种格式
波形文件一般通过 tcl 脚本输入来生成,常见做法是:
xrun -input wave.tcl test.v三种波形格式对应不同的查看工具:
| 格式 | 查看工具 | 说明 |
|---|---|---|
| shm | SimVision | Xcelium 自带工具,无需额外 license |
| db | Indago | 调试分析工具,适合大规模信号追踪 |
| fsdb | Verdi | 业界常用,需要额外 license 和 PLI 加载 |
生成 fsdb 时,必须加上-loadpli1来保证仿真器识别 fsdb 相关 task:
xrun -input wave.tcl \ -loadpli1 ${FSDB_INST_DIR}/.../boot/debpli.so:novas_pli_boot \ test.v这里的${FSDB_INST_DIR}需要替换成实际的 Verdi 安装路径。如果这个路径写错,仿真会报 PLI 加载失败,波形文件也不会生成。我一般会先确认debpli.so文件确实存在,再写进脚本。
3.3 覆盖率收集:-coverage 与 -covoverwrite
覆盖率收集需要添加-coverageoption,后面跟要收集的覆盖率类型:
xrun -coverage B,E,F,T,U -covoverwrite test.v各字母含义如下:
| 字母 | 覆盖率类型 |
|---|---|
| B | Branch(分支覆盖率) |
| E | Expression(表达式覆盖率) |
| F | FSM(状态机覆盖率) |
| T | Toggle(翻转覆盖率) |
| U | User-defined(用户自定义覆盖率) |
| All | 以上全部 |
一般还会加上-covoverwrite,打开对覆盖率的重载功能。不加这个 option,第二次跑仿真时覆盖率数据可能不会覆盖旧数据,导致你看到的是上一次的结果。这个坑在回归测试里特别隐蔽,因为覆盖率数字看起来“正常”,但实际上没更新。
3.4 门级仿真:SDF 反标与时序检查
门级仿真(Gate Level Simulation)需要把延时文件反标到门级网标中,通过$sdf_annotate系统任务实现。常用 option 包括:
xrun -notimingcheck -nospecify -sdf_verbose -tfile tcheck.file test.v-notimingcheck:不做时序检查-nospecify:specify 不起作用,即没有延时和时序检查-sdf_verbose:展示反标的具体信息-tfile tcheck.file:关闭某个 module 的时序检查
tcheck.file的写法规则如下:
PATH test.dut.ff_i0 -tcheck // 关闭 ff_i0 的 timing check PATH test.dut_i $setup -tcheck // 关闭 dut 的 setup timing check PATH test... -tcheck // 关闭 test 所有下属层次 timing check门级仿真里零延迟门级震荡是常见问题,加上-gateloopwarn可以打印具体信息,帮你定位是哪个门产生了震荡。
4. 避坑排查:仿真报错、license 与挂死问题的处理
4.1 仿真报错:从 *E 到 -genhier
elaborate 阶段报了一个隐式名字在 hierarchy 出错的错误,log 上只显示一个*E,看起来一头雾水。这时候用xmhelp查看错误具体原因:
xmhelp xmelab *E常见原因是在使用 generate 时没有按照 Verilog 标准写法给定名称。解决方法有两种:一是按照标准写法加上名称,二是添加-genhieroption 放宽语法检查:
xrun -genhier test.v-genhier不是万能药,它只是放宽检查,不解决根本问题。如果代码里 generate 块确实需要命名,还是应该补上名字,否则后续调试时信号层级会很难看。
4.2 license 报错:-licqueue 与 lmstat
仿真阶段报 license 错误:
xmsim: *F,NOLICN: Unable to checkout license for the simulation. 'lic_error -18'.xrun只有在 simulation 阶段才会检测 license。可能的原因有两种:
一是当前服务器上有 4 个 xrun 的 license,但你提交了 5 个 xrun job。这时候加上-licqueue,让仿真排队等待 license 释放:
xrun -licqueue test.v二是你没有某些 feature 的 license。用lmstat打印 license 安装信息:
lmstat -a -c $LM_LICENSE_FILE # 或者 lmstat -a -c $CDS_LIC_FILE取决于哪个变量指向 license。lmstat的输出会列出所有 feature 的使用情况,看看你需要的 feature 是不是已经满了,或者根本没装。
4.3 仿真挂死:从波形到 linedebug
仿真器看起来像是挂死了,先别急着 kill。按以下顺序排查:
- 检查波形是否增加,即仿真时间是否在前进。如果波形在动,说明仿真没挂,只是跑得慢。
- 如果波形不动,加上
-gui -linedebug进行具体定位:
xrun -gui -linedebug test.v- 加上
-profile,查看生成的profile.out里 license check 时间。通常为 0.1s,如果特别长,代表仿真卡在等待 license 上:
xrun -profile -profoutput profile.out test.v- 如果是 gate level 仿真,也可能是零延迟门级震荡,加上
-gateloopwarn打印具体信息。
4.4 特殊场景的 option 语法扩展
有些项目里文件扩展名不标准,比如.sv11表示 SystemVerilog,.v11表示 Verilog。可以用-sysv_ext和-vlog_ext指定:
xrun -sysv_ext .sv11 -vlog_ext .v11 test.v11-profile和-profoutput配合使用,可以生成各组件 time 和内存消耗信息。profile.out包含检查 license 时间、各组件消耗仿真时间,对性能调优很有帮助。
5. 进阶技巧:用 -helpall 和 xmhelp 建立自己的排错手册
xrun -helpall生成的xrun_all_option.txt有 1521 个 option,但真正高频使用的不到 50 个。我的习惯是:第一次遇到某个场景时,用xrun -helpargs <option>查清楚用法,然后把命令和参数说明记到一个自己的xrun_notes.md里。下次遇到类似问题,直接翻笔记,不用重新查。
xmhelp的用法也值得展开。除了xmhelp xmsim *E这种查错误码的方式,还可以用xmhelp xmvlog查看 compile 阶段的所有错误类型。我一般会在项目初期把xmhelp xmvlog、xmhelp xmelab、xmhelp xmsim的输出各存一份,遇到报错先在里面搜关键字,比直接上网搜快得多。
还有一个容易被忽略的技巧:-parseinfo include可以把 compile 阶段 include 的信息打印出来。当工程里 include 路径混乱、宏定义冲突时,这个 option 能帮你快速定位到底是哪个文件被 include 了、顺序对不对。
xrun -parseinfo include -f filelist.f test.v最后说一个我自己的教训。有一次跑回归测试,覆盖率数字一直不更新,我以为是 testbench 没覆盖到新代码,查了半天才发现是没加-covoverwrite。从那以后,我每次跑覆盖率收集都强制走一遍-coverage All -covoverwrite,再也没出现过覆盖率数据不刷新的问题。希望这些经验能帮到你,少走一些我走过的弯路。
本文还有配套的精品资源,点击获取