4. 创建与配置设计分区
在上一节完成增量编译规划之后,真正落到 Quartus 工程里的第一步,是把“计划中的模块边界”变成工具能够识别的 Design Partition(设计分区)。Design Partition 是 Quartus 增量编译的基本单位:只有被声明为分区的层次,才会被单独综合、单独布局布线,并在后续编译中保留其网表与布局结果。没有分区,就没有增量;分区划错,增量编译的收益会大打折扣,甚至出现“每次全编译”的假增量现象。
本节围绕四件事展开:如何创建分区、如何指定分区类型、空分区与顶层分区如何处理、以及如何导出分区层次供团队复用。
一、创建 Design Partition 的两种入口
Quartus 中创建分区主要有两条路径,二者等价,只是操作位置不同。
第一条路径在 Project Navigator → Hierarchy 标签页中完成。展开工程层次树,右键点击目标模块实例,选择 Design Partition → Set as Design Partition。此时该实例图标上会出现一个分区标记,表示它已成为独立分区。
第二条路径在 Assignments → Design Partitions Window 中完成。打开该窗口后,可以看到当前工程所有已声明的分区列表,每一行对应一个分区实例,列包括 Partition Name、Hierarchy Path、Type、Netlist Type、Fitter Placement、Routing 等。在这里可以新增、删除、修改分区属性,是分区管理的“总控台”。
需要特别强调:分区必须落在实例(instance)上,而不是模块定义(module)上。同一个模块被多次例化时,每个实例都可以独立成为分区,也可以只让其中一个成为分区。例如一个 fir_filter 模块在顶层被例化两次,分别命名为 u_fir_a 和 u_fir_b,那么可以只把 u_fir_a 设为分区,而 u_fir_b 保持普通逻辑。这一点在规划阶段就要想清楚,否则后期改名会导致分区路径失效。
二、分区类型(Partition Type)的选择
Design Partitions Window 中的 Type 列决定该分区在增量编译中的角色,常见取值如下:
- Default:普通分区,参与综合与布局布线,可被增量复用。绝大多数功能模块使用此类型。
- Top:顶层分区,代表整个设计的顶层,通常只有一个,且不可删除。
- Empty:空分区,用于占位,不包含实际逻辑,常用于预留接口或后续替换。
- Reconfigurable:用于部分重配置流程,普通增量编译工程一般不使用。
选择类型时遵循一个原则:只有需要独立保留编译结果、且边界稳定的模块才设为 Default 分区。如果一个模块每次编译都会改动,把它设为分区反而增加管理成本,因为每次都要重新综合该分区。通常建议把“接口稳定、内部逻辑可能迭代”的模块设为分区,例如通信协议栈、算法加速核、视频处理流水线等。
三、空分区与顶层分区的处理
空分区(Empty Partition) 是一个特殊但实用的机制。它的作用是:在顶层保留一个分区位置,但该分区内部暂时没有逻辑,或者逻辑由后续版本填充。空分区在编译时会被当作黑盒处理,不参与综合。使用空分区时要注意两点:
- 空分区的端口必须与顶层连接一致,否则编译会报端口不匹配错误。
- 空分区不能直接参与时序分析,因为它没有内部网表。若需要时序收敛,必须先用真实逻辑填充。
顶层分区(Top Partition) 是 Quartus 自动创建的分区,代表整个设计的顶层。它不能被删除,也不能被设为 Empty。顶层分区的作用是承载所有子分区的连接关系。当子分区被增量复用后,顶层分区仍然需要重新布局布线,因为子分区之间的连线可能变化。因此,顶层分区的稳定性直接影响增量编译的收益:如果顶层端口或子分区之间的连接频繁改动,即使子分区被复用,顶层仍需大量重布线,整体编译时间下降有限。
四、分区层次导出与复用
当分区配置完成后,可以把分区层次结构导出为 .qpartition 文件,供其他工程或团队成员复用。操作路径为:Project → Export Design Partition,选择导出路径并命名。导出的文件记录了分区名称、层次路径、类型、网表类型等属性。
导入时使用 Project → Import Design Partition,选择 .qpartition 文件即可。导入后,Quartus 会按照文件中的层次路径在目标工程中查找对应实例,并自动设置分区属性。如果目标工程的层次结构与导出时不一致,导入会失败或部分失败,因此导出前应确保层次命名规范统一。
下面这张图展示了从工程层次到分区配置、再到导出复用的完整关系。图中左侧是层次树中的实例,中间是 Design Partitions Window 中的属性列,右侧是导出文件与复用目标。
五、配置检查与常见问题
分区配置完成后,建议在 Design Partitions Window 中逐项核对以下内容:
| 检查项 | 正确做法 | 常见错误 |
|---|---|---|
| 分区路径 | 与层次树中的实例名完全一致 | 模块改名后未更新分区,导致分区失效 |
| Type | 功能模块用 Default,顶层用 Top,占位用 Empty | 把顶层误设为 Default,导致顶层被当作普通分区 |
| Netlist Type | 需要复用布局时选 Post-Fit | 选 Post-Syn 后期望复用布局,实际仍需重新布局 |
| 端口一致性 | 空分区端口与顶层连接匹配 | 空分区端口缺失,编译报端口不匹配 |
一个典型的配置片段如下,展示了在 .qsf 文件中分区相关设置的实际写法:
set_global_assignment -name PARTITION_NETLIST_TYPE POST_FIT -section_id u_dsp_core
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id u_dsp_core
set_global_assignment -name PARTITION_TYPE DEFAULT -section_id u_dsp_core
set_global_assignment -name PARTITION_NETLIST_TYPE POST_FIT -section_id u_fir_a
set_global_assignment -name PARTITION_TYPE DEFAULT -section_id u_fir_a
set_global_assignment -name PARTITION_TYPE EMPTY -section_id u_empty_slot
这些设置与 Design Partitions Window 中的列一一对应。理解 .qsf 中的写法,有助于在脚本化流程或版本管理中批量维护分区配置。