FPGA 进阶 43:时序收敛实战案例——WNS 违例怎么一步步收
本文是
fpga/进阶层第 47 篇。理论看 STA、手段看时序收敛方法、约束看约束实战和时序例外;这篇是串起来的实战流程和案例。
一、五步标准动作

二、现象→根因→手段对照表
| 报告现象 | 根因 | 手段 |
|---|---|---|
| logic levels >12~15,逻辑延迟主导 | 组合链太长 | 插流水寄存器(最有效)/retiming |
| 同一 net 扇出数千~数万,大量路径违例 | 高扇出拖慢整片 | 寄存器复制/MAX_FANOUT/phys_opt |
| 布线延迟占比高、逻辑分散 | 布局距离远 | Pblock 聚拢关键模块、物理优化 |
| 违例路径跨两个异步钟 | 假违例 | 同步器 + set_clock_groups(见多时钟) |
| IP 边界路径违例 | IP 流水级没开 | 配 IP 内部流水/接口寄存器 |
| TNS 巨大、普遍差一点 | 频率过高/策略保守 | 降频或提策略(Explore/Performance) |
| 拥塞区反复违例 | 布线资源紧张 | 降局部密度、Pblock、复制 |
| WHS 大面积负 | 时钟偏斜/异步漏切 | 修时钟结构、补异步约束 |
三、案例片段
案例 A:长运算链。 乘法结果经大判优 mux 再累加,违例路径 14 级 LUT、WNS −1.8ns。→ 判优链中间插一级寄存器,切两段 7 级,WNS +0.6ns;控制/valid 同步打一拍。
案例 B:高扇出启动信号。 start 脉冲直连 1.8 万个使能端,TNS 巨大。→ RTL 加 (* max_fanout=2000 *) 让综合复制 10 份分发,布线后 TNS 归零。
案例 C:假违例。 恢复钟域到系统钟大量违例——查设计已有异步 FIFO,约束漏分组 → 补 set_clock_groups,违例消失(硬件没问题)。
案例 D:IP 接口。 FFT IP 输出到用户逻辑违例 → IP 配置打开输出流水寄存器,路径缩到 IP 内部寄存器到用户寄存器一级。
案例 E:拥塞。 大位宽 crossbar 区域反复违例 → 关键模块 Pblock 聚拢 + 实现策略换 Performance_Explore + phys_opt 复制高扇出,收敛。
四、纪律清单
- [ ] 先分析后动手,最差路径展开看级数/扇出/布线;
- [ ] 一次只改一个变量,重跑对比 WNS/TNS;
- [ ] 不用 false_path 消真违例(仅真异步/静态路径);
- [ ] 建立(slow corner)保持(fast corner)双签;
- [ ] 收敛后再谈提频,留 5%~10% 时序裕量给温度/电压波动;
- [ ] 改动后回归功能仿真(打拍改变延迟)。
相关与延伸
一句话总结
时序收敛实战五步:看形态(TNS 大=面问题/几条=点问题)→ 展开最差路径看起点终点、逻辑级数、布线占比、扇出 → 按根因施策 → 一次改一个变量重跑验证 → 双角点建立保持都签。根因手段对照:逻辑级数深(>12 级 LUT)就插流水寄存器切链(收益最大,配 retiming);高扇出信号(复位/使能/状态位带数万负载)就寄存器复制(MAX_FANOUT 属性/phys_opt 自动复制);布线占比高就 Pblock 聚拢;跨异步钟的违例是假违例,做同步器后 set_clock_groups;IP 边界违例开 IP 流水级。保持时间违例先重跑(工具自动插延迟),大面积保持问题查时钟偏斜结构,异步漏约束就补时钟组——绝不拿 false_path 压真违例,收敛后留 5%~10% 裕量。