sky130のnmosのvds-ids特性を描く
設計ことはじめとしてnmosのvds-ids特性を描きたい。 Vgsに対してパラメトリック解析を行いたいが、ngspiceの機能として備えていないためpythonスクリプトで対応してみた。
実際にやってみた感想としては、記述量が多くなってしまいあまり良い方法でないと思った。 良い方法があれば教えてほしいです。
回路図
ネットリスト
** sch_path: /home/unifagf/work/xschem/tutor/test2/test2.sch **.subckt test2 XM1 net2 net1 GND GND sky130_fd_pr__nfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29' + pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W' + sa=0 sb=0 sd=0 mult=1 m=1 V1 net2 GND 1.8 V2 net1 GND VG **** begin user architecture code .lib /home/unifagf/skywater/skywater-pdk/libraries/sky130_fd_pr_ngspice/latest/models/sky130.lib.spice tt .dc V1 0 1.8 0.1 .parameter VG=1.8 .save all .control set filetype=ASCII .endc **** end user architecture code **.ends .GLOBAL GND .end
set filetype=ASCIIは、rawファイルをbinaryではなくASCIIで出力させるためのコマンド。 spyci(https://pypi.org/project/spyci/)でrawファイルを読み込むために必要。
グラフ
ゲート幅が1umより小さいので、チャネル長変調効果が強く出ている。
スクリプト
処理のフロー
スクリプト本体(run.py)
#!/usr/bin/env python import argparse import subprocess import itertools import os import os.path import numpy as np import pandas as pd import sys import re from spyci import spyci import matplotlib.pyplot as plt import shutil # print(' '.join([f'"{s}"' for s in sys.argv])) scriptdir = os.path.dirname(sys.argv[0]) # pythonスクリプトがおいてあるディレクトリ # 引数の設定解析 parser = argparse.ArgumentParser( description='Run parametric analysis from xschem file.') parser.add_argument('schema', help='Original xschem file.') parser.add_argument('-c', '--clean', action='store_true', help='Clean previous work directories.') parser.add_argument('-n', '--netlist', action='store_true', help='Generate parameterized netlists.') parser.add_argument('-s', '--simulation', action='store_true', help='Run simulations.') parser.add_argument('-r', '--result', action='store_true', help='Export results.') parser.add_argument('-o', '--output', nargs='?', default=scriptdir, help='Specify output directory') args = parser.parse_args() # ディレクトリ生成 schname = os.path.splitext(os.path.basename(args.schema))[0] # 拡張子なしのファイル名を取得 netdir = os.path.join(args.output, 'tmp') rawdir = os.path.join(args.output, 'tmp') logdir = os.path.join(args.output, 'tmp') retdir = os.path.join(args.output, 'result') if args.netlist: os.makedirs(netdir, exist_ok=True) if args.simulation: os.makedirs(rawdir, exist_ok=True) os.makedirs(logdir, exist_ok=True) if args.result: os.makedirs(retdir, exist_ok=True) # パラメータ設定 params = {'VG': ['{:01.1f}'.format(n) for n in np.linspace(0, 1.8, 10)]} # パラメータの組み合わせ生成 keys = list() param_comb = list() df = pd.DataFrame() if len(params) >= 0: # パラメータがある場合 keys = list(params.keys()) param_comb = list(itertools.product(*[params[k] for k in keys])) df = pd.DataFrame(param_comb, columns=keys) df['ngspice_net'] = '-' df['ngspice_raw'] = '-' df['ngspice_out'] = '-' for index, row in df.iterrows(): filename = f'{schname}_' + "_".join([f'{k}{str(row[k])}' for k in keys]) df.at[index, 'ngspice_net'] = os.path.join(netdir, f'{filename}.net') df.at[index, 'ngspice_raw'] = os.path.join(rawdir, f'{filename}.raw') df.at[index, 'ngspice_out'] = os.path.join(logdir, f'{filename}.out') else: # パラメータがない場合 filename = f'{schname}' _d = {'ngspice_net': os.path.join(netdir, f'{filename}_.net'), 'ngspice_raw': os.path.join(rawdir, f'{filename}_.raw'), 'ngspice_out': os.path.join(logdir, f'{filename}_.out')} df = pd.DataFrame(_d) def subprocess_run(cmd): """ サブプロセスを実行する関数 """ result = subprocess.run(cmd, stdout=subprocess.PIPE, encoding='utf-8', shell=True) return result # ファイル削除 if args.clean: shutil.rmtree(netdir) shutil.rmtree(rawdir) shutil.rmtree(logdir) shutil.rmtree(retdir) # ネットリスト生成 if args.netlist: original_netlist = os.path.join(netdir, f'orig_{schname}.net.spice') # 回路図から生成したネットリスト cmd = 'xschem --netlist ' + \ f'--netlist_path "{netdir}" ' + \ f'--netlist_filename "{original_netlist}" ' + \ f'--quit "{os.path.abspath(args.schema)}"' print(cmd) proc = subprocess_run(cmd) # パラメータを変更したネットリストを生成 with open(original_netlist, 'r', newline='') as rf: print() orig_lines = rf.readlines() for index, row in df.iterrows(): with open(row['ngspice_net'], 'w') as wf: for line in orig_lines: s = line for k in params.keys(): m = re.match(r'^\.parameter\s+' + k + r'=', s) # 「.parameter hoge=...」という行を置換 if m is not None: v = row[k] s = f'.parameter {k}={v}\n' wf.write(s) print('{} generated.'.format(row['ngspice_net'])) # simulation実行 if args.simulation: print('run simulation') for index, row in df.iterrows(): cmd = 'ngspice --autorun --batch ' + \ '--output="{}" '.format(row['ngspice_out']) + \ '--rawfile="{}" "{}"'.format(row['ngspice_raw'], row['ngspice_net']) print(cmd) result = subprocess_run(cmd) # グラフを描画 if args.result: print(df) # パラメータ一覧を表示 print(spyci.list_vars(df.at[0, 'ngspice_raw'])) # 信号名一覧を表示 fig, ax = plt.subplots() for index, row in df.iterrows(): data = spyci.load_raw(row['ngspice_raw']) x = np.real(data['values']['v(v-sweep)']) y = -np.real(data['values']['i(v1)']) ax.plot(x, y, label='VG={}'.format(row['VG'])) ax.set_xlabel('Vds (V)') ax.set_ylabel('Ids (A)') ax.legend(loc='upper right') ax.grid(visible=True) ax.set_xlim([0, 1.8]) graphimg = os.path.join(retdir, 'nmos_idsvds.png') plt.savefig(graphimg)
使い方
./run.py -nsr test2.sch
sky130のセットアップ
目的
skywaterのフリーなPDK(sky130)で回路のお勉強をするためにspiceの実行環境を整えたい。
参考にしたサイト
https://github.com/bluecmd/learn-sky130/blob/main/schematic/xschem/getting-started.md https://github.com/mabrains/sky130_ubuntu_setup
セットアップ
mkdir -p ~/build/sky130_ubuntu_setup cd ~/build/sky130_ubuntu_setup git clone https://github.com/mabrains/sky130_ubuntu_setup.git sudo ./install_pdk.sh
xschemのインストール
sudo apt-get install libx11-6 libx11-dev libxrender1 libxrender-dev libxcb1 libx11-xcb-dev libcairo2 libcairo2-dev tcl8.6 tcl8.6-dev tk8.6 tk8.6-dev flex bison libxpm4 libxpm-dev gawk git mkdir ~/build cd ~/build git clone https://github.com/StefanSchippers/xschem.git cd xschem ./configure make -j4 sudo make install
起動確認
xschem
PDKのモデルをngspiceで読み込めるようにパッチを当てる。
mkdir -p ~/.xschem/xschem_library cd ~/.xschem/xschem_library git clone https://github.com/StefanSchippers/xschem_sky130.git xschem_sky130 cd ~/skywater/skywater-pdk/libraries cp -a ./sky130_fd_pr ./sky130_fd_pr_ngspice cd ./sky130_fd_pr_ngspice/latest/ patch -p2 < ~/.xschem/xschem_library/xschem_sky130/sky130_fd_pr.patch
xschemrcの編集
gedit ~/.xschem/xschem_library/xschem_sky130/xschemrc
SKYWATER_MODELSとSKYWATER_STDCELLSを置き換える
set SKYWATER_MODELS ~/skywater/skywater-pdk/libraries/sky130_fd_pr_ngspice/latest$ set SKYWATER_STDCELLS ~/skywater/skywater-pdk/libraries/sky130_fd_sc_hd/latest
ngspiceインストール
sudo apt install ngspice
gawインストール(不要だった)
mkdir -p ~/build/gaw cd ~/build/gaw sudo apt install libgtk-3-dev build-essential wget http://download.tuxfamily.org/gaw/download/gaw3-20200922.tar.gz tar -xf gaw3-20200922.tar.gz cd gaw3-20200922 ./configure make -j$(nproc) sudo make install
gawを起動して閉じる。
gaw
gawrcを開く。
gedit ~/.gaw/gawrc
以下のように編集
up_listenPort = 2020
動作確認
適当な作業ディレクトリに移動してxschemを実行
mkdir -p ~/work/xschem/test1 cd ~/work/xschem/test1 xschem
INSを押して、階層をたどっていきnfet_01v8.symを選択
回路図を描く。
簡単な操作説明
- 部品配置はINS
- nfetは「/home/unifagf/.xschem/xschem_library/xschem_sky130/sky130_fd_pr/nfet_01v8.sym」
- 電圧源は「/usr/local/xschem/schem_library_devices/vsource.sym」
- GNDは「/usr/local/xschem/schem_library_devices/gnd.sym」
- ワイヤはw、w中にwで折れ曲がり点追加、ダブルクリックで終了
- xschem公式のビデオがわかりやすいhttps://xschem.sourceforge.io/stefan/xschem_man/video_tutorials/editing_and_sim.mp4
s1のコマンドは以下の通り
.lib /home/unifagf/skywater/skywater-pdk/libraries/sky130_fd_pr_ngspice/latest/models/sky130.lib.spice tt .dc V1 0 1.8 0.1 .save all
Options>Show netlist winにチェック Simulation>Configure simulators and toolsでspice>Ngspiceとなっていることを確認
画面右上のNetlistをクリック、閉じる 画面右上のSimulateをクリック、少し待つ
プロット可能な信号一覧を表示 display
電流を表示 plot v1#branch
Id-Vd特性が確認できた。
ラズパイをNAS化する。
はじめに
Raspberry Pi 4B 4GBをdperson/sambaでNAS化した。
参考にしたサイト
ラズパイのヘッドレスセットアップ
- SDカードへのOSのインストールRaspberry Pi Imager v1.6.2でRASPBERRY PI OS(32-BIT)(RELEASED2021-10-30)をインストールする。
- SSHの有効化。Mobaxterm上で下記コマンドを実行。
touch /cygdrive/g/ssh ※gドライブはSDカードの/bootディレクトリ
- SDカードをラズパイに挿入して起動。
- ラズパイのIPを探す。Mobaxterm上で下記コマンドを実行。私の場合、MACアドレスはdc-a6から始まっていた。
for i in {0..255}; do ping -w 1 -n 1 192.168.3.$i done arp -a
- SSH接続。
- パスワードはraspberry
ssh pi@192.168.3.11
- ユーザー名をpiから変更。 Raspbianでユーザー名piを名前変更する。 - アプリ開発備忘録 に従って進める。
- 固定IP化。 ラズベリーパイで固定IPアドレスを設定する - ムギークのブログ に従って進める。
- SSHを公開鍵方式に変更。mobaxterm上で実行。
- mobaxtermのUser sessionsを右クリックしてSSHのセッションを追加しておくと便利。
ssh-keygen ssh-copy-id Unifagf@192.168.3.129
- VNCのセットアップ。
VNCでRaspberry Piにリモートデスクトップ接続 (Windows/Mac/Linux対応) – Indoor Corgi
に従って進める。
- mobaxtermからはなぜかVNC接続できなかったため、VNCviewerを使用。
HDDのセットアップ
力尽きたので以降は簡潔に。
- パーテーション作成
- フォーマット
- 自動マウント
sambaのセットアップ
Raspberry Pi 3 b+にsambaをdockerで入れてファイルサーバ化する - Qiitaに従って進める。
オペアンプの増幅回路と高精度ネットワーク抵抗
オペアンプの増幅回路
下記回路が基本構成。
作動増幅回路
反転増幅回路
非反転増幅回路
高精度ネットワーク抵抗
増幅回路は抵抗の比で回路のゲインが決まる。ネットワーク抵抗は抵抗値の比精度がよいと言われるが、特性として保証している製品はあまり多くない。増幅回路向きの高精度ネットワーク抵抗のメモ。
https://www.vishay.com/docs/28770/acasat.pdf
- VishayのACASシリーズ
https://www.susumu.co.jp/product/category.php?cid=2
- SSMのRMシリーズ
https://www.analog.com/en/products/lt5400.html
- ADIのLT5400
-
- MaximのMAX5490
https://www.vishay.com/ppg?60001
- VishayのMPMシリーズ
https://www.vishay.com/networks-and-arrays/list/product-60005/
- VishayのORNシリーズ
微小電流測定用のアンプ
微小電流測定用のアンプについて勉強したメモ
参考文献
-
- 測定機器メーカーのケースレーが出しているLow Level Measurements Handbook
https://www.jstage.jst.go.jp/article/sicejl1962/44/10/44_10_681/_pdf
- ケースレーの方の微小電流測定に関する日本語記事
- 上記ハンドブックを翻訳したような内容
-
- EDNの記事
- ICメーカーのトップエンジニアの方々のテクニック紹介
測定限界
熱雑音による測定限界を考える。 熱雑音は以下の式で表される。kBはボルツマン定数1.308e-23 J/K。
グラフ化すると以下のようになる。
信号源のインピーダンスを1GΩとして、熱雑音は10fA/√Hzと非常に低い値となる。 電圧測定では測定限界が熱雑音に制限されることが多いが、 電流測定では熱雑音は無視してよく、ケースレーの資料にあるように「摩擦電気効果」「圧電効果」「電気化学効果」が支配的で10nA程度が限界となるようだ。
電流測定IC
シャント式
Current Sense Amplifier icで検索するとヒットするものは大体こちら。 電源電流測定などでメジャーな方式だが、微小電流には向いていないようだ。
- www.ti.com
- Texas InstrumentsのINA181
- リニアアンプ
- 測定範囲75uA?-制限なし
- バイアス電流75uAが下限値?
フィードバック式
「Transimpedance Amplifier IC」で検索するとヒットする。
-
- Analog devicesのAD8304
- 対数アンプ
- 測定範囲100pA-10mA
-
- Texas InstrumentsのOPA857
- リニアアンプ
- 測定範囲15nA-240uA
- 上限は+3.3V電源の場合
積分式
- www.ti.com
- Texas InstrumentsのDDC112
- 電流入力タイプのADC