ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Vivado与ModelSim联合仿真配置实战:从编译库到波形调通全记录

Vivado与ModelSim联合仿真配置实战:从编译库到波形调通全记录 Vivado 2020.2和ModelSim 2020.4这对组合我前阵子刚配完中间踩了一堆坑从编译仿真库到最终把波形调出来前前后后折腾了一天。今天这篇我不打算写那种点几下鼠标就成功的爽文因为真实情况根本不是那样。我会按自己的实际操作顺序来写顺便把每个关键步骤为什么要这么做、做的时候容易在哪翻车都讲明白。这篇文章适合谁看如果你是第一次在Vivado工程里挂ModelSim做仿真或者已经被什么vsim-3033、Failed to access library、编译库报错砸过那这篇就是写给你的。Vivado自带的xsim不是不能用但很多老工程师还是习惯ModelSim的波形界面和do脚本尤其是看眼图、查时序、批量跑回归的时候ModelSim的工作流确实顺手。1. 为什么我坚持用ModelSim而不是xsim版本选型的底层逻辑1.1 xsim和ModelSim到底差在哪很多刚接触Vivado的同学会困惑Vivado不是自带了xsim仿真器吗为什么还要费劲去挂ModelSim答案其实很实际xsim在纯行为级仿真上够用但一旦遇到大型IP、复杂AXI总线的调试它的波形查看效率和命令行控制能力明显不如ModelSim顺手。ModelSim的do脚本可以让我把整个回归测试流程自动化几百个testbench跑完自动汇总结果这在xsim里做起来就没那么痛快了。ModelSim还有一个隐形优势团队协作。很多人手上的旧工程、旧testbench、旧脚本全是在ModelSim里写的直接切xsim意味着所有脚本重写风险太大。这也是不少公司明明可以用xsim却还是统一要求ModelSim的原因。1.2 官方支持列表里没有2020.4但为什么我偏要用它这里有个很关键的信息必须先说清楚Xilinx官方UG973文档里Vivado 2020.2对应的ModelSim支持版本是ModelSim SE-64 10.6b那一代2020.4并不在官方列表里。也就是说你在Vivado的compile_simlib编译仿真库的时候版本检测可能会给你弹个Warning甚至Error这是很多人第一步就卡住的地方。但我实测下来2020.4在Windows 10/11环境下和Vivado 2020.2配合行为级仿真是完全能跑的。前提是你要明白它为什么能被跑通ModelSim 2020.4的vsim核心和10.6b没有本质变化Xilinx的仿真库是由Verilog/VHDL源码编译出来的只要库编译成功vsim版本稍新一点读取这些库文件完全没问题。如果你用的ModelSim是Intel FPGA Starter Edition那个定制版情况就不一样了这个版本是Intel定制的Vivado的库编译工具经常不认它表现为executable路径不对或ModelSim版本不兼容。所以我建议用Siemens EDA官网的ModelSim SE/DE版本别用Intel定制版来配Vivado。1.3 版本适配速查组合官方支持实测可用性建议Vivado 2020.2 ModelSim SE 10.6b支持稳定求稳首选Vivado 2020.2 ModelSim 2020.4不在列表可跑通注意编译库报错可按本文方法操作Vivado 2020.2 ModelSim Intel Starter 2020.4不支持容易失败不要用Vivado 2020.2 Questa官方部分支持需要额外配置新手不建议所以我个人的建议是如果你只是想快点把仿真跑起来手头有官方支持列表里的ModelSim就用那个别折腾。但如果你已经装了2020.4也不需要卸载照着下面几步走是能用的。2. 安装配置之前必须做对的三件事路径、环境变量与License2.1 安装路径一个中文字符都不能有这个事我真的是用血泪教训验证过无数次。ModelSim的编译器和Vivado的仿真库脚本对路径里的中文、空格、特殊字符非常敏感。你装D:\仿真软件\ModelSim这种路径前面几步可能没事但编译库的时候大概率会报一些莫名其妙的错网上查半天也找不到原因最后发现就是路径问题。建议按下面这个方式来放Vivado安装路径C:\eda\Vivado2020.2 ModelSim安装路径C:\eda\modeltech64_2020.4Windows用户名也尽量别用中文。如果你当前Windows账户名是中文ModelSim有些临时文件目录会生成到用户目录下后面跑仿真也可能因为权限或路径问题失败。实在不行就新建一个纯英文的Windows账户来搞开发别嫌麻烦。2.2 环境变量少配一个仿真器就起不来ModelSim安装完成后有两个环境变量建议手动确认一下PATH里要包含C:\eda\modeltech64_2020.4\win64这样命令行里直接敲vsim才能启动。MGLS_LICENSE_FILE要指向你的ModelSim license文件位置格式是C:\eda\modeltech64_2020.4\license.dat或者端口服务器地址。顺便说一句Vivado 2020.2的license走的是FlexLM那套用的环境变量是XILINXD_LICENSE_FILE和ModelSim不是同一个。我之前有次Vivado能启动但ModelSim起不来查了半天发现是MGLS_LICENSE_FILE根本没设对。两个license系统是独立的别混在一起。注意改完环境变量之后已经打开的Vivado和ModelSim不会自动感知必须关掉重新打开。这一步经常被忽略我见过好几个同事改完环境变量不重启然后来问为什么还是没生效。2.3 License相关的几个典型翻车现场ModelSim的license问题具体表现通常是双击vsim.exe之后闪退或者在Vivado里启动仿真时ModelSim打开一下立刻消失。排查链路一般是先单独启动ModelSim看有没有license弹窗报错。打开环境变量设置页面确认MGLS_LICENSE_FILE的值确实存在。如果用的是license server在命令行里执行lmutil lmdiag或者lmstat看服务器状态。还有一点容易忽略ModelSim安装目录下的license.dat如果权限不对Vivado以管理员权限调用vsim时可能读取失败。这个不常见但我在Windows 10上踩过一次。3. 编译仿真库Vivado与ModelSim打通的关键一役3.1 为什么第三方仿真器非要编译Xilinx库这个原理很多教程没讲透。Xilinx的IP核和原语比如FIFO、BRAM、DSP48E、GT收发器它们的仿真模型并不是一个现成的二进制文件而是由Verilog/VHDL源码和加密模型组成。Vivado自带的xsim能直接加载这些源码因为它知道自己家库的位置但ModelSim不知道所以你必须先把这些源码用ModelSim的vlib、vlog、vmap工具编译成ModelSim能识别的库文件。编译库的本质就一句话把Xilinx的仿真模型从Vivado的格式转换成ModelSim的格式并建立好库名和物理路径之间的映射关系。3.2 GUI方式Tools - Compile Simulation Libraries在Vivado里点开Tools - Compile Simulation Libraries弹出的窗口里需要设置几个东西Simulator选ModelSim。Executable path填vsim.exe所在的目录也就是C:\eda\modeltech64_2020.4\win64。Output directory建议填一个专门放库的目录比如C:\eda\modeltech64_2020.4\vivado_lib。Family这里就要看情况选了见3.3节。如果点击Compile之后弹出版本不支持的提示先别慌看它是Warning还是Error。Warning一般可以直接继续Error的话就回到本文1.2节的方法检查ModelSim版本和类型是不是SE/DE。3.3 Family选择不要全选除非你时间多很多教程会跟你说Family全选这是最稳但最费时间的做法。全选所有器件家族视电脑性能不同要编译20到40分钟而且中途一旦有个器件家族报错整个流程就卡在那里了。如果你项目里只用了Artix-7或者Zynq-7000在Family里只勾选对应家族就够了几分钟就编译完。我自己常用的组合是Family: zynq7000, artix7 Language: Verilog如果你的设计里用了VHDL的IP那Language就得选All否则后面仿真会报找不到VHDL库。3.4 编译完先检查这三样东西编译过程结束后别急着去Vivado里配仿真器先做三个检查第一打开输出目录看看是不是生成了unisim、unimacro、xpm、secureip这些文件夹。没有这些文件夹说明编译并没有成功。第二找到ModelSim的modelsim.ini文件用记事本打开看Library段里是否有类似这样的映射unisim C:/eda/modeltech64_2020.4/vivado_lib/unisim xpm C:/eda/modeltech64_2020.4/vivado_lib/xpm如果映射被写进去了说明库编译结果已被ModelSim登记。如果没有就需要手动用vmap补上这个在第五章会详细讲。第三单独启动一次ModelSim在Transcript窗口输入命令vmap回车后应该能看到一排映射列表。这一步能确认当前工作目录下ModelSim到底认哪些库。4. Vivado工程内绑定ModelSim第一次把仿真跑起来4.1 在Vivado中指定ModelSim和编译库路径编译好仿真库之后回到Vivado主界面依次打开Tools - Settings - EDA Tool Options - Simulation在右侧找到ModelSim Simulator相关配置Simulator executable path填C:\eda\modeltech64_2020.4\win64。编译仿真库路径那里填刚才编译库的输出目录C:\eda\modeltech64_2020.4\vivado_lib。然后还要到Project Settings - Simulation里把默认仿真工具从Simulator (XSim)改成ModelSim Simulator。这一步不能漏很多人配置了EDA Tool Options却没有改项目设置结果点仿真还是启动xsim。4.2 Run Behavioral Simulation背后到底发生了什么在Sources窗口选中你的testbench文件右键Run Simulation - Run Behavioral SimulationVivado不会直接弹出一个仿真界面而是会在后台拼一个启动脚本然后去执行。Vivado做的动作包括把设计里的所有RTL文件和IP仿真模型文件整理出来调用ModelSim的vlib建一个work库再vlog编译所有源文件最后用一行很长的vsim命令启动仿真。这行vsim命令里会带一堆-L参数比如-L unisim -L unisims_ver -L xpm -L secureip。这些-L参数就是告诉vsim如果设计里引用了Xilinx的库去这些名字对应的库目录下找。4.3 第一次把波形跑出来的标准动作第一次跑通的标准动作我是这样记的防止自己反复踩坑单独启动ModelSim一次确认license没问题。确认Vivado工程路径是纯英文。确认testbench文件已经被设为仿真顶层。点Run Behavioral Simulation。如果ModelSim窗口正常弹出在Transcript里看到Loading work.tb_top然后在Wave窗口里选择信号右键Add To Wave。点击Run -All观察波形是否有变化。注意如果你需要观察RTL内部信号但wave窗口里看不到这些信号那是因为ModelSim默认开启了优化。可以用vsim -voptargsacc来关闭信号优化或者把需要观察的信号加入log命令。在Vivado自动启动的ModelSim中这个参数一般会自动带上但手动仿真时容易漏。5. 联合仿真踩坑实录从库丢失到波形空白的完整排查5.1 最经典Failed to access library unisim这个报错应该是Vivado挂ModelSim最常见的错误没有之一。表现形式是Vivado顺利调起了ModelSim但Transcript窗口立刻出现Failed to access library unisim at unisim.排查第一步确认编译库输出目录里确实有unisim文件夹。如果有那就是modelsim.ini里的映射丢了。打开ModelSim安装目录下的modelsim.ini找到[Library]段手动加一行unisim C:/eda/modeltech64_2020.4/vivado_lib/unisim或者更优雅的做法是在ModelSim的Transcript窗口里执行vmap unisim C:/eda/modeltech64_2020.4/vivado_lib/unisimvmap的作用是动态修改当前用户目录下的modelsim.ini映射表。但要注意如果Vivado启动ModelSim时使用了工程目录下的另一个modelsim.ini你的vmap可能加到了错误的文件里。这也是为什么我强调要看脚本日志里vsim启动时的工作路径。5.2 modelsim.ini到底改了哪一个ModelSim在Windows下的配置文件名是modelsim.ini但这个文件可能同时存在于好几个地方位置作用ModelSim安装目录下系统级默认配置当前工作目录下本次运行优先使用的配置用户目录下当ModelSim从不同路径启动时可能用到坑就坑在这里你在安装目录下改了映射但Vivado启动ModelSim时工作目录在工程目录下ModelSim优先读取工程目录下的modelsim.ini结果你改的映射根本没生效。排查方法在ModelSim Transcript窗口执行pwd看当前工作目录在哪然后确认该目录下有没有modelsim.ini。5.3 工程路径和用户名中文导致的一切诡异问题这我必须单独立一条。有次我帮同事排一个ModelSim启动后RTL文件全部编译报错的问题所有报错都是文件路径里带乱码字符。一看他的Windows用户名是张三工程路径是D:\项目A\prj1Vivado生成临时脚本的时候把这些路径写进do文件ModelSim解析中文路径直接崩了。这种问题排查起来很烦因为报错信息往往不直接说路径有中文而是报一些语法错误或文件不存在。我个人的硬性规范是所有开发相关路径必须满足英文、数字、下划线。如果你已经被这个问题折磨最简单的办法是把工程移动到一个纯英文路径下再重新加载。5.4 仿真提示找不到IP核模块但代码明明没问题如果你在设计里例化了Xilinx的FIFO IP或AXI IP仿真时ModelSim报错找不到模块很多人的第一反应是库没配好但其实还有一个很常见的坑IP的仿真模型没有生成。Vivado里IP核的输出产物是可以选择的默认可能只生成综合产生的网表文件没有生成仿真模型。解决办法是打开IP Catalog找到对应IP。右键选择Generate Output Products。在弹窗里选Simulation相关的选项确认生成了仿真模型文件。如果你用的是IP的Instantiation Template这些模板文件不是完整的IP仿真模型只是端口例化样板。仿真时必须把IP核生成的仿真源文件一并加入工程不能只靠一个例化模板。5.5 波形全是空白信号被优化掉或testbench根本没触发有时候ModelSim正常启动、库也正常加载但Wave窗口里一片空白要么就是有信号但没有跳变。这个问题分两种原因。第一种是信号被ModelSim优化掉了。Vivado自动拉起ModelSim时一般会带-voptargsacc参数来保留信号可见性但如果你是手动在ModelSim里重新编译仿真很可能没带这个参数。这种情况下在vsim命令里加上-voptargsacc然后重新启动仿真。vsim -voptargsacc work.tb_top第二种是testbench里的时钟或复位信号没写对。这个更常见。比如testbench里只写了#100;但没给时钟信号写always #5 clk ~clk;波形当然不会动。我记得有次我在testbench里忘了写initial begin clk 0; end结果时钟一直是不定态X所有信号跟着全是X还以为是ModelSim出了问题。排查这种问题我的习惯是先看时钟和复位信号的波形如果它们是X态那问题基本在testbench本身不是在工具。5.6 编译库中途失败的应急处理如果你编译仿真库过程中报错中断别急着重复点Compile。Vivado的库编译工具不会自动清理残留文件残留的库文件可能损坏重复编译大概率还是失败。正确做法是删除之前设置的输出目录整个删掉。关掉所有ModelSim进程避免modelsim.ini被占用。重新打开Vivado的Compile Simulation Libraries配置好后重新编译。如果依然失败把Transcript窗口里第一条报错信息复制到搜索引擎里查比盲试高效得多。6. 进阶用法do脚本与批量回归仿真6.1 do脚本的基本结构ModelSim配好之后如果你还是每次手动添加波形、手动点Run那模拟仿真的效率并没有真正提起来。ModelSim最大的好处是支持do脚本把整个仿真流程固化成文件以后每次直接一行命令跑完。一个最简单的do脚本大概长这样vlib work vlog C:/prj/testbench/tb_top.v vlog C:/prj/rtl/top.v vsim -voptargsacc work.tb_top add wave -r /tb_top/* run -all解释一下关键点vlib work创建work库。重复执行时会提示库已存在可以加-force参数。vlog编译RTL源文件和testbench。vsim启动仿真-voptargsacc保证信号可见。add wave -r /tb_top/*递归添加tb顶层下所有信号。run -all跑完整段仿真。6.2 把do脚本和Vivado集成起来有了do脚本之后就不一定非要从Vivado界面里点那个Run Simulation了。你可以在Vivado的Tcl Console里执行launch_simulation -simulator modelsim -scripts_only这个命令会生成ModelSim需要运行的do脚本然后你可以自己去ModelSim里执行。当然要看脚本内容做一下定制。如果你希望全自动跑完直接出波形图可以在do脚本里加一行quit -sim这样仿真结束自动关闭仿真器适合批量回归。6.3 让回归测试真正变成一键执行批量回归的时候我通常会在工程目录下写一个run_all.do脚本把所有testbench文件名放在一个列表里循环编译执行set testbenches { tb_adder tb_multiplier tb_fifo_top } foreach tb $testbenches { vlib work vlog C:/prj/rtl/*.v vlog C:/prj/testbench/${tb}.v vsim -voptargsacc work.${tb} run -all add wave -r /* quit -sim }这个脚本的缺点是每次编译重复比较慢。更高效的做法是把RTL只编译一次然后循环编译testbench和启动仿真。你可以根据自己的工程结构调整。我个人在实际操作中的体会是Vivado和ModelSim联仿的难点从来不是点按钮本身而是版本匹配、库编译和配置映射这套环境工程。一旦环境打通后续的仿真工作流反而比xsim顺手很多。最后再分享一个小技巧把编译库用的目录和配置参数记在一个备忘录里下次重装系统或者换电脑时照着做十分钟就能恢复环境不用再次摸索。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进