7、重构分区(Reconfigurable Partition)创建:在Vivado中创建RP、分配动态模块、配置RP属性
好,咱们今天聊聊重构分区,也就是 RP 的创建。这部分我当年刚接触时也绕了不少弯路,说白了,RP 就是给动态模块预留的“空位”。你想想看,没有这个空位,动态模块往哪儿放?
7.1 什么是重构分区?
重构分区,英文叫 Reconfigurable Partition,简称 RP。它是 FPGA 芯片上的一块物理区域。这块区域在运行时可以被重新配置,而芯片的其他部分照常工作。
我个人习惯把 RP 理解成“插座”。静态逻辑是墙里的电线,动态模块就是各种电器。你插上风扇它就吹风,插上灯泡它就发光。但插座的位置是固定的,这就是 RP。
核心要点:RP 是物理区域,不是逻辑概念。它对应着芯片上具体的 LUT、FF、BRAM、DSP 等资源。
7.2 在 Vivado 中创建 RP
创建 RP 的步骤其实不复杂。我一般在工程初期就把 RP 规划好,免得后期改来改去。
7.2.1 创建 RP 的两种方式
| 方式 | 操作路径 | 适用场景 |
|---|---|---|
| 图形化 | Vivado 界面 → 打开网表 → 右键模块 → 选择“Create Reconfigurable Partition” | 小工程、快速验证 |
| Tcl 命令 | 在 Tcl Console 中执行命令 | 自动化流程、大型工程 |
我个人更推荐用 Tcl 命令。为什么呢?因为可重复性好。你这次点鼠标创建了,下次换个版本还得再点一遍。用脚本的话,一键搞定。
7.2.2 Tcl 命令示例
# 创建一个名为 u_dynamic_region 的 RP
create_reconfigurable_partition -name u_dynamic_region \
-cell [get_cells u_dynamic_region] \
-partition_type dynamic
这里要注意,-cell 参数指定的是你要设为动态的模块实例。这个模块在 RTL 里已经存在了,只是现在告诉 Vivado:“嘿,这个模块以后要动态换。”
7.3 分配动态模块
创建好 RP 之后,下一步就是分配动态模块。说白了,就是告诉 Vivado:这个 RP 里可以放哪些版本的模块。
每个动态模块可以有多个实现版本。比如你有一个图像处理模块,白天用高清版,晚上用低功耗版。这两个版本都放在同一个 RP 里,但不同时运行。
7.3.1 添加动态模块
# 为 RP 添加两个动态模块版本
add_reconfigurable_module -name u_dynamic_region \
-cell [get_cells u_dynamic_region] \
-module_name image_high_perf
add_reconfigurable_module -name u_dynamic_region \
-cell [get_cells u_dynamic_region] \
-module_name image_low_power
嗯,这里有个坑。我曾经犯过一个错误:两个模块的端口定义不一致。结果编译时一堆错误。所以,所有动态模块的端口必须完全一样——名字、方向、位宽,一个都不能差。
注意:动态模块的顶层端口必须与 RP 的接口完全匹配。否则 Vivado 会报错,而且错误信息不太友好,排查起来很头疼。
7.4 配置 RP 属性
RP 的属性配置很关键。它决定了这个分区在物理上长什么样,以及它和静态逻辑怎么通信。
7.4.1 主要属性
- 分区类型(Partition Type):动态还是静态。RP 必须设为 dynamic。
- 资源范围(Range):指定 RP 占用的物理资源。可以是 Pblock 形式。
- 接口模式(Interface Mode):决定 RP 与静态逻辑的连接方式。常见的有 slice、tile 等。
- 复位行为(Reset Behavior):重构时是否复位内部寄存器。
7.4.2 设置 Pblock
Pblock 是 RP 的物理边界。没有 Pblock,Vivado 不知道把动态模块放在芯片的哪个位置。
# 创建一个 Pblock 并分配给 RP
create_pblock pblock_dynamic
resize_pblock pblock_dynamic -add {SLICE_X0Y0:SLICE_X10Y10}
add_cells_to_pblock pblock_dynamic [get_cells u_dynamic_region]
这个例子把 RP 限制在了一个 11x11 的 SLICE 阵列里。实际项目中,你需要根据模块的资源消耗来估算大小。我一般会多留 20% 的余量,免得后期加功能时放不下。
7.5 知识体系图
下面这张图总结了 RP 创建的核心流程。你可以把它当作操作清单来用。
小技巧:创建 RP 时,我习惯先用 report_utilization 看看模块的资源占用。然后根据这个数据来设定 Pblock 的大小。别凭感觉猜,数据说话最靠谱。
7.6 避坑指南
最后,分享几个我踩过的坑:
- 端口不匹配:动态模块的端口必须和 RP 接口完全一致。我吃过一次亏,两个模块的端口顺序不同,结果编译通过但运行时崩溃。
- Pblock 太小:如果 Pblock 范围不够大,布局布线会失败。我一般会留 30% 的余量。
- 忘记设置 Partition Type:创建 RP 后一定要检查属性。我曾经忘了设成 dynamic,结果折腾了半天才发现。
嗯,RP 创建这部分就这些内容。记住,RP 是动态重构的基石,基础打好了,后面的路就顺了。
公众号:蓝海资料掘金营,微信deep3321