問題
１．厚さ 100 nmの a-SiO2 の単位面積当たり静電容量 COX を求めよ。
a-SiO2 の 比誘電率は εr = 11.9 とする。
２．TransferCurve.csvのデータから、飽和移動度を求めよ
電極幅 W = 300 μm, L = 50 μm とする。
飽和移動度を求める際の Vg、Vd は各自で選ぶこと。
その値を選んだ理由も説明せよ。

電界効果トランジスタ(FET)の基本動作
トランジスタの基本機能
1. 増幅機能
ゲート電圧に電流が比例する領域を利用
2. スイッチ機能 ゲート電圧による大きな電流の変調を利用
Ids
キャリア

ｹﾞｰﾄ
ドレインVds

Ids

Vgs

絶縁層

ソース

Off状態

半導体

1Tr1C DRAM
ワード線(書込)Tr(スイッチング)
データ(ビット)線(書込,破壊読出し)C(メモリーノード)

On電流: 動作速度

On状態
Vgs

リーク電流:消費電力

動作点: 駆動電圧

FET特性の解析: 飽和領域

VDS > Vp = VGS – Vth𝑉𝑉𝐷𝐷𝐷𝐷
2𝑊𝑊𝜇𝜇𝐶𝐶𝑂𝑂𝑂𝑂 𝑉𝑉𝐺𝐺𝐺𝐺 − 𝑉𝑉𝑡𝑡𝑡 2
𝐼𝐼𝐷𝐷𝐷𝐷 =2𝐿𝐿
𝐼𝐼𝐷𝐷𝐷𝐷 1/2 =𝑊𝑊
𝜇𝜇𝐶𝐶 𝑉𝑉 − 𝑉𝑉𝑡𝑡𝑡
2𝐿𝐿 𝑂𝑂𝑂𝑂 𝐺𝐺𝐺𝐺

IDS1/2 vs. VGSをプロット
VGS軸切片: Vth
傾き: 飽和移動度
Saturation mobility, µsat

200
150

VGS=0–15V

100
500051412642015

VDS=2,4,6,8,10V

10810VDS (V)IDS (µA)

𝑉𝑉𝐺𝐺𝐺𝐺 − 𝑉𝑉𝑡𝑡𝑡 𝑉𝑉𝐷𝐷𝐷𝐷 −IDS (µA)

𝑊𝑊𝜇𝜇𝐶𝐶𝑂𝑂𝑂𝑂
𝐿𝐿

IDS1/2 (µA1/2)

𝐼𝐼𝐷𝐷𝐷𝐷 =a-IGZO TFT

2µsat
Vth-2 02468 10 12 14 16

VGS (V)

ゲート容量 COXの計算
ゲート絶縁体: アモルファス SiO2
誘電率: 11.9ε0(ε0 = 8.854418782e-12 C2N-1m-2)
厚さ 100 nm
1 m2当たり静電容量
COX = 11.9ε0 / 100e-9 [m] = 0.00105 F/m2

プログラム

TFTiv.py

直線に見える 1.9 ~ 10.0 V で、numpy.polyfit() で一次多項式にフィッティング
ai = np.polyfit(xfit, yfit, 1)# y = ai[1] + ai[0]xVth = -ai[1] / ai[0] = 1.794 V
1

𝑑𝑑𝑑𝑑𝑑𝑑2= ai[0] = 0.001114 A1/2/V
𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝐼𝐼𝐷𝐷𝐷𝐷 1/2 =𝝁𝝁𝒔𝒔𝒔𝒔𝒔𝒔 =𝑊𝑊𝜇𝜇𝐶𝐶𝑂𝑂𝑂𝑂 𝑉𝑉𝐺𝐺𝐺𝐺 − 𝑉𝑉𝑡𝑡𝑡
2𝐿𝐿

dIgs1/2/dVgs
𝑾𝑾𝑪𝑪𝟐𝟐𝟐𝟐 𝑶𝑶𝑶𝑶

2= 0.000392 m2/Vs = 3.92 cm2/Vs

TFTiv.py
import reプログラム (抜粋)# 正規表現モジュールを読み込む#===================================# parameters#===================================
infile = 'TransferCurve.csv'
dg = 100e-9 #merg = 11.9
W = 300.0e-6 #m
L = 50.0e-6# Ids^(1/2)-VgsプロットをするVds
Vds0 = 10.0
# 余計な文字が含まれている文字列から、# 浮動小数点に変換できる最初の文字列を切り出し、# 浮動小数点に変換して返す
def pfloat(str, defval = None):# 文字列から、浮動小数点に使える文字が連続している部分を切り出す
m = re.search(r'([+¥-eE¥d¥.]+)', str)
# 一致した文字列を取得
valstr = m.group()
try:
return float(valstr)
except:return defval

def read_csv(fname):print("")
with open(fname) as f:fin = csv.reader(f)labels = next(fin)xlabel = labels[0]# label行が 空文字 の場合、データとしては読み込まない
ylabels = []for i in range(1, len(labels)):
if labels[i] == '':breakylabels.append(labels[i])ny = len(ylabels)
x = []
ylist = []for i in range(ny):ylist.append([])
for row in fin:x.append(pfloat(row[0]))for i in range(1, ny+1):
v = pfloat(row[i])if v is not None:
ylist[i-1].append(v)else:ylist[i-1].append(None)
return xlabel, ylabels, x, ylist

TFTiv.py

プログラム (抜粋)

def main():
Cox = erg * e0 / dg #(F/m^2)
print("")
print("Cox = {:12.6g} [F/m^2]".format(Cox))
xlabel, ylabels, Vgs, IdsVgs = read_csv(infile)nVgs = len(IdsVgs[0])nVds = len(ylabels)
Vds = []
for i in range(nVds):
Vds.append(pfloat(ylabels[i]))print("")
print("nVds=", nVds)
print("nVgs=", nVgs)
print("xlabel : ", xlabel)print("ylabels: ", ylabels)
print("Vds: ", Vds)

# sqrt(Ids) データを作る
print("")
print("Vds used: {} V (iVds = {})".format(Vds[iVds], iVds))
sqrtIds = []for ig in range(nVgs):
sqrtIds.append(sqrt(IdsVgs[iVds][ig]))# 最小二乗法のデータ
xfit = []yfit = []for i in range(nVgs):
if xfitmin <= Vgs[i] <= xfitmax:
xfit.append(Vgs[i])yfit.append(sqrtIds[i])print("")
print("Least squares fitting:")
print("Vgs range: {} - {} V".format(xfitmin, xfitmax))
print("Vgs=", xfit)
print("Igs^(1/2)=", yfit)# 出力特性 Ids - Vds をプロットするためのデータを作る
IdsVds = np.empty([nVgs, nVds])
ai = np.polyfit(xfit, yfit, 1)
for ig in range(nVgs):# y = ai[1] + ai[0]x
for id in range(nVds):
Vth = -ai[1] / ai[0]IdsVds[ig][id] = IdsVgs[id][ig]grad = ai[0]mu = grad * grad / (W * Cox / 2.0 / L)
print("Vth = {:6.4g} V".format(Vth))# sqrt(Ids) - Vgsプロットをする Vds0 のデータ番号 iVds を探す
print("dIgs^1/2/dVgs = {:12.4g} A^(1/2)/V".format(grad))# Vds[i] が小さい方から順に、Vds0 <= Vds[i] となる i を探すが、# 浮動小数点誤差があることを考慮し、Vds0 - 1.0e-3 <= Vds[i] とする print("mu_sat = {} m^2/Vs = {} cm^2/Vs".format(mu, 1.0e4 * mu))
for i in range(nVds):
if Vds0 - 1.0e-3 <= Vds[i]:iVds = ibreakTFTiv.py

プログラム (抜粋)# 最小二乗の結果を確認する直線# フィッティング範囲より広くプロットする
xcal = []ycal = []xx = xfitmin - 0.5
xcal.append(xx)ycal.append(ai[1] + ai[0] * xx)
xx = max(Vgs)xcal.append(xx)ycal.append(ai[1] + ai[0] * xx)# 伝達特性 Ids-Vgs のグラフ
for id in range(nVds):
ax1.plot(Vgs, IdsVgs[id], linewidth = 0.5, marker = 'o',markersize = 0.5,
label = 'Vds={} V'.format(Vds[id]))
for id in range(nVds):
ax1.plot(Vgs, IdsVgs[id], linewidth = 0.5, marker = 'o',markersize = 0.5,
label = 'Vds={} V'.format(Vds[id]))ax1.set_xlabel('Vgs (V)')
ax1.set_ylabel("Ids (A)")
ax1.set_yscale('log')# 凡例のアンカーを左上に設定
ax1.legend(loc = 'upper left', fontsize = legend_fontsize)# 出力特性 Ids-Vds のグラフ
# 20点の Vgs を選び、そのうち、線形でIdsが見えるデータのみ表示する
nskip = int(nVgs / 20.0 + 1.0e-6)
for ig in range(0, nVgs, nskip):# 線形プロットで見えないほどIdsが小さいデータは表示しない
if max(IdsVds[ig]) < 1.0e-7:
continueax2.plot(Vds, IdsVds[ig], linewidth = 0.5, marker = 'o', markersize= 0.5,label = 'Vgs={} V'.format(Vgs[ig]))
ax2.set_xlabel('Vds (V)')
ax2.set_ylabel("Ids (A)")
ax2.legend(loc = 'upper left', fontsize = legend_fontsize)# Ids^(1/2) - Vgs グラフ
ax3.plot(Vgs, sqrtIds, linestyle = 'none', marker = 'o', markersize =0.5)
ax3.plot(xcal, ycal, linestyle = '-', linewidth = 0.5)
ax3.set_xlabel('Vgs (V)')
ax3.set_ylabel("Ids$^{1/2}$ (A$^{1/2}$)")
plt.tight_layout()
plt.pause(0.1)
print("Press ENTER to exit>>", end = '')input()