0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CMOSアナログ回路入門: LSI設計者のための 半導体シリーズのPythonコード   カスコード回路など

Last updated at Posted at 2024-07-03

image.png

import math

# 定数の設定
Cc = 0.3e-10  # キャパシタンス Cc (ファラッド単位)
GBW = 2000e6  # 利得帯域幅 GBW (ヘルツ単位)
SR = 150e-6  # スルーレート SR (V/s)
gm1 = GBW * (2 * math.pi) * Cc  # gm1 計算
gm6 = 10 * gm1  # gm6 は gm1 の10倍
beta_p = 1e-4  # p型のβ
beta_n = 2e-4  # n型のβ

# 差動テイル電流 I5 の計算
I5 = SR * Cc  # I5 = スルーレート * キャパシタンス
I1 = I5 / 2  # I1 は I5 の半分

# gm1 に対するアスペクト比 (wL)
aspect_ratio_1 = (gm1**2) / (2 * beta_n * I1)  # (wL)_1

# gm6 に対するアスペクト比 (wL) は与えられた値
aspect_ratio_2 = 20  # 与えられたアスペクト比

# 差動テイル電流 I7 の計算
I7 = aspect_ratio_2 * I5  # I7 = (wL アスペクト比) * I5

# λn と λp の値
lambda_n = 0.1  # λn (n型)
lambda_p = 0.1  # λp (p型)

# λn と λp の逆数
inverse_lambda_n = 1 / lambda_n  # λn の逆数
inverse_lambda_p = 1 / lambda_p  # λp の逆数

# gm1 / ((I5 / 2)(λn + λp))
gm1_ratio = gm1 / ((I5 / 2) * (lambda_n + lambda_p))

# gm6 / ((I7)(λn + λp))
gm6_ratio = gm6 / (I7 * (lambda_n + lambda_p))

# 最終結果の計算
final_result = gm1_ratio * gm6_ratio

# デシベル変換
def to_dB(value):
    return 20 * math.log10(value) if value > 0 else -float('inf')

# 結果を表示
print(f"gm1: {gm1:.3e} S ({to_dB(gm1):.3f} dB)")
print(f"gm6: {gm6:.3e} S ({to_dB(gm6):.3f} dB)")
print(f"I5 (差動テイル電流): {I5:.3e} A")
print(f"I1: {I1:.3e} A")
print(f"(wL) アスペクト比 1: {aspect_ratio_1:.3e}")
print(f"(wL) アスペクト比 2: {aspect_ratio_2}")
print(f"I7 (差動テイル電流 I7): {I7:.3e} A")
print(f"λn の逆数: {inverse_lambda_n:.3e}")
print(f"λp の逆数: {inverse_lambda_p:.3e}")
print(f"gm1 / ((I5 / 2)(λn + λp)): {gm1_ratio:.3e} ({to_dB(gm1_ratio):.3f} dB)")
print(f"gm6 / ((I7)(λn + λp)): {gm6_ratio:.3e} ({to_dB(gm6_ratio):.3f} dB)")
print(f"最終結果: {final_result:.3e} ({to_dB(final_result):.3f} dB)")

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import quad
from scipy.integrate import cumtrapz

# ガウス関数の定義
def gauss_function(x, sigma):
    return -np.exp(-x**2 / (2 * sigma**2))

# 不定積分関数の定義(積分定数を0とする)
def indefinite_integral(x, sigma):
    # scipyのquad関数で積分
    integral, _ = quad(gauss_function, 0, x, args=(sigma))
    return integral

# パラメータ設定
sigma = 0.01 # 標準偏差
x_values = np.linspace(-3, 3, 400)  # x 軸の範囲
y_values = gauss_function(x_values, sigma)  # y 値を計算

# 不定積分の計算
indef_integral_values = np.array([indefinite_integral(x, sigma) for x in x_values])

# プロットの作成
plt.figure(figsize=(10, 6))

# ガウス関数のプロット
plt.plot(x_values, y_values, label=r'$g(x) = -e^{-\frac{x^2}{2\sigma^2}}$', color='blue')

# 不定積分のプロット(積分定数は0)
plt.plot(x_values, indef_integral_values, label='Indefinite Integral of g(x)', color='orange')

# プロットの設定
plt.title("Negative Gaussian Function and Its Indefinite Integral")
plt.xlabel('x')
plt.ylabel('g(x)')
plt.axhline(0, color='black', linewidth=0.8)
plt.axvline(0, color='black', linewidth=0.8)
plt.legend()
plt.grid(True)

# プロットを表示
plt.show()

p33

import numpy as np
import matplotlib.pyplot as plt

# 定数の定義
e = 1.602e-19    # 電気素量 (C)
k_B = 1.38e-23   # ボルツマン定数 (J/K)
T = 300          # 絶対温度 (K), 室温と仮定
beta = 1e-6      # MOSFET のパラメータ (例として 1e-6 を設定)
gamma = 0.5      # 電界効果移動度に依存する係数 (仮定)
V_T = 0.7        # しきい値電圧 (V)

# ゲート・ソース間電圧 VGS とドレイン・ソース間電圧 VDS の範囲を設定
V_GS = np.linspace(0.6, 1.5, 100)  # ゲート・ソース間電圧 (V)
V_DS = np.linspace(0, 1, 100)      # ドレイン・ソース間電圧 (V)

# 2次元グリッドの作成
V_GS_grid, V_DS_grid = np.meshgrid(V_GS, V_DS)

# ドレイン電流 ID の計算
ID = beta * np.exp(gamma * (V_GS_grid - V_T)) * (1 - np.exp(-e * V_DS_grid / (k_B * T)))

# ドレイン電流 ID をプロット
plt.figure(figsize=(10, 8))
cp = plt.contourf(V_GS_grid, V_DS_grid, ID, levels=50, cmap='viridis')
plt.colorbar(cp)
plt.xlabel("$V_{GS}$ (V)")
plt.ylabel("$V_{DS}$ (V)")
plt.title("MOSFET Drain Current $I_D$ vs $V_{GS}$ and $V_{DS}$")
plt.show()

p36

import numpy as np
import matplotlib.pyplot as plt

# Definition of constants
beta = 1e-6       # MOSFET gain parameter (example value set to 1e-6)
V_T = 0.7         # Threshold voltage (V)
lambda_ = 0.02    # Channel length modulation parameter
gamma = 0.5       # Coefficient in the weak inversion region (assumed)

# Define the range for V_GS (gate-source voltage) and V_DS (drain-source voltage)
V_GS = np.linspace(0.2, 1.5, 100)  # Gate-source voltage (V)
V_DS = np.linspace(0, 1.5, 100)    # Drain-source voltage (V)

# Create an array to store drain current values
ID = np.zeros((len(V_GS), len(V_DS)))

# Calculate the drain current ID
for i, Vgs in enumerate(V_GS):
    for j, Vds in enumerate(V_DS):
        # Non-saturation region
        if Vds < Vgs - V_T:
            ID[i, j] = beta * ((Vgs - V_T) * Vds - 0.5 * Vds**2)
        # Saturation region
        elif Vgs >= V_T:
            ID[i, j] = 0.5 * beta * (Vgs - V_T)**2 * (1 + lambda_ * Vds)
        # Weak inversion region
        else:
            ID[i, j] = beta * np.exp(gamma * (Vgs - V_T))

# Create a meshgrid for V_GS and V_DS
V_GS_mesh, V_DS_mesh = np.meshgrid(V_GS, V_DS)

# Plot the results
plt.figure(figsize=(10, 8))
cp = plt.contourf(V_GS_mesh, V_DS_mesh, ID.T, levels=50, cmap='viridis')
plt.colorbar(cp)  # Add a colorbar
plt.xlabel("$V_{GS}$ (V)")  # X-axis label
plt.ylabel("$V_{DS}$ (V)")  # Y-axis label
plt.title("MOSFET Drain Current $I_D$ vs $V_{GS}$ and $V_{DS}$")  # Title
plt.show()

p42

import numpy as np
import matplotlib.pyplot as plt

# Constants definition
W = 1e-4         # Channel width (example: 100 µm)
L = 1e-6         # Channel length (example: 1 µm)
Cox = 1e-8       # Gate oxide capacitance (example: 10 nF/cm^2)
V_T = 0.7        # Threshold voltage (V)
V_sat = 1e5      # Saturation drift velocity (cm/s)
gamma = 0.5      # Coefficient in the weak inversion region (assumed)

# Define the range of gate voltage V_GS
V_GS = np.linspace(0, 2, 100)  # Gate voltage (V)

# Calculate mutual transconductance g_m for each region
g_m = np.zeros_like(V_GS)  # Initialize g_m array

# Weak inversion region: V_GS < V_T
weak_inversion = V_GS < V_T
g_m[weak_inversion] = (W / L) * np.exp(gamma * (V_GS[weak_inversion] - V_T))

# Strong inversion region: V_GS >= V_T
strong_inversion = V_GS >= V_T
g_m[strong_inversion] = (W / L) * (V_GS[strong_inversion] - V_T)

# Velocity saturation region: g_m becomes a constant value
g_m[V_GS > 1.2] = V_sat * W * Cox  # Set g_m constant for V_GS > 1.2 (example)

# Plot the results
plt.figure(figsize=(10, 6))
plt.plot(V_GS, g_m, label="$g_m$ (Mutual Transconductance)")
plt.axvline(x=V_T, color='r', linestyle='--', label="Threshold Voltage $V_T$")
plt.xlabel("Gate Voltage $V_{GS}$ (V)")
plt.ylabel("Mutual Transconductance $g_m$ (S)")
plt.title("MOSFET Mutual Transconductance $g_m$ vs. Gate Voltage $V_{GS}$")
plt.legend()
plt.grid()
plt.show()

p55

import numpy as np
import matplotlib.pyplot as plt

# Constants definition
gm = 5e-3   # Transconductance of the MOSFET (5 mS)
ro = 1e4    # Intrinsic output resistance of the MOSFET (10 kΩ)
Zs = np.linspace(0, 1000, 100)  # Source resistance (0 to 1 kΩ)

# Calculate output resistance Rout for varying source resistance Zs
Rout = ro * (1 + gm * Zs) + (Zs / ro) * gm * Zs

# Plotting the results
plt.figure(figsize=(8, 6))
plt.plot(Zs, Rout, label=r'$R_{out}$ (Output Resistance)', color='blue')
plt.xlabel('Source Resistance $Z_s$ (Ω)')
plt.ylabel('Output Resistance $R_{out}$ (Ω)')
plt.title('Output Resistance $R_{out}$ vs. Source Resistance $Z_s$')
plt.grid(True)
plt.legend()
plt.show()

p133

import numpy as np
import matplotlib.pyplot as plt

# Define constants
Delta_Vin = 0.01      # Differential input voltage (V)
gm = 1e-3             # Transconductance (S, 1 mS)
Rout_eff = 1e4        # Effective output resistance (Ω)
Cout = 1e-12          # Output capacitance (F, 1 pF)

# Define time range
t = np.linspace(0, 5e-8, 500)  # Time from 0 to 50 ns

# Calculate Vout(t) based on the equation
Vout_t = Delta_Vin * gm * Rout_eff * (1 - np.exp(-t / (Rout_eff * Cout)))

# Approximate linear response for small time values
Vout_linear = Delta_Vin * (gm / Cout) * t

# Plot the transient response
plt.figure(figsize=(10, 6))
plt.plot(t, Vout_t, label='$V_{out}(t)$ (Exact)', color='blue')
plt.plot(t, Vout_linear, label='$V_{out}(t) \\approx \\Delta V_{in} \\frac{g_m}{C_{out}} t$ (Approximation)', linestyle='--', color='orange')
plt.xlabel('Time (s)')
plt.ylabel('Output Voltage $V_{out}(t)$ (V)')
plt.title('Transient Response of the Amplifier Circuit')
plt.legend()
plt.grid()
plt.show()

p154

import numpy as np
import matplotlib.pyplot as plt

# Define the range of threshold voltage mismatch and beta mismatch
Delta_VT = np.linspace(0, 0.1, 100)     # Threshold voltage mismatch (0 to 0.1V)
Delta_beta_beta = np.linspace(0, 0.1, 100)  # Beta mismatch (0 to 0.1)

# Define constant values
V_T = 0.7      # Threshold voltage (V)
V_GS = 1.2     # Gate-source voltage (V)

# Calculate current mismatch (ΔI / I)
Delta_I_I = np.sqrt(4 * (Delta_VT / (V_GS - V_T))**2 + Delta_beta_beta**2)

# Plot the result as a surface plot
Delta_VT_mesh, Delta_beta_beta_mesh = np.meshgrid(Delta_VT, Delta_beta_beta)

# Surface plot of current mismatch
plt.figure(figsize=(10, 6))
plt.contourf(Delta_VT_mesh, Delta_beta_beta_mesh, Delta_I_I, levels=50, cmap='viridis')
plt.colorbar(label='Current Mismatch ΔI/I')
plt.xlabel('Threshold Voltage Mismatch ΔV_T (V)')
plt.ylabel('Beta Mismatch Δβ/β')
plt.title('Current Mismatch ΔI/I vs. ΔV_T and Δβ/β')
plt.grid(True)
plt.show()


ボルツマン統計、電子エネルギー


import numpy as np
import matplotlib.pyplot as plt

# Constants
k_B = 1.38e-23  # Boltzmann constant (J/K)
T = [300, 500, 700]  # Temperatures in Kelvin
E = np.linspace(0, 1.5e-19, 500)  # Energy range (Joules)

def boltzmann_distribution(E, T, k_B):
    return np.exp(-E / (k_B * T))

# Plotting
plt.figure(figsize=(10, 6))

for temp in T:
    distribution = boltzmann_distribution(E, temp, k_B)
    plt.plot(E * 1e19, distribution, label=f'T = {temp} K')  # Convert energy to eV for the x-axis

plt.title('Boltzmann Distribution of Electronic Energy Levels')
plt.xlabel('Energy (eV)')
plt.ylabel('Probability Density')
plt.legend()
plt.grid(True)
plt.show()


import numpy as np
import matplotlib.pyplot as plt

# Constants
k = 1.38e-23  # Boltzmann constant (J/K)
T = 300       # Temperature in Kelvin
q = 1.60e-19   # Electron charge (C)
I_s = 1e-12    # Saturation current (A)

# Diode equation
def diode_current(V, I_s, T, q, k):
    V_t = k * T / q  # Thermal voltage
    return I_s * (np.exp(V / V_t) - 1)

# Voltage range
V = np.linspace(-0.5, 0.8, 500)  # Voltage range from -0.5V to 0.8V

# Calculate current
I = diode_current(V, I_s, T, q, k)

# Plotting
plt.figure(figsize=(10, 6))
plt.plot(V, I, label='PN Junction Diode Characteristics')
plt.yscale('log')  # Log scale for current to show a wide range
plt.title('PN Junction Diode Voltage-Current Characteristics')
plt.xlabel('Voltage (V)')
plt.ylabel('Current (A)')
plt.grid(True, which='both', linestyle='--', linewidth=0.5)
plt.legend()
plt.show()






p42


import numpy as np
import matplotlib.pyplot as plt

# Constants
mu = 500e-4  # mobility (m^2/Vs)
Cox = 10e-9  # oxide capacitance per unit area (F/m^2)
W = 10e-6  # width of the MOSFET (m)
L = 2e-6  # length of the MOSFET (m)
V_T = 0.7  # threshold voltage (V)
lambda_ = 0.02  # channel length modulation parameter (1/V)
gamma = 0.1  # subthreshold slope factor (1/V)

beta = (W / L) * mu * Cox

# V_DS and V_GS range
V_DS = np.linspace(0, 2, 200)
V_GS_values = [0.5, 1.0, 1.5, 2.0]  # Different V_GS values

def I_D(V_GS, V_DS):
    if V_GS > V_T:
        if V_DS < (V_GS - V_T):
            return beta * ((V_GS - V_T) * V_DS - 0.5 * V_DS**2)
        else:
            return 0.5 * beta * (V_GS - V_T)**2 * (1 + lambda_ * V_DS)
    else:
        return beta * np.exp(gamma * (V_GS - V_T))

# Plotting
plt.figure(figsize=(10, 6))

for V_GS in V_GS_values:
    I_D_values = [I_D(V_GS, V) for V in V_DS]
    plt.plot(V_DS, I_D_values, label=f'V_GS = {V_GS} V')

plt.xlabel('$V_{DS}$ (V)')
plt.ylabel('$I_D$ (A)')
plt.title('$I_D$ vs. $V_{DS}$ Characteristics for different $V_{GS}$ values')
plt.legend()
plt.grid(True)
plt.show()


import numpy as np
import matplotlib.pyplot as plt

# Constants
W = 1e-6       # Channel width (meters)
L = 1e-6       # Channel length (meters)
mu = 200e-4    # Carrier mobility (m^2/V·s)
Cox = 1e-8     # Oxide capacitance per unit area (F/m^2)
gamma = 0.1    # Fitting parameter
V_T = 0.7      # Threshold voltage (V)

# Calculate beta
beta = (W / L) * mu * Cox

# Gate-source voltage range
V_GS = np.linspace(0, 2, 500)  # Gate-source voltage range from 0V to 2V

# Calculate drain current
I_D = beta * np.exp(-gamma * (V_GS - V_T))

# Plotting
plt.figure(figsize=(10, 6))
plt.plot(V_GS, I_D, label=r'$I_D = \beta e^{-\gamma (V_{GS} - V_T)}$')
plt.title('MOSFET Drain Current vs. Gate-Source Voltage')
plt.xlabel('Gate-Source Voltage $V_{GS}$ (V)')
plt.ylabel('Drain Current $I_D$ (A)')
plt.yscale('log')  # Log scale for current to show a wide range
plt.grid(True, which='both', linestyle='--', linewidth=0.5)
plt.legend()
plt.show()



P38
VGS-VT=√(2×ID/β)
P40
ID=(β/2)×(VGS-VT)^2
gm=β(VGS-VT)
横軸VGS


import numpy as np
import matplotlib.pyplot as plt

# Constants
W = 1e-6       # Channel width (meters)
L = 1e-6       # Channel length (meters)
mu = 200e-4    # Carrier mobility (m^2/V·s)
Cox = 1e-8     # Oxide capacitance per unit area (F/m^2)
V_T = 0.7      # Threshold voltage (V)

# Calculate beta
beta = (W / L) * mu * Cox

# Gate-source voltage range
V_GS = np.linspace(0.8, 2, 500)  # Gate-source voltage range from 0.8V to 2V

# Calculate drain current ID
I_D = (beta / 2) * (V_GS - V_T)**2

# Calculate transconductance gm
g_m = beta * (V_GS - V_T)

# Plotting
plt.figure(figsize=(12, 6))

# Plot ID vs. VGS
plt.subplot(2, 1, 1)
plt.plot(V_GS, I_D, label=r'$I_D = \frac{\beta}{2} (V_{GS} - V_T)^2$', color='blue')
plt.title('MOSFET Drain Current $I_D$ vs. Gate-Source Voltage $V_{GS}$')
plt.xlabel('Gate-Source Voltage $V_{GS}$ (V)')
plt.ylabel('Drain Current $I_D$ (A)')
plt.grid(True)
plt.legend()

# Plot gm vs. VGS
plt.subplot(2, 1, 2)
plt.plot(V_GS, g_m, label=r'$g_m = \beta (V_{GS} - V_T)$', color='red')
plt.title('MOSFET Transconductance $g_m$ vs. Gate-Source Voltage $V_{GS}$')
plt.xlabel('Gate-Source Voltage $V_{GS}$ (V)')
plt.ylabel('Transconductance $g_m$ (S)')
plt.grid(True)
plt.legend()

plt.tight_layout()
plt.show()



P49
ソース接地増幅

import numpy as np
import matplotlib.pyplot as plt

# Constants
W_L = 100  # Ratio W/L
mu = 600e-4  # Mobility μ in cm²/V·s
Cox = 2.5e-8  # Oxide capacitance per unit area Cox in F/cm²
VTH = 0.7  # Threshold voltage VTH in V
A = 0.0000001  # Amplitude A in V
omega = 2 * np.pi * 1  # Frequency ω in rad/s
VGS = 3.2  # Gate-source voltage VGS in V
gm = 0.002  # Transconductance gm in S

# Calculation of the constant term
constant_term = (W_L * mu * Cox / 2) * ((VGS - VTH) ** 2)
print(f'Constant Term: {constant_term}')

# Time array
t = np.linspace(0, 1, 1000)

# Input voltage vin
vin = A * np.sin(omega * t)

# Drain current ID
ID = constant_term + gm * vin

# Plotting
plt.figure(figsize=(10, 6))
plt.plot(t, ID, label='$I_D$')
plt.xlabel('Time (t)')
plt.ylabel('$I_D$')
plt.title('Plot of $I_D$ versus Time')
plt.legend()
plt.grid(True)
plt.show()

image.png

p50からp54

小信号等価回路
出力並列ROUT=r×ron/(r+ron)
rは電位固定された出力抵抗
ronはVinの出力抵抗
小信号等価回路ソース接地増幅
-ROUT×gm

小信号等価回路ゲート接地増幅
ROUT(gm+1/ron)

小信号等価回路ドレイン接地増幅
gm× ROUT/(1+gm×ROUT)

import numpy as np
import matplotlib.pyplot as plt

# Parameters
r = 1.0  # Output resistance
ron = 1.0  # Output resistance of Vin
gm = 1.0  # Transconductance

# Output parallel resistance
ROUT = r * ron / (r + ron)

# Small signal equivalent circuits
def source_degenerated_amplifier(ROUT, gm):
    return -ROUT * gm

def gate_degenerated_amplifier(ROUT, gm, ron):
    return ROUT * (gm + 1/ron)

def drain_degenerated_amplifier(ROUT, gm):
    return gm * ROUT / (1 + gm * ROUT)

# Frequency range for plotting
frequencies = np.linspace(1, 1e6, 1000)  # 1 Hz to 1 MHz

# Gain calculations
gain_source = source_degenerated_amplifier(ROUT, gm)
gain_gate = gate_degenerated_amplifier(ROUT, gm, ron)
gain_drain = drain_degenerated_amplifier(ROUT, gm)

# Convert gain to decibels
gain_source_db = 20 * np.log10(np.abs(gain_source))
gain_gate_db = 20 * np.log10(np.abs(gain_gate))
gain_drain_db = 20 * np.log10(np.abs(gain_drain))

# Plotting
plt.figure(figsize=(10, 6))
plt.plot(frequencies, gain_source_db * np.ones_like(frequencies), label='Source Degenerated Amplifier')
plt.plot(frequencies, gain_gate_db * np.ones_like(frequencies), label='Gate Degenerated Amplifier')
plt.plot(frequencies, gain_drain_db * np.ones_like(frequencies), label='Drain Degenerated Amplifier')

plt.xlabel('Frequency (Hz)')
plt.ylabel('Gain (dB)')
plt.title('Gain of Small Signal Equivalent Circuits in dB')
plt.legend()
plt.xscale('log')
plt.grid(True)
plt.show()

image.png

ドレイン接地回路レベルシフタ電位変換
VOUT=Vin-VTH-√(2I/β)

import math

# 入力値の設定
R = 1e3  # 負荷抵抗 (Ω)
r0 = 1e3  # 出力抵抗 (Ω)
gm = 1e-3  # トランジスタの増幅率 (S)
I = 1e-6  # 電流 (A)
VT = 0.7  # 閾値電圧 (V)
W = 1e-6  # チャンネル幅 (m)
L = 1e-6  # チャンネル長 (m)
mu = 200e-4  # キャリアの移動度 (m^2/Vs)
Cox = 1e-2  # 酸化膜の容量 (F/m^2)

# 利得計算
gain_gate = (R * r0) / (R + r0)
gain_drain = gain_gate * (gm + 1 / r0)
gain_feedback = (gm * gain_gate) / (1 + gm * gain_gate)

# 出力電圧計算
beta = (W / L) * mu * Cox
Vout = VT - math.sqrt(2 * I / beta)

# 結果の表示
print(f"ゲート接地増幅回路の利得: {gain_gate:.2f}")
print(f"ドレイン接地増幅回路の利得: {gain_drain:.2f}")
print(f"フィードバック後の利得: {gain_feedback:.2f}")
print(f"出力電圧: {Vout:.2f} V")


import numpy as np
import matplotlib.pyplot as plt

# Constants
A = 1          # Amplitude of input sine wave
omega = 2 * np.pi * 1  # Angular frequency (1 Hz)
V_TH = 0.7     # Threshold voltage (V)
I = 0.01       # Current (A)
beta = 0.1     # Process transconductance parameter (A/V^2)

# Time vector
t = np.linspace(0, 1, 1000)

# Input voltage
V_in = A * np.sin(omega * t)

# Output voltage
V_out = V_in - V_TH - np.sqrt(2 * I / beta)

# Plotting
plt.figure(figsize=(10, 6))
plt.plot(t, V_in, label='Vin = Asin(ωt)')
plt.plot(t, V_out, label='Vout = Vin - VTH - √(2I/β)')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.title('Drain-Grounded Level Shifter Circuit')
plt.legend()
plt.grid(True)
plt.show()

image.png

P55

P59 よく使うパラメータ

import math

# 定数およびパラメータの定義
λ = 0.01  # Lambda (V^-1)
ID = 1e-3  # Drain current (A)
W = 10e-6  # Width of the MOSFET (m)
L = 1e-6  # Length of the MOSFET (m)
μ = 350e-4  # Mobility (m^2/Vs)
Cox = 2.3e-3  # Oxide capacitance per unit area (F/m^2)

# 出力抵抗の計算
ro = 1 / (λ * ID)

# gmの計算
gm = math.sqrt(2 * (W / L) * μ * Cox * ID)

# 一定要素のVDの計算
VD = math.sqrt(2 * ID / ((W / L) * μ * Cox))

# ダイオード接続抵抗の計算
rd = 1 / gm

# ゲートバイアス印加MOSFET抵抗の計算(出力抵抗と同じ)
rg = ro

# 結果の出力
print(f"出力抵抗 ro = {ro:.2e} Ω")
print(f"gm = {gm:.2e} S")
print(f"一定要素のVD = {VD:.2f} V")
print(f"ダイオード接続抵抗 rd = {rd:.2e} Ω")
print(f"ゲートバイアス印加MOSFET抵抗 rg = {rg:.2e} Ω")

image.png

p60


import sympy as sp

# Define variables
g_m, r_o, Z_S, Z_D, v_g, v_s_star, v_d_star = sp.symbols('g_m r_o Z_S Z_D v_g v_s_star v_d_star')

# Define the numerator and denominator of i_d
numerator = g_m * v_g - (g_m + 1/r_o) * v_s_star + v_d_star/r_o
denominator = 1 + g_m * Z_S + (Z_S + Z_D) / r_o

# Expression for i_d
i_d = numerator / denominator

# Calculate G_m (assuming vin = vg)
vin = v_g
G_m = i_d / vin

# Simplify the expression for G_m
G_m_simplified = sp.simplify(G_m)
print("Simplified G_m:", G_m_simplified)

# Example numerical values
g_m_val = 1e-3  # Transconductance (Siemens)
r_o_val = 1000  # Output resistance (Ohms)
Z_S_val = 50    # Source impedance (Ohms)
Z_D_val = 100   # Drain impedance (Ohms)
v_g_val = 1     # Gate voltage (V)
v_s_star_val = 0.5  # Source voltage (V)
v_d_star_val = 1.5  # Drain voltage (V)

# Substitute numerical values into G_m
G_m_numeric = G_m_simplified.subs({
    g_m: g_m_val,
    r_o: r_o_val,
    Z_S: Z_S_val,
    Z_D: Z_D_val,
    v_g: v_g_val,
    v_s_star: v_s_star_val,
    v_d_star: v_d_star_val
})

print("Numerical G_m:", G_m_numeric)

# Define the given parameters
gm = 0.01  # Transconductance (in S, Siemens)
ro = 10e3  # Output resistance (in Ohms)
Zs = 5e3   # Source resistance (in Ohms)
Zd = 2e3   # Drain resistance (in Ohms)

# 1. Calculate the voltage conversion factor Gm
# Formula from the image: Gm = gm * ro / (ro + Zs + Zd + gm * ro * Zs)
Gm = gm * ro / (ro + Zs + Zd + gm * ro * Zs)
print(f"Voltage Conversion Factor Gm = {Gm:.4f}")

# 2. Calculate the output resistances Rs* and Rd*
# Formula from the image:
Rs_star = (1 / gm) + Zs + (Zd / (gm * ro))
Rd_star = ro + gm * ro * Zs + Zd
print(f"Source-side Effective Resistance Rs* = {Rs_star:.2f} Ohms")
print(f"Drain-side Effective Resistance Rd* = {Rd_star:.2f} Ohms")

# 3. Calculate the overall gain A
# Assuming Rout_eff = ro
# Gain formula: A = gm * Zs / (1 + gm * Zs)
A = gm * Zs / (1 + gm * Zs)
print(f"Overall Gain A = {A:.4f}")

# Additional resistance calculation if needed
Rout_eff = (ro * Rd_star) / (ro + Rd_star)
print(f"Effective Output Resistance Rout_eff = {Rout_eff:.2f} Ohms")


P62
ソース接地、ゲート接地、ドレイン接地の増幅は
出力抵抗=オン抵抗×ROUT/(オン抵抗+ROUT)に比例する
ROUTを大きくするとオン抵抗の値に収束して増幅値も大きくなる

# Import necessary libraries
import sympy as sp

# Define the variables
R_out, r_o, g_m, Z_S, Z_D, R_out_eff, G_m, id_vin, vg = sp.symbols('R_out r_o g_m Z_S Z_D R_out_eff G_m id_vin vg')

# Formula G.7
A_G7 = R_out * (id_vin * R_out_eff * G_m - g_m * r_o / (r_o + (g_m * r_o + 1) * Z_S + Z_D) * R_out_eff) / (r_o + (g_m * r_o + 1) * Z_S + Z_D)

# Formula G.8
A_G8 = R_out * (id_vin * R_out_eff - (g_m * r_o + 1) / (r_o + (g_m * r_o + 1) * Z_S + Z_D) * R_out_eff) / (r_o + (g_m * r_o + 1) * Z_S + Z_D)

# Formula G.9
R_out_eff_formula = r_o * R_out / (r_o + R_out)

# Formula G.10
A_G10 = -g_m * Z_S / (1 + g_m * Z_S)

# Display the formulas
print("Formula G.7: ", A_G7)
print("Formula G.8: ", A_G8)
print("Formula G.9 (Effective R_out): ", R_out_eff_formula)
print("Formula G.10: ", A_G10)

# Substitute example values to calculate (Optional, input your own values here)
example_values = {
    R_out: 1000,  # Replace with your value
    r_o: 100,     # Replace with your value
    g_m: 0.01,    # Replace with your value
    Z_S: 500,     # Replace with your value
    Z_D: 200,     # Replace with your value
    R_out_eff: 900, # Replace with your value
    G_m: 0.02,    # Replace with your value
    id_vin: 0.005 # Replace with your value
}

# Calculate with example values
A_G7_value = A_G7.subs(example_values)
A_G8_value = A_G8.subs(example_values)
R_out_eff_value = R_out_eff_formula.subs(example_values)
A_G10_value = A_G10.subs(example_values)

print("\nCalculated Results with Example Values:")
print("A (G.7): ", A_G7_value)
print("A (G.8): ", A_G8_value)
print("R_out_eff (G.9): ", R_out_eff_value)
print("A (G.10): ", A_G10_value)

P68~P73
増幅×ローパス
-gm×出力抵抗/(1+s/ωP)

ソース接地増幅

-gm×出力抵抗(1-s/ωz)/((1+s/ωP) (1+s/ωi))


import math

# 入力値の設定
R = 1e3  # 負荷抵抗 (Ω)
r0 = 1e3  # 出力抵抗 (Ω)
gm = 1e-3  # トランジスタの増幅率 (S)
I = 1e-6  # 電流 (A)
VT = 0.7  # 閾値電圧 (V)
W = 1e-6  # チャンネル幅 (m)
L = 1e-6  # チャンネル長 (m)
mu = 200e-4  # キャリアの移動度 (m^2/Vs)
Cox = 1e-2  # 酸化膜の容量 (F/m^2)

# 利得計算
gain_gate = (R * r0) / (R + r0)
gain_drain = gain_gate * (gm + 1 / r0)
gain_feedback = (gm * gain_gate) / (1 + gm * gain_gate)

# 出力電圧計算
beta = (W / L) * mu * Cox
Vout = VT - math.sqrt(2 * I / beta)

# 結果の表示
print(f"ゲート接地増幅回路の利得: {gain_gate:.2f}")
print(f"ドレイン接地増幅回路の利得: {gain_drain:.2f}")
print(f"フィードバック後の利得: {gain_feedback:.2f}")
print(f"出力電圧: {Vout:.2f} V")



import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

# Define the parameters for the transfer functions
gm = 0.1  # Transconductance (Siemens)
R_out = 100000000  # Output resistance (Ohms)
omega_P = 2 * np.pi * 1e6  # Pole frequency (rad/s)
omega_z = 2 * np.pi * 10e6  # Zero frequency (rad/s)
omega_i = 2 * np.pi * 100e3  # Another pole frequency (rad/s)

# Define the transfer functions
# Simple Amplifier with Low-pass Filter
num1 = [gm * R_out]
den1 = [1, omega_P]

# Common Source Amplifier
num2 = [gm * R_out, gm * R_out * omega_z]
den2 = [1, omega_P + omega_i, omega_P * omega_i]

# Create the transfer function systems
system1 = signal.TransferFunction(num1, den1)
system2 = signal.TransferFunction(num2, den2)

# Frequency range for Bode plot
w = np.logspace(3, 8, 1000)  # Frequency range from 1 kHz to 100 MHz

# Calculate the Bode plots
w, mag1, phase1 = signal.bode(system1, w)
w, mag2, phase2 = signal.bode(system2, w)

# Plot the Bode magnitude plots
plt.figure()
plt.semilogx(w, mag1, label='Simple Amplifier with Low-pass Filter')
plt.semilogx(w, mag2, label='Common Source Amplifier')
plt.xlabel('Frequency [rad/s]')
plt.ylabel('Magnitude [dB]')
plt.title('Bode Magnitude Plot')
plt.legend()
plt.grid(which='both', axis='both')

# Plot the Bode phase plots
plt.figure()
plt.semilogx(w, phase1, label='Simple Amplifier with Low-pass Filter')
plt.semilogx(w, phase2, label='Common Source Amplifier')
plt.xlabel('Frequency [rad/s]')
plt.ylabel('Phase [degrees]')
plt.title('Bode Phase Plot')
plt.legend()
plt.grid(which='both', axis='both')

plt.show()

image.png

P96
熱ノイズ

import math

# 入力値の設定
k_B = 1.38e-23  # ボルツマン定数 (J/K)
T = 300  # 絶対温度 (K)
R = 1e3  # 抵抗値 (Ω)
Delta_f = 1e6  # 帯域幅 (Hz)

# 熱ノイズ電圧の計算
V_n = math.sqrt(4 * k_B * T * R * Delta_f)

# ノイズ電力の計算
P_n = 4 * k_B * T * R * Delta_f

# 結果の表示
print(f"熱ノイズ電圧 (RMS): {V_n:.2e} V")
print(f"ノイズ電力: {P_n:.2e} W")


import numpy as np
import matplotlib.pyplot as plt

# Constants
k_B = 1.38e-23  # Boltzmann's constant (J/K)
T = 300  # Temperature in Kelvin
r_ds = 1000  # Channel resistance (Ohms)

# Flicker noise constants
K = 1e-16  # Arbitrary constant for flicker noise
n = 1  # Frequency exponent for flicker noise

# Frequency range (logarithmic scale)
frequencies = np.logspace(1, 7, 500)  # 10 Hz to 10 MHz

# Thermal noise (independent of frequency)
S_thermal = 4 * k_B * T * r_ds * np.ones_like(frequencies)

# Flicker noise (1/f noise)
S_flicker = K / frequencies**n

# Plotting
plt.figure(figsize=(8, 6))
plt.loglog(frequencies, S_thermal, label='Thermal Noise', linewidth=2)
plt.loglog(frequencies, S_flicker, label='Flicker Noise (1/f)', linewidth=2)

# Labels and title
plt.title('Thermal Noise and Flicker Noise in MOSFET (Log-Log Plot)')
plt.xlabel('Frequency (Hz)')
plt.ylabel('Noise Power Spectral Density (V^2/Hz)')
plt.grid(True, which='both', linestyle='--', linewidth=0.5)
plt.legend()

# Show plot
plt.show()



P103

vin=Asinωt
Vinプラス=VCM+vin/2

Vinマイナス=VCM-vin/2

増幅=(√β×Iss)(Vinプラス-Vinマイナス)

import math

# 定数の設定
A = 0.1  # 振幅
omega = 1  # 角周波数
t = 1  # 時間
VCM = 3  # 共通モード電圧
beta = 1000  # トランジスタの直流電流増幅率
Iss =1   # ソース電流

# 入力電圧
vin = A * math.sin(omega * t)

# プラス入力電圧とマイナス入力電圧
Vin_plus = VCM + vin / 2
Vin_minus = VCM - vin / 2

# 増幅後の電圧
amplified_voltage = (math.sqrt(beta) * Iss) * (Vin_plus - Vin_minus)

# 増幅電圧比をデシベルに変換
gain_db = 20 * math.log10(amplified_voltage)

# 結果を表示
print(f"増幅後の電圧: {amplified_voltage} V")
print(f"増幅電圧比: {gain_db} dB")

image.png



p103

import math

# 定数の設定
VDD = 5.0  # 電源電圧の設定(例: 5V)
M3_M4_Voltage_Difference = 0.2  # M3とM4間の電圧差(例: 0.2V)
Fixed_Voltage = 0.9  # 固定電圧(例: 0.9V)

# 出力許容電圧の計算
Permissible_Output_Voltage = VDD - M3_M4_Voltage_Difference - Fixed_Voltage
print(f"Permissible Output Voltage = {Permissible_Output_Voltage} V")

# 6.11式: トランスコンダクタンスの計算
def transconductance(I1, I2, vin):
    return (I1 - I2) / vin

# 6.11式の特別ケース: g_md = sqrt(β * I_SS)
def gmd(beta, Iss):
    return math.sqrt(beta * Iss)

# 6.18式: CMRRの計算
def cmrr(Adm, Acm):
    return Adm / Acm

# 6.19式: 飽和電圧 V_DSat の計算
def v_dsat(Vgs, Vt, beta, I):
    return Vgs - Vt

# 6.20式: 入力電圧範囲の計算
def permissible_input_voltage(Vdsat1, Vtn, Vdsat5, Vdd, Vdsat3, Vtp):
    return (Vdsat1 + Vtn + Vdsat5, Vdd - Vdsat3 - abs(Vtp) + Vtn)

# 6.13式: 差動モード利得 A_DM の計算
def differential_mode_gain(gmd, ro4, ro2, vin):
    return gmd * (ro4 * ro2) / (ro4 + ro2) * vin

# 6.17式: 出力電圧 v_out の計算
def output_voltage(Adm, vin, Acm, vcm):
    return Adm * vin + Acm * vcm

# 6.14式: 入力MOSFETの相互コンダクタンス G_m の計算
def mutual_conductance(gm, ro5):
    return gm / ro5

# 変数の設定(例)
beta = 1e-3  # トランスコンダクタンス係数
Iss = 1e-3   # バイアス電流
I1 = 1e-3    # 電流1
I2 = 0.9e-3  # 電流2
vin = 0.1    # 入力電圧
ro4 = 10e3   # M4の出力抵抗
ro2 = 10e3   # M2の出力抵抗
Adm = 200    # 差動モード利得
Acm = 1      # 同相モード利得
Vcm = 0.1    # 入力同相電圧
Vgs = 1.2    # ゲート-ソース間電圧
Vt = 0.6     # 閾値電圧
I = 0.5e-3   # ドレイン電流
Vdsat1 = 0.3  # M1の飽和電圧
Vtn = 0.7     # Nチャネルの閾値電圧
Vdsat5 = 0.2  # M5の飽和電圧
Vdd = 5.0     # 電源電圧
Vdsat3 = 0.3  # M3の飽和電圧
Vtp = -0.7    # Pチャネルの閾値電圧

# 式に基づく計算
gmd_value = gmd(beta, Iss)
cmrr_value = cmrr(Adm, Acm)
dsat_voltage = v_dsat(Vgs, Vt, beta, I)
permissible_input = permissible_input_voltage(Vdsat1, Vtn, Vdsat5, Vdd, Vdsat3, Vtp)
differential_gain = differential_mode_gain(gmd_value, ro4, ro2, vin)
output_voltage_value = output_voltage(Adm, vin, Acm, Vcm)

# 結果の表示
print(f"Transconductance g_md = {gmd_value} S")
print(f"CMRR = {cmrr_value}")
print(f"Saturation Voltage V_DSat = {dsat_voltage} V")
print(f"Permissible Input Voltage Range = {permissible_input} V")
print(f"Differential Mode Gain A_DM = {differential_gain} V")
print(f"Output Voltage v_out = {output_voltage_value} V")

p123

def calculate_v_be1(A, T, T_r, R2, C, V_BE1):
    """ Calculate the first term of V_BE1 """
    return V_BE1 * (1 - A * (T - T_r)) / (R2 * (1 + C * (T - T_r)))

def calculate_delta_v_be(B, T, T_r, R1, C, delta_V_BE):
    """ Calculate the second term of Delta V_BE """
    return delta_V_BE * (1 + B * (T - T_r)) / (R1 * (1 + C * (T - T_r)))

def approximate_v_be1(V_BE1, T, T_r, C):
    """ Approximation for V_BE1 """
    return V_BE1 * (1 - 4 * C * (T - T_r))

def approximate_delta_v_be(delta_V_BE, R1, B, C, T, T_r):
    """ Approximation for Delta V_BE """
    return delta_V_BE / R1 * (1 + (B - C) * (T - T_r))

# Example values (Replace these with actual values)
A = 0.01  # Coefficient A
B = 0.02  # Coefficient B
C = 0.005  # Coefficient C
T = 300  # Temperature (K)
T_r = 298  # Reference Temperature (K)
R1 = 10  # Resistance R1 (Ohms)
R2 = 15  # Resistance R2 (Ohms)
V_BE1 = 0.7  # V_BE1 (V)
delta_V_BE = 0.01  # Delta V_BE (V)

# Calculate each term
term1 = calculate_v_be1(A, T, T_r, R2, C, V_BE1)
term2 = calculate_delta_v_be(B, T, T_r, R1, C, delta_V_BE)
approx_term1 = approximate_v_be1(V_BE1, T, T_r, C)
approx_term2 = approximate_delta_v_be(delta_V_BE, R1, B, C, T, T_r)

# Display results
print("Term 1:", term1)
print("Term 2:", term2)
print("Approximation of Term 1:", approx_term1)
print("Approximation of Term 2:", approx_term2)


p154

import math

def current_error_ratio(delta_VT, VGS, VT, delta_beta, beta):
    """
    Calculate the current error ratio ΔI/I using the given formula.
    
    Parameters:
    delta_VT (float): Change in threshold voltage (ΔVT)
    VGS (float): Gate-source voltage (VGS)
    VT (float): Threshold voltage (VT)
    delta_beta (float): Change in beta (Δβ)
    beta (float): Beta value (β)
    
    Returns:
    float: Current error ratio ΔI/I
    """
    term1 = (delta_VT / (VGS - VT)) ** 2
    term2 = (delta_beta / beta) ** 2
    return 4 * math.sqrt(term1 + term2)

# Example values (Replace these with actual values)
delta_VT = 0.01  # Change in threshold voltage (ΔVT)
VGS = 5          # Gate-source voltage (VGS)
VT = 1           # Threshold voltage (VT)
delta_beta = 0.02  # Change in beta (Δβ)
beta = 1         # Beta value (β)

# Calculate current error ratio ΔI/I
current_error = current_error_ratio(delta_VT, VGS, VT, delta_beta, beta)

# Display result
print("Current Error Ratio (ΔI/I):", current_error)

p179


# Given constants from the image for the cascode circuit voltage gain formula
gm1_2 = 380 * 10**-6  # gm1,2 transconductance in S
gm4 = 4000 * 10**-6  # gm4 transconductance in S
gm6 = gm4  # Same transconductance for gm6 as gm4
ro2 = 10**4  # ro2 resistance in ohms
ro4 = ro2  # ro4 is the same as ro2
ro6 = ro2  # ro6 is also the same as ro2
ro8 = ro2  # ro8 is also the same as ro2

# Calculate the voltage gain A0 using the formula
A0 = (gm1_2 * gm4 * ro2 * ro4) / (gm6 * ro6 * ro8)

# Output the result for voltage gain
print("The voltage gain A0 is approximately:", A0)

p180

# 定数とパラメータの設定
V_T = 0.7  # 閾値電圧 V_T (例: 0.7V)
V_DSat2 = 0.2  # 飽和電圧 V_DSat2 (例: 0.2V)
V_DSat9 = 0.2  # 飽和電圧 V_DSat9 (例: 0.2V)
V_Bias1 = 2.0  # 基準バイアス電圧 V_Bias1 (例: 2.0V)
V_ov4 = 0.1  # オーバードライブ電圧 V_ov4 (例: 0.1V)

# 入力電圧 V_in,CM の下限を計算する関数
def calculate_input_voltage_min(V_T, V_DSat2, V_DSat9):
    return V_T + V_DSat2 + V_DSat9

# ソース電圧 V_B を計算する関数
def calculate_source_voltage(V_Bias1, V_T, V_ov4):
    return V_Bias1 - V_T - V_ov4

# 計算結果の表示
input_voltage_min = calculate_input_voltage_min(V_T, V_DSat2, V_DSat9)
source_voltage = calculate_source_voltage(V_Bias1, V_T, V_ov4)

print(f"最低入力電圧 V_in,CM = {input_voltage_min} V")
print(f"ソース電圧 V_B = {source_voltage} V")


p182

# Given constants from the image for the effective output resistance and voltage gain
gm2 = 380 * 10**-6  # gm2 transconductance in S
gm4 = 4000 * 10**-6  # gm4 transconductance in S
gm6 = gm4  # gm6 is the same as gm4
ro2 = 10**4  # ro2 resistance in ohms
ro4 = ro2  # ro4 is the same as ro2
ro6 = ro2  # ro6 is also the same as ro2
ro8 = ro2  # ro8 is also the same as ro2
ro10 = ro2  # ro10 is also the same as ro2

# Calculate the effective output resistance Rout_eff
Rout_eff = (gm4 * ro4 * (ro2 // ro10)) / (gm6 * ro6 * ro8)
print("The effective output resistance Rout_eff is approximately:", Rout_eff, "ohms")

# Calculate the voltage gain A0 using the formula
A0 = gm2 * Rout_eff
print("The voltage gain A0 is approximately:", A0)

p185

# MOSFETのパラメータ(任意の値を設定してください)
gm1 = 1e-3  # トランスコンダクタンス(S)
ro1 = 10e3  # 出力抵抗(Ω)
gm6 = 2e-3  # 2段目のトランスコンダクタンス(S)
ro6 = 15e3  # 2段目の出力抵抗(Ω)
ro7 = 20e3  # 負荷抵抗(Ω)

# 初段の電圧増幅度
Av1 = gm1 * (ro1 / (ro1 + ro7))

# 2段目の電圧増幅度
Av2 = gm6 * (ro6 / (ro6 + ro7))

# 全体の電圧増幅度
Av_total = Av1 * Av2

# dB表記に変換
Av_total_dB = 20 * np.log10(Av_total)

print(f"初段の電圧増幅度: {Av1:.2f}")
print(f"2段目の電圧増幅度: {Av2:.2f}")
print(f"全体の電圧増幅度: {Av_total:.2f}")
print(f"全体の電圧増幅度 (dB): {Av_total_dB:.2f} dB")


p187



# 各パラメータの初期値を設定
V_DD = 3  # 電源電圧 [V]
Cout = 10e-12  # 出力容量 [F]
Cc = 0.2 * Cout  # 補償容量 (Coutの20%)

# トランスコンダクタンスの関係
gm1 = 1e-3  # 入力段トランスコンダクタンス [S]
gm6 = 10 * gm1  # 出力段トランスコンダクタンス [S]

# スルーレート (立ち上がり速度) の設定
SR = 1e6  # 立ち上がり速度 [V/s]

# バイアス電流 I5 の計算 (I5 = SR * Cc)
I5 = SR * Cc

# ωu (ゲイン帯域幅積) の計算 (ωu = gm1 / Cc)
omega_u = gm1 / Cc

# 結果を表示
print(f"電源電圧: {V_DD} V")
print(f"出力容量 C_out: {Cout:.2e} F")
print(f"補償容量 C_c: {Cc:.2e} F")
print(f"入力段のトランスコンダクタンス g_m1: {gm1:.2e} S")
print(f"出力段のトランスコンダクタンス g_m6: {gm6:.2e} S")
print(f"バイアス電流 I5: {I5:.2e} A")
print(f"ゲイン帯域幅積 ωu: {omega_u:.2e} rad/s")

P188

gm12×R1×ROUT×(gm6-sCc)/(1+As+Bs^2)のボード線図
A=R1×ROUT×gm6×Cc
B=C1×COUT+(C1+COUT)×Cc
時定数1=R1×gm6×ROUT×Cc
時定数2=COUT/(gm6)
I5=スルーレート×Cc
gm1=Cc×利得幅域幅

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

# Given parameters (assuming realistic LSI MOSFET values)
R1 = 1e3          # Ohms
ROUT = 1e3        # Ohms
gm6 = 1e-3        # Siemens
Cc = 1e-12        # Farads
C1 = 1e-12        # Farads
COUT = 1e-12      # Farads
gm12 = 1e-3       # Siemens

# Additional parameters
slew_rate = 1e6   # V/s (example value)
gain_bandwidth_product = 1e6  # Hz (example value)

# Calculate constants A and B
A = R1 * ROUT * gm6 * Cc
B = C1 * COUT + (C1 + COUT) * Cc

# Calculate time constants
tau_1 = R1 * gm6 * ROUT * Cc
tau_2 = COUT / gm6

# Calculate slew rate current
I5 = slew_rate * Cc

# Calculate transconductance gm1
gm1 = Cc * gain_bandwidth_product

# Print calculated values
print(f"A = {A:.3e}")
print(f"B = {B:.3e}")
print(f"Time constant 1 (tau_1) = {tau_1:.3e} s")
print(f"Time constant 2 (tau_2) = {tau_2:.3e} s")
print(f"Slew rate current (I5) = {I5:.3e} A")
print(f"Transconductance (gm1) = {gm1:.3e} S")

# Define the numerator and denominator of the transfer function
num = [gm12 * R1 * ROUT, -gm12 * R1 * ROUT * Cc]
den = [1, A, B]

# Create the transfer function
H = signal.TransferFunction(num, den)

# Generate Bode plot
w, mag, phase = signal.bode(H)

# Plot the Bode magnitude plot
plt.figure()
plt.semilogx(w, mag)
plt.title('Bode Magnitude Plot')
plt.xlabel('Frequency [rad/s]')
plt.ylabel('Magnitude [dB]')
plt.grid(which='both', axis='both')

# Plot the Bode phase plot
plt.figure()
plt.semilogx(w, phase)
plt.title('Bode Phase Plot')
plt.xlabel('Frequency [rad/s]')
plt.ylabel('Phase [degrees]')
plt.grid(which='both', axis='both')

# Show plots
plt.show()



image.png

import numpy as np
import matplotlib.pyplot as plt

# Parameters
Fs = 10000  # Sampling frequency (Hz)
T = 1       # Duration of the signal (seconds)
t = np.linspace(0, T, int(Fs * T), endpoint=False)  # Time axis

# Carrier signal parameters
f_c = 1000   # Carrier frequency (Hz)
A_c = 1      # Carrier amplitude

# Modulating signal parameters
f_m = 50     # Modulating signal frequency (Hz)
A_m = 0.5    # Modulating signal amplitude
modulating_signal = A_m * np.sin(2 * np.pi * f_m * t)

# Amplitude Modulation (AM)
am_signal = (A_c + modulating_signal) * np.cos(2 * np.pi * f_c * t)

# Frequency Modulation (FM)
k_f = 2 * np.pi * 500  # Frequency modulation sensitivity
fm_signal = A_c * np.cos(2 * np.pi * f_c * t + k_f * np.cumsum(modulating_signal) / Fs)

# Phase Modulation (PM)
k_p = np.pi / 2  # Phase modulation sensitivity
pm_signal = A_c * np.cos(2 * np.pi * f_c * t + k_p * modulating_signal)

# Plotting
plt.figure(figsize=(12, 8))

# Amplitude Modulation
plt.subplot(3, 1, 1)
plt.plot(t, am_signal)
plt.title('Amplitude Modulation (AM)')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')

# Frequency Modulation
plt.subplot(3, 1, 2)
plt.plot(t, fm_signal)
plt.title('Frequency Modulation (FM)')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')

# Phase Modulation
plt.subplot(3, 1, 3)
plt.plot(t, pm_signal)
plt.title('Phase Modulation (PM)')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')

plt.tight_layout()
plt.show()


p188

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

# Define the parameters
gm_12 = 1e-3  # Transconductance of the first stage (S)
gm_6 = 1e-3   # Transconductance of the second stage (S)
R1 = 1e4      # Resistance R1 (ohms)
Rout = 1e4    # Output Resistance Rout (ohms)
Cc = 1e-12    # Compensation Capacitance (Farads)
Cout = 1e-12  # Output Capacitance (Farads)
Ci = 1e-12    # Input Capacitance (Farads)

# Calculate poles
p1 = gm_6 * R1 * Rout * Cc
p2 = gm_6 * Cc / Cout

# Transfer function constants
K = gm_12 * R1 * Rout

# Transfer function (numerator and denominator)
numerator = [K]
denominator = [1, p1, p2]

# Create the transfer function
system = signal.TransferFunction(numerator, denominator)

# Generate Bode plot
frequencies = np.logspace(1, 8, 500)  # Frequency range
w, mag, phase = signal.bode(system, frequencies)

# Plot magnitude
plt.figure()
plt.semilogx(w, mag)  # Bode magnitude plot
plt.title('Bode Plot - Magnitude')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Magnitude [dB]')
plt.grid(True, which="both", ls="--")

# Plot phase
plt.figure()
plt.semilogx(w, phase)  # Bode phase plot
plt.title('Bode Plot - Phase')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Phase [degrees]')
plt.grid(True, which="both", ls="--")

plt.show()


p188

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

# パラメータの設定(任意の値を調整してください)
R1 = 10e3     # 抵抗 (Ω)
Rout = 20e3   # 出力抵抗 (Ω)
Cc = 2e-12    # 位相補償用キャパシタ (F)
C1 = 1e-12    # キャパシタ (F)
Cout = 5e-12  # 負荷容量 (F)
gm6 = 2e-3    # トランスコンダクタンス (S)

# 伝達関数 H(s) の分子と分母を定義
# 分子: gm6 - sCc
num = [gm6, -Cc]

# 分母の各項を計算
den = [
    1,
    (R1 * gm6 * Rout * Cc) + (C1 + Cout + (C1 + Cout) * Cc),
    gm6 * Cc * (R1 + Rout) * (C1 + Cout + (C1 + Cout) * Cc),
    gm6 * (C1 * Cout + (C1 + Cout) * Cc)
]

# 伝達関数を作成
system = signal.TransferFunction(num, den)

# 周波数範囲を指定してボード線図を描画
w, mag, phase = signal.bode(system)

# ボード線図をプロット
plt.figure(figsize=(10, 8))

# 振幅特性(ゲイン)
plt.subplot(2, 1, 1)
plt.semilogx(w, mag)  # 周波数軸を対数スケールに設定
plt.title('Bode Plot of Transfer Function')
plt.xlabel('Frequency [rad/s]')
plt.ylabel('Magnitude [dB]')
plt.grid(which='both', linestyle='--')

# 位相特性
plt.subplot(2, 1, 2)
plt.semilogx(w, phase)  # 周波数軸を対数スケールに設定
plt.xlabel('Frequency [rad/s]')
plt.ylabel('Phase [degrees]')
plt.grid(which='both', linestyle='--')

# グラフを表示
plt.tight_layout()
plt.show()


p189

import numpy as np

# パラメータの設定
gm1 = 1e-3  # トランスコンダクタンス (S)
R1 = 10e3   # 抵抗値 (Ω)
Rout = 20e3 # 出力抵抗 (Ω)
Cc = 2e-12  # 位相補償用キャパシタ (F)
gm6 = 2e-3  # 2段目のトランスコンダクタンス (S)

# 式 (P1): 差動入力段の出力端子の時定数
tau = R1 * gm6 * Rout * Cc
print(f"差動入力段の出力端子の時定数: {tau:.2e} 秒")

# 式 (P2): 負荷容量 C_out
C_out = 10e-12  # 負荷容量 (F)
t_out = C_out / gm6
print(f"負荷容量による時定数: {t_out:.2e} 秒")

# 式 (P3): ゲート-ドレイン間の電流 i_g
v1 = 0.1  # 入力電圧 (V)
ig = gm6 * v1 * Cc
print(f"ゲート-ドレイン間の電流 i_g: {ig:.2e} A")

# 式 (P4): 零点 z
z = -gm6 / Cc
print(f"零点 z の値: {z:.2e} Hz")

p191

# Define the given values based on the image
beta_p = 22.5 * 10**-6  # Parameter in A/V^2
V_DD = 3  # Supply voltage in volts
V_in_max = 2.5  # Maximum input voltage in volts
V_Tn = 0.7  # Threshold voltage for n-type in volts
V_TPI = 0.7  # Absolute value of the threshold voltage for PI in volts
W_by_L = 2  # (W/L)_3 ratio based on the approximation

# Calculate the current I3 using the formula
I3 = (beta_p / 2) * W_by_L * (V_DD - V_in_max + V_Tn - abs(V_TPI))**2

# Output the result
print("The current I3 is:", I3, "A")

p192

import math

# Constants based on the image
beta_n = 45 * 10**-6  # Parameter in A/V^2 for n-type
beta_p = 22.5 * 10**-6  # Parameter in A/V^2 for p-type
I1 = 380 * 10**-6  # Current in A
I4 = 2 * 10**-4  # Another current in A
I5 = 22.5 * 10**-6  # Another current in A

# Calculate g_m1 based on the given formula
gm1 = math.sqrt(2 * beta_n * (I1))  # g_m1 formula
print("g_m1:", gm1, "S")

# Calculate W/L ratio for M1 based on given formula
W_by_L_1 = gm1**2 / (2 * beta_n * I1)
print("(W/L)_1:", W_by_L_1)

# Calculate W/L ratio for M6
gm6 = 10 * gm1  # Given
gm4 = 4000 * 10**-6  # From the image
W_by_L_6 = gm6 / gm4  # W/L ratio for M6
print("(W/L)_6:", W_by_L_6)

# Calculate gm4 and I4
gm4 = math.sqrt(2 * beta_p * (I4))
print("g_m4:", gm4, "S")

# Calculate the next W/L ratio for M4 using I4
W_by_L_4 = gm4**2 / (2 * beta_p * I4)
print("(W/L)_4:", W_by_L_4)


p193


import math

# Given values from the image
I7 = 900 * 10**-6  # Current I7 in amperes (900 µA)
beta_n = 2 * 10**-4  # Parameter in A/V^2
W_by_L_7 = 40  # (W/L)_7 ratio
V_DT_sat = 0.47  # Saturation voltage in volts

# Calculate minimum output voltage using the formula
V_out_min = math.sqrt((2 * I7) / (beta_n * W_by_L_7))
print("The minimum output voltage V_out_min is:", V_out_min, "V")

# Confirm the final result based on the provided equation in the image
final_V_out_min = math.sqrt((2 * 900 * 10**-6) / (2 * 10**-4 * 40))
print("Final V_out_min based on equation is:", final_V_out_min, "V")

p194


import math

# Given values from the image
V_DD = 3.0  # Supply voltage in volts
I6 = 900 * 10**-6  # Current I6 in amperes (900 µA)
beta_p = 10**-4  # Parameter in A/V^2 for p-type
W_by_L_6 = 80  # (W/L)_6 ratio

# Calculate the maximum output voltage Vout_max using the formula
V_out_max = V_DD - math.sqrt((2 * I6) / (beta_p * W_by_L_6))
print("The maximum output voltage Vout_max is:", V_out_max, "V")

# Voltage gain calculation variables
gm1 = 380 * 10**-6  # Transconductance in S
gm6 = 4000 * 10**-6  # Transconductance for gm6 in S
I5 = I6 / 2  # Current I5 is half of I6
I7 = I6  # Given that I7 = I6
lambda_n = 0.1  # Channel length modulation for n-type
lambda_p = 0.1  # Channel length modulation for p-type

# Calculate the voltage gain A0 using the formula
A0 = (gm1 / (I5 * (lambda_n + lambda_p))) * (gm6 / (I7 * (lambda_n + lambda_p)))
print("The voltage gain A0 is approximately:", A0)

p198


# MOSFETのパラメータ設定
VDD = 5.0          # 電源電圧 (V)
VTp = 0.7          # P型MOSFETのしきい値電圧 (V)
VTn = 0.8          # N型MOSFETのしきい値電圧 (V)
delta_Vov1 = 0.2   # 過剰電圧 (V)
delta_Vov3 = 0.1   # 過剰電圧3 (V)

# 許容電圧範囲の計算
V_max = VDD - VTp + delta_Vov3  # 入力許容範囲の上限
V_min = VTn + delta_Vov1        # 入力許容範囲の下限

# 許容電圧範囲を表示
print(f"入力許容範囲の上限: {V_max:.2f} V")
print(f"入力許容範囲の下限: {V_min:.2f} V")

p281


import numpy as np
import matplotlib.pyplot as plt

# サンプリング周波数とシミュレーションの設定
fs = 1000  # サンプリング周波数 (Hz)
f_in = 10  # 入力信号の周波数 (Hz)
T = 1.0    # シミュレーション時間 (秒)
N = int(fs * T)  # サンプル数

# 時間軸の作成
t = np.linspace(0, T, N, endpoint=False)

# 入力信号(サイン波)の生成
v_in = np.sin(2 * np.pi * f_in * t)

# 量子化ノイズ N(z) の生成
# ノイズは小さなランダムな値を使用
quantization_noise = np.random.normal(0, 0.1, N)

# 出力信号の生成 (画像の式16.3に基づく)
# Vout(z) = z^(-1) * Vin(z) + (1 - z^(-1)) * N(z)
v_out = np.zeros(N)
for i in range(1, N):
    v_out[i] = v_in[i-1] + (1 - 1/fs) * quantization_noise[i-1]

# FFT解析の実行
f = np.fft.fftfreq(N, 1/fs)  # 周波数軸の生成
V_in_fft = np.abs(np.fft.fft(v_in))  # 入力信号のFFT
V_out_fft = np.abs(np.fft.fft(v_out))  # 出力信号のFFT
quant_noise_fft = np.abs(np.fft.fft(quantization_noise))  # 量子化ノイズのFFT

# 結果のプロット
plt.figure(figsize=(12, 8))

# 入力信号のFFT
plt.subplot(3, 1, 1)
plt.plot(f[:N//2], V_in_fft[:N//2])
plt.title('FFT of Input Signal (Vin)')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Magnitude')
plt.grid()

# 量子化ノイズのFFT
plt.subplot(3, 1, 2)
plt.plot(f[:N//2], quant_noise_fft[:N//2])
plt.title('FFT of Quantization Noise (N)')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Magnitude')
plt.grid()

# 出力信号のFFT
plt.subplot(3, 1, 3)
plt.plot(f[:N//2], V_out_fft[:N//2])
plt.title('FFT of Output Signal (Vout)')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Magnitude')
plt.grid()

# グラフを表示
plt.tight_layout()
plt.show()

p188


import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

# 定数の設定
gm1 = 1e-3            # トランスコンダクタンス g_m1 (1 mS)
gm6 = 5e-3            # トランスコンダクタンス g_m6 (5 mS)
Cc = 1e-12            # キャパシタンス C_C (1 pF)
C2 = 2e-12            # キャパシタンス C_2 (2 pF)
R1 = 10e3             # 抵抗 R_1 (10 kΩ)
R2 = 10e3             # 抵抗 R_2 (10 kΩ)

# 各周波数の計算
omega_z = gm6 / Cc                      # ゼロの周波数
omega_p1 = 1 / (gm6 * Cc * R1 * R2)     # 第一ポールの周波数
omega_p2 = gm6 / C2                     # 第二ポールの周波数

# 伝達関数の係数設定
numerator = [gm1 * gm6 * R1 * R2, -gm1 * gm6 * R1 * R2 / omega_z]  # 分子の係数 (ゼロの項を含む)
denominator = [1, (omega_p1 + omega_p2), omega_p1 * omega_p2]      # 分母の係数 (ポールの項を含む)

# 伝達関数の定義
system = signal.TransferFunction(numerator, denominator)

# ボード線図の周波数範囲を設定して計算
w, mag, phase = signal.bode(system)

# ボード線図を描画
plt.figure(figsize=(12, 8))

# ゲインプロット
plt.subplot(2, 1, 1)
plt.semilogx(w, mag, 'b')
plt.title('Bode Plot - Gain and Phase')
plt.ylabel('Magnitude (dB)')
plt.grid(True, which='both', linestyle='--', linewidth=0.5)

# 位相プロット
plt.subplot(2, 1, 2)
plt.semilogx(w, phase, 'r')
plt.xlabel('Frequency (rad/s)')
plt.ylabel('Phase (degrees)')
plt.grid(True, which='both', linestyle='--', linewidth=0.5)

# グラフを表示
plt.tight_layout()
plt.show()

p198


# パラメータ設定
V_DD = 3.0                 # 電源電圧 (V)
V_T0 = 1.0                 # MOSFETの閾値電圧V_T0 (V)
V_TN = 1.0                 # MOSFETの閾値電圧V_TN (V)
delta_v_ov3 = 0.1          # オーバードライブ電圧 Δv_ov3 (V)
delta_v_ov1 = 0.2          # オーバードライブ電圧 Δv_ov1 (V)
delta_v_ov5 = 0.1          # オーバードライブ電圧 Δv_ov5 (V)

# 入力共通モード電圧範囲の計算
V_cm_max = V_DD - abs(V_T0 - V_TN + delta_v_ov3)
V_cm_min = V_T0 + delta_v_ov1

# 結果の表示
results_cm = {
    "Input Common Mode Voltage Range - Max (V_cm_max)": f"{V_cm_max:.4f} V",
    "Input Common Mode Voltage Range - Min (V_cm_min)": f"{V_cm_min:.4f} V",
    "Overdrive Voltage Δv_ov5": f"{delta_v_ov5:.4f} V"
}

# 結果を表示
import pandas as pd
df_cm = pd.DataFrame(results_cm.items(), columns=["Parameter", "Value"])
import ace_tools as tools; tools.display_dataframe_to_user("Input Common Mode Voltage Calculation Results", df_cm)

p278

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import lfilter, butter

# Sampling frequency
fs = 1000  # Hz
T = 1.0  # Signal duration (seconds)
t = np.linspace(0, T, int(fs * T), endpoint=False)

# Input analog signal (e.g., sine wave)
f_input = 5  # Input signal frequency (Hz)
analog_signal = 0.5 * np.sin(2 * np.pi * f_input * t)

# Design of low-pass filter
nyq = 0.5 * fs
cutoff = 50  # Cutoff frequency (Hz)
order = 5
b, a = butter(order, cutoff / nyq, btype='low', analog=False)
filtered_signal = lfilter(b, a, analog_signal)

# Delta-Sigma modulator simulation
quantized_signal = np.zeros_like(filtered_signal)
integrator = 0.0
for i in range(len(filtered_signal)):
    integrator += filtered_signal[i]
    if integrator > 0:
        quantized_signal[i] = 1
        integrator -= 1
    else:
        quantized_signal[i] = -1
        integrator += 1

# After oversampling, downsampling (reduce by 1/N)
N = 16  # Downsampling ratio
downsampled_signal = quantized_signal[::N]

# Plot
plt.figure(figsize=(12, 8))

plt.subplot(3, 1, 1)
plt.plot(t, analog_signal, label='Input Analog Signal')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.title('Input Analog Signal')
plt.grid()

plt.subplot(3, 1, 2)
plt.plot(t, quantized_signal, label='After Delta-Sigma Modulation')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.title('After Delta-Sigma Modulation')
plt.grid()

downsampled_t = t[::N]  # Time after downsampling
plt.subplot(3, 1, 3)
plt.step(downsampled_t, downsampled_signal, label='After Downsampling')
plt.xlabel('Time (s)')
plt.ylabel('Output Code')
plt.title('Output Code After Downsampling')
plt.grid()

plt.tight_layout()
plt.show()



import numpy as np
import matplotlib.pyplot as plt

# Sampling frequency and time axis setup
fs = 1000  # Sampling frequency (Hz)
T = 1.0  # Signal duration (seconds)
t = np.linspace(0, T, int(fs * T), endpoint=False)

# Input analog signal (sine wave signal)
fin = 5  # Input signal frequency (Hz)
analog_signal = 0.5 * np.sin(2 * np.pi * fin * t)

# Reference voltage setup
V_ref = 0.3  # Reference voltage

# Accumulator (Integrator)
integrator = 0.0
output_signal = np.zeros_like(analog_signal)

# Signal processing using a difference operator (Δ)
for i in range(len(analog_signal)):
    integrator += analog_signal[i]
    if integrator > V_ref:
        output_signal[i] = 1
        integrator -= V_ref  # Feedback with the difference from the reference voltage
    elif integrator < -V_ref:
        output_signal[i] = -1
        integrator += V_ref
    else:
        output_signal[i] = 0

# Plotting
plt.figure(figsize=(10, 8))

# Input analog signal
plt.subplot(3, 1, 1)
plt.plot(t, analog_signal, label='Input Analog Signal')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.title('Input Analog Signal')
plt.grid(True)

# Output of the accumulator
plt.subplot(3, 1, 2)
plt.plot(t, np.cumsum(analog_signal), label='Output of Accumulator')
plt.xlabel('Time (s)')
plt.ylabel('Cumulative Value')
plt.title('Output of Accumulator')
plt.grid(True)

# Final output signal using the difference operator
plt.subplot(3, 1, 3)
plt.step(t, output_signal, label='Final Output Signal using Difference Operator')
plt.xlabel('Time (s)')
plt.ylabel('Output Code')
plt.title('Final Output Signal (Pulse Density)')
plt.grid(True)

plt.tight_layout()
plt.show()





import numpy as np
import matplotlib.pyplot as plt

# Define parameters
fs = 2000  # Sampling frequency (Hz)
fin = 50   # Input signal frequency (Hz)
N = 4      # Number of stages (related to oversampling ratio)
BW = fin * 2  # Bandwidth (approximately twice the input signal frequency)
V_ref = 1.0  # Reference voltage

# Time vector
t = np.arange(0, 1, 1/fs)

# Generate input analog signal (sinusoidal)
analog_signal = 0.5 * np.sin(2 * np.pi * fin * t)

# Sampling the input signal
sampled_signal = analog_signal

# Initialize arrays
cumulative_sum = np.zeros_like(sampled_signal)
delta_signal = np.zeros_like(sampled_signal)
output_signal = np.zeros_like(sampled_signal)

# Perform the processing
for i in range(1, len(sampled_signal)):
    # Cumulative sum (integrator)
    cumulative_sum[i] = cumulative_sum[i-1] + sampled_signal[i]
    
    # Compute the difference between cumulative sum and reference voltage
    delta_signal[i] = cumulative_sum[i] - V_ref
    
    # Feedback: if delta is greater than zero, subtract the reference voltage
    if delta_signal[i] > 0:
        output_signal[i] = 1
        cumulative_sum[i] -= V_ref  # Feedback to the cumulative sum
    else:
        output_signal[i] = 0

# Plot the results
plt.figure()
plt.subplot(3, 1, 1)
plt.plot(t, analog_signal, label='Analog Signal')
plt.title('Analog Input Signal')
plt.grid(True)

plt.subplot(3, 1, 2)
plt.plot(t, delta_signal, label='Delta Signal', color='r')
plt.title('Delta Signal (Cumulative Sum - V_ref)')
plt.grid(True)

plt.subplot(3, 1, 3)
plt.plot(t, output_signal, label='Output Signal', color='g')
plt.title('Output Signal (Pulse Density)')
plt.grid(True)

plt.tight_layout()
plt.show()







import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fsolve

# トランジスタの特性
def transistor_characteristics(L, W, Vth, Vgs, Id):
    """
    トランジスタの特性を計算する関数
    """
    gm = (2 * Id) / (Vgs - Vth)  # 相互コンダクタンス
    rds = 1 / ((Id / Vgs) * (W / L))  # 出力抵抗
    gm_rds = gm * rds  # Intrinsic gain
    return gm, rds, gm_rds

# 初期パラメータ
L1 = 0.28e-6  # m
L2 = 0.56e-6  # m
W_L = 10
Vgs1 = 0.8
Vgs2 = 0.9
Vth_nMOS = 0.63
Vth_pMOS = 0.72

# nMOSとpMOSの特性計算
Id_nMOS = 35e-6
Id_pMOS = 3.3e-6

gm_nMOS, rds_nMOS, gm_rds_nMOS = transistor_characteristics(L1, W_L, Vth_nMOS, Vgs1, Id_nMOS)
gm_pMOS, rds_pMOS, gm_rds_pMOS = transistor_characteristics(L1, W_L, Vth_pMOS, Vgs1, Id_pMOS)

# サイズ変更後の特性計算
W_L_new = 100
gm_nMOS_new, rds_nMOS_new, gm_rds_nMOS_new = transistor_characteristics(L2, W_L_new / 10, Vth_nMOS, Vgs2, Id_nMOS)
gm_pMOS_new, rds_pMOS_new, gm_rds_pMOS_new = transistor_characteristics(L2, W_L_new, Vth_pMOS, Vgs2, Id_pMOS)

# 結果の表示
print("nMOS (L=0.28μm):")
print(f"  gm = {gm_nMOS:.2e} S")
print(f"  rds = {rds_nMOS:.2e} Ω")
print(f"  gm * rds = {gm_rds_nMOS:.2e}")
print("pMOS (L=0.28μm):")
print(f"  gm = {gm_pMOS:.2e} S")
print(f"  rds = {rds_pMOS:.2e} Ω")
print(f"  gm * rds = {gm_rds_pMOS:.2e}")

print("\n変更後のnMOS (L=0.56μm):")
print(f"  gm = {gm_nMOS_new:.2e} S")
print(f"  rds = {rds_nMOS_new:.2e} Ω")
print(f"  gm * rds = {gm_rds_nMOS_new:.2e}")
print("変更後のpMOS (L=0.56μm):")
print(f"  gm = {gm_pMOS_new:.2e} S")
print(f"  rds = {rds_pMOS_new:.2e} Ω")
print(f"  gm * rds = {gm_rds_pMOS_new:.2e}")

# プロット
fig, ax = plt.subplots(2, 1, figsize=(10, 10))

# gm/Id のプロット
Vgs = np.linspace(0.5, 1.0, 100)
gm_over_Id_nMOS = (2 * Id_nMOS) / (Vgs - Vth_nMOS)
gm_over_Id_pMOS = (2 * Id_pMOS) / (Vgs - Vth_pMOS)

ax[0].plot(Vgs, gm_over_Id_nMOS, label='nMOS', color='blue')
ax[0].plot(Vgs, gm_over_Id_pMOS, label='pMOS', color='red')
ax[0].set_xlabel('Vgs (V)')
ax[0].set_ylabel('gm / Id (S/A)')
ax[0].legend()
ax[0].set_title('gm / Id vs. Vgs')

# gm * rds のプロット
rds_nMOS = 1 / ((Id_nMOS / Vgs) * (W_L / L1))
rds_pMOS = 1 / ((Id_pMOS / Vgs) * (W_L / L1))

gm_rds_nMOS = gm_nMOS * rds_nMOS
gm_rds_pMOS = gm_pMOS * rds_pMOS

ax[1].plot(Vgs, gm_rds_nMOS, label='nMOS', color='blue')
ax[1].plot(Vgs, gm_rds_pMOS, label='pMOS', color='red')
ax[1].set_xlabel('Vgs (V)')
ax[1].set_ylabel('gm * rds (S Ω)')
ax[1].legend()
ax[1].set_title('gm * rds vs. Vgs')

plt.tight_layout()
plt.show()

http://imasaracmosanalog.blog111.fc2.com/?cat=52&page=0
P103


import numpy as np

# Constants (adjust as per your circuit setup)
V_DD = 0.2  # Supply voltage in volts
V_fixed = 0.9  # Fixed voltage in volts
beta = 1.0  # Transconductance parameter, adjust as needed
I_SS = 1e-3  # Tail current (in amps), adjust as needed

# Input voltage (difference between two gate voltages)
V_in = 0.1  # Example input voltage difference in volts, adjust as needed

# Calculate the drain currents for M1 and M2 using the equation
I1 = (I_SS / 2) + (beta * V_in / (2 * I_SS)) * V_in
I2 = (I_SS / 2) - (beta * V_in / (2 * I_SS)) * V_in

# Calculate the transconductance g_m
g_m = np.sqrt(beta * I_SS / 2)

# Print the results
print(f"Drain current I1: {I1} A")
print(f"Drain current I2: {I2} A")
print(f"Transconductance g_m: {g_m} S")

# Additional calculations can be added based on your specific requirements.
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?