CMOSアンプ設計

```
import numpy as np

# Define constants
mu_Cox = 1e-4  # Mobility * Oxide capacitance (example value)
W = 1e-6  # Channel width (example value)
L = 1e-6  # Channel length (example value)
VT = 0.7  # Threshold voltage (example value)
lambda_ = 0.02  # Channel length modulation (example value)

# Define a function for calculating the constant K
def calc_K(mu_Cox, W, L):
    return (mu_Cox * W) / (2 * L)

# Define a function for calculating current in the saturation region (ideal)
def Id_sat_ideal(VGS, VT, K):
    return K * (VGS - VT) ** 2

# Define a function for calculating current in the saturation region (real)
def Id_sat_real(VGS, VT, K, VDS, lambda_):
    return K * (VGS - VT) ** 2 * (1 + lambda_ * VDS)

# Define a function for calculating current in the triode region
def Id_triode(VGS, VT, K, VDS):
    return K * (2 * (VGS - VT) * VDS - VDS ** 2)

# Define a function for calculating transconductance
def gm(K, VGS, VT):
    return 2 * K * (VGS - VT)

# Define a function for calculating output conductance
def gds(lambda_, Id):
    return lambda_ * Id

# Example values for VGS and VDS
VGS = 1.0  # Gate-source voltage (example value)
VDS = 0.5  # Drain-source voltage (example value)

# Calculate constant K
K = calc_K(mu_Cox, W, L)

# Calculate currents in different regions
Id_sat_ideal_value = Id_sat_ideal(VGS, VT, K)
Id_sat_real_value = Id_sat_real(VGS, VT, K, VDS, lambda_)
Id_triode_value = Id_triode(VGS, VT, K, VDS)

# Calculate transconductance and output conductance
gm_value = gm(K, VGS, VT)
gds_value = gds(lambda_, Id_sat_real_value)

# Display results
print(f"Constant K: {K:.4e}")
print(f"Saturation Region (Ideal) Id: {Id_sat_ideal_value:.4e} A")
print(f"Saturation Region (Real) Id: {Id_sat_real_value:.4e} A")
print(f"Triode Region Id: {Id_triode_value:.4e} A")
print(f"Transconductance gm: {gm_value:.4e} S")
print(f"Output Conductance gds: {gds_value:.4e} S")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/c18e53d4-90cd-8a53-dfdc-8ab42ca0eb31.png)

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

# Define the frequencies for Bode plot
frequencies = np.logspace(3, 9, 1000)  # 1kHz to 1GHz

# Parameters from the circuit
A0 = 400  # DC Gain

# Pole frequencies (before compensation)
fp1_before = 16e6  # 16 MHz
fp2_before = 53e6  # 53 MHz

# Pole frequencies (after compensation)
fM1_after = 160e3  # 160 kHz
fM2_after = 530e6  # 530 MHz

# Transfer function for before compensation
def transfer_function_before(f):
    return A0 / ((1 + 1j * f / fp1_before) * (1 + 1j * f / fp2_before))

# Transfer function for after compensation
def transfer_function_after(f):
    return A0 / ((1 + 1j * f / fM1_after) * (1 + 1j * f / fM2_after))

# Calculate magnitude and phase
magnitude_before = 20 * np.log10(np.abs(transfer_function_before(frequencies)))
phase_before = np.angle(transfer_function_before(frequencies), deg=True)

magnitude_after = 20 * np.log10(np.abs(transfer_function_after(frequencies)))
phase_after = np.angle(transfer_function_after(frequencies), deg=True)

# Plotting
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 10))

# Magnitude plot
ax1.semilogx(frequencies, magnitude_before, label='Before Compensation', linestyle='--')
ax1.semilogx(frequencies, magnitude_after, label='After Compensation', color='red')
ax1.set_title('Bode Plot: Magnitude Response')
ax1.set_ylabel('Magnitude (dB)')
ax1.legend()
ax1.grid(True, which='both', linestyle='--', linewidth=0.5)

# Phase plot
ax2.semilogx(frequencies, phase_before, label='Before Compensation', linestyle='--')
ax2.semilogx(frequencies, phase_after, label='After Compensation', color='red')
ax2.set_title('Bode Plot: Phase Response')
ax2.set_xlabel('Frequency (Hz)')
ax2.set_ylabel('Phase (degrees)')
ax2.legend()
ax2.grid(True, which='both', linestyle='--', linewidth=0.5)

plt.tight_layout()
plt.show()


```


```
# Import necessary libraries
import matplotlib.pyplot as plt
import numpy as np

# Updated parameters based on detailed image information
A0 = 400  # DC Gain
Cp1 = 0.5e-12  # 0.5 pF
Cp2 = 3e-12    # 3 pF
CM = 50e-12    # 50 pF

# Resistor values from image
rp1 = 20e3  # 20 kOhm
rp2 = 1e3   # 1 kOhm

# Transconductance value
gm1 = 2e-3  # 2 mS
gm6 = 10e-3  # 10 mS

# Calculate pole frequencies before compensation
fp1_before = 1 / (2 * np.pi * Cp1 * rp1)  # First pole frequency
fp2_before = 1 / (2 * np.pi * Cp2 * rp2)  # Second pole frequency

# Calculate pole frequencies after compensation
fM1_after = 1 / (2 * np.pi * CM * rp1)  # First pole frequency after compensation
fM2_after = gm6 / (2 * np.pi * Cp2)     # Second pole frequency after compensation

# Define the frequency range for Bode plot
frequencies = np.logspace(3, 9, 1000)  # 1kHz to 1GHz

# Recalculate transfer functions with updated values
def transfer_function_before_updated(f):
    return A0 / ((1 + 1j * f / fp1_before) * (1 + 1j * f / fp2_before))

def transfer_function_after_updated(f):
    return A0 / ((1 + 1j * f / fM1_after) * (1 + 1j * f / fM2_after))

# Calculate magnitude and phase with updated transfer functions
magnitude_before_updated = 20 * np.log10(np.abs(transfer_function_before_updated(frequencies)))
phase_before_updated = np.angle(transfer_function_before_updated(frequencies), deg=True)

magnitude_after_updated = 20 * np.log10(np.abs(transfer_function_after_updated(frequencies)))
phase_after_updated = np.angle(transfer_function_after_updated(frequencies), deg=True)

# Plotting
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 10))

# Magnitude plot
ax1.semilogx(frequencies, magnitude_before_updated, label='Before Compensation (Updated)', linestyle='--')
ax1.semilogx(frequencies, magnitude_after_updated, label='After Compensation (Updated)', color='red')
ax1.set_title('Bode Plot: Magnitude Response (Updated)')
ax1.set_ylabel('Magnitude (dB)')
ax1.legend()
ax1.grid(True, which='both', linestyle='--', linewidth=0.5)

# Phase plot
ax2.semilogx(frequencies, phase_before_updated, label='Before Compensation (Updated)', linestyle='--')
ax2.semilogx(frequencies, phase_after_updated, label='After Compensation (Updated)', color='red')
ax2.set_title('Bode Plot: Phase Response (Updated)')
ax2.set_xlabel('Frequency (Hz)')
ax2.set_ylabel('Phase (degrees)')
ax2.legend()
ax2.grid(True, which='both', linestyle='--', linewidth=0.5)

plt.tight_layout()
plt.show()



```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/cd8baf1c-020e-3020-3de8-72df1a1a06a9.png)



```

# Import necessary libraries
import matplotlib.pyplot as plt
import numpy as np

# Define the frequency range
frequencies = np.logspace(1, 8, 1000)  # 10 Hz to 100 MHz
omega = 2 * np.pi * frequencies  # Angular frequency

# Define parameters for the transfer function (assumed values)
gm = 10e-3     # Transconductance (10 mS)
Rs = 1e3       # Source resistance (1 kOhm)
Rd = 10e3      # Drain resistance (10 kOhm)
Ci = 1e-12     # Input capacitance (1 pF)
Co = 5e-12     # Output capacitance (5 pF)

# Calculate each component of the transfer function
def input_response(omega):
    return 1 / (1 + 1j * omega * Ci * Rs)

def amplifier_gain():
    return -gm * Rd

def output_response(omega):
    return 1 / (1 + 1j * omega * Co * Rd)

# Calculate the total transfer function
def transfer_function(omega):
    return input_response(omega) * amplifier_gain() * output_response(omega)

# Calculate magnitude and phase
G = transfer_function(omega)
magnitude = 20 * np.log10(np.abs(G))
phase = np.angle(G, deg=True)

# Plot the Bode plot
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 10))

# Magnitude plot
ax1.semilogx(frequencies, magnitude, label='Magnitude Response', color='blue')
ax1.set_title('Bode Plot: Magnitude and Phase Response (Assumed Parameters)')
ax1.set_ylabel('Magnitude (dB)')
ax1.grid(True, which='both', linestyle='--', linewidth=0.5)
ax1.legend()

# Phase plot
ax2.semilogx(frequencies, phase, label='Phase Response', color='green')
ax2.set_xlabel('Frequency (Hz)')
ax2.set_ylabel('Phase (degrees)')
ax2.grid(True, which='both', linestyle='--', linewidth=0.5)
ax2.legend()

plt.tight_layout()
plt.show()

```


```


```