数字后端设计流程:从RTL到GDSII的完整旅程

说实话,刚入行那会儿,我觉得后端设计就是个「黑盒」——RTL代码丢进去,GDSII吐出来。直到自己完整跑过几个项目,才明白这中间每一步都有门道。

今天咱们就把这个流程拆开看看。从RTL到GDSII,到底经历了什么?每个阶段输入输出是什么?模块化设计又插在哪个位置?

整体流程概览

一个典型的数字后端设计流程,可以分成六大阶段。我习惯把它们画成一张图,这样团队沟通时一目了然。

数字后端设计流程总图 数字后端设计流程总图 RTL综合 Synthesis 布局规划 Floorplan 单元放置 Placement 时钟树综合 CTS 布线 Routing 签核 Signoff 模块化设计贯穿始终:Hierarchical Design / Block-Level Partition 每个阶段都可以按模块独立迭代,最后在顶层拼接 输入:RTL代码 → 输出:GDSII版图 每个阶段都有独立的检查点(Checkpoint)和ECO能力 迭代优化

这张图我贴在了工位上好几年。每次新人来,我都先指着它讲一遍。你想想看,六个阶段,每个阶段都有明确的输入输出,模块化设计就像一条线,把它们串了起来。

各阶段详解

1. RTL综合(Synthesis)

输入:RTL代码(Verilog/VHDL)、综合约束(SDC)、工艺库(Liberty)

输出:门级网表(Gate-level Netlist)、时序报告、面积报告

综合说白了,就是把你的RTL代码翻译成工艺库里的标准单元。我见过不少前端工程师觉得综合很简单,其实不然。约束写不好,后面全白干。

我的习惯:综合阶段我会特别关注 transition 和 fanout 的约束。曾经有个项目,综合时没管 fanout,结果 CTS 阶段时钟歪得一塌糊涂,最后 ECO 改了三轮。

2. 布局规划(Floorplan)

输入:门级网表、物理库(LEF)、IO约束、芯片面积估算

输出:芯片尺寸、IO Pad位置、宏单元(Memory/IP)摆放、电源网络规划

布局规划是后端设计里最「艺术」的一步。同样的网表,不同的人摆出来,时序和面积能差20%。

避坑指南:我曾经在一个28nm项目里,把一个大Memory放在了芯片角落,结果绕线资源不够,信号线绕了半个芯片才连上。从那以后,我摆宏单元前一定会先看绕线资源图。

3. 单元放置(Placement)

输入:布局规划后的设计、时序约束、物理库

输出:标准单元位置、初步时序报告、拥塞报告

工具会自动把标准单元放到合适的位置。但这里有个坑——工具默认是「贪心」的,它会优先满足时序,有时候会牺牲绕线。我建议你跑完placement后,一定要看congestion map。

放置阶段 目标 常见问题
全局放置 粗略分配位置,评估拥塞 局部密度过高
详细放置 精确摆放,满足时序 setup violation
优化放置 微调位置,修复DRC pin access问题

4. 时钟树综合(CTS)

输入:放置后的设计、时钟约束(时钟周期、skew目标、latency目标)

输出:时钟树网表、时钟报告(skew、latency、功耗)

CTS是后端设计里最「敏感」的阶段。时钟树做不好,整个芯片就像个心律不齐的病人。我习惯在CTS之前先手动规划一下时钟根节点(clock root)的位置,工具自动做的有时候不够聪明。

关键指标:时钟偏斜(Clock Skew)一般控制在时钟周期的5%以内。比如500MHz的芯片,skew最好小于100ps。超过这个数,hold timing就很难修。

5. 布线(Routing)

输入:CTS后的设计、绕线规则(RC参数、最小间距、最小宽度)

输出:完成绕线的版图、RC寄生参数文件(SPEF)、最终时序报告

布线分全局布线和详细布线两步。全局布线先规划大致的走线通道,详细布线再一条条把线连上。这里最容易出的是天线效应(Antenna Effect)和串扰(Crosstalk)。

6. 签核(Signoff)

输入:布线后的版图、寄生参数、时序约束、物理验证规则(DRC/LVS)

输出:GDSII文件、最终时序报告、DRC/LVS报告、功耗报告、IR Drop报告

签核就是「交卷」前的最后检查。我见过最惨的一次,DRC跑了三天,最后发现有个via的间距差了0.01微米。嗯,这种错误一次就记住了。

模块化设计在流程中的位置

模块化设计不是某个阶段的事,它贯穿整个流程。说白了,就是把大芯片拆成小块,每个小块独立做后端,最后在顶层拼起来。

为什么这么做?原因很简单:

  • 并行加速:五个模块可以同时跑,比串行快5倍
  • 隔离风险:一个模块出问题,不影响其他模块
  • 复用价值:同一个模块可以在多个项目里复用

但模块化也有代价——顶层拼接时会有「边界时序」问题。我建议你在划分模块时,尽量把关键路径放在模块内部,不要跨模块。

我的经验:模块划分时,每个模块的大小控制在50万到200万门之间比较合适。太小了,顶层拼接工作量太大;太大了,模块内部工具跑不动。

各阶段输入输出速查表

阶段 主要输入 主要输出 模块化介入点
综合 RTL, SDC, Liberty 门级网表 模块级综合约束
布局规划 网表, LEF, IO约束 芯片尺寸, 宏单元位置 模块边界定义
单元放置 布局规划结果, 时序约束 标准单元位置 模块内独立放置
时钟树 放置后设计, 时钟约束 时钟树网表 模块级时钟平衡
布线 CTS后设计, 绕线规则 版图, SPEF 模块内独立布线
签核 版图, 寄生参数, 验证规则 GDSII, 报告 模块级签核+顶层拼接

一点个人感悟

做了这么多年后端,我最大的体会是:流程是死的,人是活的。每个项目都有它的特殊性,别死磕流程,要理解每个阶段「为什么」这么做。

比如,有些低功耗项目会在布局规划阶段就做电源域划分,而不是等到CTS之后。再比如,有些高频芯片会在综合阶段就手动插入时钟门控,而不是让工具自动做。

嗯,流程是骨架,经验才是血肉。后面几章咱们会深入每个阶段,把模块化设计的细节一个个掰开揉碎讲清楚。