見出し画像

Klayout の使い方 その3:LVS

1.LVS とは

LVS (Layout versus Schematic) とは,作成したレイアウトが想定している回路図と同じ接続関係になっているかどうかをチェックする工程です.配線が意図しないところでつながってしまっている,というようなミスを検出できます.大変ありがたいんですが,往々にして LVS のエラー修正はどこでミスしているのかを特定するのが難しいことが多く,ものすごく辛いです.LVS を通っていなくても製造は可能ですが,そのチップが正常動作することはまずありません.がんばりましょう.

Skywater 130 nm では現時点 (2022年8月) で,Klayoutだけで LVS を完結することができず,netgen という別のツールを使う必要があります.

2.回路図の準備

回路図とレイアウトを比較するので,当然ながら回路図とレイアウトの両方が必要です.まずは回路図を用意します.xschem を起動して,buf1 にピンをつけただけの回路を作ります.buf1 はスタンダードセルです.xschem 起動画面の Digital standard cells から gates_sky130 もしくは all_sky130_gates を選びます.

TOP.sch  のスタセル選択メニュー

その中から buf_1 を選びましょう.もしくは,インスタンス挿入で /foss/pdk/sky130A/libs.ref/xschem/  の sky130_stdcells から buf_1.sym を挿入でも構いません.buf1 を置いたら,入力端子に ipin,出力端子に opin をつないでそれぞれ名前を in,out にします.

buf にピンをつけた回路

シミュレーションをするわけではないので,モデルカード (TT_MODEL) は不要です.セーブしたら右上の Netlist ボタンを押してネットリストを生成し,~/.xschem/simulations/filename.spice  を作業ディレクトリにコピーしておきます.中身は下のようになっているはずです.

** sch_path: /foss/designs/klayout/buf1.sch
**.subckt buf1 in out
*.ipin in
*.opin out
x1 in VGND VNB VPB VPWR out sky130_fd_sc_hd__buf_1
**.ends
.end

ピンは in/out の2つに見えますが,電源・グラウンド・P基板・N基板も端子をもっていることが分かります.

3.レイアウトの作成

レイアウトを作成します.klayout を起動したら,/foss/pdk/sky130A/libs.ref/sky130_fd_sc_hd/gds/sky130_fd_sc_hd.gds  を開きます.このレイアウトの中から sky130_fd_sc_hd__buf_1 をコピーし,新規レイアウトにコピーします.トップセルにインスタンスとして置きます.デバイスの構造としてはインスタンスを置くだけで終わりですが,どこが何という端子かを表すためにピンとラベルを追加する必要があります.下図の5箇所です.

buf_1 のレイアウトとピン

バッファはインバータを2つつなげたものです.左側のゲートにつながっている li が入力 (in),右側のドレインにつながっている li が出力 (out),上の met1 が電源 (VPWR),下の met1 がグラウンド (VGND) です.上側の nwell がウェル電位 (VPB) です.nwell なのになんで VPB? という感じもしますが,たぶん pMOS の Backgate で PB です.VNBは? 不要です.VNB は (ここでは) p基板 が自動的に VNB になります.

要確認:トリプルウェルのとき pwell が VNB になることを確認.

レイアウトでのピン指定は,ピン指定用のレイヤーとラベルを使います.レイヤーリストを見ると,met1 というレイヤーにも下のような種類があることが分かります.

レイヤー

"drawing" が普通の描画レイヤーで,このレイヤーは実際にマスク製造に利用されます.それとは別に,"pin" はピン指定用のレイヤーです.まず,met1.pin の Box を電源線の met1.drawing  に重ねて置きます.pinレイヤーはマスク製造には使われないので,形は適当で構いません.pinを置いたら,次はピンに名前をつけます.met1.label  レイヤーを選び,Text でピン名 (VPWR) を pin の Box に重なるように置きます.下図のような感じになります.Text size の指定が反映されないので字が小さくて見えにくいですが…

VPWRピンを置いたところ

これで,met1.pin  と重なっている met1.drawing  が,"VPWR" という名前の端子であることが指定できました.

ここで注意してもらいたいのは,met1.pin  も met1.label  も端子の識別用であってマスク製造には使われないということです.そのため,これらのレイヤーは met1.drawing  と重なって初めて用を成します.met1.drawing  のない場所に pin と label を置いても無視されます.

他のピンも同様に指定したらレイアウトの準備は完了です.セーブしておきましょう.

4.ネットリストの抽出

レイアウトから回路図 (ネットリスト) を抽出します.
Tools → LVS から sky130A.lylvs  を実行します.

LVS (用のネットリスト抽出スクリプト)

LVS の下に sky130A.lylvs が現れない場合は,Manage Technologies で LVS ディレクトリが作られていること,および Macros → Macro Development で LVSタブに sky130A が読み込まれていることを確認してください.

Macro Development の LVSスクリプト

スクリプトを実行すると,以下のような表示になって抽出が実行されます.終わると自動で閉じて元の画面に戻ります.

ネットリスト抽出中

LVS という名前になっていながら,実はこのスクリプトはネットリストの抽出までしかやってくれません.きちんと定義すれば LVSの実行からグラフィカルな LVS の結果の確認もできるのですが,今のところそういうスクリプトは整備されていないようです.誰か作らないかな. (とオープンソース界隈で発言すると「よしお前が作れ」と言われる.)
ちなみに MakeLSI の OpenRule 1um ではちゃんとLVS できます.

LVSが終わると,作業ディレクトリに "cellname_extracted.spice" というファイルができているはずです.これが抽出されたネットリストで,buf1 の場合は以下のような内容になっているはずです.必要なピンがきちんと定義されていることを確認してください.ピンが足りない場合はレイアウトにきちんと pin,label が置かれているか確認してください.また,"pin VGND, VPWR" のように1行に複数書かれている場合はそのピンは短絡しています.これもレイアウトを修正しましょう.

* Extracted by KLayout on : 04/08/2022 19:10

* cell buf1
* pin VPB
* pin out
* pin in
* pin VGND
* pin VPWR
* pin VNB
.SUBCKT buf1 VPB out in VGND VPWR VNB
* cell instance $1 r0 *1 -0.614,-0.197
X$1 VPB in out VGND VPWR VNB sky130_fd_sc_hd__buf_1
.ENDS buf1

* cell sky130_fd_sc_hd__buf_1
* pin VPB
* pin A
* pin X
* pin VGND
* pin VPWR
* pin VNB
.SUBCKT sky130_fd_sc_hd__buf_1 VPB A X VGND VPWR VNB
* device instance $1 r0 *1 0.47,2.09 pfet_01v8_hvt
M$1 \$3 A VPWR VPB pfet_01v8_hvt L=150000U W=790000U AS=205400000000P
+ AD=114550000000P PS=2100000U PD=1080000U
* device instance $2 r0 *1 0.91,2.09 pfet_01v8_hvt
M$2 VPWR \$3 X VPB pfet_01v8_hvt L=150000U W=790000U AS=114550000000P
+ AD=205400000000P PS=1080000U PD=2100000U
* device instance $3 r0 *1 0.47,0.495 nfet_01v8
M$3 \$3 A VGND VNB nfet_01v8 L=150000U W=520000U AS=135200000000P
+ AD=75400000000P PS=1560000U PD=810000U
* device instance $4 r0 *1 0.91,0.495 nfet_01v8
M$4 VGND \$3 X VNB nfet_01v8 L=150000U W=520000U AS=75400000000P
+ AD=135200000000P PS=810000U PD=1560000U
.ENDS sky130_fd_sc_hd__buf_1

5.netgen による LVS の実行

Klayout で LVSの比較までできないので,xschem のネットリストとレイアウトから抽出したネットリストの比較は netgen というツールで行ないます.
その前に,抽出したネットリスト (cellname_extracted.spice) をちょっと修正します.トップセルがサブサーキットの定義になっていますが,これだと netgen がトップセルを識別できないので,".subckt" と ".ends" をコメントアウトします.

*.SUBCKT buf1 VPB out in VGND VPWR VNB
* cell instance $1 r0 *1 -0.614,-0.197
X$1 VPB in out VGND VPWR VNB sky130_fd_sc_hd__buf_1
*.ENDS buf1

これ地味に面倒なんだけど回避する方法ないのかな…

修正が終わったら netgen を起動します.コマンドラインで netgen だけで OK です.下図のようなウィンドウが開きます.

netgen を起動したところ

起動したら,lvs コマンドで比較しましょう.コマンドはシンプルで

lvs netlist1 netlist2

です.一方を xschem で作ったもの,もう一方を Klayout で抽出したものを指定します.うまく行くと下のようになります

LVS実行結果

味気ない画面ですが,下から3行目 "Result: Circuits match uniquely." が成功のメッセージです.実行結果の詳細は,作業ディレクトリに comp.out  というテキストファイルができています.exit で netgen を終了し,comp.out  を確認しましょう.まぁ "match uniquely" が出た場合は LVSを通っているので見なくてもいいですが.

Circuit 1 cell sky130_fd_sc_hd__buf_1 is a black box; will not flatten Circuit 2
Equate elements: no current cell.

Subcircuit summary:
Circuit 1: buf1.spice |Circuit 2: buf1_extracted.spice
-------------------------------------------|-------------------------------------------
sky130_fd_sc_hd__buf_1 (1) |sky130_fd_sc_hd__buf_1 (1)
Number of devices: 1 |Number of devices: 1
Number of nets: 6 |Number of nets: 6
---------------------------------------------------------------------------------------
Circuits match uniquely.
Netlists match uniquely.
Cells have no pins; pin matching not needed.
Device classes buf1.spice and buf1_extracted.spice are equivalent.
Circuits match uniquely.

ちなみに失敗するとどういうことになるかというのも試してみましょう.レイアウトで真ん中の配線と出力端子を li で短絡してみます.

配線を短絡させてみる

ネットリストを抽出し,LVS をかけると下のようになります.

do not match

comp.out  を見てみると

LVS結果

LVSのデバッグは往々にして非常に困難です.商用ツールの様々な機能を使ってもかなり辛い作業です.がんばりましょう.

6.問題点

Klayout での抽出は MOSトランジスタのソースとドレインが入れ替わることがあるなど,不完全な部分があるようです.ツール,ルールともに今後整備が進むことを祈りましょう.

この記事が気に入ったらサポートをしてみませんか?