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.
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.