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

  1. /****************************************************************************/
  2. /*        Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991                  */
  3. /*          By MicroSim Corporation, All Rights Reserved                    */
  4. /****************************************************************************/
  5. /* acbjt.c
  6.  *   $Revision:   1.7  $
  7.  *   $Author:   pwt  $
  8.  *   $Date:   15 Aug 1990 14:44:04  $ */
  9.  
  10. /******************* USERS OF DEVICE EQUATIONS OPTION ***********************/
  11. /******** The procedure for changing the bipolar model parameters  **********/
  12. /******** and device equations is the same as for the MOSFET.  See **********/
  13. /******** the comments in the files mos.c and m.h for details.     **********/
  14.  
  15. #include "option1.h"
  16. #ifdef USE_DECL_ARGS
  17. void ACLoad_Q(    struct q_ *, double );
  18. _complex ACPrb_Q(    struct q_ *, double, int, int);
  19. #else
  20. void ACLoad_Q();
  21. _complex ACPrb_Q();
  22. #endif
  23.  
  24. #define GBE    (Instance->qcv_gpi)    /* active conductances */
  25. #define GMU    (Instance->qcv_gmu)
  26. #define GM    (Instance->qcv_gm)
  27. #define GCE    (Instance->qcv_go)
  28. #define GX    (Instance->qcv_gx)
  29. #define GJS    (Instance->qcv_gjs)
  30. #define GNBN    (Instance->qcv_gnbn)
  31. #define GNBC    (Instance->qcv_gnbc)    
  32.  
  33. #define AREA    (Instance->q_area)
  34.  
  35. #define CBN    (Instance->q_sda.q_ac.qac_cbn)    /* device capacitances */
  36. #define CBC    (Instance->q_sda.q_ac.qac_cbc)
  37. #define CBE    (Instance->q_sda.q_ac.qac_cbe)
  38. #define CJS    (Instance->q_sda.q_ac.qac_cjs)
  39. #define CBX    (Instance->q_sda.q_ac.qac_cBc)
  40.  
  41. #define RC    ((double)Instance->q_model->Q_rc)
  42. #define RE    ((double)Instance->q_model->Q_re)
  43. #define TD    ((double)Instance->q_model->Q_ptf)
  44.  
  45. #define LPNP    (Instance->q_model->Q_lpnp)
  46.  
  47. void ACLoad_Q(    /* Process BJT for AC analysis */
  48.   Instance,    /* device to evaluate */
  49.   Omega        /* 2*pi*frequency */
  50.   )
  51. struct q_ *Instance;
  52. double Omega;
  53.  
  54. /*
  55. whjb    25 Mar 87    created (from code taken from ACLoad)
  56. pwt    27 Oct 87    re-written for lateral devices
  57. pwt    02 Mar 88    add full diode treatment for substrate diode
  58. pwt    02 Mar 88    BJT resistances Q_re and Q_rc now stored as resistance
  59. pwt    04 Mar 88    rename from BjtAC
  60. pwt    15 Oct 89    add quasi-saturation enhancements
  61. */
  62. { double gcpr, gepr, xjs, xBc, xbn,
  63.     gm   = GM,                /* active conductance */
  64.     xbc  = Omega*CBC,            /* reactances */
  65.     xbe  = Omega*CBE,
  66.     xteq = Omega*Instance->qcv_gcbeq,
  67.     xgm  = 0.;
  68.  
  69.   if ( TD != 0.) {
  70.     gm += GCE;
  71.     xgm = -gm*sin(Omega*TD);
  72.     gm  =  gm*cos(Omega*TD) - GCE;
  73.     }
  74.  
  75. /* Stuff terms into matrix */
  76.  
  77.   AC_MAT_I(q_Bc) = AC_MAT_I(q_cB) = -( AC_MAT_I(q_BB) = xBc = Omega*CBX );
  78.   AC_MAT_I(q_Sj) = AC_MAT_I(q_jS) = -( AC_MAT_I(q_SS) = xjs = Omega*CJS );
  79.   AC_MAT_I(q_nb) = AC_MAT_I(q_bn) = -( AC_MAT_I(q_nn) = xbn = Omega*CBN );
  80.  
  81.   AC_MAT_I(q_bb) = ( LPNP ? xjs : 0.) + xbc + xbe + xteq + xbn;
  82.   AC_MAT_I(q_cc) = ( LPNP ? 0.: xjs ) + xbc + xBc;
  83.   AC_MAT_I(q_ee) =  xbe + xgm;
  84.   AC_MAT_I(q_ec) =  xteq;
  85.   AC_MAT_I(q_ce) = -xgm;
  86.   AC_MAT_I(q_cb) =  xgm - xbc;
  87.   AC_MAT_I(q_bc) = -xbc - xteq;
  88.   AC_MAT_I(q_eb) = -xbe - xgm - xteq;
  89.   AC_MAT_I(q_be) = -xbe;
  90.  
  91.   AC_MAT_R(q_Bb) = AC_MAT_R(q_bB) = -( AC_MAT_R(q_BB) = GX );
  92.   AC_MAT_R(q_Sj) = AC_MAT_R(q_jS) = -( AC_MAT_R(q_SS) = GJS);
  93.   AC_MAT_R(q_Cn) = AC_MAT_R(q_nC) = -( AC_MAT_R(q_CC) = gcpr = AREA*RC );
  94.   AC_MAT_R(q_Ee) = AC_MAT_R(q_eE) = -( AC_MAT_R(q_EE) = gepr = AREA*RE );
  95.  
  96.   AC_MAT_R(q_bb) = ( LPNP ? GJS : 0.) + GX  + GMU + GBE;
  97.   AC_MAT_R(q_cc) = ( LPNP ? 0.: GJS ) + GMU + GCE + GNBC;
  98.   AC_MAT_R(q_ee) =  gepr + GBE + GCE + gm;
  99.  
  100.   AC_MAT_R(q_eb) = ( AC_MAT_R(q_be) = -GBE ) - gm;
  101.   AC_MAT_R(q_ce) = ( AC_MAT_R(q_ec) = -GCE ) - gm;
  102.   AC_MAT_R(q_cb) = ( AC_MAT_R(q_bc) = -GMU ) + gm - GNBN - GNBC;
  103.  
  104.   AC_MAT_R(q_cn) =  GNBN;
  105.   AC_MAT_R(q_nb) =  GNBN + GNBC;
  106.   AC_MAT_R(q_nc) = -GNBC;
  107.   AC_MAT_R(q_nn) =  gcpr - GNBN;
  108.  
  109.   } /* End ACLoad_Q */
  110.  
  111.  
  112.  
  113.  
  114. _complex ACPrb_Q(    /* Calc. BJT current (for Probe) for AC analysis */
  115.   Instance,    /* device to evaluate */
  116.   Omega,    /* 2*pi*frequency */
  117.   Pin,        /* pin designator: 'c'|'b'|'e'|'s' (case insensitive) */
  118.   ForceRecalc
  119.   )
  120. struct q_ *Instance;
  121. double Omega;
  122. int Pin, ForceRecalc;
  123.  
  124. /*
  125. pwt    04 Mar 88    creation
  126. pwt    15 Oct 89    add quasi-saturation enhancements
  127. pwt    16 Aug 90    add ForceRecalc argument for report speed-up
  128. */
  129. {
  130.   static _complex            /* calculated branch currents */
  131.     ibn, ibe, ibc, ice, ijs;
  132.  
  133.   static struct q_ *instance;        /* "previous call" argument values */
  134.   static double omega;
  135.  
  136.   if ( ForceRecalc ||
  137.        Instance != instance ||
  138.        Omega    != omega ) {
  139.  
  140.     _complex
  141.       vbe, vbc, vbx, vjs, vbn,        /* node voltages */
  142.       ybe, ybc, ybx, yjs, ybn,        /* branch admittances */
  143.       ygm, yce, yeq_cb;
  144.  
  145.     instance = Instance;
  146.     omega    = Omega;
  147.  
  148.     vbe.re = VltVct [Instance->q_b] - VltVct [Instance->q_e];
  149.     vbe.im = VltVctI[Instance->q_b] - VltVctI[Instance->q_e];
  150.  
  151.     vbc.re = VltVct [Instance->q_b] - VltVct [Instance->q_c];
  152.     vbc.im = VltVctI[Instance->q_b] - VltVctI[Instance->q_c];
  153.  
  154.     vbx.re = VltVct [Instance->q_B] - VltVct [Instance->q_c];
  155.     vbx.im = VltVctI[Instance->q_B] - VltVctI[Instance->q_c];
  156.  
  157.     vjs.re = VltVct [Instance->q_S] - ( LPNP ? VltVct [Instance->q_b] : VltVct [Instance->q_c] );
  158.     vjs.im = VltVctI[Instance->q_S] - ( LPNP ? VltVctI[Instance->q_b] : VltVctI[Instance->q_c] );
  159.  
  160.     vbn.re = VltVct [Instance->q_b] - VltVct [Instance->q_n];
  161.     vbn.im = VltVctI[Instance->q_b] - VltVctI[Instance->q_n];
  162.  
  163.     ybe.re = GBE; ybe.im = Omega*CBE;
  164.     ybc.re = GMU; ybc.im = Omega*CBC;
  165.     yjs.re = GJS; yjs.im = Omega*CJS;
  166.     ybx.re = 0.;  ybx.im = Omega*CBX;
  167.     ybn.re = 0.;  ybn.im = Omega*CBN;
  168.     ygm.re = GM;  ygm.im = 0.;
  169.     yce.re = GCE; yce.im = 0.;
  170.     yeq_cb.re=0.; yeq_cb.im = Omega*Instance->qcv_gcbeq;
  171.  
  172.     if ( TD != 0.) {
  173.       ygm.re +=  yce.re;
  174.       ygm.im  = -ygm.re*sin(Omega*TD);
  175.       ygm.re  =  ygm.re*cos(Omega*TD) - yce.re;
  176.       }
  177.     ibn = cmul(ybn,vbn);
  178.     ibe = cadd( cmul(ybe,vbe), cmul(yeq_cb,vbc) );
  179.     ibc = cadd( cmul(ybc,vbc), cmul(ybx,vbx) );
  180.     ice = cadd( cmul(ygm,vbe), cmul(yce,csub(vbe,vbc)) );
  181.     ijs = cmul(yjs,vjs);
  182.     }
  183.  
  184.   switch ( toupper(Pin) ) {    /* select pin and combine currents */
  185.     _complex tmp;
  186.  
  187.     case 'C':
  188.       tmp = csub(csub(ice,ibc),ibn);
  189.       return LPNP ? tmp : csub(tmp,ijs);
  190.  
  191.     case 'B':
  192.       tmp = cadd(cadd(ibe,ibc),ibn);
  193.       return LPNP ? csub(tmp,ijs) : tmp;
  194.  
  195.     case 'E':
  196.       return cadi(ibe,ice);
  197.  
  198.     case 'S':
  199.       return ijs;
  200.     }
  201.  
  202.   } /* end of ACPrb_Q */
  203.