3. 大型FPGA工程的分区规划原则

在 Quartus 增量编译(Incremental Compilation)流程中,分区(Partition)不是简单地把工程切成几块,而是把设计映射为“可独立综合、可独立布局布线、可被复用或替换”的物理实现单元。分区规划一旦确定,后续的 LogicLock 区域、Fitter 约束、增量编译的保留/复用策略都会围绕它展开。因此,分区规划是增量编译能否真正节省编译时间、稳定收敛时序的前提。本节围绕四条原则展开:按功能模块划分、按时钟域划分、按物理区域划分,以及分区粒度与层次化设计策略。

一、按功能模块划分:让分区边界与设计意图一致

最自然的分区依据是设计的功能层次。Quartus 的增量编译以设计层次(Design Partition)为单位,通常把顶层下的一个子模块声明为一个分区。例如一个视频处理工程可划分为 video_in、scaler、frame_buffer_ctrl、video_out 四个分区,每个分区对应一个独立的功能块。

按功能划分的关键在于“边界稳定”。分区边界应尽量落在寄存器到寄存器的路径上,避免把组合逻辑跨分区切开。若一个分区输出直接驱动另一个分区的组合逻辑,Fitter 在增量编译时仍需重新优化跨分区路径,复用效果会明显下降。实践中的做法是:在分区输出端口处插入一级寄存器,使分区之间形成“寄存器—寄存器”的清晰边界。例如:

// 分区边界处插入输出寄存器,稳定跨分区时序
always @(posedge clk_video) begin
    scaler_data_out <= scaler_data_int;
    scaler_de_out   <= scaler_de_int;
end

这样,scaler 分区被替换或重新编译时,其输出时序特性变化被限制在分区内部,不会波及下游分区。

二、按时钟域划分:把跨时钟域路径隔离在分区之外

大型 FPGA 往往包含多个时钟域,如 clk_100m、clk_200m、clk_video、clk_ddr。跨时钟域(CDC)路径的时序分析复杂,且对布局布线敏感。如果同一分区内混合多个时钟域,增量编译时该分区几乎无法被有效复用,因为任何一处改动都可能影响多个时钟域的时序。

更合理的做法是让每个分区尽量工作在单一主时钟域下,把 CDC 同步器(如双触发器同步、异步 FIFO)单独划为一个“边界分区”或放在顶层。这样,各时钟域内部的分区可以独立编译、独立锁定,CDC 路径作为固定接口被保留。下图给出一个按时钟域与功能混合划分的示意:

分区规划:功能 × 时钟域 × 物理区域 clk_video 域 clk_200m 域 clk_ddr 域 video_in 分区 P1 · 输入采集 scaler 分区 P2 · 缩放 video_out 分区 P3 · 输出 frame_buffer_ctrl 分区 P4 · 帧缓存控制 ddr_scheduler 分区 P5 · 调度 ddr_phy_if 分区 P6 · 物理接口 ddr_calib 分区 P7 · 校准 cdc_sync 边界分区 · 跨时钟域同步 物理区域约束(LogicLock): P1/P2/P3 → Region_A P4/P5 → Region_B P6/P7 → Region_C

图中每个分区都落在单一主时钟域内,cdc_sync 作为边界分区集中处理跨域信号。这样,当 scaler 需要修改时,只需重新编译 P2,其余分区保持锁定,编译时间可从全编译的数十分钟缩短到几分钟量级。

三、按物理区域划分:让分区与器件资源对应

FPGA 的物理资源分布并不均匀:不同 Bank 的时钟资源、DSP 列、BRAM 列、收发器位置各不相同。分区规划必须考虑目标器件的物理布局,否则会出现“逻辑上合理、物理上无法收敛”的情况。

Quartus 通过 LogicLock 区域把分区约束到指定物理范围。例如在 Stratix 10 或 Arria 10 上,可以把高速接口相关分区约束到靠近收发器 Bank 的区域,把 DSP 密集型分区约束到 DSP 列附近。一个实用的经验是:分区面积应留出 15%~25% 的余量,避免后续小改动导致区域溢出、被迫重新布局。

物理区域划分还要注意时钟资源。若一个分区需要用到全局时钟网络,应确保该区域内有可用的全局时钟引脚或时钟控制块。否则 Fitter 可能被迫使用局部时钟,带来额外的偏斜和时序风险。

四、分区粒度与层次化设计策略

分区粒度是规划中最难权衡的问题。粒度过粗,一个分区包含大量逻辑,任何小改动都会触发整个分区重编译,增量收益有限;粒度过细,分区数量过多,跨分区路径增多,Fitter 的优化空间被切碎,反而可能降低整体质量。

实践中可参考以下经验区间:

设计规模建议分区数量单分区逻辑量参考典型粒度
中等规模(50K~200K LE)4~8 个10K~40K LE功能模块级
大型(200K~500K LE)8~15 个20K~60K LE功能模块 + 时钟域
超大型(>500K LE)15~30 个30K~80K LE层次化子模块

层次化设计策略的核心是“顶层薄、子模块厚”。顶层只保留分区实例化、CDC 同步器和少量胶合逻辑,把绝大部分功能下沉到子模块分区中。这样顶层几乎不变,增量编译时只需替换发生变化的子分区。

分区规划检查要点:
  • 分区边界是否落在寄存器输出端,避免组合逻辑跨分区;
  • 每个分区是否尽量处于单一主时钟域;
  • LogicLock 区域是否留出 15%~25% 资源余量;
  • 分区数量是否与设计规模匹配,避免过粗或过细;
  • 顶层是否足够薄,CDC 是否集中管理。
常见误区:把分区边界切在组合逻辑中间,或让一个分区横跨三个时钟域。这两种做法都会使增量编译的“保留”失效,Quartus 会强制重新布局布线整个分区甚至相邻分区,编译时间不降反升。

分区规划完成后,应在 Quartus 的 Assignments → Design Partitions Window 中逐一确认分区类型(Default、Reconfigurable、Empty 等)和保留级别,并结合 LogicLock Region 设置物理约束。建议在首次全编译后导出分区布局(Export Partition),作为后续增量编译的基线。只有分区边界稳定、物理区域合理、粒度适中,增量编译才能在大型 FPGA 工程中真正发挥“改一处、编一块”的价值。