版块:FPGA

新手跑 Timing Closure 经常"越修越差",根源是没有按依赖顺序走。这篇是我们在 7 系列/MPSoC 项目上反复验证过的流程,按顺序做,收敛过程可解释、可回归。

第 0 步:先确认约束是真的

在动任何逻辑之前:

1. 时钟约束齐全:create_clock 是否覆盖所有 PLL/MMCM 输出(推导时钟别手填)、input/output delay 是否按芯片外真实时序算(对端 FPGA/ADC 的 tsu+tco+板级延迟);
2. false path 和 multicycle 有没有滥标——每个 multicycle 都是借来的时间,标错一处就是硅片上的隐性 bug;
3. I/O standard 和 VCCO 一致。

工具给的 WNS 建立在错误约束上毫无意义。花半天审约束,省三天的瞎调。

第 1 步:分类病理,不要一上来改 RTL

打开时序报告,把 failing path 按形态归三类,处理路径完全不同:

- 路由绕远型(logic level 少但 route 段占大头):先动 CMT 区域约束/pblock,别动代码;
- 逻辑深度型(LUT 级数长):算术结构问题,见第 2 步;
- 高扇出/拥塞型(net fanout 大、route 时间发散):寄存器复制、提升 fanout 阈值、region 调整。

第 2 步:砍逻辑深度(数据通路优先)

1. 加减法器链改树状、乘加用 DSP48 硬核的 MREG/PREG 打一拍再出——让算术运算消失在硬核流水里是收益最大的一步;
2. 长比较器/计数器的进位链:超过 ~16 位考虑分块并行比较;
3. 状态机改 one-hot 或分段(sequential → Moore 化输出)减少控制深度;
4. 地址计算提前一拍拍住:FSM 发 read 命令那拍就把 addr 锁好。

第 3 步:重定时(retiming)用对而不是滥用

register retiming 工具对 DSP/滤波/矩阵流水效果好。但注意:

- 含 CE 语义(enable-based clock gating)的路径重定时会把 enable 搬位导致功耗上涨 15%+,看综合报告再放行;
- 异步复位域跨 retiming 边界的问题,工具不会报 warning,review RTL reset 结构后再开。

第 4 步:CDC——先除险,再谈收敛

跨时钟域路径的 timing report 不可信(工具按各自时钟算 metstable 窗口)。正确动作:

1. 用静态检查(CDC lint)列出所有 crossing,逐条确认结构:打两拍、握手、异步 FIFO 格雷码;
2. 单 bit 控制信号 → 同步器 + 保证脉冲宽度 > 源域 2 周期;
3. 多 bit 总线 → 格雷码/握手/异步 FIFO,裸同步打拍必出"新旧混叠";
4. 综合后用 set_max_delay -datapath_only 或 create_clock_group -asynchronous 二选一,别又 asyc 又 max_delay 互相抵消。

第 5 步:hold 修复的正确姿势

高主频或 SSI 器件上 hold violation 常见:

1. hold 修复是插 buffer 链,工具自动做。人工介入的点:修复后布线拥塞、hold buffer 占掉的 LUT 让 setup 再恶化——看 rpt 的 correlation:修 hold 时 setup 是否劣化;
2. 100% 的 hold 违例来自"快路径":同一条路径 setup 修好了、hold 又破——检查时钟树 skew 和共线对;
3. 输出 I/O 的 hold(对端采样窗口)优先从板级(改时钟树/输出延迟约束)解决,芯片内插延迟治标。

收尾:建立基线回归

WNS/TNS 每天记录进表格,每次只允许一类改动。收敛不是玄学,是"每步都有数据背书"。

你们团队有没有"约束 review checklist"沉淀?欢迎回帖分享条目,我汇总成一篇合订本。