一、综合与约束概述:综合流程介绍、约束的作用、综合与后端的关系

大家好,我是老李。做芯片设计验证这行十几年了,今天咱们聊聊综合与约束。说实话,很多刚入行的朋友觉得综合就是跑个脚本,约束就是写几行SDC。嗯,我当年也这么想,直到有一次项目差点翻车……

1.1 综合流程介绍

综合是什么?说白了,就是把RTL代码翻译成门级网表。你写的Verilog是行为级描述,综合工具帮你把它变成具体的标准单元、连线、逻辑门。

我习惯把综合流程分成三步走:

  1. 翻译(Translation):读入RTL代码,解析成内部统一的布尔表达式
  2. 逻辑优化(Logic Optimization):化简冗余逻辑,共享公共子表达式
  3. 映射(Mapping):把优化后的逻辑映射到工艺库里的标准单元

举个例子,你写了个 assign y = (a & b) | (a & c),工具会先识别出 a 是公共因子,优化成 assign y = a & (b | c),然后映射成一个AOI复合门。这就是综合的魔力。

核心要点:综合不是简单的"翻译",它包含大量优化决策。同样的RTL,不同的约束会得到完全不同的网表。

我在项目中遇到过最典型的情况:同一个模块,A工程师综合出来面积是1000um²,B工程师综合出来是1500um²。为什么差这么多?约束写法不同,优化策略就不同。

1.2 约束的作用

约束,就是告诉综合工具:你要往哪个方向优化。

没有约束的综合,就像没有导航的司机——能跑,但不知道往哪开。工具会默认选择面积最小、功耗最低的方案,但你的设计可能需要高频、高性能。

约束主要分几类:

约束类型 作用 典型命令
时序约束 定义时钟、输入输出延迟 create_clock, set_input_delay
面积约束 限制芯片面积 set_max_area
功耗约束 控制动态/静态功耗 set_max_dynamic_power
设计规则约束 保证物理可实现 set_max_transition, set_max_capacitance

我个人习惯把约束分成"硬约束"和"软约束"。硬约束是必须满足的,比如时钟周期、最大扇出;软约束是尽量满足的,比如面积、功耗。你想想看,如果时钟周期设得太紧,工具会拼命插buffer、换大驱动单元,面积和功耗就上去了。这就是trade-off。

小技巧:写约束时,先写时钟约束,再写IO约束,最后加设计规则约束。顺序很重要,因为后面的约束会基于前面的结果做优化。

1.3 综合与后端的关系

综合和后端(布局布线)是什么关系?很多人以为它们是独立的两个阶段——综合做完,网表扔给后端就完事了。错!

我举个例子你就明白了。综合阶段用的是线负载模型(Wire Load Model)来估算连线延迟。但实际布局布线后,连线延迟可能跟估算差30%甚至更多。为什么会这样?因为综合不知道具体的物理位置,它只能猜。

所以现在主流做法是物理综合(Physical Synthesis)——综合工具里集成了粗略的布局引擎,能估算出更准确的延迟。我在做28nm项目时,就吃过这个亏:综合时序全过,后端一跑,setup violation一大堆。后来加了物理综合选项,问题才解决。

注意:综合阶段不要过度优化。留一些余量给后端,比如时钟周期设成目标频率的90%~95%。否则后端一调整,时序就崩了。

综合和后端的协作,我总结成三点:

  • 约束一致性:综合用的SDC,后端也要用同一份。我曾经见过综合和后端各写各的约束,结果对不上,浪费了两周debug时间。
  • 网表质量:综合输出的网表要干净,不能有悬空线、多余buffer。后端最烦的就是"垃圾网表"——修都修不动。
  • 迭代反馈:后端跑完,把实际的延迟信息反馈给综合,重新优化。这叫"时序收敛闭环"。

1.4 知识体系总览

下面这张图,是我自己画的综合与约束的核心逻辑。你看一眼就能明白整个流程的脉络:

综合与约束核心流程 RTL代码 SDC约束 工艺库(liberty) 综合引擎 翻译 → 优化 → 映射 门级网表 后端布局布线 反馈延迟信息 输入数据 处理过程 输出结果 反馈迭代

从这张图你能看到:RTL、SDC、工艺库三者缺一不可。综合引擎吃进去这三样,吐出门级网表。后端拿到网表后,再把实际延迟反馈回来,形成迭代闭环。

我曾经在一个项目里,综合阶段没考虑后端反馈,结果流片回来芯片只能跑标称频率的70%。后来花了三个月重新做综合+后端迭代,才把性能拉回来。嗯,从那以后我再也不敢忽视综合和后端的协同了。

一句话总结:综合是RTL到网表的桥梁,约束是这座桥的"设计图纸",后端是桥的"实际施工"。图纸画得再好,施工不配合,桥也得塌。

好了,这一章就聊到这儿。记住:综合不是终点,是后端工作的起点。约束写得好,后端少烦恼。

可可精品资料库