トランジスタ関連のコード


MOSFETの特性
https://www.ritsumei.ac.jp/ocw/se/2007-54813/lecture_doc/13.pdf


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

# MOSFET parameters
mu_Cox = 50e-6  # Mobility and oxide capacitance product (A/V^2)
W = 10e-6  # Width of the MOSFET (m)
L = 1e-6   # Length of the MOSFET (m)
Vth = 1.0  # Threshold voltage (V)
lambda_ = 0.02  # Channel-length modulation parameter (1/V)

# Function to calculate ID
def calculate_ID(VGS, VDS):
    return (1/2) * mu_Cox * (W/L) * (VGS - Vth)**2 * (1 + lambda_ * VDS)

# VGS and VDS ranges
VGS_range = np.linspace(0, 3, 100)  # Gate-source voltage range (V)
VDS_range = np.linspace(0, 3, 100)  # Drain-source voltage range (V)

# Calculate ID for VGS-VDS graph
ID_VDS = np.array([[calculate_ID(VGS, VDS) for VDS in VDS_range] for VGS in VGS_range])

# Plot ID vs VDS for different VGS values
plt.figure(figsize=(10, 6))
for i, VGS in enumerate(np.linspace(1, 3, 5)):
    plt.plot(VDS_range, calculate_ID(VGS, VDS_range), label=f'VGS={VGS:.1f}V')

plt.xlabel('VDS (V)')
plt.ylabel('ID (A)')
plt.title('ID vs VDS for different VGS values')
plt.legend()
plt.grid(True)
plt.show()

# Calculate sqrt(ID) for sqrt(ID) vs VGS graph
sqrt_ID_VGS = np.sqrt((1/2) * mu_Cox * (W/L)) * (VGS_range - Vth) * np.sqrt(1 + lambda_ * VDS_range.mean())

# Plot sqrt(ID) vs VGS
plt.figure(figsize=(10, 6))
plt.plot(VGS_range, sqrt_ID_VGS, label='sqrt(ID) vs VGS')

plt.xlabel('VGS (V)')
plt.ylabel('sqrt(ID) (sqrt(A))')
plt.title('sqrt(ID) vs VGS')
plt.legend()
plt.grid(True)
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/265db9bc-6d25-e332-04bc-fdd2ca0e4c82.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/f0030f94-fb12-9a5a-3b80-02fa60d12078.png)

2点から相互コンダクタンスを求める
```
import numpy as np
import matplotlib.pyplot as plt

# VGSの範囲を定義
VGS = np.linspace(1, 3, 500)  # 1Vから3Vまでの範囲で500ポイント

# IDの計算
ID = ((2-1)/(2-1.5))*(VGS-1.5) + 1

# プロットの作成
plt.figure(figsize=(8, 6))
plt.plot(VGS, ID, label='$I_D = \\left( \\frac{2-1}{2-1.5} \\right) (V_{GS} - 1.5) + 1$')
plt.xlabel('$V_{GS}$ (V)')
plt.ylabel('$I_D$ (mA)')
plt.title('$I_D$ vs $V_{GS}$')
plt.legend()
plt.grid(True)
plt.show()

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/74a3388f-924e-6855-a8e8-3d8db9f9e641.png)


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

# Define the points (replace with actual values)
A = 10  # Example value for A
B = 5   # Example value for B
C = 8   # Example value for C
E = 7   # Example value for E
F = 3   # Example value for F
G = 12  # Example value for G

# Function to draw an arrow
def draw_arrow(ax, start, end, label):
    ax.annotate('', xy=end, xytext=start,
                arrowprops=dict(arrowstyle='->', lw=2),
                label=label)

# Plot settings for large-signal and small-signal analysis
fig, ax = plt.subplots()

# Arrows for large-signal and small-signal analyses
draw_arrow(ax, (0, A), (B, C), 'Large Signal 1')
draw_arrow(ax, (B, C), (E, F), 'Small Signal')
draw_arrow(ax, (E, F), (G, 0), 'Large Signal 2')

# Set plot range
ax.set_xlim(-1, G + 1)
ax.set_ylim(-1, max(A, C, F) + 1)

# Set axis labels
ax.set_xlabel('Vin')
ax.set_ylabel('Vout')

# Set graph title
ax.set_title('Large-Signal and Small-Signal Analysis')

# Time variable for small-signal equivalent circuit
t = np.linspace(0, 2 * np.pi, 1000)
input_signal = (E - B) * np.sin(t)
output_signal = -(C - F) * np.sin(t)

# Plot the small-signal equivalent circuit
fig, ax2 = plt.subplots()
ax2.plot(t, input_signal, label='Input Signal')
ax2.plot(t, output_signal, label='Output Signal')
ax2.legend()

# Set graph title
ax2.set_title('Small-Signal Equivalent Circuit')
ax2.set_xlabel('Time (t)')
ax2.set_ylabel('Signal')

# Display the graphs
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/c365aca3-7bbd-72be-5d05-3e7e04fbe58e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/bcf9951a-5c7b-26ef-da3d-9abd59674703.png)
ソース接地の小信号等価回路
```
import numpy as np
import matplotlib.pyplot as plt

# 一般化された定数
VGS_min = 1.0  # VGSの最小値
VGS_max = 2.0  # VGSの最大値
VGS_threshold = 1.5  # VGSのしきい値
ID_min = 1.0  # IDの最小値
ID_max = 2.5  # IDの最大値
VGS_ID_min = 1.5  # IDの最小値に対応するVGS
VGS_ID_max = 2.0  # IDの最大値に対応するVGS
RL = 1.0  # 負荷抵抗

# VGSの範囲
VGS_range = np.linspace(VGS_min, VGS_max, 100)

# IDの計算
ID_slope = (ID_max - ID_min) / (VGS_ID_max - VGS_ID_min)
ID_intercept = ID_min - ID_slope * (VGS_ID_min - VGS_threshold)
ID = ID_slope * (VGS_range - VGS_threshold) + ID_intercept

# gmの計算
gm = ID_slope

# 入力信号の設定
t = np.linspace(0, 2 * np.pi, 1000)
input_signal = np.sin(t)

# 出力信号の計算
output_signal = -gm * RL * input_signal

# プロット
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(8, 12))

# VGS vs IDのプロット
ax1.plot(VGS_range, ID)
ax1.set_title('VGS vs ID')
ax1.set_xlabel('VGS (V)')
ax1.set_ylabel('ID (mA)')
ax1.grid(True)

# 入力信号のプロット
ax2.plot(t, input_signal)
ax2.set_title('Input Signal (sin(t))')
ax2.set_xlabel('Time (s)')
ax2.set_ylabel('Input Amplitude')
ax2.grid(True)

# 出力信号のプロット
ax3.plot(t, output_signal)
ax3.set_title('Output Signal (-gm × RL × sin(t))')
ax3.set_xlabel('Time (s)')
ax3.set_ylabel('Output Amplitude')
ax3.grid(True)

plt.tight_layout()
plt.show()

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/806c20a8-6c39-4ed5-2fbd-c2c30696084d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/44bc2b3c-de76-fa64-26e2-0110383fb7f7.png)




```
import numpy as np

# Constants definition
mu = 350e-4  # Mobility (cm^2/Vs)
Cox = 3.45e-8  # Oxide capacitance (F/cm^2)
W = 10e-6  # Width of the transistor (cm)
L = 1e-6  # Length of the transistor (cm)
VGS = 2.0  # Gate-Source Voltage (V)
Vth = 0.7  # Threshold Voltage (V)
lambda_ = 0.02  # Channel length modulation parameter
VDS = 1.5  # Drain-Source Voltage (V)
K = mu * Cox  # Process constant

# Calculate the drain current
ID = (1/2) * mu * Cox * (W/L) * ((VGS - Vth)**2) * (1 + lambda_ * VDS)
print(f'Drain Current ID: {ID} A')

# Calculate gm
gm = np.sqrt(2 * K * (W/L) * ID)
print(f'Transconductance gm: {gm} S')

# Calculate drain resistance seen from the source side
drain_resistance = 1 / gm
print(f'Drain resistance seen from the source side: {drain_resistance} ohms')



```

```
import numpy as np

# Constants definition
KP = 350e-4 * 3.45e-8  # Process constant (F/Vs)
W = 10e-6  # Width of the transistor (cm)
L = 1e-6  # Length of the transistor (cm)
lambda_ = 0.02  # Channel length modulation parameter
Load_resistance = 10e3  # Load resistance (ohms)
ID = 550e-6  # Drain current (A)

# Calculate gm
gm = np.sqrt(2 * KP * (W/L) * ID)
print(f'Transconductance gm: {gm} S')

# Calculate on-resistance
on_resistance = 1 / (lambda_ * ID)
print(f'On-resistance: {on_resistance} ohms')

# Calculate voltage gain A
A = gm / (gm + 1/Load_resistance + 1/on_resistance)
print(f'Voltage Gain A: {A}')

# Display gain in decibels
A_dB = 20 * np.log10(A)
print(f'Voltage Gain A (in decibels): {A_dB} dB')


```


```
import numpy as np

# Constants definition
mu = 350e-4  # Mobility (cm^2/Vs)
Cox = 3.45e-8  # Oxide capacitance (F/cm^2)
W = 10e-6  # Width of the transistor (cm)
L = 1e-6  # Length of the transistor (cm)
Vth = 0.7  # Threshold Voltage (V)
VDD = 5.0  # Drain-Source Voltage (V)
R = 1e3  # Load resistance (ohms)
ID = 550e-6  # Drain current (A)

# Calculate VOD
VOD = np.sqrt((2 * ID) / ((W/L) * mu * Cox))
print(f'Overdrive Voltage VOD: {VOD} V')

# Calculate VGS
VGS = np.sqrt((2 * ID) / ((W/L) * mu * Cox)) + Vth
print(f'Gate-Source Voltage VGS: {VGS} V')

# Calculate Overdrive Voltage 2
VOD2 = VDD - ID * R
print(f'Overdrive Voltage 2: {VOD2} V')


```

```
def calculate_gm(ID, μ, Cox, W_over_L, VGS, Vth, λ, VDS):
    gm = μ * Cox * W_over_L * (VGS - Vth) * (1 + λ * VDS)
    return gm

def calculate_gm1(ID, VGS, Vth):
    gm1 = 2 * ID / (VGS - Vth)
    return gm1

def calculate_gm_times_R(gm, R):
    gm_times_R = gm * R
    return gm_times_R

# 与えられた値の例（適宜値を変更してください）
ID = 1e-3  # ID=(1/2)×μ×Cox×(W/L)((VGS-Vth)^2)× (1+λ×VDS)
μ = 600  # モビリティ μ
Cox = 1e-6  # Cox
W_over_L = 10  # W/L
VGS = 3  # VGS
Vth = 1  # Vth
λ = 0.01  # λ
VDS = 5  # VDS
R = 1e3  # R

# gm を計算
gm = calculate_gm(ID, μ, Cox, W_over_L, VGS, Vth, λ, VDS)
print("gm:", gm)

# gm1 を計算
gm1 = calculate_gm1(ID, VGS, Vth)
print("gm1:", gm1)

# gm * R を計算
gm_times_R = calculate_gm_times_R(gm, R)
print("gm * R:", gm_times_R)
```




```
# Constants
W = 50  # Width
L = 1  # Length
mu_Cox = 100e-6  # Mobility and oxide capacitance
VGS = 1.1  # Gate-source voltage
VT = 0.7  # Threshold voltage
Rload = 5e3  # Load resistance
VDD = 5  # Supply voltage

# (1) Calculate ID
ID = (1/2) * (W/L) * mu_Cox * (VGS - VT)**2
print(f"ID = {ID * 1e6} µA")  # Convert to µA for display

# (2) Calculate Vout
Vout = VDD - ID * Rload
print(f"Vout = {Vout} V")

# (3) Calculate VDS
VDS = Vout
print(f"VDS = {VDS} V (VDS > VGS - VT = {VGS - VT} V)")

# (4) Calculate gm
gm = (W/L) * mu_Cox * (VGS - VT)
print(f"gm = {gm * 1e6} µA/V")  # Convert to µA/V for display

# (5) Calculate A0
ron = float('inf')  # Given lambda = 0, ron is infinite
A0 = -gm * Rload
print(f"A0 = {A0}")


```




```
# 必要なライブラリをインポート
import numpy as np

# パラメータ設定
L = 0.5e-6  # ゲート長 [m]
W_n = 10e-6  # NMOSのゲート幅 [m]
mu_n = 200e-4  # NMOSの移動度 [m^2/Vs]
mu_p = 100e-4  # PMOSの移動度 [m^2/Vs]
V_DD = 5.0  # 電源電圧 [V]
V_THn = 0.7  # NMOSのしきい値電圧 [V]
V_THp = -0.7  # PMOSのしきい値電圧 [V]（負の値）

# 電源電圧の中間点でスイッチングする条件
V_IN_star = V_DD / 2

# NMOSとPMOSのドレイン電流が等しいときの条件
# V_GSn = V_IN_star - V_SS (ここではV_SSを0と仮定)
V_GSn = V_IN_star
V_GSp = V_DD - V_IN_star

# PMOSのゲート幅を計算
W_p = W_n * (mu_n / mu_p) * ((V_GSn - V_THn) / (V_GSp - abs(V_THp)))**2

print(f"PMOSのゲート幅 W_p は {W_p * 1e6:.2f} µm です。")
```