最近在Ubuntu 20.04上装VCS2018,原本以为就是个解压、配环境变量的事,结果前前后后折腾了两天才把所有链路打通:系统依赖、编译器版本、license配置、图形界面显示、输入法干扰,每一样都能让仿真跑不起来。这篇就把我的完整安装过程、踩过的坑和最终验证方法整理出来,给准备在这套系统上搭数字仿真环境的人做个参考。
这篇文章适合三类人看:刚接触数字IC验证、准备在个人电脑上装VCS的在校学生;公司分配了新工作站、需要从零搭建EDA环境的工程师;以及已经在Ubuntu 20.04上装了但跑不通、正在到处搜报错的老哥。内容覆盖从依赖安装、目录规划、环境变量配置到Verdi图形栈调优的全过程。
1. 安装前先把系统和依赖盘清楚:VCS2018挑库不挑运气
VCS2018这个版本发布的时候,主流的发行版还是Ubuntu 16.04/18.04。拿到Ubuntu 20.04上装,最大的问题不是软件本身,而是新版系统带的GCC版本和运行库跟它不匹配。很多人一上来就急着解压安装包,结果编译testbench的时候报一堆莫名其妙的错误,然后开始怀疑安装包坏了,其实根子都在系统环境上。
1.1 先确认系统位数和GCC版本上限
VCS2018官方支持的是64位系统,这一点新机器基本都没问题,重点在GCC版本。VCS在编译仿真模型的时候,会调用系统中的GCC来生成本地可执行文件,它对GCC版本有严格检查,版本太新就直接报错停掉。
Ubuntu 20.04默认装的是GCC 9,VCS2018显然认不了这么新的版本,所以安装前要准备好一个较老的GCC。我实际用的是GCC 7,通过update-alternatives在系统里做版本切换,实测VCS 2018编译仿真完全没问题。更老一点的版本也可以,但没必要刻意追求最低版本,GCC 7在20.04上正好能通过apt直接装,省去手动编译的麻烦。
注意:安装前先在终端执行
gcc --version看当前版本,如果已经是9.x,不要卸载它,系统里很多工具链依赖这个版本,用update-alternatives做多版本共存才是正路。
1.2 缺的库一次性补齐,别用“缺啥装啥”的笨办法
VCS和Verdi依赖的库文件比较杂,包括ncurses、X11图形库、字体库等。Ubuntu 20.04相比16.04砍掉了不少32位兼容库和旧版图形库,所以安装前最好一次性把依赖补齐,省得后面反复折腾。
我整理了一份实际用到的安装命令,可以直接复制执行:
sudo apt update sudo apt install -y build-essential gcc-7 g++-7 sudo apt install -y libncurses5 libtinfo5 libpng-dev sudo apt install -y libx11-dev libxext-dev libxmu-dev libxt-dev libxi-dev sudo apt install -y libxaw7-dev libc6-dev libstdc++-7-dev sudo apt install -y xfonts-100dpi xfonts-75dpi fontconfig这里有几个细节说明一下。libncurses5和libtinfo5是VCS命令行交互界面必须的,Ubuntu 20.04默认只有libncurses6,如果缺了这两个,VCS启动时会直接说找不到共享库。libxmu、libxt这一组是Verdi图形界面依赖的X11开发库,少了它们Verdi能装上但启动时要么闪退要么报X11相关错误。xfonts-100dpi和xfonts-75dpi是字体包,Verdi界面的字体渲染异常通常就是因为没装这两个。
1.3 磁盘空间与运行权限:两个容易被忽略的前提
VCS2018完整解压后大约需要10GB左右空间,加上仿真项目里生成的中间文件,建议至少预留20GB。我见过同事在只剩3GB的磁盘上装VCS,解压到一半报"No space left on device",然后整个安装包目录是残缺的,后面怎么配都跑不起来。
另一个关键是安装目录的权限。VCS解压后里的bin目录下有大量可执行文件,如果是root安装、普通用户使用,建议把整个安装目录chown给对应用户:
sudo chown -R $USER:$USER /opt/synopsys不建议直接拿root账号跑VCS。由VCS调用的GCC在编译过程中会创建大量临时文件,root权限下产生的文件归属混乱,后面清理起来非常麻烦。
2. 解压摆放与环境变量:跑通命令行前的关键配置
系统依赖装好之后,接下来才是安装包本身的处理。VCS2018这种EDA工具的安装方式和普通软件不太一样,它没有图形化安装向导,本质上是把工具链解压到固定目录,然后通过环境变量告诉系统去哪里找可执行文件。
2.1 安装包的解压逻辑与目录规划
先规划好目录结构。我习惯把Synopsys全家桶统一放在一处,方便管理和统一配置:
mkdir -p /opt/synopsysVCS2018下载下来通常是一个.tar.gz文件,文件名的命名规则是vcs-mx_vO-2018.09-SP2-1.tar.gz之类的格式,其中O-2018.09-SP2就是版本号。解压后目录里会有一个顶层目录,例如vcs,里面才是真正的工具链。
解压命令没什么特别的:
tar -xzf vcs-mx_vO-2018.09-SP2.tar.gz -C /opt/synopsys解压完成后的目录结构大致是:
/opt/synopsys/vcs/ ├── bin/ ├── linux64/ ├── doc/ ├── etc/ └── ...bin目录放着vcs、vcsDVE、vcs_shell等可执行文件,linux64里是64位编译环境所需的库和可执行体。这里要特别提醒,VCS有32位和64位两套编译体系,在Ubuntu 20.04上只用64位就够了,所有命令都要加上-full64参数,后面会细说。
2.2 VCS_HOME、PATH、LM_LICENSE_FILE到底怎么配
环境变量是VCS正常工作的核心。VCS需要三个关键变量:VCS_HOME告诉系统工具安装在哪个目录,PATH让shell能找到vcs命令,LM_LICENSE_FILE指定许可证服务器。配置写入~/.bashrc文件末尾:
export VCS_HOME=/opt/synopsys/vcs export PATH=$VCS_HOME/bin:$PATH export LM_LICENSE_FILE=27020@license-server-ipLM_LICENSE_FILE的格式是端口@服务器地址。这里的前提是你手上已经有一份合法的VCS授权信息,通常是公司内部搭建的license服务器,拿到IP和端口后填进来就行。如果这个变量配置错误或者根本就是空的,VCS的编译命令会在最早期直接报license相关错误,连testbench都会在编译阶段被掐断。
提醒:如果之前装过其他EDA工具,
LM_LICENSE_FILE可能已经有值。多个license服务器之间用英文冒号分隔,不要覆盖掉原来的配置,否则其他工具会连不上许可证。
配置完执行source ~/.bashrc让它生效,然后在终端输入which vcs,如果能显示/opt/synopsys/vcs/bin/vcs,说明基本配置已经就位。
2.3 多版本GCC共存时的链接处理
前面提到要装GCC 7,但系统默认的GCC 9还在,必须通过update-alternatives让终端使用的GCC切到7。这一步很简单但很关键:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 50 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 50 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 40 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 40切换的时候执行:
sudo update-alternatives --config gcc sudo update-alternatives --config g++光标选择gcc-7那一项即可。切换完再用gcc --version确认当前已经是7.x。
这里有个坑我一开始没意识到:VCS虽然调用系统的GCC做编译,但它内部还会带着自己的编译器前端(比如专门处理SystemVerilog的VCS原生编译器),系统GCC只是用于把生成的C代码编成可执行文件。所以造成的情况是:VCS本身的SystemVerilog语法解析和GCC版本无关,但最终生成simv可执行文件那一步由GCC完成,GCC版本太新会导致链接阶段的ABI不兼容或者代码生成器崩溃。
3. 用最小仿真验证安装:版本号不能说明一切
环境变量配好、依赖库装齐之后,还不能急着往项目里灌代码。先用一个最小示例把整条链路验证一遍,确定编译、仿真、波形导出都没问题,再投入到实际项目中。
3.1 用一条命令做烟雾测试
最简单的检查就是看版本号:
vcs -ID这个命令会打印VCS的详细版本信息和编译参数。如果这里能正常输出版本信息,说明VCS主程序、动态库依赖已经全部满足。如果在这里就报类似error while loading shared libraries,说明还是缺依赖库,回头检查第1.2节的内容。
同时可以验证一下Verdi:
verdi -versionVerdi的路径和VCS通常不在同一个目录,需要单独把它的bin目录加进PATH。这里要留意,如果环境变量里Verdi的VERDI_HOME没指向正确路径,verdi -version可能还是能打印出版本号,但启动GUI时会白屏,原因在于Verdi运行时除了bin目录还要用到安装目录下的share和platform目录,路径不完整就会界面异常。
3.2 最小testbench怎么写最省事
验证安装的testbench不需要多复杂,功能太简单反而看不出问题,功能太复杂又会混淆代码问题与环境问题。我建议用一个小计数器加上fsdb波形导出的完整结构:
// top.v module top(input wire clk, input wire rst_n, output reg [3:0] cnt); always @(posedge clk or negedge rst_n) begin if (!rst_n) cnt <= 4'b0; else cnt <= cnt + 1'b1; end endmodule// tb_top.v module tb_top; reg clk; reg rst_n; wire [3:0] cnt; top u_top( .clk(clk), .rst_n(rst_n), .cnt(cnt) ); initial begin clk = 0; forever #5 clk = ~clk; end initial begin rst_n = 0; #20; rst_n = 1; end initial begin $fsdbDumpfile("wave.fsdb"); $fsdbDumpvars(0, tb_top); #200; $finish; end endmodule这个testbench结构很典型:一个时钟源、一个复位信号、一个被测模块,再加一段fsdb波形导出代码。功能虽小,可覆盖的验证点很全,能确认VCS能编译门级模块和testbench代码,能正确执行仿真并正常推出,同时生成Verdi可打开的波形文件。
3.3 编译、仿真、波形导出的标准动作
把上面两个文件放在同一个目录,执行:
vcs -full64 -sverilog +v2k -debug_access+all -timescale=1ns/1ps -o simv top.v tb_top.v逐项拆解一下这些参数。-full64指定以64位模式编译,在Ubuntu 20.04上必须加,否则默认会尝试32位编译然后报错。-sverilog让编译器支持SystemVerilog语法特性。+v2k兼容老的Verilog 2000语法。-debug_access+all把仿真过程中的信号访问权限全部打开,这样后面Verdi里才能看到内部信号变化。-o simv指定编译产物名称,vcs默认生成的可执行文件就叫simv,显式写出来更直观。
编译成功后会生成simv文件,接着运行:
./simv仿真过程会打印类似Chronologic VCS simulator copyright 2018的开头信息,然后进入执行阶段,最后正常退出。因为testbench里有$finish,所以程序会自己结束,不会一直挂在那边。如果在仿真阶段断言或波形导出的系统函数没有编译进去,这里会直接报undefined reference,那就要回头看-debug_access+all有没有漏掉。
仿真结束后,目录里会出现wave.fsdb文件。用Verdi打开:
verdi -full64 -f filelist.f -ssf wave.fsdb &实际使用中通常会把源文件列表写进一个filelist.f文件里方便管理:
// filelist.f top.v tb_top.v-ssf参数指定波形文件路径。Verdi启动后能看到顶层模块结构,在Source窗口点开tb_top,选中u_top就能看到计数器的跳变波形,同时在Waveform窗口里添加信号观察。到这里,整条链路就算真正跑通了。
3.4 第一次跑通前最常见的三个报错
第一类报错是license相关,通常在vcs命令刚启动时就出现license或者feature字样。解决办法是先确认LM_LICENSE_FILE格式是否正确,以及license服务器地址能不能ping通。还要注意license用户数是否被占满,团队共用服务器时容易碰上这种问题。
第二类报错是GCC版本不匹配,表现是编译到一半突然冒出一大段GCC报错,里面经常会看到类似internal compiler error或者unsupported version的提示。这个问题几乎都是系统GCC版本过高引起,回到第2.3节用update-alternatives切到GCC 7,再重新编译就正常了。
第三类报错是找不到头文件或者标准库,比如cannot find crti.o: No such file or directory。这是典型的32位编译库缺失,确认编译命令里有-full64参数后基本不会再遇到。如果已经加了-full64还报这错,检查一下libc6-dev是否安装完整。
4. Verdi图形界面调优:显卡驱动与输入法框架的坑
命令行仿真是VCS的主干,但实际项目的调试效率很大程度上依赖Verdi这个图形界面。Verdi在Ubuntu 20.04上跑起来,图形栈相关的坑比VCS本身还多。标题里提到的NVIDIA 535驱动和搜狗输入法,这两样东西我都是在实际使用中踩过雷的。
4.1 NVIDIA 535驱动安装后Verdi为什么打不开
很多人在Ubuntu 20.04上装NVIDIA 535驱动,主要是为了跑深度学习或者3D渲染,装完后发现Verdi启动时直接闪退,或者报类似libGL error: unable to load driver: swrast_dri.so的错误。
这个问题的本质是NVIDIA驱动自带的OpenGL库和Verdi内部的Qt/OpenGL渲染模块之间存在兼容性摩擦。Verdi本身对显卡加速需求并不高,它只是用OpenGL做波形缩放和画布刷新,完全可以用软件渲染替代。
我用的解决办法是安装mesa软件渲染库:
sudo apt install -y libgl1-mesa-glx libgl1-mesa-dri libegl1然后启动Verdi前设置一个环境变量:
export LIBGL_ALWAYS_INDIRECT=1 verdi -full64 -ssf wave.fsdb &LIBGL_ALWAYS_INDIRECT=1强制OpenGL走间接渲染模式,让Verdi用软件渲染绘制波形画布。代价是超大波形的平移缩放会稍微慢一点,但对日常调试来说感知不强。如果你的机器主要用来做仿真验证而不跑3D应用,甚至可以直接把显卡驱动换成NVIDIA的开源驱动nouveau,Verdi的渲染稳定性反而更好。
4.2 搜狗输入法/输入法框架对Verdi的隐形干扰
搜狗输入法在Ubuntu 20.04上基于fcitx框架运行,这个框架会在X11层拦截键盘事件。Verdi作为老牌Qt界面程序,对XIM协议的处理比较老派,跟fcitx组合在一起容易出现两个诡异问题。
第一个问题是快捷键失灵。在Verdi里敲字母或数字很正常,但按Ctrl+加号缩放波形、按Ctrl+F查找信号时会发现没反应,甚至有时按回车会直接把源代码窗口里选中的一行替换掉。
第二个问题是光标漂移和位置错乱。在Verdi的波形窗口点击某个时间点,光标准线没有出现在鼠标点击的位置,偏移量还不固定,开始还以为是Qt版本问题,最后才定位到是fcitx输入框对鼠标事件的干扰。
解决办法很实用:启动Verdi前把输入法切到英文模式。
fcitx-remote -cfcitx-remote -c是关闭fcitx输入皮肤的指令,关闭后键盘事件直接透传给应用。在Verdi里正式开始调试时,切到英文输入状态后快捷键和光标都恢复正常了。如果不想每次动手切,可以在fcitx配置里把Verdi加进“按应用启用/禁用输入法”的白名单或黑名单,路径一般在~/.config/fcitx/profile,添加一行Verdi=Disabled即可自动规避。
4.3 远程开发时显示与字体问题的对策
实际工程中,VCS和Verdi往往跑在公司内部的Linux服务器上,本地通过X11转发打开GUI。这个场景下问题更明显。X11转发默认不支持OpenGL加速,Verdi启动后要么黑屏、要么波形区刷新慢得像幻灯片。
不折腾显卡的前提下有两条路可走。一条是在服务器上装Xvfb虚拟显示:
sudo apt install -y xvfb xvfb-run -a verdi -full64 -ssf wave.fsdb &这会起一个虚拟的X server,Verdi渲染完全不依赖本地显卡,速度比X11转发快很多,但代价是看不到界面,只能配合截图或者VNC远程桌面使用。
另一条更实用:直接用VNC或者NoMachine连到服务器桌面,在真实X session里运行Verdi。这种方式下Verdi的渲染走服务器本地显卡,远程传输走压缩流,稳定性比X11转发高一个量级。Verdi的字体显示也要注意,远程桌面下如果字体发虚或者出现方框,装一下xfonts-100dpi和xfonts-75dpi,然后清一下字体缓存:
sudo fc-cache -fv字体方面的另外一个坑是分辨率适配。Verdi的波形字体在1920x1080下默认偏小,长时间盯屏幕很累。改字体大小也不需要动系统设置,在Verdi里通过Tools -> Preferences -> Waveform调整字体号即可,改完立即生效,不用重启。
5. 日常使用里最值得记住的几个修复习惯
安装完成、仿真跑通只是第一步。VCS在Ubuntu 20.04上长期使用下来,还会遇到一些重复性的问题。这里分享几个我总结出的修复习惯,能省不少事。
5.1 环境变量配置坚持最小化原则
网上很多教程会推荐在~/.bashrc里堆一堆export,比如SNPSLMD_LICENSE_FILE、Verdi_HOME、PATH里加好几个路径。这种配置方式短期没问题,时间一长你就会发现,不同版本EDA工具的库路径互相污染,今天这个工具连不上license,明天那个工具加载了错误的动态库。
我的建议是只保留必要的三个核心变量:VCS_HOME、VCS_ARCH和LM_LICENSE_FILE,再加上Verdi的VERDI_HOME和对应的PATH路径。其他工具链相关的变量放进各自的启动脚本里,比如source /opt/scripts/questa.env这样,用哪个工具就source哪个环境,互不干扰。
排查环境变量问题时,最实用的命令是echo $LD_LIBRARY_PATH,逐条盯着看有没有路径指向了旧版本的库目录。很多诡异问题最后都出在LD_LIBRARY_PATH上,它比PATH更隐蔽,因为它影响的是动态加载阶段而不是命令查找阶段。
5.2 项目目录里的simv和中间文件定期清理
VCS编译一个中等规模的验证环境,生成的中间文件动不动就是几个GB起步。常见的有simv、simv.daidir、csrc、ucli.key和一堆.fsdb波形文件。新工程建目录的时候最好在顶层放一个clean.sh:
#!/bin/bash rm -rf simv simv.daidir csrc VC_LOG.* ucli.key rm -rf *.fsdb *.vpd *DVEfiles*每次跑完一轮回归,执行一下./clean.sh,既清理了磁盘,也避免了旧的编译缓存干扰新的编译。有一个细节:simv.daidir目录里放的是VCS编译生成的增量仿真数据,如果代码结构有大的改动,旧的增量数据可能导致编译时拼装出旧版本内容,编译行为变得不可预测。经常做全量清理,能减少这类玄学问题。
5.3 把本次安装记录固化成一个checklist
装完VCS的当周你可能还记得所有细节,一个月后重装或者给同事的新机器配置环境,又得从头开始查。我在安装文档里硬化了一份checklist,每次配置完按顺序打勾,出问题时就按序号倒查。
清单大致是这样的:
- 系统已更新到最新补丁,磁盘剩余空间大于20GB
- gcc/g++当前版本为7.x,通过update-alternatives切换并已确认
- libncurses5、libtinfo5、X11开发库已安装完毕
- VCS安装目录权限归属当前用户
VCS_HOME与PATH配置正确,which vcs有输出LM_LICENSE_FILE指向有效license服务器vcs -ID正常输出版本信息- 最小testbench完整走通编译、仿真、fsdb导出、Verdi打开四步
这套清单的价值在于,它把环境配置中的模糊地带全部变成可执行的验证动作,尤其适合负责维护团队EDA环境的工程师。新机器配置完成后,照着清单跑一遍就知道环境是不是真的可用,不用等同事开始跑项目时才发现缺库缺工具。
回到最开始说的,VCS2018在Ubuntu 20.04上安装这件事,技术难度并不高,难的是那些一环扣一环的环境依赖。只要把系统GCC版本控制好、库文件装齐、license配置正确、图形显示栈处理干净,这套环境跑起来是很稳定的。我这边装完之后,连续跑了几个模块的回归都没出过环境问题,希望这篇记录也能让你的安装过程顺利一点。