JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

布线:连起所有金属

单元已经摆好、时钟树也搭好了——可眼下它们就像一座只有高楼、没有道路的城市。布线就是工具真正画出金属连线的环节:把数以百万计的导线,穿织进一摞像多层立交一样叠起来的金属层,靠过孔在楼层之间上下穿梭,而且每一步都得守住代工厂的间距规则。读到最后你会明白,为什么导线从来都不是免费的:每一根金属都带着实打实的电阻和电容,而这恰恰是下一篇要去测量的东西。

用金属把一切连起来

到这一步,布局已经把每个标准单元停进了各自的格子,时钟树综合也把时钟接好了。可你退后一步打量整颗芯片,会发现一件让人不安的事:这是一座没有道路的高楼城市。每个单元的输入、输出引脚都孤零零地立在那儿,在电学上彼此隔绝,等着被连起来。网表里写着*“这个 NAND 的输出必须送到那三个触发器的输入”*——可眼下还没有任何东西把这个信号在物理上送过去。布线就是铺下金属、真正完成这些连接的那一步。

你可以把它想成:在已经分配好的地址之间铺路。布线器的活儿,是为设计中的每一条网络,从每个驱动引脚到它要喂的每个负载引脚,画出一条连续的金属带——而一颗现代芯片有数以百万计的网络。它不能直接画直线,因为那样导线会交叉、短路在一起。于是它把这些线穿织进一张层叠的网格里,就像一座城市把车流分摊到地面街道、高架桥和隧道上,让车辆永不相撞。

金属堆叠(BEOL)

晶体管本身住在最底层,刻在硅里——那一层叫前段制程(front end of line,FEOL)。叠在它们*上方*的一切都是布线,那就是后段制程(back end of line,BEOL):一摞由绝缘层隔开的金属层,在选定的位置上下打通。这就是你的路网,而且是真正意义上的多层结构——想象十几层甚至更多层的高速公路一层叠一层,每一层的车道都只朝一个方向跑,于是相邻两层是相互垂直交叉,而不是去抢同一条车道。

对后端工程师来说最要紧的一点是:每一层并不一样。最底下的几层金属(就叫它们 M1、M2)又薄又窄——用来在相邻单元之间做短距离的本地跳接正合适,但单位长度的电阻很大,像一条拥挤的单车道窄巷。上层金属则又厚又宽——电阻低,专为横跨整颗芯片的长途奔袭以及供电网络而生,像一条六车道的高速公路。所以布线器并不把各层当成可以随意替换的:短的本地网络留在底下,又长又时序紧要的网络以及电源则被“升”到楼上,那里的金属又粗又快。

# Resistance of a wire segment (intuition, not a tool command)
#   R = rho * Length / (Width * Thickness)
# Thinner + narrower lower layers  ->  small (W * Thickness)  ->  larger R.
# Same length on a thick upper layer is far less resistive.
为什么底层电阻大:导线的电阻随着横截面变小而上升。又瘦又窄的底层金属做短跳接很好,跑长距离却很吃亏——这正是长网络要被布到上层厚金属去的原因。

全局布线 → 详细布线

你不会一口气把整颗芯片布完,就像导航软件不会在你还没倒出车道之前,就把整趟行程逐条车道地算清楚。布线器分两遍来做,先粗后细,而这两遍之间的区别,正是这一节要建立的整套思维模型。

全局布线是在“区域”这个层级上做规划。整颗芯片被切成一张粗粒度的方格网(这些格子常叫 *gcell*),布线器为每条网络大致定下*它会穿过哪些格子、骑在哪些金属层上*——此时还一根精确的线都不画。这就是高速公路规划的视角:“这个信号往东北方向,穿过这几片街区,主要走上层楼面。”尤为关键的是,全局布线还会统计有多少导线想穿过每条格子边界,于是它能在真正动手之前就看到麻烦——太多车都想挤同一个上匝道。

详细布线接着才是真正的铺路。它拿过全局规划,把实际的金属铺在合法的轨道上——也就是每一层上预先定好的“车道”——挑定确切的宽度、确切的位置、确切的过孔点,把所有东西都对齐到代工厂允许的栅格上。导线就是在这一步从“意图”变成真正的几何图形。

  1. 全局布线:把芯片切成粗格子,给每条网络分配一条大致路径和一份层预算,并估算导线会在哪里堆积。
  2. 轨道分配:在每条网络选定的层上,给它指定具体的车道,把车流摊开,好让详细布线那一步有腾挪的余地。
  3. 详细布线:画出确切的金属线段和过孔,全部对齐到合法的轨道和栅格位置上。
  4. 搜索与修复(search-and-repair):揪出剩下的违规之处,对惹事的导线做拆线重布,直到版图干净为止。

过孔与换层

一个信号光靠一层楼是到不了目的地的——它迟早得换层,就像司机得离开地面街道、上到高架桥上去。各金属层之间在设计上本就是相互绝缘的,所以导线要在相邻两层之间跳转,唯一的去处就是在绝缘层里特意打通的那个垂直连接:过孔(via)。过孔就是这摞金属层的上下匝道。

一个过孔只连相邻的两层——M1 到 M2、M2 到 M3,依此类推。要从低层一路爬到上面的厚金属层,布线器就得搭一座过孔叠(via stack):一列上下叠起来的过孔,每层一个,笔直地穿过这些楼层。一个从底下 M1 上某个单元引脚出发的信号,正是这样被吊上 M6 这条高速,再一路降下来够到它的负载。

布线中的拥塞与 DRC

芯片上有些街区想穿过去的导线,远远多过能容下它们的车道数。这就是拥塞:某个区域里对布线轨道的需求超过了供给。它通常能追溯到更早做出的选择——布局时单元堆得太密,或是许多网络汇聚到的某个热点——这也是为什么拥塞是后端工程师收到的、提示“布局规划或布局得再看一眼”的最响亮信号。当一个区域过度拥塞,详细布线器就是塞不下所有导线、又不违规,于是你要么得到失败,要么得到难看的绕远——把导线拉长,进而伤害时序。

而且布线器并不能哪儿塞得下就往哪儿塞金属——它画的每一根线,都必须一边画一边遵守代工厂的规则,也就是设计规则。同一层上的两根线之间至少要隔开一个最小距离,否则就会短路、或是根本造不出来;每根线都有最小线宽;过孔还有自己的包覆(enclosure)和间距规则。布线器本质上是在解一道巨大的装箱难题,而每一块拼图都得遵守晶圆厂写下的那本规则手册。

当布线器确实撞上一个一遍走不掉的违规时,它就退而求其次,使出拆线重布(rip-up and reroute):把惹事的导线扯掉,再沿一条能避开冲突的不同路径重新铺下去。你可以想象:重铺一段路来缓解一处堵车,然后再去查查,看自己是不是一不小心在两个街区外又造出了一处新的堵。它天生就是迭代式的,这也是为什么布一个大模块可能要跑上好几个小时。

导线不是免费的(RC)

下面这个观念会直接把你带进下一篇。在前端的世界里,一根导线几乎就是免费、瞬时的连接——原理图上的一根线而已。而在下面这里,它是一条实实在在的金属带,而真实的金属有两个躲不掉的属性:电阻(R),因为金属会阻碍电流;以及电容(C),因为这根线挨着别的导体,会像一个小电容的两块极板那样,在它们之间存住电荷。

这两者合在一起,就让每根导线都带上了一份延迟。直觉很简单:信号没法瞬间把一根线的电压翻转过来,因为它得先把电流*推过*电阻,去给电容充上电——而这个 R 乘以 C 的乘积越大,导线就要越久才能稳定下来。一条又长、又走在底层薄金属上的网络,是两头吃亏的最坏情形:薄金属带来一大堆电阻,长度又带来一大堆电容。这正是长网络被“升”到上层厚金属去的更深层原因——金属更粗就砍掉了 R,延迟也就跟着降下来。

# Why a wire now costs time (intuition, not a tool command)
#   wire delay  grows with  R * C
#     R  larger on thin/narrow lower layers
#     C  larger for long wires and tightly-packed neighbors
# => long net on thin metal = slow.  Same net on thick upper metal = faster.
你在这一步并不去算精确的数字——那是下一篇的活儿。要带走的只是一个方向感:延迟跟着 R*C 这个乘积走,R 在又瘦又窄的层上最糟,而 C 随长度和拥挤程度而增大。