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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/8588d3a4-98c9-2ed2-750b-aca465f85e42.png)

https://kakitamablog.com/2stage-opamp-stable-condition/
```
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)")
```
https://aicdesign.org/2016-short-course-notes-2/


http://cmoshanahana.web.fc2.com/lsi_opamp_opamp2.html


https://www.ieee-jp.org/section/kansai/chapter/sscs/20051212/seminer-taniguchi.pdf

https://kobaweb.ei.st.gunma-u.ac.jp/lecture/tanimoto-OTA-111013final.pdf


https://www.ssc.pe.titech.ac.jp/private/publications/2007/Matsuzawa_Presentation/VDEC_200701.pdf

https://kobaweb.ei.st.gunma-u.ac.jp/lecture/motozawa-sensei_20220704_r1.pdf

https://www.google.com/search?sca_esv=23f4d2fe96db8c88&sxsrf=ADLYWIK64eRwOqFj87XPpQy3jH1AwPZD7Q:1720007467844&q=cmos%E3%82%A2%E3%83%8A%E3%83%AD%E3%82%B0%E5%9B%9E%E8%B7%AF%E5%85%A5%E9%96%80&source=lnms&fbs=AEQNm0BqbPbAzSj6PhNr7nv9Ltx-oFh8tVsgXi1MyFbswNtTUOS5b68chsyOj2QEdx4EPnOXQZXFtg8iq2YMejzbnly9hN5gD6PBSrPsSnqNqMrzQCXwRbP6fJq5WK0IeJJ6NX5ZnoTf9aHGYNpN2Q1Is-WD_Bjd8VVVJGmeyPwHWEseC_DibGUrzZ7YE8eM5gDddKdBT6Ft3amPiQVOF61P0TsguBw5A-VsaWZBcN8wzTdmFA5faCo&sa=X&ved=2ahUKEwiC4IaR54qHAxUxlK8BHdtXCM0Q0pQJegQIExAB&biw=1920&bih=911&dpr=1

https://mosfet.chips.jp/cmos/index.html

https://openit.kek.jp/training/2020/daq/text/transistor-fusayasu.pdf


https://kobaweb.ei.st.gunma-u.ac.jp/lecture/2015-06-18mos-fet-matsuda.pdf

https://kobaweb.ei.st.gunma-u.ac.jp/lecture/AnalogHPrev.pdf

https://ocw.nagoya-u.jp/files/123/r_note05.pdf

https://kakitamablog.com/gijutsusho-shohyo-cmos-analog-circuit-intro/

https://upa-engineering.hatenablog.com/entry/2019/06/17/102934

http://designcircuit.blog.fc2.com/?pc

https://kobaweb.ei.st.gunma-u.ac.jp/news/pdf/2020/20201211_analog_koba.pdf

https://repository.kulib.kyoto-u.ac.jp/dspace/bitstream/2433/59292/1/D_Okada_Kenichi.pdf

https://kobaweb.ei.st.gunma-u.ac.jp/news/pdf/2015/150310FLCkuwasawa.pdf

http://designcircuit.blog.fc2.com/blog-entry-6.html

https://aicdesign.org/




```
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
ソース接地増幅

```py
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/9d27a70f-e1c0-0ee1-3325-870beb6939e1.png)

ｐ５０からｐ５４

小信号等価回路
出力並列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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/a231abdf-6ef3-3db0-9cc6-0acf21bc5f22.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/6cce977e-6fb2-ba4b-7c7a-49b4f863c6c5.png)

P55


https://www.google.com/search?q=%E3%82%AB%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E5%9B%9E%E8%B7%AF&oq=%E3%81%8B%E3%81%99%E3%81%93%E3%83%BC%E3%81%A9&gs_lcrp=EgZjaHJvbWUqCQgDEAAYBBiABDIGCAAQRRg5MgkIARAAGAQYgAQyCQgCEAAYBBiABDIJCAMQABgEGIAEMgkIBBAAGAQYgAQyCQgFEAAYBBiABDIJCAYQABgEGIAEMgkIBxAAGAQYgAQyCQgIEAAYBBiABDIJCAkQABgEGIAE0gEINTg0NWowajeoAgiwAgE&sourceid=chrome&ie=UTF-8



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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/1d20cfe2-fa52-d859-e309-2b6710f2c071.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/58f41baa-c29c-0387-a19f-730a5709b46a.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/363b2cc3-22b8-fada-26af-6c6a34305b7f.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/16e9331d-2e28-310c-e7bd-e9330a652b77.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)
```

p２７８



```
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()







```





http://www.venus.dti.ne.jp/~s-takei/circuit/left3.html


https://note.com/akira_tsuchiya/n/n710ed2d0e428


```
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.
```