1. 数字后端流程中 place 阶段的核心定位与整体思路
数字后端设计里,place(布局)这个环节处在一个非常微妙的位置。往前一步是 floorplan,往后一步是 CTS 和 route,它像是整个物理实现的“中场发动机”——floorplan 定下了 die 和 core 的边界、macro 的摆放、power plan 的骨架,而 place 则要把成千上万个 std cell 按照时序、拥塞、功耗的多重约束,安放到合法且合理的行(row)里。很多人刚入行时觉得 place 就是跑一条place_opt_design命令,等它跑完看报告就行,但真正做过几个项目之后你会发现,place 阶段埋下的隐患,往往要到 route 甚至 signoff 阶段才爆发,到时候再回头改,代价可能是几天甚至一周的迭代。
这篇文章我想围绕 place 阶段展开,把 std cell 布局、setup 时序优化、congestion 控制这几条主线串起来讲清楚。适合正在学习数字后端流程的在校生、刚转岗到后端的工程师,以及想系统梳理 place 阶段方法论的中级工程师。我不会只讲命令怎么敲,而是把每个决策背后的“为什么”讲透——为什么这个阶段要优先修 setup,为什么 congestion 要在 place 阶段就压下去,为什么有些 io pin 到 bufg 的路径会在 place 阶段报出 poor placement 的警告。这些问题的答案,决定了你跑 place 时到底是在“碰运气”还是在“做设计”。
place 阶段的输入是 floorplan 后的 DEF、时序约束 SDC、工艺库文件以及各种 physical 约束。输出是一个合法化的 placed DEF,以及一份能反映当前时序和拥塞状况的报告。听起来简单,但中间涉及的优化维度非常多:global placement 决定大致位置,legalization 把 cell 对齐到 row 和 site,detailed placement 再做局部微调,同时 timing-driven placement 会不断根据 setup/hold 的 slack 去推动 cell 移动。整个过程是一个多目标优化的博弈,你不可能让所有指标同时最优,必须根据项目阶段和设计特点做取舍。
我个人的习惯是,place 阶段先把 congestion 和 setup 这两件事盯死。原因很直接:congestion 在 place 阶段如果已经超过 1% 的 overflow,到了 route 阶段基本会恶化到 3% 以上,那时候再修就是拆东墙补西墙;而 setup 在 place 阶段修不到位,CTS 之后 clock skew 一加进来,slack 会进一步恶化,到时候能动的空间更小。所以 place 阶段的目标不是“跑完就行”,而是“给后面留足余量”。
2. place 阶段的核心细节解析与实操要点
2.1 std cell 布局的基本原理与 legalization 机制
std cell 的布局不是随便找个空位塞进去就完事。工艺库里的每个 std cell 都有固定的高度(通常是 site 高度的整数倍),宽度则各不相同。place 工具在做 global placement 时,会先把 cell 当成可重叠的点来优化线长和时序,得到一个理想位置;然后 legalization 阶段再把这些重叠的 cell 推开,对齐到合法的 row 和 site 上。这个过程有点像停车场停车——global placement 是告诉你“理想车位在哪”,legalization 是实际把车停进划线车位里,如果理想位置附近没空位,就得挪到远一点的地方。
这里有个关键点:legalization 之后,cell 的实际位置和理想位置之间会有偏差,这个偏差会直接影响线长和时序。如果设计密度太高,legalization 的挪动幅度会很大,时序和拥塞都会恶化。所以我在 place 之前一定会检查 floorplan 的利用率,一般控制在 70% 到 75% 之间比较稳妥,超过 80% 就要警惕。你可以用checkPlace命令来检查 placement 的合法性,它会报告 overlap、row 对齐、site 对齐等问题。
注意:legalization 之后一定要跑一次
checkPlace,如果报告里有大量 overlap 或者 unplaced cell,说明 floorplan 的 row 定义或者 blockage 设置有问题,不要急着往下跑。
2.2 setup 时序优化的时机与策略
place 阶段修 setup 的逻辑和 CTS 之后完全不同。CTS 之前 clock 是理想时钟,工具看到的是零 skew、零 latency 的理想情况,所以 place 阶段修出来的 setup slack 是“乐观值”。但这不代表 place 阶段不用修 setup——恰恰相反,place 阶段要把 setup 修到足够好,给 CTS 之后的 skew 和 latency 留出余量。我的经验是,place 阶段结束时 WNS 最好能到 -50ps 以内,TNS 控制在 -200ps 以内,这样 CTS 之后即使恶化 100 到 150ps,也还有机会在 route 阶段修回来。
place 阶段修 setup 的主要手段有几个:cell sizing(把驱动能力弱的 cell 换成强的)、buffer insertion(在长线上插 buffer)、cell movement(把关键路径上的 cell 拉近)、logic restructuring(用工具做 pin swap 或者 gate merge)。这些手段里,cell sizing 和 buffer insertion 对 congestion 的影响最大,因为强驱动 cell 和 buffer 都会占用更多面积和布线资源。所以我在 place 阶段会分两轮修 setup:第一轮用place_opt_design做全局优化,第二轮用optDesign -preCTS做增量优化,中间穿插 congestion 检查,避免时序修上去了但拥塞爆了。
2.3 congestion 的成因与 place 阶段的控制手段
congestion 的本质是布线资源供不应求。在 place 阶段,cell 的分布决定了布线需求的分布,如果某个区域 cell 密度过高,或者 pin density 过大,就会形成 congestion hotspot。常见的 congestion 成因包括:macro 周围的 channel 太窄、std cell 行利用率不均、高 pin 密度的 cell 扎堆、power stripe 占用了太多布线层。
place 阶段控制 congestion 的手段主要有:调整 floorplan 的利用率分布、设置 partial blockage 或者 density screen、用place_opt_design的 congestion 优化选项、手动挪动 macro 或者调整 channel 宽度。我一般会在 place 之后跑reportCongestion或者用 congestion map 来看 hotspot 分布,如果 overflow 超过 0.5%,就要定位具体区域并分析原因。有时候 congestion 不是全局问题,而是某个 macro 的 pin 太密导致的局部热点,这时候调整 macro 的 orientation 或者加一个小的 blockage 就能解决。
2.4 io pin 到 bufg 的 poor placement 警告解读
热词里提到的 “poor placement for routing between an io pin and bufg” 是一个很典型的 place 阶段警告。它的意思是:工具发现从某个 io pin 到 bufg(clock buffer)之间的路径,在当前的布局下布线会非常困难,可能因为距离太远、中间有 blockage、或者绕行路径太长。这个警告不能忽略,因为 io pin 到 bufg 的路径通常是 clock path 的一部分,如果这条路径的 insertion delay 太大或者 skew 太差,会影响整个 clock tree 的质量。
处理这个警告的思路是:先确认这个 io pin 是不是真的需要连到 bufg,如果是 clock 输入 pin,那就要确保 bufg 的位置离 io pin 足够近,中间没有 macro 或者 blockage 阻挡。如果 bufg 是工具自动插入的,可以手动把它挪到 io pin 附近,或者用create_clock的时候指定 source latency 来放宽约束。如果这个路径不是关键路径,也可以在 place 阶段先忽略,等 CTS 之后再看实际影响。
3. place 阶段实操过程与核心环节实现
3.1 place 前的准备工作与检查清单
在跑 place 之前,我会做一轮完整的检查,确保输入文件和环境没有问题。这个检查清单包括:floorplan 的 DEF 是否包含正确的 row 和 track 定义、SDC 是否覆盖了所有时钟和 io 约束、工艺库的 lef 和 lib 是否匹配、power plan 是否已经完成并且没有 DRC 问题、blockage 和 endcap 是否已经放置好。这些检查看起来琐碎,但任何一个环节出问题,place 的结果都不可信。
具体命令上,我会先跑checkDesign做整体检查,然后checkPlace看 floorplan 的合法性,再用reportCongestion看初始拥塞情况。如果初始 congestion 就很差,说明 floorplan 需要调整,不要硬跑 place。另外,我会确认setPlaceMode里的关键参数,比如-congEffort设成 high、-timingDriven打开、-maxDensity设成 0.75 左右。这些参数决定了 place 引擎的优化力度和方向。
3.2 place_opt_design 的关键参数与运行策略
place_opt_design是 place 阶段的主命令,它的参数设置直接决定了优化效果。我常用的参数组合是:
setPlaceMode -congEffort high \ -timingDriven true \ -maxDensity 0.75 \ -placeIOPins false \ -modulePlan false place_opt_design -outDir ./place_result-congEffort high会让工具在 place 时更积极地分散 cell,降低 congestion,但代价是线长可能略微增加。-timingDriven true打开时序驱动,工具会根据 slack 去推动 cell 移动。-maxDensity 0.75限制最大密度,避免局部过密。-placeIOPins false表示不移动 io pin,因为 io pin 的位置通常在 floorplan 阶段已经定好了。
跑完place_opt_design之后,我会先看 summary 报告里的 WNS、TNS、congestion overflow 这三个指标。如果 WNS 差于 -100ps 或者 overflow 超过 1%,我会先分析原因,而不是直接跑第二轮优化。常见的做法是:如果 congestion 差,先加 blockage 或者降低局部密度;如果 setup 差,先看关键路径的 cell 分布,确认是不是 legalization 挪动太大导致的。
3.3 optDesign -preCTS 增量优化与 setup 修复
place_opt_design跑完之后,通常还需要一轮optDesign -preCTS来做增量优化。这一轮的重点是修 setup,同时控制 congestion 不恶化。命令大概是这样:
setOptMode -effort high \ -fixCap true \ -fixTran true \ -fixSetup true \ -setupTargetSlack 0.0 optDesign -preCTS -outDir ./opt_result-fixCap和-fixTran会修 max cap 和 max tran 的 violation,这些 violation 如果不修,到了 route 阶段会变成 DRC 问题。-fixSetup true打开 setup 修复,-setupTargetSlack 0.0表示目标是把 slack 修到 0 以上。实际项目中,我一般会把 target slack 设成 0.05ns 左右,留一点余量给后面的 CTS。
这一轮跑完之后,我会对比 place 前后的 congestion map,确认 setup 修复没有导致新的 hotspot。如果发现某个区域 congestion 明显恶化,就要定位是哪些 cell 被挪过去了,必要时手动加 blockage 或者调整 cell 位置。
3.4 congestion 分析与 hotspot 定位实操
congestion 分析我一般用两种方式:一种是看reportCongestion的文本报告,它会列出 overflow 最严重的区域和具体的 gcell 坐标;另一种是看 GUI 里的 congestion map,用颜色直观地显示热点分布。文本报告适合定位具体坐标,GUI 适合看整体趋势。
定位到 hotspot 之后,我会先分析成因。如果是 macro 周围 channel 太窄,就考虑调整 macro 位置或者加宽 channel;如果是 std cell 密度过高,就加 partial blockage 或者降低局部利用率;如果是 pin density 太高,就看看是不是某些高 pin 密度的 cell 扎堆了,可以考虑分散它们。有时候 hotspot 是因为 power stripe 占用了太多 routing track,这时候需要和 power plan 的同事确认能不能调整 stripe 宽度或者间距。
提示:congestion 修复不要一次加太多 blockage,否则会把 cell 挤到别的地方形成新的 hotspot。建议每次只处理一个区域,修完再看整体 map。
3.5 place 结果的质量评估与交付标准
place 跑完之后,怎么判断结果好不好?我一般看这几个指标:WNS 和 TNS 是否在预期范围内、congestion overflow 是否低于 0.5%、max cap 和 max tran 的 violation 是否清零、cell density 是否均匀、有没有 unplaced cell 或者 overlap。这些指标里,WNS 和 congestion 是硬指标,其他是辅助指标。
如果这些指标都达标,就可以把 placed DEF 和相关的报告交付给 CTS 阶段。交付的时候我会附上一份简短的说明,包括 place 阶段用的关键参数、当前的 WNS/TNS、congestion 情况、以及已知的风险点。这份说明能帮 CTS 工程师快速了解 place 的结果,避免重复排查。
4. 常见问题与排查技巧实录
4.1 place 后 setup 恶化严重的排查思路
place 后 setup 恶化严重,最常见的原因是 legalization 挪动太大。你可以对比 global placement 和 legalization 之后的 cell 位置,如果发现关键路径上的 cell 被挪了很远,说明局部密度太高,legalization 被迫做了大范围调整。解决办法是降低局部密度,或者给关键路径上的 cell 加 region 约束,让它们待在理想位置附近。
另一个常见原因是 cell sizing 过度。工具为了修 setup,会把很多 cell 换成强驱动版本,强驱动 cell 的输入 cap 更大,会加重前级驱动负担,形成新的 violation。这时候需要检查reportCap和reportTran,看看是不是有新的 max cap 或者 max tran violation。如果有,就要在optDesign里打开-fixCap和-fixTran,让工具同时修这些 violation。
4.2 congestion 在 place 阶段压不下去的应对策略
congestion 压不下去,通常不是 place 参数的问题,而是 floorplan 的问题。我遇到过好几次,place 参数怎么调都没用,最后发现是某个 macro 的 channel 只有 5um,而实际布线需要 15um。这种情况下,唯一的办法是回到 floorplan 阶段调整 macro 位置或者 channel 宽度。
如果 floorplan 没问题,那就要看是不是 power plan 占用了太多 routing 资源。有些项目为了 IR drop 达标,会把 power stripe 做得很密,结果 signal routing 的 track 不够用。这时候需要和 power 工程师协商,看能不能在某些区域减少 stripe 或者换用更窄的 stripe。
还有一种情况是 pin density 过高。某些 std cell 的 pin 特别密,如果它们扎堆在一起,局部布线需求会远超供给。解决办法是用setPlaceMode -placeIoPin或者手动加 density screen,把这些 cell 分散开。
4.3 io pin 到 bufg 路径的修复方法
io pin 到 bufg 的 poor placement 警告,修复方法取决于这条路径的性质。如果是 clock path,那就要确保 bufg 离 io pin 足够近,中间没有阻挡。你可以手动把 bufg 挪到 io pin 附近,或者用create_clock的-source选项指定 source latency,让工具知道这条路径有额外的延迟预算。
如果这条路径不是 clock path,而是普通的数据路径,那就要看它的 slack 是否紧张。如果 slack 很松,可以忽略这个警告;如果 slack 紧张,就要考虑调整 io pin 的位置或者加 buffer 来改善布线。
4.4 place 阶段常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决手段 |
|---|---|---|---|
| WNS 恶化超过 100ps | legalization 挪动太大 | 对比 global 和 legal 后的 cell 位置 | 降低局部密度,加 region 约束 |
| congestion overflow > 1% | floorplan channel 太窄 | 看 congestion map 定位 hotspot | 调整 macro 位置或加宽 channel |
| max cap violation 增多 | cell sizing 过度 | 跑 reportCap 看 violation 分布 | 打开 -fixCap 同时修 |
| unplaced cell 存在 | row 定义或 blockage 问题 | 跑 checkPlace 看报告 | 修正 floorplan 的 row 和 blockage |
| io pin 到 bufg 警告 | bufg 离 io pin 太远 | 看路径距离和中间阻挡 | 挪 bufg 或加 source latency |
4.5 实操心得与避坑经验
做了这么多项目,我在 place 阶段踩过的坑总结下来有几个。第一个是不要迷信工具的默认参数,place_opt_design的默认congEffort是 medium,对于高利用率设计来说不够,一定要手动设成 high。第二个是不要等到 place 跑完才看 congestion,最好在 floorplan 阶段就用reportCongestion预估一下,提前发现风险。第三个是 setup 修复不要一次修太狠,分两轮做,中间检查 congestion,避免时序修上去了但布线爆了。
还有一个经验是,place 阶段的报告一定要仔细看,尤其是 warning 和 info 级别的消息。很多问题在 warning 里已经提示了,比如某个 cell 被挪到了很远的地方、某条路径的 estimated delay 异常大,这些信息能帮你提前定位问题,而不是等到 CTS 或者 route 阶段才发现。
最后分享一个小技巧:如果 place 之后 congestion 和 setup 都达标,但你对结果不太放心,可以跑一次route -global做快速全局布线,看看实际的 routing overflow 和 via 数量。这个步骤花不了多少时间,但能给你一个更接近真实的 congestion 评估,比单纯看 place 阶段的估算更靠谱。