第4章:LibreLaneによる物理設計詳解とレポート解読(バックエンド演習版)
本章では、第3章で論理的な正しさを証明したLチカ回路(Verilog)を、シリコン上の「物理的な形(レイアウト)」へと自動変形させるバックエンド工程(物理設計)に挑みます。LibreLaneの裏側で自律動作するOpenROADの挙動を追いかけ、出力される回路の「健康診断書(レポート)」を読み解く手法を学びます。
※本章は現行版(ttsky25b / LibreLane 3.0.3)に準拠して改訂しています。 実行コマンドは tt harden ではなく ./tt/tt_tool.py --harden、成果物は runs/wokwi/... 配下です(第2章参照)。
4.1 【Step 1】プロジェクト設定の確認(info.yaml と LibreLane設定の役割分担)
物理設計(ハードニング)を実行する前に、「どのモジュールをトップとして、どのファイルを使うか」をプロジェクト記述ファイルで指示します。Tiny Tapeoutでは設定が2種類に分かれます。
- プロジェクト記述(
info.yaml):top_moduleとsource_files(=どのVerilogを使うか)を書く。 - LibreLane設定(ユーザーコンフィグ):
CLOCK_PERIOD・DIE_AREA・密度などの物理パラメータを書く。./tt/tt_tool.py --create-user-configで生成される。
info.yaml(プロジェクト記述)を開き、トップモジュールと入力ファイルを指定します。
# info.yaml(プロジェクトのメタ情報)
project:
title: "Detailed LED Blinker"
description: "A 24-bit counter based LED blinker for student laboratory."
top_module: "tt_um_led_blinker" # トップモジュール名
source_files:
- "tt_um_led_blinker.v" # 第3章で作ったVerilogファイル名
※キー名はテンプレート実物に従ってください。 世代によって source_files / input_files、ファイル形式(info.yaml / config.yaml / config.json)に差があります。使用中の ttsky-verilog-template 同梱ファイルのキー名に合わせるのが確実です。
4.2 【Step 2】ハードニング実行と裏側で動くOpenROADの5大シーケンス
WSL2の仮想環境(venv)がアクティブで、第2章の環境変数(PDK_ROOT/PDK/LIBRELANE_TAG)が設定済みの状態で、プロジェクトのルートに移動して以下を実行します。
cd ~/my_chip_project # LibreLane設定ファイルを生成 ./tt/tt_tool.py --create-user-config # 物理自動設計(ハードニング)を実行 ./tt/tt_tool.py --harden
画面には、様々なEDAツールがバトンを繋ぎながら回路を形作っていくログが流れます。内部では、以下の5大シーケンスが順に実行されています。
- 論理合成(Synthesis):
内部でYosysが起動します。RTLコードのcounter + 1という抽象的な記述を分解し、SkyWater 130nm PDKに含まれる具体的な「Dフリップフロップ(sky130_fd_sc_hd__dfxtp_2)」や「AND/ORゲート」の部品接続図(ネットリスト)へ翻訳します。 - 床配置(Floorplan):
内部でOpenROADのフロアプランエンジンが起動します。回路を敷き詰める四角い領域(ダイ)の枠線を確定させ、外部入出力ピン(clkやuo_out[0])を外周の指定座標に固定します。さらに、回路全体に安定して電気を供給するための電源格子(Power Grid)を縦横に張り巡らせます。※ダイ寸法はプロジェクト設定(タイル数や
DIE_AREA)で決まります。Tiny Tapeoutの1タイルの寸法は世代・シャトルによって異なるため、固定値の暗記ではなく自分の設定値・レポート値で確認してください。 - セル配置(Placement):
標準セルゲート部品を、領域内の「行(Row)」に沿って自動的に敷き詰めます。最初は大まかな位置を決める「グローバル配置」、次に重なりを許さず整列させる「詳細配置(Detailed Placement)」の2段階で行われます。 - クロックツリー合成(CTS:Clock Tree Synthesis):
同期回路のclk信号は、すべてのフリップフロップへできる限り同時に届く必要があります。配線長の差で生じる到着時間のズレ(クロック・スキュー)を抑えるため、OpenROADはタイミング調整用バッファを挿入し、樹状のクロック配線を構築します。 - 詳細配線(Routing):
セル同士のピンを繋ぐ信号線を、複数の金属層を立体交差させながら、ショートや断線が起きないように3次元的に自動配線します。
4.3 【健康診断書の解読】タイミングレポート(STA)の読み方演習
ハードニングが完了すると、半導体が指定速度で動くかを検証した静的タイミング解析(STA)のレポートが生成されます。
※レポートの所在について: 現行のLibreLane(OpenLane 2系)では、レポートは runs/<RUN_TAG>/reports/ 直下にまとまっているのではなく、フローの各ステップごとのサブフォルダ(例:配置後STAや配線後STAのステップ用フォルダ)に分散して出力されます。runs/wokwi/ 以下をステップ番号順にたどり、STA(OpenROAD/OpenSTA)系ステップの出力フォルダを探してください。ファイルを横断検索するなら次のコマンドが便利です。
# runs配下からタイミング系レポートを探す例 find runs/wokwi -name "*.rpt" | grep -i -E "tns|wns|sta|timing"
STAレポートには、以下のような「あるレジスタから次のレジスタへ信号が届くまでの時間」と「制限時間」の計算が並びます(数値は説明用の例)。
=== STA Setup Timing Report (SkyWater 130nm, clk=50MHz) ===
Startpoint: counter_reg[0] (rising edge-triggered FF, clocked by clk)
Endpoint: counter_reg[23] (rising edge-triggered FF, clocked by clk)
Path Group: clk
Path Type: setup (max)
Delay Time Description
---------------------------------------------------------
0.00 0.00 clock clk (rising edge)
0.45 0.45 ^ counter_reg[0]/CLK (FFにクロック到達)
0.32 0.77 v counter_reg[0]/Q (FF内部遅延を経て出力)
0.15 0.92 v _and2_/X (論理ゲート通過)
... [複数の論理ゲートを通過する遅延] ...
2.10 3.02 v counter_reg[23]/D (到達:ゴールFFの入口にデータ到着)
---------------------------------------------------------
data arrival time 3.02 (実際のデータ到着時刻)
20.00 20.00 clock clk (next rising edge) (次のクロック立ち上がり=20ns)
-0.10 19.90 clock uncertainty (ジッタ等の不確かさを差し引く)
-0.95 18.95 library setup time (FFのセットアップ時間を差し引く)
---------------------------------------------------------
data required time 18.95 (デッドライン)
---------------------------------------------------------
data required time 18.95
data arrival time -3.02
---------------------------------------------------------
slack (MET) 15.93 (➔ 余裕あり:15.93ns の余裕)
※Slackの計算(重要): セットアップ解析では slack = data required time − data arrival time です。
・data required time = クロック周期 − 不確かさ − セットアップ時間 = 20.00 − 0.10 − 0.95 = 18.95ns
・data arrival time = 3.02ns
・slack = 18.95 − 3.02 = 15.93ns(プラス=余裕あり)
旧版の例では required=16.83 と arrival=−3.02 で slack=13.81 となっていましたが、required time が「20.00 − 0.10 = 19.90」と整合せず、内部の数字が食い違っていました。STAは「制限時間(required)から到着(arrival)を引く」という関係が常に成り立つので、上記のように各行が筋の通った値になっているかを必ず確認してください。実際の数値はライブラリ・配線結果で変わります。
【試験・実験の急所】Slack(スラック)の合否判定ルール
Q1:最後の行が「slack (MET)」でプラスの値になっている場合は?
【合格】 要求された周期(この例では50MHz=20ns)に対し、信号が余裕をもって間に合っていることを意味します。このタイミング制約については、製造しても狙った速度で動作する見込みです。
Q2:もしここが「slack (VIOLATED)」でマイナスの値になっていたら?
【タイミング違反(要修正)】 次のクロックまでにデータが間に合わず、誤動作の原因になります。対策は、(1) LibreLane設定の CLOCK_PERIOD を大きくして目標周波数を下げる、(2) 回路(パイプライン化など)を見直す、(3) 配置配線の密度や合成戦略を調整する、などです。
4.4 【Step 3】面積レポートと高密度エラーの先回り対策
次に、領域をどれくらい効率よく使えているかを示す面積・利用率のレポートを確認します(ファイル名・所在はステップフォルダ内。find で area や util を含むレポートを探すと見つかります)。
# 面積・利用率系レポートを探す例 find runs/wokwi -name "*.rpt" | grep -i -E "area|util"
Chip area for module 'tt_um_led_blinker': 4200 um^2 Number of cells: 154 Utilization: 24.50 %
Utilization(セル利用率): 与えられた領域のうち、実際のゲート部品が占める面積の割合です。Lチカのような小さな回路では20〜30%程度になり、配線を通す隙間がたっぷりあるため、Routing工程は通りやすくなります。
現場の知恵: 次章でPicoRV32のようなCPUコアを詰め込むと、この値が大きく跳ね上がります。利用率が高すぎると、OpenROADは配線を通す隙間を見つけられず、Congestion(配線混雑)で停止します。その場合は、セルの密度目標(LibreLane設定の PL_TARGET_DENSITY_PCT)を下げる、ダイ面積を広げる、といった調整を行います(第5章で実践)。
4.5 【補足】レイアウトをGUIで眺める
ハードニング結果はOpenROADやKLayoutのGUIで確認できます。WSLでGUIが開かない場合は、ターミナルで xhost +local:docker を実行してからお試しください。
# OpenROADのGUIで開く ./tt/tt_tool.py --open-in-openroad # KLayoutで開く ./tt/tt_tool.py --open-in-klayout # レイアウトをPNG画像に書き出す(librsvg2-bin, pngquant が必要) ./tt/tt_tool.py --create-png