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

  1. /****************************************************************************/
  2. /*        Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991                  */
  3. /*          By MicroSim Corporation, All Rights Reserved                    */
  4. /****************************************************************************/
  5. /* acgasfet.c
  6.  *   $Revision:   1.6  $
  7.  *   $Author:   pwt  $
  8.  *   $Date:   15 Aug 1990 14:42:10  $ */
  9.  
  10. /******************* USERS OF DEVICE EQUATIONS OPTION ***********************/
  11. /******** The procedure for changing the GaAsFET 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_B(    struct b_ *, double );
  18. _complex ACPrb_B(    struct b_ *, double, int, int);
  19. #else
  20. void ACLoad_B();
  21. _complex ACPrb_B();
  22. #endif
  23.  
  24. #define AREA    (Instance->b_area)    /* device area */
  25. #define GM    (Instance->bcv_gm)    /* active conductances */
  26. #define GDS    (Instance->bcv_gds)
  27. #define GGS    (Instance->bcv_ggs)
  28. #define GGD    (Instance->bcv_ggd)
  29.  
  30. #define CGS    (Instance->b_sda.b_ac.bac_cgs)    /* capacitances */
  31. #define CGD    (Instance->b_sda.b_ac.bac_cgd)
  32. #define CDS    (Instance->b_sda.b_ac.bac_cds)
  33.  
  34. #define RD    (Instance->b_model->B_rd)    /* passive conductances */
  35. #define RG    (Instance->b_model->B_rg)
  36. #define RS    (Instance->b_model->B_rs)
  37.  
  38. #define TAU    ((double)Instance->b_model->B_tau)    /* transit time */
  39.  
  40. void ACLoad_B(    /* Process GaAsFET for AC analysis */
  41.   Instance,    /* device to evaluate */
  42.   Omega        /* 2*pi*frequency */
  43.   )
  44. struct b_ *Instance;
  45. double Omega;
  46.  
  47. /*
  48. whjb    27 Mar 87    created (from code taken from ACLoad)
  49. pwt    15 Jul 87    include device forward/reverse mode calculations
  50. pwt    03 Nov 87    correct TAU contribution
  51. pwt    20 Jan 88    correct d-s conductance (typo) error
  52. pwt    04 Mar 88    rename from GfetAC
  53. */
  54. { struct bsv_def *sv[1];        /* state vector */
  55.   double gdpr, gspr,
  56.     xgs = Omega*CGS,
  57.     xgd = Omega*CGD,
  58.     xds = Omega*CDS,
  59.     xgm = 0.,
  60.     gm  = GM;
  61.  
  62.   int fwd;                /* forward/reverse mode */
  63.  
  64.   EVAL_SV0(sv,Instance,b_sda.b_sv);
  65.  
  66.   fwd = B_VGS(0) > B_VGD(0) ? YES : NO;
  67.  
  68.   if ( TAU != 0.) {
  69.     double
  70.       arg = Omega*TAU,
  71.       mag = gm/sqrt(1+arg*arg),
  72.       phs = -atan(arg);
  73.  
  74.     xgm = mag*sin(phs);
  75.     gm  = mag*cos(phs);
  76.     }
  77.  
  78. /* Load matrix */
  79.  
  80.   AC_MAT_I(b_dg) = ( fwd ?  xgm : -xgm ) - xgd;
  81.   AC_MAT_I(b_ds) = ( fwd ? -xgm :  0.  ) - xds;
  82.   AC_MAT_I(b_dd) = ( fwd ?  0.  :  xgm ) + xgd + xds;
  83.  
  84.   AC_MAT_I(b_sd) = ( fwd ?  0.  : -xgm ) - xds;
  85.   AC_MAT_I(b_sg) = ( fwd ? -xgm :  xgm ) - xgs;
  86.   AC_MAT_I(b_ss) = ( fwd ?  xgm :  0.  ) + xds + xgs;
  87.  
  88.   AC_MAT_I(b_gd) = -xgd;
  89.   AC_MAT_I(b_gs) = -xgs;
  90.   AC_MAT_I(b_gg) =  xgd+xgs;
  91.  
  92.   AC_MAT_R(b_Dd) = AC_MAT_R(b_dD) = -( AC_MAT_R(b_DD) = gdpr = AREA*RD );
  93.   AC_MAT_R(b_Ss) = AC_MAT_R(b_sS) = -( AC_MAT_R(b_SS) = gspr = AREA*RS );
  94.   AC_MAT_R(b_Gg) = AC_MAT_R(b_gG) = -( AC_MAT_R(b_GG) = RG );
  95.  
  96.   AC_MAT_R(b_ds) = ( fwd ? -gm :  0. ) - GDS;
  97.   AC_MAT_R(b_dg) = ( fwd ?  gm : -gm ) - GGD;
  98.   AC_MAT_R(b_dd) = ( fwd ?  0. :  gm ) + GDS + GGD + gdpr;
  99.  
  100.   AC_MAT_R(b_sd) = ( fwd ?  0. : -gm ) - GDS;
  101.   AC_MAT_R(b_sg) = ( fwd ? -gm :  gm ) - GGS;
  102.   AC_MAT_R(b_ss) = ( fwd ?  gm :  0. ) + GDS + GGS + gspr;
  103.  
  104.   AC_MAT_R(b_gd) = -GGD;
  105.   AC_MAT_R(b_gs) = -GGS;
  106.   AC_MAT_R(b_gg) =  GGD + GGS + RG;
  107.  
  108.   } /* End of ACLoad_B */
  109.  
  110.  
  111.  
  112.  
  113. _complex ACPrb_B(    /* Calc. GaAsFET current (for Probe) for AC analysis */
  114.   Instance,    /* device to evaluate */
  115.   Omega,    /* 2*pi*frequency */
  116.   Pin,        /* pin designator: 'd'|'g'|'s' (case insensitive) */
  117.   ForceRecalc
  118.   )        /* return: complex current */
  119. struct b_ *Instance;
  120. double Omega;
  121. int Pin, ForceRecalc;
  122.  
  123. /*
  124. pwt    04 Mar 88    creation
  125. pwt    16 Aug 90    add ForceRecalc argument for report speed-up
  126. */
  127. {
  128.   static _complex            /* calculated branch currents */
  129.     igd, igs, ids;
  130.  
  131.   static struct b_ *instance;        /* "previous call" argument values */
  132.   static double omega;
  133.  
  134.   if ( ForceRecalc ||
  135.        Instance != instance ||
  136.        Omega    != omega ) {
  137.  
  138.     _complex
  139.       vgd, vgs, vds,        /* node voltages */
  140.       ygd, ygs, yds, ygm;    /* branch admittances */
  141.  
  142.     struct bsv_def *sv[1];
  143.  
  144.     EVAL_SV0(sv,Instance,b_sda.b_sv);
  145.  
  146.     instance = Instance;
  147.     omega    = Omega;
  148.  
  149.     vgd.re = VltVct [Instance->b_g] - VltVct [Instance->b_d];
  150.     vgd.im = VltVctI[Instance->b_g] - VltVctI[Instance->b_d];
  151.  
  152.     vgs.re = VltVct [Instance->b_g] - VltVct [Instance->b_s];
  153.     vgs.im = VltVctI[Instance->b_g] - VltVctI[Instance->b_s];
  154.  
  155.     vds.re = VltVct [Instance->b_d] - VltVct [Instance->b_s];
  156.     vds.im = VltVctI[Instance->b_d] - VltVctI[Instance->b_s];
  157.  
  158.     ygd.re = GGD; ygd.im = Omega*CGD;
  159.     ygs.re = GGS; ygs.im = Omega*CGS;
  160.     yds.re = GDS; yds.im = Omega*CDS;
  161.     ygm.re = GM;  ygm.im = 0.;
  162.  
  163.     if ( TAU != 0.) {
  164.       double
  165.         arg = Omega*TAU,
  166.         mag = ygm.re/sqrt(1+arg*arg),
  167.         phs = -atan(arg);
  168.  
  169.       ygm.re = mag*cos(phs);
  170.       ygm.im = mag*sin(phs);
  171.       }
  172.  
  173.     igd = cmul(ygd,vgd);    /* calculate branch currents */
  174.     igs = cmul(ygs,vgs);
  175.     ids = B_VGS(0) > B_VGD(0) ?
  176.             cadd( cmul(yds,vds), cmul(ygm,vgs) ) :
  177.             csub( cmul(yds,vds), cmul(ygm,vgd) ) ;
  178.     }
  179.  
  180.   switch ( toupper(Pin) ) {    /* select pin and combine currents */
  181.     case 'D': return csub(ids,igd);
  182.     case 'G': return cadd(igd,igs);
  183.     case 'S': return cadi(ids,igs);
  184.     }
  185.  
  186.   } /* end of ACPrb_B */
  187.