Glade:アナログ回路の設計
(2020/05/17:akita11=ネットリストの端子名順について追記)
ここでは、アナログ回路の例として、コンパレータ(電圧比較器)を作ってみたいと思います。「Gladeを使ったLSI設計」のインバータの設計手順を使うことも多いので、必要であれば復習したり戻って確認しながら進めてください。 https://makelsi.github.io/images/docs/Glade/cmp06.png
コンパレータは、こんな記号の回路で、+側の電圧がー側の電圧より高い場合に出力(右側)が"1"、そうでないときに"0"になる回路です。オペアンプでも似たような使い方ができます。
※なお以下でつくるコンパレータは、以下のGladeフォルダ内にありますので、参考(答え合わせ?)にしてください。
回路図の作成
まずはコンパレータの回路図を作成します。コンパレータの回路構成にはいろいろあるのですが、ここでは比較的シンプルな、こんな回路↓を使ってみます(実は「コンパレータ 回路」で画像検索して最初に出てきた回路なのはナイショ)。差動増幅回路とソース接地回路をつないだ、かなり基本的な構成の回路です。
https://makelsi.github.io/images/docs/Glade/cmp01.png
まずはライブラリOpenRule1um_Basicを開いておきます。その後、OpenRule1umのテクノロジファイル(OpenRule1um.tch)を使って新しいライブラリをつくります。続いてその中に、コンパレータのCellをつくります。名前はcmpとしてみます。そのcmpの中に、新しいViewとしてschematic(回路図)を作ります。最初は空っぽの画面が出てきます。ここに、回路図を描いていきます。回路図を描き始める前に、View→DisplayOptionから、描画グリッドを以下のように"0.0625"(=1/16)に設定しておきましょう。
https://makelsi.github.io/images/docs/Glade/cmp04.png
MOSトランジスタは、ライブラリOpenRule1um_Basicの"pchOR1"(pMOS)または"nchOR1"(nMOS)を使います。インスタンスとして呼び出しますので、Create→Instanceから新しいpMOSのインスタンスをつくってみます。↓のような設定ダイアログが出てきます(出てこないときはF3キーを押すと出てくるはず)。
https://makelsi.github.io/images/docs/Glade/cmp01a.png
CellNameに"pchOR1"を選ぶと、pMOSを作成できますが、隣に"Instance Properties"というタブがあるので、選んでみます。
https://makelsi.github.io/images/docs/Glade/cmp01b.png
このように、いまから作成するpMOSのパラメータを指定できます。具体的には、l(ゲート長L)とw(ゲート幅W)を指定できます。デフォルトの値は、l=1um、w=2umですが、とりあえずこのまま作ってみましょう。
https://makelsi.github.io/images/docs/Glade/cmp01c.png
こんな感じでpMOSが1個置かれます。この調子で、とりあえず必要なpMOS 4個とnMOS 5個を置いてみます(場所は適当でOK)。
続いて、回路の入出力端子をつくります。Create→Pinで、端子(Pin)をつくります。このコンパレータには、入力2個(VPとVM)、出力1個(VO)、電源(+側のVDDと-側のVSS)の合計5個があります。端子(Pin)には、Direction(向き)とUse(用途)を指定できるので、入力端子はINPUT/SIGNAL、出力端子はOUTPUT/SIGNAL、電源端子はINOUT(NONEでもいいかも)/POWER、を指定しておきます(このダイアログが出てこないときはF3キーで)。
https://makelsi.github.io/images/docs/Glade/cmp01d.png
あとはMOSトランジスタや端子(Pin)の位置や向き(右クリック→Propertyから指定できる)や、必要ならばMOSトランジスタのパラメータ(L/W)を指定しながら配置し、接続していきます。ここで右上のpMOS(上の回路図ではM6)だけ、ゲート幅Wを18uとしておいてください。それ以外のnMOS/pMOSは、デフォルトのl=1u/w=2uのままでOKです。
回路図を書き終わったら、Check→CheckCellviewで、回路図のチェックをします。未配線の箇所などがあると、下のMessageWindowに「ここが未配線だよ」というエラーが出るので、修正していきます。CheckCellviewしてエラー・Warningが0個になったら、回路図は(回路図としては)完成です。
回路図がOKになったら、他の回路でもこのコンパレータcmpを使えるように、回路図記号(symbol)をつくっておきましょう。Create→Symbol、で、配置する端子(Pin)の位置を指定しながら作成できます。-側電源のVSSは下(bottom)にしておくとよいでしょう。
https://makelsi.github.io/images/docs/Glade/cmp05.png
↑こんな感じのSymbolが作られます(Cell=cmp内にView=symbolが作られる)。ただ、これだと味気ないというか、コンパレータっぽくないので、見慣れたコンパレータの記号にしておいたほうがいいですよね。図形描画の機能を使って、コンパレータの記号に修正しておきましょう。このとき線などの描画は、レイヤ選択(LSW)で"device"というレイヤを選んでから行います。
https://makelsi.github.io/images/docs/Glade/cmp06.png
見慣れたコンパレータの記号になりました。
なお赤い四角が端子(Pin)ですが、その中心がグリッドに乗っていることを確認しておきましょう(ズレていたらプロパティから修正する)。そうすると、このSymbolを使って回路図を描くときに便利です。
回路シミュレーション
この回路図は、回路図としては未配線箇所などの問題がないというだけで、回路として正しく動作するかは別問題です。そこで回路シミュレーションで、正しく動作するかを確認してみましょう。
まず回路図を、「Glade:はじめの一歩(6)=インバータの設計(回路シミュレーション)」と同じように、 回路シミュレーションで使えるネットリスト形式で保存しておきます。このとき、View→DisplayOptionから、"Object Setting"の"Instance Names"を"Force Spice compatible"を選んでおいてください↓。ファイル名は "cmp.cdl"としておきます。 https://makelsi.github.io/images/docs/Glade/cmp02.png
↓こちらは作成したコンパレータの回路を呼び出して、電源や信号を与える部分で、メモ帳などのテキストエディタで新規のファイルを作成し、以下の内容を書いて、"sim_cmp.sp"として保存しておきます。(拡張子が*.spになっているかを要確認。Windowsだと見えないけど拡張子が*.txtになってハマることが多いので注意)
code:sim_cmp.sp
* circuit simulation
.lib 'mos_PTS06.lib'
.inc 'cmp.cdl'
* target circuit
*.SUBCKT cmp VM VP VDD VO VSS
x1 VM VP VDD VO VSS cmp
* Dummy resistor to connect circuit's GND(VSS) to GND
r0 VSS GND 1e-30
* Power Supply
vdd VDD GND dc 5v
* Input Signal
vp VP GND pwl 0us 0v 10us 5v
vm VM GND dc 2.5V
.tran 1us 10us
.end
なお、この途中の"x1 VM VP VDD VO VSS cmp"のところが、さきほど設計したコンパレータの回路を呼び出している部分です。このVM、VP等の端子の順序が、Gladeの仕様のようで、不定(時々変わる)のようです。実際の端子の順序は、CDLにexportするときのダイアログに表示されているものを確認するか、または出力されたcmp.cdlをテキストエディタ等で開いて確認してください。その順序にあわせて、このsim_cmp.spのこの呼び出し部分の端子を記述します。
↓これは今回出力したcmp.cdlの端子の定義のところです。この例では、「VM VP VDD VO VSS」の順になっています(これにあわせてsim_cmp.spを書いているわけです)。
code:cmp.cdl
(中略)
.SUBCKT cmp VM VP VDD VO CSS
(以下略)
もう一つ、「Glade:はじめの一歩(6)=インバータの設計(回路シミュレーション)」で使った、以下のmos_PTS06.libをダウンロードしておきます(すでにダウンロード済みであればそのまま次へ)。このファイルは、cmp.cdlやsim_cmp.spと同じフォルダに置きます。(※Windowsだとファイルを保存時に、自動的に拡張子"txt"がついてしまって、"mos_PTS06.lib.txt"というファイル名になってしまうので、ファイル名を"mos_PTS06.lib"に変更しておいてください) LTspiceからRunでシミュレーションを実行し、現れる結果表示ウインドウで右クリックから表示する信号名を選んで表示させます。
https://makelsi.github.io/images/docs/Glade/cmp03.png
このように、VpがVmより高いときにはVo="1"(5V)、それ以外のときはVo="0"(0V)となり、コンパレータとして動作していることが確認できます。動作波形がこうならない場合は、回路図にミスが有るはずなので、よく確認してください。
レイヤと設計ルール
さていよいよ、このコンパレータのレイアウトを設計してみます。Gladeを使ったLSI設計の「はじめてのLSI設計〜レイアウト設計編」から「Glade:はじめの一歩(6)=インバータの設計(回路シミュレーション)」をひととおりやって、レイアウト設計に関する基本的な事項(レイヤ構成、設計ルールなど)は復習しておいてください。 PCell
レイアウト設計においてMOSトランジスタをつくるのに、長方形を並べて描画してもよいのですが、数が多いと面倒ですし、間違いも入りやすくなります。またレイアウト設計中に、サイズ(LやW)を修正することもよくありますが、そのたびに長方形を書き直すのは、かなり面倒です。
そこで、"PCell"というものを使いましょう。PCellは、Parameterized Cellの略で、パラメータを指定すると、それにあわせたレイアウトを自動的に生成する機能です。例えばMOSトランジスタの場合、パラメータのLやWを指定すれば、そのとおりのOMSトランジスタのレイアウトが自動で生成されます。あとからLやWを修正すると、レイアウトもそれに合わせて自動で生成されます。たぶんその便利さは、長方形をたくさん並べた人でないとわからないと思いますので、ぜひ一度は、先のインバータの設計のように長方形を並べて設計してみるとよいと思います。
PCellを使う前に、一度だけ設定をしておく必要があります。GladeのPCellは、中身はPythonで書かれているスクリプトであるため、Pythonでそれを実行できるように、環境変数"PYTHONPATH"を設定しておく必要があります。ちょっと面倒ですが、一度だけなので、がんばって設定してください。
Windowsの場合は、コントロールパネル→システム→システムの詳細設定、から「環境変数」を選び、ユーザ変数に新規で以下のように環境変数"PYTHONPATH"を作成し、その値を、OpenRule1umを展開してあるフォルダ(具体的には、PCellスクリプトであるnchOR1.pyがあるフォルダ)を指定しておきます。設定が済んだら、Gladeをいったん終了して再度起動しておきます。なおGladeのインストールのときに、環境変数GLADE_HOME(Gladeのインストールしたディレクトリ)とPYTHONHOME(GLADE_HOMEと同じにする)も設定しているはずです。設定していなくてもPCell以外はそれほど困らないのですが、PCellを使うときには必要なので、これらの設定を確認しておいてください。
https://makelsi.github.io/images/docs/Glade/cmp05a.png
コンパレータcmpの中に、レイアウトのViewを作成(Create→Viewでlayout)し、そこにレイアウトを作成していきます。
適当なところで、Create→Instaneでインスタンス作成で、ダイアログ(出てきていなければF3キー)でライブラリOpenRule1um_Basic"のセル"nchOR1"を選んでみると、MOSトランジスタの影が出てきて、クリックで配置できます。この配置するときのPropertyで、または配置後に選択してプロパティのところで、パラメータを指定できます(パラメータを変更すると、それにあわせたレイアウトが自動生成さえる)。
MOSトランジスタのLとWは、↓この部分のサイズのことです。
https://makelsi.github.io/images/docs/Glade/cmp07.png
例えばw=6e-6($ 6✕10^{-6}m、つまり6umのこと)とすると、↓のようにW=6umのnMOSになります。
https://makelsi.github.io/images/docs/Glade/cmp08.png
L=2e-6、つまり$ 2\times 10^{-6}mとすれば、↓のようにゲート長Lが2倍の2umになります。
https://makelsi.github.io/images/docs/Glade/cmp09.png
"nf"というパラメータは、1つのPCell内に直列で並べるMOSトランジスタの数(Finger数と呼ぶ)です。例えばnf=2とすると、↓のように2個のnMOSが直列に並んだものができます。
https://makelsi.github.io/images/docs/Glade/cmp10.png
"polyCnt"は、ゲート電極に、メタルML1と接続するコンタクトを含むpcontを置くかどうかを指定します。あとでメタル配線をつなぐならば、ここを1にしておくと、↓こちらのようにpcontが置かれたレイアウトになります。
https://makelsi.github.io/images/docs/Glade/cmp11.png
"leftCnt"と"rightCnt"は、両端にコンタクト(dcont)を置くかどうかを指定します。MOSトランジスタを並べて使うときにはこれを"0"にする場合もあります。↓こちらはleftCnt=0とした例で、左端だけコンタクト(dcont)が置かれていないことがわかります。
https://makelsi.github.io/images/docs/Glade/cmp12.png
なおPCellを使っていると、ときどきエラーがでてMOSトランジスタのレイアウトが現れないことがあります。多くの場合、下部のMessageWindowに、"Layer cont purpose drawing not defined in techfile."のようなエラーが出ているかと思います。これはどうもGladeのバグのようなのですが、テクノロジファイルのレイヤ指定がたまに失われてしまうのが原因のようです。そのようなときには、File→Import→TechnologyFileから、いま使っているラリブラリに、作成時に使ったテクノロジファイルの"OpenRule1u.tch"を指定して読み込んでおくと大丈夫なようです。
レイアウト設計
ではPCellの使い方が大体わかったところで、コンパレータのレイアウト設計をはじめていきましょう。まず描画グリッドの設定をしておきます。OpenRule1umでは、基本的に1umグリッドに図形などを配置しますが、念のためその半分の0.5umのグリッドを設定しておきましょう。View→DisplayOptionから、グリッドをX/Yともに"0.5"にしておきます。
https://makelsi.github.io/images/docs/Glade/cmp13.png
回路のレイアウト方法には、いろいろコツや流儀(コモンセントロイド、など)があるのですが、とりあえずは回路図にあるMOSトランジスタと同じ位置に、どんどん並べていきましょう。まずは適当に配置していけばOKです。
なお右上のpMOSだけは、回路図でW=18umに設定しましたので、レイアウトでもそれにあわせます。パラメータを"w=18e-6"としてもよいのですが、とても細長い形状になってしまうので、一般にはnf(Finger数)を調整して、あまり細長くならないようにします。ここでは↓のようにnf=2、w=9e-6、としてみましょう。↓のようにW=9umのpMOSが2個直列につながった構造になりますが、これを交互に並列につなぐことで、等価的にW=18umのpMOSになります。
https://makelsi.github.io/images/docs/Glade/cmp14a.png
https://makelsi.github.io/images/docs/Glade/cmp14.png
とりあえずすべてのトランジスタを配置したら、設計ルールや、相互の接続関係を考慮しながら、(必要ならばpolyCntを1/0も選びながら)配置を決めていきます。必要に応じてMOSトランジスタを選択してのプロパティから、回転(R90など)もさせます。適宜、DRCをかけて、MOSトランジスタが近すぎないか、などを確認していくとよいでしょう。今回は↑のように配置してみます。
トランジスタの配置が終わったら、ウエル(NWL)コンタクトのためのnsubcontを置きます。一般にウエルコンタクトは、なるべくたくさん並べたほうが性能がよくなるので、なるべく多く配置します。↓の例では、セルnsubcontを、2um間隔で13個並べています。また個々のpMOSやnsubcontを含むように、NWLレイヤで長方形を描いておきます(これですべてのpMOSのNウエルが接続されます)。
なおこのとき、上下方向のVDD/VSSの位置を、論理ゲートのラリブラリであるスタンダードセルにあわせておくと、それと組み合わせての回路設計をやりやすくなります。高さの確認のため、OpenRule1um_StdCellのinv1(layout)を呼び出して、横に置いて、それにあわせて上下のVDD/VSSの位置をまずはあわせておきましょう。
https://makelsi.github.io/images/docs/Glade/cmp15.png
同様に、nMOS側の基板コンタクト(psubcont)も2um間隔でなるべくたくさん(この例では13個)並べておきます。
あとは各トランジスタをつなぐ配線を、ML1レイヤのパス(Path)や長方形(Rectangle)で描いていきます(パスはF3で出てくるダイアログで幅(width)を指定します。↓の例では2umのパスを描いています)
https://makelsi.github.io/images/docs/Glade/cmp17.png
右上のW=18umのpMOSは、W=9umのpMOSを2個並列につなぐことにしてあったので、こちらのようにS/DはML1で、ゲートGはPOLで接続します。
https://makelsi.github.io/images/docs/Glade/cmp18.png
ひととおりの配線が終わったら、入出力端子(VP, VN, VO)のところに、↓のようにViaセルを置いておきましょう。これは、一般に外部との配線にはML2レイヤ(2層目のメタル配線)を使うので、それを接続しやすいようにするためです。それぞれのところに、端子名のTextをML2レイヤで置いておきます。
https://makelsi.github.io/images/docs/Glade/cmp19.png
最後に電源のVDD/VSSのところにも、ML1レイヤでTextのVDD/VSSを置いておきます。
レイアウトの検証
ひととおりレイアウトが終わったら、正しく設計できているかを検証していきます。まずは回路図とレイアウトとの一致を確認するLVSです。
まずはVerify→Extractから、回路抽出(LPE)です。
https://makelsi.github.io/images/docs/Glade/cmp20.png
抽出ルールには、OpenRule1um/Gladeフォルダにある、"OpenRule1um-lvs.py"を指定します。これでセルcmpにViewの"extracted"が生成されます。NetlistViewerで、各ノードとレイアウトの対応を確認できます。
https://makelsi.github.io/images/docs/Glade/cmp21.png
続いてVerify→LVSでLVSです。
https://makelsi.github.io/images/docs/Glade/cmp22.png
↓のように、左側のレイアウト側(Extracted View)は、↑のLPEで生成されたcmp/extractedを指定し、右側の回路図側は、"Schmetic Source"に"schematic"を選んでおくと、最初に作成した回路図のcmp/schematicが使われます。
https://makelsi.github.io/images/docs/Glade/cmp23.png
回路図とレイアウトが、(接続関係・トランジスタのサイズを含めて)一致すれば、↓こちらのようにエラー結果(cmp.err)に0個の素子(device)と0個のネットが書き出されたよ(つまりエラーはないよ)、ということが確認できます。エラーがあった場合は、どこか不一致の原因があるはずなので、レイアウトをよく確認してください。
https://makelsi.github.io/images/docs/Glade/cmp24.png
最後にDRCをかけて、エラーがあったら修正し、LVSのチェックも行います。LVSとDRCのエラーがともに0個になったらがなくなったらレイアウトは完成です!