1. 解析モードの要点
■ DC解析(動作点)
- 目的: 定常状態の Vnode, Ibranch を求める。
- 数式: [G]*V = I(非線形あり→ニュートン反復)。
- モデル置換: C=open, L=short。
■ AC解析(小信号周波数応答)
-
目的: OP点周りのゲイン/位相。
-
手順: DC(OP)→小信号線形化→H(jω)評価。
-
例: RC-LPF
- H(jω) = 1 / (1 + j ω R C)
- |H|_dB = 20*log10(1/sqrt(1+(ωRC)^2))
- Phase = -atan(ωRC) [rad]
- fc = 1/(2πRC)
■ 過渡解析(時間応答)
-
目的: V(t), I(t) 波形。
-
例: RCステップ応答
- τ = R*C
- Vout(t) = Vin*(1 - exp(-t/τ))
2. 測定・評価の基本
- 利得: Gain_dB(f) = 20*log10( |Vout/Vin| )
- 位相: Phase_deg = angle(Vout/Vin)*180/π
- 立上り時間: t_r(10–90%) を波形から取得
- 時定数照合: t_63% ≈ τ
- 消費電力(平均): Pavg = (1/T) ∫ v(t)*i(t) dt
- SNDR(必要時): 20*log10( Vrms_signal / Vrms_dist+noise )
3. 収束・数値安定化の実務
- 初期条件: .ic V(node)=value
- スイッチ急峻入力→PWLやTD, TR パラメータで立上りを与える
- GMIN, RELTOL, ABSTOL 調整
- TRANのステップ上限: .tran maxstep 指定(ナイキスト考慮)
- 周波数掃引は十分点数(dec/lin)確保
4. 実行用SPICEネットリスト
4.1 RC Low-Pass(DC/AC/TRAN一式)
* RC Low-Pass Filter
V1 in 0 SIN(0 1 1k) ; 1 kHz, 1 Vpp/2 (振幅=1V)
R1 in out 1k
C1 out 0 1u
* Analyses
.op
.ac dec 100 10 100k
.tran 0.1m 5m 0 1u ; step=0.1ms, maxstep=1us
* Probes
.probe V(in) V(out)
* Checks (理論照合目安)
* fc ~ 1/(2*pi*1e3*1e-6) = 159.15 Hz
.end
評価ポイント
- ACで |H(1kHz)| ≈ 1/sqrt(1+(2π1e31e-3)^2) ≈ 0.157 → -16.1 dB 目安
- TRANでステップ応答させる場合は V1 を PULSE に変更し τ=1 ms を確認
4.2 CMOS インバータ(TRAN中心:遅延/立上り)
(レベル1簡易モデル例。ツール付属のMOSモデルに置換可)
* CMOS Inverter (Transient)
.param VDD=1.8 Wn=10u Ln=180n Wp=20u Lp=180n
VDD vdd 0 {VDD}
Vin in 0 PULSE(0 {VDD} 0 100p 100p 5n 10n) ; 10 ns 周期
* NMOS/PMOS(レベル1の簡易例)
.model NMOS NMOS Vto=0.45 KP=200e-6 Lambda=0.05
.model PMOS PMOS Vto=-0.45 KP=100e-6 Lambda=0.05
Mn out in 0 0 NMOS W={Wn} L={Ln}
Mp out in vdd vdd PMOS W={Wp} L={Lp}
Cload out 0 20f
.tran 10p 100n 0 1p
.op
.probe V(in) V(out)
* 測定例(ツールにより .meas 可)
* 伝搬遅延 t_pHL/t_pLH:V(out) が 0.5*VDD を横切る時間差
.end
評価ポイント
- ノイズマージン: DCスイープで Vin を 0→VDD、Vout を取得し VIL/VIH 推定
- 遅延: 入力/出力の50%クロッシング差分
- 負荷容量依存: Cload を掃引し遅延曲線作成
4.3 共ソース増幅器(AC/TRAN:利得と帯域)
* Common-Source Amplifier (AC + Transient)
.param VDD=1.8 RD=10k RS=0 Rsig=50 CL=200f
VDD vdd 0 {VDD}
Vin in 0 AC 1 SIN(0 5m 10k) ; AC=1 for AC gain, TRAN=5 mV@10 kHz
* NMOSモデル(例:Level1簡易)
.model NMOS NMOS Vto=0.5 KP=300e-6 Lambda=0.05
* バイアス用電流源 or 抵抗分割(ここでは定電流源例)
Ib vdd vb DC 200u
Rb1 vb 0 1e9 ; DCパス
M1 out in 0 0 NMOS W=20u L=180n
RD out vdd {RD}
CL out 0 {CL}
.op
.ac dec 200 10 100Meg
.tran 0.1u 2m 0 0.1u
.probe V(in) V(out)
* 目安:中域利得 Av ≈ -gm*RD || ro
* f3dB ≈ 1 / (2*pi*Rout*CL) (Rout ~ RD || ro)
.end
評価ポイント
- AC: 中域で Gain_dB ≈ 20*log10(|Av|)。低・高域の極/零点でロールオフ確認
- TRAN: 小振幅正弦で波形位相遅れと歪み確認
- バイアス最適化: Ib, W/L を調整し gm, ro→目標利得と帯域に合わせる
5. 実務チェックリスト
- モデル: ツール付属の BSIM/PSP へ置換(レベル1は教育用)
- 温度依存: .temp、TC1/TC2、AC/TRAN再実行
- ばらつき: .mc、.param で Monte Carlo/コーナー
- 出力: .meas で数値抽出(利得、fc、遅延、立上り、消費電力)
6. 典型トラブルと対処
-
収束失敗(dc op point failed)
- 初期条件 .ic、ソフトスタート入力、GMIN/RELTOL緩和
-
TRANでギザギザ(数値振動)
- maxstep を小さく、trtol 調整、ソースの立上りに有限傾斜
-
AC結果が想定外
- OPが不適切(カットオフ/飽和)、小信号条件確認、ネット名選択ミス
import numpy as np
import matplotlib.pyplot as plt
# =========================
# 0) Global plot settings
# =========================
plt.rcParams["figure.figsize"] = (9, 5)
# ============================================================
# 1) RC Low-Pass Filter — AC(Bode) and Transient Step
# RCローパス:周波数応答とステップ応答(理論式)
# ============================================================
# --- Parameters (change here) ---
R_rc = 1e3 # [ohm]
C_rc = 1e-6 # [F]
Vin_step = 1.0 # [V] step amplitude
f_min, f_max = 10.0, 1e5
N_pts = 600
# --- Derived ---
tau = R_rc * C_rc
fc = 1.0 / (2.0 * np.pi * tau)
# --- Bode (magnitude/phase) ---
f = np.logspace(np.log10(f_min), np.log10(f_max), N_pts)
w = 2.0 * np.pi * f
H = 1.0 / (1.0 + 1j * w * R_rc * C_rc)
mag_db = 20.0 * np.log10(np.abs(H))
phase_deg = np.angle(H, deg=True)
# --- Transient (step response) ---
t_end = 5.0 * tau
t = np.linspace(0.0, t_end, 1000)
vout_step = Vin_step * (1.0 - np.exp(-t / tau))
print("=== RC-LPF key numbers ===")
print(f"tau = {tau:.6e} s")
print(f"fc = {fc:.3f} Hz")
idx_1k = np.argmin(np.abs(f - 1e3))
print(f"|H|(1 kHz) = {10**(mag_db[idx_1k]/20):.4f} ({mag_db[idx_1k]:.2f} dB)")
# --- Plots ---
plt.figure()
plt.semilogx(f, mag_db)
plt.title("RC Low-Pass | Magnitude")
plt.xlabel("Frequency [Hz]")
plt.ylabel("Gain [dB]")
plt.grid(True, which="both")
plt.figure()
plt.semilogx(f, phase_deg)
plt.title("RC Low-Pass | Phase")
plt.xlabel("Frequency [Hz]")
plt.ylabel("Phase [deg]")
plt.grid(True, which="both")
plt.figure()
plt.plot(t, vout_step)
plt.title("RC Low-Pass | Step Response")
plt.xlabel("Time [s]")
plt.ylabel("Vout [V]")
plt.grid(True)
# ============================================================
# 2) CMOS Inverter (approx) — delay via RC model
# CMOSインバータ遅延近似:Ron×Cload の0.69則
# 入力:矩形波、出力:一次RCの立上り/立下り近似
# ============================================================
# --- Parameters ---
VDD = 1.8
f_clk = 100e6 # input clock
Tclk = 1.0 / f_clk
tr_in = 100e-12 # input rise time
tf_in = 100e-12 # input fall time
Ron_p = 2.0e3 # PMOS on-resistance (approx)
Ron_n = 1.5e3 # NMOS on-resistance (approx)
Cload = 20e-15 # load capacitance
# --- Derived delays (Elmore-like) ---
tpHL = 0.69 * Ron_n * Cload # high->low
tpLH = 0.69 * Ron_p * Cload # low->high
print("\n=== CMOS Inverter (approx) ===")
print(f"tpHL ~ {tpHL*1e12:.2f} ps")
print(f"tpLH ~ {tpLH*1e12:.2f} ps")
# --- Build input waveform and RC output approx over two periods ---
t2 = np.linspace(0.0, 2*Tclk, 4000)
vin_rect = 0.5*VDD*(1.0+np.sign(np.sin(2*np.pi*f_clk*t2))) # 0/ VDD ideal
# Output: piecewise RC towards 0 or VDD depending on input level
vout = np.zeros_like(t2)
v = VDD
last_edge_t = 0.0
charging = True # initial assume input low → PMOS on → charge to VDD
for i, tt in enumerate(t2):
# detect input state
in_high = vin_rect[i] > (0.5*VDD)
if in_high and charging:
# just switched to discharge (toward 0) at this step
charging = False
last_edge_t = tt
v_start = v
elif (not in_high) and (not charging):
# just switched to charge (toward VDD)
charging = True
last_edge_t = tt
v_start = v
# update v by RC law relative to last edge
dt = tt - last_edge_t
if charging: # towards VDD with Ron_p
v = VDD - (VDD - v_start)*np.exp(-dt/(Ron_p*Cload))
else: # towards 0 with Ron_n
v = v_start*np.exp(-dt/(Ron_n*Cload))
vout[i] = v
plt.figure()
plt.plot(t2, vin_rect, label="Vin")
plt.plot(t2, vout, label="Vout")
plt.title("CMOS Inverter | Approx Transient")
plt.xlabel("Time [s]")
plt.ylabel("Voltage [V]")
plt.grid(True)
plt.legend()
# ============================================================
# 3) Common-Source Amplifier — 1-pole AC model
# 共ソース増幅器:小信号1極モデル(gm, ro, RD, CL)
# ============================================================
# --- Parameters ---
gm = 2.5e-3 # [S]
ro = 40e3 # [ohm]
RD = 10e3 # [ohm]
CL_cs = 200e-15 # [F]
# --- Small-signal midband gain and pole ---
Rout = 1.0 / (1.0/ro + 1.0/RD)
Av0 = -gm * Rout
wp = 1.0 / (Rout * CL_cs)
fp = wp / (2.0*np.pi)
f_cs = np.logspace(2, 9, 800) # 100 Hz .. 1 GHz
w_cs = 2.0 * np.pi * f_cs
Hcs = Av0 / (1.0 + 1j * w_cs / wp)
mag_cs = 20.0 * np.log10(np.abs(Hcs))
phs_cs = np.angle(Hcs, deg=True)
print("\n=== Common-Source 1-pole ===")
print(f"Av0 (midband) ~ {Av0:.2f} V/V ({20*np.log10(abs(Av0)):.2f} dB)")
print(f"fp ~ {fp:.3e} Hz")
plt.figure()
plt.semilogx(f_cs, mag_cs)
plt.title("Common-Source | Magnitude (1-pole)")
plt.xlabel("Frequency [Hz]")
plt.ylabel("Gain [dB]")
plt.grid(True, which="both")
plt.figure()
plt.semilogx(f_cs, phs_cs)
plt.title("Common-Source | Phase (1-pole)")
plt.xlabel("Frequency [Hz]")
plt.ylabel("Phase [deg]")
plt.grid(True, which="both")
plt.show()