ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux下VCS与Synopsys AXI VIP环境搭建实战与避坑指南

Linux下VCS与Synopsys AXI VIP环境搭建实战与避坑指南 刚拿到VCS 2022.06和Synopsys AXI VIP 2020.12的时候我以为安装就是解压、export环境变量、跑一个example三步搞定。真正动手之后才发现这套组合的坑比想象中多GCC版本、license feature、synopsys_sim.setup映射、UVM版本选择、transaction打印刷屏任何一个环节没对上编译或运行阶段都会用各种方式告诉你不行。这篇就把我从零开始搭环境、首次仿真的完整过程以及踩过之后觉得值得写下来的避坑经验整理出来给需要在Linux下配置这套AXI VIP验证环境的同学当参考。1. 装之前先想清楚版本搭配、License与GCC这三大前置条件1.1 版本兼容性为什么2020.12的VIP能配2022.06的VCS很多第一次接触Synopsys VIP的人会纠结一个问题VCS版本比VIP版本新会不会不兼容这个担心可以理解但需要看本质。Synopsys的VIP和VCS虽然出自同一家但版本号并不是严格一一对应的。VIP 2020.12的release notes里通常会写清楚它支持哪些VCS版本区间通常是一个范围比如2019.06到2022.06都在支持列表内。VCS 2022.06反而比某些老版本更适合因为它对UVM 1.2、SystemVerilog语法和DPI-C的支持更完整。我的建议是在安装之前先去VIP包的doc目录下找release_notes或readme文件搜索VCS关键词确认自己的VCS版本在Supported Tool列表里。这一步别省我见过有人拿着VIP 2021.x去配VCS 2017结果编译报出大量UVM宏不识别折腾两天最后发现是版本跨度太大VIP里的部分代码用了新语法老VCS根本解析不了。另外VCS 2022.06自带的UVM库是自带集成的通常不需要额外下载UVM源码包。VIP包里的UVM环境会默认依赖VCS安装目录下的$VCS_HOME/etc/uvm所以首次安装一定要把VCS_HOME这个变量指对。如果指错后续大量报错都会围绕UVM library not found展开处理起来非常浪费时间。1.2 License要确认的Feature不要等到编译才去查License问题是我个人认为最容易被忽略、但炸起来最痛的一环。VCS本身能启动不代表AXI VIP也能用。VCS的license和VIP的license通常是两个独立授权VIP的feature一般跟着你买的VIP包走。如果你只确认了VCS能跑没确认VIP feature编译阶段可能会通过但仿真一开始VIP就会报license checkout失败甚至直接挂起。建议在装之前就手动执行一次license检查。假设license server是27001license_server命令是lmstat -a -c 27001license_server | grep -i axi或者用lmdiag去查具体feature是否能被当前机器checkout。注意这里的feature名以你拿到的正式授权为准不同合同和不同VIP类型会有差异不要拿网上的截图硬套。如果出现license checkin异常或者No such feature exists先别碰编译选项直接联系负责license的同事核对授权这比在VCS命令行里折腾半天有效得多。还有一个细节VCS 2022.06对license的环境变量有两类常见写法LM_LICENSE_FILE和SNPSLMD_LICENSE_FILESynopsys系列工具通常两个都会去读。我在bash里习惯两个都设置同一个值省得某些子工具只认其中一个时出幺蛾子。Synopsys SNPSLMD_LICENSE_FILE如果被其他工具污染也会导致feature识别异常。1.3 GCC、Perl与tcl/tk最容易低估的系统依赖VCS 2022.06在编译SystemVerilog和UVM代码时后台会调用GCC来生成C相关的仿真可执行文件所以GCC版本必须落在VCS支持的范围内。检查方法很简单vcs -print_gcc_version这条命令会打印VCS当前识别到的GCC版本信息。如果你的系统默认GCC是11或12这种比较新的版本而VCS支持的是7或8编译时大概率会出现类似cstdio: No such file or directory、bits/cconfig.h not found之类的报错。这时不要硬扛老老实实装一个受支持的GCC然后通过环境变量指给VCSexport VCS_GCC/usr/bin/gcc-7 export VCS_G/usr/bin/g-7再重新执行vcs -print_gcc_version确认。这一步在较新的Ubuntu或CentOS Stream系统上尤其容易踩我这边第一次就是默认GCC 12导致VIP的DPI-C编译一直失败换成GCC 7之后一次通过。另外VIP包里的部分脚本、以及VCS的波形/覆盖率相关工具是依赖Perl和tcl/tk的。建议装之前顺手检查perl -v tclsh puts [info patchlevel]如果缺tclsh后面VCS自带的一些GUI工具或VIP脚本的交互步骤会直接报错错误信息还不一定直接告诉你缺了tcl往往表现为脚本跑到一半No such command。所以这些系统依赖最好在解压VIP包之前就配齐。2. VIP目录不是解压完就结束环境变量与synopsys_sim.setup还得对上2.1 解压后的VIP包里到底有什么Synopsys AXI VIP的解压目录结构不同小版本会有些差异但大体上围绕几个部分组织。我这边解压后看到的是这样的axi_vip_2020.12/ ├── bin/ ├── doc/ ├── examples/ ├── lib/ ├── scripts/ └── src/ └── svt/ └── axi/src/svt/axi是AXI VIP的核心SystemVerilog源码里面能看到svt_axi_pkg.sv、svt_axi_master.sv、svt_axi_slave.sv这类文件这是整个VIP的真正主体。lib里可能放着预编译好的库文件不同安装方式内容不一样。scripts目录下有VIP官方提供的编译脚本一般以.f或.tcl结尾。examples目录则是价值最高的参考资料里面有AXI master、AXI slave、AXI monitor相关的测试用例工程后面首次仿真基本从这里起步。不要一见目录就直接去翻源代码先看doc目录里的release note和用户指南。特别是AXI_VIP_User_Guide.pdf这类文档版本兼容性、环境变量要求、编译选项说明全在里面。网上很多教程会直接给你一套命令但不同版本之间就是有差异文档才是最权威的。2.2 环境变量设置顺序和值都有讲究我最终使用的环境变量大概是这样一组在bash下放在~/.bashrc或当前工程的env.sh里都行关键是每次打开终端source一次export VCS_HOME/tools/synopsys/vcs-2022.06 export AXI_VIP_HOME/tools/synopsys/axi_vip_2020.12 export UVM_HOME$VCS_HOME/etc/uvm export VERDI_HOME/tools/synopsys/verdi-2022.06 export SNPSLMD_LICENSE_FILE27001license_server export LM_LICENSE_FILE27001license_server export PATH$VCS_HOME/bin:$AXI_VIP_HOME/bin:$VERDI_HOME/bin:$PATH这里有个容易犯的错是把UVM_HOME指向$AXI_VIP_HOME下面的某个uvm目录。不要这么做。VIP在绝大多数情况下希望使用VCS自带的UVM库你强行给它换一个UVM路径编译时会同时出现两套UVM类定义轻则warning重则直接UVM类型冲突。还有一点PATH里VCS_HOME/bin必须在系统自带vcs的路径之前否则which vcs可能指向一个旧版本。安装完成后可以用这三条命令做快速自检which vcs vcs -ID | head -5 ls $AXI_VIP_HOME/examples如果vcs能打印版本、examples目录能看到内容说明前两步环境基本对上了再往下走就有意义。2.3 synopsys_sim.setup映射关系搞错会输得莫名其妙VCS编译工程时逻辑库的查找依赖synopsys_sim.setup文件。这个文件可以放在当前工作目录也可以放在HOME目录但当前工作目录的优先级更高。很多首次用VIP的人不知道它的存在结果遇到类似Cant find logical library WORK或者Unable to open ...的报错时完全摸不着头脑。我这边工程根目录下的synopsys_sim.setup长这样WORK : ./work DEFAULT : $VCS_HOME/etc/uvm AXI_VIP : $AXI_VIP_HOME/src/svt/axi解释一下这三行的含义。WORK是VCS编译中间产物和运行文件的默认逻辑库DEFAULT是兜底库找不到其他映射时就到这里找AXI_VIP是把VIP源码目录映射成一个逻辑库名。实际编译时你的filelist里如果直接写相对路径可能不需要AXI_VIP映射但如果VIP的源码里通过include或import引用了逻辑库名就必须有这个映射。这个文件的坑在于路径里的环境变量能不能展开取决于VCS启动时是否继承了对应环境变量。如果你在一个新终端里没source环境变量就直接vcs那么这个文件里的$AXI_VIP_HOME会展开成一个空串结果等于路径不存在。我建议在编译脚本第一行强制source ~/.bashrc或者直接在synopsys_sim.setup里写绝对路径避免这种低级问题。3. 编译报错别急着怀疑人生从VCS命令行反推问题根因3.1 最简可运行的VCS编译命令模板VIP包里通常自带编译脚本但为了理解每一步在做什么我还是建议先手动敲一遍最小命令。以我跑通的AXI master/slave加DUT的testbench为例命令大概是这个形态cd $AXI_VIP_HOME/examples/axi_basic vcs -sverilog -full64 -ntb_opts uvm-1.2 \ -timescale1ns/1ps \ -assert enable_diag \ -debug_accessall \ -f filelist.f \ -top tb_top \ -o simv \ -l compile.log逐个说下几个关键选项。-sverilog开启SystemVerilog支持这个不加基本寸步难行。-ntb_opts uvm-1.2让VCS使用自带的UVM 1.2库VIP 2020.12对UVM 1.2的支持比较成熟不要在这里改成UVM 1.1或UVM 2.0版会碰到一串兼容性问题。-timescale1ns/1ps统一整个工程的时间精度VIP内部和DUT的时序模型如果精度不同仿真结果会出现莫名其妙的时间采样偏移。-debug_accessall保证后续可以用Verdi看信号、用UVM debug工具做调试少加了后面想补还得重新编译。-f filelist.f把工程里所有源文件按列表一次性读进来比手写几百个文件路径靠谱得多。如果VIP包提供的是Makefile你可以先用make看它实际执行的vcs命令。这样做的好处是官方脚本里的编译选项是经过验证的你至少能知道这个版本VIP推荐哪些flag。把这些flag抄下来再逐步精简成自己的模板比从零摸索快很多。3.2 三个高频报错和它们的真正根因编译阶段我遇到过的高频报错基本能归成三类这里整理成一个对照表报错关键词表面现象真正根因Error-[UVMS]/Cannot find UVM编译一开始就报UVM库缺失-ntb_opts uvm-1.2没加或UVM_HOME指错Cant open include file svt_axi_pkg.svinclude路径找不到VIP头文件AXI_VIP_HOME没设对或filelist里没引VIP sourceError-[DPI-C] shared library load failed编译通过运行simv时报.so加载失败LD_LIBRARY_PATH缺VCS或VIP的lib路径先说第一类。VIP环境里UVM库是基础设施如果你编译时发现一堆uvm_*类未定义优先查vcs命令后面到底有没有-ntb_opts uvm-1.2。很多教程截图里没有这个选项是因为他们把defineUVM_NO_DPI这种宏直接写进了filelist用宏绕过了UVM的DPI部分。这种做法可以让编译通过但会牺牲UVM的很多打印和report机制不建议上来就绕过。第二类更常见。VIP源码文件非常多通常filelist里会通过相对AXI_VIP_HOME的路径引用比如$AXI_VIP_HOME/src/svt/axi/svt_axi_pkg.sv。如果你的终端里AXI_VIP_HOME没导出VCS拿到的是空路径结果自然是找不到文件。建议在编译脚本最前面加一段检查if [ -z $AXI_VIP_HOME ]; then echo AXI_VIP_HOME is not set exit 1 fi养成这个习惯后环境变量问题会在第一时间暴露而不是以奇怪的include错误形式出现。第三类DPI-C报错比较阴。它通常不是编译阶段暴露而是在你运行./simv时突然报类似error while loading shared libraries: libvcsuvm.so。这是VCS的UVM DPI库路径不在系统动态库搜索路径里。解决方式是把这个路径加进去export LD_LIBRARY_PATH$VCS_HOME/linux64/lib:$VCS_HOME/lib:$LD_LIBRARY_PATH如果VIP还有自己的DPI库同理把$AXI_VIP_HOME/lib也加进去。这步不处理好哪怕编译全绿仿真也起不来。3.3 例子工程不是拿来抄的是拿来对照的跑通example之前先把examples目录下的工程结构看一遍重点关注三个文件filelist.f、tb_top.sv、test.sv。filelist.f告诉你官方是怎么组织编译顺序的tb_top.sv告诉你怎么实例化VIP组件test.sv告诉你最简testcase长什么样。我第一次排错时犯过一个低级错误把example里的文件全部拷贝到自己的目录但忘了拷run.f里指向的VIP相对路径依赖结果一编译全是找不到VIP文件。后来学乖了先老老实实在原目录make example确认能跑通之后再拷贝出来改。这个顺序非常重要它能把我的改动引入的问题和环境本身的问题彻底分开。还有一点example工程里通常有多个testcase比如axi_master_test、axi_slave_test分别针对Master VIP和Slave VIP。第一次跑建议直接跑package自带的默认test不要上来就改参数。默认test要能通过你才可以判断整个VIP安装是健康的如果默认test都挂那问题大概率出在环境配置而不是你的DUT逻辑。4. 跑通第一条AXI事务安装成功的真正标准4.1 example testcase里最容易忽略的配置项很多人的安装步骤走到编译完成就停下来了觉得能编过就是装好了。这是误解。AXI VIP装没装好至少要看到一条AXI读或写事务在VIP和DUT之间正常传输。example里跑的第一步通常是用Master VIP发起一笔写操作Slave VIP接收中间接一个最简的DUT。在这个阶段最容易被忽略的是svt_axi_configuration的配置。这个configuration对象控制着AXI协议版本、数据宽度、outstanding能力、使能哪些信号等关键参数。如果你不配置VIP会使用默认值默认值有时候和你的DUT接口对不上比如DUT只支持AXI4-LiteVIP默认却跑了AXI4 full协议那么仿真里会出现一堆协议违例报错。我常用的最小配置类似这样放在test class的build_phase里svt_axi_configuration cfg; function void build_phase(uvm_phase phase); super.build_phase(phase); cfg svt_axi_configuration::type_id::create(cfg); cfg.axi_protocol_type svt_axi_configuration::AXI4_LITE; cfg.data_width 32; cfg.addr_width 32; uvm_config_db#(svt_axi_configuration)::set(this, *.env.master_agent*, cfg, cfg); endfunction这里层路径*.env.master_agent*要和你example里的agent实例名一致不是所有工程都叫这个名字。如果路径对不上config_db设置静默失效VIP还是会用默认配置这类问题很难查因为它不报错只是行为不符合预期。4.2 transaction打印爆屏的关闭方法首次仿真跑起来之后你大概率会发现终端被transaction打印刷爆了。每个AXI读请求、写请求、响应都会打印一大段transaction信息仿真速度肉眼可见变慢。这是Synopsys VIP默认verbose level偏高的结果不是故障。想关掉最粗暴的方法是运行时把UVM verbosity调低./simv UVM_TESTNAMEaxi_basic_test UVM_VERBOSITYUVM_NONE -l run.log但这样做会把UVM的report信息也一起干掉连错误信息都可能被过滤。我更推荐找VIP自己的print控制。在Synopsys的AXI VIP里transaction打印通常由configuration里的report_verbosity或对应开关控制你可以在VIP源码里搜report_verbosity、transaction_reporting、print_transaction这些关键词看看当前这个版本具体支持哪个队列。我本地2020.12版本里是在test的connect_phase里对agent调svt_axi_master_agent master_agent; master_agent.set_report_verbosity_level(UVM_NONE);这相当于只关掉这个agent的详细打印UVM全局的error/warning还是正常显示。注意不同小版本接口可能有变化所以最稳妥的做法还是以VIP源码里的实际接口为准。我见过有人用很高版本的某篇博客里的关闭方式结果在2020.12上报compile error因为方法名和参数都不一样了。4.3 看波形才知道AXI握手到底有没有发生跑完testcase控制台打印UVM_ERROR Count: 0并不能完全证明AXI事务真的成功了。我自己的判断标准是打开波形看到AXI四个通道的握手信号确实按照协议拉起来读数据通道上出现了预期数据。这样才算数。用VCS跑仿真时如果编译阶段加了-debug_accessall就可以在testbench里直接dump FSDB波形。通常是在tb_top里加initial begin $fsdbDumpfile(test.fsdb); $fsdbDumpvars(0, tb_top, all); end如果编译时没加-debug_accessall这里会报类似$fsdbDumpvars not found的错误或者生成空的fsdb文件。所以我前面强调编译选项时把debug_access放在很前面就是这个原因。波形生成后用Verdi打开verdi -sv -f filelist.f -top tb_top -ssf test.fsdb 重点看几个信号AW通道的awvalid和awready是否同时拉高过一个周期W通道的wvalid/wready是否全部拍都对上B通道的bvalid/bready有没有回来R通道的rvalid/rready和返回的rdata是不是期望值。如果只是控制台打印pass但波形里握手从来没发生过很可能是VIP配置的协议类型和DUT接口对不上或者连接根本没接对。这类问题脱离波形几乎没法定位。5. 覆盖率收集与Verdi联仿让安装结果直接服务验证效率5.1 VCS覆盖率收集与merge最小配置AXI VIP装好之后如果不做覆盖率收集它的价值其实只发挥了一半。Synopsys VIP内部一般自带了不少功能覆盖率点和协议覆盖率模型但你需要用VCS的覆盖率收集功能把这些covergroup宏编译进去并在仿真时打开收集开关。编译阶段需要加-cm选项例如vcs -sverilog -full64 -ntb_opts uvm-1.2 \ -cm linecondfsmtgl \ -debug_accessall \ -f filelist.f \ -top tb_top -o simv \ -l compile.log运行阶段也要配上-cm./simv UVM_TESTNAMEaxi_basic_test \ -cm linecondfsmtgl \ -cm_name axi_basic \ -l run.log仿真结束后会生成simv.vdb目录。收集多个用例时每个用例用不同的-cm_name最后统一merge。merge命令很直接urg -dir simv.vdb/axi_basic \ -dir simv.vdb/axi_read \ -dir simv.vdb/axi_write \ -format text -report cover_report打开cover_report目录下的摘要文件重点关注AXI VIP自带的covergroup覆盖率。如果协议覆盖率偏低说明当前激励连基本的outstanding、interleaving、burst长度变化都没测到需要回到sequence层面加测试。覆盖率这步真正价值是帮你判断VIP用到位了没有。5.2 VCS与Verdi联仿的设置最后说一下VCS和Verdi联仿。很多团队习惯用VCS跑仿真、Verdi看波形和debug这套组合的配置其实不复杂只要三件事做对环境变量、编译选项、dump函数。环境变量方面Verdi的bin路径要加进PATH同时动态库路径要能找到Verdi的PLI库。常见设置export VERDI_HOME/tools/synopsys/verdi-2022.06 export PATH$VERDI_HOME/bin:$PATH export LD_LIBRARY_PATH$VERDI_HOME/share/PLI/VCS/LINUX64:$LD_LIBRARY_PATHVerdi版本太老的话可能不支持VCS 2022.06生成的调试数据结构打开波形时会提示版本不匹配。这种情况下优先看Verdi的release note里对VCS版本的兼容范围如果确实不匹配只能升级Verdi或换VCS版本。这里又回到了开头说的版本兼容性自查提前做好能省很多事。编译时只要保证-debug_accessall和-debug_region之类的选项正确仿真时在tb里调用$fsdbDumpvars生成波形最后用Verdi打开即可。联仿调通后整个环境就算真正可用了VCS负责快速仿真VIP负责AXI协议建模和覆盖率收集Verdi负责问题定位三者串起来就是一套能直接支撑日常验证工作的闭环。最后再分享一个我自己的习惯整套环境跑通之后新建AXI验证工程时永远从examples目录拷贝一份最简环境来改而不是从零写编译脚本和testbench。因为VIP版本一旦更新编译选项、DPI库路径、UVM兼容性都可能变化自己手写脚本不去对照官方example迟早会被版本差异教训一顿。把example作为起点根据自己的DUT接口去改配置和连接这条路走顺了AXI VIP才算真正在你手上落地。
返回列表