Design tool for Butterworth-optimized photodiode transimpedance amplifiers (TIAs), with focus on balanced (differential) detection applications.
Two identical photodiodes are connected to two identical TIA channels. The small difference between their output voltages is extracted as the signal. This requires:
-
Low and stable
$I_b$ (JFET-input opamp): inter-channel DC offset$= R_f \times \Delta I_b$ -
Low temperature drift of
$I_b$ : bipolar opamps produce unacceptable offset drift for this application -
Noise performance is secondary to
$I_b$ stability
-
Butterworth-optimized
$C_f$ — exact solution (no approximation of$\omega_c R_f C_f \gg 1$ ) -
2nd-order Butterworth NEB —
$\pi\sqrt{2}/4 \cdot f_{-3\text{dB}}$ , not the single-pole approximation - Piecewise voltage noise integration — accounts for noise gain shape (zero, rising, plateau, rolloff regions)
- Opamp comparison table — compare all opamps in the database with one function call
-
Parameter sweep & plotting — explore
$R_f$ vs SNR/bandwidth/shot-noise-limit trade-offs - CSV-based component database — add new opamps or photodiodes by editing a CSV file
OPAMP_circuit_design/
├── tia_design.py # Calculation engine (functions & dataclasses)
├── Photodiode_TIA_design.ipynb # Interactive notebook
├── docs/theory_note.tex # Full derivations of TIA formulas (LaTeX source)
├── docs/theory_note.pdf # Compiled PDF
├── data/
│ ├── opamps.csv # Opamp parameter database
│ └── photodiodes.csv # Photodiode parameter database
└── README.md
from tia_design import *
opamps = load_opamps()
pd = load_photodiodes()['PIN-6D']
# Single design
result = design_tia(opamps['OPA827'], pd, R_f=20e3, Vb=12, E_photo=0.15e-3)
print_result(result)
# Compare all opamps
compare_opamps(opamps, pd, R_f=20e3, Vb=12, E_photo=0.15e-3)
# Compare JFET-input opamps only
jfet = {k: v for k, v in opamps.items() if v.input_type == 'JFET'}
compare_opamps(jfet, pd, R_f=20e3, Vb=12, E_photo=0.15e-3)=== TIA Design: OPA827 ===
C_d = 55.0 pF, C_i = 73.0 pF
C_f = 7.26 pF (Butterworth optimum)
BW = 1.48 MHz, NEB = 1.64 MHz
Noise gain peak = 11.1
Noise breakdown (output-referred RMS):
E_noe (opamp voltage) = 79.7 uV
E_noR (Rf thermal) = 23.2 uV
E_no_bg (total BG) = 83.0 uV
E_noi_sig (sig shot) = 131.6 uV
Figures of merit:
Signal = 1650.00 mV
SNR = 10604 (80.5 dB)
bg/shot ratio = 0.63 (shot-noise limited)
Offset/ch = 60.0 nV
Add one row to data/opamps.csv. Each column corresponds to a specific datasheet parameter:
| CSV column | Datasheet parameter | Unit | Where to find in datasheet |
|---|---|---|---|
name |
Part number | — | Front page |
f_c |
Gain Bandwidth Product (GBW or GBP) | Hz | "Electrical Characteristics" table, or "Open-Loop Gain vs Frequency" plot (frequency at 0 dB) |
I_b |
Input Bias Current | A | "Electrical Characteristics" table, typical value |
f_f |
1/f noise corner frequency | Hz | "Input Voltage Noise Spectral Density vs Frequency" plot — the frequency where the 1/f slope meets the white-noise floor |
e_nif |
Input Voltage Noise Density (flat/white region) | V/sqrt(Hz) | Same plot as above — the flat floor level at high frequency (typically > 1 kHz) |
i_nif |
Input Current Noise Density (flat/white region) | A/sqrt(Hz) | "Input Current Noise Spectral Density vs Frequency" plot — the flat floor level. For JFET opamps this is often listed only in the characteristics table |
C_icm |
Common-Mode Input Capacitance | F | "Electrical Characteristics" table or "Typical Application" section |
C_id |
Differential Input Capacitance | F | Same as above. If not listed separately, set to 0 |
input_type |
Input stage type | — | JFET, bipolar, or CMOS — from product description or "Features" section |
notes |
Free-form description | — | — |
Example row:
OPA828,45e6,1e-12,200,3.4e-9,4.5e-15,5.2e-12,3e-12,JFET,New low-noise JFET opampPhotodiode parameters are stored in data/photodiodes.csv:
| CSV column | Datasheet parameter | Unit | Description |
|---|---|---|---|
name |
Part number | — | — |
Cd_spec |
Junction Capacitance at specified reverse bias | F | "Electrical Characteristics" table, at Vb_spec |
Vb_spec |
Reverse bias voltage for Cd_spec |
V | The bias condition under which Cd_spec is specified |
phi_b |
Built-in voltage (contact potential) | V | Typically 0.2-0.6 V for Si. Used in the abrupt-junction model: C_d(Vb) = Cd0 / sqrt(1 + Vb/phi_b) |
Id_spec |
Dark current at specified reverse bias | A | "Electrical Characteristics" table, at Vb_spec |
r_phi |
Responsivity | A/W | "Responsivity vs Wavelength" plot, at operating wavelength |
wl |
Operating wavelength | m | Wavelength at which r_phi is specified |
The design_tia() function takes the following operating condition parameters:
| Parameter | Unit | Description |
|---|---|---|
R_f |
Ohm | Feedback resistance of the TIA. Determines transimpedance gain (V_out = R_f x I_p). Larger R_f gives higher gain and lower relative thermal noise, but reduces bandwidth |
Vb |
V | Reverse bias voltage applied to the photodiode. Affects junction capacitance C_d (higher Vb reduces C_d) and dark current I_d |
E_photo |
W | Incident optical power on the photodiode. The signal photocurrent is I_p = E_photo x r_phi |
T |
K | Operating temperature (default 296 K = 23 C). Affects Johnson noise of R_f |
C_s |
F | Stray capacitance in parallel with C_f (e.g. PCB parasitic). Default 0 |
C_d_override |
F | Optional override for photodiode capacitance. Use when the measured C_d differs from the abrupt-junction model |
Full step-by-step derivations are given in docs/theory_note.pdf.
The TIA uses an opamp with a single-pole open-loop gain
where the natural frequency and damping ratio are:
The Butterworth (maximally-flat) condition
This is the exact solution without the common approximation
For the Butterworth response, the
The noise equivalent bandwidth for an
This replaces the single-pole approximation
- Graeme, J. (1996). Photodiode Amplifiers: Op Amp Solutions. McGraw-Hill.
- Hobbs, P. C. D. (2009). Building Electro-Optical Systems: Making It All Work. 2nd ed., Wiley.
Python >= 3.10. Install dependencies:
pip install -r requirements.txt