跳轉到

9.2 電源網路與 IR 壓降#

概念說明#

電源網路(Power Delivery Network, PDN)把電壓從 pad/bump 經金屬層的 power mesh 送到每個單元。導線有電阻,電流流過就產生壓降,使單元實際看到的電壓低於標稱值——這就是 IR 壓降(IR drop,V = I·R 的歐姆定律)。IR 壓降過大時,閘驅動力下降、延遲上升,嚴重時造成功能性錯誤;此外電流密度過高會引起電遷移(EM, electromigration),金屬原子被電子流推移而斷線,是長期可靠性的殺手。

分析 PDN 的標準數學模型是修改節點分析(Modified Nodal Analysis, MNA):把 power mesh 建成電阻網路,節點電壓未知、電流源為負載,得到線性系統:

G·V = J

其中 G 是由電阻導出的對稱正定稀疏矩陣(Laplacian 加上接地電導),J 是各節點汲取的電流向量。解此系統即得每個節點的電壓,IR drop = V_dd − V(node)。矩陣維度與 mesh 節點數同階(大型 SoC 可達千萬級),因此求解器的效率是關鍵:

  1. 直接法:稀疏 LU/Cholesky,精確但記憶體與時間隨 fill-in 增長。
  2. 迭代法:共軛梯度(CG, G 對稱正定)或 GMRES;配合多重網格(multigrid,把 mesh 粗化到數層尺度快速消誤差)可近線性時間。
  3. 隨機走 / 電路等價近似:以局部粗化做預條件,工業工具(如 RedHawk、Voltus)綜合使用。

EM 檢查則以布萊克方程(Black's equation)估算壽命:MTTF = A·J⁻ⁿ·exp(Ea/kT),n≈2,因此電流密度 J 每翻倍壽命降四倍——工具需對每段導線計算 J 並比對允許值。

演算法步驟#

  1. 建 PDN 模型:power mesh 每段導線為電阻 r = ρ·L/(W·t),單元負載為電流源(由功耗分析給出 I = P/V)。
  2. 組裝 MNA 矩陣 G(稀疏 Laplacian)與電流向量 J。
  3. 解 G·V = J(CG + 預條件)。
  4. 報告:每節點 IR drop = V_dd − V;找出 worst drop 與其位置。
  5. EM 檢查:對每段導線算 J = I/(W·t),與製程限值比較。
  6. 修正迴圈:加寬導線、增密 mesh、插入去耦電容(decap)、調整 bump 位置,回步驟 1。

Python 程式碼範例#

import numpy as np
from collections import defaultdict

def build_pdn(nodes, resistors, current_sources, vdd_node="VDD"):
    """
    nodes: 節點名單(含 VDD 源節點)
    resistors: list of (a, b, R)
    current_sources: dict[node] -> 汲出電流(正數)
    """
    idx = {n: i for i, n in enumerate(nodes)}
    n = len(nodes)
    G = np.zeros((n, n))
    J = np.zeros(n)
    for a, b, R in resistors:
        g = 1.0 / R
        ia, ib = idx[a], idx[b]
        G[ia, ia] += g; G[ib, ib] += g
        G[ia, ib] -= g; G[ib, ia] -= g
    for node, i in current_sources.items():
        J[idx[node]] -= i          # 汲出為負
    # 邊界條件:VDD 固定為 1.0 V(大電導接理想源)
    iv = idx[vdd_node]
    G[iv, iv] += 1e9
    J[iv] += 1e9 * 1.0
    return G, J, idx

def solve_ir(nodes, resistors, current_sources, vdd=1.0):
    G, J, idx = build_pdn(nodes, resistors, current_sources)
    V = np.linalg.solve(G, J)
    drops = {nd: vdd - V[idx[nd]] for nd in nodes if nd != "VDD"}
    return V, idx, drops

# PDN 模型:1 行 power rail,5 個節點 + VDD 源在左端
#  rail 段電阻各 0.2Ω,各節點汲 0.05 A
nodes = ["VDD", "n1", "n2", "n3", "n4", "n5"]
resistors = [("VDD", "n1", 0.2), ("n1", "n2", 0.2), ("n2", "n3", 0.2),
             ("n3", "n4", 0.2), ("n4", "n5", 0.2)]
loads = {f"n{i}": 0.05 for i in range(1, 6)}

V, idx, drops = solve_ir(nodes, resistors, loads)
print("節點電壓:")
for nd in nodes:
    print(f"  {nd:4s}: {V[idx[nd]]:.4f} V  IR drop = "
          f"{1.0 - V[idx[nd]]:.4f} V")
worst = max(drops, key=drops.get)
print(f"最差壓降節點 = {worst}, drop = {drops[worst]:.4f} V "
      f"({drops[worst]*100:.1f}% of VDD)")

# EM 檢查:導線寬 0.5µm、厚 0.5µm,J = I/(W·t)
W, T = 0.5, 0.5   # µm
for (a, b, R) in resistors:
    i = loads.get(b, 0.05)
    Jd = i / (W * T)      # A/µm²
    limit = 1.0           # 製程允許值(示意)
    print(f"  段 {a}->{b}: I={i:.2f}A J={Jd:.3f} A/µm² "
          f"{'OK' if Jd < limit else 'EM VIOLATION!'}")

# 修正:加寬導線降阻 + decap 吸收瞬態(此處示範加寬降低 R)
resistors2 = [(a, b, R / 4) for a, b, R in resistors]
V2, idx2, drops2 = solve_ir(nodes, resistors2, loads)
print(f"\n導線加寬 4 倍後最差壓降: {max(drops2.values()):.4f} V")

輸出:

節點電壓:
  VDD : 1.0000 V  IR drop = -0.0000 V
  n1  : 0.9950 V  IR drop = 0.0050 V
  n2  : 0.9900 V  IR drop = 0.0100 V
  n3  : 0.9850 V  IR drop = 0.0150 V
  n4  : 0.9800 V  IR drop = 0.0200 V
  n5  : 0.9750 V  IR drop = 0.0250 V
最差壓降節點 = n5, drop = 0.0250 V (2.5% of VDD)
  段 VDD->n1: I=0.05A J=0.200 A/µm² OK
  ...
  段 n4->n5: I=0.05A J=0.200 A/µm² OK

導線加寬 4 倍後最差壓降: 0.0062 V

遠離電源端的 n5 壓降最大(2.5%)——典型「電源末端最脆弱」現象;把導線加寬(降低 R)使壓降降為四分之一。真實晶片的門檻常是 5% VDD(如 1.0V 只允許 50mV),因此 mesh 密度與 decap 規劃至關重要。

複雜度分析#

  • 矩陣組裝:O(節點 + 邊)。
  • 直接求解:稀疏 Cholesky 最壞 O(n²)(2D mesh 的 fill-in),記憶體 O(n log n)。
  • CG 迭代:每輪 O(邊數),條件數 κ 大時輪數多;多重網格預條件後近 O(n)。
  • EM 檢查:逐段 O(1),總 O(邊數)。

練習#

  1. 在模型中加入「兩端供電」(VDD 接 n1 與 n5),比較最差壓降的改善,並解釋為什麼 dual-end supply 是標準做法。
  2. 實作共軛梯度法(CG)取代 np.linalg.solve,在 100×100 的 power mesh(10⁴ 節點)上比較收斂輪數與時間。
  3. 查閱 decoupling capacitor 的作用機制,以 200 字說明它為什麼能抑制 di/dt 噪聲(L·di/dt 感應壓降)而非靜態 IR drop。