这一篇在干嘛?
比赛项目写到最后,你一定攒了不少可复用的模块:串口收发、FIFO、按键消抖……每次都靠复制粘贴
.v文件来复用,既乱又容易改出 bug。这一篇讲怎么用 Module Packager(SWUG507)把这些模块打包成正式 IP,让它们出现在 TD 的 IP Catalog 里,点鼠标就能例化。同系列其他篇目见 模块打包器目录页。
mpack 是什么、能干嘛
Module Packager(下文简称 mpack)是安路官方提供的 IP 打包工具,作用只有一件事:把你写的 RTL 代码打包成 IP,供安路 EDA 工具(TD)直接使用。它主要能做三件事:
- 自动解析 RTL,识别 module 的端口;
- 解析 module 的 parameter,把它们变成 IP 的可配置参数;
- 支持总线(bus)绑定,比如把一组 AXI 信号绑成一条总线。
先认清它的边界:三个硬性限制
上手之前必须知道 mpack 目前不支持什么,免得白忙一场:
| 限制 | 说明 | 应对办法 |
|---|---|---|
| 只支持 Verilog | VHDL、SystemVerilog 正在开发中 | 用纯 Verilog 写模块 |
| 只支持单个 RTL 文件 | 一个 IP 只对应一个 .v 文件 | 把多个文件的内容手动合并到一个文件里再打包 |
| 不支持约束文件 | 无法随 IP 添加 SDC 等约束 | 约束在 TD 工程里单独添加 |
它在 TD 的 RTL 处理流程里处于什么位置

在 TD 里使用你自己的 RTL,共有三条路:
- ① 直接添加源文件:把
.v文件加进 TD 工程,最原始的方式,复用全靠复制粘贴; - ② IP Catalog 例化单个 IP:可在 IP 页面改配置,但 IP 之间的连线要手动写 RTL;
- ③ Design Integrator 例化多个 IP:自动生成 IP 间连接的 RTL,适合搭”积木”式设计。
mpack 打包出来的 IP 属于后两种用法。注意区分两个长得像的名字:
- Module Packager:开放给用户用的 IP 打包工具,是 IP Packager 的简化版;
- 打包后在 IP Catalog 的分类不同:mpack 的产物显示在 User IP 分类下,官方工具打包的显示在 Primitive IP 和 Soft IP 分类下。
常见坑:别把 mpack 当成万能封装器
它是”简化版”,参数传递只支持
parameter形式,且十六进制参数会被自动转成十进制显示。如果你的模块依赖`include的头文件宏、localparam需要暴露、或者多文件互相引用,得先改造代码结构,否则打包出来的 IP 参数和端口会对不上。
第一步:新建 mpack 工程
mpack 不是独立软件,它藏在 TD 菜单里。打开路径:Tools → Module Packager。
打开后,File → Create Project 新建工程,需要填两样东西:
- 工作空间目录:选一个目录作为 IP 仓库目录。关键点:这个目录以后可以直接添加到 IP Catalog,让打包出来的 IP 被 TD 识别,所以建议单独建一个专用目录,比如
D:/my_ip_repo/; - IP 名称:被打包 IP 的名字。每个 IP 会新建一个子目录,目录名就是 IP 名。

点击 Finish 后进入 IP 打包页面,可以看到 IP 名称和版本号(Version Identifier)。

常见坑:工作空间目录选错位置
工作空间目录就是以后的 IP 仓库根目录,不要选到单个 IP 内部去。手册第 3 章明确说:添加到 IP Catalog 的是包含很多 IP 的仓库路径,而不是单个 IP 的路径。路径选浅了,后面整个仓库都挂不上。
第二步:导入 RTL 文件
mpack 对 RTL 语法有明确要求:参数传递只支持 parameter 形式,总线支持 AXI 等常见总线类型。
在 mpack 页面左侧点开 FileSets 下的子页面(名称为 IP名称_files),在右侧空白处右键 → Add File,选择要打包的 Verilog 文件,然后在 top module name 输入框里填 IP 的 module 名称。

这一步做对了,切换到 ports 子页面就能看到 module 下的所有端口——这是判断”导入成功”最直观的信号。

常见坑:top module 填错或文件里有多个 module
如果文件里有多个 module,mpack 只处理你填的 top module。端口列表是空的或者缺端口,第一件事就是检查 top module name 拼写,以及文件里是不是混入了别的 module 定义。
第三步:检查参数和端口
这一步没有”操作”,只有”核对”:把界面上自动生成的参数、端口与你的 RTL 源码逐项比对,不一致就根据错误信息修改。
两个必须知道的规则:
- 十六进制参数自动转十进制:RTL 里写
parameter WIDTH = 8'h10,界面上会显示十进制的 16;在 IP 例化页面也只支持输入十进制数字; - 该规则只针对整数:字符串、浮点类参数不受影响,按原样显示和输入。
常见坑:例化时填十六进制报错
很多同学习惯在例化页面填
8'hFF,结果报错。记住:整数参数一律填十进制,想填FF就填255。
第四步:绑定 bus 总线
如果你的模块带总线接口(比如 AXI-Lite),需要在 businterfaces 页面把 RTL 端口(physical port)和总线协议定义的端口(logic port)绑定起来。两个先决常识:
- bus 里的 clock 和 reset 信号无需绑定(它们可以单独绑成 clock 总线和 reset 总线);
- 当前无法自动绑定,logic port → physical port 的对应关系要逐个手动指定。
操作流程:
- 依次点击 businterfaces → Add,进入 bus 绑定页面;
- 填写 bus 的名称、类型和方向,提交后 businterfaces 下会生成以 bus 名命名的子页面;
- 在子页面的 portMaps 中,为每个 logicPort 选择对应的 physicalPort——前者是总线协议定义的端口名,后者是你 module 里的输入输出端口名。

三个容易翻车的细节:
| 项目 | 要求 | 说明 |
|---|---|---|
| bus 名称 | 按规范命名,推荐 S_AXI_LITE 这种格式 | 大写下划线,前缀表明方向(S_ 从机 / M_ 主机) |
| bus 类型 | 必须选对 | mpack 支持一组常见总线类型,在类型下拉框里能看到 |
| bus 方向 | master 或 slave | 你的模块是总线的哪一端就选哪个 |

绑定完成后逐行检查 portMaps 对应关系。绑定错了不会立刻报错,而是等你例化时才发现信号接反,排查成本高得多。
常见坑:clock/reset 想绑进数据总线
手册明确说 clock 和 reset 不需要绑进普通 bus。如果强行绑进去,协议检查可能通不过。正确做法是不绑,或单独绑成 clock/reset 总线。
保存、修改与重新打开工程
以上步骤完成后,File → Save Project 即完成 IP 打包。工程文件是 IP 目录下的 .pack 文件。
打包后发现 IP 有误怎么办?不需要从头再来:
- 在 mpack 中选择打开 IP 工程;
- 在文件夹选择窗口找到该 IP 的工程文件夹,选中对应的
.pack文件点”打开”; - 修改完成后再次 Save Project 即可。
常见坑:改了 RTL 却不改打包工程
打包的 IP 不会自动跟随你的
.v文件更新。源码改了端口或参数之后,必须重新打开.pack工程更新端口/参数映射并重新保存,否则 IP Catalog 里的还是旧版本接口。
把 IP 加入 IP 仓库并在 TD 中例化
打包好的 IP 不会自己出现在 TD 里,需要把仓库路径告诉 TD:
- TD 菜单栏 Tools → IP Catalog;
- 在 IP Catalog 页面选择 UserIP 分类,右键 → Add IP Depot;
- 选择第 2 章里那个工作空间目录,完成设置。

设置完成后,该仓库下的所有 IP 都会显示在 IP Catalog 中。它们在使用上和系统 IP 没有任何区别:搜索、双击例化、改参数、连到 Design Integrator,全部一样。还有两条省事规则:
- 在 IP Catalog 里设置好仓库路径后,Design Integrator 会自动继承,不用重复添加;
- 仓库路径是”装着一堆 IP 的目录”,可以直接分享给队友——团队里一个人打包,全队受益。
最后一步:在 TD 里例化这个 IP(双击 IP Catalog 中的条目、配置参数、生成例化代码),具体操作参考 TD User Guide。
通关标准:
- 从零打包一个带
parameter的 Verilog 模块,并在 IP Catalog 的 UserIP 分类下看到它;
- 为带总线接口的模块完成 bus 绑定,portMaps 对应关系逐项核对无误;
- 修改一次源码并重新打开
.pack工程完成 IP 更新,仓库路径已共享给队友可复用。
为什么我 Add File 之后 ports 页面是空的?
大概率是 top module name 没填或填错。mpack 靠这个输入框定位要解析的 module,填对之后 ports 子页面才会列出全部端口。另外确认文件是纯 Verilog 且只有一个待打包 module。
十六进制的 parameter 在例化页面怎么填?
mpack 会把十六进制参数自动转成十进制显示,例化页面也只接受十进制整数(字符串和浮点参数不受影响)。RTL 里的
8'hFF对应例化时填255。
bus 绑定时 clock 和 reset 要绑吗?
不需要。总线协议里的 clock/reset 信号免绑,可以单独绑成 clock 总线和 reset 总线。portMaps 里只处理数据、地址、握手等协议信号。
队友想用我打包的 IP,他把单个 IP 目录加进 IP Catalog 却看不到,为什么?
Add IP Depot 添加的应该是仓库根目录(包含很多 IP 的那个工作空间目录),而不是某个 IP 的子目录。把你的工作空间目录整个发给他,添加后仓库下所有 IP 都会出现在 IP Catalog 中。
mpack 打包的 IP 和官方 IP 在 TD 里用起来有区别吗?
功能上没有区别:都能在 IP Catalog 例化、都能进 Design Integrator 自动连线。唯一差别是分类位置——mpack 的 IP 显示在 User IP 分类下,官方的显示在 Primitive IP 和 Soft IP 分类下。