This package Mos2 contains functions and records with data of the mosfet model level 2.
Extends from Modelica.Icons.Package (Icon for standard packages).
Name | Description |
---|---|
Mos2ModelLineParams | Record for Mosfet model line parameters (for level 2) |
Mos2ModelLineVariables | Record for Mosfet model line variables (for level 2) |
Mos2Calc | Further mosfet variables (for level 2) |
mos2ModelLineParamsInitEquations | Initial precalculation |
drainCur | Drain current calculation |
mos2RenameParameters | Parameter renaming to internal names |
mos2RenameParametersDev | Device parameter renaming to internal names |
This record Mos1ModelLineParams contains the model line parameters that are used for the mosfet transistors level 2 in SPICE3.
Extends from Mos.MosModelLineParams (Record for Mosfet model line parameters (for level 1, 2, 3 and 6)).
Type | Name | Default | Description |
---|---|---|---|
Initialization | |||
Real | m_jctSatCurDensity.start | 0.0 | JS, Bulk jct. sat. current density, input - use tSatCurDens |
Resistance | m_sheetResistance.start | 0.0 | RSH, Sheet resistance [Ohm] |
Real | m_bulkJctPotential.start | 0.8 | PB, Bulk junction potential, input - use tBulkPot |
Real | m_bulkJctBotGradingCoeff.start | 0.5 | MJ, Bottom grading coefficient |
Real | m_bulkJctSideGradingCoeff.start | 0.33 | MJSW, Side grading coefficient |
Real | m_oxideThickness.start | 1.0e-7 | TOX, Oxide thickness unit: micron |
Real | m_gateSourceOverlapCapFactor.start | 0.0 | CGS0, Gate-source overlap cap |
Real | m_gateDrainOverlapCapFactor.start | 0.0 | CGD0, Gate-drain overlap cap |
Real | m_gateBulkOverlapCapFactor.start | 0.0 | CGB0, Gate-bulk overlap cap |
Real | m_fNcoef.start | 0.0 | KF, Flicker noise coefficient |
Real | m_fNexp.start | 1.0 | AF, Flicker noise exponent |
Real | m_oxideCapFactor.start | 0.0 | |
Voltage | m_vt0.start | 0.0 | VTO, Threshold voltage [V] |
Capacitance | m_capBD.start | 0.0 | CBD, B-D junction capacitance [F] |
Capacitance | m_capBS.start | 0.0 | CBS, B-S junction capacitance [F] |
CapacitancePerArea | m_bulkCapFactor.start | 0.0 | CJ, Bottom junction cap per area [F/m2] |
Permittivity | m_sideWallCapFactor.start | 0.0 | CJSW, Side grading coefficient [F/m] |
Real | m_fwdCapDepCoeff.start | 0.5 | FC, Forward bias jct. fit parm. |
Voltage | m_phi.start | 0.6 | PHI, Surface potential [V] |
Voltage | m_gamma.start | 0.0 | GAMMA, Bulk threshold parameter [V] |
InversePotential | m_lambda.start | 0.0 | Channel-length modulation [1/V] |
Real | m_substrateDoping.start | 0.0 | NSUB, Substrate doping |
Real | m_gateType.start | 1.0 | TPG, Gate type |
PerArea_cm | m_surfaceStateDensity.start | 0.0 | NSS, Gate type [1/cm2] |
Area_cmPerVoltageSecond | m_surfaceMobility.start | 600.0 | UO, Surface mobility [cm2/(V.s)] |
Length | m_latDiff.start | 0.0 | LD, Lateral diffusion [m] |
Current | m_jctSatCur.start | 1.0e-14 | IS, Bulk junction sat. current [A] |
Resistance | m_drainResistance.start | 0 | RD, Drain ohmic resistance [Ohm] |
Resistance | m_sourceResistance.start | 0 | RS, Source ohmic resistance [Ohm] |
Transconductance | m_transconductance.start | 2.0e-5 | input - use tTransconductance [A/V2] |
record Mos2ModelLineParams "Record for Mosfet model line parameters (for level 2)" extends Mos.MosModelLineParams( m_lambda(start=0.0), m_transconductance(start=2.0e-5), m_bulkJctSideGradingCoeff(start=0.33), m_oxideThickness(start=1.0e-7)); Real m_narrowFactor( start = 0.0) "DELTA, Width effect on threshold"; Real m_critFieldExp( start = 0.0) "UEXP, Crit. field exp for mob. deg"; Real m_critField( start = 1.0e4) "UCRIT, Crit. field for mob. degradation"; Real m_maxDriftVel( start = 0.0) "VMAX, Maximum carrier drift velocity"; Real m_junctionDepth( start = 0.0) "XJ, Junction depth"; Modelica.SIunits.Charge m_channelCharge( start = 1.0) "NEFF, Total channel charge coeff"; Real m_fastSurfaceStateDensity( start = 0.0) "NFS, Fast surface state density";end Mos2ModelLineParams;
This record MosModelLineVariables contains the model line variables that are used for the mosfet transistors level 2 SPICE3.
Extends from Mos.MosModelLineVariables (Record for Mosfet model line variables (for level 1)).
record Mos2ModelLineVariables "Record for Mosfet model line variables (for level 2)" extends Mos.MosModelLineVariables; Real m_bulkCapFactor; Real m_substrateDoping; Real m_xd;end Mos2ModelLineVariables;
This record Mos1Calc contains further mosfet variables (for level 2) that are needed for the calculations.
Extends from Mos.MosCalc (Further mosfet variables (for level 1, 2, 3 and 6)).
Type | Name | Default | Description |
---|---|---|---|
Initialization | |||
Integer | m_mode.start | 1 | Mode |
Transconductance | m_tTransconductance.start | 0. | [A/V2] |
Real | m_tSurfMob.start | 0. | |
Voltage | m_tPhi.start | 0.7 | [V] |
Voltage | m_tVto.start | 1. | [V] |
Real | m_tSatCurDens.start | 0. | |
Current | m_tDrainSatCur.start | 0. | [A] |
Current | m_tSourceSatCur.start | 0. | [A] |
Capacitance | m_tCBDb.start | 0. | [F] |
Capacitance | m_tCBDs.start | 0. | [F] |
Capacitance | m_tCBSb.start | 0. | [F] |
Capacitance | m_tCBSs.start | 0. | [F] |
Real | m_tCj.start | 0. | |
Real | m_tCjsw.start | 0. | |
Voltage | m_tBulkPot.start | 0.7 | [V] |
Real | m_tDepCap.start | 0.35 | |
Voltage | m_tVbi.start | 1. | [V] |
Voltage | m_VBScrit.start | 0.7 | [V] |
Voltage | m_VBDcrit.start | 0.7 | [V] |
Real | m_f1b.start | 0. | |
Real | m_f2b.start | 0. | |
Real | m_f3b.start | 0. | |
Real | m_f1s.start | 0. | |
Real | m_f2s.start | 0. | |
Real | m_f3s.start | 0. | |
Real | m_dVt.start | 0. | |
Capacitance | m_capgd.start | 0. | [F] |
Capacitance | m_capgs.start | 0. | [F] |
Capacitance | m_capgb.start | 0. | [F] |
Charge | m_qgs.start | 0. | [C] |
Charge | m_qgd.start | 0. | [C] |
Charge | m_qgb.start | 0. | [C] |
record Mos2Calc "Further mosfet variables (for level 2)" extends Mos.MosCalc;end Mos2Calc;
This function mos1ModelLineParamsInitEquation does the initial precalculation of the mosfet model line parameters for level 2.
Type | Name | Default | Description |
---|---|---|---|
Mos2ModelLineParams | in_p | Input record model line parameters for MOS2 | |
SpiceConstants | in_C | Spice constants | |
Integer | in_m_type | Type of MOS transistor |
Type | Name | Description |
---|---|---|
Mos2ModelLineVariables | out_v | Output record with model line variables |
function mos2ModelLineParamsInitEquations "Initial precalculation" input Mos2ModelLineParams in_p "Input record model line parameters for MOS2"; input SpiceConstants in_C "Spice constants"; input Integer in_m_type "Type of MOS transistor"; output Mos2ModelLineVariables out_v "Output record with model line variables"; protected Modelica.SIunits.Voltage vtnom; Modelica.SIunits.Voltage fermis; Real fermig; Real wkfng; Real wkfngs; Real egfet1; Real vfb; algorithm out_v.m_oxideCapFactor := in_p.m_oxideCapFactor; out_v.m_transconductance := in_p.m_transconductance; out_v.m_phi := in_p.m_phi; out_v.m_gamma := in_p.m_gamma; out_v.m_vt0 := in_p.m_vt0; out_v.m_substrateDoping := in_p.m_substrateDoping; out_v.m_bulkCapFactor := in_p.m_bulkCapFactor; vtnom := in_p.m_tnom * in_C.CONSTKoverQ; egfet1 := 1.16 - (7.02e-4 * in_p.m_tnom * in_p.m_tnom) / (in_p.m_tnom + 1108); out_v.m_oxideCapFactor := 3.9 * 8.854214871e-12 / in_p.m_oxideThickness; if ( not (in_p.m_transconductanceIsGiven > 0.5)) then out_v.m_transconductance := in_p.m_surfaceMobility * 1.0e-4 * out_v.m_oxideCapFactor; end if; if (in_p.m_substrateDopingIsGiven > 0.5) then if ( out_v.m_substrateDoping * 1.0e6 > 1.45e16) then if ( not (in_p.m_phiIsGiven > 0.5)) then out_v.m_phi := 2 * vtnom * Modelica.Math.log( out_v.m_substrateDoping * 1.0e6 / 1.45e16); out_v.m_phi := max( 0.1, out_v.m_phi); end if; fermis := in_m_type * 0.5 * out_v.m_phi; wkfng := 3.2; if ( in_p.m_gateType <> 0) then fermig := in_m_type * in_p.m_gateType * 0.5 * egfet1; wkfng := 3.25 + 0.5 * egfet1 - fermig; end if; wkfngs := wkfng - (3.25 + 0.5 * egfet1 + fermis); if ( not (in_p.m_gammaIsGiven > 0.5)) then out_v.m_gamma := sqrt(2.0 * 11.70 * 8.854214871e-12 * in_C.CHARGE * out_v.m_substrateDoping * 1.0e6) / out_v.m_oxideCapFactor; end if; if ( not (in_p.m_vtOIsGiven > 0.5)) then vfb := wkfngs - in_p.m_surfaceStateDensity * 1.0e4 * in_C.CHARGE / out_v.m_oxideCapFactor; out_v.m_vt0 := vfb + in_m_type * (out_v.m_gamma * sqrt(out_v.m_phi)+ out_v.m_phi); else vfb := out_v.m_vt0 - in_m_type * (out_v.m_gamma * sqrt(out_v.m_phi) + out_v.m_phi); end if; out_v.m_xd := sqrt( (in_C.EPSSIL + in_C.EPSSIL) / (in_C.CHARGE * out_v.m_substrateDoping * 1.0e6)); else out_v.m_substrateDoping := 0.0; end if; end if; if ( not (in_p.m_bulkCapFactorIsGiven > 0.5)) then out_v.m_bulkCapFactor := sqrt( in_C.EPSSIL * in_C.CHARGE * out_v.m_substrateDoping * 1e6 /(2 * in_p.m_bulkJctPotential)); end if;end mos2ModelLineParamsInitEquations;
This function drainCur calculates the main currents that flows from drain node to source node (level 2).
Type | Name | Default | Description |
---|---|---|---|
Voltage | vbs | [V] | |
Voltage | vgs | [V] | |
Voltage | vds | [V] | |
Mosfet | in_m | Record mosfet | |
Mos2Calc | in_c | Input record Mos2Calc | |
Mos2ModelLineParams | in_p | Input record model line parameters for MOS2 | |
SpiceConstants | in_C | Spice constants | |
Mos2ModelLineVariables | in_vp | Input record model line variables | |
Integer | in_m_type | Type of MOS transistor |
Type | Name | Description |
---|---|---|
Mos2Calc | out_c | Output record Mos2Calc |
function drainCur "Drain current calculation" input Modelica.SIunits.Voltage vbs; input Modelica.SIunits.Voltage vgs; input Modelica.SIunits.Voltage vds; input Mosfet.Mosfet in_m "Record mosfet"; input Mos2Calc in_c "Input record Mos2Calc"; input Mos2ModelLineParams in_p "Input record model line parameters for MOS2"; input SpiceConstants in_C "Spice constants"; input Mos2ModelLineVariables in_vp "Input record model line variables"; input Integer in_m_type "Type of MOS transistor"; output Mos2Calc out_c "Output record Mos2Calc"; protected Real vt; // K * T / Q Real beta1; Real dsrgdb; Real d2sdb2; Real sphi = 0.0; Real sphi3 = 1.0; // square root of phi Real barg; Real sarg; Real bsarg = 0.0; Real sarg3; Real d2bdb2; Real factor; Real dbrgdb; Real eta; Real vbin; Real vth; Real dgddb2; Real dgddvb; Real dgdvds; Real gamasd; Real gammad; Real xn = 1.0; Real argg = 0.0; Real vgst; Real vgsx; Real dgdvbs; Real body; Real bodys = 0.0; Real gdbdv; Real dodvbs; Real dodvds = 0.0; Real dxndvd = 0.0; Real dxndvb = 0.0; Real dudvgs; Real dudvds; Real dudvbs; Real ufact; Real ueff; Real dsdvgs; Real dsdvbs; Real dbsrdb; Real gdbdvs = 0.0; Real dldvgs; Real dldvds; Real dldvbs; Real clfact; Real xleff; Real deltal; Real xwb; Real xld; Real xlamda = in_p.m_lambda; Real phiMinVbs; Real tmp; Real argss; Real argsd; Real args = 0.0; Real argd = 0.0; Real argxs = 0.0; Real argxd = 0.0; Real dbargs; Real dbargd; Real dbxws; Real dbxwd; Real xwd; Real xws; Real daddb2; Real dasdb2; Real ddxwd; Real cfs; Real cdonco; Real argv; Real gammd2; Real arg; Real y3; Real xvalid = 0.0; Real[4] sig1; Real[4] sig2; Real[4] a4; Real[4] b4; Real[8] x4; Real[8] poly4; Real delta4; Integer j; Integer iknt = 0; Integer i; Integer jknt = 0; Real v1; Real v2; Real xv; Real a1; Real b1; Real c1; Real d1; Real b2; Real r1; Real s1; Real s2; Real p1; Real p0; Real p2; Real a3; Real b3; Real sargv; Real dldsat; Real xlfact; Real xdv; Real xlv; Real vqchan; Real dqdsat; Real vl; Real dfunds; Real dfundg; Real dfundb; Real xls; Real dfact; Real vdson; Real cdson; Real gdson; Real didvds; Real gmw; Real gbson; Real expg; algorithm out_c := in_c; vt := in_C.CONSTKoverQ * in_C.REFTEMP; phiMinVbs := out_c.m_tPhi - vbs; if ( vbs <= 0.0) then sarg := sqrt( phiMinVbs); dsrgdb := -0.5 / sarg; d2sdb2 := 0.5 * dsrgdb / phiMinVbs; else sphi :=sqrt(out_c.m_tPhi); sphi3 :=out_c.m_tPhi*sphi; sarg :=sphi/(1.0 + 0.5*vbs/out_c.m_tPhi); tmp :=sarg/sphi3; dsrgdb :=-0.5*sarg*tmp; d2sdb2 :=-dsrgdb*tmp; end if; if ( (vds-vbs) >= 0) then barg := sqrt( phiMinVbs + vds); dbrgdb := -0.5 / barg; d2bdb2 := 0.5 * dbrgdb / (phiMinVbs + vds); else barg := sphi / (1.0 + 0.5 * (vbs - vds) / out_c.m_tPhi); tmp := barg / sphi3; dbrgdb := -0.5 * barg * tmp; d2bdb2 := -dbrgdb * tmp; end if; factor := 0.125 * in_p.m_narrowFactor * 2.0 * Modelica.Constants.pi*in_C.EPSSIL / out_c.m_capOx * out_c.m_lEff; eta := 1.0 + factor; vbin := out_c.m_tVbi * in_m_type + factor * phiMinVbs; if ( (in_vp.m_gamma > 0.0) or (in_vp.m_substrateDoping > 0.0)) then xwd := in_vp.m_xd * barg; xws := in_vp.m_xd * sarg; argss := 0.0; argsd := 0.0; dbargs := 0.0; dbargd := 0.0; dgdvds := 0.0; dgddb2 := 0.0; if ( in_p.m_junctionDepth > 0) then tmp := 2.0 / in_p.m_junctionDepth; argxs := 1.0 + xws * tmp; argxd := 1.0 + xwd * tmp; args := sqrt( argxs); argd := sqrt( argxd); tmp := 0.5 * in_p.m_junctionDepth / out_c.m_lEff; argss := tmp * (args - 1.0); argsd := tmp * (argd - 1.0); end if; gamasd := in_vp.m_gamma * (1.0 - argss - argsd); dbxwd := in_vp.m_xd * dbrgdb; dbxws := in_vp.m_xd * dsrgdb; if ( in_p.m_junctionDepth > 0) then tmp := 0.5 / out_c.m_lEff; dbargs := tmp * dbxws / args; dbargd := tmp * dbxwd / argd; dasdb2 := -in_vp.m_xd * (d2sdb2 + dsrgdb * dsrgdb * in_vp.m_xd / (in_p.m_junctionDepth * argxs)) / (out_c.m_lEff * args); daddb2 := -in_vp.m_xd * (d2bdb2 + dbrgdb * dbrgdb * in_vp.m_xd / (in_p.m_junctionDepth * argxd)) / (out_c.m_lEff * argd); dgddb2 := -0.5 * in_vp.m_gamma * (dasdb2 + daddb2); end if; dgddvb := -in_vp.m_gamma * (dbargs + dbargd); if ( in_p.m_junctionDepth > 0) then ddxwd := -dbxwd; dgdvds := -in_vp.m_gamma * 0.5 * ddxwd / (out_c.m_lEff * argd); end if; else gamasd := in_vp.m_gamma; gammad := in_vp.m_gamma; dgddvb := 0.0; dgdvds := 0.0; dgddb2 := 0.0; end if; out_c.m_von := vbin + gamasd * sarg; vth := out_c.m_von; out_c.m_vdsat := 0.0; if ( in_p.m_fastSurfaceStateDensity <> 0.0 and out_c.m_capOx <> 0.0) then cfs := in_C.CHARGE * in_p.m_fastSurfaceStateDensity * 1.0e4; cdonco := -(gamasd * dsrgdb + dgddvb * sarg) + factor; xn := 1.0 + cfs / out_c.m_capOx * in_m.m_width * out_c.m_lEff + cdonco; tmp := vt * xn; out_c.m_von := out_c.m_von + tmp; argg := 1.0 / tmp; vgst := vgs - out_c.m_von; else vgst := vgs - out_c.m_von; if ( vgs <= out_c.m_von) then // cutoff region out_c.m_gds := 0.0; out_c.m_cdrain := 0.0; out_c.m_gm := 0.0; out_c.m_gmbs := 0.0; return; end if; end if; sarg3 := sarg * sarg * sarg; gammad := gamasd; dgdvbs := dgddvb; body := barg * barg * barg - sarg3; gdbdv := 2.0 * gammad * (barg * barg * dbrgdb - sarg * sarg * dsrgdb); dodvbs := -factor + dgdvbs * sarg + gammad * dsrgdb; if ( (in_p.m_fastSurfaceStateDensity <> 0.0) and (out_c.m_capOx <> 0.0)) then dxndvb := 2.0 * dgdvbs * dsrgdb + gammad * d2sdb2 + dgddb2 * sarg; dodvbs := dodvbs + vt * dxndvb; dxndvd := dgdvds * dsrgdb; dodvds := dgdvds * sarg + vt * dxndvd; end if; // evaluate effective mobility and its derivatives ufact := 1.0; ueff := in_p.m_surfaceMobility * 1e-4; dudvgs := 0.0; dudvds := 0.0; dudvbs := 0.0; if (out_c.m_capOx > 0.0) then tmp := in_p.m_critField * in_C.EPSSIL * 100 / in_vp.m_oxideCapFactor; if (vgst > tmp) then ufact := exp( in_p.m_critFieldExp * Modelica.Math.log( tmp / vgst)); ueff := in_p.m_surfaceMobility * 1.0e-4 * ufact; dudvgs := -ufact * in_p.m_critFieldExp / vgst; dudvds := 0.0; dudvbs := in_p.m_critFieldExp * ufact * dodvbs / vgst; end if; end if; // evaluate saturation voltage and its derivatives according to // grove-frohman equation vgsx := vgs; gammad := gamasd / eta; dgdvbs := dgddvb; if (in_p.m_fastSurfaceStateDensity <> 0 and out_c.m_capOx <> 0) then vgsx := max( vgs, out_c.m_von); end if; if (gammad > 0) then gammd2 := gammad * gammad; argv := (vgsx - vbin) / eta + phiMinVbs; if (argv <= 0.0) then out_c.m_vdsat := 0.0; dsdvgs := 0.0; dsdvbs := 0.0; else arg := sqrt( 1.0 + 4.0 * argv / gammd2); out_c.m_vdsat := (vgsx - vbin) / eta + gammd2 * (1.0 - arg) / 2.0; out_c.m_vdsat := max( out_c.m_vdsat, 0.0); dsdvgs := (1.0 - 1.0 / arg) / eta; dsdvbs := (gammad * (1.0 - arg) + 2.0 * argv / (gammad * arg)) / eta * dgdvbs + 1.0 / arg + factor * dsdvgs; end if; else out_c.m_vdsat := (vgsx - vbin) / eta; out_c.m_vdsat := max( out_c.m_vdsat, 0.0); dsdvgs := 1.0; dsdvbs := 0.0; end if; if (in_p.m_maxDriftVel > 0) then // evaluate saturation voltage and its derivatives // according to baum's theory of scattering velocity saturation v1 := (vgsx - vbin) / eta + phiMinVbs; v2 := phiMinVbs; xv := in_p.m_maxDriftVel * out_c.m_lEff / ueff; a1 := gammad / 0.75; b1 := -2.0 * (v1 + xv); c1 := -2.0 * gammad * xv; d1 := 2.0 * v1 * (v2 + xv) - v2 * v2 - 4.0 / 3.0 * gammad * sarg3; b2 := a1 * c1 - 4.0 * d1; r1 := -b1 * b1 / 3.0 + b2; s1 := 2.0 * b1 * b1 * (-b1) / 27.0 + b1 * b2 / 3.0 + (-d1) * (a1 * a1 - 4.0 * b1) - c1 * c1; s2 := s1 * s1; p1 := s2 / 4.0 + r1 * r1 * r1 / 27.0; p0 := abs( p1); p2 := sqrt( p0); sig1[1] := 1.0; sig1[2] := -1.0; sig1[3] := 1.0; sig1[4] := -1.0; sig2[1] := 1.0; sig2[2] := 1.0; sig2[3] := -1.0; sig2[4] := -1.0; if (p1 < 0) then y3 := 2.0 * exp( Modelica.Math.log( sqrt( s2 / 4.0 + p0)) / 3.0) * cos( Modelica.Math.atan( -2.0 * p2 / s1) / 3.0) + b1 / 3.0; else y3 := exp( Modelica.Math.log( abs( -s1 / 2.0 + p2)) / 3.0) + exp( Modelica.Math.log( abs( -s1 / 2.0 - p2)) / 3.0) + b1 / 3.0; end if; a3 := sqrt( a1 * a1 / 4.0 - b1 + y3); b3 := sqrt( y3 * y3 / 4.0 - d1); for i in 1:4 loop a4[i] := a1/2.0+sig1[i]*a3; b4[i] := y3/2.0+sig2[i]*b3; delta4 := a4[i]*a4[i]/4.0-b4[i]; if (delta4 >= 0) then iknt := iknt+1; tmp := sqrt(delta4); x4[iknt] := -a4[i]/2.0+tmp; iknt := iknt+1; x4[iknt] := -a4[i]/2.0-tmp; end if; end for; jknt := 0; for j in 1:iknt loop if (x4[j] > 0) then poly4[j] := x4[j]*x4[j]*x4[j]*x4[j]+a1*x4[j]*x4[j]*x4[j]; poly4[j] := poly4[j]+b1*x4[j]*x4[j]+c1*x4[j]+d1; if (abs(poly4[j]) <= 1.0e-6) then jknt := jknt+1; if (jknt <= 1) then xvalid := x4[j]; end if; if (x4[j] <= xvalid) then xvalid := x4[j]; end if; end if; end if; end for; if (jknt > 0) then out_c.m_vdsat := xvalid * xvalid - phiMinVbs; end if; end if; // evaluate effective channel length and its derivatives dldvgs := 0.0; dldvds := 0.0; dldvbs := 0.0; if (vds <> 0.0) then gammad :=gamasd; if ((vbs - out_c.m_vdsat) <= 0) then bsarg := sqrt(out_c.m_vdsat + phiMinVbs); dbsrdb := -0.5 / bsarg; else bsarg :=sphi/(1.0 + 0.5*(vbs - out_c.m_vdsat)/out_c.m_tPhi); dbsrdb :=-0.5*bsarg*bsarg/sphi3; end if; bodys := bsarg * bsarg * bsarg - sarg3; gdbdvs := 2.0 * gammad * (bsarg * bsarg * dbsrdb - sarg * sarg * dsrgdb); if (in_p.m_maxDriftVel <= 0) then if (in_vp.m_substrateDoping <> 0.0 and (xlamda <= 0.0)) then argv := (vds - out_c.m_vdsat) / 4.0; sargv := sqrt(1.0 + argv * argv); arg := sqrt(argv + sargv); xlfact := in_vp.m_xd / (out_c.m_lEff * vds); xlamda := xlfact * arg; dldsat := vds * xlamda / (8.0 * sargv); dldvgs := dldsat * dsdvgs; dldvds := -xlamda + dldsat; dldvbs := dldsat * dsdvbs; end if; else argv := (vgsx - vbin) / eta - out_c.m_vdsat; xdv := in_vp.m_xd / sqrt(in_p.m_channelCharge); xlv := in_p.m_maxDriftVel * xdv / (2.0 * ueff); vqchan := argv - gammad * bsarg; dqdsat := -1.0 + gammad * dbsrdb; vl := in_p.m_maxDriftVel *out_c. m_lEff; dfunds := vl * dqdsat - ueff * vqchan; dfundg := (vl - ueff * out_c.m_vdsat) / eta; dfundb := -vl * (1.0 + dqdsat - factor / eta) + ueff * (gdbdvs - dgdvbs * bodys / 1.5) / eta; dsdvgs := -dfundg / dfunds; dsdvbs := -dfundb / dfunds; if ((in_vp.m_substrateDoping <> 0.0) and (xlamda <= 0.0)) then argv := vds - out_c.m_vdsat; argv := max(argv,0.0); xls := sqrt(xlv * xlv + argv); dldsat := xdv / (2.0 * xls); xlfact := xdv / (out_c.m_lEff * vds); xlamda := xlfact * (xls - xlv); dldsat := dldsat / out_c.m_lEff; dldvgs := dldsat * dsdvgs; dldvds := -xlamda + dldsat; dldvbs := dldsat * dsdvbs; end if; end if; end if; // limit channel shortening at punch-through xwb :=in_vp.m_xd*sqrt(out_c.m_tBulkPot); xld :=out_c.m_lEff - xwb; clfact :=1.0 - xlamda*vds; dldvds :=-xlamda - dldvds; xleff :=out_c.m_lEff*clfact; deltal :=xlamda*vds*out_c.m_lEff; if (in_vp.m_substrateDoping == 0.0) then xwb := 0.25e-6; end if; if (xleff < xwb) then xleff := xwb / (1.0 + (deltal - xld) / xwb); clfact := xleff / out_c.m_lEff; dfact := xleff * xleff / (xwb * xwb); dldvgs := dfact * dldvgs; dldvds := dfact * dldvds; dldvbs := dfact * dldvbs; end if; // evaluate effective beta (effective kp) beta1 := out_c.m_Beta * ufact / clfact; // test for mode of operation and branch appropriately gammad := gamasd; dgdvbs := dgddvb; if (vds <= 1.0e-10) then if (vgs <= out_c.m_von) then if ((in_p.m_fastSurfaceStateDensity == 0.0) or (out_c.m_capOx == 0.0)) then out_c.m_gds := 0.0; else out_c.m_gds := beta1 * (out_c.m_von - vbin - gammad * sarg) * exp(argg * (vgs - out_c.m_von)); end if; else out_c.m_gds :=beta1*(vgs - vbin - gammad*sarg); end if; out_c.m_cdrain :=0.0; out_c.m_gm :=0.0; out_c.m_gmbs :=0.0; return; end if; if (vgs <= out_c.m_von) then // subthreshold region if (out_c.m_vdsat <= 0) then out_c.m_gds := 0.0; if (vgs > vth) then return; end if; out_c.m_cdrain := 0.0; out_c.m_gm := 0.0; out_c.m_gmbs := 0.0; return; end if; vdson := min(out_c.m_vdsat, vds); if (vds > out_c.m_vdsat) then barg := bsarg; dbrgdb := dbsrdb; body := bodys; gdbdv := gdbdvs; end if; cdson := beta1 * ((out_c.m_von - vbin - eta * vdson * 0.5) * vdson - gammad * body / 1.5); didvds := beta1 * (out_c.m_von - vbin - eta * vdson - gammad * barg); gdson := -cdson * dldvds / clfact - beta1 * dgdvds * body / 1.5; if (vds < out_c.m_vdsat) then gdson := gdson + didvds; end if; gbson := -cdson * dldvbs / clfact + beta1 * (dodvbs * vdson + factor * vdson - dgdvbs * body / 1.5 - gdbdv); if (vds > out_c.m_vdsat) then gbson := gbson + didvds * dsdvbs; end if; expg := exp(argg * (vgs - out_c.m_von)); out_c.m_cdrain := cdson * expg; gmw := out_c.m_cdrain * argg; out_c.m_gm := gmw; if (vds > out_c.m_vdsat) then out_c.m_gm := gmw + didvds * dsdvgs * expg; end if; tmp := gmw * (vgs - out_c.m_von) / xn; out_c.m_gds := gdson * expg - out_c.m_gm * dodvds - tmp * dxndvd; out_c.m_gmbs := gbson * expg - out_c.m_gm * dodvbs - tmp * dxndvb; elseif (vds <= out_c.m_vdsat) then // linear region out_c.m_cdrain := beta1 * ((vgs - vbin - eta * vds / 2.0) * vds - gammad * body / 1.5); arg := out_c.m_cdrain * (dudvgs / ufact - dldvgs / clfact); out_c.m_gm := arg + beta1 * vds; arg := out_c.m_cdrain * (dudvds / ufact - dldvds / clfact); out_c.m_gds := arg + beta1 * (vgs - vbin - eta * vds - gammad * barg - dgdvds * body / 1.5); arg := out_c.m_cdrain * (dudvbs / ufact - dldvbs / clfact); out_c.m_gmbs := arg - beta1 * (gdbdv + dgdvbs * body / 1.5 - factor * vds); else // saturation region out_c.m_cdrain := beta1 * ((vgs - vbin - eta * out_c.m_vdsat / 2.0) * out_c.m_vdsat - gammad * bodys / 1.5); arg := out_c.m_cdrain * (dudvgs / ufact - dldvgs / clfact); out_c.m_gm := arg + beta1 * out_c.m_vdsat + beta1 * (vgs - vbin - eta * out_c.m_vdsat - gammad * bsarg) * dsdvgs; out_c.m_gds := -out_c.m_cdrain * dldvds / clfact - beta1 * dgdvds * bodys / 1.5; arg := out_c.m_cdrain * (dudvbs / ufact - dldvbs / clfact); out_c.m_gmbs := arg - beta1 * (gdbdvs + dgdvbs * bodys / 1.5 - factor * out_c.m_vdsat) + beta1 * (vgs - vbin - eta * out_c.m_vdsat - gammad * bsarg) * dsdvbs; end if;end drainCur;
This function mos2RenameParameters assigns the external (given by the user, e.g., RD) technology parameters to the internal parameters (e.g., m_drainResistance). It also does the analysis of the IsGiven values (level 2).
Type | Name | Default | Description |
---|---|---|---|
ModelcardMOS2 | ex | Modelcard with technologie parameters | |
SpiceConstants | con | Spice constants |
Type | Name | Description |
---|---|---|
Mos2ModelLineParams | intern | Output record model line parameters |
function mos2RenameParameters "Parameter renaming to internal names" input ModelcardMOS2 ex "Modelcard with technologie parameters"; input SpiceConstants con "Spice constants"; output Mos2ModelLineParams intern "Output record model line parameters"; algorithm intern.m_narrowFactor := ex.DELTA; // DELTA, Width effect on threshold intern.m_critFieldExp := ex.UEXP; // UEXP, Crit. field exp for mob. deg intern.m_critField := ex.UCRIT; // UCRIT, Crit. field for mob. degradation intern.m_maxDriftVel := ex.VMAX; // VMAX, Maximum carrier drift velocity intern.m_junctionDepth := ex.XJ; // XJ, Junction depth intern.m_channelCharge := ex.NEFF; // NEFF, Total channel charge coeff intern.m_fastSurfaceStateDensity := ex.NFS; // NFS, Fast surface state density intern.m_oxideCapFactor := 0; intern.m_vtOIsGiven := if (ex.VTO > -1e40) then 1 else 0; intern.m_vt0 := if (ex.VTO > -1e40) then ex.VTO else 0; intern.m_capBDIsGiven := if (ex.CBD > -1e40) then 1 else 0; intern.m_capBD := if (ex.CBD > -1e40) then ex.CBD else 0; intern.m_capBSIsGiven := if (ex.CBS > -1e40) then 1 else 0; intern.m_capBS := if (ex.CBS > -1e40) then ex.CBS else 0; intern.m_bulkCapFactor := ex.CJ; // F/(m*m) zero-bias bulk junction bottom cap. per sq-meter of junction area (default 0) intern.m_sideWallCapFactor := ex.CJSW; // F/m zero-bias junction sidewall cap. per meter of junction perimeter (default 0) intern.m_fwdCapDepCoeff := ex.FC; // coefficient for forward-bias depletion capacitance formula (default 0.5) intern.m_phiIsGiven := if (ex.PHI > -1e40) then 1 else 0; intern.m_phi := if (ex.PHI > -1e40) then ex.PHI else 0.6; intern.m_gammaIsGiven := if (ex.GAMMA > -1e40) then 1 else 0; intern.m_gamma := if (ex.GAMMA > -1e40) then ex.GAMMA else 0; intern.m_lambda := ex.LAMBDA; // 1/V channel-length modulation (default 0) intern.m_substrateDopingIsGiven := if (ex.NSUB > -1e40) then 1 else 0; intern.m_substrateDoping := if (ex.NSUB > -1e40) then ex.NSUB else 0; intern.m_gateType := ex.TPG; // type of gate material: +1 opp. to substrate, -1 same as substrate, 0 Al gate (default 1) intern.m_surfaceStateDensity := ex.NSS; // 1/(cm*cm) surface state density (default 0) intern.m_surfaceMobility := ex.UO; // (cm*cm)/(Vs) surface mobility (default 600) intern.m_latDiff := ex.LD; // m lateral diffusion (default 0) intern.m_jctSatCur := ex.IS; // A bulk junction saturation current (defaul 1e-14) intern.m_drainResistanceIsGiven := if (ex.RD > -1e40) then 1 else 0; intern.m_drainResistance := if (ex.RD > -1e40) then ex.RD else 0; intern.m_sourceResistanceIsGiven := if (ex.RS > -1e40) then 1 else 0; intern.m_sourceResistance := if (ex.RS > -1e40) then ex.RS else 0; intern.m_transconductanceIsGiven := if (ex.KP > -1e40) then 1 else 0; intern.m_transconductance := if (ex.KP > -1e40) then ex.KP else 2e-5; intern.m_tnom := if (ex.TNOM > -1e40) then ex.TNOM + SpiceConstants.CONSTCtoK else 300.15; intern.m_jctSatCurDensity := ex.JS; // A/(m*m) bulk junction saturation current per sq-meter of junction area (default 0) intern.m_sheetResistance := ex.RSH; // Ohm drain and source diffusion sheet resistance (default 0) intern.m_bulkJctPotential := ex.PB; // V bulk junction potential (default 0.8) intern.m_bulkJctBotGradingCoeff := ex.MJ; // bulk junction bottom grading coeff. (default 0.5) intern.m_bulkJctSideGradingCoeff := ex.MJSW; // bulk junction sidewall grading coeff. (default 0.5) intern.m_oxideThickness := ex.TOX; // m oxide thickness (default 1e-7) intern.m_oxideThicknessIsGiven := if (ex.TOX > -1e40) then 1 else 0; intern.m_oxideThickness := if (ex.TOX > -1e40) then ex.TOX else 1e-7; intern.m_gateSourceOverlapCapFactor := ex.CGSO; // F/m gate-source overlap capacitance per meter channel width (default 0) intern.m_gateDrainOverlapCapFactor := ex.CGDO; // F/m gate-drain overlap capacitance per meter channel width (default 0) intern.m_gateBulkOverlapCapFactor := ex.CGBO; // F/m gate-bulk overlap capacitance per meter channel width (default 0) intern.m_fNcoef := ex.KF; // flicker-noise coefficient (default 0) intern.m_fNexp := ex.AF; // flicker-noise exponent (default 1)end mos2RenameParameters;
This function mos2RenameParameters assigns the external (given by the user) device parameters to the internal parameters. It also does the analysis of the IsGiven values (level 2).
Type | Name | Default | Description |
---|---|---|---|
ModelcardMOS2 | ex | ||
Integer | mtype | ||
Length | W | Width of channel region [m] | |
Length | L | Length of channel region [m] | |
Area | AD | Area of drain diffusion [m2] | |
Area | AS | Area of source diffusion [m2] | |
Length | PD | Drain perimeter [m] | |
Length | PS | Source perimeter [m] | |
Real | NRD | Length of drain squares | |
Real | NRS | Length of Source squares | |
Integer | OFF | Optional initial condition: 0 - IC not used, 1 - IC used, not implemented yet | |
Real | IC | Initial condition values, not implemented yet | |
Temp_C | TEMP | Temperature [degC] |
Type | Name | Description |
---|---|---|
Mosfet | dev | Output record Mosfet |
function mos2RenameParametersDev "Device parameter renaming to internal names" input ModelcardMOS2 ex; input Integer mtype; input Modelica.SIunits.Length W "Width of channel region"; input Modelica.SIunits.Length L "Length of channel region"; input Modelica.SIunits.Area AD "Area of drain diffusion"; input Modelica.SIunits.Area AS "Area of source diffusion"; input Modelica.SIunits.Length PD "Drain perimeter"; input Modelica.SIunits.Length PS "Source perimeter"; input Real NRD "Length of drain squares"; input Real NRS "Length of Source squares"; input Integer OFF "Optional initial condition: 0 - IC not used, 1 - IC used, not implemented yet"; input Real IC "Initial condition values, not implemented yet"; input Modelica.SIunits.Temp_C TEMP "Temperature"; output Mosfet.Mosfet dev "Output record Mosfet"; algorithm /*device parameters*/ dev.m_len := L; // L, length of channel region dev.m_width := W; // W, width of channel region dev.m_drainArea := AD; // AD, area of drain diffusion dev.m_sourceArea := AS; // AS, area of source diffusion dev.m_drainSquares := NRD; // NRD, length of drain in squares dev.m_sourceSquares := NRS; // NRS, length of source in squares dev.m_drainPerimiter := PD; // PD, Drain perimeter; dev.m_sourcePerimiter := PS; // PS, Source perimeter dev.m_dICVDSIsGiven := if (IC > -1e40) then 1 else 0; dev.m_dICVDS := if (IC > -1e40) then IC else 0; dev.m_dICVGSIsGiven := if (IC > -1e40) then 1 else 0; dev.m_dICVGS := if (IC > -1e40) then IC else 0; dev.m_dICVBSIsGiven := if (IC > -1e40) then 1 else 0; dev.m_dICVBS := if (IC > -1e40) then IC else 0; dev.m_off := OFF; // non-zero to indicate device is off for dc analysis dev.m_bPMOS := mtype; // P type MOSfet model dev.m_nLevel := ex.LEVEL; assert(ex.LEVEL== 1, "only MOS Level1 implemented"); dev.m_dTemp :=TEMP + SpiceConstants.CONSTCtoK;end mos2RenameParametersDev;