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 创建核心流程 步骤 1:创建 RP 选择模块实例 设为动态分区 步骤 2:分配模块 添加动态模块版本 端口必须一致 步骤 3:配置属性 设置 Pblock 配置接口模式 三种创建方式:图形化界面 | Tcl 命令 | 脚本自动化 关键属性配置 属性 说明 推荐值 Partition Type 分区类型 dynamic Resource Range 物理资源范围 Pblock 指定 Interface Mode 接口连接模式 slice / tile Reset Behavior 重构时复位行为 建议使能复位

小技巧:创建 RP 时,我习惯先用 report_utilization 看看模块的资源占用。然后根据这个数据来设定 Pblock 的大小。别凭感觉猜,数据说话最靠谱。

7.6 避坑指南

最后,分享几个我踩过的坑:

  • 端口不匹配:动态模块的端口必须和 RP 接口完全一致。我吃过一次亏,两个模块的端口顺序不同,结果编译通过但运行时崩溃。
  • Pblock 太小:如果 Pblock 范围不够大,布局布线会失败。我一般会留 30% 的余量。
  • 忘记设置 Partition Type:创建 RP 后一定要检查属性。我曾经忘了设成 dynamic,结果折腾了半天才发现。

嗯,RP 创建这部分就这些内容。记住,RP 是动态重构的基石,基础打好了,后面的路就顺了。


公众号:蓝海资料掘金营,微信deep3321