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")
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()
# 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()