home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 13 / 13.iso / p / p064 / 3.ddi / TMPUPD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-01  |  22.6 KB  |  805 lines

  1. /****************************************************************************/
  2. /*        Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991                  */
  3. /*          By MicroSim Corporation, All Rights Reserved                    */
  4. /****************************************************************************/
  5. /* tmpupd.c
  6.  *   $Revision:   1.25  $
  7.  *   $Author:   sv  $
  8.  *   $Date:   28 Feb 1991 11:00:30  $ */
  9.  
  10. #include "option1.h"
  11. #include "mserrors.h"
  12. #ifdef USE_DECL_ARGS
  13. void NewLine(int);
  14. #else
  15. void NewLine();
  16. #endif
  17.  
  18. #define EGFET(temp)    (1.16 - ( 7.02E-4 * temp*temp )/( temp + 1108 ))
  19. #define NAMELENGTH    10
  20.  
  21. #define PRINT_NAME(name,len)\
  22.     sprintf(junk,NameFormat,name),\
  23.     fprintf(OutFile,"%s",junk),\
  24.     len = strlen(junk)
  25.  
  26. static char
  27.   NameFormat[]     = " %-8s ",
  28.   SixParm[]    = "%11s%11s%11s%11s%11s%11s\n",
  29.   FiveParm[]    = "%11s%11s%11s%11s%11s\n",
  30.   FourParm[]    = "%11s%11s%11s%11s\n",
  31.   ThreeParm[]    = "%11s%11s%11s\n",
  32.   OneParm[]    = "%11s\n",
  33.   ModTitle[]    = "\n\n\n **** %s MODEL PARAMETERS\n NAME         %s\n",
  34.   DevTitle0[]    = " **** DEVICE PARAMETERS\n NAME         %s\n",
  35.   DevTitle1[]    = "\n\n\n **** %s\n NAME        VALUE\n",
  36.   Spacer[]    = "              %s\n",
  37.   B_Heading0[]    = "VTO       BETA         IS        VBI        CGS        CGD",
  38.   B_Heading1[]    = " RG         RD         RS",
  39.   D_Heading[]    = " IS         VJ        CJO         RS        IKF         BV",
  40.   J_Heading[]    = "VTO       BETA         IS         PB        CGS        CGD",
  41.   M_Heading[]    = "VTO        PHI         PB      IS(JS)        KP         UO",
  42.   Q_Heading0[]    = " BF        ISE        VJE        CJE         RE        RB ",
  43.   Q_Heading1[]    = " BR        ISC        VJC        CJC         RC        RBM",
  44.   Q_Heading2[]    = " IS        ISS        VJS        CJS";
  45.  
  46. void Tmp1Mod(    /* Update ONE model to a new temperature */
  47.   Told,        /* Temperature models have now */
  48.   Tnew,        /* Temperature models will have on exit */
  49.   Id,        /* Model type to be processed */
  50.   Mloc1st,    /* 1st model to be processed */
  51.   OutFile,    /* Output file for updated values */
  52.   PrintHdr,    /* YES: Print heading for first one */
  53.   IsModel,    /* NO: Mloc1st is device ptr not model ptr */
  54.   mcanalysis    /* NO: not running monte-carlo */
  55.   )
  56. double    Told, Tnew;
  57. int    Id;
  58. struct Gen_ *Mloc1st;
  59. FILE    *OutFile;
  60. int    *PrintHdr, IsModel, mcanalysis;
  61.  
  62. /*
  63. whjb    04 Oct 86    creation
  64. pwt    13 Oct 86    add semiconductor devices
  65. whjb    28 Nov 86    split off from TmpUpd
  66. pwt    29 Dec 87    take out update of "fc*pb" (M_fc is now just "fc")
  67. pwt    29 Feb 88    housekeeping
  68. pwt    01 Mar 88    add BJT substrate capacitor updates
  69. pwt    01 Mar 88    add BJT parasitic resistor updates
  70. pwt    02 Mar 88    add BJT substrate current updates
  71. pwt    11 Apr 88    modify JFET updates to include junction grading ("M")
  72. pwt    06 Oct 88    add various diode updates
  73. pwt    11 Sep 88    diode upgrade for BV
  74. pwt    12 Apr 90    add TriQuint upgrades to GaAsFET
  75. */
  76.  
  77. { int len;
  78.   struct Gen_ *mloc;
  79.   char *modelname;
  80.   char junk[MBUFF];
  81.   double
  82.     tnom   = TNOM+CTOK,
  83.     reftmp = 27+CTOK,    /* explicitly 27'C */
  84.     vtref  = reftmp*BOLTZ/CHARGE,
  85.     vt1    = Told*BOLTZ/CHARGE,
  86.     eg     = EGFET(Tnew),
  87.     eg1    = EGFET(Told),
  88.     egref  = EGFET(reftmp),
  89.     arg    = egref/vtref - eg /VT,
  90.     arg1   = egref/vtref - eg1/vt1,
  91.     fact2  = Tnew/reftmp,
  92.     fact1  = Told/reftmp,
  93.     pbfact = -VT *( 3*log(fact2) + arg ),
  94.     pbfat1 = -vt1*( 3*log(fact1) + arg1),
  95.     t_dif  = Tnew-Told,
  96.     t_rat  = Tnew/Told;
  97. /*
  98.  * if IsModel == 0, we want only one model and are passing in a device
  99.  * pointer not a model pointer
  100.  */
  101.   if (IsModel == 0) {
  102.     struct gen_ *dloc = (struct gen_ *) Mloc1st;
  103.  
  104.     Mloc1st = dloc -> gen_model;
  105.     modelname = Mloc1st -> Gen_name;
  106.     }
  107. /*
  108.  * Process each model structure for which temperature updating is done
  109.  */
  110.   for (mloc = Mloc1st;
  111.        mloc != NULL ;
  112.        mloc = NULL /*IsModel ? mloc->Gen_next  : NULL*/) {    /* only do 1 */
  113.  
  114.     if (IsModel != 0) {
  115.       if (mloc -> Gen_nom != NULL && mcanalysis) continue;
  116.       modelname = mloc -> Gen_name;
  117.       }
  118.  
  119.     len = 0;
  120.     switch (Id) {
  121.  
  122. /*** GaAs MESFET ***/
  123.  
  124.       case 'B': {
  125.         struct B_ *mod = (struct B_ *)mloc;
  126.         double oldpb, pbo, gmaold, gmanew, pbrat, oldcjf, newcjf;
  127.  
  128. #define VTO    (mod->B_vto)
  129. #define VTO_TC    (mod->B_vtotc)
  130. #define BETA    (mod->B_beta)
  131. #define BETA_TCE    (mod->B_betatce)
  132. #define EG    (mod->B_eg)
  133. #define XTI    (mod->B_xti)
  134. #define RG    (mod->B_rg)
  135. #define RD    (mod->B_rd)
  136. #define RS    (mod->B_rs)
  137. #define TRG1    (mod->B_trg1)
  138. #define TRD1    (mod->B_trd1)
  139. #define TRS1    (mod->B_trs1)
  140. #define CGD    (mod->B_cgd)
  141. #define CGS    (mod->B_cgs)
  142. #define IS    (mod->B_is)
  143. #define M    (mod->B_m)
  144. #define N    (mod->B_n)
  145. #define VBI    (mod->B_vbi)
  146.  
  147.         VTO  += VTO_TC*t_dif;            /* VTO_TC is V/degree */
  148.         BETA *= pow(1.01,BETA_TCE*t_dif);    /* BETA_TCE is %/degree */
  149.  
  150.         IS   *= exp( EG/(N*VT) * (t_rat-1) ) * pow(t_rat,XTI/N);
  151.  
  152. /* update RS, RD, RS (which are stored as conductances) */
  153.  
  154.         RG *= 1 + (Told-tnom)*TRG1;
  155.         RG /= 1 + (Tnew-tnom)*TRG1;
  156.  
  157.         RD *= 1 + (Told-tnom)*TRD1;
  158.         RD /= 1 + (Tnew-tnom)*TRD1;
  159.  
  160.         RS *= 1 + (Told-tnom)*TRG1;
  161.         RS /= 1 + (Tnew-tnom)*TRG1;
  162.  
  163. /* calculate Cgs, Cgd & Vbi for Tref */
  164.  
  165.         oldpb  =  VBI;
  166.         pbo    = (VBI-pbfat1)/fact1;
  167.         gmaold = (VBI-pbo)/pbo;
  168.         oldcjf = 1 + M*(.0004*(Told-reftmp) - gmaold);
  169.         CGS   /= oldcjf;
  170.         CGD   /= oldcjf;
  171.  
  172. /* calculate new Cgs, Cgd & Pb */
  173.  
  174.         VBI     = FLOAT(fact2*pbo + pbfact);
  175.         gmanew = (VBI-pbo)/pbo;
  176.         newcjf = 1 + M*(.0004*(Tnew-reftmp) - gmanew);
  177.         CGS   *= newcjf;
  178.         CGD   *= newcjf;
  179.  
  180.         pbrat  = VBI/oldpb;
  181.  
  182.         mod->B_fc *= pbrat;        /* really fc*pb */
  183.         mod->B_f1 *= pbrat;
  184.  
  185.         mod->B_vcrit = N*VT*log(N*VT/(IS*ROOT2));
  186.  
  187.         if (OutFile != NULL) {
  188.           if (*PrintHdr) {
  189.             *PrintHdr = NO;
  190.             if (IsModel) fprintf(OutFile,ModTitle,"GaAsFET",B_Heading0);
  191.             else         fprintf(OutFile,DevTitle0,B_Heading0);
  192.             fprintf(OutFile,Spacer,B_Heading1);
  193.             }
  194.           PRINT_NAME(modelname,len);
  195.           if (len > NAMELENGTH) NewLine(NAMELENGTH);
  196.  
  197.           fprintf(OutFile,SixParm,
  198.             FmtFlt(VTO,FMTE,3),FmtFlt(BETA,FMTE,3),
  199.             FmtFlt(IS,FMTE,3),FmtFlt(VBI,FMTE,3),
  200.             FmtFlt(CGS,FMTE,3),FmtFlt(CGD,FMTE,3));
  201.  
  202.           fprintf(OutFile,NameFormat,"");
  203.           fprintf(OutFile,ThreeParm,
  204.             FmtFlt((double)RG==0.?0.:1/RG,FMTE,3),
  205.             FmtFlt((double)RD==0.?0.:1/RD,FMTE,3),
  206.             FmtFlt((double)RS==0.?0.:1/RS,FMTE,3));
  207.           }
  208.  
  209. #undef VTO
  210. #undef VTO_TC
  211. #undef BETA
  212. #undef BETA_TCE
  213. #undef CGD
  214. #undef CGS
  215. #undef IS
  216. #undef M
  217. #undef N
  218. #undef VBI
  219. #undef RS
  220. #undef EG
  221. #undef XTI
  222.  
  223.         break;
  224.         }
  225.  
  226. /*** Diodes ***/
  227.  
  228.       case 'D': {
  229.         struct D_ *mod = (struct D_ *)mloc;
  230.         double oldpb, pbo, gmaold, gmanew, pbrat;
  231.  
  232. #define BV    (mod->D_bv)
  233. #define CJO    (mod->D_cjo)
  234. #define EG    (mod->D_eg)
  235. #define IKF    (mod->D_ikf)
  236. #define IS    (mod->D_is)
  237. #define ISR    (mod->D_isr)
  238. #define M    (mod->D_m)
  239. #define N    (mod->D_n)
  240. #define NR    (mod->D_nr)
  241. #define RS    (mod->D_rs)
  242. #define VJ    (mod->D_vj)
  243. #define XTI    (mod->D_xti)
  244.  
  245.         IS  *= exp( EG/(N*VT) * (t_rat-1) ) * pow( t_rat, XTI/N);
  246.         ISR *= exp( EG/(NR*VT)* (t_rat-1) ) * pow( t_rat, XTI/NR); 
  247.  
  248. /* update RS, IKF, and BV */
  249.  
  250.         RS  *= 1 + (Told-tnom)*(mod->D_trs1 + (Tnew-tnom)*mod->D_trs2);
  251.         RS  /= 1 + (Tnew-tnom)*(mod->D_trs1 + (Tnew-tnom)*mod->D_trs2);
  252.  
  253.         IKF /= 1 + (Told-tnom)*mod->D_tikf;
  254.         IKF *= 1 + (Tnew-tnom)*mod->D_tikf;
  255.  
  256.         BV  /= 1 + (Told-tnom)*(mod->D_tbv1 + (Tnew-tnom)*mod->D_tbv2);
  257.         BV  *= 1 + (Tnew-tnom)*(mod->D_tbv1 + (Tnew-tnom)*mod->D_tbv2);
  258.  
  259. /* calculate Cjo & Vj for Tref */
  260.  
  261.         oldpb  =  VJ;
  262.         pbo    = (VJ-pbfat1)/fact1;
  263.         gmaold = (VJ-pbo)/pbo;
  264.         CJO   /= 1 + M*(.0004*(Told-reftmp) - gmaold);
  265.  
  266. /* calculate new Cjo & Vj */
  267.  
  268.         VJ     = FLOAT(fact2*pbo + pbfact);
  269.         gmanew = (VJ-pbo)/pbo;
  270.         CJO   *= 1 + M*(.0004*(Tnew-reftmp) - gmanew);
  271.         pbrat  = VJ/oldpb;
  272.  
  273.         mod->D_fc *= pbrat;        /* really fc*vj */
  274.         mod->D_f1 *= pbrat;
  275.  
  276.         mod->D_vcrit = N*VT*log(N*VT/(IS*ROOT2));
  277.  
  278.         if (OutFile != NULL) {
  279.           if (*PrintHdr) {
  280.             *PrintHdr = NO;
  281.             if (IsModel) fprintf(OutFile,ModTitle,"DIODE",D_Heading);
  282.             else         fprintf(OutFile,DevTitle0,D_Heading);
  283.             }
  284.           PRINT_NAME(modelname,len);
  285.           if (len > NAMELENGTH) NewLine(NAMELENGTH);
  286.           fprintf(OutFile,SixParm,
  287.             FmtFlt(IS,FMTE,3),
  288.             FmtFlt(VJ,FMTE,3),
  289.             FmtFlt(CJO,FMTE,3),
  290.             FmtFlt((double)RS==0.?0.:1/RS,FMTE,3),
  291.             FmtFlt(IKF,FMTE,3),
  292.             (double)BV==0.?"":FmtFlt(BV,FMTE,3));    /* don't print if 0 */
  293.           }
  294.  
  295. #undef BV
  296. #undef CJO
  297. #undef EG
  298. #undef IKF
  299. #undef IS
  300. #undef ISR
  301. #undef M
  302. #undef N
  303. #undef NR
  304. #undef RS
  305. #undef VJ
  306. #undef XTI
  307.  
  308.         break;
  309.         }
  310.  
  311. /*** Junction FET ***/
  312.  
  313.       case 'J': {
  314.         struct J_ *mod = (struct J_ *)mloc;
  315.         double oldpb, pbo, gmaold, gmanew, pbrat, oldcjf, newcjf;
  316.  
  317. #define VTO    (mod->J_vto)
  318. #define VTO_TC    (mod->J_vtotc)
  319. #define BETA    (mod->J_beta)
  320. #define BETA_TCE    (mod->J_betatce)
  321. #define CGD    (mod->J_cgd)
  322. #define CGS    (mod->J_cgs)
  323. #define M    (mod->J_m)
  324. #define N    (mod->J_n)
  325. #define PB    (mod->J_pb)
  326. #define IS    (mod->J_is)
  327. #define XTI    (mod->J_xti)
  328.  
  329.         VTO  += VTO_TC*t_dif;        /* VTO_TC is V/degree */
  330.         BETA *= pow(1.01,BETA_TCE*t_dif);    /* BETA_TCE is %/degree */
  331.         IS   *= exp(1.11/(N*VT) * (t_rat-1) ) * pow( t_rat, XTI/N);
  332.  
  333. /* calculate Cgs, Cgd & Pb for Tref */
  334.  
  335.         oldpb  =  PB;
  336.         pbo    = (PB-pbfat1)/fact1;
  337.         gmaold = (PB-pbo)/pbo;
  338.         oldcjf = 1 + M*(.0004*(Told-reftmp) - gmaold);
  339.         CGS   /= oldcjf;
  340.         CGD   /= oldcjf;
  341.  
  342. /* calculate new Cgs, Cgd & Pb */
  343.  
  344.         PB     = FLOAT(fact2*pbo + pbfact);
  345.         gmanew = (PB-pbo)/pbo;
  346.         newcjf = 1 + M*(.0004*(Tnew-reftmp) - gmanew);
  347.         CGS   *= newcjf;
  348.         CGD   *= newcjf;
  349.  
  350.         pbrat  = PB/oldpb;
  351.  
  352.         mod->J_fc *= pbrat;        /* really fc*pb */
  353.         mod->J_f1 *= pbrat;
  354.  
  355.         mod->J_vcrit = VT*log(VT/(IS*ROOT2));
  356.  
  357.         if (OutFile != NULL) {
  358.           if (*PrintHdr) {
  359.             *PrintHdr = NO;
  360.             if (IsModel) fprintf(OutFile,ModTitle,"JFET",J_Heading);
  361.             else         fprintf(OutFile,DevTitle0,J_Heading);
  362.             }
  363.           PRINT_NAME(modelname,len);
  364.           if (len > NAMELENGTH) NewLine(NAMELENGTH);
  365.           fprintf(OutFile,SixParm,
  366.             FmtFlt(VTO,FMTE,3),FmtFlt(BETA,FMTE,3),
  367.             FmtFlt(IS,FMTE,3),FmtFlt(PB,FMTE,3),
  368.             FmtFlt(CGS,FMTE,3),FmtFlt(CGD,FMTE,3));
  369.           }
  370.  
  371. #undef VTO
  372. #undef VTO_TC
  373. #undef BETA
  374. #undef BETA_TCE
  375. #undef CGD
  376. #undef CGS
  377. #undef IS
  378. #undef M
  379. #undef N
  380. #undef PB
  381. #undef XTI
  382.  
  383.         break;
  384.         }
  385.  
  386. /*** MOSFET ***/
  387.  
  388.       case 'M': {
  389.         struct M_ *mod = (struct M_ *)mloc;
  390.         double pbo, oldphi, phio, gmaold, gmanew,
  391.           coeold, coenew, vfb, isat,
  392.           rat3on2 = t_rat * sqrt(t_rat);
  393.  
  394. #define IS    (mod->M_is)
  395. #define JS    (mod->M_js)
  396. #define JSSW    (mod->M_jssw)
  397. #define KP    (mod->M_kp)
  398. #define MJ    (mod->M_mj)
  399. #define MJSW    (mod->M_mjsw)
  400. #define PB    (mod->M_pb)
  401. #define PBSW    (mod->M_pbsw)
  402. #define PHI    (mod->M_phi)
  403. #define TYPE    (mod->M_type)
  404. #define UO    (mod->M_uo)
  405. #define VBI    (mod->M_vbi)
  406. #define VTO    (mod->M_vto)
  407.  
  408.         KP /= rat3on2;
  409.         UO /= rat3on2;
  410.  
  411.         oldphi = PHI;
  412.         phio   = (PHI-pbfat1)/fact1;
  413.         PHI    = FLOAT(fact2*phio + pbfact);
  414.  
  415.         vfb  = VBI - .5*TYPE*oldphi;
  416.         vfb += .5*( eg1 - eg );
  417.         VBI  = vfb + .5*TYPE*PHI;
  418.  
  419.         VTO = FLOAT(VBI + TYPE*(mod->M_gamma)*sqrt(PHI));
  420.  
  421.         { double tmp = exp( eg1/vt1 - eg/VT );
  422.  
  423.           IS   *= tmp;
  424.           JS   *= tmp;
  425.           JSSW *= tmp;
  426.           }
  427.  
  428.         pbo  = (PBSW-pbfat1)/fact1;
  429.         PBSW = FLOAT(fact2*pbo + pbfact);
  430.  
  431.         pbo    = (PB-pbfat1)/fact1;
  432.         gmaold = (PB-pbo)/pbo;
  433.         coeold = 1 + MJ*(.0004*(Told-reftmp) - gmaold);
  434.         mod->M_cbd  /= coeold;
  435.         mod->M_cbs  /= coeold;
  436.         mod->M_cj   /= coeold;
  437.         mod->M_cjsw /= 1 + MJSW*(.0004*(Told-reftmp) - gmaold);
  438.  
  439.         PB     = FLOAT(fact2*pbo + pbfact);
  440.         gmanew = (PB-pbo)/pbo;
  441.         coenew = 1 + MJ*(.0004*(Tnew-reftmp) - gmanew);
  442.         mod->M_cbd  *= coenew;
  443.         mod->M_cbs  *= coenew;
  444.         mod->M_cj   *= coenew;
  445.         mod->M_cjsw *= 1 + MJSW*(.0004*(Tnew-reftmp) - gmanew);
  446.  
  447.         isat = MAX(IS,JS);
  448.  
  449.         if (OutFile != NULL) {
  450.           if (*PrintHdr) {
  451.             *PrintHdr = NO;
  452.             if (IsModel) fprintf(OutFile,ModTitle,"MOSFET",M_Heading);
  453.             else         fprintf(OutFile,DevTitle0,M_Heading);
  454.             }
  455.           PRINT_NAME(modelname,len);
  456.           if (len > NAMELENGTH) NewLine(NAMELENGTH);
  457.           fprintf(OutFile,SixParm,
  458.             FmtFlt(VTO,FMTE,3),FmtFlt(PHI,FMTE,3),FmtFlt(PB,FMTE,3),
  459.             FmtFlt(isat,FMTE,3),FmtFlt(KP,FMTE,3),FmtFlt(1e4*UO,FMTE,3));
  460.           }
  461.  
  462. #undef IS
  463. #undef JS
  464. #undef JSSW
  465. #undef KP
  466. #undef MJ
  467. #undef MJSW
  468. #undef PB
  469. #undef PBSW
  470. #undef PHI
  471. #undef TYPE
  472. #undef UO
  473. #undef VBI
  474. #undef VTO
  475.  
  476.         break;
  477.         }
  478.  
  479. /*** Bipolar transistor ***/
  480.  
  481.       case 'Q': {
  482.         struct Q_ *mod = (struct Q_ *)mloc;
  483.         double oldpb, pbo, gmaold, gmanew, pbrat, bfactr;
  484.  
  485. #define BF    (mod->Q_bf)
  486. #define BR    (mod->Q_br)
  487. #define CJC    (mod->Q_cjc)
  488. #define CJE    (mod->Q_cje)
  489. #define CJS    (mod->Q_cjs)
  490. #define EG    (mod->Q_eg)
  491. #define IS    (mod->Q_is)
  492. #define ISC    (mod->Q_isc)
  493. #define ISE    (mod->Q_ise)
  494. #define ISS    (mod->Q_iss)
  495. #define MJC    (mod->Q_mjc)
  496. #define MJE    (mod->Q_mje)
  497. #define MJS    (mod->Q_mjs)
  498. #define NC    (mod->Q_nc)
  499. #define NE    (mod->Q_ne)
  500. #define NS    (mod->Q_ns)
  501. #define RB    (mod->Q_rb)
  502. #define RBM    (mod->Q_rbm)
  503. #define RC    (mod->Q_rc)
  504. #define RE    (mod->Q_re)
  505. #define VJC    (mod->Q_vjc)
  506. #define VJE    (mod->Q_vje)
  507. #define VJS    (mod->Q_vjs)
  508. #define XTB    (mod->Q_xtb)
  509. #define XTI    (mod->Q_xti)
  510.  
  511.         IS  *= exp( EG/VT     *(t_rat-1) ) * pow( t_rat, XTI);
  512.         ISC *= exp( EG/(NC*VT)*(t_rat-1) ) * pow( t_rat, XTI/NC);
  513.         ISE *= exp( EG/(NE*VT)*(t_rat-1) ) * pow( t_rat, XTI/NE);
  514.         ISS *= exp( EG/(NS*VT)*(t_rat-1) ) * pow( t_rat, XTI/NS);
  515.  
  516.         bfactr = pow( t_rat, XTB);
  517.         BF  *= bfactr;
  518.         BR  *= bfactr;
  519.         ISC /= bfactr;
  520.         ISE /= bfactr;
  521.         ISS /= bfactr;
  522.  
  523.         mod->Q_vcrit = VT*log(VT/(IS*ROOT2));
  524.  
  525. /* calculate Cjc & Vjc for Tref */
  526.  
  527.         oldpb  =  VJC;
  528.         pbo    = (VJC-pbfat1)/fact1;
  529.         gmaold = (VJC-pbo)/pbo;
  530.         CJC   /= 1 + MJC*(.0004*(Told-reftmp) - gmaold);
  531.  
  532. /* calculate new Cjc & Vjc */
  533.  
  534.         VJC    = FLOAT(fact2*pbo + pbfact);
  535.         gmanew = (VJC-pbo)/pbo;
  536.         CJC   *= 1 + MJC*(.0004*(Tnew-reftmp) - gmanew);
  537.  
  538.         pbrat  = VJC/oldpb;
  539.         mod->Q_fcpc *= pbrat;
  540.         mod->Q_f1bc *= pbrat;
  541.  
  542. /* calculate Cje & Vje for Tref */
  543.  
  544.         oldpb  =  VJE;
  545.         pbo    = (VJE-pbfat1)/fact1;
  546.         gmaold = (VJE-pbo)/pbo;
  547.         CJE   /= 1 + MJE*(.0004*(Told-reftmp) - gmaold);
  548.  
  549. /* calculate new Cje & Vje */
  550.  
  551.         VJE    = FLOAT(fact2*pbo + pbfact);
  552.         gmanew = (VJE-pbo)/pbo;
  553.         CJE   *= 1 + MJE*(.0004*(Tnew-reftmp) - gmanew);
  554.  
  555.         pbrat  = VJE/oldpb;
  556.         mod->Q_fcpe *= pbrat;
  557.         mod->Q_f1be *= pbrat;
  558.  
  559. /* calculate Cjs & Vjs for Tref */
  560.  
  561.         pbo    = (VJS-pbfat1)/fact1;
  562.         gmaold = (VJS-pbo)/pbo;
  563.         CJS   /= 1 + MJS*(.0004*(Told-reftmp) - gmaold);
  564.  
  565. /* calculate new Cjs & Vjs */
  566.  
  567.         VJS    = FLOAT(fact2*pbo + pbfact);
  568.         gmanew = (VJS-pbo)/pbo;
  569.         CJS   *= 1 + MJS*(.0004*(Tnew-reftmp) - gmanew);
  570.  
  571. /* update parasitic resistance values */
  572.  
  573.         RB  /= 1 + (Told-tnom)*(mod->Q_trb1 + (Told-tnom)*mod->Q_trb2);
  574.         RB  *= 1 + (Tnew-tnom)*(mod->Q_trb1 + (Tnew-tnom)*mod->Q_trb2);
  575.  
  576.         RBM /= 1 + (Told-tnom)*(mod->Q_trm1 + (Told-tnom)*mod->Q_trm2);
  577.         RBM *= 1 + (Tnew-tnom)*(mod->Q_trm1 + (Tnew-tnom)*mod->Q_trm2);
  578.  
  579. /* these parasitic resistors' values are stored as conductances */
  580.  
  581.         RC  *= 1 + (Told-tnom)*(mod->Q_trc1 + (Told-tnom)*mod->Q_trc2);
  582.         RC  /= 1 + (Tnew-tnom)*(mod->Q_trc1 + (Tnew-tnom)*mod->Q_trc2);
  583.  
  584.         RE  *= 1 + (Told-tnom)*(mod->Q_tre1 + (Told-tnom)*mod->Q_tre2);
  585.         RE  /= 1 + (Tnew-tnom)*(mod->Q_tre1 + (Tnew-tnom)*mod->Q_tre2);
  586.  
  587.         if (OutFile != NULL) {
  588.           if (*PrintHdr) {
  589.             *PrintHdr = NO;
  590.             if (IsModel) fprintf(OutFile,ModTitle,"BJT",Q_Heading0);
  591.             else         fprintf(OutFile,DevTitle0,Q_Heading0);
  592.             fprintf(OutFile,Spacer,Q_Heading1);
  593.             fprintf(OutFile,Spacer,Q_Heading2);
  594.             }
  595.           PRINT_NAME(modelname,len);
  596.           if (len > NAMELENGTH) NewLine(NAMELENGTH);
  597.  
  598.           fprintf(OutFile,SixParm,FmtFlt(BF,FMTE,3),
  599.             FmtFlt(ISE,FMTE,3),FmtFlt(VJE,FMTE,3),FmtFlt(CJE,FMTE,3),
  600.             FmtFlt((double)RE==0.?0.:1/RE,FMTE,3),FmtFlt(RB,FMTE,3));
  601.  
  602.           fprintf(OutFile,NameFormat,"");
  603.           fprintf(OutFile,SixParm,FmtFlt(BR,FMTE,3),
  604.             FmtFlt(ISC,FMTE,3),FmtFlt(VJC,FMTE,3),FmtFlt(CJC,FMTE,3),
  605.             FmtFlt((double)RC==0.?0.:1/RC,FMTE,3),FmtFlt(RBM,FMTE,3));
  606.  
  607.           fprintf(OutFile,NameFormat,"");
  608.           fprintf(OutFile,FourParm,FmtFlt(IS,FMTE,3),
  609.             FmtFlt(ISS,FMTE,3),FmtFlt(VJS,FMTE,3),FmtFlt(CJS,FMTE,3));
  610.           }
  611.  
  612. #undef BF
  613. #undef BR
  614. #undef CJC
  615. #undef CJE
  616. #undef CJS
  617. #undef EG
  618. #undef IS
  619. #undef ISC
  620. #undef ISE
  621. #undef ISS
  622. #undef MJC
  623. #undef MJE
  624. #undef MJS
  625. #undef NC
  626. #undef NE
  627. #undef NS
  628. #undef RB
  629. #undef RBM
  630. #undef RC
  631. #undef RE
  632. #undef VJC
  633. #undef VJE
  634. #undef VJS
  635. #undef XTB
  636. #undef XTI
  637.  
  638.         break;
  639.         }
  640.  
  641. /* end-of-models */
  642.  
  643.       }
  644.     }
  645.   } /* done */
  646.  
  647. void Tmp1Dev(    /* Update ONE device to a new temperature */
  648.   Told,        /* Temperature models have now */
  649.   Tnew,        /* Temperature models will have on exit */
  650.   Id,        /* Device type to be processed */
  651.   Dloc1st,    /* 1st device to be processed */
  652.   OutFile,    /* Output file for updated values */
  653.   PrintHdr    /* YES: print header */
  654.   )
  655. double    Told, Tnew;
  656. int    Id;
  657. struct gen_ *Dloc1st;
  658. FILE    *OutFile;
  659. int    *PrintHdr;
  660.  
  661. /*
  662. whjb    28 Nov 86    split off from TmpUpd
  663. pwt    29 Feb 88    re-work resistor updates so dev->r_g is working value
  664. pwt    21 Mar 88    fix cap. & ind. to include model scaling in printout
  665. */
  666.  
  667. { int len;
  668.   struct gen_ *dloc;
  669.   char    junk[MBUFF];
  670.   char *zero_val_msg =
  671.     "This device scales to 0.0 at this temperature";
  672.   double
  673.     tnom   = TNOM+CTOK,
  674.     vt1    = Told*BOLTZ/CHARGE,
  675.     eg     = EGFET(Tnew),
  676.     eg1    = EGFET(Told),
  677.     factor = exp( eg1/vt1 - eg/VT );
  678.  
  679. /*
  680.  * Process each device structure for which temperature updating is done
  681.  */
  682.   for ( dloc = Dloc1st;
  683.         dloc != NULL;
  684.         dloc = /*dloc->gen_next*/ NULL ) {        /* only do 1 */
  685.  
  686.     switch (Id) {
  687.  
  688. /*** Capacitors ***/
  689. /*    needs work similar to resistor; i.e. maintaining two values, one that
  690.     was read in, and one for the current operating temperature.  May wait
  691.     until device temperatures can vary independently. */
  692.  
  693.       case 'C': {
  694.         struct c_ *dev = (struct c_ *)dloc;
  695.         struct C_ *mod = dev->c_model;
  696.  
  697.         if ( mod == NULL ) break;    /* !!! no model */
  698.  
  699.         dev->c_c /= 1 + (Told-tnom)*(mod->C_tc1 + (Told-tnom)*mod->C_tc2);
  700.         dev->c_c *= 1 + (Tnew-tnom)*(mod->C_tc1 + (Tnew-tnom)*mod->C_tc2);
  701.  
  702.         if (OutFile != NULL) {
  703.           if (*PrintHdr) {
  704.             *PrintHdr = NO;
  705.             fprintf(OutFile,DevTitle1,"CAPACITORS");
  706.             }
  707.           PRINT_NAME(dev->c_name,len);
  708.           if (len > NAMELENGTH) NewLine(NAMELENGTH);
  709.           fprintf(OutFile,OneParm,FmtFlt(dev->c_c*mod->C_c,FMTE,3));
  710.           }
  711.  
  712.         break;
  713.         }
  714.  
  715. /*** Inductors ***/
  716. /*    needs work similar to resistor; i.e. maintaining two values, one that
  717.     was read in, and one for the current operating temperature.  May wait
  718.     until device temperatures can vary independently. */
  719.  
  720.       case 'L': {
  721.         struct l_ *dev = (struct l_ *)dloc;
  722.         struct L_ *mod = dev->l_model;
  723.  
  724.         if ( mod == NULL ) break;    /* !!! no model */
  725.  
  726.         dev->l_l /= 1 + (Told-tnom)*(mod->L_tc1 + (Told-tnom)*mod->L_tc2);
  727.         dev->l_l *= 1 + (Tnew-tnom)*(mod->L_tc1 + (Tnew-tnom)*mod->L_tc2);
  728.  
  729.         if (OutFile != NULL) {
  730.           if (*PrintHdr) {
  731.             *PrintHdr = NO;
  732.             fprintf(OutFile,DevTitle1,"INDUCTORS");
  733.             }
  734.           PRINT_NAME(dev->l_name,len);
  735.           if (len > NAMELENGTH) NewLine(NAMELENGTH);
  736.           fprintf(OutFile,OneParm,FmtFlt(dev->l_l*mod->L_l,FMTE,3));
  737.           }
  738.         break;
  739.         }
  740.  
  741. /*** MOS transistors ***/
  742.  
  743.       case 'M': {
  744.         struct m_ *dev = (struct m_ *)dloc;
  745.  
  746. /* update drain and source saturation currents */
  747.  
  748.         dev->m_idsat *= factor;
  749.         dev->m_issat *= factor;
  750.  
  751.         break;
  752.         }
  753.  
  754. /*** Resistors ***/
  755.  
  756.       case 'R': {
  757.         double tc1, tc2, scale;
  758.         struct r_ *dev = (struct r_ *)dloc;
  759.         struct R_ *mod = dev->r_model;
  760.  
  761.         if (mod != NULL || dev->r_tc1 != 0.0 || dev->r_tc2 != 0.0) {
  762.  
  763.      /* exp coefficient */
  764.  
  765.           if (mod != NULL && DOUBLE(mod->R_tce) != 0.) {
  766.             dev->r_r /= pow( 1.01, (Told-tnom)*mod->R_tce);
  767.             dev->r_r *= pow( 1.01, (Tnew-tnom)*mod->R_tce);
  768.             scale     = mod->R_r;
  769.             }
  770.           else {                      /* linear and quadratic coefficients */
  771.             if (mod == NULL) {
  772.               tc1   = dev->r_tc1;
  773.               tc2   = dev->r_tc2;
  774.               scale = 1.;
  775.               }
  776.             else {
  777.               tc1   = mod->R_tc1;
  778.               tc2   = mod->R_tc2;
  779.               scale = mod->R_r;
  780.               }
  781.             dev->r_r /= 1 + (Told-tnom)*(tc1 + (Told-tnom)*tc2);
  782.             dev->r_r *= 1 + (Tnew-tnom)*(tc1 + (Tnew-tnom)*tc2);
  783.             }
  784.           dev->r_r = MAX(dev->r_r,1e-20);
  785.  
  786.           if (OutFile != NULL) {
  787.             if (*PrintHdr) {
  788.               *PrintHdr = NO;
  789.               fprintf(OutFile,DevTitle1,"RESISTORS");
  790.               }
  791.             PRINT_NAME(dev->r_name,len);
  792.             if (len > NAMELENGTH) NewLine(NAMELENGTH);
  793.             if ( dev->r_r == 1e-20 ) {
  794.               SimError(FATAL_ERROR,zero_val_msg);
  795.               }
  796.             else
  797.               fprintf(OutFile,OneParm,FmtFlt(dev->r_r * scale,FMTE,3));
  798.             }
  799.           }    /* end of if(model exists or device tc's!=0) */
  800.         break;
  801.         }
  802.       } /* end of device switch */
  803.     } /* end of device loop */
  804.   } /* done */
  805.