目录
- 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 参数配置(实现可配置IP)
- 4.6 审核与最终打包
- 5 自建IP完整使用教程(Block Design工程集成)
- 5.1 加载自建IP到当前工程(首次使用必做)
- 5.2 在Block Design中添加自建IP
- 5.3 自建IP参数可视化配置(精细化实操)
- 5.5 端口引出与顶层映射
- 5.6 设计校验与错误修复
- 5.7 生成IP输出与顶层HDL文件(必须步骤)
- 5.8 自建IP迭代使用(更新逻辑后)
- 5.9 自建IP使用核心要点
- 6 自定义IP跨工程复用方法
- 7 自定义IP迭代更新方法
- 8 注意事项
- 9 常见问题与解决方案
- 10 创建可配置分频器自定义IP
- 10.1 功能说明
- 10.2 完整可编译Verilog源码
- 10.3 源码预处理(IP封装必备)
- 10.4 分步封装为自定义IP
- 10.5 Block Design调用自定义IP
- 10.6 板级验证
- 11 总结
1 概述
自定义IP(Custom 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_div);
2、IP Display Name:界面展示名称,可填写中文,直观标注模块功能;
3、Version:IP版本号,首次打包默认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 → Settings;
2、左侧展开IP → Repository,点击加号添加路径;
3、选择你存放IP的整个文件夹(不要选单个文件);
4、点击OK保存;
5、在左侧IP Catalog右键选择Update IP Catalog刷新IP库;
6、刷新后能搜到你的IP,代表加载成功。
注意:每个新工程首次使用该自建IP都需要添加一次仓库路径;建议将常用IP固定路径,避免重复配置。
5.2 在Block Design中添加自建IP
1、新建或打开已有的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 External;
2、可以双击端口改名,方便后续引脚约束识别;
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 → Repository
4、添加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:输入系统时钟(默认50MHz)
rst_n:低电平同步复位
clk_out:分频输出时钟
可配置参数:DIV_NUM(分频系数,正整数,默认25000000,50MHz输入可分频得到1Hz时钟)
10.2 完整可编译Verilog源码
新建Verilog文件,命名为clk_div.v,粘贴以下代码,代码简洁规范、无语法错误、支持参数配置,适配IP封装标准:
module clk_div #(parameter DIV_NUM=25000000// 分频系数,可外部配置)(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 cnt<=25'd0;clk_out<=1'b0;endelseif(cnt==DIV_NUM-1)begin cnt<=25'd0;clk_out<=~clk_out;// 时钟翻转endelsebegin cnt<=cnt+1'b1;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。
步骤2:IP基础信息配置
可自定义分频系数的通用时钟分频IP,支持任意偶数分频
- IP Name:user_clk_div
- IP Display Name:clk_div_v1_0
- Version:1.0
- Vendor:user
- Library:common
- Category:Clock
- Description:clk_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分频IP;
2、添加官方时钟IP,生成50MHz系统时钟;
3、自动连线完成时钟、复位匹配;
4、双击分频IP,修改DIV_NUM参数即可改变闪烁频率;
5、将输出端口右键引出为顶层端口,用于控制LED;
6、校验无报错、生成输出文件与顶层代码。
10.6 板级验证
1、编写XDC约束文件,将LED对应顶层端口绑定FPGA物理引脚;
2、执行综合、实现、生成比特流;
3、下载后观察LED周期性闪烁,代表自制IP功能完全正常。
11 总结
自定义IP是FPGA从“手写代码”进阶到“工程化模块化开发”的关键技能。简单理解就是:把自己常用的代码打包成官方样式模块,一次编写、随处拖拽、改参即用、终身复用。熟练掌握打包、调用、复用、迭代流程,能极大简化工程结构、减少重复开发、降低bug率,是FPGA和Zynq开发的必备能力。
不要忘记关注我,点赞收藏,我会为你带来更多优质内容!