I model a few physical aspects of a MOSFET cell. My MOSFET_Model subclass does much more.

Method __init__ Undocumented
Method lowerLimit Returns X with a soft lower limit of limit, using an expression that is numerically robust for all unlimited values and for modestly lower-limited values.
Method Cdox Given oxide thickness tox (m), returns the oxide capacitance per unit area (F/cm^2). AV compatible.
Method PF Given acceptor or donor concentration N, returns the substrate (bulk) Fermi potential PF (phi_F) at nominal temperature. AV compatible.
Method Vfb Given oxide thickness tox, acceptor concentration NA, and donor concentration NG of polysilicon gate, returns the flatband voltage. AV compatible.
Method gamma Given oxide thickness tox and acceptor concentration NA, returns the body effect coefficient. AV compatible.
Method VT Given oxide thickness tox, acceptor concentration NA, and donor concentration NG of polysilicon gate, returns the threshold voltage. AV compatible.
Method Vgsm Returns the lower limit of Vgs for computing n.
Method mu Given doping concentration N, returns the approximate surface mobility of silicon. AV compatible.
Method Kp Given channel width W and length L, acceptor concentration NA, and oxide thickness tox, returns the transconductance parameter Kp. AV compatible.
Method theta Given the mobility reduction coefficient factor Bt and oxide thickness tox, returns the coefficient theta for the Vgs-induced reduction in effective mobility. AV compatible.
Method Lpn No summary
Method n Given VGS (may be a Numpy array), oxide thickness tox, acceptor concentration NA, and donor concentration NG of polysilicon gate, returns n. NOT AV compatible!

Inherited from ArchOpts:

Instance Variable architecture A dict set from the device spec, containing entries N_channel, LDD, vertical, and Rp.
Method N_channel Property: True if N-channel (NMOS), False if P-channel (PMOS).
Method P_channel Property: True if P-channel (NMOS), False if N-channel (PMOS).
Method has_ldd Property: True if includes a lightly doped drift region.
Method has_jfet Property: True if includes a JFET region.
Method has_Rp Property: True if there is enough baseline drain-source leakage to warrant having a fixed resistor in parallel with the MOS3 primitive modeling the channel.
Method npi Returns the unchanged input if N-channel, else the "inverted" value of the input. "Inverted" means different things for different object types:
Method npp Returns the first arg if N channel, else the second one.
Method npr Returns the args, except with the first two reversed if P Channel.
def lowerLimit(self, A, X, limit=None, test=None):

Returns X with a soft lower limit of limit, using an expression that is numerically robust for all unlimited values and for modestly lower-limited values.

The limiter output is log(2)/A when X equals limit.

See AlsoT&M (10.4.6) p. 612. The B-source expression counterpart to this is Expressionist.lowerLimit.
def Cdox(self, tox):

Given oxide thickness tox (m), returns the oxide capacitance per unit area (F/cm^2). AV compatible.

def PF(self, N):

Given acceptor or donor concentration N, returns the substrate (bulk) Fermi potential PF (phi_F) at nominal temperature. AV compatible.

Note: You have to ensure that N does not exceed the upper degeneracy limit.

See AlsoT&M pp. 9-10.
def Vfb(self, tox, NA, NG=None):

Given oxide thickness tox, acceptor concentration NA, and donor concentration NG of polysilicon gate, returns the flatband voltage. AV compatible.

If NG is None, 0, or not specified, then my PM attribute must be set to a metal gate contact potential.

The calculation is fairly involved, and is derived from the metal-substrate (gate-bulk) voltage PMS that is required to cancel the total gate-oxide-bulk contact potential. A small correction term is subtracted from that difference [T&M (2.2.6) p. 71].

PMS = PM - PS where PM is the gate ("metal") contact potential and PS is the bulk ("substrate") contact potential. If the gate and bulk are doped exactly the same or are both degenerate (one being n- and the other p+), then PMS will be twice the gate's (negative) Fermi potential.

PMS is a float or child AV object derived from the result of a call to PF for the p+ bulk and the Fermi potential of the n- polysilicon gate, which is calculated from the work function potential PM of a polysilicon gate based on NG. But if my PM (phi_M) attribute was set in my constructor, its value (which may be expressed as an AV object) is used directly as the work function potential PM for a metal gate.

TODO: Because of the complexity of the computation, a repeated call with the same arguments will return a cached result.

Calls PF and Cdox.

def gamma(self, tox, NA):

Given oxide thickness tox and acceptor concentration NA, returns the body effect coefficient. AV compatible.

An issue with units is addressed during my constructor's one-time calculation of sqrt_2qe: es is in F/m, but m_NA is in cm^-3 and Cdox is in F/cm^2.

Scaling the latter two to meters rather than centimeters multiplies m_NA by 1e6 and Cdox by 1e4. This results in a numerator (after the square root of 1e6) that is 1e3 times as big, and a denominator that is 1e4 times as big. Thus, the T&M formula (2.4.26a) needs to have a constant scalar of 10 included in the numerator.

Calls Cdox.

def VT(self, tox, NA, NG=None):

Given oxide thickness tox, acceptor concentration NA, and donor concentration NG of polysilicon gate, returns the threshold voltage. AV compatible.

If NG is None, 0, or not specified, then my PM attribute must be set to a metal gate contact potential.

Calls PF, Vfb, and gamma.

def Vgsm(self, gamma, Vgs0):

Returns the lower limit of Vgs for computing n.

Call gamma and Vgs0 to get the two argument values.

def mu(self, N, sma=0.45, N_forced=False):

Given doping concentration N, returns the approximate surface mobility of silicon. AV compatible.

The material is N- for N_channel architecture, or if the keyword N_forced is set True. Otherwise it is P+, with hole mobility.

The calculation of muBulk was adapted from http://ecee.colorado.edu/~bart/book/mobility.htm, s2.9.1. Units are cm^2/(V*s).

You can force the value to be for bulk mobility by setting the sma keyword to 1.0.

Surface vs Bulk Mobility

With the default value of the sma keyword (which may be an AV object as well as NA), the result is assumed to be 0.45 of muBulk. That's the best info I have, from T&M p. 159; p. 217 ["may be roughly half of the bulk mobility (as evaluated for lightly doped substrates), or less for heavily doped substrates"], and p. 245 ["significantly lower than the bulk mobility (e.g., by a factor of 2)"].

Mason https://www.egr.msu.edu/classes/ece410/mason/files/Ch6.pdf in his ECE 410 lecture notes 6.19 cites typical N- surface mobility as 500-580 cm^2/(V*s), and "typical" bulk mobility (6.3) as 1360. That works out to a fraction of 0.37 - 0.43.

Sergio Franco in Analog Circuit Design: Discrete and Integrated (p. 407) says mobility at the surface is "somewhere in the neighborhood of one-half to one-third of its bulk value."

def Kp(self, W, L, NA, tox):

Given channel width W and length L, acceptor concentration NA, and oxide thickness tox, returns the transconductance parameter Kp. AV compatible.

The all-region model [T&M (4.9.1) p. 209] for Ids is:

   Ids = Kp*Pt^2*2*n*(a^2 - b^2)
     where
       Kp =  W/L*mu*Cdox
       a = log(1 + exp(Vgst/(2*n*Pt)))
       b = log(1 + exp((Vgst-n*Vds)/(2*n*Pt)))

Everything to the left of n is dependent only on constants and parameters, so you can also define a scale for (4.9.1) as follows:

   scale = Kp * Pt**2 * 2

Then the expression becomes:

   Ids = scale*n*(a^2 - b^2)

The channel "width" parameter W is just for a single cell. Since there can be thousands of cells in a power MOSFET, overall device Kp is likely to be much bigger than the result.

Calls mu and Cdox.

def theta(self, Bt, tox):

Given the mobility reduction coefficient factor Bt and oxide thickness tox, returns the coefficient theta for the Vgs-induced reduction in effective mobility. AV compatible.

Effective mobility is then calculated as follows:

   mu_eff = mu / (1 + theta*(Vgs - VT))

Computing theta is a simple matter of factoring in the effect of tox so that Bt can be relatively free of size effects:

   theta = Bt / tox

T&M (p. 220) introduce this term as Beta_sub_theta and suggest its range is "typically 0.5 to 2 nm * V^-1." A value of zero would entirely eliminate the effect of higher Vgs reducing mu.

Also used in computing a different theta for accumulation in drift. For that, Bt may be smaller due to the oxide being thickened partway along the drift path (LDMOS) or the gate being far away for much of the drift path (VDMOS).

def Lpn(self, xj, L, tox):

Given junction depth xj, channel length L, and oxide thickness tox (all in meters), returns the nominal length of the pinchoff region Lpn relative to the channel length. AV compatible.

It is calculated as follows:

   Lpn = La / L
     where
       La = sqrt(3 * tox * xj)

The junction depth xj is an absolute (not relative) value that is anywhere from a low percentage of the channel length L to a bit bigger than it.

The result Lpn is a "nominal length" because it's the (relative) length of the pinchoff region when Vds just exceeds the onset of saturation. More precisely, it is the fractional length of the channel that is "lost" from inversion when log(1+(Vds-Vds_prime)/VE) = 1. Vds_prime is the drain-source (or source-drain) voltage at the onset of saturation, very close to Vgst/n. VE is a fitting parameter with a value in the general neighborhood of 1.0.

With VE equal to 1.0, Lpn is the pinchoff region length when Vds is 1.718 times Vds_prime. The pinchoff region doubles (again, with VE equal to 1.0) when Vds quadruples from that point. And when Vds is 11x times greater, the pinchoff region will have tripled in length. So, considering how much greater the operating range of a power MOSFET is beyond saturation, Lpn must be kept well below L.

The simplest constraint to impose on Lpn is to assume Vds_prime is zero (a conservative lower limit, since it would require Vgst=0). Then, at breakdown voltage Vds = Vds_BV and requiring that Lpn*log(1+Vds/VE) < L,:

   Lpn < L/log(1 + Vds_BV/VE)
def n(self, VGS, tox, NA, NG=None):

Given VGS (may be a Numpy array), oxide thickness tox, acceptor concentration NA, and donor concentration NG of polysilicon gate, returns n. NOT AV compatible!

The term n is used in the all-region model [T&M (4.9.1) p. 209] and is treated as the equivalent of the more commonly used "alpha." It is the inverse of the first derivative of the surface potential deep in depletion vs Vgs.

If NG is None, 0, or not specified, then my PM attribute must be set to a metal gate contact potential. (The Hspice simulator's implementation of MOS3 assumes NG=1e18.)

This method is NOT AV compatible, because the result relies on VGS, a float (or Numpy array).

API Documentation for pingspice, generated by pydoctor at 2021-09-18 08:41:11.