1990年、NHKが「電子立国日本」と持て囃した半導体業界に 30年ぶりにスポットライトが当たっています。舞台に立っているのは最先端製造技術ですが、ここでは裏方として舞台を支えてきた製造+設計の橋渡し役である PDK や半導体の開発コスト構造、レガシー半導体の活用等々、製造技術に偏りがちの半導体を設計やビジネス面からの切り口で論考を上げて来ました。今回は、生業である設計エンジニアから見たオープンソース EDA ツールである KLayout の Python API に関して簡単に紹介したいと思います。設計者だけでなく、製造やプロセス開発畑の方にも参考になる内容に膨らましていますので、ご笑読頂ければ幸いです。
なお、本内容は、過去の業務経験を元にした、個人的意見・見解の表明であり、いかなる組織を代表したものではありません
KLayout
KLayout は、2006年に Ver 0.9 を正式リリースされた、GDSII/OASIS データの Viewer/Editor で、ドイツの Matthias Koefferleinさんが、管理している GitHub にて、オープンソースEDAツールとして開発されています。2025年11月時点での最新版は 0.30.5 で以下のような機能が実装されています。
Viewer
- オーバーレイ機能: 複数のレイアウトを 1 つのウィンドウに読み込むことができます
- 非常に柔軟なレイヤー構成:塗りつぶしパターン、フレームと塗りつぶしの色の選択など、豊富な表示オプション。アニメーション、透明化、暗転/ハイライト表示など…
- レイヤーのグループ化: レイヤーのグループの表示プロパティを一度に変更できます
- 高度なレイヤー表示属性: レイヤーに名前を付けたり、追加の変換を行ったり、特定の階層レベルを選択したり、プロパティで図形を選択したりできます。
- レイヤー属性を他のパネルにコピーして貼り付ける
- 描画順序: 一番上に表示するレイヤーを選択します
- 階層を降りる: コンテキストに埋め込まれたセルを表示します
- 柔軟なルーラー:無制限の数、柔軟な表示スタイル。複数のテンプレートを設定でき、ルールは編集(移動、削除、コピー&ペースト)できます。
- シェイプとインスタンスブラウザ
- ブックマーク、さまざまなズーム モード、マウス ホイールのサポート、スクリーンショット機能など...
- レイヤープロパティ、ルーラーの元に戻す/やり直し...
- 保存: レイアウトまたはその一部 (セル、レイヤー) を、スケーリングまたは異なるデータベース単位で別の形式で保存します。
- 画像オーバーレイ機能: 画像ファイル (jpg、png、gif など) を読み込んで、レイアウト内の任意の位置に配置できます。
- マーカー ブラウザ: 特定のエラー レポート ファイルを読み込むことができ、ブラウザ ツールが提供されます。
- 画像を反転/回転するためのグローバル変換
エディタ
- 多くのオプションを備えたスマートな描画機能: 角度制約、グリッド...
- サブセル内での真のインプレース編集、バリアント構築機能
- 無制限の元に戻す/やり直し
- 図形を引き伸ばしたり、エッジや頂点を移動したりするためのスマートな部分編集機能
- 図形やセル全体をコピーして他のレイアウトに貼り付けることもできます
- 多くの高度な編集機能: 階層操作、ブール演算、クリップ、角の丸め、サイズ変更、配置、レイヤー操作...
- レイアウトに動的にバインドされた外部ライブラリのサポート
- パラメータ化可能なセル(PCell)
その他の機能
- さまざまな便利なユーティリティ関数: XOR ツール、レイアウト差分ツール、塗りつぶしツール...
- 検証とレイヤー操作の基本セットを備えたDRC機能
- LVSの機能
- 特別なクエリ言語を使用した強力な検索と置換機能
- テクノロジーパッケージマネージャー
- アドオンパッケージマネージャー(「Salt」)
東海理化の PDK が公開された以降、KLayout を弄り始めましたが、まぁ良くできています。欧州のオープンソースシリコン界隈(= FSi )では、KLayout をカスタムレイアウトの中心ツールとして見ている様です。今年の FSiC2025 では、Matthias 本人の発表の他にも、PEX の開発状況等が発表されていますので、ご興味がある方は、FSiC2025 のサイトから発表資料をダウンロード下さい。
KLayout Python API
OpenSUSI の東海理化の TR-1um リポジトリには、KLayout 向けの DRC/LVS の Runset とその開発ドキュメントを Tutorial としてまとめています。DRC/LVS の開発にご興味があるかたは、そちらもご参考下さい。
本稿では、更に KLayout を使いこなすための KLayout Python API を紹介いたします。ちなみに、私の MAC Book Pro には homebrew にて install しています。
ちょっとした準備
homebrew で KLayout をインストールすると、基本 GUI モードでの利用になりますが、MAC の Terminal から headless で使いたいので、~/.zprofile にて以下のように alias を指定します。
alias klayout=/Applications/klayout.app/Contents/MacOS/klayout
参考リンク
東海理化向けの DRC/LVS を開発していた時にも感じていましたが、KLayout はリファレンスマニュアルが豊富なのに比べて、チュートリアル情報が少なく、どうしても Cut & Try で確かめながら機能を確認していかないとならないです。Python API のリファレンスも大変シンプルですので、実験しながら先に進みます。
Layout の Cell 構造へのアクセス
以下のような Python コードを書いて GDSII ファイルを読み込んで見ます。
#! /usr/bin/env python3
import sys
import klayout.db as db
#
ly = db.Layout()
args = sys.argv
#
ifile = args[1]
#
ly.read(ifile)
#
if ly.top_cells() != None :
for cl in ly.top_cells():
print("TOP_CELL:" + cl.name)
exit
小セルがない、単一階層の GDSII を読み込んだ結果は、以下の通りになります。
$ ./TEST1.py out.gds
TOP_CELL:OUT_TOP
東海理化から提供されている STDLIB を読み込んで見ます。TOP が複数ある GDSII なので、以下のようになります。
$ ./TEST1.py IP62_5_stdcell.gds
TOP_CELL:MUX2
TOP_CELL:DFFR
....
TOP_CELL:CLKBUF_X12
TOP_CELL:DFFS
次に、PCELLを複数小セルとして配置した GDSII を読み込んで見ます。
% ./TEST1.py TEST_LVS.gds
TOP_CELL:TEST_LVS
今度は、以下のような Python コードを書いて、同じ GDSII ファイルを読み込んで見ます。
#! /usr/bin/env python3
import sys
import klayout.db as db
#
ly = db.Layout()
args = sys.argv
#
ifile = args[1]
#
ly.read(ifile)
#
if ly.each_cell() != None :
for cl in ly.each_cell():
print("CELLs:" + cl.name)
exit
./TEST2.py TEST_LVS.gds
CELLs:RR
CELLs:CSIO
CELLs:RS
CELLs:TEST_LVS
今度は、each_cell では無くて each_cell_bottom_up を使って、下の階層から順番にセルをアクセスして見ます。
#! /usr/bin/env python3
import sys
import klayout.db as db
#
ly = db.Layout()
args = sys.argv
#
ifile = args[1]
#
ly.read(ifile)
#
if ly.each_cell() != None :
for idx in ly.each_cell_bottom_up():
print("CELL(%3d):" % idx + ly.cell(idx).name)
exit
実行すると以下のようになります。each_cell_bottom_up は cell の index のリストを返します。
% ./TEST3.py TEST_LVS.gds
CELL( 2):RS
CELL( 1):CSIO
CELL( 0):RR
CELL( 3):TEST_LVS
今度は、下の階層から親セルを表示できるように、以下のようにプログラムに改造します。
#! /usr/bin/env python3
import sys
import klayout.db as db
#
ly = db.Layout()
args = sys.argv
#
ifile = args[1]
#
ly.read(ifile)
#
if ly.each_cell() != None :
for idx in ly.each_cell_bottom_up():
cl = ly.cell(idx)
print("CELL(%2d):%-10s" % (idx, cl.name), end='>> ' )
for id in cl.each_parent_cell() :
print( "PARENT(%2d):%-10s" % (id, ly.cell(id).name), end=' ' )
#
print()
#
exit
実行すると。
% ./TEST3.py TEST_LVS.gds
CELL( 2):RS >> PARENT( 3):TEST_LVS
CELL( 1):CSIO >> PARENT( 3):TEST_LVS
CELL( 0):RR >> PARENT( 3):TEST_LVS
CELL( 3):TEST_LVS >>
each_parent_cell は 親セルの index の list を返してくれます。小セルは複数の親セルから参照されることもあるので list を返すようになっています。
今度は each_cell_top_down を使って、上の階層から順番にセルをアクセスして、階層毎に配置されている小セルを表示するコードを書いて見ます。
#! /usr/bin/env python3
import sys
import klayout.db as db
#
ly = db.Layout()
args = sys.argv
#
ifile = args[1]
#
ly.read(ifile)
#
if ly.each_cell() != None :
for idx in ly.each_cell_top_down() :
cl = ly.cell(idx)
print("CELL(%2d):%-10s" % (idx, cl.name), end='>> ' )
for id in cl.each_child_cell() :
print( "CHILD(%2d):%-10s" % (id, ly.cell(id).name), end=' ' )
#
print()
#
exit
実行すると
% ./TEST4.py TEST_LVS.gds
CELL( 3):TEST_LVS >> CHILD( 0):RR CHILD( 1):CSIO CHILD( 2):RS
CELL( 0):RR >>
CELL( 1):CSIO >>
CELL( 2):RS >>
上記の様に Python API を使って、Klayout の Layout DB 内のセル構造にアクセスできることができました。Klayout の Class Library には、Ruby からも Python からでもアクセスができる様ですが、コンパイル時にそれぞれの interpreter と一緒に Build する必要があります。
なお、上記の例の Python code では、Module:db の Layout class と Cell class を使っています。それぞれの Class の詳細はこちらを参照下さい
まとめ
Python API を使って GDSII ファイルの内部構造へのアクセスを試してみました。Cadence の Skill と同じく、EDA ツールの Layout データに直接アクセスできる手段があると、設計の効率を上げるツールを自ら開発することが可能になります。チュートリアルが乏しいことは、少し残念ではありますが、振り返ると 1987 年に導入した Cadence の前身の SDA 社の Edge ツール で Skill 言語を学んだ時も、資料が乏しい中で Cut & Try だった事を思い出しています。皆さんも是非挑戦して見て下さい。