跳轉到

10.1 機器學習在EDA的應用#

概念說明#

傳統 EDA 演算法以精確數學模型(Elmore delay、HPWL、SAT、MNA)為核心,但它們有共同的瓶頸:模型與真實物理/製造之間的落差,以及搜尋空間大到無法窮舉。機器學習(ML)在兩個方向切入:

  1. 更準的代理模型(surrogate model):以神經網路學習「設計特徵 → PPA(功耗/效能/面積)」的映射,取代昂貴的模擬或 STA。例如以 GNN(圖神經網路)直接在 netlist 圖上預測擁塞、繞線資源需求;以 GCN 預測寄生電容;繞線前的 congestion 預測可省去 GR-DR 迭代。Google 的晶片佈局論文(2021, Nature)以強化學習做巨塊(macro)擺放,把「放置決策序列」建模為馬可夫決策過程,以 policy gradient 訓練——雖然學界對其基線比較有爭議,但確實開啟了 RL-for-placement 的研究熱潮。
  2. 更好的搜尋策略:合成中的邏輯優化序列(如 ABC 的 resyn、resyn2、resyn3 各種 script 組合)傳統上靠人挑,ML 可學「哪個序列對這個設計最有效」(如貝葉斯優化、強化學習選擇動作)。驗證中的覆蓋率收斂(見 5.1 的 bias 回饋)也可由 RL 接手。

ML 在 EDA 的獨特挑戰:(1) 資料稀缺——一個晶片的設計資料是公司機密且樣本極少,難以像影像那樣做大資料訓練;(2) 分佈漂移——換製程節點或換設計風格,模型立刻失準;(3) 正確性要求——EDA 的答案錯了就是流片失敗,ML 通常只能「預測 + 用精確工具驗證」,無法單獨擔綱。因此目前的主流範式是 ML-in-the-loop:ML 提供快速估計與候選排序,精確演算法做最終確認。

演算法步驟(GNN 擁塞預測 + 用於繞線引導)#

  1. 把 netlist 編碼為異質圖:節點 = 單元(特徵:類型、面積、層數)、邊 = net(特徵:扇出、驅動強度)。
  2. 訓練資料:歷史設計的「佈局後、繞線後」真實擁塞圖。
  3. GNN 訊息傳遞:k 層圖卷積聚合鄰域特徵,輸出每個 GCell 的預測擁塞。
  4. 推論:對新設計的佈局做預測,得到擁塞熱圖。
  5. 下游使用:全局繞線的邊成本加上「預測擁塞懲罰」,或提前對熱區做單元散開(placement refinement)。

Python 程式碼範例#

以下用一個極簡的「訊息傳遞」GNN(純 numpy,不依賴框架)示範 netlist 特徵學習的骨架:以隨機初始化的權重聚合鄰居資訊,輸出每節點的擁塞預測分數。

import numpy as np

def build_graph(nets, n_cells):
    """netlist -> 鄰接串列(net 展開成團)"""
    adj = [[] for _ in range(n_cells)]
    for net in nets:
        for a in net:
            for b in net:
                if a != b:
                    adj[a].append(b)
    return [sorted(set(x)) for x in adj]

def features_of(cells, nets_of):
    """節點特徵:[面積, 扇出數, 是否時脈]"""
    return np.array([[c.get("area", 1.0) / 10.0,
                      nets_of[i] / 5.0,
                      1.0 if c.get("is_clk") else 0.0]
                     for i, c in enumerate(cells)])

def gnn_forward(F, adj, W1, W2, layers=3):
    """簡化 GNN:H' = relu(鄰居平均 @ W1 + 自身 @ W1),最後線性到分數"""
    H = F
    for _ in range(layers):
        Hn = H.copy()
        for v in range(len(H)):
            if adj[v]:
                agg = H[adj[v]].mean(axis=0) @ W1 + H[v] @ W1
                Hn[v] = np.maximum(0, agg)
        H = Hn
    return H @ W2        # 每節點一個擁塞分數

def train_demo():
    rng = np.random.default_rng(0)
    cells = [{"area": rng.uniform(1, 10), "is_clk": rng.random() < 0.05}
             for _ in range(50)]
    nets = []
    for _ in range(30):
        k = rng.integers(2, 5)
        nets.append(list(rng.choice(50, k, replace=False)))
    nets_of = {i: 0 for i in range(50)}
    adj = build_graph(nets, 50)
    for net in nets:
        for c in net:
            nets_of[c] += 1
    F = features_of(cells, nets_of)
    W1 = rng.normal(0, 0.5, (3, 3))
    W2 = rng.normal(0, 0.5, (3, 1))
    scores = gnn_forward(F, adj, W1, W2).ravel()
    top = np.argsort(-scores)[:5]
    print("預測擁塞風險 Top-5 單元:")
    for i in top:
        print(f"  cell{i:2d}  分數={scores[i]:.3f}  "
              f"扇出={nets_of[i]}  面積={cells[i]['area']:.1f}")
    return scores, nets

scores, nets = train_demo()

# 模擬「真實擁塞」:以實際繞線使用量為標籤(示範訓練迴圈的資料流)
usage = {}
for net in nets:
    for c in net:
        usage[c] = usage.get(c, 0) + 1
true_hot = sorted(usage, key=lambda c: -usage[c])[:5]
print("\n實際高使用量 Top-5:", true_hot)
print("(訓練目標即為讓 scores 與此類真實標籤的排序一致)")

輸出示意:

預測擁塞風險 Top-5 單元:
  cell12  分數=1.842  扇出=4  面積=8.7
  cell31  分數=1.655  扇出=4  面積=6.2
  ...
實際高使用量 Top-5: [12, 31, 7, 44, 3]
(訓練目標即為讓 scores 與此類真實標籤的排序一致)

範例展示 ML-in-EDA 的資料流:netlist → 圖特徵 → GNN 分數 → 與真實標籤(實際繞線使用量)比對 → 反向傳播更新權重。真實系統中 scores 會被佈局器/繞線器當作先驗,直接改變演算法的搜尋順序。

複雜度分析#

  • GNN 訊息傳遞:O(L·(|V|·d² + |E|·d)),L 為層數、d 為特徵維度。
  • 推論速度:一次前向在毫秒~秒級,比執行完整 GR-DR 迭代快 10³~10⁵ 倍——這是代理模型的價值。
  • 訓練:瓶頸在「標籤取得」(需跑完整流程),遷移學習與自監督是當前研究重點。

練習#

  1. 把 gnn_forward 的聚合從 mean 改成 max-pooling,觀察對高扇出節點分數的影響。
  2. 實作簡單的訓練迴圈:以「實際使用量歸一化」為標籤,用梯度下降更新 W1、W2(100 輪),量測 Top-5 預測的命中率。
  3. 查閱 Google 的 RL 佈局論文與其後的重現性研究,以 300 字整理「RL 佈局目前與傳統工具的真實差距」。