home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991 */
- /* By MicroSim Corporation, All Rights Reserved */
- /****************************************************************************/
- /* tmpupd.c
- * $Revision: 1.25 $
- * $Author: sv $
- * $Date: 28 Feb 1991 11:00:30 $ */
-
- #include "option1.h"
- #include "mserrors.h"
- #ifdef USE_DECL_ARGS
- void NewLine(int);
- #else
- void NewLine();
- #endif
-
- #define EGFET(temp) (1.16 - ( 7.02E-4 * temp*temp )/( temp + 1108 ))
- #define NAMELENGTH 10
-
- #define PRINT_NAME(name,len)\
- sprintf(junk,NameFormat,name),\
- fprintf(OutFile,"%s",junk),\
- len = strlen(junk)
-
- static char
- NameFormat[] = " %-8s ",
- SixParm[] = "%11s%11s%11s%11s%11s%11s\n",
- FiveParm[] = "%11s%11s%11s%11s%11s\n",
- FourParm[] = "%11s%11s%11s%11s\n",
- ThreeParm[] = "%11s%11s%11s\n",
- OneParm[] = "%11s\n",
- ModTitle[] = "\n\n\n **** %s MODEL PARAMETERS\n NAME %s\n",
- DevTitle0[] = " **** DEVICE PARAMETERS\n NAME %s\n",
- DevTitle1[] = "\n\n\n **** %s\n NAME VALUE\n",
- Spacer[] = " %s\n",
- B_Heading0[] = "VTO BETA IS VBI CGS CGD",
- B_Heading1[] = " RG RD RS",
- D_Heading[] = " IS VJ CJO RS IKF BV",
- J_Heading[] = "VTO BETA IS PB CGS CGD",
- M_Heading[] = "VTO PHI PB IS(JS) KP UO",
- Q_Heading0[] = " BF ISE VJE CJE RE RB ",
- Q_Heading1[] = " BR ISC VJC CJC RC RBM",
- Q_Heading2[] = " IS ISS VJS CJS";
-
- void Tmp1Mod( /* Update ONE model to a new temperature */
- Told, /* Temperature models have now */
- Tnew, /* Temperature models will have on exit */
- Id, /* Model type to be processed */
- Mloc1st, /* 1st model to be processed */
- OutFile, /* Output file for updated values */
- PrintHdr, /* YES: Print heading for first one */
- IsModel, /* NO: Mloc1st is device ptr not model ptr */
- mcanalysis /* NO: not running monte-carlo */
- )
- double Told, Tnew;
- int Id;
- struct Gen_ *Mloc1st;
- FILE *OutFile;
- int *PrintHdr, IsModel, mcanalysis;
-
- /*
- whjb 04 Oct 86 creation
- pwt 13 Oct 86 add semiconductor devices
- whjb 28 Nov 86 split off from TmpUpd
- pwt 29 Dec 87 take out update of "fc*pb" (M_fc is now just "fc")
- pwt 29 Feb 88 housekeeping
- pwt 01 Mar 88 add BJT substrate capacitor updates
- pwt 01 Mar 88 add BJT parasitic resistor updates
- pwt 02 Mar 88 add BJT substrate current updates
- pwt 11 Apr 88 modify JFET updates to include junction grading ("M")
- pwt 06 Oct 88 add various diode updates
- pwt 11 Sep 88 diode upgrade for BV
- pwt 12 Apr 90 add TriQuint upgrades to GaAsFET
- */
-
- { int len;
- struct Gen_ *mloc;
- char *modelname;
- char junk[MBUFF];
- double
- tnom = TNOM+CTOK,
- reftmp = 27+CTOK, /* explicitly 27'C */
- vtref = reftmp*BOLTZ/CHARGE,
- vt1 = Told*BOLTZ/CHARGE,
- eg = EGFET(Tnew),
- eg1 = EGFET(Told),
- egref = EGFET(reftmp),
- arg = egref/vtref - eg /VT,
- arg1 = egref/vtref - eg1/vt1,
- fact2 = Tnew/reftmp,
- fact1 = Told/reftmp,
- pbfact = -VT *( 3*log(fact2) + arg ),
- pbfat1 = -vt1*( 3*log(fact1) + arg1),
- t_dif = Tnew-Told,
- t_rat = Tnew/Told;
- /*
- * if IsModel == 0, we want only one model and are passing in a device
- * pointer not a model pointer
- */
- if (IsModel == 0) {
- struct gen_ *dloc = (struct gen_ *) Mloc1st;
-
- Mloc1st = dloc -> gen_model;
- modelname = Mloc1st -> Gen_name;
- }
- /*
- * Process each model structure for which temperature updating is done
- */
- for (mloc = Mloc1st;
- mloc != NULL ;
- mloc = NULL /*IsModel ? mloc->Gen_next : NULL*/) { /* only do 1 */
-
- if (IsModel != 0) {
- if (mloc -> Gen_nom != NULL && mcanalysis) continue;
- modelname = mloc -> Gen_name;
- }
-
- len = 0;
- switch (Id) {
-
- /*** GaAs MESFET ***/
-
- case 'B': {
- struct B_ *mod = (struct B_ *)mloc;
- double oldpb, pbo, gmaold, gmanew, pbrat, oldcjf, newcjf;
-
- #define VTO (mod->B_vto)
- #define VTO_TC (mod->B_vtotc)
- #define BETA (mod->B_beta)
- #define BETA_TCE (mod->B_betatce)
- #define EG (mod->B_eg)
- #define XTI (mod->B_xti)
- #define RG (mod->B_rg)
- #define RD (mod->B_rd)
- #define RS (mod->B_rs)
- #define TRG1 (mod->B_trg1)
- #define TRD1 (mod->B_trd1)
- #define TRS1 (mod->B_trs1)
- #define CGD (mod->B_cgd)
- #define CGS (mod->B_cgs)
- #define IS (mod->B_is)
- #define M (mod->B_m)
- #define N (mod->B_n)
- #define VBI (mod->B_vbi)
-
- VTO += VTO_TC*t_dif; /* VTO_TC is V/degree */
- BETA *= pow(1.01,BETA_TCE*t_dif); /* BETA_TCE is %/degree */
-
- IS *= exp( EG/(N*VT) * (t_rat-1) ) * pow(t_rat,XTI/N);
-
- /* update RS, RD, RS (which are stored as conductances) */
-
- RG *= 1 + (Told-tnom)*TRG1;
- RG /= 1 + (Tnew-tnom)*TRG1;
-
- RD *= 1 + (Told-tnom)*TRD1;
- RD /= 1 + (Tnew-tnom)*TRD1;
-
- RS *= 1 + (Told-tnom)*TRG1;
- RS /= 1 + (Tnew-tnom)*TRG1;
-
- /* calculate Cgs, Cgd & Vbi for Tref */
-
- oldpb = VBI;
- pbo = (VBI-pbfat1)/fact1;
- gmaold = (VBI-pbo)/pbo;
- oldcjf = 1 + M*(.0004*(Told-reftmp) - gmaold);
- CGS /= oldcjf;
- CGD /= oldcjf;
-
- /* calculate new Cgs, Cgd & Pb */
-
- VBI = FLOAT(fact2*pbo + pbfact);
- gmanew = (VBI-pbo)/pbo;
- newcjf = 1 + M*(.0004*(Tnew-reftmp) - gmanew);
- CGS *= newcjf;
- CGD *= newcjf;
-
- pbrat = VBI/oldpb;
-
- mod->B_fc *= pbrat; /* really fc*pb */
- mod->B_f1 *= pbrat;
-
- mod->B_vcrit = N*VT*log(N*VT/(IS*ROOT2));
-
- if (OutFile != NULL) {
- if (*PrintHdr) {
- *PrintHdr = NO;
- if (IsModel) fprintf(OutFile,ModTitle,"GaAsFET",B_Heading0);
- else fprintf(OutFile,DevTitle0,B_Heading0);
- fprintf(OutFile,Spacer,B_Heading1);
- }
- PRINT_NAME(modelname,len);
- if (len > NAMELENGTH) NewLine(NAMELENGTH);
-
- fprintf(OutFile,SixParm,
- FmtFlt(VTO,FMTE,3),FmtFlt(BETA,FMTE,3),
- FmtFlt(IS,FMTE,3),FmtFlt(VBI,FMTE,3),
- FmtFlt(CGS,FMTE,3),FmtFlt(CGD,FMTE,3));
-
- fprintf(OutFile,NameFormat,"");
- fprintf(OutFile,ThreeParm,
- FmtFlt((double)RG==0.?0.:1/RG,FMTE,3),
- FmtFlt((double)RD==0.?0.:1/RD,FMTE,3),
- FmtFlt((double)RS==0.?0.:1/RS,FMTE,3));
- }
-
- #undef VTO
- #undef VTO_TC
- #undef BETA
- #undef BETA_TCE
- #undef CGD
- #undef CGS
- #undef IS
- #undef M
- #undef N
- #undef VBI
- #undef RS
- #undef EG
- #undef XTI
-
- break;
- }
-
- /*** Diodes ***/
-
- case 'D': {
- struct D_ *mod = (struct D_ *)mloc;
- double oldpb, pbo, gmaold, gmanew, pbrat;
-
- #define BV (mod->D_bv)
- #define CJO (mod->D_cjo)
- #define EG (mod->D_eg)
- #define IKF (mod->D_ikf)
- #define IS (mod->D_is)
- #define ISR (mod->D_isr)
- #define M (mod->D_m)
- #define N (mod->D_n)
- #define NR (mod->D_nr)
- #define RS (mod->D_rs)
- #define VJ (mod->D_vj)
- #define XTI (mod->D_xti)
-
- IS *= exp( EG/(N*VT) * (t_rat-1) ) * pow( t_rat, XTI/N);
- ISR *= exp( EG/(NR*VT)* (t_rat-1) ) * pow( t_rat, XTI/NR);
-
- /* update RS, IKF, and BV */
-
- RS *= 1 + (Told-tnom)*(mod->D_trs1 + (Tnew-tnom)*mod->D_trs2);
- RS /= 1 + (Tnew-tnom)*(mod->D_trs1 + (Tnew-tnom)*mod->D_trs2);
-
- IKF /= 1 + (Told-tnom)*mod->D_tikf;
- IKF *= 1 + (Tnew-tnom)*mod->D_tikf;
-
- BV /= 1 + (Told-tnom)*(mod->D_tbv1 + (Tnew-tnom)*mod->D_tbv2);
- BV *= 1 + (Tnew-tnom)*(mod->D_tbv1 + (Tnew-tnom)*mod->D_tbv2);
-
- /* calculate Cjo & Vj for Tref */
-
- oldpb = VJ;
- pbo = (VJ-pbfat1)/fact1;
- gmaold = (VJ-pbo)/pbo;
- CJO /= 1 + M*(.0004*(Told-reftmp) - gmaold);
-
- /* calculate new Cjo & Vj */
-
- VJ = FLOAT(fact2*pbo + pbfact);
- gmanew = (VJ-pbo)/pbo;
- CJO *= 1 + M*(.0004*(Tnew-reftmp) - gmanew);
- pbrat = VJ/oldpb;
-
- mod->D_fc *= pbrat; /* really fc*vj */
- mod->D_f1 *= pbrat;
-
- mod->D_vcrit = N*VT*log(N*VT/(IS*ROOT2));
-
- if (OutFile != NULL) {
- if (*PrintHdr) {
- *PrintHdr = NO;
- if (IsModel) fprintf(OutFile,ModTitle,"DIODE",D_Heading);
- else fprintf(OutFile,DevTitle0,D_Heading);
- }
- PRINT_NAME(modelname,len);
- if (len > NAMELENGTH) NewLine(NAMELENGTH);
- fprintf(OutFile,SixParm,
- FmtFlt(IS,FMTE,3),
- FmtFlt(VJ,FMTE,3),
- FmtFlt(CJO,FMTE,3),
- FmtFlt((double)RS==0.?0.:1/RS,FMTE,3),
- FmtFlt(IKF,FMTE,3),
- (double)BV==0.?"":FmtFlt(BV,FMTE,3)); /* don't print if 0 */
- }
-
- #undef BV
- #undef CJO
- #undef EG
- #undef IKF
- #undef IS
- #undef ISR
- #undef M
- #undef N
- #undef NR
- #undef RS
- #undef VJ
- #undef XTI
-
- break;
- }
-
- /*** Junction FET ***/
-
- case 'J': {
- struct J_ *mod = (struct J_ *)mloc;
- double oldpb, pbo, gmaold, gmanew, pbrat, oldcjf, newcjf;
-
- #define VTO (mod->J_vto)
- #define VTO_TC (mod->J_vtotc)
- #define BETA (mod->J_beta)
- #define BETA_TCE (mod->J_betatce)
- #define CGD (mod->J_cgd)
- #define CGS (mod->J_cgs)
- #define M (mod->J_m)
- #define N (mod->J_n)
- #define PB (mod->J_pb)
- #define IS (mod->J_is)
- #define XTI (mod->J_xti)
-
- VTO += VTO_TC*t_dif; /* VTO_TC is V/degree */
- BETA *= pow(1.01,BETA_TCE*t_dif); /* BETA_TCE is %/degree */
- IS *= exp(1.11/(N*VT) * (t_rat-1) ) * pow( t_rat, XTI/N);
-
- /* calculate Cgs, Cgd & Pb for Tref */
-
- oldpb = PB;
- pbo = (PB-pbfat1)/fact1;
- gmaold = (PB-pbo)/pbo;
- oldcjf = 1 + M*(.0004*(Told-reftmp) - gmaold);
- CGS /= oldcjf;
- CGD /= oldcjf;
-
- /* calculate new Cgs, Cgd & Pb */
-
- PB = FLOAT(fact2*pbo + pbfact);
- gmanew = (PB-pbo)/pbo;
- newcjf = 1 + M*(.0004*(Tnew-reftmp) - gmanew);
- CGS *= newcjf;
- CGD *= newcjf;
-
- pbrat = PB/oldpb;
-
- mod->J_fc *= pbrat; /* really fc*pb */
- mod->J_f1 *= pbrat;
-
- mod->J_vcrit = VT*log(VT/(IS*ROOT2));
-
- if (OutFile != NULL) {
- if (*PrintHdr) {
- *PrintHdr = NO;
- if (IsModel) fprintf(OutFile,ModTitle,"JFET",J_Heading);
- else fprintf(OutFile,DevTitle0,J_Heading);
- }
- PRINT_NAME(modelname,len);
- if (len > NAMELENGTH) NewLine(NAMELENGTH);
- fprintf(OutFile,SixParm,
- FmtFlt(VTO,FMTE,3),FmtFlt(BETA,FMTE,3),
- FmtFlt(IS,FMTE,3),FmtFlt(PB,FMTE,3),
- FmtFlt(CGS,FMTE,3),FmtFlt(CGD,FMTE,3));
- }
-
- #undef VTO
- #undef VTO_TC
- #undef BETA
- #undef BETA_TCE
- #undef CGD
- #undef CGS
- #undef IS
- #undef M
- #undef N
- #undef PB
- #undef XTI
-
- break;
- }
-
- /*** MOSFET ***/
-
- case 'M': {
- struct M_ *mod = (struct M_ *)mloc;
- double pbo, oldphi, phio, gmaold, gmanew,
- coeold, coenew, vfb, isat,
- rat3on2 = t_rat * sqrt(t_rat);
-
- #define IS (mod->M_is)
- #define JS (mod->M_js)
- #define JSSW (mod->M_jssw)
- #define KP (mod->M_kp)
- #define MJ (mod->M_mj)
- #define MJSW (mod->M_mjsw)
- #define PB (mod->M_pb)
- #define PBSW (mod->M_pbsw)
- #define PHI (mod->M_phi)
- #define TYPE (mod->M_type)
- #define UO (mod->M_uo)
- #define VBI (mod->M_vbi)
- #define VTO (mod->M_vto)
-
- KP /= rat3on2;
- UO /= rat3on2;
-
- oldphi = PHI;
- phio = (PHI-pbfat1)/fact1;
- PHI = FLOAT(fact2*phio + pbfact);
-
- vfb = VBI - .5*TYPE*oldphi;
- vfb += .5*( eg1 - eg );
- VBI = vfb + .5*TYPE*PHI;
-
- VTO = FLOAT(VBI + TYPE*(mod->M_gamma)*sqrt(PHI));
-
- { double tmp = exp( eg1/vt1 - eg/VT );
-
- IS *= tmp;
- JS *= tmp;
- JSSW *= tmp;
- }
-
- pbo = (PBSW-pbfat1)/fact1;
- PBSW = FLOAT(fact2*pbo + pbfact);
-
- pbo = (PB-pbfat1)/fact1;
- gmaold = (PB-pbo)/pbo;
- coeold = 1 + MJ*(.0004*(Told-reftmp) - gmaold);
- mod->M_cbd /= coeold;
- mod->M_cbs /= coeold;
- mod->M_cj /= coeold;
- mod->M_cjsw /= 1 + MJSW*(.0004*(Told-reftmp) - gmaold);
-
- PB = FLOAT(fact2*pbo + pbfact);
- gmanew = (PB-pbo)/pbo;
- coenew = 1 + MJ*(.0004*(Tnew-reftmp) - gmanew);
- mod->M_cbd *= coenew;
- mod->M_cbs *= coenew;
- mod->M_cj *= coenew;
- mod->M_cjsw *= 1 + MJSW*(.0004*(Tnew-reftmp) - gmanew);
-
- isat = MAX(IS,JS);
-
- if (OutFile != NULL) {
- if (*PrintHdr) {
- *PrintHdr = NO;
- if (IsModel) fprintf(OutFile,ModTitle,"MOSFET",M_Heading);
- else fprintf(OutFile,DevTitle0,M_Heading);
- }
- PRINT_NAME(modelname,len);
- if (len > NAMELENGTH) NewLine(NAMELENGTH);
- fprintf(OutFile,SixParm,
- FmtFlt(VTO,FMTE,3),FmtFlt(PHI,FMTE,3),FmtFlt(PB,FMTE,3),
- FmtFlt(isat,FMTE,3),FmtFlt(KP,FMTE,3),FmtFlt(1e4*UO,FMTE,3));
- }
-
- #undef IS
- #undef JS
- #undef JSSW
- #undef KP
- #undef MJ
- #undef MJSW
- #undef PB
- #undef PBSW
- #undef PHI
- #undef TYPE
- #undef UO
- #undef VBI
- #undef VTO
-
- break;
- }
-
- /*** Bipolar transistor ***/
-
- case 'Q': {
- struct Q_ *mod = (struct Q_ *)mloc;
- double oldpb, pbo, gmaold, gmanew, pbrat, bfactr;
-
- #define BF (mod->Q_bf)
- #define BR (mod->Q_br)
- #define CJC (mod->Q_cjc)
- #define CJE (mod->Q_cje)
- #define CJS (mod->Q_cjs)
- #define EG (mod->Q_eg)
- #define IS (mod->Q_is)
- #define ISC (mod->Q_isc)
- #define ISE (mod->Q_ise)
- #define ISS (mod->Q_iss)
- #define MJC (mod->Q_mjc)
- #define MJE (mod->Q_mje)
- #define MJS (mod->Q_mjs)
- #define NC (mod->Q_nc)
- #define NE (mod->Q_ne)
- #define NS (mod->Q_ns)
- #define RB (mod->Q_rb)
- #define RBM (mod->Q_rbm)
- #define RC (mod->Q_rc)
- #define RE (mod->Q_re)
- #define VJC (mod->Q_vjc)
- #define VJE (mod->Q_vje)
- #define VJS (mod->Q_vjs)
- #define XTB (mod->Q_xtb)
- #define XTI (mod->Q_xti)
-
- IS *= exp( EG/VT *(t_rat-1) ) * pow( t_rat, XTI);
- ISC *= exp( EG/(NC*VT)*(t_rat-1) ) * pow( t_rat, XTI/NC);
- ISE *= exp( EG/(NE*VT)*(t_rat-1) ) * pow( t_rat, XTI/NE);
- ISS *= exp( EG/(NS*VT)*(t_rat-1) ) * pow( t_rat, XTI/NS);
-
- bfactr = pow( t_rat, XTB);
- BF *= bfactr;
- BR *= bfactr;
- ISC /= bfactr;
- ISE /= bfactr;
- ISS /= bfactr;
-
- mod->Q_vcrit = VT*log(VT/(IS*ROOT2));
-
- /* calculate Cjc & Vjc for Tref */
-
- oldpb = VJC;
- pbo = (VJC-pbfat1)/fact1;
- gmaold = (VJC-pbo)/pbo;
- CJC /= 1 + MJC*(.0004*(Told-reftmp) - gmaold);
-
- /* calculate new Cjc & Vjc */
-
- VJC = FLOAT(fact2*pbo + pbfact);
- gmanew = (VJC-pbo)/pbo;
- CJC *= 1 + MJC*(.0004*(Tnew-reftmp) - gmanew);
-
- pbrat = VJC/oldpb;
- mod->Q_fcpc *= pbrat;
- mod->Q_f1bc *= pbrat;
-
- /* calculate Cje & Vje for Tref */
-
- oldpb = VJE;
- pbo = (VJE-pbfat1)/fact1;
- gmaold = (VJE-pbo)/pbo;
- CJE /= 1 + MJE*(.0004*(Told-reftmp) - gmaold);
-
- /* calculate new Cje & Vje */
-
- VJE = FLOAT(fact2*pbo + pbfact);
- gmanew = (VJE-pbo)/pbo;
- CJE *= 1 + MJE*(.0004*(Tnew-reftmp) - gmanew);
-
- pbrat = VJE/oldpb;
- mod->Q_fcpe *= pbrat;
- mod->Q_f1be *= pbrat;
-
- /* calculate Cjs & Vjs for Tref */
-
- pbo = (VJS-pbfat1)/fact1;
- gmaold = (VJS-pbo)/pbo;
- CJS /= 1 + MJS*(.0004*(Told-reftmp) - gmaold);
-
- /* calculate new Cjs & Vjs */
-
- VJS = FLOAT(fact2*pbo + pbfact);
- gmanew = (VJS-pbo)/pbo;
- CJS *= 1 + MJS*(.0004*(Tnew-reftmp) - gmanew);
-
- /* update parasitic resistance values */
-
- RB /= 1 + (Told-tnom)*(mod->Q_trb1 + (Told-tnom)*mod->Q_trb2);
- RB *= 1 + (Tnew-tnom)*(mod->Q_trb1 + (Tnew-tnom)*mod->Q_trb2);
-
- RBM /= 1 + (Told-tnom)*(mod->Q_trm1 + (Told-tnom)*mod->Q_trm2);
- RBM *= 1 + (Tnew-tnom)*(mod->Q_trm1 + (Tnew-tnom)*mod->Q_trm2);
-
- /* these parasitic resistors' values are stored as conductances */
-
- RC *= 1 + (Told-tnom)*(mod->Q_trc1 + (Told-tnom)*mod->Q_trc2);
- RC /= 1 + (Tnew-tnom)*(mod->Q_trc1 + (Tnew-tnom)*mod->Q_trc2);
-
- RE *= 1 + (Told-tnom)*(mod->Q_tre1 + (Told-tnom)*mod->Q_tre2);
- RE /= 1 + (Tnew-tnom)*(mod->Q_tre1 + (Tnew-tnom)*mod->Q_tre2);
-
- if (OutFile != NULL) {
- if (*PrintHdr) {
- *PrintHdr = NO;
- if (IsModel) fprintf(OutFile,ModTitle,"BJT",Q_Heading0);
- else fprintf(OutFile,DevTitle0,Q_Heading0);
- fprintf(OutFile,Spacer,Q_Heading1);
- fprintf(OutFile,Spacer,Q_Heading2);
- }
- PRINT_NAME(modelname,len);
- if (len > NAMELENGTH) NewLine(NAMELENGTH);
-
- fprintf(OutFile,SixParm,FmtFlt(BF,FMTE,3),
- FmtFlt(ISE,FMTE,3),FmtFlt(VJE,FMTE,3),FmtFlt(CJE,FMTE,3),
- FmtFlt((double)RE==0.?0.:1/RE,FMTE,3),FmtFlt(RB,FMTE,3));
-
- fprintf(OutFile,NameFormat,"");
- fprintf(OutFile,SixParm,FmtFlt(BR,FMTE,3),
- FmtFlt(ISC,FMTE,3),FmtFlt(VJC,FMTE,3),FmtFlt(CJC,FMTE,3),
- FmtFlt((double)RC==0.?0.:1/RC,FMTE,3),FmtFlt(RBM,FMTE,3));
-
- fprintf(OutFile,NameFormat,"");
- fprintf(OutFile,FourParm,FmtFlt(IS,FMTE,3),
- FmtFlt(ISS,FMTE,3),FmtFlt(VJS,FMTE,3),FmtFlt(CJS,FMTE,3));
- }
-
- #undef BF
- #undef BR
- #undef CJC
- #undef CJE
- #undef CJS
- #undef EG
- #undef IS
- #undef ISC
- #undef ISE
- #undef ISS
- #undef MJC
- #undef MJE
- #undef MJS
- #undef NC
- #undef NE
- #undef NS
- #undef RB
- #undef RBM
- #undef RC
- #undef RE
- #undef VJC
- #undef VJE
- #undef VJS
- #undef XTB
- #undef XTI
-
- break;
- }
-
- /* end-of-models */
-
- }
- }
- } /* done */
-
- void Tmp1Dev( /* Update ONE device to a new temperature */
- Told, /* Temperature models have now */
- Tnew, /* Temperature models will have on exit */
- Id, /* Device type to be processed */
- Dloc1st, /* 1st device to be processed */
- OutFile, /* Output file for updated values */
- PrintHdr /* YES: print header */
- )
- double Told, Tnew;
- int Id;
- struct gen_ *Dloc1st;
- FILE *OutFile;
- int *PrintHdr;
-
- /*
- whjb 28 Nov 86 split off from TmpUpd
- pwt 29 Feb 88 re-work resistor updates so dev->r_g is working value
- pwt 21 Mar 88 fix cap. & ind. to include model scaling in printout
- */
-
- { int len;
- struct gen_ *dloc;
- char junk[MBUFF];
- char *zero_val_msg =
- "This device scales to 0.0 at this temperature";
- double
- tnom = TNOM+CTOK,
- vt1 = Told*BOLTZ/CHARGE,
- eg = EGFET(Tnew),
- eg1 = EGFET(Told),
- factor = exp( eg1/vt1 - eg/VT );
-
- /*
- * Process each device structure for which temperature updating is done
- */
- for ( dloc = Dloc1st;
- dloc != NULL;
- dloc = /*dloc->gen_next*/ NULL ) { /* only do 1 */
-
- switch (Id) {
-
- /*** Capacitors ***/
- /* needs work similar to resistor; i.e. maintaining two values, one that
- was read in, and one for the current operating temperature. May wait
- until device temperatures can vary independently. */
-
- case 'C': {
- struct c_ *dev = (struct c_ *)dloc;
- struct C_ *mod = dev->c_model;
-
- if ( mod == NULL ) break; /* !!! no model */
-
- dev->c_c /= 1 + (Told-tnom)*(mod->C_tc1 + (Told-tnom)*mod->C_tc2);
- dev->c_c *= 1 + (Tnew-tnom)*(mod->C_tc1 + (Tnew-tnom)*mod->C_tc2);
-
- if (OutFile != NULL) {
- if (*PrintHdr) {
- *PrintHdr = NO;
- fprintf(OutFile,DevTitle1,"CAPACITORS");
- }
- PRINT_NAME(dev->c_name,len);
- if (len > NAMELENGTH) NewLine(NAMELENGTH);
- fprintf(OutFile,OneParm,FmtFlt(dev->c_c*mod->C_c,FMTE,3));
- }
-
- break;
- }
-
- /*** Inductors ***/
- /* needs work similar to resistor; i.e. maintaining two values, one that
- was read in, and one for the current operating temperature. May wait
- until device temperatures can vary independently. */
-
- case 'L': {
- struct l_ *dev = (struct l_ *)dloc;
- struct L_ *mod = dev->l_model;
-
- if ( mod == NULL ) break; /* !!! no model */
-
- dev->l_l /= 1 + (Told-tnom)*(mod->L_tc1 + (Told-tnom)*mod->L_tc2);
- dev->l_l *= 1 + (Tnew-tnom)*(mod->L_tc1 + (Tnew-tnom)*mod->L_tc2);
-
- if (OutFile != NULL) {
- if (*PrintHdr) {
- *PrintHdr = NO;
- fprintf(OutFile,DevTitle1,"INDUCTORS");
- }
- PRINT_NAME(dev->l_name,len);
- if (len > NAMELENGTH) NewLine(NAMELENGTH);
- fprintf(OutFile,OneParm,FmtFlt(dev->l_l*mod->L_l,FMTE,3));
- }
- break;
- }
-
- /*** MOS transistors ***/
-
- case 'M': {
- struct m_ *dev = (struct m_ *)dloc;
-
- /* update drain and source saturation currents */
-
- dev->m_idsat *= factor;
- dev->m_issat *= factor;
-
- break;
- }
-
- /*** Resistors ***/
-
- case 'R': {
- double tc1, tc2, scale;
- struct r_ *dev = (struct r_ *)dloc;
- struct R_ *mod = dev->r_model;
-
- if (mod != NULL || dev->r_tc1 != 0.0 || dev->r_tc2 != 0.0) {
-
- /* exp coefficient */
-
- if (mod != NULL && DOUBLE(mod->R_tce) != 0.) {
- dev->r_r /= pow( 1.01, (Told-tnom)*mod->R_tce);
- dev->r_r *= pow( 1.01, (Tnew-tnom)*mod->R_tce);
- scale = mod->R_r;
- }
- else { /* linear and quadratic coefficients */
- if (mod == NULL) {
- tc1 = dev->r_tc1;
- tc2 = dev->r_tc2;
- scale = 1.;
- }
- else {
- tc1 = mod->R_tc1;
- tc2 = mod->R_tc2;
- scale = mod->R_r;
- }
- dev->r_r /= 1 + (Told-tnom)*(tc1 + (Told-tnom)*tc2);
- dev->r_r *= 1 + (Tnew-tnom)*(tc1 + (Tnew-tnom)*tc2);
- }
- dev->r_r = MAX(dev->r_r,1e-20);
-
- if (OutFile != NULL) {
- if (*PrintHdr) {
- *PrintHdr = NO;
- fprintf(OutFile,DevTitle1,"RESISTORS");
- }
- PRINT_NAME(dev->r_name,len);
- if (len > NAMELENGTH) NewLine(NAMELENGTH);
- if ( dev->r_r == 1e-20 ) {
- SimError(FATAL_ERROR,zero_val_msg);
- }
- else
- fprintf(OutFile,OneParm,FmtFlt(dev->r_r * scale,FMTE,3));
- }
- } /* end of if(model exists or device tc's!=0) */
- break;
- }
- } /* end of device switch */
- } /* end of device loop */
- } /* done */