home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991 */
- /* By MicroSim Corporation, All Rights Reserved */
- /****************************************************************************/
- /* acgasfet.c
- * $Revision: 1.6 $
- * $Author: pwt $
- * $Date: 15 Aug 1990 14:42:10 $ */
-
- /******************* USERS OF DEVICE EQUATIONS OPTION ***********************/
- /******** The procedure for changing the GaAsFET model parameters **********/
- /******** and device equations is the same as for the MOSFET. See **********/
- /******** the comments in the files mos.c and m.h for details. **********/
-
- #include "option1.h"
- #ifdef USE_DECL_ARGS
- void ACLoad_B( struct b_ *, double );
- _complex ACPrb_B( struct b_ *, double, int, int);
- #else
- void ACLoad_B();
- _complex ACPrb_B();
- #endif
-
- #define AREA (Instance->b_area) /* device area */
- #define GM (Instance->bcv_gm) /* active conductances */
- #define GDS (Instance->bcv_gds)
- #define GGS (Instance->bcv_ggs)
- #define GGD (Instance->bcv_ggd)
-
- #define CGS (Instance->b_sda.b_ac.bac_cgs) /* capacitances */
- #define CGD (Instance->b_sda.b_ac.bac_cgd)
- #define CDS (Instance->b_sda.b_ac.bac_cds)
-
- #define RD (Instance->b_model->B_rd) /* passive conductances */
- #define RG (Instance->b_model->B_rg)
- #define RS (Instance->b_model->B_rs)
-
- #define TAU ((double)Instance->b_model->B_tau) /* transit time */
-
- void ACLoad_B( /* Process GaAsFET for AC analysis */
- Instance, /* device to evaluate */
- Omega /* 2*pi*frequency */
- )
- struct b_ *Instance;
- double Omega;
-
- /*
- whjb 27 Mar 87 created (from code taken from ACLoad)
- pwt 15 Jul 87 include device forward/reverse mode calculations
- pwt 03 Nov 87 correct TAU contribution
- pwt 20 Jan 88 correct d-s conductance (typo) error
- pwt 04 Mar 88 rename from GfetAC
- */
- { struct bsv_def *sv[1]; /* state vector */
- double gdpr, gspr,
- xgs = Omega*CGS,
- xgd = Omega*CGD,
- xds = Omega*CDS,
- xgm = 0.,
- gm = GM;
-
- int fwd; /* forward/reverse mode */
-
- EVAL_SV0(sv,Instance,b_sda.b_sv);
-
- fwd = B_VGS(0) > B_VGD(0) ? YES : NO;
-
- if ( TAU != 0.) {
- double
- arg = Omega*TAU,
- mag = gm/sqrt(1+arg*arg),
- phs = -atan(arg);
-
- xgm = mag*sin(phs);
- gm = mag*cos(phs);
- }
-
- /* Load matrix */
-
- AC_MAT_I(b_dg) = ( fwd ? xgm : -xgm ) - xgd;
- AC_MAT_I(b_ds) = ( fwd ? -xgm : 0. ) - xds;
- AC_MAT_I(b_dd) = ( fwd ? 0. : xgm ) + xgd + xds;
-
- AC_MAT_I(b_sd) = ( fwd ? 0. : -xgm ) - xds;
- AC_MAT_I(b_sg) = ( fwd ? -xgm : xgm ) - xgs;
- AC_MAT_I(b_ss) = ( fwd ? xgm : 0. ) + xds + xgs;
-
- AC_MAT_I(b_gd) = -xgd;
- AC_MAT_I(b_gs) = -xgs;
- AC_MAT_I(b_gg) = xgd+xgs;
-
- AC_MAT_R(b_Dd) = AC_MAT_R(b_dD) = -( AC_MAT_R(b_DD) = gdpr = AREA*RD );
- AC_MAT_R(b_Ss) = AC_MAT_R(b_sS) = -( AC_MAT_R(b_SS) = gspr = AREA*RS );
- AC_MAT_R(b_Gg) = AC_MAT_R(b_gG) = -( AC_MAT_R(b_GG) = RG );
-
- AC_MAT_R(b_ds) = ( fwd ? -gm : 0. ) - GDS;
- AC_MAT_R(b_dg) = ( fwd ? gm : -gm ) - GGD;
- AC_MAT_R(b_dd) = ( fwd ? 0. : gm ) + GDS + GGD + gdpr;
-
- AC_MAT_R(b_sd) = ( fwd ? 0. : -gm ) - GDS;
- AC_MAT_R(b_sg) = ( fwd ? -gm : gm ) - GGS;
- AC_MAT_R(b_ss) = ( fwd ? gm : 0. ) + GDS + GGS + gspr;
-
- AC_MAT_R(b_gd) = -GGD;
- AC_MAT_R(b_gs) = -GGS;
- AC_MAT_R(b_gg) = GGD + GGS + RG;
-
- } /* End of ACLoad_B */
-
-
-
-
- _complex ACPrb_B( /* Calc. GaAsFET current (for Probe) for AC analysis */
- Instance, /* device to evaluate */
- Omega, /* 2*pi*frequency */
- Pin, /* pin designator: 'd'|'g'|'s' (case insensitive) */
- ForceRecalc
- ) /* return: complex current */
- struct b_ *Instance;
- double Omega;
- int Pin, ForceRecalc;
-
- /*
- pwt 04 Mar 88 creation
- pwt 16 Aug 90 add ForceRecalc argument for report speed-up
- */
- {
- static _complex /* calculated branch currents */
- igd, igs, ids;
-
- static struct b_ *instance; /* "previous call" argument values */
- static double omega;
-
- if ( ForceRecalc ||
- Instance != instance ||
- Omega != omega ) {
-
- _complex
- vgd, vgs, vds, /* node voltages */
- ygd, ygs, yds, ygm; /* branch admittances */
-
- struct bsv_def *sv[1];
-
- EVAL_SV0(sv,Instance,b_sda.b_sv);
-
- instance = Instance;
- omega = Omega;
-
- vgd.re = VltVct [Instance->b_g] - VltVct [Instance->b_d];
- vgd.im = VltVctI[Instance->b_g] - VltVctI[Instance->b_d];
-
- vgs.re = VltVct [Instance->b_g] - VltVct [Instance->b_s];
- vgs.im = VltVctI[Instance->b_g] - VltVctI[Instance->b_s];
-
- vds.re = VltVct [Instance->b_d] - VltVct [Instance->b_s];
- vds.im = VltVctI[Instance->b_d] - VltVctI[Instance->b_s];
-
- ygd.re = GGD; ygd.im = Omega*CGD;
- ygs.re = GGS; ygs.im = Omega*CGS;
- yds.re = GDS; yds.im = Omega*CDS;
- ygm.re = GM; ygm.im = 0.;
-
- if ( TAU != 0.) {
- double
- arg = Omega*TAU,
- mag = ygm.re/sqrt(1+arg*arg),
- phs = -atan(arg);
-
- ygm.re = mag*cos(phs);
- ygm.im = mag*sin(phs);
- }
-
- igd = cmul(ygd,vgd); /* calculate branch currents */
- igs = cmul(ygs,vgs);
- ids = B_VGS(0) > B_VGD(0) ?
- cadd( cmul(yds,vds), cmul(ygm,vgs) ) :
- csub( cmul(yds,vds), cmul(ygm,vgd) ) ;
- }
-
- switch ( toupper(Pin) ) { /* select pin and combine currents */
- case 'D': return csub(ids,igd);
- case 'G': return cadd(igd,igs);
- case 'S': return cadi(ids,igs);
- }
-
- } /* end of ACPrb_B */