综合工具演进史:从Synergy、BuildGates到Genus的迁移之路 聊数字芯片设计逻辑综合是RTL到门级网表中间那一段最“工具味”的流程。业界有一家EDA巨头也靠这套流程被很多人记住但现在大家天天挂在嘴边的Genus并不是这家厂商第一款综合工具。在它之前Synergy、BuildGates、PKS、RTL Compiler这一串名字分别代表了这家厂商在不同时期对综合的理解从传统RTL综合到物理综合再到后来被整合成一个统一平台。这篇文章就把这些“曾经的综合工具”翻出来讲讲它们是怎么来的、为什么被替代以及它们留下的技术习惯如何一路影响到了现在。适合正在做综合的工程师、准备从老Flow迁移的团队也适合刚接触逻辑综合的学生——看工具的变迁史其实就是看一个行业在算力、工艺和生态之间反复取舍的过程。1. 为什么说“曾经的综合工具”一串被替代的名字1.1 第一代自研产品Synergy的遗憾上世纪九十年代中期综合市场已经有一个近乎垄断的标杆产品。后进者想切这块蛋糕单靠算法很难因为综合工具本质上是“经验密集型软件”用户已经把约束写法、脚本习惯、库文件格式全押在既有工具上。Synergy就是在这样的环境下推出的。它在技术指标上并不是完全落后部分设计甚至能压出更小面积但一碰到用户的SDC约束、IP库和既有Flow兼容成本就上来了。结果很现实客户试完后绝大多数还是回到老工具。Synergy在当年也支持Tcl也讲逻辑优化但它和前端代码、后端点工具配合时始终没有形成闭环。一个综合工具如果只负责把RTL变成网表后面布局布线一旦发现时序问题前端就要反复改约束这种“打乒乓球”的工作方式没人受得了。再加上上市时间比竞品晚算法优化上又缺少足够多的真实量产设计去磨Synergy最终没能承担起“主流综合工具”的角色。它最大的意义其实是让这家厂商第一次意识到综合工具不是给RTL做翻译而是要和全流程的约束、库、时序签核体系咬合在一起。1.2 BuildGates物理综合的赌注到了2000年左右工艺进到130nm甚至更小互连延时占比上升原来靠统计线负载模型估算线长的做法越来越不准。所以有创业团队提出物理综合综合时先做一个快速布局把每个cell的位置估算出来再去算线长、算时序然后在这个物理信息上做逻辑优化。这家巨头通过收购拿到了BuildGates打算用这个思路正面挑战当时的市场标杆。BuildGates确实把布局感知综合做得更早很多概念到现在都是通用的。但它有一个致命伤综合里的快速布局和最终布局布线工具的布局结果经常不一致工具之间也没有统一的数据库。用户在综合后看着时序报告不错跑到后端又变了这种“报告漂移”最消耗信任度。你优化了半天的一条关键路径后端点工具一重新布局线长模型变了关键路径直接换了一条综合工具前面做的努力全白费。所以物理综合这个概念火了一阵却没能在当时真正成为主流。不过BuildGates给行业留下的问题一直存在怎么让综合提前感知物理位置而不是到最后一步才面对现实。1.3 PKS与RTL Compiler两条技术路线的合流几乎同一时期这家厂商还有另一条线叫PKS也是做物理知识综合。PKS和BuildGates方向相似于是内部就出现了两套团队、两套引擎。再后来这家厂商又收购了一家做高层次综合和RTL综合的创业公司把产品整合成RTL Compiler。这一下公司内部至少有三个综合工具在并行老的Synergy、物理综合方向的BuildGates/PKS、以及后来的RTL Compiler。对外客户的困惑就是到底用哪一个对内维护成本也非常高。最终这家厂商选择了以RTL Compiler接班后续版本不断迭代并且在另一条后端实现流程里成为标准综合器。大概在2017年前后Genus正式亮相直接接替RTL Compiler。从“曾经的一堆名字”到“现在的一个入口”你看到的不只是产品更换而是产品线被不断收敛物理综合的探索、高层次综合的基因、Tcl脚本生态、UPF和DFT能力全部被塞进了同一个工具里。对用户来说选项变少反而是好事因为终于不用猜厂商主推哪个了标准答案就写在启动命令里。2. 综合工具到底在算什么不只是RTL翻译2.1 “综合”是把行为描述变成电路取舍很多人把综合理解成“把Verilog翻译成门级网表”但更准确的比喻是厨师做菜。RTL是你的需求约束是口味偏好工艺库是后厨里能用的食材和灶台综合工具就是那个厨师。同样的菜有人用小锅快炒有人用大锅炖出来的门级结构完全不同。RTL只规定了“每个时钟周期应该算什么”但没有规定“这个加法器用行波进位还是进位选择结构”没有规定“这些逻辑门是并列放还是串起来形成一条最长路径”也没有规定“哪些寄存器需要被合并”。逻辑综合大体分三步第一步elaborate把RTL解析并展开成内部统一的中间表示寄存器和组合逻辑仍然是抽象行为第二步做逻辑优化包括布尔化简、公共子表达式提取、资源共享第三步做技术映射把优化后的逻辑匹配到标准单元库里的具体门。前两步和CPU编译器有点像第三步更像家具定制同样的柜子可以用整板也可以用多块小板拼。综合工具的价值就在于知道什么时候选整板、什么时候拼板让总面积、路径时延和功耗综合最优。所以评价一款综合工具不是看它能不能“翻译成功”而是看它在面对同一个设计意图时能不能找出更省的实现方式。老工具和现代工具之间的差距核心也在这里计算资源变强了搜索空间可以更大算法迭代了质量结果更好约束交互方式更成熟用户能更精细地控制优化。但底层的问题始终是那个——在无数种实现方式里找到满足时序、面积、功耗约束的那一个。2.2 约束、库与多角点外围生态决定上限算法能决定一个工具跑多快但真正决定它好不好用的是外围生态。综合工具读进来的数据包括SDC时序约束、Liberty工艺库的时序功耗模型、LEF物理库如果要做布局感知、UPF低功耗意图。这些数据从哪来从前端设计、IP厂商、代工厂、后端流程里来任何一个环节格式对不上工具再强都白搭。工艺库文件里每一行都不是随便给的里面包含cell的leakage power、timing arc、slew阈值、下一级输入电容以及CCS或者ECSM这样的非线性时序模型。工具要用这些数据去遍历路径计算时序。多角多模的意思就是同时考虑slow角、fast角还有低功耗模式、高性能模式。一个cell在快速角下可能很快但在慢速角下发火很大一条路径在一种模式下满足时序在另一种模式下却变成关键路径。所以现代综合工具默认就要做这种多角多模优化而不是只对着一个最坏角跑。老工具失败很多时候不是算法不行而是生态不兼容。用户在旧工具里已经写了成千上万行约束和脚本新工具性能提升百分之十但迁移成本可能要两个星期还要重新验证结果这笔账很难算清。这也是为什么综合工具市场后来几乎固化领先者占据生态第二名活得辛苦第三名只能在细分场景里找机会。回过头看Synergy那一代产品的结局与其说是输在优化引擎不如说是输在没有建立起完整的配套生态。2.3 物理综合的教训反馈要闭环BuildGates和PKS都尝试过把布局信息引入综合思路是对的深亚微米下线长不再只跟扇出有关必须考虑物理位置。但做这个事的前提是综合引擎和布局引擎要共享同一个数据库、同一套时序引擎。如果综合用一个快速布线器布局布线又用另一个引擎两边对同一段路径的估算自然差出好几个门级延时。用户一看到这种漂移就会认为工具不靠谱。现代Genus实现中物理信息又回来了但形式更成熟。它不再强行“布局”而是在综合时允许用户输入floorplan、宏单元摆放位置或者抽象的block形状通过快速估计线长分布来指导优化。后端流程再通过统一的数据底座把综合结果和后续布局布线连起来。也就是说当年物理综合的核心理念并没有死只是换了一个更聪明的落地方式不是用另一个引擎去预猜后端结果而是把后端的关键约束提前拿到综合阶段来考虑。这个词被反复提起是因为综合工具的压力一直存在。你在综合阶段做的设计决策会直接决定后端能不能收敛。如果综合阶段不管物理效应后端跑到一半发现某块区域密度过高、绕线拥塞前端就要回到RTL或者约束层面重新来一遍。所以每一个“曾经的综合工具”其实都是在这条路上试错有的试错了方向有的试对了概念最后能留下来的一定是把生态、算法和反馈机制都做顺了的那一个。3. 老工具留下的三笔遗产SDC、Tcl和Flow思维3.1 SDC约束语言成了事实标准不管哪家综合工具现在都要先支持SDC。这门约束语言当年从一个综合工具里发展出来后来被行业标准组织接手维护。它定义了create_clock、set_input_delay、set_clock_groups这些命令用户写的约束可以从逻辑综合一路用到后端综合读一遍时钟树综合读一遍布线再读一遍时序签核还能继续读同一份。工具想在这个市场活下来必须先把这个接口接好。老工具时代不同综合工具对SDC的解析是有差异的命令名称、默认值、异常路径的处理方式都出现过兼容性偏差。而真正能被长期用下来的工具一定是在SDC兼容性上做得足够稳的。到了Genus你基本可以把RTL Compiler那份SDC约束原样带过来这也是老工具留下的最大实用遗产。约束是设计意图的一部分它不是附属品优先级甚至比综合器本身还要高。换工具可以换约束里的每一条例外路径、每一条set_multicycle_path都得当成设计资产来管理。3.2 Tcl脚本与“可回归”的工程习惯综合这层几乎没有人用GUI点按钮都是写脚本。老一代工具把Tcl定义为交互语言后续所有工具都沿用了这个思维。一个完整Flow包括设置库路径、读RTL、elaborate、施加约束、综合优化、报告输出、网表写出。脚本化带来一个特别重要的工程习惯回归测试。每天晚上跑一轮综合固定一批代表设计看面积、时序、泄漏功耗有没有退化。这个习惯不是综合工具发明的但老工具时代被固化成了严谨的工程纪律。所以当你拿到一个老Flow不要只看到一堆命令要看到命令背后的意图。比如set_dont_use不是随便写的它是在告诉工具“这些库单元功耗不划算、尺寸不合适别用”group_path是告诉工具“这几条路径我要单独盯不要被其他路径平均掉”。这些意图在迁移到Genus时通常都要保留不能因为命令名变了就丢掉。脚本最怕的不是长而是不知道每行在干什么迁移老Flow的第一步是先做注释和分类而不是直接跑一遍看结果。3.3 低功耗和DFT综合早期就要介入的习惯老综合工具曾经只关注面积和时序后来功耗成为芯片的核心指标RTL级低功耗技术出现了。综合阶段要自动做门控时钟、电源域隔离、电平转换插入同时DFT也要在综合时考虑扫描链怎么接、可测性逻辑怎么插。曾经的RTL Compiler就已经支持这些到了Genus这些变成了一套紧密集成能力读UPF综合时插入时钟门控网表输出后交给签核工具验证隔离和恢复逻辑。这意味着你换综合工具时不能只对比纯逻辑综合的QoR还要测试UPF、DFT、多角点优化这些延伸能力。很多团队迁移时在这里踩坑主流程综合结果很漂亮加上UPF和DFT之后面积功耗完全失控。原因通常是低功耗单元没有提前设好dont_use、隔离逻辑插入位置不对、或者扫描链的时钟规划没反映到综合约束里。工具只是执行方设计意图还是得由工程师在早期表达清楚。老工具留下的这三样东西——SDC、Tcl、Flow纪律本质上都是“让设计意图可表达、可回归、可交接”的工程方法。4. 从RC老Flow迁到Genus迁移步骤与结果对比4.1 常规迁移步骤先说清楚不同版本、不同工艺、不同设计类型迁移细节一定会有差异。下面的流程是常见做法具体命令以你手上的工具版本手册为准。迁移第一步不是打开Genus而是盘点老RC脚本把约束、编译选项、DFT配置、UPF配置、输出文件分别拆开。很多老脚本喜欢把所有代码写在一个文件里换工具时这种文件最难处理因为你没法判断哪些命令是必要的、哪些只是历史遗留。拆完之后照着下面这个骨架建新脚本# 设置库和RTL路径 set_db init_lib_search_path {../lib ../rtl} set_db init_hdl_search_path {../rtl} # 读入工艺库和RTL read_libs {../lib/stdcells_slow.lib ../lib/stdcells_fast.lib} read_hdl -v2001 {top.v datapath.v} # 解析设计 elaborate top init_design # 读入约束 read_sdc ../constraints/top.sdc # 设置优化力度并综合 set_db syn_generic_effort high set_db syn_map_effort high synthesize -to_mapped -effort high # 报告和输出 report_qor report_timing write_netlist outputs/top_gate.v write_sdc outputs/top.sdc write_db outputs/top.genus_db这个骨架看起来简单但用起来有几个要点。第一read_libs的顺序会影响工具对同名的处理一般把慢速库放在前面报告时序时默认按慢速角评估。第二read_hdl之后必须elaborate和init_design很多老脚本是从别的工具带过来的容易漏掉init_design这一步结果后面命令一连串报错。第三write_db非常关键它保存的是完整综合现场中间结果、约束、属性、库设置比只写网表和SDC更能还原当时的环境。如果后端发现时序问题需要回溯一个db文件能省你半天时间。4.2 结果对比看哪些指标迁移初期最容易犯的错是只盯着综合报告里的QoR数字。Genus的时序引擎和RC不同对同一组约束的报告可能在某些路径上更乐观或更悲观。你真正要比较的是把Genus输出网表交给后端点工具跑完后的总时序收敛难度、DRC clean程度、ECO工作量。这才是用户感受得到的差距。对比维度老RC基线Genus迁移初期说明面积基线通常持平或略好别用单个block下结论WNS/TNS基线可能更好也可能更差时序引擎版本不同报告口径有差异泄漏功耗基线看UPF和低功耗设置需要单独跑低功耗回归运行时间基线可能±20%取决于effort和并行核数内存占用基线可能更高服务器内存要预留DB可回溯性弱强write_db关键时刻能救场建议选五到十个有代表性的block做回归连续跑两个星期再下结论。所谓代表性就是取面积大的、时钟复杂的、拥塞敏感的、有低功耗需求的几类都要覆盖。单次跑一个block看到面积变好就急着全量迁移后面可能在某个奇怪模块上翻车。4.3 老脚本迁移的三个坑坑一把RC时代的compile命令直接当成Genus的synthesize用。命令名看起来接近但选项体系不一样。RC里很多set_attribute写法到了Genus要改成set_db如果只是全局搜索替换很容易丢掉一些条件选项。最稳的办法是每翻译一段就跑一次简单设计做对比确认命令行为和预期一致。坑二忘了对层次化约束的作用域做检查。老脚本经常靠current_design在不同层级之间跳转换到Genus后有些设计用一次init_design就能覆盖所有层次但跨模块的约束路径写法要重新核对。曾经见过一个案例老脚本里对一个较底层的时钟做了create_clock迁移后命令没报错但时钟根本没作用到顶层时序路径上白白跑丢了一个礼拜。坑三没有保留综合现场的习惯。老脚本很多最终只写出网表和SDC数据库没有保留。一旦后端发现问题想看看综合时的约束或属性设置只能靠重新跑一遍来复现。在Genus里write_db成本很低建议每个block、每个版本都归档一个。配合上脚本的版本管理综合结果才能真正做到可追溯。5. 实际踩过的坑QoR异常先别怀疑工具5.1 面积超标往往来自DRV修整有一种问题最常出现综合完面积比预估大百分之二十。这时候别急着怀疑约束先跑report_design_rules看是不是有一堆max_transition、max_capacitance违规。工具为了修这些DRV会疯狂插入buffer面积自然就上去了。为什么会出现这个现象通常是RTL里某个net的负载太重或者某个输出端口直接带了一大扇出再或者某些high-fanout net没有被提前处理。解决办法不是简单放宽约束——那样后端会加倍还回来。正确做法是在RTL或约束层面把负载分拆比如手动复制寄存器、对高扇出信号做tree shaping或者把某些不必要的buffer单元设成dont_use。特别提醒DRV违规和时序违规的处理逻辑完全不同时序违规可能是约束设得紧DRV违规却往往说明结构设计有问题。看到面积变差时先分清是哪一类再动手调。5.2 工具版本升级导致结果“性格”变化同一份RTL、同一份约束从RC换到Genus或者Genus小版本升级结果都会变化这是正常的。综合优化器的搜索空间巨大算法调整一点局部结构就会不同。你要是拿一次实验的结果去否定一个新版本很容易误判。正确做法是固定回归集和评估标准连续跑三轮看收敛趋势。实际处理中还要注意工具之间对时序例外路径的默认处理方式不同。比如set_false_path、set_multicycle_path在路径筛选、报告统计上可能有细微差异导致WNS的数字不能直接对比。遇到这种情况先看是不是约束解释差异再看是不是真时序退化。版本升级时最好把时序例外清单打印出来跟老版本做diff很多“结果变差”是假象。5.3 多时钟和例外路径少用false_path多分析很多综合时序问题出在例外路径写得“太野”。为了clean timing有人会把一些路径直接设成false_path结果掩盖了真实逻辑问题。比如两个时钟域之间没有做同步处理也没有CDC检查你就把跨时钟路径全部设为false_path综合报告当然干净但芯片跑起来可能出毛刺。最好的习惯是先把例外路径保留在文件里但不要急着全量应用先跑一轮不设例外的综合看看真实violation长什么样再一条一条判断哪些是合理的例外、哪些是逻辑设计缺陷。在多时钟设计里异步时钟域之间优先用set_clock_groups -asynchronous而不是逐个set_false_path前者还能保留时钟域交叉检查的语义。综合工具不会替你做设计判断它只是执行你给的自由度。你把一条真实存在的路径标成false就等于告诉工具“这条路径坏了我负责”后面出了问题背锅的还是你自己。一个人看脚本不如让整个团队定期review例外路径这比任何工具选项都管用。5.4 UPF和DFT加进来之后结果才算数还有一个常见的坑是把纯逻辑综合和带UPF/DFT的综合分开评估。很多团队迁移到Genus后先跑一个不带UPF的验证脚本看到QoR变好就开心结果把UPF读进去面积多了百分之十而且隔离单元插得到处都是。仔细查下来问题常常出在低功耗单元的set_dont_use没有配置好或者power domain边界上没有指定合适的level shifter库单元。综合工具只能按你给的库和应用脚本来干活UPF描述里的每个domain、每个isolation strategy最终都会变成一个具体的cell插入决策。如果你有DFT插入的流程同样要提前考虑。扫描链插入会影响布局和时钟树综合脚本里的时序约束不能完全忽略扫描时钟。建议在迁移标准里加入一个“综合DFTUPF全流程”场景专门跑最小的测试芯片所有输出网表都要过一遍形式验证确认功能没有变化。很多老工具的问题换个新工具不一定消失但会在早期暴露得更清楚。如果你问我从这些老工具一路用下来最深的感受是什么我觉得不是哪个工具算法更强而是综合工具在数字流程里的位置从来没有变过它是要把设计意图变成物理可实现电路、并且让后端愿意接手的那道关口。Synergy、BuildGates、PKS、RTL Compiler这些名字消失了但它们逼出来的SDC生态、Tcl脚本习惯、UPF和DFT早期集成还有“物理信息要反馈到综合”的理念全都沉淀在Genus里了。以后如果再有人问“旧工具有什么价值”你可以告诉他价值不在命令在思路。