Doping and devices
from matplotlib import pyplot import numpy as np from scipy.optimize import root_scalar import plotly.graph_objs as go from common import draw_classic_axes, configure_plotting configure_plotting() def sqrt_plus(x): return np.sqrt(x * (x >= 0)) # Band structure parameters. E_V, E_C, E_F = -1.2, 1.8, .4 E_D, E_A = E_C - .7, E_V + .5 m_h, m_e = 1, .5
Learning goals
After this lecture you will be able to:
- Compute carrier density and Fermi level position of doped semiconductors
- Describe the functioning principles of semiconducting devices
Lecture video (Part 1/2)
Lecture video (Part 2/2)
Lecture video - Extra topics
In the previous lecture, we learned how to deal with partially filled bands.
The concept of electrons/holes established the foundations needed to understand semiconductors.
We saw that the filling in semiconductors can be controlled by tuning the temperature.
However, Fermi level control through temperature is still far too constrained and leads to equal electron and hole densities
Adding an impurity to semiconductor¶
In order to understand doping, we need to remember some basic chemistry. Most semiconductors are made up of group IV elements (Si, Ge) or binary compounds between group III-V elements (GaAs). In both cases, there are 4 valence electrons per atom. If we want to increase the average number of electrons per atom, we can add a group V element that has an extra valence electron. We therefore refer to group V elements as donor impurities. However, the extra donor electron is bound to the impurity because group V elements also have an extra proton. In order to estimate the binding strength, we treat the lattice as a background and only consider the system of an electron bound to a proton. We immediately recognize this system as a Hydrogen model with energy levels
The spatial extent of the bound state is given by the Bohr radius:
However, we have to remember that the above equations are written in the free space background.
In our case, the extra electron moves in the semiconductor's conduction band and not free space.
Therefore, there are a couple of differences from the Hydrogen model.
One difference is that the electron's mass is conduction band's effective mass.
Another difference is that the interactions between the electron and proton are screened by the lattice.
As a result, we need to introduce the following substitutions:
with Bohr radius
On the other hand, we can add a group III element to reduce the average number of electrons in the system. Group III elements lacks 1 electron and 1 proton and are therefore known as acceptors. We treat the absence of an electron as a hole and the lacking proton as an effective negative charge. As a result, we once again end up with a Hydrogen model, except this time the charges are flipped (hole circles around a negative center). That allows us to use the previous results and to conclude that an acceptor creates a weakly bound state above the valence band.
Density of states with donors and acceptors¶
E = np.linspace(-3, 3, 1000) fig_dos, ax = pyplot.subplots() n_F = 1/(np.exp(2*(E - E_F)) + 1) g_e = m_e * sqrt_plus(E - E_C) g_h = m_h * sqrt_plus(E_V - E) ax.plot(E, g_h, label="$g_h$") ax.plot(E, g_e, label="$g_e$") sigma = 0.01 g_D = np.exp(-(E_D - E)**2 / sigma**2) g_A = .7 * np.exp(-(E_A - E)**2 / sigma**2) ax.plot(E, g_D, label='$g_D$') ax.plot(E, g_A, label='$g_A$') ax.legend() ax.set_xticks([E_V, E_C, E_A, E_D]) ax.set_xticklabels(['$E_V$', '$E_C$', '$E_A$', '$E_D$']) ax.set_ylabel('$g$') ax.set_xlabel('$E$') draw_classic_axes(ax, xlabeloffset=.2)
In order to model multiple donor/acceptor states, we assume that they are all degenerate at the binding energy. Therefore, we model the density of states of donors/acceptors as a Dirac delta function:
where
How good is this Dirac delta approximation?
That depends on the concentrations.
If we keep on adding impurities, then at some point the weakly bound states will begin to overlap.
The overlap will create an effective tight-binding model that leads to a formation of an "impurity" band which breaks our approximation.
We must therefore prevent the overlap of impurity bound states.
From the previous section, we know that the extent of the bound state is roughly 4 nm and thus the distance between impurity atoms cannot exceed that.
As a result, the impurity concentration is bounded to
Number of carriers¶
We now have the necessary tools to determine how the Fermi level changes with doping. The algorithm to determine the Fermi level of a semiconductor was outlined in the previous lecture and we continue to use it here. The process is the same up until the third step—charge conservation. The semiconductor now contains dopant atoms that become ionized, and therefore charged. For example, if a donor impurity bound state loses an electron, it becomes positively charged. To solve the problem let us introduce all the necessary concentrations:
Symbol | Concentration of |
---|---|
electrons in the conduction band | |
holes in the valence band | |
electrons in the donor bound states | |
holes in the acceptor bound states | |
donor impurities | |
acceptor impurities |
We determine the electron/hole occupation of the donor/acceptor states by applying Fermi-Dirac statistics to their simple Dirac delta density of states:
Here we refer to
The equation is not an easy one to solve: all of the terms on the lhs depend non-trivially on
-
Firstly, we assume that the Fermi level is far from both bands
and . The approximation allows us to use the law of mass action from the previous lecture: -
Secondly, we determined that electrons/holes are weakly bound to the impurities. Therefore, at ambient temperatures, we assume that all the impurities are fully ionized and therefore
.
The approximations allow us to simplify the charge balance equation:
which is just the quadratic equation for
We can now easily find the Fermi level.
From the first approximation, we know that the simplified relation between
We express the lhs with the quadratic equation solution and solve for Fermi level:
and
When is a semiconductor intrinsic, and when it is extrinsic?
By definition the semiconductor is intrinsic when
Temperature dependence of the carrier density and Fermi level¶
It is instructive to consider how
def n(E_F, T, N_C, N_V, N_D, N_A, E_C, E_V, E_D, E_A, /): """Compute total charge density of a doped semiconductor.""" n_e = N_C * np.exp(-(E_C - E_F) / T) n_h = N_V * np.exp((E_V - E_F) / T) n_ionized_D = N_D / (1 + np.exp((E_F - E_D) / T)) n_ionized_A = N_A / (1 + np.exp((E_A - E_F) / T)) return n_e - n_h - n_ionized_D + n_ionized_A def equilibrium_E_F(*args): """Compute the Fermi energy in equilibrium""" E_C, E_V = args[5], args[6] return root_scalar(n, args, bracket=(E_C, E_V)).root N_C, N_V, N_D, N_A, E_C, E_V, E_D, E_A = 1, 4, 0.01, 0.003, 1, -1, 0.8, -0.9 Ts = np.linspace(0.001, .4, 100) E_Fs = np.array( [equilibrium_E_F(T, N_C, N_V, N_D, N_A, E_C, E_V, E_D, E_A) for T in Ts] ) fig = pyplot.figure(figsize=(10, 10)) ax1, ax2 = fig.subplots(nrows=2) ax1.plot(Ts, E_Fs, label=r"$N_A \neq 0$") ax1.plot( Ts, [equilibrium_E_F(T, N_C, N_V, N_D - N_A, 0, E_C, E_V, E_D, E_A) for T in Ts], label="$N_A = 0$", linestyle="--", c="#1f77b4", ) ax1.hlines([E_C, (E_C + E_V) / 2, E_D], Ts[0], Ts[-1], 'k', linestyles=":") ax1.set_ylim(-.1, 1.1) ax1.set_ylabel("$E_F$") ax1.set_xlabel("$T$") ax1.set_yticks([E_C, (E_C + E_V) / 2, E_D]) ax1.set_yticklabels(["$E_C$", "$(E_C + E_V) / 2$", "$E_D$"]) ax1.legend() draw_classic_axes(ax1, y=-.05, ylabeloffset=0.01) ax2.plot(Ts, N_V * np.exp((E_V - E_Fs) / Ts), label="$n_h$") ax2.plot(Ts, N_C * np.exp(-(E_C - E_Fs) / Ts), label="$n_e$") ax2.hlines((N_D - N_A), Ts[0], Ts[-1], 'k', linestyles=":") ax2.set_ylim(0, (N_D - N_A) * 3) ax2.legend() ax2.set_ylabel("$n$") ax2.set_xlabel("$T$") ax2.set_yticks([(N_D - N_A)]) ax2.set_yticklabels(["$N_D - N_A$"]) draw_classic_axes(ax2, ylabeloffset=0.01)
As we go from highest to lowest temperature, we observe several regimes:
- Intrinsic limit . If the temperature is sufficiently large, then
and therefore . Additionally, if holes are heavier than electrons, then grows with temperature in this limit. - Extrinsic limit. As we decrease the temperature, we decrease the number of intrinsic carriers to the point where most of the charge carriers come form the fully ionized donors. As a result, the number of carriers stays approximately constant in this temperature range.
- Freeze-out limit. Once the temperature is sufficiently low
, we expect the electrons to "freeze away" from the conduction band to the donor band. The charge carriers still come from the donors, however, not all donors are ionized now. - Zero temperature. There are no charge carriers in neither conduction nor valence bands. If there are no acceptors, then the Fermi level goes to halfway between the donor and the conduction bands. Otherwise, the highest energy electrons are in the donor band and therefore
should match the donor band.
Exercise
check that you can reproduce all the relevant limits in a calculation.
Combining semiconductors: -junction¶
What happens if we bring two differently doped semiconductors together (one of
Band diagram¶
Previously we dealt with homogeneous materials, now the position coordinate (let's call it
Let us build up the band diagram step by step:
def trans(x, a, b): x = (x-a)/(b-a) return h(x)/(h(x) + h(1-x)) def h(x): return (x > 0) * np.exp(-1/x) left_cutoff = 0.3 right_cutoff = 0.7 x = np.linspace(0, 1, 100) mid_idx = (x > left_cutoff) * (x < right_cutoff) Ef_p = 0.5 Ef_n = Ef_p + 0.25 Ef_delta = Ef_n - Ef_p E_C_1 = 1 E_V_1 = 0.25 E_C = E_C_1 - trans(x, left_cutoff, right_cutoff)*Ef_delta E_V = E_V_1 - trans(x, left_cutoff, right_cutoff)*Ef_delta fig1 = go.Figure() fig1.add_trace(go.Scatter( x = [0, left_cutoff], y = [E_V_1, E_V_1], line_color = 'red', mode = 'lines', name = r'$E_V$', )) fig1.add_trace(go.Scatter( x = [0, left_cutoff], y = [E_C_1, E_C_1], line_color = 'blue', mode = 'lines', name = r'$E_C$', )) # n bands (button 1) fig1.add_trace(go.Scatter( x = [right_cutoff, 1], y = [E_V_1, E_V_1], line_color = 'red', mode = 'lines', showlegend=False )) fig1.add_trace(go.Scatter( x = [right_cutoff, 1], y = [E_C_1, E_C_1], line_color = 'blue', mode = 'lines', showlegend=False )) # p fermi fig1.add_trace(go.Scatter( x = [0, left_cutoff], y = [Ef_p, Ef_p], line_color='black', mode = 'lines', line_dash='dot', name=r'$E_F$' )) # n fermi (button 1) fig1.add_trace(go.Scatter( x = [right_cutoff, 1], y = [Ef_n, Ef_n], line_color='black', mode = 'lines', line_dash='dot', name='r$E_f$', showlegend=False )) fig1.add_trace(go.Scatter( x = [right_cutoff, 1], y = [E_V_1-Ef_delta, E_V_1-Ef_delta], line_color = 'red', mode = 'lines', showlegend=False, visible=False )) fig1.add_trace(go.Scatter( x = [right_cutoff, 1], y = [E_C_1-Ef_delta, E_C_1-Ef_delta], line_color = 'blue', mode = 'lines', showlegend=False, visible=False )) fig1.add_trace(go.Scatter( x = [0, 1], y = [Ef_p, Ef_p], line_color='black', mode = 'lines', line_dash='dot', name='r$E_F$', visible=False, )) fig1.add_trace(go.Scatter( x = x[mid_idx], y = E_C[mid_idx], line_color='blue', line_dash='dot', visible=False, showlegend=False )) fig1.add_trace(go.Scatter( x = x[mid_idx], y = E_V[mid_idx], line_color = 'red', line_dash='dot', visible=False, showlegend=False )) base_annot = [ dict( x = 1.065, y = -0.1, xref = "x", yref = "y", axref = "x", ayref = "y", text = "", ax = 0.9, ay = -0.1, showarrow=True, arrowhead=3, arrowsize=30, arrowwidth=0.1, arrowcolor='black'), dict( x = -0.05, y = 1.12, xref = "x", yref = "y", axref = "x", ayref = "y", text = "", ax = -0.05, ay = 1.1, showarrow=True, arrowhead=3, arrowsize=30, arrowwidth=0.1, arrowcolor='black'), dict( showarrow=False, x = 0.15, y = -0.05, xref = "x", yref = "y", axref = "x", ayref = "y", text = "p-region"), dict( showarrow=False, x = 0.5, y = -0.05, xref = "x", yref = "y", axref = "x", ayref = "y", text = "depletion region"), dict( showarrow=False, x = 0.85, y = -0.05, xref = "x", yref = "y", axref = "x", ayref = "y", text = "n-region") ] annot = [ dict( x = 0.85, y = 0.75, xref = "x", yref = "y", axref = "x", ayref = "y", ax = 0.85, ay = 0.9, showarrow=True, arrowhead=3, arrowsize=2, arrowwidth=1, arrowcolor='black'), dict( x = 0.85, y = 1, xref = "x", yref = "y", axref = "x", ayref = "y", ax = 0.85, ay = 0.849, showarrow=True, arrowhead=3, arrowsize=2, arrowwidth=1, arrowcolor='black'), dict( x = 0.8, y = 0.9, xref = "x", yref = "y", axref = "x", ayref = "y", text = r'$\delta \varphi$', font = dict(size=40), showarrow=False), *base_annot ] updatemenus=list([ dict( type="buttons", direction="down", active=0, buttons=list([ dict(label="n and p", method="update", args=[{"visible": [True, True, True, True, True, True, False, False, False, False, False]}, {'annotations':base_annot}]), dict(label="Equilibrium", method="update", args=[{"visible": [True, True, False, False, False, False, True, True, True, False, False]}, {'annotations':annot}]), dict(label="Band Bending", method="update", args=[{"visible": [True, True, False, False, False, False, True, True, True, True, True]}, {'annotations':annot}]), ]), ) ] ) layout = dict( dragmode=False, showlegend = True, updatemenus=updatemenus, plot_bgcolor = 'rgb(254, 254, 254)', yaxis_range=[(E_V_1-Ef_delta)-0.1, 0.1+E_C_1], xaxis_range=[-0.05, 1.05], width = 800, height = 600, xaxis=dict(title=r'$x$', showticklabels=False), yaxis=dict(title=r'$E$', showticklabels=False), title='Band Diagram' ) fig1.add_annotation( x = 1.065, y = -0.1, xref = "x", yref = "y", axref = "x", ayref = "y", text = "", ax = 0.9, ay = -0.1, showarrow=True, arrowhead=3, arrowsize=30, arrowwidth=0.1, arrowcolor='black') fig1.add_annotation( x = -0.05, y = 1.12, xref = "x", yref = "y", axref = "x", ayref = "y", text = "", ax = -0.05, ay = 1.1, showarrow=True, arrowhead=3, arrowsize=30, arrowwidth=0.1, arrowcolor='black') fig1.add_annotation( showarrow=False, x = 0.15, y = -0.05, xref = "x", yref = "y", axref = "x", ayref = "y", text = "p-region") fig1.add_annotation( showarrow=False, x = 0.5, y = -0.05, xref = "x", yref = "y", axref = "x", ayref = "y", text = "depletion region") fig1.add_annotation( showarrow=False, x = 0.85, y = -0.05, xref = "x", yref = "y", axref = "x", ayref = "y", text = "n-region") fig1.update_xaxes(showline=True, linewidth=2, linecolor='black') fig1.update_yaxes(showline=True, linewidth=2, linecolor='black') fig1.update_layout(layout) fig1
The main difference between
We can understand the junction with a simple picture.
In physics, most of the time we expect things to change continuously.
Therefore, we expect that the valence
On a more microscopic level, the electrons at the junction in the
The charge density
The typical values of
-junction diode¶
What happens if we apply voltage to a junction?
Because the conductivity of the
The number of majority carriers moving across the junction is proportional to their concentration. Increasing the voltage bias "pushes" carriers up in energy, it depends exponentially on the voltage.
We therefore get the Shockley diode equation:
Solar cell¶
Light absorbed in the
Semiconducting laser¶
A heavily doped
MOSFET and quantum well¶
See the book for details.
Summary¶
Density of states in a doped semiconductor:
fig_dos
Charge balance determines the number of electrons and holes as well as the position of the Fermi level.
If dopant concentration is low, then
If dopant concentration is high, then in
Temperature switches between intrinsic and extrinsic regimes, and controls the carrier density
Conductance combines the contributions of electrons and holes, and allows to determine
A
Exercises¶
Exercise 1: Crossover between extrinsic and intrinsic regimes¶
In the lecture we have identified the intrinsic and extrinsic regimes.
Let us now work out what happens when the semiconductor is at the border between these two regimes, and the dopant concentration
- Write down the law of mass action and the charge balance condition for a doped semiconductor.
- Solve this system of equations for
and only assuming . - Verify that your solution reproduces intrinsic regime when
and the extrinsic regime when
Exercise 2: Donor ionization¶
Let us examine when the full donor ionization is a good assumption. For that we consider a doped semiconductor in the extrinsic regime.
- Assume that all dopants are ionized, determine the position of the Fermi level.
- Write down the concentration of dopants that are not ionized.
- Determine at what donor concentration one cannot assume anymore that all donors are ionized in germanium at room temperature.
Exercise 3: Performance of a diode¶
Consider a pn-junction diode as follows
source
By Raffamaiden CC BY-SA 3.0), Link
The current flowing through a diode as a function of applied bias voltage is given by the Shockley diode equation:
where
- What is the significance of adding dopant atoms to an intrinsic semiconductor? Can two intrinsic semiconductors joined together make a diode?
- Discuss which processes carry current in a diode under reverse bias.
- Based on this, estimate how the saturation current
depends on temperature.
Exercise 4: Quantum well heterojunction in detail¶
Consider a a quantum well formed from a layer of GaAs of thickness
source
Vectorised by User:Sushant savla from the work by Gianderiu - Quantum well.svg, CC-BY-SA 3.0.
Assume that the band gap of the Al
- Sketch the band diagram of this quantum well.
- Write down the Schrödinger's equation for electrons and holes
- Find the energies of electron and holes in the quantum well as a function of
. - Calculate the density of states of electron and holes in this quantum well.
- If we want to design a quantum well with a bandgap 0.1 eV larger than that of bulk GaAs, what thickness
do we need? - Why is this structure more useful for making a laser than a normal pn-junction?
- What would be the advantage of doping the Al
Ga As compared to the GaAs in this quantum well?