📄 soi3temp.c
字号:
/**********STAG version 2.7Copyright 2000 owned by the United Kingdom Secretary of State for Defenceacting through the Defence Evaluation and Research Agency.Developed by : Jim Benson, Department of Electronics and Computer Science, University of Southampton, United Kingdom.With help from : Nele D'Halleweyn, Ketan Mistry, Bill Redman-White, and Craig Easson.Based on STAG version 2.1Developed by : Mike Lee,With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards and John Bunyan.Acknowledgements : Rupert Howes and Pete Mole.**********//********** Modified by Paolo Nenzi 2002ngspice integration**********/#include "ngspice.h"#include "cktdefs.h"#include "soi3defs.h"#include "const.h"#include "sperror.h"#include "suffix.h"intSOI3temp(GENmodel *inModel, CKTcircuit *ckt){ SOI3model *model = (SOI3model *)inModel; SOI3instance *here;/* All variables ending in 1 denote that they pertain to the model and so use model->SOI3tnom for temperature - the others use here->SOI3temp. REFTEMP is temp at which hard-coded quantities are given. */ double egfet,egfet1; /* Band Gap */ double fact1,fact2; /* temperature/REFTEMP */ double kt,kt1; /* kT @ various temps */ double arg1; /* ??? */ double ratio,ratio4; /* (temp/tnom) and (temp/tnom)^(3/2) */ double phio; /* temp adjusted phi PHI0*/ double pbo; double gmanew,gmaold; double capfact; double pbfact1,pbfact; /* ??? */ double vt,vtnom; double wkfngfs; /* work function difference phi(gate,Si) */ double wkfngf; /* work fn of front gate */ double wkfngbs; /* work fn diff of back gate = 0 usu. */ double fermig; /* fermi level of gate */ double fermis; /* fermi level of Si */ double xd_max; /* Minimum Si film thickness for this model to be valid */ double eta_s; /* JimB - new variables for improved threshold voltage conversion model. */ double Edelta0; double psi_delta0; /* loop through all the transistor models */ for( ; model != NULL; model = model->SOI3nextModel) { /* perform model defaulting */ if(!model->SOI3tnomGiven) { model->SOI3tnom = ckt->CKTnomTemp; } fact1 = model->SOI3tnom/REFTEMP; vtnom = model->SOI3tnom*CONSTKoverQ; kt1 = CONSTboltz * model->SOI3tnom; egfet1 = 1.16-(7.02e-4*model->SOI3tnom*model->SOI3tnom)/ (model->SOI3tnom+1108); arg1 = -egfet1/(kt1+kt1)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); /* this is -Egnom + Egref. - sign due to it being in bracket with log(fact1) 'cos we wanted log(1/fact1). */ pbfact1 = -2*vtnom *(1.5*log(fact1)+CHARGE*arg1); /* 2 comes from fact phi=2*phi_F ^ */ /* now model parameter preprocessing */ if(!model->SOI3frontOxideThicknessGiven || model->SOI3frontOxideThickness == 0 || !model->SOI3backOxideThicknessGiven || model->SOI3backOxideThickness == 0 || !model->SOI3bodyThicknessGiven || model->SOI3bodyThickness == 0) { (*(SPfrontEnd->IFerror))(ERR_FATAL, "%s: SOI3 device film thickness must be supplied", &model->SOI3modName); return(E_BADPARM); } else /* Oxide and film thicknesses are supplied. */ { model->SOI3frontOxideCapFactor = 3.9 * 8.854214871e-12/ model->SOI3frontOxideThickness; model->SOI3backOxideCapFactor = 3.9 * 8.854214871e-12/ model->SOI3backOxideThickness; model->SOI3bodyCapFactor = 11.7 * 8.854214871e-12/ model->SOI3bodyThickness; model->SOI3C_ssf = CHARGE*model->SOI3frontSurfaceStateDensity*1e4; model->SOI3C_ssb = CHARGE*model->SOI3backSurfaceStateDensity*1e4; eta_s = 1 + model->SOI3C_ssf/model->SOI3frontOxideCapFactor; if(!model->SOI3transconductanceGiven) { if(!model->SOI3surfaceMobilityGiven) { model->SOI3surfaceMobility=600; } model->SOI3transconductance = model->SOI3surfaceMobility * model->SOI3frontOxideCapFactor * 1e-4 /*(m**2/cm**2) for mobility */; } if(model->SOI3substrateDopingGiven) { /* work everything out */ if(model->SOI3substrateDoping*1e6 /*(cm**3/m**3)*/ >1.45e16) { if(!model->SOI3phiGiven) { model->SOI3phi = 2*vtnom* log(model->SOI3substrateDoping* 1e6/*(cm**3/m**3)*//1.45e16); model->SOI3phi = MAX(0.1,model->SOI3phi); }/* Now that we have ascertained both the doping * * and the body film thickness, check to see * * if we have a thick film device. If not, complain ! */ xd_max=2*sqrt((2* 11.7 * 8.854214871e-12 * model->SOI3phi)/ (CHARGE*1e6 /*(cm**3/m**3)*/ * model->SOI3substrateDoping)); if(model->SOI3bodyThickness < xd_max) { (*(SPfrontEnd->IFerror))(ERR_WARNING, "%s: Body Film thickness may be too small \nfor this model to be valid", &model->SOI3modName); /* return(E_PAUSE); don't want to stop, just issue a warning */ }/* End of thick film check - msll 21/2/94 Changed to only give warning - msll 31/10/95 */ if(!model->SOI3vfbFGiven) { if(!model->SOI3frontFixedChargeDensityGiven) model->SOI3frontFixedChargeDensity = 0; fermis = model->SOI3type * 0.5 * model->SOI3phi; wkfngf = 3.2; if(!model->SOI3gateTypeGiven) model->SOI3gateType=1; if(model->SOI3gateType != 0) { fermig = model->SOI3type *model->SOI3gateType*0.5*egfet1; wkfngf = 3.25 + 0.5 * egfet1 - fermig; } wkfngfs = wkfngf - (3.25 + 0.5 * egfet1 +fermis); /* Fixed oxide charge is normally +ve for both n and p-channel, so need -ve voltage to neutralise it */ model->SOI3vfbF = wkfngfs - model->SOI3frontFixedChargeDensity * 1e4 /*(cm**2/m**2)*/ * CHARGE/model->SOI3frontOxideCapFactor; } if(!model->SOI3vfbBGiven) { wkfngbs = (1-model->SOI3type)*0.5*model->SOI3phi; /* assume p-sub */ model->SOI3vfbB = wkfngbs - model->SOI3backFixedChargeDensity * 1e4 /*(cm**2/m**2)*/ * CHARGE/model->SOI3backOxideCapFactor; } if(!model->SOI3gammaGiven) { model->SOI3gamma = sqrt(2 * 11.70 * 8.854214871e-12 * CHARGE * model->SOI3substrateDoping * 1e6 /*(cm**3/m**3)*/)/model->SOI3frontOxideCapFactor; } if(!model->SOI3gammaBGiven) { model->SOI3gammaB = sqrt(2 * 11.70 * 8.854214871e-12 * CHARGE * model->SOI3substrateDoping * 1e6 /*(cm**3/m**3)*/)/model->SOI3backOxideCapFactor; } if(model->SOI3vt0Given) { /* NSUB given AND VT0 given - change vfbF */ model->SOI3vfbF = model->SOI3vt0 - model->SOI3type * (eta_s*model->SOI3phi + model->SOI3gamma*sqrt(model->SOI3phi)); } else { if(model->SOI3vtexGiven) { /* JimB - Improved threshold voltage conversion model. */ if (model->SOI3delta0 < 0) { model->SOI3delta0 = 0; } if (model->SOI3vdex < 0) { /* Use convention that Vd at which Vtex was extracted */ /* is always +ve. */ model->SOI3vdex = -model->SOI3vdex; } /* Exponential term delta*phiF/phit (SOI3phi = 2phiF) */ Edelta0 = exp(MIN(MAX_EXP_ARG, (model->SOI3delta0*model->SOI3phi)/(2*vtnom)) ); /* Modified surface potential term (2+delta)*phiF + vdex/2 */ /* (SOI3phi = 2phiF) */ psi_delta0 = ((2+model->SOI3delta0)*model->SOI3phi/2) + model->SOI3vdex/2; model->SOI3vfbF = model->SOI3vtex - model->SOI3type * (eta_s*psi_delta0 + model->SOI3gamma* sqrt(psi_delta0 + vtnom*Edelta0) ); } } } else /* Substrate doping less than intrinsic silicon, so set to zero. */ { model->SOI3substrateDoping = 0; (*(SPfrontEnd->IFerror))(ERR_FATAL, "%s: Nsub < Ni",&model->SOI3modName); return(E_BADPARM); } } else /* NSUB not given, have to assume that VT0, PHI and GAMMA are given */ { xd_max=(2* 11.7 * 8.854214871e-12*sqrt(model->SOI3phi))/ (model->SOI3gamma*model->SOI3frontOxideCapFactor); if(model->SOI3bodyThickness < xd_max) { (*(SPfrontEnd->IFerror))(ERR_WARNING, "%s :Body Film thickness may be too small \nfor this model to be valid", &model->SOI3modName); /* return(E_PAUSE); */ }/* End of thick film check - msll 21/2/94 Changed to only give warning - msll 31/10/95 */ /* If vtext given in netlist, but no vt0. */ if( (model->SOI3vtexGiven) && (!model->SOI3vt0Given) ) { /* JimB - Improved threshold voltage conversion model. */ if (model->SOI3delta0 < 0) { model->SOI3delta0 = 0; } if (model->SOI3vdex < 0) { /* Use convention that Vd at which Vtex was extracted */ /* is always +ve. */ model->SOI3vdex = -model->SOI3vdex; } /* Exponential term delta*phiF/phit (SOI3phi = 2phiF) */ Edelta0 = exp(MIN(MAX_EXP_ARG, (model->SOI3delta0*model->SOI3phi)/(2*vtnom)) ); /* Modified surface potential term (2+delta)*phiF + vdex/2 */ /* (SOI3phi = 2phiF) */ psi_delta0 = ((2+model->SOI3delta0)*model->SOI3phi/2) + model->SOI3vdex/2; model->SOI3vfbF = model->SOI3vtex - model->SOI3type * (eta_s*psi_delta0 + model->SOI3gamma* sqrt(psi_delta0 + vtnom*Edelta0) ); } else /* If no vtex, then use vt0, either netlist or default value. */ { /* Use standard threshold voltage model. */ model->SOI3vfbF = model->SOI3vt0 - model->SOI3type * (eta_s*model->SOI3phi + model->SOI3gamma*sqrt(model->SOI3phi)); } if (!model->SOI3vfbBGiven) { model->SOI3vfbB = 0; /* NSUB not given, vfbB not given */ } } } if((model->SOI3vsatGiven)&&(model->SOI3vsat != 0)) { model->SOI3TVF0 = 0.8*exp(model->SOI3tnom/600); } else { model->SOI3TVF0 = 0; } /* loop through all instances of the model */ for(here = model->SOI3instances; here!= NULL; here = here->SOI3nextInstance) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -