1990年、NHKが「電子立国日本」と持て囃した半導体業界に 30年ぶりにスポットライトが当たっています。舞台に立っているのは最先端製造技術ですが、ここでは裏方として舞台を支えてきた製造+設計の橋渡し役である PDK や半導体の開発コスト構造、レガシー半導体の活用等々、製造技術に偏りがちの半導体を設計やビジネス面からの切り口で論考を上げて来ました。今回は、生業である設計エンジニアから見たオープンソース EDA ツールである KLayout の Python API に関して簡単に紹介したいと思います。設計者だけでなく、製造やプロセス開発畑の方にも参考になる内容に膨らましていますので、ご笑読頂ければ幸いです。
なお、本内容は、過去の業務経験を元にした、個人的意見・見解の表明であり、いかなる組織を代表したものではありません
第一回の「Klayout の Python API を試してみた!」では、Layout と Cell Class に関して解説。第二回では Instance Class に関して解説。第三回では Pcell のパラメーター変更とファイルの保存。第四回では Python API で PCell を作成。第五回では、本格的に TR-1um 向けの PCell Library のプロトを開発しました。第六回では、第五回で積み残した PCell 関連 Python API の詳細に関して説明します。
PCellDeclarationHelper
第五回の PCell 開発でリファレンスい使った sky130 の fet.py では PCellDeclarationHelper class を継承した class pfet(PCellDeclarationHelper) の中で以下のメソッド関数を定義しています。
- __init__(self)
- display_text_impl(self)
- coerce_parameters_impl(self)
- can_create_from_shape_impl(self)
- parameters_from_shape_impl(self)
- transformation_from_shape_impl(self)
- produce_impl(self)
前回開発した pfet.py では (1),(2),(7) のメソッド関数を定義していますが、それ以外のメソッド関数の働きに関して深堀りします。
なお、各メソッドの詳細に関しては Class PCellDeclarationHelper を参照下さい。以下、和訳になります。
2. display_text_impl(self)5.
説明: 表示テキストを配信します
このメソッドは、人間が読める形式で PCell を識別する必要があります。このテキストは、PCell の Cell Tree にも表示されます。
3. coerce_parameters_impl(self)
説明: パラメータを強制します。
このメソッドは、パラメータを調整して一貫性のあるパラメータセットをレンダリングし、パラメータ範囲のエラーを修正することを目的としています。このメソッドは、例えば PCell ユーザーインターフェース内で「Apply」ボタンが押された際に呼び出され、実際のパラメータを計算します。
__init__(self) で指定したパラメーターに人間が不正な値を入れた場合は coerce_parameters_impl(self) の中で修正します。例えば、トランジスタの L=**-1** が入力された場合はデフォルトの値に強制修正するとかです。
4. can_create_from_shape_impl(self)
説明: 指定された形状から PCell を作成できる場合は true を返します。
PCell が Shape オブジェクトを通じて利用可能なシェイプから作成できる場合、このメソッドは true を返します。シェイプが存在するレイアウトには layout、レイヤーには layer でアクセスできます。
デフォルトの実装では false を返します。
5. parameters_from_shape_impl(self)
説明: 図形からパラメータを設定します。
can_create_from_shape_impl が true を返す場合、このメソッドが呼び出され、指定されたシェイプ( shape、layout、layerを参照)のパラメータが設定されます。layer パラメータを設定するには LayerInfo オブジェクトを作成する必要があります。つまり、以下のように記述します。
self.l = self.layout.get_info(self.layer)
デフォルトの実装では何も行われません。このメソッドで設定されていないすべてのパラメータにはデフォルト値が設定されます。
例えば「layer」というパラメータを使用すると、パラメータゲッターは「layer」引数を隠蔽します。この場合、引数には「_layer」を使用してください(「layout」、「shape」、「cell」の場合も同様です)。
self.l = self.layout.get_info(self._layer)
む〜意味がわからん。。。
6. transformation_from_shape_impl(self)
説明: シェイプから作成するときに、初期の PCell インスタンス変換を取得します。
can_create_from_shape_impl が trueを返す場合、このメソッドが呼び出され、指定されたシェイプから初期変換を取得します(shape、layout、layerを参照)。
このメソッドは Trans オブジェクトを返す必要があります。デフォルトの実装では、単位変換(変位や回転なし)を返します。
7. produce_impl()
説明: レイアウトを生成します
パラメータアクセサメソッドによって提供されるパラメータ値と、layout と cell を介したレイアウトとセルを使用して、このメソッドは指定されたセル内の最終的なレイアウトを生成します。
具体的な例
3. coerce_parameters_impl(self)
PCell parameter の入力 pane でパラメーターを手入力して「Apply」ボタンを押した後で、入力されたパラメーターから導出が必要な内部変数を計算します。以下実験して見ます。
class pfet(pya.PCellDeclarationHelper):
def __init__(self):
# Initialize super class.
super(pfet, self).__init__()
#
self.param("type", self.TypeString, "Type", default="PFET")
#
self.param("l", self.TypeDouble, "Length", default=fet_lp, unit="um")
self.param("w", self.TypeDouble, "Width", default=fet_wp, unit="um")
self.param("a", self.TypeDouble, "Area", default=(fet_lp*fet_wp), readonly=True, unit="um^2")
#
def display_text_impl(self):
# Provide a descriptive text for the cell
return "pfet(L=" + ('%.3f' % self.l) + ",W=" + ('%.3f' % self.w) + ",Area=" + ('%.3f' % self.a) + ")"
def coerce_parameters_impl(self):
self.a = self.w * self.l
return()
Area は Readonly ですので L/W から計算されます。
Create PCell from shape
Rudy での実装のマニュアルの説明の和訳
以下の3つのメソッドの実装は任意です。これらは、KLayoutの編集メニューで「Convert to PCell」が選択されている場合、既知のPCellごとに「can_create_from_shape_impl」が呼び出されます。このメソッドには、形状、レイアウト、レイヤーが渡されます。このメソッドが「true」を返した場合、KLayout はこの PCell を変換対象としてリストに提示します。この PCell が選択されると、KLayout は「parameters_from_shape_impl」と「transformation_from_shape_impl」を呼び出し、その形状から作成される新しい PCell の初期パラメータと初期変換を取得します。「parameter_from_shape_impl」は、実装本体で対応するセッターが設定されていない限り、すべてのパラメータにデフォルト値を使用します。
ちなみに sky130 の fet.py では以下の記載になっています。
4. can_create_from_shape_impl(self)
def can_create_from_shape_impl(self):
# Implement the "Create PCell from shape" protocol: we can use any shape which
# has a finite bounding box
return self.shape.is_box() or self.shape.is_polygon() or self.shape.is_path()
5. parameters_from_shape_impl(self)
def parameters_from_shape_impl(self):
# Implement the "Create PCell from shape" protocol: we set r and l from the shape's
# bounding box width and layer
self.r = self.shape.bbox().width() * self.layout.dbu / 2
self.l = self.layout.get_info(self.layer)
6. transformation_from_shape_impl(self)
def transformation_from_shape_impl(self):
# Implement the "Create PCell from shape" protocol: we use the center of the shape's
# bounding box to determine the transformation
return pya.Trans(self.shape.bbox().center())
Convert to PCell の具体例
EDit -> Selecction -> "Convert to PCell" を選択します。
具体的な事例として Shape:PATH を Basic:PCell:Round Path に変更してみます。
実行すると Shape が PCell に替わります。
can_create_from_shape_impl(self) は、既存の Shape を PCell に変更する際、必要な parameter 情報を取得する時に使われる様です。
結論
TR-1um 用の PCell では当面実装しないことにします。
PCell の開発(途中)
以上のような手順で TR-1um 用の PCell を開発しています。以下、パラメーターとして (l,w,finger)の変更を可能にした pfet と nfet の PCell です。
まとめ
Python API を使って GDSII ファイルの内部構造へのアクセスを試してみました。Cadence の Skill と同じく、EDA ツールの Layout データに直接アクセスできる手段があると、設計の効率を上げるツールを自ら開発することが可能になります。チュートリアルが乏しいことは、少し残念ではありますが、振り返ると 1987 年に導入した Cadence の前身の SDA 社の Edge ツール で Skill 言語を学んだ時も、資料が乏しい中で Cut & Try だった事を思い出しています。皆さんも是非挑戦して見て下さい。





