アナログCMOS集積回路の設計基礎編

https://sites.google.com/site/allen2011cmos/hand_calc

p17
```
import numpy as np

# Constants (you can adjust these values based on the specific MOSFET)
q = 1.6e-19         # Elementary charge (C)
epsilon_si = 11.7    # Relative permittivity of silicon
epsilon_0 = 8.854e-12  # Vacuum permittivity (F/m)
k = 1.38e-23        # Boltzmann constant (J/K)
T = 300             # Temperature in Kelvin (K)
ni = 1.5e10         # Intrinsic carrier concentration (cm^-3)
Nsub = 1e17         # Substrate doping concentration (cm^-3)
C_ox = 9.6e-9       # Oxide capacitance per unit area (F/μm²)
Phi_MS = 0.5        # Metal-semiconductor work function difference (V)

# Derived parameters
Phi_F = (k * T / q) * np.log(Nsub / ni)  # Fermi potential (V)
Q_dep = np.sqrt(2 * epsilon_si * epsilon_0 * q * Nsub * 2 * Phi_F)  # Depletion charge (C/cm^2)

# Threshold voltage calculation
V_TH = Phi_MS + 2 * Phi_F + Q_dep / C_ox

# Output the threshold voltage
print(f"Threshold voltage V_TH = {V_TH:.4f} V")

```
p25
```
import numpy as np

# Constants (These can be modified based on specific device parameters)
mu_n = 450e-4  # Electron mobility (m^2/V/s)
C_ox = 9.6e-9  # Oxide capacitance per unit area (F/μm^2)
W = 10e-6      # Width of MOSFET (m)
L = 2e-6       # Length of MOSFET (m)
V_TH = 1.0     # Threshold voltage (V)
V_GS = 2.0     # Gate-source voltage (V)
I_D = 1e-3     # Drain current (A)

# First form: g_m = mu_n * C_ox * (W/L) * (V_GS - V_TH)
g_m_1 = mu_n * C_ox * (W / L) * (V_GS - V_TH)

# Second form: g_m = sqrt(2 * mu_n * C_ox * (W/L) * I_D)
g_m_2 = np.sqrt(2 * mu_n * C_ox * (W / L) * I_D)

# Output the transconductance values
print(f"Transconductance g_m (first form) = {g_m_1:.4e} S")
print(f"Transconductance g_m (second form) = {g_m_2:.4e} S")


```
```
import numpy as np
import matplotlib.pyplot as plt

# パラメータ設定
mu_n = 150e-3     # 電子移動度 (m^2/Vs)
C_ox = 2.5e-3     # 酸化膜容量 (F/m^2)
W_L = 10          # トランジスタの幅/長さ比
V_TH = 1.0        # しきい値電圧 (V)

# ドレイン電流の範囲 (A)
I_D = np.linspace(0, 100e-6, 500)  # 0〜100μAの範囲
# ゲート-ソース電圧の範囲 (V)
V_GS = np.linspace(0, 5, 500)      # 0〜5Vの範囲

# (2.17) g_m を V_GS - V_TH を用いて計算
g_m_vs_vgs = mu_n * C_ox * W_L * (V_GS - V_TH)
g_m_vs_vgs[V_GS < V_TH] = 0  # V_GS が V_TH より小さい場合は g_m を 0 に設定

# (2.18) g_m を I_D を用いて計算
g_m_vs_id = np.sqrt(2 * mu_n * C_ox * W_L * I_D)

# (2.19) g_m を I_D と V_GS を用いて計算
V_GS_ID = V_TH + 2 * I_D / (mu_n * C_ox * W_L)  # V_GS = V_TH + 2I_D / (mu_n * C_ox * W_L)
g_m_vs_vgs_id = 2 * I_D / (V_GS_ID - V_TH)

# プロット設定
plt.figure(figsize=(14, 6))

# 図 2.18 の各プロット
plt.subplot(1, 3, 1)
plt.plot(V_GS - V_TH, g_m_vs_vgs, label='$g_m$ vs $V_{GS} - V_{TH}$')
plt.xlabel('$V_{GS} - V_{TH}$ (V)')
plt.ylabel('$g_m$ (S)')
plt.title('$g_m$ vs $V_{GS} - V_{TH}$')
plt.grid(True)

plt.subplot(1, 3, 2)
plt.plot(I_D * 1e6, g_m_vs_id, label='$g_m$ vs $I_D$')
plt.xlabel('$I_D$ (μA)')
plt.ylabel('$g_m$ (S)')
plt.title('$g_m$ vs $I_D$')
plt.grid(True)

plt.subplot(1, 3, 3)
plt.plot(V_GS_ID - V_TH, g_m_vs_vgs_id, label='$g_m$ vs $V_{GS} - V_{TH}$ (from $I_D$)')
plt.xlabel('$V_{GS} - V_{TH}$ (V)')
plt.ylabel('$g_m$ (S)')
plt.title('$g_m$ vs $V_{GS} - V_{TH}$ (from $I_D$)')
plt.grid(True)

plt.tight_layout()
plt.show()
```
p28
```
import numpy as np

# Constants (You can adjust these based on your MOSFET characteristics)
q = 1.6e-19         # Elementary charge (C)
epsilon_si = 11.7    # Relative permittivity of silicon
epsilon_0 = 8.854e-12  # Vacuum permittivity (F/m)
Nsub = 1e17         # Substrate doping concentration (cm^-3)
C_ox = 9.6e-9       # Oxide capacitance per unit area (F/μm²)
V_TH0 = 1.0         # Threshold voltage without body effect (V)
V_SB = 0.3          # Source-bulk voltage (V)
k = 1.38e-23        # Boltzmann constant (J/K)
T = 300             # Temperature (K)
ni = 1.5e10         # Intrinsic carrier concentration (cm^-3)

# Fermi potential (Phi_F) calculation
Phi_F = (k * T / q) * np.log(Nsub / ni)

# Body effect coefficient (gamma)
gamma = np.sqrt(2 * q * epsilon_si * epsilon_0 * Nsub) / C_ox

# Threshold voltage with body effect (V_TH)
V_TH = V_TH0 + gamma * (np.sqrt(2 * Phi_F + V_SB) - np.sqrt(2 * Phi_F))

# Output the threshold voltage
print(f"Threshold voltage with body effect V_TH = {V_TH:.4f} V")


```
p29

```
import numpy as np

# Constants (adjust based on your MOSFET characteristics)
mu_n = 450e-4       # Electron mobility (m^2/V/s)
C_ox = 9.6e-9       # Oxide capacitance per unit area (F/μm²)
W = 10e-6           # Width of MOSFET (m)
L = 2e-6            # Length of MOSFET (m)
V_TH0 = 1.0         # Threshold voltage without body effect (V)
V_GS = 2.0          # Gate-source voltage (V)
V_X = 0.1           # Some voltage (V)
k = 1.38e-23        # Boltzmann constant (J/K)
T = 300             # Temperature (K)
q = 1.6e-19         # Elementary charge (C)
epsilon_si = 11.7   # Relative permittivity of silicon
epsilon_0 = 8.854e-12  # Vacuum permittivity (F/m)
Nsub = 1e17         # Substrate doping concentration (cm^-3)
ni = 1.5e10         # Intrinsic carrier concentration (cm^-3)

# Fermi potential calculation (Phi_F)
Phi_F = (k * T / q) * np.log(Nsub / ni)

# Body effect coefficient (gamma)
gamma = np.sqrt(2 * q * epsilon_si * epsilon_0 * Nsub) / C_ox

# Calculate drain current I_D using the given equation
I_D = (0.5 * mu_n * C_ox * (W / L) *
       (V_GS - V_TH0 - gamma * (np.sqrt(2 * Phi_F - V_X) - np.sqrt(2 * Phi_F)))**2)

# Output the drain current
print(f"Drain current I_D = {I_D:.4e} A")

```
p37
```
# Constants (adjust these values based on your specific case)
W = 10e-6        # Width of the MOSFET (m)
E = 1e-6         # Effective length of the diffusion region (m)
C_j = 1e-15      # Junction capacitance per unit area (F/μm²)
C_jsw = 2e-15    # Sidewall junction capacitance (F/μm²)

# For Figure 2.32(a):
C_DB_a = W * E * C_j + 2 * (W + E) * C_jsw
C_SB_a = C_DB_a  # Since C_DB = C_SB for this case

# For Figure 2.32(b):
C_DB_b = (W / 2) * E * C_j + 2 * ((W / 2) + E) * C_jsw
C_SB_b = W * E * C_j + 2 * (W + 2 * E) * C_jsw

# Output the capacitances for both cases
print(f"Capacitance C_DB (Figure 2.32(a)) = {C_DB_a:.4e} F")
print(f"Capacitance C_SB (Figure 2.32(a)) = {C_SB_a:.4e} F")

print(f"Capacitance C_DB (Figure 2.32(b)) = {C_DB_b:.4e} F")
print(f"Capacitance C_SB (Figure 2.32(b)) = {C_SB_b:.4e} F")


```

p38
```
# Constants (adjust these values as needed)
W = 10e-6        # Width of the MOSFET (m)
L = 2e-6         # Length of the MOSFET (m)
L_eff = 1.8e-6   # Effective channel length (m)
C_ox = 9.6e-9    # Oxide capacitance per unit area (F/μm²)
C_d = 1e-12      # Depletion capacitance (F)
C_ov = 2e-15     # Overlap capacitance (F)

# Gate-drain and gate-source capacitances (off region)
C_GD_off = C_GS_off = C_ox * W

# Gate-bulk capacitance
C_GB = (W * L * C_ox * C_d) / (W * L * C_ox + C_d)

# Capacitance in the saturation region
C_GD_sat = C_GS_sat = (W * L * C_ox) / 2

# Capacitance in the linear region
C_GS_lin = (2 * W * L_eff * C_ox) / 3 + W * C_ov

# Output the calculated capacitances
print(f"Gate-Drain Capacitance (Off Region) C_GD_off = {C_GD_off:.4e} F")
print(f"Gate-Bulk Capacitance C_GB = {C_GB:.4e} F")
print(f"Gate-Drain Capacitance (Saturation Region) C_GD_sat = {C_GD_sat:.4e} F")
print(f"Gate-Source Capacitance (Linear Region) C_GS_lin = {C_GS_lin:.4e} F")


```
p41

```

import numpy as np

# Constants (adjust these values for your specific MOSFET)
mu_n = 450e-4        # Electron mobility (m^2/V/s)
C_ox = 9.6e-9        # Oxide capacitance per unit area (F/μm²)
W = 10e-6            # Width of the MOSFET (m)
L = 2e-6             # Length of the MOSFET (m)
V_GS = 2.0           # Gate-source voltage (V)
V_TH = 1.0           # Threshold voltage (V)
gamma = 0.3          # Body effect parameter (V^0.5)
V_SB = 0.5           # Source-bulk voltage (V)
Phi_F = 0.3          # Fermi potential (V)

# Calculate the derivative of V_TH with respect to V_BS
dV_TH_dV_SB = -gamma / 2 * (2 * Phi_F + V_SB)**(-0.5)

# Calculate the body transconductance g_mb
g_mb = mu_n * C_ox * (W / L) * (V_GS - V_TH) * dV_TH_dV_SB

# Output the body transconductance
print(f"Body transconductance g_mb = {g_mb:.4e} S")

```
p42
```
import numpy as np

# Constants (adjust these for your specific MOSFET parameters)
g_m = 1e-3          # Transconductance (S)
gamma = 0.3         # Body effect parameter (V^0.5)
V_SB = 0.5          # Source-bulk voltage (V)
Phi_F = 0.3         # Fermi potential (V)

# Body transconductance calculation
g_mb = g_m * (gamma / (2 * np.sqrt(2 * Phi_F + V_SB)))

# Output the body transconductance
print(f"Body transconductance g_mb = {g_mb:.4e} S")


```

p43
```
import numpy as np
import matplotlib.pyplot as plt

# Constants (adjust based on the MOSFET parameters)
mu_n = 450e-4       # Electron mobility (m^2/V/s)
C_ox = 9.6e-9       # Oxide capacitance per unit area (F/μm²)
W = 10e-6           # Width of the MOSFET (m)
L = 2e-6            # Length of the MOSFET (m)
gamma = 0.3         # Body effect parameter
Phi_F = 0.3         # Fermi potential (V)

# Bias current I_1 values (in Amps)
I_1_values = np.linspace(1e-6, 10e-3, 100)

# Calculate g_m and g_mb for different I_1 values
g_m_values = np.sqrt(2 * mu_n * C_ox * (W / L) * I_1_values)
g_mb_values = g_m_values * (gamma / (2 * np.sqrt(2 * Phi_F + np.sqrt(I_1_values))))

# Plot g_m and g_mb as a function of I_1
plt.figure(figsize=(8, 6))
plt.plot(I_1_values, g_m_values, label='$g_m$', color='blue', linewidth=2)
plt.plot(I_1_values, g_mb_values, label='$g_{mb}$', color='red', linewidth=2)

plt.xlabel('Bias Current $I_1$ (A)')
plt.ylabel('Transconductance (S)')
plt.title('Dependence of $g_m$ and $g_{mb}$ on Bias Current $I_1$')
plt.legend()
plt.grid(True)
plt.xscale('log')  # Logarithmic scale for better visualization
plt.show()


```


p44


```
import numpy as np
import matplotlib.pyplot as plt

# MOSFETのパラメータ設定 (画像の表 2.1 を参考)
VTO_NMOS = 0.7          # NMOSのしきい値電圧 (V)
UO_NMOS = 99e-4         # NMOSのチャネル移動度 (cm^2/Vs)
TOX_NMOS = 9e-9         # NMOSのゲート酸化膜厚 (m)
LAMBDA_NMOS = 0.02      # NMOSのチャネル長変調係数 (V^-1)
W_NMOS = 10e-6          # NMOSの幅 (m)
L_NMOS = 2e-6           # NMOSのチャネル長 (m)

# 定数
C_ox = 3.9 * 8.85e-12 / TOX_NMOS  # 酸化膜容量 (F/m^2)

# 入力電圧の範囲
V_GS = np.linspace(0, 5, 500)  # ゲート-ソース電圧 (0V 〜 5V)
V_DS = np.linspace(0.1, 5, 5)  # ドレイン-ソース電圧 (0.1V, 1V, 2V, 3V, 5V)

# ドレイン電流 I_D の計算 (飽和領域と線形領域)
I_D = np.zeros((len(V_DS), len(V_GS)))

for i, v_ds in enumerate(V_DS):
    for j, v_gs in enumerate(V_GS):
        if v_gs > VTO_NMOS:  # V_GS > VTO のとき
            if v_ds < (v_gs - VTO_NMOS):  # 線形領域
                I_D[i, j] = UO_NMOS * C_ox * (W_NMOS / L_NMOS) * ((v_gs - VTO_NMOS) * v_ds - (v_ds**2) / 2)
            else:  # 飽和領域
                I_D[i, j] = (1 / 2) * UO_NMOS * C_ox * (W_NMOS / L_NMOS) * (v_gs - VTO_NMOS)**2 * (1 + LAMBDA_NMOS * v_ds)

# プロット
plt.figure(figsize=(10, 6))
for i, v_ds in enumerate(V_DS):
    plt.plot(V_GS, I_D[i, :]*1e6, label=f'$V_{{DS}}$ = {v_ds:.1f} V')  # ドレイン電流 I_D を µA 単位で表示

plt.xlabel('$V_{GS}$ (V)')
plt.ylabel('$I_D$ (µA)')
plt.title('NMOS I-V Characteristics')
plt.legend()
plt.grid(True)
plt.show()
```
p81
```
def voltage_gain(g_m, r_0, R_D, R_S, g_mb):
    numerator = -g_m * r_0 * R_D
    denominator = R_D + R_S + r_0 + (g_m + g_mb) * R_S * r_0
    return numerator / denominator

def av(g_m, r_0, R_D, R_S, g_mb):
    numerator = -g_m * r_0 * R_D * (R_S + r_0 + (g_m + g_mb) * R_S * r_0)
    denominator = (R_D + R_S + r_0 + (g_m + g_mb) * R_S * r_0) * (R_S + r_0 + (g_m + g_mb) * R_S * r_0)
    return numerator / denominator

# Example usage:
g_m = 0.01  # Example values for parameters
r_0 = 10000
R_D = 5000
R_S = 1000
g_mb = 0.001

vout_vin = voltage_gain(g_m, r_0, R_D, R_S, g_mb)
av_value = av(g_m, r_0, R_D, R_S, g_mb)

print("Voltage Gain (Vout/Vin):", vout_vin)
print("A_v:", av_value)

```

p83
```
import numpy as np
import matplotlib.pyplot as plt

# パラメータ設定
mu_n = 150e-3      # 電子移動度 (m^2/Vs)
C_ox = 2.5e-3      # 酸化膜容量 (F/m^2)
W_L = 10           # トランジスタの幅/長さ比
V_TH = 1.0         # しきい値電圧 (V)
R_S = 1e3          # ソース抵抗 (Ω)
V_out = 0.2        # 出力電圧の初期値 (V)
eta = 0.1          # ボディ効果係数

# 入力電圧範囲 (Vin)
V_in = np.linspace(0, 5, 500)

# トランスコンダクタンス gm の計算
g_m = mu_n * C_ox * W_L * (V_in - V_TH - V_out)
g_m[V_in < (V_TH + V_out)] = 0  # V_in が (V_TH + V_out) より小さい場合は gm を 0 に設定

# ボディ効果 gm_b の計算
g_mb = eta * g_m

# 小信号利得 Av の計算
A_v = (g_m * R_S) / (1 + (g_m + g_mb) * R_S)

# プロット
plt.figure(figsize=(10, 6))
plt.plot(V_in, A_v, label='$A_v$ vs $V_{in}$')
plt.xlabel('$V_{in}$ (V)')
plt.ylabel('$A_v$ (Gain)')
plt.title('Small-Signal Gain $A_v$ vs $V_{in}$')
plt.grid(True)
plt.legend()
plt.show()
```


```
# Define the parameters
g_m = 0.01  # Example transconductance in Siemens
g_mb = 0.001  # Example backgate transconductance in Siemens
r_o = 1e3  # Example output resistance in ohms
R_P = 1e3  # Example value for RP in ohms
R_D = 1e3  # Example value for RD in ohms

# Compute the numerator and denominator
numerator = (g_m + g_mb) * r_o + 1
denominator = r_o + (g_m + g_mb) * r_o * R_P + R_P + R_D

# Compute Vout/Iin
Vout_Iin = (numerator / denominator) * R_D * R_P

# Display the result
print(f"Vout/Iin = {Vout_Iin}")


```


p85
```

import numpy as np
import matplotlib.pyplot as plt

# パラメータ設定
V_in = 1.2          # ゲート入力電圧 (V)
V_TH0 = 0.6         # 初期しきい値電圧 (V)
phi_F = 0.7         # Fermi 電位 (V)
V_SB = 0.2          # ソース-バルク間電圧 (V)
gamma = 0.4         # ボディ効果係数 (V^1/2)
mu_n = 50e-4        # 電子移動度 (cm^2/Vs)
C_ox = 0.4          # 酸化膜容量密度 (F/m^2)
W_L = 20 / 0.5      # トランジスタの幅/長さ比
I_D = 200e-6        # ドレイン電流 (200 μA)

# 初期のしきい値電圧 V_TH を計算
V_TH = V_TH0 + gamma * (np.sqrt(2 * phi_F + V_SB) - np.sqrt(2 * phi_F))

# 出力電圧 Vout の計算 (式 (3.81) の逆算)
V_out = V_in - V_TH - np.sqrt((2 * I_D) / (mu_n * C_ox * (W_L)))

# プロット用のデータ
V_in_range = np.linspace(0.7, 2.0, 500)  # 入力電圧の範囲
V_out_values = []

# 入力電圧に対する出力電圧を計算
for vin in V_in_range:
    V_th = V_TH0 + gamma * (np.sqrt(2 * phi_F + V_SB) - np.sqrt(2 * phi_F))
    vout = vin - V_th - np.sqrt((2 * I_D) / (mu_n * C_ox * (W_L)))
    V_out_values.append(vout)

# プロット
plt.figure(figsize=(10, 6))
plt.plot(V_in_range, V_out_values, label='$V_{out}$ vs $V_{in}$')
plt.xlabel('$V_{in}$ (V)')
plt.ylabel('$V_{out}$ (V)')
plt.title('Output Voltage $V_{out}$ vs Input Voltage $V_{in}$')
plt.grid(True)
plt.legend()
plt.show()

```



p97
```
import sympy as sp

# Define the symbolic variables
Vin, Vout = sp.symbols('Vin Vout')
gm1, gm2, gmb1, gmb2 = sp.symbols('gm1 gm2 gmb1 gmb2')
ro1, ro2, RD = sp.symbols('ro1 ro2 RD')

# Define the equation for Vout/Vin
numerator = (gm2 + gmb2) * ro2 + 1
denominator_part1 = ro2 + (1 + (gm2 + gmb2) * ro2) * ((1/(gmb1) + 1/gm1) * ro1) + RD
denominator_part2 = ro1 / (1/gmb1 + 1/gm2)

# Final equation for Vout/Vin
Vout_Vin = (numerator / denominator_part1 + RD * denominator_part2).simplify()

# Display the symbolic result
sp.pprint(Vout_Vin)

# Function to substitute values and calculate the result
def calculate_vout_vin(gm1_val, gm2_val, gmb1_val, gmb2_val, ro1_val, ro2_val, RD_val):
    # Substitute numeric values into the symbolic equation
    Vout_Vin_numeric = Vout_Vin.subs({
        gm1: gm1_val,
        gm2: gm2_val,
        gmb1: gmb1_val,
        gmb2: gmb2_val,
        ro1: ro1_val,
        ro2: ro2_val,
        RD: RD_val
    })
    
    # Return the numeric value of Vout/Vin
    return Vout_Vin_numeric

# Example values for the variables (you can modify these values as needed)
gm1_val = 1e-3   # Example: transconductance gm1 = 1 mS
gm2_val = 2e-3   # Example: transconductance gm2 = 2 mS
gmb1_val = 1e-4  # Example: body transconductance gmb1 = 0.1 mS
gmb2_val = 2e-4  # Example: body transconductance gmb2 = 0.2 mS
ro1_val = 10e3   # Example: output resistance ro1 = 10 kΩ
ro2_val = 20e3   # Example: output resistance ro2 = 20 kΩ
RD_val = 5e3     # Example: drain resistance RD = 5 kΩ

# Calculate Vout/Vin using the example values
Vout_Vin_result = calculate_vout_vin(gm1_val, gm2_val, gmb1_val, gmb2_val, ro1_val, ro2_val, RD_val)

# Print the numeric result
print("Vout/Vin =", Vout_Vin_result)


```

p108
```

import sympy as sp

# Define the symbolic variables
gm1, gm2, gm3, gmb2, gmb3 = sp.symbols('gm1 gm2 gm3 gmb2 gmb3')
ro1, ro2, ro3, ro4 = sp.symbols('ro1 ro2 ro3 ro4')

# Equation for Rout
Rout_part1 = (1 + (gm2 + gmb2) * ro2) * ro1 + ro2
Rout_part2 = (1 + (gm3 + gmb3) * ro3) * ro4 + ro3
Rout = Rout_part1 * Rout_part2

# Equation for |Av|
Av = gm1 * (gm2 * ro2 * ro1) * (gm3 * ro3 * ro4)

# Simplify the equations if needed
Rout = Rout.simplify()
Av = Av.simplify()

# Display the results
sp.pprint(Rout)
sp.pprint(Av)

# Example: You can substitute numeric values as needed
def calculate_rout_av(gm1_val, gm2_val, gm3_val, gmb2_val, gmb3_val, ro1_val, ro2_val, ro3_val, ro4_val):
    Rout_numeric = Rout.subs({
        gm1: gm1_val,
        gm2: gm2_val,
        gm3: gm3_val,
        gmb2: gmb2_val,
        gmb3: gmb3_val,
        ro1: ro1_val,
        ro2: ro2_val,
        ro3: ro3_val,
        ro4: ro4_val
    })
    Av_numeric = Av.subs({
        gm1: gm1_val,
        gm2: gm2_val,
        gm3: gm3_val,
        gmb2: gmb2_val,
        gmb3: gmb3_val,
        ro1: ro1_val,
        ro2: ro2_val,
        ro3: ro3_val,
        ro4: ro4_val
    })
    return Rout_numeric, Av_numeric

# Example values (you can modify these values)
gm1_val = 1e-3   # Transconductance gm1
gm2_val = 2e-3   # Transconductance gm2
gm3_val = 1.5e-3 # Transconductance gm3
gmb2_val = 1e-4  # Body transconductance gmb2
gmb3_val = 2e-4  # Body transconductance gmb3
ro1_val = 10e3   # Output resistance ro1
ro2_val = 20e3   # Output resistance ro2
ro3_val = 15e3   # Output resistance ro3
ro4_val = 5e3    # Output resistance ro4

# Calculate Rout and Av with the example values
Rout_result, Av_result = calculate_rout_av(gm1_val, gm2_val, gm3_val, gmb2_val, gmb3_val, ro1_val, ro2_val, ro3_val, ro4_val)

# Print the numeric results
print("Rout =", Rout_result)
print("|Av| =", Av_result)

```

p173
```

import numpy as np

# Parameter settings
W_L1 = 2.0  # W/L ratio for transistor 1
W_L2 = 4.0  # W/L ratio for transistor 2
lambda_val = 0.02  # Channel length modulation parameter λ
VDS1 = 5.0  # Fixed value of V_DS1
VDS2 = 3.0  # Fixed value of V_DS2

# Calculation of I_D2 / I_D1
ID2_ID1 = (W_L2 / W_L1) * ((1 + lambda_val * VDS2) / (1 + lambda_val * VDS1))

# Print the result
print(f"The current ratio I_D2 / I_D1 is: {ID2_ID1}")

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

# Define parameters
gm = 5e-3       # Transconductance (adjusted to 5 mS for higher gain)
gmb = 0.5e-3    # Body transconductance (adjusted to 0.5 mS)
RS = 50         # Source resistance (reduced to 50 ohms for higher gain)
RD = 10e3       # Drain resistance (example 10 kOhms)
CGS1 = 1e-12    # Capacitance CGS1 (example 1 pF)
CSB1 = 1e-12    # Capacitance CSB1 (example 1 pF)
CDG = 0.5e-12   # Capacitance CDG (example 0.5 pF)
CDB = 0.5e-12   # Capacitance CDB (example 0.5 pF)

# Calculate intermediate values
omega_in = 1 / (RS * (CGS1 + CSB1) * (1 / (gm + gmb)))  # Eq. (6.11)
omega_out = 1 / (RD * (CDG + CDB))  # Eq. (6.12)
DC_gain = (gm + gmb) / (1 + (gm + gmb) * RS)

# Convert DC gain to dB for verification
DC_gain_dB = 20 * np.log10(DC_gain)
print(f"DC Gain: {DC_gain_dB:.2f} dB")

# Define the transfer function
numerator = [DC_gain]
denominator = [1 / (omega_in * omega_out), (1 / omega_in) + (1 / omega_out), 1]

system = signal.TransferFunction(numerator, denominator)

# Frequency range for the Bode plot
frequencies = np.logspace(1, 9, 1000)  # Frequency range from 10^1 to 10^9 rad/s
w, mag, phase = signal.bode(system, frequencies)

# Plot the magnitude (Bode plot)
plt.figure()
plt.semilogx(w, mag)  # Bode magnitude plot
plt.title('Bode Plot - Magnitude (Gain >= 10 dB)')
plt.xlabel('Frequency [rad/s]')
plt.ylabel('Magnitude [dB]')
plt.grid(True)

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

# Show the plots
plt.show()

```
p214

```


```


```


```

```

```


```


```


```


```


```

```


```


```


```


```


```

```


```


```


```


```


```

```

```


```


```


```


```

```

```


```


```


```


```


```

```


```


```


```


```


```

```


```


```


```


```