1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

前回はNazca designを使って光導波路のCADパターンを作成する方法をご紹介しました。今回は別のpythonベースのフォトニックICのCADパターン生成ツールであるGDSFactoryをご紹介します。

🌟 GDSFactory とは?(https://gdsfactory.github.io/gdsfactory/)

「Python で 大規模なPhotonic IC のレイアウトを自動生成できるツール」として世界中で使われているオープンソースのCAD生成ツールになります。
ホームページを覗いてみると、海外の有名企業から大学研究機関で使用されているツールであり、頻繁にアップデートされており、精力的に開発が進められているソフトウェアであることが確認できます。

特徴をまとめるとこんな感じです:
• Python で パラメトリックなデバイス を生成可能
• PDK を構造化して管理できる
• FDTD / MODE / SPICE などのシミュレーションと自然に連携
• YAML・Jupyter Notebook と相性の良い モダンな構成管理
• GDS レイアウトだけでなく、
回路レベル設計(ネットリスト)→ 物理レイアウトまで対応
• pip で簡単にインストールでき、開発コミュニティも活発

フォトニクス分野で使われている「自動レイアウト生成ツール」の中では
ここ数年で最も勢いのある OSS です。

筆者も少し触ってみましたが、nazca designと比べると、
・gdsfactory は企業向けの PDK(フォトニクス製造ルール)を前提にした設計フローが強い
・シミュレーション連携・自動最適化・プロセス層管理など設計から製造まで一貫したワークフロー構築を想定
・個人で「好きな形のデバイスを自由に描きたいユーザー」より、
プロセスに沿ったパラメトリックデバイスを大量に生成するユーザーに向いている

という印象を受けました。

とはいえ、pythonでCADを書いてDRCはKlayout上で実行という使い方であれば、Nazca designとほとんど同じですが。

スクリーンショット 2025-12-01 143609.png

• 言語:Python
• 出力:GDSII(KLayoutやL-Editで開ける)
• 用途:
o シリコンフォトニクス (Si-Photonics)
o InP Photonics
o 光導波路設計
o 光集積回路の自動生成
Python を使って、
パッシブデバイスからアクティブデバイスのCADパターンを自動生成できます。
今回はGDSFactoryをつかって、導波路パターンを生成するスクリプトを組んでみましたので、ご紹介いたします。

📝今回の実施内容(GDSFactoryでリング共振器のパターンの生成)

今回作成したスクリプトは以下になります。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import gdsfactory as gf

# ============================================================
# ★ gdsfactory のセルキャッシュ・レイアウトをすべてクリア
#    → 同じスクリプトを何度実行してもセル名衝突しない
# ============================================================
gf.clear_cache()

from dataclasses import dataclass
import gdstk
import numpy as np


# ==========================
# レイヤー定義
# ==========================
@dataclass(frozen=True)
class Layers:
    CORE: tuple = (1, 0)   # 1 nmグリッドのまま使いたいレイヤー
    DUP:  tuple = (3, 0)   # COREのコピーを5 nmグリッドで配置するレイヤー

L = Layers()


# ==========================
# CORE → DUP にコピーして 5 nm スナップ
# ==========================
def duplicate_and_snap_gds(
    input_gds: str,
    output_gds: str,
    core_layer: int = 1,
    dup_layer: int = 3,
    grid_5nm: float = 0.005,
):
    """
    input_gds を読み込み、
      - layer == core_layer のポリゴンを DUPレイヤーにコピー
      - コピー側だけ 5 nm グリッドにスナップ
    して output_gds に書き出す。
    """
    lib = gdstk.read_gds(input_gds)

    for cell in lib.cells:
        new_polys = []
        for poly in cell.polygons:
            if poly.layer == core_layer:
                pts = poly.points
                pts2 = np.array(pts, float)

                # 5 nm (=0.005 µm) にスナップ
                pts2[:, 0] = np.round(pts2[:, 0] / grid_5nm) * grid_5nm
                pts2[:, 1] = np.round(pts2[:, 1] / grid_5nm) * grid_5nm

                new_polys.append(
                    gdstk.Polygon(
                        pts2,
                        layer=dup_layer,
                        datatype=poly.datatype,
                    )
                )

        for p in new_polys:
            cell.add(p)

    lib.write_gds(output_gds)
    print(f"Duplicated & snapped GDS written: {output_gds}")


# ==========================
# 導波路付きリングを配置する関数
# ==========================
def add_ring_with_bus(
    c: gf.Component,
    *,
    center=(0.0, 0.0),
    ring_radius: float = 10.0,
    ring_width: float = 0.5,
    bus_length: float = 30.0,
    bus_width: float = 0.5,
    gap: float = 0.2,
    core_layer=L.CORE,
):
    """
    Component c の中に、
      ・リング共振器
      ・直線バス導波路(矩形近似)
    を CORE レイヤー上に配置する。
    """
    cx, cy = center

    # --- リング(gdsfactory の組み込みセルを使用) ---
    ring = gf.components.ring(
        radius=ring_radius,
        width=ring_width,
        angle_resolution=2.5,
        layer=core_layer,
    )
    ring_ref = c.add_ref(ring)
    ring_ref.move((cx, cy))  # リング中心を (cx, cy) に移動

    # --- バス導波路(矩形で近似) ---
    bus = gf.components.rectangle(
        size=(bus_length, bus_width),
        layer=core_layer,
    )
    bus_ref = c.add_ref(bus)

    bus_center_y = cy + ring_radius + gap + bus_width / 2
    bus_center_x = cx

    bus_ref.move(
        (
            bus_center_x - bus_length / 2,
            bus_center_y - bus_width / 2,
        )
    )

    return ring_ref, bus_ref


# ==========================
# メイン
# ==========================
if __name__ == "__main__":
    c = gf.Component("All_Rings")

    add_ring_with_bus(
        c,
        center=(0.0, 0.0),
        ring_radius=10.0,
        ring_width=0.5,
        bus_length=30.0,
        bus_width=0.5,
        gap=0.2,
        core_layer=L.CORE,
    )

    add_ring_with_bus(
        c,
        center=(40.0, 0.0),
        ring_radius=8.0,
        ring_width=0.4,
        bus_length=25.0,
        bus_width=0.4,
        gap=0.25,
        core_layer=L.CORE,
    )

    add_ring_with_bus(
        c,
        center=(0.0, 30.0),
        ring_radius=6.0,
        ring_width=0.4,
        bus_length=20.0,
        bus_width=0.4,
        gap=0.3,
        core_layer=L.CORE,
    )

    raw_gds = "rings_raw.gds"
    c.write_gds(raw_gds)
    print(f"Raw GDS written: {raw_gds}")

    output_gds = "rings_with_5nm_copy.gds"
    duplicate_and_snap_gds(
        raw_gds,
        output_gds,
        core_layer=L.CORE[0],
        dup_layer=L.DUP[0],
        grid_5nm=0.005,
    )

📝 このスクリプトの目的と実行内容

今回紹介するスクリプトは、gdsfactory + gdstk + NumPy を組み合わせて、光導波路パターンを自動生成しつつ、特定レイヤーだけ 5 nm グリッドに変換して重ね書きさせるためのものです。

🎯 スクリプトの目的

1. gdsfactory で複数のリング共振器+バス導波路をパラメトリックに生成する
o 半径、導波路幅、ギャップなどを自由に変更可能
o 同一 Component に複数のリングをまとめて配置する
2. 生成された GDS から、CORE レイヤーの図形だけを抽出して別レイヤーへコピーする
3. コピー側のみ「5 nm グリッドにスナップ(量子化)」する
o → 1 nm グリッドの形状を粗い 5 nm グリッドに丸める
o → 近似処理や製造ルール検証などに使える
4. 処理後の新しい GDS を書き出す
つまり、
「元の形状は保持しつつ、別レイヤーに粗いグリッドのコピーを自動生成する」
という CAD/Mask 設計でありがちな処理をワンショットで実行できるスクリプトです。


🔍 スクリプトが実行している内容の流れ

① gdsfactory のキャッシュをクリア
gf.clear_cache()
gdsfactory はセル名の重複を避けるためセルキャッシュを持っていますが、
同じスクリプトを何度も走らせる時に「セル名衝突」が起きることがあります。
そこで実行のたびに 完全初期化します。


② レイヤー定義
class Layers:
CORE = (1, 0)
DUP = (3, 0)
• CORE (1,0) … 元の導波路形状を描くレイヤー
• DUP (3,0) … 5 nm グリッドにスナップしたコピーを置くレイヤー
後工程で「元の図形」と「量子化した図形」を比較できるように分離しています。


③ リング+バス導波路を配置する関数
def add_ring_with_bus(...):
gdsfactory のコンポーネントを利用して
• リング共振器(ring)
• 矩形バス導波路(rectangle)
を指定した center に自動配置するためのユーティリティです。
リング中心を座標指定し、
バス導波路は リング外周 + gap の位置に自動配置されます。


④ 3つのリング構造を配置
メイン処理では異なるパラメータのリングを 3 つ作って並べています。
例:
• 半径 10 µm のリング(原点付近)
• 半径 8 µm のリング(+X 方向に 40 µm)
• 半径 6 µm のリング(+Y 方向に 30 µm)


⑤ GDS 出力(元の CORE レイヤーのみ)
c.write_gds("rings_raw.gds")
この段階で gdsfactory だけで生成した純粋な GDS が得られます。


⑥ CORE レイヤーを別レイヤーへコピーし、5 nm スナップする
duplicate_and_snap_gds(...)
gdstk を使って処理を行います。
処理内容

  1. rings_raw.gds を読み込む
  2. layer==CORE のポリゴンだけ抽出
  3. NumPy で頂点座標を 5 nm (=0.005 µm) グリッドに丸め(スナップ)
  4. pts2[:,0] = np.round(pts2[:,0] / 0.005) * 0.005
  5. 新しいレイヤー DUP (3,0) として GDS に追加
  6. rings_with_5nm_copy.gds として保存

📦 出力される2つの GDS
ファイル名 内容
rings_raw.gds gdsfactory が生成したオリジナル構造(CORE レイヤーのみ)
rings_with_5nm_copy.gds 元の CORE + 5 nm グリッドに丸めた DUP レイヤーの両方が入った GDS

✨ 出力結果
それでは生成されたrings_with_5nm_copy.gdsを開いてみます。
画像2.png
グリッド1nmのパターン上にグリッド5nmに変換したパターンの重ね書きがうまくできていることが確認できます。

今回ご紹介しただけでなく、GDSFactoryにはDRC機能などもあり、活用すれば大規模なPICの作成も容易にできるでしょう。

※本記事は筆者個人の見解であり、所属組織の公式見解を示すものではありません。

問い合わせ

光学シミュレーションソフトの導入や技術相談、
設計解析委託をお考えの方はサイバネットシステムにお問合せください。

光学ソリューションサイトについては以下の公式サイトを参照:
👉 光学ソリューションサイト(サイバネット)

光学分野のエンジニアリングサービスについては以下の公式サイトを参照:
👉 光学エンジニアリングサービス(サイバネット)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?