DIODE VS TEMPERATURE

← all examples · interactive version of ex/vd.py · diodes, references and bias
n_i(T)
I_S(T)
V_D = (kT/q)·ln(I_C/I_S)
NON-LINEARITY
BIAS
The reference area is 1 µm2 = 10-8 cm2, as in the script. I_S scales with it, V_D with its logarithm.
DEVICE
SWEEP
V_D AT 27°C
dV_D/dT
MAX NON-LIN
n_i AT 27°C
I_S AT 27°C
(V_D-E_g/q-3kT/q)/T
Advanced (density of states)
Simple (doubles every 11 K)
BSIM 4.8
V_D(T)
Deviation from straight

WHAT YOU ARE LOOKING AT

A diode biased at a constant current has a voltage across it that falls almost perfectly linearly with temperature. That is the basis of every temperature sensor and every bandgap reference you will build, so it is worth knowing where the slope comes from and how linear “almost perfectly” really is.

The chain is short. The intrinsic carrier concentration ni(T) comes from the density of states and the bandgap, and it is a ferocious function of temperature — look at the log axis. The saturation current goes as ni2. And then

VD = (kT/q)·ln(IC/IS)

puts the two temperature dependences against each other: kT/q rising, ln(1/IS) falling much faster. The result is the falling, nearly straight line in the third panel. The fourth panel is what is left after subtracting the best straight line through it — a couple of millivolts of curvature, and that curvature is exactly the error a first-order bandgap reference cannot correct.

The slope is not a constant of nature; it depends on where the diode is biased, through dVD/dT = (VD − Eg/q − 3kT/q)/T. The familiar −2 mV/K belongs to a diode sitting near 0.7 V. With the script's numbers — 1 µm2 of junction and 1019 doping on both sides — IS comes out extremely small, VD lands near 0.91 V, and the slope is only −0.95 mV/K. The last readout evaluates that formula so you can watch it track the fitted slope as you move the bias. And notice where the fitted line extrapolates to at 0 K: about Eg/q + 3kT/q, which is where a bandgap reference gets both its name and its output voltage.

THINGS WORTH TRYING

THE PYTHON

def calc_ni(T):
    mn = (0.98*0.19*0.19)**(1/3)*m0
    mp = 0.81*m0                       # heavy hole
    Nc = 2*np.sqrt(np.power((2*pi*k*T*mn)/(h*h),3))
    Nv = 2*np.sqrt(np.power((2*pi*k*T*mp)/(h*h),3))
    ni = np.sqrt(Nc*Nv)*np.exp(-Eg/(2*k*T))
    return ni*cm3

I_s = q*A*n_i_adv**2*(1/NA*np.sqrt(Dn/tau_n) + 1/ND*np.sqrt(Dp/tau_n))
Vd  = k*T/q*np.log(I_c/I_s)

line = np.polynomial.polynomial.polyfit(T,Vd,1)
vd_lin_err = Vd - (T*line[1] + line[0])

Source: ex/vd.py, based on Streetman. The diffusion constants are fixed at their 300 K values (Dn = 36, Dp = 12 cm2/s), as in the script; the antenna leakage example adds their temperature dependence.