アナログCMOS集積回路の設計 演習編


https://www.amazon.co.jp/%E3%82%A2%E3%83%8A%E3%83%AD%E3%82%B0CMOS%E9%9B%86%E7%A9%8D%E5%9B%9E%E8%B7%AF%E3%81%AE%E8%A8%AD%E8%A8%88-%E6%BC%94%E7%BF%92%E7%B7%A8-%E9%BB%92%E7%94%B0-%E5%BF%A0%E5%BA%83/dp/4621080628/ref=pd_sbs_d_sccl_1_3/356-3572326-7934763?pd_rd_w=lCJHi&content-id=amzn1.sym.cc4f782f-18e8-4959-acfc-ffdf7905539a&pf_rd_p=cc4f782f-18e8-4959-acfc-ffdf7905539a&pf_rd_r=T8A259F4SCSTN278GX3H&pd_rd_wg=X00Ey&pd_rd_r=071813ab-787a-4e73-9670-d824ccfa9374&pd_rd_i=4621080628&psc=1

```
# Constants
epsilon_0 = 8.85e-14  # Vacuum permittivity in F/cm
epsilon_ox = 3.9 * epsilon_0  # Permittivity of SiO2 in F/cm

# Given values
mu_n = 350  # Electron mobility in cm^2/V/s
mu_p = 150  # Hole mobility in cm^2/V/s
tox = 9e-9  # Oxide thickness in cm
V_th = 1.0  # Threshold voltage in V
V_gs = 2.0  # Gate-source voltage in V
beta = 50e-6  # Transconductance parameter in A/V^2
W = 10e-6  # Channel width in cm
L = 1e-6   # Channel length in cm

# Capacitance calculation
C_ox = epsilon_ox / tox  # Gate capacitance in F/cm^2

# Drain current in saturation region
I_D = (beta / 2) * (V_gs - V_th)**2

# Transconductance
g_m = beta * (V_gs - V_th)

# Small-signal transconductance
g_m_small = 2 * I_D / (V_gs - V_th)

# Small-signal drain current
I_D_small = (beta / 2) * (W / L) * (V_gs - V_th)**2

# Output the results
print(f"Gate capacitance (C_ox): {C_ox:.3e} F/cm^2")
print(f"Drain current (I_D): {I_D:.3e} A")
print(f"Transconductance (g_m): {g_m:.3e} S")
print(f"Small-signal transconductance (g_m_small): {g_m_small:.3e} S")
print(f"Small-signal drain current (I_D_small): {I_D_small:.3e} A")
```

```

import math

# 定数の定義
q = 1.6e-19  # 電荷 (C)
N_A = 1e17  # アクセプタ濃度 (cm^-3)
phi_F = 0.3  # フェルミポテンシャル (V)
V_BS = 0.0  # ソースバルク電圧 (V)
lambda_value = 0.02  # チャネル長調整効果係数 (V^-1)
V_DS = 3.0  # ドレインソース電圧 (V)

# これまでの定義
epsilon_0 = 8.85e-14  # 真空の誘電率 (F/cm)
epsilon_ox = 3.9 * epsilon_0  # 酸化膜の誘電率 (F/cm)
tox = 9e-9  # 酸化膜の厚さ (cm)
C_ox = epsilon_ox / tox  # ゲート容量 (F/cm^2)
beta = 50e-6  # トランスコンダクタンスパラメータ (A/V^2)
V_th0 = 1.0  # 基準しきい値電圧 (V)
V_gs = 2.0  # ゲートソース電圧 (V)
I_D = (beta / 2) * (V_gs - V_th0)**2  # 飽和領域におけるドレイン電流 (A)

# チャネル長調整式 (2.4)
V_th = V_th0 + math.sqrt((2 * q * N_A / C_ox) * (V_BS + 2 * phi_F)) - math.sqrt((2 * q * N_A / C_ox) * 2 * phi_F)

# ドレイン電流式 (2.5)
I_D_lambda = (beta / 2) * (V_gs - V_th)**2 * (1 + lambda_value * V_DS)

# トランスコンダクタンス (2.6)
g_m = math.sqrt(2 * beta * I_D) * (1 + lambda_value * V_DS)

# 小信号モデルの出力抵抗 (2.7)
r_o = 1 / (lambda_value * I_D)

# チャネル長調整効果 (2.18)
g_m_channel = g_m / (2 * math.sqrt(2 * phi_F + V_BS))

# 出力抵抗 (2.38)
r_o_small = 1 / I_D

# 結果表示
print(f"しきい値電圧 (V_th): {V_th:.3f} V")
print(f"ドレイン電流 (I_D_lambda): {I_D_lambda:.3e} A")
print(f"トランスコンダクタンス (g_m): {g_m:.3e} S")
print(f"小信号モデルの出力抵抗 (r_o): {r_o:.3e} Ω")
print(f"チャネル長調整効果を考慮したトランスコンダクタンス (g_m_channel): {g_m_channel:.3e} S")
print(f"小信号モデルの出力抵抗 (r_o_small): {r_o_small:.3e} Ω")
```


P28
```
import math

# 定数の定義
q = 1.6e-19  # 電荷 (C)
N_A = 1e17  # アクセプタ濃度 (cm^-3)
phi_F = 0.3  # フェルミポテンシャル (V)
V_BS = 0.0  # ソースバルク電圧 (V)
lambda_value = 0.02  # チャネル長調整効果係数 (V^-1)
V_DS = 3.0  # ドレインソース電圧 (V)
epsilon_0 = 8.85e-14  # 真空の誘電率 (F/cm)
epsilon_ox = 3.9 * epsilon_0  # 酸化膜の誘電率 (F/cm)
tox = 9e-9  # 酸化膜の厚さ (cm)
C_ox = epsilon_ox / tox  # ゲート容量 (F/cm^2)
V_th0 = 1.0  # 基準しきい値電圧 (V)
V_gs = 2.0  # ゲートソース電圧 (V)
V_sg = 2.5  # ソースゲート電圧 (V, PMOS用)
W = 10e-6  # チャネル幅 (cm)
L = 1e-6  # チャネル長 (cm)
mu_n = 350  # 電子の移動度 (cm^2/V/s)
mu_p = 150  # 正孔の移動度 (cm^2/V/s)

# ドレイン電流 (NMOS)
I_D_nmos = (1/2) * mu_n * C_ox * (W / L) * (V_gs - V_th0)**2

# チャネル長調整効果を考慮したドレイン電流 (2.5)
I_D_lambda = (1/2) * mu_n * C_ox * (W / L) * ((V_gs - V_th0)**2 - (V_DS - V_gs)**2 / 4)

# トランスコンダクタンス (2.6)
g_m_nmos = (2 * I_D_nmos) / (V_gs - V_th0)

# 小信号モデルの出力抵抗 (2.7)
r_o_nmos = 1 / (lambda_value * I_D_nmos)

# PMOSのドレイン電流
I_D_pmos = (1/2) * mu_p * C_ox * (W / L) * (V_sg - V_th0)**2

# PMOSの出力抵抗
r_o_pmos = 1 / (lambda_value * I_D_pmos)

# チャネル長調整効果を考慮したしきい値電圧 (2.4)
V_th_adjusted = V_th0 + math.sqrt((2 * q * N_A / C_ox) * (V_BS + 2 * phi_F)) - math.sqrt((2 * q * N_A / C_ox) * 2 * phi_F)

# ゲート容量計算式 (CG)
C_G = (2 / 3) * W * L * C_ox

# ソース・ドレイン間の浮遊容量 (C_DB)
C_DB = W * L * C_ox

# しきい値電圧の変化量 (ΔV_th)
V_SB = 0.4  # ソースバルク電圧 (V)
gamma = 0.5  # ゲートのしきい値の係数
Delta_Vth = gamma * (math.sqrt(2 * phi_F - V_SB) - math.sqrt(2 * phi_F))

# 結果表示
print(f"NMOS ドレイン電流 (I_D_nmos): {I_D_nmos:.3e} A")
print(f"PMOS ドレイン電流 (I_D_pmos): {I_D_pmos:.3e} A")
print(f"チャネル長調整効果を考慮した NMOS ドレイン電流 (I_D_lambda): {I_D_lambda:.3e} A")
print(f"NMOS トランスコンダクタンス (g_m_nmos): {g_m_nmos:.3e} S")
print(f"NMOS 小信号モデルの出力抵抗 (r_o_nmos): {r_o_nmos:.3e} Ω")
print(f"PMOS 小信号モデルの出力抵抗 (r_o_pmos): {r_o_pmos:.3e} Ω")
print(f"しきい値電圧の変化量 (ΔV_th): {Delta_Vth:.3e} V")
print(f"ゲート容量 (C_G): {C_G:.3e} F")
print(f"ソース・ドレイン間の浮遊容量 (C_DB): {C_DB:.3e} F")


```
P22
```
import math

# 定数の定義
q = 1.6e-19  # 電荷 (C)
N_A = 1e17  # アクセプタ濃度 (cm^-3)
phi_F = 0.3  # フェルミポテンシャル (V)
V_BS = 0.0  # ソースバルク電圧 (V)
lambda_value = 0.02  # チャネル長調整効果係数 (V^-1)
V_DS = 3.0  # ドレインソース電圧 (V)
epsilon_0 = 8.85e-14  # 真空の誘電率 (F/cm)
epsilon_ox = 3.9 * epsilon_0  # 酸化膜の誘電率 (F/cm)
tox = 9e-9  # 酸化膜の厚さ (cm)
C_ox = epsilon_ox / tox  # ゲート容量 (F/cm^2)
V_th0 = 1.0  # 基準しきい値電圧 (V)
V_gs = 2.0  # ゲートソース電圧 (V)
V_sg = 2.5  # ソースゲート電圧 (V, PMOS用)
W = 10e-6  # チャネル幅 (cm)
L = 1e-6  # チャネル長 (cm)
mu_n = 350  # 電子の移動度 (cm^2/V/s)
mu_p = 150  # 正孔の移動度 (cm^2/V/s)
E = 1.5e-6  # 拡散領域の幅 (cm)
C_sw = 5e-15  # 単位面積あたりの拡散容量 (F/cm^2)
C_ov = 2e-15  # オーバーラップ容量 (F/cm)

# ドレイン電流 (NMOS) の計算
I_D_nmos = mu_n * C_ox * (W / L) * ((V_gs - V_th0) * V_DS - (V_DS**2) / 2)

# チャネル長調整効果を考慮したドレイン電流 (2.5)
I_D_lambda = mu_n * C_ox * (W / L) * ((V_gs - V_th0) * V_DS - (V_DS**2) / 2)

# トランスコンダクタンス (2.6)
g_m_nmos = math.sqrt(2 * mu_n * C_ox * (W / L) * I_D_nmos)

# 小信号モデルの出力抵抗 (2.7)
r_o_nmos = 1 / (lambda_value * I_D_nmos)

# ゲートドレイン間の容量 (C_DB)
C_DB = (W / 2) * E * C_ox + 2 * ((W / 2) + E) * C_sw

# ゲートソース間の容量 (C_SB)
C_SB = (W / 2) * E * C_ox + 2 * ((W / 2) + E) * C_sw

# ゲートソース間の容量 (C_GS)
C_GS = (2 / 3) * W * L * C_ox + W * C_ov

# トランジスタの周波数特性 (f_T)
f_T = g_m_nmos / (2 * math.pi * (C_DB + C_GS))

# 結果表示
print(f"NMOS ドレイン電流 (I_D_nmos): {I_D_nmos:.3e} A")
print(f"チャネル長調整効果を考慮した NMOS ドレイン電流 (I_D_lambda): {I_D_lambda:.3e} A")
print(f"NMOS トランスコンダクタンス (g_m_nmos): {g_m_nmos:.3e} S")
print(f"NMOS 小信号モデルの出力抵抗 (r_o_nmos): {r_o_nmos:.3e} Ω")
print(f"ゲート-ドレイン容量 (C_DB): {C_DB:.3e} F")
print(f"ゲート-ソース容量 (C_SB): {C_SB:.3e} F")
print(f"ゲート-ソース間容量 (C_GS): {C_GS:.3e} F")
print(f"トランジスタの周波数特性 (f_T): {f_T:.3e} Hz")
```

P37
```
import math

# 定数の定義
mu_n = 350  # 電子の移動度 (cm^2/V/s)
mu_p = 100  # 正孔の移動度 (cm^2/V/s)
C_ox = 8.85e-8  # 酸化膜容量 (F/cm^2)
W = 50e-6  # チャネル幅 (cm)
L = 0.5e-6  # チャネル長 (cm)
lambda_value = 0.02  # チャネル長調整パラメータ (V^-1)
V_gs = 1.5  # ゲート-ソース電圧 (V)
V_th = 0.7  # しきい値電圧 (V)
V_ds = 1.466  # ドレイン-ソース電圧 (V)
I_D = 0.5e-3  # ドレイン電流 (A)
gamma = 0.4  # 基板バイアス係数
V_SB = 0.5  # ソースバルク電圧 (V)

# しきい値電圧の計算 (基板バイアス効果を考慮)
V_th_adjusted = V_th + gamma * (math.sqrt(2 * phi_F + V_SB) - math.sqrt(2 * phi_F))

# ドレイン電流の計算 (飽和領域)
I_D_calculated = (1 / 2) * mu_n * C_ox * (W / L) * (V_gs - V_th_adjusted)**2 * (1 + lambda_value * V_ds)

# トランスコンダクタンス g_m1
g_m1 = math.sqrt(2 * mu_n * C_ox * (W / L) * I_D)

# 出力抵抗 r_o1
r_o1 = 1 / (lambda_value * I_D)

# M2 トランジスタのトランスコンダクタンス g_m2
g_m2 = math.sqrt(2 * mu_p * C_ox * (W / L) * I_D)

# M2 トランジスタの出力抵抗 r_o2
r_o2 = 10e3  # 10kΩ

# 負荷抵抗 R_L の計算 (並列接続)
R_L = 1 / (1 / r_o1 + 1 / r_o2 + g_m2)

# 増幅回路の電圧利得 A_v の計算
A_v = -g_m1 * R_L

# PMOS の場合のトランスコンダクタンス g_m2 (PMOS用)
g_m2_PMOS = 0.876e-3  # 0.876 mS

# PMOS の場合の負荷抵抗 R_L の計算
R_L_PMOS = 1 / (1 / r_o1 + 1 / r_o2 + g_m2_PMOS)

# PMOS の場合の増幅回路の電圧利得 A_v の計算
A_v_PMOS = -g_m1 * R_L_PMOS

# 結果表示
print(f"しきい値電圧 (V_th_adjusted): {V_th_adjusted:.3f} V")
print(f"ドレイン電流 (I_D_calculated): {I_D_calculated:.3e} A")
print(f"トランスコンダクタンス g_m1: {g_m1:.3e} S")
print(f"出力抵抗 r_o1: {r_o1:.3e} Ω")
print(f"M2 のトランスコンダクタンス g_m2: {g_m2:.3e} S")
print(f"M2 の出力抵抗 r_o2: {r_o2:.3e} Ω")
print(f"負荷抵抗 R_L: {R_L:.3e} Ω")
print(f"増幅回路の電圧利得 A_v: {A_v:.3f}")
print(f"PMOS の負荷抵抗 R_L_PMOS: {R_L_PMOS:.3e} Ω")
print(f"PMOS の増幅回路の電圧利得 A_v_PMOS: {A_v_PMOS:.3f}")


```
P39
```
import math

# 定数の定義
mu_n = 350  # 電子の移動度 (cm^2/V/s)
mu_p = 100  # 正孔の移動度 (cm^2/V/s)
C_ox = 8.85e-8  # 酸化膜容量 (F/cm^2)
W = 50e-6  # チャネル幅 (cm)
L = 0.5e-6  # チャネル長 (cm)
lambda_p = 0.05  # PMOSのチャネル長調整パラメータ (V^-1)
V_gs = 1.5  # ゲート-ソース電圧 (V)
V_th = 0.7  # しきい値電圧 (V)
I_D1 = 0.5e-3  # M1のドレイン電流 (A)
I_D2 = 0.5e-3  # M2のドレイン電流 (A)
V_DS2 = 1.534  # M2のドレイン-ソース電圧 (V)
V_dd = 2.00  # 電源電圧 (V)

# M2 の出力抵抗 r_o2 の計算
r_o2 = 1 / (lambda_p * I_D2)  # 40kΩ として計算される

# トランスコンダクタンス g_m1
g_m1 = math.sqrt(2 * mu_n * C_ox * (W / L) * I_D1)

# トランスコンダクタンス g_m2
g_m2 = math.sqrt(2 * mu_p * C_ox * (W / L) * I_D2)

# 負荷抵抗 R_L の計算 (r_o1 || r_o2 || 1/g_m2)
r_o1 = r_o2  # M1とM2の同一条件で
R_L = 1 / (1 / r_o1 + 1 / r_o2 + g_m2)

# 電圧利得 A_v の計算
A_v = -g_m1 * R_L

# 最小 V_DS1 の計算
V_DS1_min = 0.269  # V_DS1 の最小値は問題文の計算から与えられる

# 最大出力電圧スイングの計算
V_out_min = V_DS1_min
V_out_max = V_dd
output_swing = (V_out_min, V_out_max)

# 結果表示
print(f"M2 の出力抵抗 r_o2: {r_o2:.3e} Ω")
print(f"トランスコンダクタンス g_m1: {g_m1:.3e} S")
print(f"トランスコンダクタンス g_m2: {g_m2:.3e} S")
print(f"負荷抵抗 R_L: {R_L:.3e} Ω")
print(f"電圧利得 A_v: {A_v:.3f}")
print(f"出力電圧スイング: {output_swing[0]:.3f} V - {output_swing[1]:.3f} V")
```
P40
```
import math

# 定数の定義
mu_n = 350  # 電子の移動度 (cm^2/V/s)
C_ox = 8.85e-8  # 酸化膜容量 (F/cm^2)
W = 50e-6  # チャネル幅 (cm)
L = 0.5e-6  # チャネル長 (cm)
lambda_value = 0  # チャネル長調整パラメータ (V^-1), 飽和領域を仮定
V_gs = 1.5  # ゲート-ソース電圧 (V)
V_th = 0.7  # しきい値電圧 (V)
I_D = 1e-3  # ドレイン電流 (A)
R_D = 2e3  # 負荷抵抗 (Ω)
V_dd = 3.0  # 電源電圧 (V)

# トランスコンダクタンス g_m の計算
g_m = math.sqrt(2 * mu_n * C_ox * (W / L) * I_D)

# 小信号抵抗 r_o の計算 (lambda がゼロの場合 r_o = 無限大)
r_o = 1 / (lambda_value * I_D) if lambda_value != 0 else float('inf')

# 負荷抵抗 R_D と r_o の並列接続 (飽和領域では r_o は無限大なので R_D の値に近づく)
R_parallel = R_D if r_o == float('inf') else 1 / (1 / r_o + 1 / R_D)

# 小信号利得 A_v の計算
A_v = -g_m * R_parallel

# オーバードライブ電圧 V_ov の計算
V_ov = V_gs - V_th

# ドレイン電流の式を用いた入力電圧 V_in の計算
V_in = V_ov / math.sqrt(2 * mu_n * C_ox * (W / L) * I_D)

# 出力電圧の計算
V_out_max = V_dd - I_D * R_D
V_out_min = V_th + V_ov  # 出力電圧スイングの最小値
output_swing = (V_out_min, V_out_max)

# 結果表示
print(f"トランスコンダクタンス g_m: {g_m:.3e} S")
print(f"小信号抵抗 r_o: {r_o:.3e} Ω")
print(f"負荷抵抗 R_parallel: {R_parallel:.3e} Ω")
print(f"小信号利得 A_v: {A_v:.3f}")
print(f"入力電圧 V_in: {V_in:.3f} V")
print(f"出力電圧スイング: {output_swing[0]:.3f} V - {output_swing[1]:.3f} V")

```


P41
```
import math

# Given constants
mu_n = 1.342e-4  # Electron mobility in A/V^2
C_ox = 1  # Oxide capacitance per unit area (assuming normalized)
W = 50e-6  # Channel width in meters
L = 0.5e-6  # Channel length in meters
V_TH = 1  # Threshold voltage in volts
R_D = 2000  # Drain resistance in ohms

# Drain current for different scenarios
I_D1 = 1e-3  # Drain current 1 in Amperes (for V_out = 1V)
I_D2 = 0.25e-3  # Drain current 2 in Amperes (for V_out = 2.5V)

# Calculating input voltage for both cases
V_in1 = math.sqrt((2 * I_D1) / (mu_n * C_ox * (W / L))) + V_TH
V_in2 = math.sqrt((2 * I_D2) / (mu_n * C_ox * (W / L))) + V_TH

# Calculating transconductance for both cases
g_m1 = math.sqrt(2 * mu_n * C_ox * (W / L) * I_D1)
g_m2 = math.sqrt(2 * mu_n * C_ox * (W / L) * I_D2)

# Calculating voltage gain for both cases
A_v1 = -g_m1 * R_D
A_v2 = -g_m2 * R_D

# Display results
results = {
    "Input Voltage for V_out = 1V": V_in1,
    "Input Voltage for V_out = 2.5V": V_in2,
    "Transconductance for V_out = 1V": g_m1,
    "Transconductance for V_out = 2.5V": g_m2,
    "Voltage Gain for V_out = 1V": A_v1,
    "Voltage Gain for V_out = 2.5V": A_v2
}

results
```
P50


P68