1. 基本方針
差動増幅回路における周波数特性を求めるために、小信号等価回路を作り、
ノード電圧 vx と vout において キルヒホッフの電流則 (KCL) を適用する。
2. vx ノードでの KCL
vx ( 1/(1/gm3) + 1/(1/sC1) ) = - gm1 vin1
整理すると:
vx (gm3 + sC1) / (gm3 sC1) = - gm1 vin1
よって:
vx = - gm1 vin1 / (gm3 + sC1)
→ ここで 入力 vin1 に対する中間ノード電圧 vx が求まった。
C1 と gm3 が並列に作用しており、低周波では gm3、
高周波ではコンデンサ C1 の影響が支配的になる。
3. vout ノードでの KCL
- gm2 vin2 - vout/r2 - gm4 vx - vout/r4 - vout sC2 = 0
整理して:
vout (1/r2 + 1/r4 + sC2) = - gm2 vin2 - gm4 vx
ここに vx を代入する。
4. vx を代入した式
vout = (r2 || r4) / (1 + sC2 (r2 || r4)) ( - gm2 vin2 + gm4 (gm1 vin1)/(gm3 + sC1) )
さらに整理して:
vout = (r2 || r4) / (1 + sC2 (r2 || r4)) ( (gm4 gm1)/(gm3 + sC1) vin1 - gm2 vin2 )
5. 差動入力の仮定
トランジスタペアが対称であると仮定し、
gm3 = gm4 = gmp
gm1 = gm2 = gmn
vin1 = vin / 2
vin2 = - vin / 2
を代入すると:
vout = (r2 || r4) / (1 + sC2 (r2 || r4)) ( gmn gmp / (gmp + sC1) ) vin
→ 差動入力 vin に対する出力 vout の式が得られた。
6. 周波数領域での表現
s = jω とすると、
vout = ( (r2 || r4) gmn (1 + ω C1 / (j gmp)) )
/ ( (1 + jω C2 (r2 || r4)) (1 + jω C1 / gmp) ) vin
7. 極 (Pole) と零点 (Zero)
この回路の伝達関数 H(jω) = vout/vin には以下の特徴がある:
-
低域極 (p1)
p1 = 1 / (C2 (r2 || r4))
→ 出力抵抗 (r2 || r4) と負荷容量 C2 によって決まる低域のカットオフ周波数。
-
高域極 (p2)
p2 = gmp / C1
→ トランジスタ gm と容量 C1 による高周波の制限。
-
零点 (z1)
z1 = 2 gmp / C1
→ C1 の影響で高周波領域に零点が現れ、特定の周波数で利得が打ち消されにくくなる。
8. 特性のまとめ
-
低周波領域: 増幅率はほぼ DC 値に近づく
Av ≈ gmn (r2 || r4)
-
中周波領域: C2 によりロールオフが始まり、ゲインが下がる
-
高周波領域: C1 の極 (p2) によりさらにゲインが減衰
ただし零点 (z1) により一時的に周波数応答が持ち上がることがある
9. ボード線図の解釈
- 低周波:フラットなゲイン (定常利得)
- p1 付近:-20 dB/dec の減衰
- p2 付近:-40 dB/dec の減衰
- z1 によって +20 dB/dec が打ち消し効果を持つ
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
# ============================
# Parameters (All variables centralized)
# ============================
gmn = 1e-3 * 20 # Transconductance of NMOS [A/V] (example: 20 mS)
gmp = 1e-3 * 10 # Transconductance of PMOS [A/V] (example: 10 mS)
r2 = 20e3 # Resistance r2 [Ohm]
r4 = 20e3 # Resistance r4 [Ohm]
C1 = 1e-12 # Capacitance C1 [F]
C2 = 10e-12 # Capacitance C2 [F]
# Parallel resistance
Rout = (r2 * r4) / (r2 + r4)
# Poles and zero
p1 = 1 / (C2 * Rout) # Low-frequency pole
p2 = gmp / C1 # High-frequency pole
z1 = 2 * gmp / C1 # Zero
print("p1 = %.2e [rad/s]" % p1)
print("p2 = %.2e [rad/s]" % p2)
print("z1 = %.2e [rad/s]" % z1)
# ============================
# Transfer function definition
# ============================
# H(s) = ( (Rout * gmn) * (1 + s/z1) ) / ( (1 + s/p1) (1 + s/p2) )
num = [Rout * gmn / z1, Rout * gmn] # numerator coefficients (s/z1 + 1)
den = [1/(p1*p2), (1/p1 + 1/p2), 1] # denominator (s^2/(p1p2) + s(1/p1+1/p2)+1)
system = signal.TransferFunction(num, den)
# ============================
# Frequency response (Bode plot)
# ============================
w = np.logspace(3, 9, 1000) # Frequency range: 1 kHz to 1 GHz
w, mag, phase = signal.bode(system, w)
# ============================
# Plot Bode diagram
# ============================
plt.figure()
plt.semilogx(w, mag)
plt.title("Bode Magnitude Response")
plt.xlabel("Frequency [rad/s]")
plt.ylabel("Magnitude [dB]")
plt.grid(which="both")
plt.figure()
plt.semilogx(w, phase)
plt.title("Bode Phase Response")
plt.xlabel("Frequency [rad/s]")
plt.ylabel("Phase [deg]")
plt.grid(which="both")
plt.show()