ARTICLE DETAIL

资讯详情

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

FPGA Vivado中IP核操作顺序:Generate Output Products与Create HDL Wrapper

FPGA Vivado中IP核操作顺序:Generate Output Products与Create HDL Wrapper FPGA新手在Xilinx Vivado里第一次调IP核的时候十有八九会被同一个问题卡住Customize IP对话框点完OK回到主界面Sources窗口里那个IP核图标旁边挂着一个黄色的感叹号右键弹出来的菜单里有Generate Output Products也有Create HDL Wrapper到底先点哪个我在带新人的时候这个问题的出现频率高得惊人网上搜到的答案大多是“先Generate再Create”但很少有人把为什么讲清楚。这篇文章就专门把这两个操作拆开揉碎把顺序背后的依赖关系解释透。你看完就能理解Vivado这套流程的逻辑而不是死记硬背“先点这个再点那个”遇到版本变化、IP改动、报错排查的时候也不至于抓瞎。1. 这两个操作分别解决什么问题1.1 Generate Output Products把IP核变成能用的“半成品”要理解Generate Output Products得先想清楚一个问题IP核在Vivado里到底是什么形态你在Customize IP界面里配置了半天参数点完OK其实只是在工程里写下了一条“我要用某个IP参数是这样这样”的记录。这个时候Vivado只知道你需要这个IP但还没有为你准备后续综合Synthesis、仿真Simulation所需要的实际文件。Generate Output Products干的就是这件事——把这些配套文件全部生成出来。具体来说它主要产出了这几类东西综合相关文件IP核的网表文件.dcp和时序约束.xdc。综合器需要这些文件才能把IP放进整个设计里。仿真相关文件IP核的行为级仿真模型通常是Verilog或VHDL文件Modelsim、Vivado Simulator都靠它们进行功能仿真。例化模板也就是后缀为.veo或.vho的模板文件。Verilog工程生成.veoVHDL工程生成.vho。这个文件里已经把IP核的端口声明和例化模板写好了后面Create HDL Wrapper要用到的核心内容就是它。部分IP还会附带示例设计和XDC约束示例方便你了解该IP在板级上的接线方式。不过这些通常不会自动加入工程需要手动确认。打个不严谨但好懂的比方IP核本身是一个“内容物”Generate Output Products把它打包成了贴着标签、写着说明、可以装进快递盒的半成品。你接下来不管是自己手写顶层模块去例化它还是让Vivado帮你生成Wrapper都得以这些产物作为基础。有意思的是很多新手容易把“IP核定制完成”误解为“IP核已经准备好可以综合了”。实际上如果你定制完IP直接去Run SynthesisVivado大概率会报错或者弹提示告诉你某些IP没有生成输出产物。这个状态你可以在Sources窗口里看到IP核的名称旁边会有一个黄色感叹号Status列写着“Needs generation”就是这个意思。1.2 Create HDL Wrapper给IP核套一个“标准外壳”Generate Output Products解决的是“文件齐不齐”的问题Create HDL Wrapper解决的则是“IP核怎么挂进设计里”的问题。在Vivado里一个IP核不能单独成为整个设计的顶层。你要么自己写一个顶层模块在代码中手动例化这个IP核把一个个端口信号连好要么让Vivado帮你自动生成一个包装文件把例化代码写好这个文件就叫HDL Wrapper。打开Create HDL Wrapper对话框之后你会看到两个选项Let Vivado manage wrapper and auto-update让Vivado自动管理这个Wrapper文件。你之后修改了IP核参数、重新生成输出产物Vivado会自动同步更新Wrapper里的端口和例化代码不需要你手动去改。Copy generated wrapper to allow edit复制一份Wrapper文件到工程里允许你手动编辑。绝大多数情况下默认的“Let Vivado manage wrapper and auto-update”就是最优解。但很多新手就是因为不理解这个选项的含义选了第二个又在Wrapper里手动加了信号结果后面IP一更新Wrapper里的例化代码和端口对不上排查起来一头雾水。这个坑后面专门讲。Create HDL Wrapper本质上是从IP核的例化模板出发生成一个顶层HDL模块里面把IP核实例化好了对外暴露的端口和你配置出来的IP端口完全一致。生成完以后你还需要在Sources窗口把这个Wrapper文件右键设置为顶层Set as Top整个设计的顶层才算确定下来。1.3 这两个操作和“顶层模块”是什么关系很多新手做完Create HDL Wrapper后一脸茫然明明我已经有Wrapper了为什么还要Set as Top按理说Vivado不是应该自动把新建的Wrapper设为顶层吗实际上Vivado并不会自动这么做。它只是生成了一个Wrapper文件但你的工程可能还有其他源文件也可能你已经有了一个旧的顶层模块。Vivado无法判断你打算用哪个作为真正的顶层所以需要你手动指定。这一步漏掉的后果就是综合的时候Vivado找不到顶层模块或者综合出来的顶层根本不是包装了IP的那个模块。另外要说清楚Create HDL Wrapper不是唯一的选择。很多有经验的工程师不喜欢用Wrapper习惯自己手写一个顶层模块来例化IP核。这个做法在纯Verilog工程里完全可行而且灵活度更高。但对于新手来说我建议老老实实用Vivado生成的Wrapper理由有两个一是自动生成的代码标准、清晰、不容易写错端口二是电脑帮你生成的例化代码信号列表和端口宽度一定是对得上的而你手写的时候一旦少打一个信号或者位宽搞错排查起来要命。2. 为什么顺序一定是先 Generate 再 Create2.1 从依赖关系看执行顺序回到核心问题为什么必须先Generate Output Products再Create HDL Wrapper我之前说了Create HDL Wrapper的本质是根据IP核的例化模板生成一层包装。而这个例化模板——也就是.veo/.vho文件——恰恰是Generate Output Products的产物之一。换句话说Create HDL Wrapper是“消费”数据的Generate Output Products是“生产”数据的。先有生产后有消费这是一个很朴素的依赖关系。如果你还没Generate就直接点击Create HDL Wrapper会发生什么部分Vivado版本比如2020.1之后会把Create HDL Wrapper按钮置灰直接不让你点。有些版本允许点击但会弹出一个警告框提示你当前IP还未生成输出产物需要先运行Generate Output Products。即便你强行生成了Wrapper由于没有例化模板作为依据生成的Wrapper可能内容不完整端口丢失或者格式错误。后续你在工程里看这个Wrapper文件会发现里面只有模块声明IP核例化部分缺失或者残缺。所以不要跟Vivado“讨价还价”。在FPGA开发流程里Generate Output Products是前置步骤Create HDL Wrapper是后续步骤这个顺序不是Vivado拍脑袋定的而是文件依赖关系决定的。2.2 如果先 Create 再 Generate 会发生什么我特意在“能用的版本”和“不能用的版本”两种情况下都试过把经验写在这里方便大家遇到类似问题时心里有底。在较早的Vivado版本比如2018.x里先Create HDL Wrapper是可以点下去的Vivado会在弹出的提示里提醒你先执行Generate Output Products。但不少新手误以为这个提示只是一个“建议”点了Yes继续生成Wrapper结果后面综合报错才回头看。这时候的Wrapper文件大概率是一个空壳——顶层模块名字有了端口是空的IP例化代码也不存在。你后续再回去Generate Output Products这个Wrapper也不会被自动修复因为Vivado认为你已经有一个Wrapper了。你需要右键选择Re-create HDL Wrapper让它重新生成或者删掉旧的Wrapper再来一次。在较新的版本2020.1及以后里Create HDL Wrapper基本被锁定在Generate Output Products之后你还没Generate的时候这个选项是灰的没法点。这种情况下Vivado相当于帮你强制规范了顺序但如果你不明白背后的道理依然会困惑为什么这个按钮不是亮的是不是我哪里配置错了还有一个常见误区是先Generate Output Products后再创建Wrapper结果在Wrapper里看到了很多奇怪的信号比如IP核内部的控制信号、状态信号新手容易怀疑自己是不是操作错了。其实这是正常的IP核的端口在定制界面里显示的是经过封装的用户端口但在Wrapper的例化代码里某些IP会暴露额外的控制端口这是IP本身的设计决定的不影响使用。2.3 Wrapper 与顶层模块之间的版本协同还有一个容易踩坑的点在于Wrapper生成之后并不是一劳永逸的。IP核的参数一旦修改比如把FIFO的数据位宽从8bit改成16bit把时钟频率从100MHz改成150MHzIP核的状态会重新变成“Out of date”。这时候你必须重新执行Generate Output Products。如果你是让Vivado管理Wrapper选了Let Vivado manage那么重新Generate之后Wrapper的端口会自动同步更新。如果你是复制了一份Wrapper手动编辑选了Copy generated wrapper to allow edit那么Vivado不会自动改你的Wrapper新生成的例化模板和你的Wrapper文件就出现了版本不一致。端口没变还好顶多内部IP版本号不同还能凑合综合端口一变你手改的Wrapper就和实际IP接口对不上了综合报错是必然的。所以如果你没有特殊理由一律选择Let Vivado manage wrapper and auto-update。选择手动编辑这个选项的真正用途是你需要在Wrapper内部添加额外的逻辑而不只是单纯例化IP。关于这一点后面实操部分再展开说。3. 完整实操流程走一遍3.1 从添加 IP 到生成比特流的标准步骤下面以Xilinx Vivado为例走一遍完整的流程。无论是做数码管动态显示、图像采集、MIPI接口还是简单的流水灯工程只要用到了IP核这个流程都是一模一样的。**第一步新建工程并选择器件。**这个就不赘述了器件选型按你的开发板型号来就行。**第二步添加IP核并配置参数。**在Flow Navigator里点IP Catalog搜索你要的IP。比如做数字时钟显示就用Clocking Wizard做数据缓存就用FIFO Generator做ADC采集就用XADC。双击IP进入Customize IP界面配置好参数点OK。**第三步Generate Output Products。**在Sources窗口的IP Sources标签下右键刚添加的IP核在菜单中选择Generate Output Products。弹出的对话框中Synthesis Options选择Out of context per IP默认选项Run Settings勾选Synthesis和Simulation两项点Generate。等待右下角的进度条跑完IP核状态变为“Generated”。提示不建议在Synthesis Options里选Global。Global模式会让IP和整个设计一起综合每次改动顶层逻辑IP也要跟着重新综合白白浪费时间。Out of context模式是让IP单独综合成网表顶层综合时直接调包大幅减少综合时间。**第四步Create HDL Wrapper。**右键IP核选择Create HDL Wrapper弹出对话框中保持默认选项Let Vivado manage wrapper and auto-update点OK。**第五步Set as Top。**在Sources窗口里选中生成的Wrapper文件右键选择Set as Top。这一步千万别漏。设置成功后Wrapper文件会变成粗体表示它是顶层模块。**第六步添加用户文件。**如果你已经写好了逻辑代码比如数码管扫描模块、图像处理模块以Add Sources的方式加入工程。这些文件会成为Wrapper下的下一级模块被Wrapper例化或者和Wrapper并列。**第七步添加约束文件。**新建或添加XDC约束文件把引脚约束和时钟约束写好。**第八步Run Synthesis、Run Implementation、Generate Bitstream。**按顺序跑完这三个环节生成比特流下载到FPGA里验证。整个流程看起来步骤多但真正和本文主题强相关的就是第三步、第四步和第五步。很多人做到第三步就被“Generate Output Products”卡住其实只要理解了它是给IP准备文件你的思路就清晰了。3.2 修改 IP 之后如何正确同步FPGA开发中IP参数修改是家常便饭。比如做图像处理时图像分辨率从640x480改成1920x1080FIFO的深度就要跟着改做通信接口时时钟频率调整也会牵连到Clocking Wizard的配置。修改IP参数的方法是双击Sources窗口里的IP核图标重新打开Customize IP界面改好参数后点OK。这时候你会注意到IP核的状态又变成了“Out of date”而且Flow Navigator里可能弹出一个提示条提醒你有IP需要重新生成输出产物。正确的处理步骤是右键IP核重新执行Generate Output Products。如果你使用的是Let Vivado manage wrapper默认推荐Wrapper会在输出产物重新生成后自动更新。你可以在Wrapper文件里看到端口已经变成了参数修改后的新版本。如果你的IP核是被你自己的顶层模块例化的你还需要手动去更新顶层模块中的例化代码把新增/删除的端口信号补上或去掉。这里有一个非常典型的坑修改IP参数后明明已经重新Generate了但综合还是报错说某些信号找不到。排查时发现是因为自己写了顶层模块例化IP而例化代码里的端口还是旧版本。对于这种情况建议直接看看IP核目录下生成的.veo文件里面有最新的例化模板对照着修改自己的顶层代码即可。3.3 批量处理多个 IP 的实用技巧实际工程中一个设计往往不止一个IP。比如一个图形显示项目可能同时用到Clocking Wizard、FIFO Generator、Block Memory Generator、XADC等四五个IP。批量操作的时候技巧是按住Ctrl或Shift多选IP核然后右键统一执行Generate Output Products。Vivado支持对多个IP同时生成输出产物会逐个处理你不用一个个点。生成的时候留意右下角的进度有时会弹出OOC综合窗口这是IP在单独做综合属正常现象不要关掉它。等它跑完你会发现后面的顶层综合时间短很多这就是OOC的魅力。如果你想把某个IP的例化模板找出来手动参考可以在工程目录下的project.gen/sources_1/ip/ip_name/ip_name.veo路径下找到用文本编辑器打开就能看到规范的例化代码。4. 顺序搞错怎么办常见问题与排查技巧4.1 新手最容易踩的 5 个坑我把带新人时遇到的共性问题整理成一张速查表方便大家遇到问题直接对照。现象原因解决办法Create HDL Wrapper按钮是灰的还没先生成输出产物先执行Generate Output Products再创建Wrapper创建了Wrapper但综合报找不到顶层没有把Wrapper设为Top右键Wrapper → Set as Top修改IP参数后综合报错信号丢失老版本Wrapper没自动更新右键IP重新Generate再右键Wrapper选择Re-create HDL Wrapper仿真报错找不到IP仿真模型Generate时只勾选了Synthesis没勾Simulation重新Generate勾选Simulation选项Wrapper里自己加了逻辑IP一更新全乱了创建Wrapper时选了Copy generated wrapper to allow edit删掉手动改过的Wrapper重新创建并选用自动管理模式第五个坑值得多说两句。很多新手看到“Copy generated wrapper to allow edit”这个选项以为选了它才有权限加自己的逻辑其实不然。在Let Vivado manage模式下Wrapper文件虽然被标记为自动管理但你仍然可以打开它查看代码。如果你想在顶层加一些自己的逻辑完全可以在Wrapper下面再添加一个自己写的模块不需要直接在Wrapper文件里改。倘若你真的需要在Wrapper内部写逻辑就要接受“IP更新后需要手动同步Wrapper”的代价这一点要想清楚。4.2 一个真实排查案例有一次我在做图像帧缓存工程用Vivado 2019.1工程里挂了一个FIFO IP和一个Clocking Wizard。原本综合、布线都正常后来因为分辨率调整我把FIFO的数据位宽从24位改成了32位深度也翻了一倍。改完参数后我直接点了Run Synthesis结果综合到一半报错提示找不到fifo_generator_inst/din[31:24]这样的信号。排查思路是这样的先看错误信息里提到的信号确实出现在FIFO例化模板里新版本的din端口已经是32位了。再看自己写的顶层文件例化FIFO的那一段代码还是旧的24位版本。问题就出在我没让Vivado管理Wrapper而是自己手写顶层例化IP改IP参数后忘了同步顶层代码。我当时没有用Vivado的自动Wrapper而是手写了一个顶层文件。处理办法是打开IP核的.veo模板照着新的端口定义把顶层文件里的例化代码更新了一遍然后重新Generate Output Products再Run Synthesis就通过了。这个案例说明一个道理无论你是用自动Wrapper还是手写顶层例化都离不开一个“同步更新”的环节。区别只在于自动Wrapper把这个环节交给Vivado手写顶层则靠你自己记住。新手阶段用自动Wrapper能少踩很多雷。4.3 几条实操心得最后分享几条我自己的实操心得算是多年用下来最值得记住的经验。第一养成固定顺序的肌肉记忆。不管什么版本、什么IP永远是先Generate Output Products再Create HDL Wrapper最后Set as Top。这条链路熟悉以后你会觉得Vivado的很多操作其实很有逻辑只是最初上手时少一个全局视角。第二修改IP后注意看状态和提示。Vivado在IP需要重新生成输出产物时会在IP核旁边显示状态标记Out of date之类同时界面顶部会弹出更新提示。不要直接忽略这些提示它们其实是在告诉你流程的下一步是什么。第三仿真输出在Generate的时候直接勾上。很多跟着教程做仿真的人会发现找不到仿真模型折腾半天其实只是因为Generate Output Products时没勾选Simulation选项。一步到位后面少很多事。第四不同Vivado版本的按钮位置和名称有差异但逻辑骨架是一样的。2020.1之后Create HDL Wrapper的入口可能更隐蔽但依赖关系没有变。你看懂了依赖关系换什么版本都不会慌。最后再补充一点如果你用的是AlteraIntel的Quartus环境对应的概念是“Generate HDL”和“Create Symbol File for Current File”命名和Vivado不一样但思考方式一致——先把IP的文件生产出来再让IP参与顶层设计。工具可以换思路是通用的。根据我个人经验FPGA开发中很多让人挠头的问题本质都是没搞清工具的操作逻辑。Generate Output Products和Create HDL Wrapper的先后顺序是你接触IP核之后遇到的第一个典型流程问题。把这两个操作的关系吃透后面再遇到更复杂的流程控制比如增量编译、调试配置、版本管理你就不容易一头雾水。希望这篇能把你的困惑解决掉让你少走一点弯路。
返回列表