Resistor example 1D - Ohmic contact procedure explanation
This page explains the following code snipped from the 1D Resistor example:
Ohmic contact equations using a procedure
proc OhmicContact {Contact} { global Vt ni Nd Na pdbSetBoolean $Contact Elec Flux 1 pdbSetBoolean $Contact Hole Flux 1 pdbSetBoolean $Contact DevPsi Flux 1 pdbSetBoolean $Contact Elec Fixed 1 pdbSetBoolean $Contact Hole Fixed 1 pdbSetBoolean $Contact DevPsi Fixed 1 pdbSetDouble $Contact Elec Flux.Scale 1.619e-19 pdbSetDouble $Contact Hole Flux.Scale 1.619e-19 pdbSetString $Contact DevPsi Equation "$Nd - $Na - Elec + Hole" pdbSetString $Contact Elec Equation "DevPsi - $Vt*log((Elec)/$ni) -$Contact" pdbSetString $Contact Hole Equation "DevPsi + $Vt*log((Hole)/$ni) -$Contact" } OhmicContact VSS OhmicContact GND
proc - the tcl procedure
The "function" or "routine" in tcl is called the "procedure," or "proc." Use the procedure to accomplish repetitive tasks. For example, this 1D resistor needs 2 ohmic contacts, one with the name "VSS," (which we'll presumably bias later), and one with the name "GND," (which we'll presumably hold at 0V). Rather than type the 11 lines necessary to set the Ohmic contact equations twice, changing only the name of the contact, we make a procedure with the 11 lines inside it, then call it twice, with the name of the contact as the argument:
OhmicContact VSS OhmicContact GND
Inside the OhmicContact procedure
Inside a proc, all variables are local. This means that to use previously-defined tcl variables we need use the "global" command to tell tcl to retrieve said variables from the outside:
global Vt ni Nd Na
Fixed and Flux are required booleans (yes/no expressed as 1/0) that must be set in the parameter database (pdb) for every contact. You can read the section, What does "Fixed" and Flux" mean?, if you'd like to know what these mean, and what physics they represent. Fixed and Flux are both "1" (yes) for an ohmic contact for all 3 pde solution variables:
pdbSetBoolean $Contact Elec Flux 1 pdbSetBoolean $Contact Hole Flux 1 pdbSetBoolean $Contact DevPsi Flux 1 pdbSetBoolean $Contact Elec Fixed 1 pdbSetBoolean $Contact Hole Fixed 1 pdbSetBoolean $Contact DevPsi Fixed 1
The pdb also contains an optional double under all contacts called "Flux.Scale". Here we have chosen to scale the electron (/cm^3) and hole (cm^3) flux through the contact nodes by q (C), elementary charge, to make the units of I (current) work out.
pdbSetDouble $Contact Elec Flux.Scale 1.619e-19 pdbSetDouble $Contact Hole Flux.Scale 1.619e-19
Finally, these lines store the 3 equation strings for the 3 pde variables in the pdb, setting the boundary conditions on these contact or boundary nodes:
pdbSetString $Contact DevPsi Equation "$Nd - $Na - Elec + Hole" pdbSetString $Contact Elec Equation "DevPsi - $Vt*log((Elec)/$ni) -$Contact" pdbSetString $Contact Hole Equation "DevPsi + $Vt*log((Hole)/$ni) -$Contact"
The first "$Contact" after "pdbSetString"
pdbSetString $Contact
is interpreted by flooxs as the *contact name*, whereas the "$Contact" in the equation strings
"DevPsi - $Vt*log((Elec)/$ni) -$Contact" "DevPsi + $Vt*log((Hole)/$ni) -$Contact"
is interpreted as the *voltage value* on that contact (in Volts) - a number.
Ohmic Contact Physics
Contact equations are boundary conditions. These are necessary to find a specific solution to pde's. In our 1D resistor case, we need 3 boundary conditions - 1 for each pde variable that exists in the Silicon.
When a contact is ohmic, several conditions are true at that edge:
1) charge neutrality - there is no net charge. In other words:
<math>Q = q(n - p + N_d^{-} - N_a^{+}) = 0.</math>
This is expressed in floods via the line
pdbSetString $Contact DevPsi Equation "$Nd - $Na - Elec + Hole"
Remember that "Equation" strings are set to zero by the flooxs parser.
2 and 3) the quasi-fermi levels are equal, and equal to the voltage on the contact
<math>E_{fn} = E_{fp} = V_{applied}</math>
In floods sudo-code, we want to say something like this:
Efn=$Contact
or
Efn-$Contact=0
But how do we get an expression for the Fermi levels? First we assume Maxwell-Boltzmann (MB) statistics. Then, electron concentration can be expressed as:
<math>n=ni*exp(\frac{E_{fn}-E_i}{kT})</math>
We can rearrange to get an expression for <math>E_{Fn}</math>:
<math>E_{Fn}=E_i-kT*log(\frac{n}{ni})</math>
So now, assigning <math>\Psi=E_i</math>
Efn-$Contact=0
becomes
pdbSetString $Contact Elec Equation "DevPsi - $Vt*log((Elec)/$ni) -$Contact"
in floods, since we know we must use only numbers and pde variable names in contact Equation strings.
The Hole Equation is similar. We start with the MB expression for holes that has Efp in it:
<math>p=ni*exp(\frac{E_i-E_{fn}}{kT})</math>
which is rearranged to get
<math>E_{Fp}=E_i+kT*log(\frac{p}{ni})</math>
such that
Efp-$Contact=0
becomes
pdbSetString $Contact Hole Equation "DevPsi + $Vt*log((Hole)/$ni) -$Contact"
in floods.
Advanced
- BEWARE: Do not use "solution const val=" variables in your contact Equation strings. This is not relevant in the simple 1D resistor example, but keep it in mind for later.