FPGA应用技巧之Vivado自定义IP创建与使用

FPGA应用技巧之Vivado自定义IP创建与使用 目录1 概述2 使用自定义IP的优势2.1 逻辑标准化封装实现一次编写、终身复用2.2 适配Block Design可视化开发流程2.3 参数可配置化适配多场景迭代2.4 工程解耦结构更清晰、易维护2.5 支持版本管理与权限隔离3 适用场景4 自定义IP完整创建与封装步骤4.1 准备工作4.2 启动IP封装向导4.3 IP基础信息配置关键4.4 端口与接口自动识别与修正4.5 参数配置实现可配置IP4.6 审核与最终打包5 自建IP完整使用教程Block Design工程集成5.1 加载自建IP到当前工程首次使用必做5.2 在Block Design中添加自建IP5.3 自建IP参数可视化配置精细化实操5.5 端口引出与顶层映射5.6 设计校验与错误修复5.7 生成IP输出与顶层HDL文件必须步骤5.8 自建IP迭代使用更新逻辑后5.9 自建IP使用核心要点6 自定义IP跨工程复用方法7 自定义IP迭代更新方法8 注意事项9 常见问题与解决方案10 创建可配置分频器自定义IP10.1 功能说明10.2 完整可编译Verilog源码10.3 源码预处理IP封装必备10.4 分步封装为自定义IP10.5 Block Design调用自定义IP10.6 板级验证11 总结1 概述自定义IPCustom IP是Vivado平台提供的个人模块封装功能。简单来说你自己写的Verilog/VHDL功能代码比如分频、滤波、串口驱动可以打包成和官方IP一模一样、可以直接拖拽、可以改参数、可以反复复用的标准模块完美适配图形化Block Design开发。Vivado自带的官方IP只能满足基础通用功能项目里专属的算法、自定义通信协议、特殊传感器驱动等没有现成IP可用。这时就需要自制IP把自己的代码变成可复用模块。本文将从零开始、通俗完整地讲解自定义IP是什么、什么时候用、怎么封装、怎么在工程中调用、怎么跨项目复用、怎么升级迭代适合所有FPGA、Zynq新手入门和工程使用。2 使用自定义IP的优势在Vivado开发中我们可以直接添加源码使用也可以把源码打包成自定义IP。相比于直接堆代码自定义IP更适合正式项目、复杂项目优势非常明显也是工程开发的标准做法下面通俗说明核心好处。2.1 逻辑标准化封装实现一次编写、终身复用如果直接写源码代码只能在当前工程用换一个工程就要重新复制、粘贴、改路径、对端口非常麻烦还容易出错。把常用功能分频、滤波、串口解析、PWM、数据缓存等打包成自定义IP后不管新建多少工程直接拖拽即用大幅减少重复劳动还能积累属于自己的IP工具库。2.2 适配Block Design可视化开发流程Vivado图形化开发Block Design只能识别官方IP和标准自定义IP普通源码不能直接拖拽连线。把自己的代码封装成IP后就能和官方IP一样鼠标拖拽、自动连线、一键配置参数轻松搭建复杂的可视化硬件系统。2.3 参数可配置化适配多场景迭代自定义IP支持可视化改参数。比如分频系数、数据位宽、波特率、工作模式不需要打开源码修改代码直接在图形界面改数值即可。同一个IP可以适配不同项目需求灵活度极高调试起来非常方便。2.4 工程解耦结构更清晰、易维护如果一个工程几百上千行代码全部堆在一起排查bug、修改功能、交接代码都会非常困难。使用自定义IP可以一个功能打包一个IP模块之间互不干扰工程结构清晰、分层明确调试简单也适合团队分工开发。2.5 支持版本管理与权限隔离自定义IP可以单独保存、版本升级。团队开发时可以把稳定成熟的代码封装成IP隐藏底层源码只开放使用接口既保护代码安全又能统一所有人的开发规范避免有人随意改核心逻辑导致工程出错。3 适用场景适合制作自定义IP的场景如下只要是自己写的、需要反复用的功能都可以打包1、自研算法逻辑滤波、CRC校验、数据解码、图像预处理等2、自定义外设驱动自己写的SPI、I2C、传感器时序驱动等3、通用工具模块分频器、延时电路、脉冲检测、数据拼接拆分、缓存拓展等4、复杂系统子功能把大型工程的某个独立子模块单独封装方便顶层调用5、所有需要多次复用、不想重复写代码的成熟功能模块。4 自定义IP完整创建与封装步骤本节用最简单、可直接照抄的步骤教大家从自己写的代码一步步打包成标准自定义IP适配绝大多数Vivado版本新手可以直接复刻操作。4.1 准备工作1、新建或打开Vivado工程选定对应FPGA芯片型号2、编写需要打包的Verilog/VHDL代码保证代码能正常编译、没有报错、端口定义清晰3、把代码添加到工程源文件编译测试通过确认功能正常4、建议一个模块只做一个功能、尽量简洁、预留可配置参数方便后续打包复用。4.2 启动IP封装向导1、点击顶部菜单栏Tools → Create and Package IP启动IP打包工具2、直接点Next下一步3、选择默认选项Package your current project打包当前工程的代码继续下一步4、选择一个文件夹用来保存打包好的IP建议单独建文件夹统一管理下一步。4.3 IP基础信息配置关键本步骤用于设置IP的专属身份信息方便后续搜索、归类和版本区分按以下规范填写即可1、IP Name纯英文名称无空格、无中文例user_clk_div2、IP Display Name界面展示名称可填写中文直观标注模块功能3、VersionIP版本号首次打包默认1.0即可4、Vendor/Library/Category自定义厂商、库名、分类方便后期归类检索5、Description简要填写IP核心功能与用途6、全部填写完成后点击Next进入下一步。4.4 端口与接口自动识别与修正软件会自动识别源码的所有端口我们只需核对修正避免端口识别错误保障IP正常使用1、核对所有输入、输出端口是否识别完整、没有认错2、时钟端口手动标记为Clock类型标注对应时钟频率3、复位端口手动标记为Reset类型选择高电平/低电平有效4、普通数据端口不需要改动5、确认无误后下一步。4.5 参数配置实现可配置IP本步骤核心作用将源码中可调整的参数开放到图形界面后续修改参数无需改动代码直接可视化调试操作更便捷1、软件会自动读出代码里所有可配置参数2、把需要后续调整的参数勾选Enable设置好默认值、取值范围3、固定不变的内部参数可以隐藏避免界面杂乱4、设置完成后下一步。4.6 审核与最终打包1、进入最终审核页面查看右上角Status状态必须无Error报错普通警告可忽略2、确认IP名称、端口、参数全部无误3、点击Package IP开始打包等待提示完成自定义IP就制作成功了。5 自建IP完整使用教程Block Design工程集成IP打包完成后不能直接使用需要加载到工程、添加到画布、配置参数、生成顶层文件才能正常编译下载。本章用通俗、极简、标准的步骤教大家完整使用自建IP。5.1 加载自建IP到当前工程首次使用必做Vivado默认仅识别官方IP自建IP需要手动添加仓库路径每个新工程只需配置一次具体步骤如下1、打开你的目标工程点击顶部Tools → Settings2、左侧展开IP → Repository点击加号添加路径3、选择你存放IP的整个文件夹不要选单个文件4、点击OK保存5、在左侧IP Catalog右键选择Update IP Catalog刷新IP库6、刷新后能搜到你的IP代表加载成功。注意每个新工程首次使用该自建IP都需要添加一次仓库路径建议将常用IP固定路径避免重复配置。5.2 在Block Design中添加自建IP1、新建或打开已有的Block Design图形画布2、点击顶部Add IP添加模块3、搜索你自定义IP的名称4、双击添加到画布模块默认继承打包时的端口和参数。5.3 自建IP参数可视化配置精细化实操自建IP最大的优势就是不改源码仅通过图形界面修改参数即可适配不同工程场景。工具会自动校验参数合法性、自适应端口规格新手也能快速调试完整实操步骤如下步骤1打开参数配置面板在画布中双击你的自建IP即可打开配置窗口。窗口只会显示你开放的可改参数内部固定参数不会显示界面干净、不容易改错。步骤2看懂参数作用、优先保留默认每个参数都会有功能说明比如“分频系数”“数据位宽”“FIFO深度”。如果没有特殊调试需求优先保留默认参数保证模块功能稳定。步骤3按需修改参数遵守简单规则杜绝报错如果需要改参数只需要遵守下面几条简单规则就能避免99%的错误只填正整数位宽、分频值、深度等参数只能填正数不能填小数、负数、字母不超最大范围不要填超出参数标注最大/最小值的数字防止寄存器溢出报错匹配时钟频率分频、延时等参数要和工程时钟对应不要出现逻辑上不可能的配置关联参数一起改如果两个参数互相绑定位宽与深度、模式与阈值要改就一起改不要单独乱改一个。步骤4自动校验端口自适应无需手动适配修改参数点击OK后软件会自动做两件事省心且不易出错自动检查参数对错填错、越界、冲突会直接弹窗提示不让错误参数保存端口自动跟着变如果改了位宽、深度等参数IP的端口宽度、接口规格会自动更新不需要你手动改连线。步骤5参数只对当前实例生效互不干扰IP的参数修改是只改当前这一个模块不会改动原始IP包1、同一个工程可以多次调用同一个IP每个IP可以设置不同参数互相不影响2、不同工程可以基于同一个IP配置成不同功能3、所有参数配置只保存在当前工程里不会破坏原始IP库。新手避坑参数配置常见禁忌1、不要强行配置不支持的参数比如只支持偶数分频的IP不要强行填奇数会直接功能异常2、改完参数必须刷新工程每次改完参数一定要重新生成Output Products否则软件还是运行旧参数3、没开放的参数不能乱改打包时隐藏的内部参数图形界面改不了要改只能改源码重新打包4、报错先恢复默认出现参数报错时先恢复默认值再慢慢微调快速定位问题。自建IP连线方式和官方IP完全一致分为自动、手动两种新手优先使用自动连线高效零出错1、自动智能连线推荐框选时钟、复位、其他IP和自建IP点击Run Connection Automation软件自动匹配信号、完成连线零出错、速度快。2、手动连线自定义信号自己定义的数据端口需要手动拖拽连线注意输入接输出、输出接输入方向不要接反。5.5 端口引出与顶层映射若需要将IP信号引出绑定FPGA硬件引脚完成板级调试操作步骤如下1、选中需要对外引出的信号线右键选择Make External2、可以双击端口改名方便后续引脚约束识别3、最后在XDC约束文件中绑定物理引脚即可对应到硬件电路。5.6 设计校验与错误修复IP添加、参数配置、连线完成后必须做全局校验排查隐性错误保障工程正常编译1、点击工具栏Validate Design检查整体设计2、所有红色Error错误必须全部修好端口悬空、参数越界、时钟缺失等3、普通黄色警告可忽略保证设计无致命问题即可。5.7 生成IP输出与顶层HDL文件必须步骤图形化IP模块无法直接编译下载必须生成硬件可识别的网表与顶层文件这是工程落地的必备步骤1、画布空白处右键 →Generate Output Products生成IP对应的硬件网表文件2、完成后再次右键 →Create HDL Wrapper生成顶层文件3、选择自动管理顶层文件软件自动设为工程顶层4、至此自建IP完全集成进工程可以正常综合、实现、生成比特流下载。5.8 自建IP迭代使用更新逻辑后后续优化IP功能、修复代码bug时无需重新创建IP直接迭代升级即可操作高效且不影响工程配置1、打开最初的IP源码工程修改代码并编译通过2、重新执行打包流程覆盖旧IP或升级版本号3、在使用该IP的工程中刷新IP库、重新生成输出文件4、工程自动更新为最新逻辑无需重新连线、重新配置参数。5.9 自建IP使用核心要点新手核心总结必记1、自建IP必须手动添加仓库路径工程才能识别2、所有参数修改只在图形界面操作不要手动改自动生成的代码3、改完源码必须重新打包否则工程永远运行旧逻辑4、一次封装、无限复用所有新工程添加路径即可使用。6 自定义IP跨工程复用方法自定义IP的核心优势就是一次封装、全工程通用跨工程复用无需重复写代码、重复打包步骤简单便捷1、记住你存放IP的文件夹路径2、打开需要使用该IP的新工程3、进入Tools → Settings → IP → Repository4、添加IP文件夹路径并确认5、刷新IP库即可直接搜索、添加、使用6、全程无需重新写代码、重新打包。7 自定义IP迭代更新方法IP功能迭代、bug修复、功能拓展无需重建支持直接升级迭代适配长期工程开发1、打开原始IP工程修改源码并编译无错2、重新打开IP打包工具3、直接重新打包覆盖旧版本4、可修改版本号区分新旧版本5、所有调用该IP的工程刷新IP库即可同步更新功能。8 注意事项1、源码规范要求用于打包的代码必须编译通过、无语法报错、无悬空端口、无不规范写法否则会直接打包失败这是IP封装的基础前提。2、端口命名简单标准端口名只用英文、下划线不要中文、空格、特殊符号避免软件识别失败。3、参数能少则少、够用就好只开放需要经常修改的参数固定功能参数隐藏减少误操作。4、路径绝对不能含中文工程路径、IP保存路径全部英文中文路径会导致加载失败、打包报错。5、不要手动改IP内核文件打包后的IP文件是工具自动生成的手动修改会导致版本错乱、编译报错改功能只改源码再重打包。6、跨芯片使用需要重校验在不同型号FPGA上使用该IP需要重新编译验证防止资源不匹配。7、成熟IP记得标注版本经常复用的IP建议标注版本方便区分升级前后功能避免工程出错。9 常见问题与解决方案问题1打包完成后IP Catalog搜不到自建IP解决确认已正确添加IP仓库路径执行Update IP Catalog刷新库核对打包过程无Error报错IP文件完整。问题2点击Package IP打包失败解决优先检查自己的源码是否有语法错、端口错、重复定义保证代码本身完全可编译。问题3添加IP后端口不对、端口缺失解决打包阶段手动修正时钟、复位端口类型重新打包覆盖即可。问题4改了源码工程功能没有变化解决必须重新打包IP、刷新工程、重新生成Output Products清除旧缓存。10 创建可配置分频器自定义IP本小节带大家只管感受一下极简、带参数配置的自定义IP过程帮助新手快速掌握自定义IP开发逻辑。10.1 功能说明本节用最基础的可配置分频器功能简单、逻辑清晰非常适合练手了解步骤和流程。实现通过修改IP参数任意调整时钟分频倍数最终驱动LED闪烁。模块端口定义clk_in输入系统时钟默认50MHzrst_n低电平同步复位clk_out分频输出时钟可配置参数DIV_NUM分频系数正整数默认2500000050MHz输入可分频得到1Hz时钟10.2 完整可编译Verilog源码新建Verilog文件命名为clk_div.v粘贴以下代码代码简洁规范、无语法错误、支持参数配置适配IP封装标准module clk_div #(parameter DIV_NUM25000000// 分频系数可外部配置)(input wire clk_in,// 输入时钟input wire rst_n,// 低电平复位output reg clk_out// 分频输出时钟);// 计数寄存器reg[24:0]cnt;// 计数器逻辑always (posedge clk_in or negedge rst_n)beginif(!rst_n)begin cnt25d0;clk_out1b0;endelseif(cntDIV_NUM-1)begin cnt25d0;clk_out~clk_out;// 时钟翻转endelsebegin cntcnt1b1;end end endmodule10.3 源码预处理IP封装必备1、将编写好的分频器代码添加到工程源文件2、先手动综合一次确认零语法报错3、保证模块功能独立、端口规范满足IP打包要求。10.4 分步封装为自定义IP严格对照前文标准打包流程对本分频器IP进行标准化配置确保一次打包成功步骤1启动封装向导Tools → Create and Package IP → Next → 选择Package your current project → 设置IP保存路径 → Next。步骤2IP基础信息配置可自定义分频系数的通用时钟分频IP支持任意偶数分频IP Nameuser_clk_divIP Display Nameclk_div_v1_0Version1.0VendoruserLibrarycommonCategoryClockDescriptionclk_div_v1_0步骤3端口属性修正clk_in手动标记为Clock时钟端口rst_n手动标记为Reset端口设置低电平有效clk_out普通输出端口默认配置步骤4参数对外开放自动抓取DIV_NUM参数勾选Enable对外开放设置默认值25000000参数描述为「时钟分频系数」供后续可视化修改。步骤5审核打包确认Status无Error点击Package IP完成自定义分频器IP封装。10.5 Block Design调用自定义IP我们首先需要将自建IP导入到我们的IP库中在其他需要调用自建IP的工程中打开IP Catalog在空白区域右键选择Add Repository。然后添加我们之前自建的IP。1、新建Block Design画布搜索并添加自制的user_clk_div分频IP2、添加官方时钟IP生成50MHz系统时钟3、自动连线完成时钟、复位匹配4、双击分频IP修改DIV_NUM参数即可改变闪烁频率5、将输出端口右键引出为顶层端口用于控制LED6、校验无报错、生成输出文件与顶层代码。10.6 板级验证1、编写XDC约束文件将LED对应顶层端口绑定FPGA物理引脚2、执行综合、实现、生成比特流3、下载后观察LED周期性闪烁代表自制IP功能完全正常。11 总结自定义IP是FPGA从“手写代码”进阶到“工程化模块化开发”的关键技能。简单理解就是把自己常用的代码打包成官方样式模块一次编写、随处拖拽、改参即用、终身复用。熟练掌握打包、调用、复用、迭代流程能极大简化工程结构、减少重复开发、降低bug率是FPGA和Zynq开发的必备能力。不要忘记关注我点赞收藏我会为你带来更多优质内容