
简介《VCS User Guide》为Synopsys VCS官方用户手册S-2021.09版面向IC设计、验证工程师及电子信息相关专业学习者用于系统了解VCS仿真验证工具的安装配置、环境搭建、库管理与日常使用。压缩包内共1个PDF文件大小约11.36MB正文涵盖许可证获取、synopsys_sim.setup创建、库概念与名称映射、仿真器设置、技术支持等章节并涉及命令行与图形界面配置、日志查看和调试排错等内容便于按目录查阅完整流程。已有4339人学习或下载具有较高参考热度。手册可作为查阅型资料帮助读者熟悉数字、模拟及混合信号IC验证中的基础操作与关键概念在搭建仿真环境、定位配置问题和规范工具使用流程时提供依据也可用于快速检索术语、流程说明与常见问题减少摸索时间适合IC验证入门者与日常工程实践参考。1. 一份 VCS 2021.09 装在 IC 设计服务器上先对齐 license 和 timescale 再谈编译IC 设计 的仿真环境里VCS 属于那种「装一次能用三年装错一次折腾三天」的工具。我见过最常见的场景新服务器到位目录结构照抄老机器vlogan能跑simv一起来就卡在 license或者更玄学的——编译全过、波形全 X最后发现两台机器的 timescale 精度不一样。S-2021.09 这个版本的文档随安装包放在$VCS_HOME/doc下很多人拿到 PDF 先翻参数表其实前三章才是重点环境变量、setup 文件、库映射。装不好不会立刻报错而是让你在回归跑到一半时才发现结果对不上那种时候排错的成本是安装阶段的十倍。这篇笔记按「先清点环境 → 再建库 → 再编译 → 最后验证」走一遍适合第一次独立在服务器上搭 VCS 的人也适合接手别人半成品环境的人。2. 装机前的环境清点VCS 2021.09 的目录、变量和 license 三件套装 VCS 这件事安装包本身反而是最简单的部分展开就能用真正决定成败的是安装前那半小时的清点工作。我一般会把它拆成三块机器能不能跑、license 拿不拿得到、路径变量有没有写对。这三块任何一块出问题表现出来的现象都长得很像——工具启动失败或者跑一半挂住新手很容易误判成安装包损坏然后重装三遍白折腾。2.1 系统、编译器与内核参数自检VCS 是纯 64 位工具链而且编译 DPI、PLI 那类 C 代码时要调用本机 gcc。先把这几项打出来看一眼uname -srm # 内核与架构必须是 x86_64 getconf LONG_BIT # 输出 64 gcc --version | head -1 # 编译 DPI/PLI 用 ulimit -s # 栈大小单位 KB df -h /opt /tmp # 安装目录与临时目录空间-full64这个参数基本是所有命令的标配但机器本身是 32 位的话加了也没用所以先看getconf LONG_BIT。gcc 版本是个隐性坑。新版发行版自带 gcc 往往偏新而工具链自带的头文件是按老编译器写的编译 DPI 时会出现一堆error: unknown type name。常见做法是单独装一个 4.8 或 7.3 的 gcc然后在环境脚本里把CC、CXX指过去别动系统默认的。ulimit -s默认一般是 8192小设计够用几十万门以上的设计做 elaborate 时容易直接段错误退出日志里还看不出原因。我一般会在环境脚本里加一句ulimit -s unlimited或者至少提到 65536。/tmp空间同样容易忽略。vcs 在细化阶段会往csrc目录和临时目录写大量中间文件一个稍大的设计占十几 GB 很正常/tmp单独分区只有 20G 的话跑到一半报「No space left on device」就很常见了。2.2 license 与环境变量先确认拿得到再动手安装之前先确认 license 服务可达这一步能省掉后面 80% 的疑似安装故障。# 指向 license 服务器端口和主机名按实际环境替换 export LM_LICENSE_FILE27020lic-srv # 查看该服务上有哪些特性被占用、还有多少空闲 lmstat -a -c $LM_LICENSE_FILE | grep -i -E vcs|Users ofLM_LICENSE_FILE是通用变量名多数工具链都认有些环境还会额外用厂商自己的专用变量两个都设上不冲突反而是保险做法。lmstat的输出重点看两处Users of ...后面括号里的数字是「已用/总数」如果已用已经等于总数那不是你装错了是排队问题。提示批处理作业系统LSF、Slurm 之类提交时不一定继承登录 shell 的环境变量很多人本地跑得好好的一进队列就报 license 错原因就在这里。环境脚本要在作业脚本开头重新 source 一次。编译和运行时都建议加上vcslicwait作用是在 license 全被占用时排队等待而不是直接失败。回归夜里跑几百个 case没有这个参数的话前几个把 license 占满后面全部瞬间失败早上一看日志一片红以为是设计问题。还有一点license 里的版本号要和安装的版本对得上。S-2021.09 需要服务端有对应版本的特性行版本太老的 license 文件即使能 checkout也可能在细化阶段报版本不匹配。2.3 安装目录规划与环境变量脚本目录我一般这样分工具装/opt/eda/工程放/proj/中间产物放本地盘或者高速盘。工具目录装完就只读别往里写东西不然下次升级会很难受。# /opt/eda/env/vcs.sh —— 每次开新 shell 都 source 一次 export VCS_HOME/opt/eda/vcs/S-2021.09 export PATH$VCS_HOME/bin:$PATH export LD_LIBRARY_PATH$VCS_HOME/linux64/lib:$LD_LIBRARY_PATH export LM_LICENSE_FILE27020lic-srv ulimit -s unlimited # 检查关键可执行文件是否都在 ls $VCS_HOME/bin | grep -E ^(vcs|vlogan|vhdlan|vdir)$ which vcs vlogan vhdlanPATH一定要放在最前面别用PATH$PATH:$VCS_HOME/bin这种追加写法。机器上装了两三个版本的时候追加写法会让老版本优先命中vcs -ID查出来是哪个版本会发现根本不是你以为的那个这种坑排查起来非常费时间。LD_LIBRARY_PATH指向linux64/lib缺了它最典型的报错是启动时提示找不到某个.so。有些机器上还会遇到架构判断错误这时候才需要加VCS_ARCH_OVERRIDElinux64强制指定平时不用设。变量典型值作用写错的后果VCS_HOME/opt/eda/vcs/S-2021.09工具根目录文档、库路径全部找不到PATH$VCS_HOME/bin:$PATH命令查找命中老版本或 command not foundLD_LIBRARY_PATH$VCS_HOME/linux64/lib运行时库启动报.so缺失LM_LICENSE_FILE27020lic-srvlicense 服务编译/仿真卡在 checkoutSYNOPSYS_SIM_SETUP工程内 setup 文件绝对路径指定库映射读到 home 里的旧配置3. 库与 setup 文件synopsys_sim.setup 的映射规则和查找顺序VCS 里「库library」的概念和软件工程里的库不太一样它更像一个存放已分析设计单元的容器vlogan或vhdlan把源码分析进某个库细化阶段再从库里按名字找模块。库到物理目录的对应关系全靠synopsys_sim.setup这个文本文件描述。这份文件写错报错信息往往只有一句「module not found」看不出任何线索。3.1 两段式还是三段式先定流程再建库流程选错后面所有脚本都得重写所以第一步先把这件事定下来。流程命令序列适用场景增量能力两段式vcs→simv纯 Verilog / SystemVerilog 工程加-Mupdate可增量编译三段式vhdlan/vlogan→vcs→simv含 VHDL、混合语言、需要分库管理改一个文件只重新分析该文件判断标准很简单工程里有.vhd文件就必须走三段式因为vcs单条命令不能直接吃 VHDL。就算全是 Verilog如果设计规模大、编译一次要十几分钟也建议走三段式因为分析阶段是文件粒度的改一个文件只重分析一个细化阶段可以靠-Mupdate增量整体迭代速度能快好几倍。混合语言工程还有个隐含要求VHDL 和 Verilog 之间的层次引用必须在细化阶段一次性解析完所以三段式的第二步不能省。3.2 setup 文件里到底写什么一个能用的最小 setup 文件长这样放在工程根目录# ./synopsys_sim.setup work : ./work rtl_lib : ./libs/rtl tb_lib : ./libs/tb gate_lib : ./libs/gate # 把站点级公共配置拆出去避免每个工程抄一遍 INCLUDE /proj/common/site.setup每行的格式是库名 : 物理路径冒号两边空格随意但库名不能带空格。work是默认库名vlogan不给-work参数时就会往这里写。路径写相对还是绝对是这里最容易踩的坑相对路径是相对于你敲命令时的当前目录不是相对于 setup 文件所在目录。所以同一个 setup 文件在工程根目录下跑和在sim/子目录下跑指向的是两个不同的物理目录表现就是「明明分析过了却说模块不存在」。我的习惯是库路径一律写绝对路径或者用$ENV{变量}展开宁可长一点。注意INCLUDE引入的文件里如果又定义了同名的库后面的定义会覆盖前面的。站点级配置里放公共工艺库工程级 setup 里放项目库顺序别搞反。手册第 1 章的 Library Name Mapping 一节讲的是库名别名映射设计代码里如果写死了某个库名迁移环境时不用改代码在 setup 里加一行别名指向真实库就行。这一行在换机器、换目录的时候能省掉大量改动量。3.3 setup 文件的查找顺序与 SYNOPSYS_SIM_SETUP工具找 setup 文件是按顺序来的找到第一个就停当前工作目录下的synopsys_sim.setup环境变量SYNOPSYS_SIM_SETUP指向的文件用户 home 目录下的synopsys_sim.setup这个「三级兜底」是最隐蔽的坑。新人接手环境时经常在工程目录下建好了 setup跑起来却还是报模块找不到查半天发现 home 目录里躺着一个几年前留下的旧 setup里面把work映射到了另一个路径——只要当前目录没有 setup 文件就会命中它。# 明确指定避免读到 home 里的历史配置 export SYNOPSYS_SIM_SETUP$PROJ/vcs/synopsys_sim.setupSYNOPSYS_SIM_SETUP我一般直接指向工程内文件的绝对路径这样不管在哪个子目录下敲命令读到的都是同一份配置。代价是同一台机器上同时做两个项目时切项目必须重新 source所以项目切换脚本里要带上这一句。分析完之后怎么确认库里有东西用vdir# 列出 work 库里已分析的设计单元 vdir -lib work # 只看某个单元的接口信息 vdir -lib work -type entity | head -20vdir输出为空基本就三种原因分析阶段其实失败了去看vlogan.log、-work指定的库名和 setup 里对不上、或者 setup 文件根本没被读到。按这个顺序查比盲改参数快得多。4. 编译与细化vlogan、vhdlan 到 vcs 的参数怎么取舍环境搭好、库建好接下来是每天都要敲的那几条命令。这里我把三段式的完整链路写一遍参数按「必给」和「看情况给」分开说能直接抄。4.1 分析阶段vlogan 的必给参数vlogan -full64 -sverilog -ntb_opts uvm-1.2 \ -timescale1ns/1ps \ -work rtl_lib \ incdir./rtl/include./tb/include \ -f rtl.f \ -l vlogan_rtl.log逐条说明-full64走 64 位模式大设计必须加不加会在内存到 4G 附近直接崩。-sverilog打开 SystemVerilog 支持。工程里用了logic、always_ff、interface这些不加这个参数会报一堆莫名其妙的语法错。-ntb_opts uvm-1.2使用工具自带的 UVM 库。这里有个选择自己下载一份 UVM 源码加进文件列表还是用自带的。我一般用自带的因为自带版本和工具的补丁是配套的自己那份很容易在 phase 执行顺序上和工具打架报出来的错还特别难定位。要用 UVM 1.1d 就把参数改成uvm-1.1d。-timescale1ns/1ps统一时间单位与精度。这条一定要在分析阶段给而不是只在细化阶段给否则每个文件的精度按各自\timescale 走混合精度仿真的结果会和你预期差一个数量级。全工程统一是省事做法代价是某些 IP 内部需要更细精度时得单独处理。-work rtl_lib指定分析进哪个库必须和 setup 文件里定义的库名完全一致大小写敏感。incdirab是 include 搜索路径多个用连起来不要重复写多个incdir虽然也能识别但可读性差。路径里带或者空格的目录趁早改掉工具解析会出问题。-f rtl.f从文件列表读源码。rtl.f里一行一个相对路径支持-v指定库文件、-y指定库目录配libext.v自动搜索。文件列表建议按「包 → 接口 → 模块 → 顶层」顺序排VCS 虽然会做依赖分析但顺序写对了能少很多 iteration。-l vlogan_rtl.log把日志落盘。不加这个参数输出只在终端作业跑完日志就没了出问题想查都查不到。如果后面要接波形调试工具再加-kdb -lca作用是生成知识库否则细化阶段开了-debug_access也看不到某些信号。VHDL 侧对应的是vhdlan -full64 -work rtl_lib \ -time 1ns/1ps \ -f vhdl.f \ -l vhdlan_rtl.log-time对应-timescale语义一样单位写法是单位/精度。4.2 细化阶段-debug_access 的取舍与 -debug_region分析完了第二步把所有库里的顶层组装成可执行文件vcs -full64 -sverilog -ntb_opts uvm-1.2 \ -timescale1ns/1ps \ -top tb_top \ -debug_accessall -debug_regioncell \ -cm linecondfsmtglbranch -cm_dir ./cov.vdb \ -Mupdate \ -o simv -l vcs_elab.log-top tb_top指定顶层模块名。多顶层时写多个-top或者用-top加配置文件。这个参数写错细化阶段会直接报找不到 top。-debug_accessall是调试能力总开关代价很大编译时间、内存占用、仿真速度三方面都会退化实测下来带全量 debug 的仿真比不带慢三到五倍。手册第 4 章给了分层做法all是全部打开pp是后处理级波形工具只能看、不能改值r是只读。日常回归推荐-debug_accesspp出了问题要交互调试时再单独编一版all的。-debug_regioncell配合-debug_access用把调试能力限制在某个范围里。设计里有大块第三方 IP 时特别有用把 IP 区排除掉能明显缩短编译时间。-cm linecondfsmtglbranch开覆盖率采集五个维度全开。-cm_dir ./cov.vdb指定数据库目录后面用urg -dir ./cov.vdb出报告。覆盖率开关只在细化阶段给运行时不用重复给重复给也不报错但没有任何意义。-Mupdate增量编译。第二次细化时只重编发生变化的模块大设计上能把十几分钟压到两三分钟。第一次编译没区别。-o simv指定输出可执行文件名。多人协作时建议带上场景名比如-o simv_smoke、-o simv_regress不然大家都是simv前后跑两个 case 互相覆盖波形对不上。-lca是打开一些「限量可用」特性的开关-kdb、部分-debug_access组合都需要它。加错不会报错只是某些特性静默失效所以建议固定写进脚本里。4.3 运行阶段simv 的常用参数与随机种子./simv ntb_random_seed20210901 \ vcsinitregrandom \ vcslicwait \ -cm linecondfsmtglbranch \ -cm_name smoke_0 \ -l sim_0.logntb_random_seed固定随机种子。验证中最重要的参数之一复现问题必须把种子记下来日志开头那行 seed 值要抄进缺陷单里不然这个 case 再也跑不回同一个状态。vcsinitregrandom让寄存器随机初始化要全零初始化就写vcsinitreg0。默认情况下寄存器是 X 态X 会在逻辑里传播很多「仿真结果全 X」的问题根源就在这。跑正常回归用 random做寄存器复位验证时用 0两种模式各跑一遍能覆盖不少遗漏。vcslicwait前面提过批处理必加。-cm_name给这次运行的覆盖率数据打标签同一个目录下多 case 数据不会互相覆盖。回归脚本里用case_$i这种命名最后urg -dir ./cov.vdb -format both合并出一份报告。交互调试模式用./simv -ucli或者加-gui但交互模式只能人工手敲回归必须走批处理。5. 避坑记录VCS 环境里最常见的五类翻车5.1 现象细化阶段报模块找不到但分析日志明明是 success原因-work指定的库名和 setup 文件里的库名对不上或者 setup 文件根本没被读到读的是 home 目录里那份旧的。还有一种情况是相对路径陷阱——在sim/子目录下执行细化相对路径解析到了另一个目录。解决先echo $SYNOPSYS_SIM_SETUP确认读到哪个文件再vdir -lib rtl_lib确认库里有东西最后核对-work参数拼写。三分钟查完比反复重编快多了。5.2 现象simv启动瞬间报无法 checkout licenselmstat显示还有空闲原因运行时的 license 变量在作业脚本里没生效或者LM_LICENSE_FILE指向的是另一台服务器。批处理环境不继承登录 shell 变量是常态。解决在作业脚本开头显式source /opt/eda/env/vcs.sh然后在同一脚本内跑一次lmstat -a -c $LM_LICENSE_FILE把输出打进日志。以后翻日志能直接看到当时 license 服务是否可达。5.3 现象编译到一半报No space left on device原因csrc目录和/tmp被打满。带-debug_accessall时中间文件体积会翻好几倍一个中等设计几十 GB 很常见。解决把-Mdir指到大容量盘定期清csrc目录下的历史残留/tmp空间小的机器用TMPDIR环境变量重定向到数据盘。回归脚本里加一个磁盘水位检查超过 85% 就先告警再跑。5.4 现象同一份代码在老机器上跑得好好的新机器上结果全 X原因-timescale只在细化阶段给了分析阶段没给各文件按各自的\timescale 精度走采样时刻错位。解决-timescale在vlogan、vhdlan、vcs三个阶段都显式给同一个值。这个参数写三遍看起来啰嗦但它是这类玄学问题的唯一根治办法。5.5 现象带 debug 编译一次要四十分钟回归根本跑不动原因-debug_accessall全量开启编译期和仿真期都在为「可能要用到」的调试能力付代价。解决日常回归用-debug_accesspp -debug_regioncell只在需要交互调试时单独编一版all。另外开-Mupdate改一个文件只重编那一个。这两条加起来迭代速度能差出五到十倍。6. 跑通验证用一个十六行的小设计确认整套环境可用环境装完别急着上真设计。先用一个最小可跑通的设计把链路走一遍出问题也好定位。准备两个文件// counter.v —— 4 位计数器带异步复位 module counter(input clk, input rst_n, output reg [3:0] q); always (posedge clk or negedge rst_n) if (!rst_n) q 4d0; else q q 4d1; endmodule // tb.v —— 只做一件事复位后跑 20 个周期并打印 module tb; reg clk 0, rst_n 0; wire [3:0] q; counter u_dut(.clk(clk), .rst_n(rst_n), .q(q)); always #5 clk ~clk; initial begin #20 rst_n 1; #200; $display([CHECK] q%0d at %0t, q, $time); $finish; end endmodule三步走完vlogan -full64 -sverilog -timescale1ns/1ps -work work counter.v tb.v -l a.log vcs -full64 -sverilog -timescale1ns/1ps -top tb -debug_accesspp -o simv -l e.log ./simv ntb_random_seed1 vcslicwait -l s.log判断标准我一般看四条缺一条就说明环境有问题检查点期望结果异常时的方向s.log尾部出现仿真时间和$finish提示没跑起来查 license 和可执行文件[CHECK]打印时间 220nsq 为 4 位以内的值时间不对查 timescalevdir -lib work列出tb和counter两个单元查-work与 setupsimv目录生成simv可执行文件查细化日志前几行最容易被跳过的是第二条。很多人看到[CHECK] q3就觉得通了其实$time打出 220000000 才是 timescale 没生效的信号到真设计上会表现成采样时刻整体偏移。所以自检时要把时间也打出来别只打数据。提示把这四步写成一个smoke.sh每次升级工具版本或换机器都先跑一遍。五分钟的投入能挡掉后面大部分「到底是环境问题还是设计问题」的争论。从那以后我每次搭完环境都会先跑这个十六行的小设计$display里的时间戳必须和预期一致才继续往下走。工具版本升级、机器迁移、环境变量被人改过这三件事发生的频率远比想象中高而它们表现出来的现象惊人地相似。希望这套流程能帮到你少在环境上耗几个晚上。本文还有配套的精品资源点击获取