Browse Source
Added three new devices from macspice3f4 (A. Wilson). These devices are not yet in a usable state. They seems to be partial porting.
pre-master-46
Added three new devices from macspice3f4 (A. Wilson). These devices are not yet in a usable state. They seems to be partial porting.
pre-master-46
60 changed files with 8442 additions and 0 deletions
-
29src/spicelib/devices/hfet1/Makefile.am
-
120src/spicelib/devices/hfet1/hfet.c
-
88src/spicelib/devices/hfet1/hfetacl.c
-
132src/spicelib/devices/hfet1/hfetask.c
-
466src/spicelib/devices/hfet1/hfetdefs.h
-
39src/spicelib/devices/hfet1/hfetdel.c
-
31src/spicelib/devices/hfet1/hfetdest.c
-
34src/spicelib/devices/hfet1/hfetext.h
-
37src/spicelib/devices/hfet1/hfetgetic.c
-
65src/spicelib/devices/hfet1/hfetinit.c
-
13src/spicelib/devices/hfet1/hfetinit.h
-
7src/spicelib/devices/hfet1/hfetitf.h
-
787src/spicelib/devices/hfet1/hfetload.c
-
245src/spicelib/devices/hfet1/hfetmask.c
-
45src/spicelib/devices/hfet1/hfetmdel.c
-
290src/spicelib/devices/hfet1/hfetmpar.c
-
60src/spicelib/devices/hfet1/hfetparam.c
-
432src/spicelib/devices/hfet1/hfetsetup.c
-
96src/spicelib/devices/hfet1/hfettemp.c
-
26src/spicelib/devices/hfet1/hfettrunc.c
-
29src/spicelib/devices/hfet2/Makefile.am
-
94src/spicelib/devices/hfet2/hfet2.c
-
64src/spicelib/devices/hfet2/hfet2acl.c
-
132src/spicelib/devices/hfet2/hfet2ask.c
-
318src/spicelib/devices/hfet2/hfet2defs.h
-
39src/spicelib/devices/hfet2/hfet2del.c
-
32src/spicelib/devices/hfet2/hfet2dest.c
-
38src/spicelib/devices/hfet2/hfet2ext.h
-
32src/spicelib/devices/hfet2/hfet2getic.c
-
65src/spicelib/devices/hfet2/hfet2init.c
-
13src/spicelib/devices/hfet2/hfet2init.h
-
7src/spicelib/devices/hfet2/hfet2itf.h
-
456src/spicelib/devices/hfet2/hfet2load.c
-
160src/spicelib/devices/hfet2/hfet2mask.c
-
45src/spicelib/devices/hfet2/hfet2mdel.c
-
177src/spicelib/devices/hfet2/hfet2mpar.c
-
60src/spicelib/devices/hfet2/hfet2param.c
-
233src/spicelib/devices/hfet2/hfet2setup.c
-
56src/spicelib/devices/hfet2/hfet2temp.c
-
27src/spicelib/devices/hfet2/hfet2trunc.c
-
29src/spicelib/devices/mesa/Makefile.am
-
130src/spicelib/devices/mesa/mesa.c
-
97src/spicelib/devices/mesa/mesaacl.c
-
140src/spicelib/devices/mesa/mesaask.c
-
467src/spicelib/devices/mesa/mesadefs.h
-
39src/spicelib/devices/mesa/mesadel.c
-
35src/spicelib/devices/mesa/mesadest.c
-
37src/spicelib/devices/mesa/mesaext.h
-
41src/spicelib/devices/mesa/mesagetic.c
-
65src/spicelib/devices/mesa/mesainit.c
-
13src/spicelib/devices/mesa/mesainit.h
-
9src/spicelib/devices/mesa/mesaitf.h
-
987src/spicelib/devices/mesa/mesaload.c
-
223src/spicelib/devices/mesa/mesamask.c
-
45src/spicelib/devices/mesa/mesamdel.c
-
273src/spicelib/devices/mesa/mesamparam.c
-
69src/spicelib/devices/mesa/mesaparam.c
-
417src/spicelib/devices/mesa/mesasetup.c
-
177src/spicelib/devices/mesa/mesatemp.c
-
30src/spicelib/devices/mesa/mesatrunc.c
@ -0,0 +1,29 @@ |
|||||
|
## Process this file with automake to produce Makefile.in
|
||||
|
|
||||
|
pkglib_LTLIBRARIES = libhfet.la |
||||
|
|
||||
|
libhfet_la_SOURCES = \
|
||||
|
hfet.c \
|
||||
|
hfetacl.c \
|
||||
|
hfetask.c \
|
||||
|
hfetdefs.h \
|
||||
|
hfetdel.c \
|
||||
|
hfetdest.c \
|
||||
|
hfetext.h \
|
||||
|
hfetgetic.c \
|
||||
|
hfetinit.c \
|
||||
|
hfetinit.h \
|
||||
|
hfetitf.h \
|
||||
|
hfetload.c \
|
||||
|
hfetmask.c \
|
||||
|
hfetmdel.c \
|
||||
|
hfetmpar.c \
|
||||
|
hfetparam.c \
|
||||
|
hfetsetup.c \
|
||||
|
hfettemp.c \
|
||||
|
hfettrunc.c |
||||
|
|
||||
|
|
||||
|
|
||||
|
INCLUDES = -I$(top_srcdir)/src/include |
||||
|
MAINTAINERCLEANFILES = Makefile.in |
||||
@ -0,0 +1,120 @@ |
|||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "ifsim.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
IFparm HFETApTable[] = { /* parameters */ |
||||
|
OP("off", HFETA_OFF, IF_FLAG ,"Device initially off"), |
||||
|
IOP("l", HFETA_LENGTH, IF_REAL ,"Length of device"), |
||||
|
IOP("w", HFETA_WIDTH, IF_REAL ,"Width of device"), |
||||
|
IOP("icvds", HFETA_IC_VDS, IF_REAL ,"Initial D-S voltage"), |
||||
|
IOP("icvgs", HFETA_IC_VGS, IF_REAL ,"Initial G-S voltage"), |
||||
|
IOP("temp", HFETA_TEMP, IF_REAL ,"Instance temperature"), |
||||
|
OP("dnode", HFETA_DRAINNODE, IF_INTEGER,"Number of drain node"), |
||||
|
OP("gnode", HFETA_GATENODE, IF_INTEGER,"Number of gate node"), |
||||
|
OP("snode", HFETA_SOURCENODE, IF_INTEGER,"Number of source node"), |
||||
|
OP("dprimenode",HFETA_DRAINPRIMENODE, IF_INTEGER,"Number of internal drain node"), |
||||
|
OP("sprimenode",HFETA_SOURCEPRIMENODE,IF_INTEGER,"Number of internal source node"), |
||||
|
OP("vgs", HFETA_VGS, IF_REAL,"Gate-Source voltage"), |
||||
|
OP("vgd", HFETA_VGD, IF_REAL,"Gate-Drain voltage"), |
||||
|
OP("cg", HFETA_CG, IF_REAL,"Gate capacitance"), |
||||
|
OP("cd", HFETA_CD, IF_REAL,"Drain capacitance"), |
||||
|
OP("cgd", HFETA_CGD, IF_REAL,"Gate_Drain capacitance"), |
||||
|
OP("gm", HFETA_GM, IF_REAL,"Transconductance"), |
||||
|
OP("gds", HFETA_GDS, IF_REAL,"Drain-Source conductance"), |
||||
|
OP("ggs", HFETA_GGS, IF_REAL,"Gate-Source conductance"), |
||||
|
OP("ggd", HFETA_GGD, IF_REAL,"Gate-Drain conductance"), |
||||
|
OP("qgs", HFETA_QGS, IF_REAL,"Gate-Source charge storage"), |
||||
|
OP("cqgs", HFETA_CQGS, IF_REAL,"Capacitance due to gate-source charge storage"), |
||||
|
OP("qgd", HFETA_QGD, IF_REAL,"Gate-Drain charge storage"), |
||||
|
OP("cqgd", HFETA_CQGD, IF_REAL,"Capacitance due to gate-drain charge storage"), |
||||
|
OP("cs", HFETA_CS, IF_REAL ,"Source current"), |
||||
|
OP("p", HFETA_POWER, IF_REAL ,"Power dissipated by the mesfet") |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
IFparm HFETAmPTable[] = { /* model parameters */ |
||||
|
IOP( "vt0", HFETA_MOD_VTO, IF_REAL,"Pinch-off voltage"), |
||||
|
IOP( "vto", HFETA_MOD_VTO, IF_REAL,"Pinch-off voltage"), |
||||
|
IOP( "lambda", HFETA_MOD_LAMBDA, IF_REAL,"Output conductance parameter"), |
||||
|
IOP( "rd", HFETA_MOD_RD, IF_REAL,"Drain ohmic resistance"), |
||||
|
IOP( "rs", HFETA_MOD_RS, IF_REAL,"Source ohmic resistance"), |
||||
|
IOP( "rg", HFETA_MOD_RG, IF_REAL,"Gate ohmic resistance"), |
||||
|
IOP( "rdi", HFETA_MOD_RDI, IF_REAL,"Drain ohmic resistance"), |
||||
|
IOP( "rsi", HFETA_MOD_RSI, IF_REAL,"Source ohmic resistance"), |
||||
|
IOP( "rgs", HFETA_MOD_RGS, IF_REAL,"Gate-source ohmic resistance"), |
||||
|
IOP( "rgd", HFETA_MOD_RGD, IF_REAL,"Gate-drain ohmic resistance"), |
||||
|
IOP( "ri", HFETA_MOD_RI, IF_REAL,""), |
||||
|
IOP( "rf", HFETA_MOD_RF, IF_REAL,""), |
||||
|
IOP( "eta", HFETA_MOD_ETA, IF_REAL,"Subthreshold ideality factor"), |
||||
|
IOP( "m", HFETA_MOD_M, IF_REAL,"Knee shape parameter"), |
||||
|
IOP( "mc", HFETA_MOD_MC, IF_REAL,"Knee shape parameter"), |
||||
|
IOP( "gamma", HFETA_MOD_GAMMA, IF_REAL,"Knee shape parameter"), |
||||
|
IOP( "sigma0", HFETA_MOD_SIGMA0, IF_REAL,"Threshold voltage coefficient"), |
||||
|
IOP( "vsigmat", HFETA_MOD_VSIGMAT,IF_REAL,""), |
||||
|
IOP( "vsigma", HFETA_MOD_VSIGMA, IF_REAL,""), |
||||
|
IOP( "mu", HFETA_MOD_MU, IF_REAL,"Moblity"), |
||||
|
IOP( "di", HFETA_MOD_DI, IF_REAL,"Depth of device"), |
||||
|
IOP( "delta", HFETA_MOD_DELTA, IF_REAL,""), |
||||
|
IOP( "vs", HFETA_MOD_VS, IF_REAL,"Saturation velocity"), |
||||
|
IOP( "nmax", HFETA_MOD_NMAX, IF_REAL,""), |
||||
|
IOP( "deltad", HFETA_MOD_DELTAD, IF_REAL,"Thickness correction"), |
||||
|
IOP( "js1d", HFETA_MOD_JS1D, IF_REAL,""), |
||||
|
IOP( "js2d", HFETA_MOD_JS2D, IF_REAL,""), |
||||
|
IOP( "js1s", HFETA_MOD_JS1S, IF_REAL,""), |
||||
|
IOP( "js2s", HFETA_MOD_JS2S, IF_REAL,""), |
||||
|
IOP( "m1d", HFETA_MOD_M1D, IF_REAL,""), |
||||
|
IOP( "m2d", HFETA_MOD_M2D, IF_REAL,""), |
||||
|
IOP( "m1s", HFETA_MOD_M1S, IF_REAL,""), |
||||
|
IOP( "m2s", HFETA_MOD_M2S, IF_REAL,""), |
||||
|
IOP( "epsi", HFETA_MOD_EPSI, IF_REAL,""), |
||||
|
IOP( "p", HFETA_MOD_P, IF_REAL,""), |
||||
|
IOP( "cm3", HFETA_MOD_CM3, IF_REAL,""), |
||||
|
IOP( "a1", HFETA_MOD_A1, IF_REAL,""), |
||||
|
IOP( "a2", HFETA_MOD_A2, IF_REAL,""), |
||||
|
IOP( "mv1", HFETA_MOD_MV1, IF_REAL,""), |
||||
|
IOP( "kappa", HFETA_MOD_KAPPA, IF_REAL,""), |
||||
|
IOP( "delf", HFETA_MOD_DELF, IF_REAL,""), |
||||
|
IOP( "fgds", HFETA_MOD_FGDS, IF_REAL,""), |
||||
|
IOP( "tf", HFETA_MOD_TF, IF_REAL,""), |
||||
|
IOP( "cds", HFETA_MOD_CDS, IF_REAL,""), |
||||
|
IOP( "phib", HFETA_MOD_PHIB, IF_REAL,""), |
||||
|
IOP( "talpha", HFETA_MOD_TALPHA, IF_REAL,""), |
||||
|
IOP( "mt1", HFETA_MOD_MT1, IF_REAL,""), |
||||
|
IOP( "mt2", HFETA_MOD_MT2, IF_REAL,""), |
||||
|
IOP( "ck1", HFETA_MOD_CK1, IF_REAL,""), |
||||
|
IOP( "ck2", HFETA_MOD_CK2, IF_REAL,""), |
||||
|
IOP( "cm1", HFETA_MOD_CM1, IF_REAL,""), |
||||
|
IOP( "cm2", HFETA_MOD_CM2, IF_REAL,""), |
||||
|
IOP( "astar", HFETA_MOD_ASTAR, IF_REAL,""), |
||||
|
IOP( "eta1", HFETA_MOD_ETA1, IF_REAL,""), |
||||
|
IOP( "d1", HFETA_MOD_D1, IF_REAL,""), |
||||
|
IOP( "vt1", HFETA_MOD_VT1, IF_REAL,""), |
||||
|
IOP( "eta2", HFETA_MOD_ETA2, IF_REAL,""), |
||||
|
IOP( "d2", HFETA_MOD_D2, IF_REAL,""), |
||||
|
IOP( "vt2", HFETA_MOD_VT2, IF_REAL,""), |
||||
|
IOP( "ggr", HFETA_MOD_GGR, IF_REAL,""), |
||||
|
IOP( "del", HFETA_MOD_DEL, IF_REAL,""), |
||||
|
IOP( "gatemod", HFETA_MOD_GATEMOD,IF_INTEGER,""), |
||||
|
IOP( "klambda", HFETA_MOD_KLAMBDA, IF_REAL,""), |
||||
|
IOP( "kmu", HFETA_MOD_KMU, IF_REAL,""), |
||||
|
IOP( "kvto", HFETA_MOD_KVTO, IF_REAL,""), |
||||
|
OP( "type", HFETA_MOD_TYPE, IF_STRING, "NHFET or PHFET"), |
||||
|
IOP( "nhfet", HFETA_MOD_NHFET, IF_FLAG,"N HFET device"), |
||||
|
IOP( "phfet", HFETA_MOD_PHFET, IF_FLAG,"P HFET device"), |
||||
|
}; |
||||
|
|
||||
|
char *HFETAnames[] = { |
||||
|
"Drain", |
||||
|
"Gate", |
||||
|
"Source" |
||||
|
}; |
||||
|
|
||||
|
int HFETAnSize = NUMELEMS(HFETAnames); |
||||
|
int HFETApTSize = NUMELEMS(HFETApTable); |
||||
|
int HFETAmPTSize = NUMELEMS(HFETAmPTable); |
||||
|
int HFETAiSize = sizeof(HFETAinstance); |
||||
|
int HFETAmSize = sizeof(HFETAmodel); |
||||
@ -0,0 +1,88 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
HFETAacLoad(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
HFETAmodel *model = (HFETAmodel*)inModel; |
||||
|
HFETAinstance *here; |
||||
|
double gm; |
||||
|
double gds; |
||||
|
double xds; |
||||
|
double ggs; |
||||
|
double xgs; |
||||
|
double ggd; |
||||
|
double xgd; |
||||
|
double ggspp; |
||||
|
double ggdpp; |
||||
|
double f; |
||||
|
|
||||
|
for( ; model != NULL; model = model->HFETAnextModel ) |
||||
|
{ |
||||
|
for( here = model->HFETAinstances; here != NULL; |
||||
|
here = here->HFETAnextInstance) |
||||
|
{ |
||||
|
gm = *(ckt->CKTstate0 + here->HFETAgm); |
||||
|
gds = *(ckt->CKTstate0 + here->HFETAgds); |
||||
|
xds = CDS*ckt->CKTomega; |
||||
|
ggs = *(ckt->CKTstate0 + here->HFETAggs); |
||||
|
xgs = *(ckt->CKTstate0 + here->HFETAqgs) * ckt->CKTomega; |
||||
|
ggd = *(ckt->CKTstate0 + here->HFETAggd); |
||||
|
xgd = *(ckt->CKTstate0 + here->HFETAqgd) * ckt->CKTomega; |
||||
|
ggspp = *(ckt->CKTstate0 + here->HFETAggspp); |
||||
|
ggdpp = *(ckt->CKTstate0 + here->HFETAggdpp); |
||||
|
if(model->HFETAkappaGiven && here->HFETAdelf != 0.0) { |
||||
|
f = ckt->CKTomega/2/M_PI; |
||||
|
gds = gds*(1+0.5*model->HFETAkappa*(1+tanh((f-here->HFETAfgds)/here->HFETAdelf))); |
||||
|
} |
||||
|
*(here->HFETAdrainDrainPtr) += model->HFETAdrainConduct; |
||||
|
*(here->HFETAsourceSourcePtr) += model->HFETAsourceConduct; |
||||
|
*(here->HFETAgatePrimeGatePrimePtr) += (ggd+ggs+ggspp+ggdpp+model->HFETAgateConduct); |
||||
|
*(here->HFETAdrainPrimeDrainPrimePtr) += (gds+ggd+model->HFETAdrainConduct+model->HFETAgf); |
||||
|
*(here->HFETAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+model->HFETAsourceConduct+model->HFETAgi); |
||||
|
*(here->HFETAsourcePrmPrmSourcePrmPrmPtr) += (model->HFETAgi+ggspp); |
||||
|
*(here->HFETAdrainPrmPrmDrainPrmPrmPtr) += (model->HFETAgf+ggdpp); |
||||
|
*(here->HFETAdrainDrainPrimePtr) -= model->HFETAdrainConduct; |
||||
|
*(here->HFETAdrainPrimeDrainPtr) -= model->HFETAdrainConduct; |
||||
|
*(here->HFETAsourceSourcePrimePtr) -= model->HFETAsourceConduct; |
||||
|
*(here->HFETAsourcePrimeSourcePtr) -= model->HFETAsourceConduct; |
||||
|
*(here->HFETAgatePrimeDrainPrimePtr) -= ggd; |
||||
|
*(here->HFETAdrainPrimeGatePrimePtr) += (gm-ggd); |
||||
|
*(here->HFETAgatePrimeSourcePrimePtr) -= ggs; |
||||
|
*(here->HFETAsourcePrimeGatePrimePtr) += (-ggs-gm); |
||||
|
*(here->HFETAdrainPrimeSourcePrimePtr) += (-gds-gm); |
||||
|
*(here->HFETAsourcePrimeDrainPrimePtr) -= gds; |
||||
|
*(here->HFETAsourcePrimeSourcePrmPrmPtr) -= model->HFETAgi; |
||||
|
*(here->HFETAsourcePrmPrmSourcePrimePtr) -= model->HFETAgi; |
||||
|
*(here->HFETAgatePrimeSourcePrmPrmPtr) -= ggspp; |
||||
|
*(here->HFETAsourcePrmPrmGatePrimePtr) -= ggspp; |
||||
|
*(here->HFETAdrainPrimeDrainPrmPrmPtr) -= model->HFETAgf; |
||||
|
*(here->HFETAdrainPrmPrmDrainPrimePtr) -= model->HFETAgf; |
||||
|
*(here->HFETAgatePrimeDrainPrmPrmPtr) -= ggdpp; |
||||
|
*(here->HFETAdrainPrmPrmGatePrimePtr) -= ggdpp; |
||||
|
*(here->HFETAgateGatePtr) += model->HFETAgateConduct; |
||||
|
*(here->HFETAgateGatePrimePtr) -= model->HFETAgateConduct; |
||||
|
*(here->HFETAgatePrimeGatePtr) -= model->HFETAgateConduct; |
||||
|
*(here->HFETAgatePrimeGatePrimePtr+1) += xgd+xgs; |
||||
|
*(here->HFETAdrainPrmPrmDrainPrmPrmPtr+1) += xgd; |
||||
|
*(here->HFETAsourcePrmPrmSourcePrmPrmPtr+1) += xgs; |
||||
|
*(here->HFETAgatePrimeDrainPrmPrmPtr+1) -= xgd; |
||||
|
*(here->HFETAgatePrimeSourcePrmPrmPtr+1) -= xgs; |
||||
|
*(here->HFETAdrainPrmPrmGatePrimePtr+1) -= xgd; |
||||
|
*(here->HFETAsourcePrmPrmGatePrimePtr+1) -= xgs; |
||||
|
*(here->HFETAdrainPrimeDrainPrimePtr+1) += xds; |
||||
|
*(here->HFETAsourcePrimeSourcePrimePtr+1) += xds; |
||||
|
*(here->HFETAdrainPrimeSourcePrimePtr+1) -= xds; |
||||
|
*(here->HFETAsourcePrimeDrainPrimePtr+1) -= xds; |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,132 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1987 Thomas L. Quarles |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into HFETA source: Paolo Nenzi 2001 |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/* ARGSUSED */ |
||||
|
int |
||||
|
HFETAask(ckt,inst,which,value,select) |
||||
|
CKTcircuit *ckt; |
||||
|
GENinstance *inst; |
||||
|
int which; |
||||
|
IFvalue *value; |
||||
|
IFvalue *select; |
||||
|
{ |
||||
|
HFETAinstance *here = (HFETAinstance*)inst; |
||||
|
static char *msg = "Current and power not available in ac analysis"; |
||||
|
switch(which) { |
||||
|
case HFETA_LENGTH: |
||||
|
value->rValue = here->HFETAlength; |
||||
|
return (OK); |
||||
|
case HFETA_WIDTH: |
||||
|
value->rValue = here->HFETAwidth; |
||||
|
case HFETA_IC_VDS: |
||||
|
value->rValue = here->HFETAicVDS; |
||||
|
return (OK); |
||||
|
case HFETA_IC_VGS: |
||||
|
value->rValue = here->HFETAicVGS; |
||||
|
return (OK); |
||||
|
case HFETA_OFF: |
||||
|
value->iValue = here->HFETAoff; |
||||
|
return (OK); |
||||
|
case HFETA_DRAINNODE: |
||||
|
value->iValue = here->HFETAdrainNode; |
||||
|
return (OK); |
||||
|
case HFETA_GATENODE: |
||||
|
value->iValue = here->HFETAgateNode; |
||||
|
return (OK); |
||||
|
case HFETA_SOURCENODE: |
||||
|
value->iValue = here->HFETAsourceNode; |
||||
|
return (OK); |
||||
|
case HFETA_DRAINPRIMENODE: |
||||
|
value->iValue = here->HFETAdrainPrimeNode; |
||||
|
return (OK); |
||||
|
case HFETA_SOURCEPRIMENODE: |
||||
|
value->iValue = here->HFETAsourcePrimeNode; |
||||
|
return (OK); |
||||
|
case HFETA_TEMP: |
||||
|
value->rValue = here->HFETAtemp; |
||||
|
case HFETA_VGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAvgs); |
||||
|
return (OK); |
||||
|
case HFETA_VGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAvgd); |
||||
|
return (OK); |
||||
|
case HFETA_CG: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAcg); |
||||
|
return (OK); |
||||
|
case HFETA_CD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAcd); |
||||
|
return (OK); |
||||
|
case HFETA_CGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAcgd); |
||||
|
return (OK); |
||||
|
case HFETA_GM: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAgm); |
||||
|
return (OK); |
||||
|
case HFETA_GDS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAgds); |
||||
|
return (OK); |
||||
|
case HFETA_GGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAggs); |
||||
|
return (OK); |
||||
|
case HFETA_GGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAggd); |
||||
|
return (OK); |
||||
|
case HFETA_QGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAqgs); |
||||
|
return (OK); |
||||
|
case HFETA_CQGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAcqgs); |
||||
|
return (OK); |
||||
|
case HFETA_QGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAqgd); |
||||
|
return (OK); |
||||
|
case HFETA_CQGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAcqgd); |
||||
|
return (OK); |
||||
|
case HFETA_CS : |
||||
|
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
||||
|
errMsg = MALLOC(strlen(msg)+1); |
||||
|
errRtn = "HFETAask"; |
||||
|
strcpy(errMsg,msg); |
||||
|
return(E_ASKCURRENT); |
||||
|
} else { |
||||
|
value->rValue = -*(ckt->CKTstate0 + here->HFETAcd); |
||||
|
value->rValue -= *(ckt->CKTstate0 + here->HFETAcg); |
||||
|
} |
||||
|
return(OK); |
||||
|
case HFETA_POWER : |
||||
|
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
||||
|
errMsg = MALLOC(strlen(msg)+1); |
||||
|
errRtn = "HFETAask"; |
||||
|
strcpy(errMsg,msg); |
||||
|
return(E_ASKPOWER); |
||||
|
} else { |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFETAcd) * |
||||
|
*(ckt->CKTrhsOld + here->HFETAdrainNode); |
||||
|
value->rValue += *(ckt->CKTstate0 + here->HFETAcg) * |
||||
|
*(ckt->CKTrhsOld + here->HFETAgateNode); |
||||
|
value->rValue -= (*(ckt->CKTstate0+here->HFETAcd) + |
||||
|
*(ckt->CKTstate0 + here->HFETAcg)) * |
||||
|
*(ckt->CKTrhsOld + here->HFETAsourceNode); |
||||
|
} |
||||
|
return(OK); |
||||
|
default: |
||||
|
return (E_BADPARM); |
||||
|
} |
||||
|
/* NOTREACHED */ |
||||
|
} |
||||
@ -0,0 +1,466 @@ |
|||||
|
#ifndef HFETA |
||||
|
#define HFETA |
||||
|
|
||||
|
#include "ifsim.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "gendefs.h" |
||||
|
#include "complex.h" |
||||
|
#include "noisedef.h" |
||||
|
|
||||
|
#define HFETAnumStates 24 |
||||
|
|
||||
|
typedef struct sHFETAinstance { |
||||
|
struct sHFETAmodel *HFETAmodPtr; |
||||
|
struct sHFETAinstance *HFETAnextInstance; |
||||
|
IFuid HFETAname; |
||||
|
int HFETAowner; /* number of owner process */ |
||||
|
int HFETAstate; /* index into state table for this device */ |
||||
|
|
||||
|
int HFETAdrainNode; |
||||
|
int HFETAgateNode; |
||||
|
int HFETAsourceNode; |
||||
|
int HFETAdrainPrimeNode; |
||||
|
int HFETAgatePrimeNode; |
||||
|
int HFETAsourcePrimeNode; |
||||
|
int HFETAdrainPrmPrmNode; |
||||
|
int HFETAsourcePrmPrmNode; |
||||
|
double HFETAlength; |
||||
|
double HFETAwidth; |
||||
|
double HFETAicVDS; |
||||
|
double HFETAicVGS; |
||||
|
double HFETAtemp; |
||||
|
double HFETAtVto; |
||||
|
double HFETAtMu; |
||||
|
double HFETAtLambda; |
||||
|
double HFETAtLambdahf; |
||||
|
double *HFETAdrainDrainPrimePtr; |
||||
|
double *HFETAgatePrimeDrainPrimePtr; |
||||
|
double *HFETAgatePrimeSourcePrimePtr; |
||||
|
double *HFETAsourceSourcePrimePtr; |
||||
|
double *HFETAdrainPrimeDrainPtr; |
||||
|
double *HFETAdrainPrimeGatePrimePtr; |
||||
|
double *HFETAdrainPrimeSourcePrimePtr; |
||||
|
double *HFETAsourcePrimeGatePrimePtr; |
||||
|
double *HFETAsourcePrimeSourcePtr; |
||||
|
double *HFETAsourcePrimeDrainPrimePtr; |
||||
|
double *HFETAdrainDrainPtr; |
||||
|
double *HFETAgatePrimeGatePrimePtr; |
||||
|
double *HFETAsourceSourcePtr; |
||||
|
double *HFETAdrainPrimeDrainPrimePtr; |
||||
|
double *HFETAsourcePrimeSourcePrimePtr; |
||||
|
double *HFETAdrainPrmPrmDrainPrmPrmPtr; |
||||
|
double *HFETAdrainPrmPrmDrainPrimePtr; |
||||
|
double *HFETAdrainPrimeDrainPrmPrmPtr; |
||||
|
double *HFETAdrainPrmPrmGatePrimePtr; |
||||
|
double *HFETAgatePrimeDrainPrmPrmPtr; |
||||
|
double *HFETAsourcePrmPrmSourcePrmPrmPtr; |
||||
|
double *HFETAsourcePrmPrmSourcePrimePtr; |
||||
|
double *HFETAsourcePrimeSourcePrmPrmPtr; |
||||
|
double *HFETAsourcePrmPrmGatePrimePtr; |
||||
|
double *HFETAgatePrimeSourcePrmPrmPtr; |
||||
|
double *HFETAgateGatePtr; |
||||
|
double *HFETAgateGatePrimePtr; |
||||
|
double *HFETAgatePrimeGatePtr; |
||||
|
|
||||
|
|
||||
|
#define HFETAvgs HFETAstate |
||||
|
#define HFETAvgd HFETAstate+1 |
||||
|
#define HFETAcg HFETAstate+2 |
||||
|
#define HFETAcd HFETAstate+3 |
||||
|
#define HFETAcgd HFETAstate+4 |
||||
|
#define HFETAcgs HFETAstate+5 |
||||
|
#define HFETAgm HFETAstate+6 |
||||
|
#define HFETAgds HFETAstate+7 |
||||
|
#define HFETAggs HFETAstate+8 |
||||
|
#define HFETAggd HFETAstate+9 |
||||
|
#define HFETAqgs HFETAstate+10 |
||||
|
#define HFETAcqgs HFETAstate+11 |
||||
|
#define HFETAqgd HFETAstate+12 |
||||
|
#define HFETAcqgd HFETAstate+13 |
||||
|
#define HFETAvgspp HFETAstate+14 |
||||
|
#define HFETAggspp HFETAstate+15 |
||||
|
#define HFETAcgspp HFETAstate+16 |
||||
|
#define HFETAvgdpp HFETAstate+17 |
||||
|
#define HFETAggdpp HFETAstate+18 |
||||
|
#define HFETAcgdpp HFETAstate+19 |
||||
|
#define HFETAqds HFETAstate+20 |
||||
|
#define HFETAcqds HFETAstate+21 |
||||
|
#define HFETAgmg HFETAstate+22 |
||||
|
#define HFETAgmd HFETAstate+23 |
||||
|
|
||||
|
|
||||
|
|
||||
|
int HFETAoff; |
||||
|
unsigned HFETAlengthGiven : 1; |
||||
|
unsigned HFETAwidthGiven : 1; |
||||
|
unsigned HFETAicVDSGiven : 1; |
||||
|
unsigned HFETAicVGSGiven : 1; |
||||
|
unsigned HFETAtempGiven : 1; |
||||
|
int HFETAmode; |
||||
|
|
||||
|
double HFETAn0; |
||||
|
double HFETAn01; |
||||
|
double HFETAn02; |
||||
|
double HFETAgchi0; |
||||
|
double HFETAcf; |
||||
|
double HFETAis1d; |
||||
|
double HFETAis2d; |
||||
|
double HFETAis1s; |
||||
|
double HFETAis2s; |
||||
|
double HFETAiso; |
||||
|
double HFETAimax; |
||||
|
double HFETAvcrit; |
||||
|
double HFETAdelf; |
||||
|
double HFETAfgds; |
||||
|
double HFETAggrwl; |
||||
|
|
||||
|
} HFETAinstance ; |
||||
|
|
||||
|
|
||||
|
/* per model data */ |
||||
|
|
||||
|
typedef struct sHFETAmodel { |
||||
|
int HFETAmodType; |
||||
|
struct sHFETAmodel *HFETAnextModel; |
||||
|
HFETAinstance *HFETAinstances; |
||||
|
IFuid HFETAmodName; |
||||
|
int HFETAtype; |
||||
|
int HFETAgatemod; |
||||
|
|
||||
|
double HFETAthreshold; |
||||
|
double HFETAlambda; |
||||
|
double HFETAeta; |
||||
|
double HFETAm; |
||||
|
double HFETAmc; |
||||
|
double HFETAgamma; |
||||
|
double HFETAsigma0; |
||||
|
double HFETAvsigmat; |
||||
|
double HFETAvsigma; |
||||
|
double HFETAmu; |
||||
|
double HFETAdi; |
||||
|
double HFETAdelta; |
||||
|
double HFETAvs; |
||||
|
double HFETAnmax; |
||||
|
double HFETAdeltad; |
||||
|
double HFETAjs1d; |
||||
|
double HFETAjs2d; |
||||
|
double HFETAjs1s; |
||||
|
double HFETAjs2s; |
||||
|
double HFETAm1d; |
||||
|
double HFETAm2d; |
||||
|
double HFETAm1s; |
||||
|
double HFETAm2s; |
||||
|
double HFETArd; |
||||
|
double HFETArs; |
||||
|
double HFETArg; |
||||
|
double HFETArdi; |
||||
|
double HFETArsi; |
||||
|
double HFETArgs; |
||||
|
double HFETArgd; |
||||
|
double HFETAri; |
||||
|
double HFETArf; |
||||
|
double HFETAepsi; |
||||
|
double HFETAa1; |
||||
|
double HFETAa2; |
||||
|
double HFETAmv1; |
||||
|
double HFETAp; |
||||
|
double HFETAkappa; |
||||
|
double HFETAdelf; |
||||
|
double HFETAfgds; |
||||
|
double HFETAtf; |
||||
|
double HFETAcds; |
||||
|
double HFETAphib; |
||||
|
double HFETAtalpha; |
||||
|
double HFETAmt1; |
||||
|
double HFETAmt2; |
||||
|
double HFETAck1; |
||||
|
double HFETAck2; |
||||
|
double HFETAcm1; |
||||
|
double HFETAcm2; |
||||
|
double HFETAcm3; |
||||
|
double HFETAastar; |
||||
|
double HFETAeta1; |
||||
|
double HFETAd1; |
||||
|
double HFETAvt1; |
||||
|
double HFETAeta2; |
||||
|
double HFETAd2; |
||||
|
double HFETAvt2; |
||||
|
double HFETAggr; |
||||
|
double HFETAdel; |
||||
|
double HFETAklambda; |
||||
|
double HFETAkmu; |
||||
|
double HFETAkvto; |
||||
|
|
||||
|
double HFETAdrainConduct; |
||||
|
double HFETAsourceConduct; |
||||
|
double HFETAgateConduct; |
||||
|
double HFETAgi; |
||||
|
double HFETAgf; |
||||
|
double HFETAdeltaSqr; |
||||
|
|
||||
|
unsigned HFETAgatemodGiven:1; |
||||
|
unsigned HFETAthresholdGiven:1; |
||||
|
unsigned HFETAlambdaGiven:1; |
||||
|
unsigned HFETAetaGiven:1; |
||||
|
unsigned HFETAmGiven:1; |
||||
|
unsigned HFETAmcGiven:1; |
||||
|
unsigned HFETAgammaGiven:1; |
||||
|
unsigned HFETAsigma0Given:1; |
||||
|
unsigned HFETAvsigmatGiven:1; |
||||
|
unsigned HFETAvsigmaGiven:1; |
||||
|
unsigned HFETAmuGiven:1; |
||||
|
unsigned HFETAdiGiven:1; |
||||
|
unsigned HFETAdeltaGiven:1; |
||||
|
unsigned HFETAvsGiven:1; |
||||
|
unsigned HFETAnmaxGiven:1; |
||||
|
unsigned HFETAdeltadGiven:1; |
||||
|
unsigned HFETAjs1dGiven:1; |
||||
|
unsigned HFETAjs2dGiven:1; |
||||
|
unsigned HFETAjs1sGiven:1; |
||||
|
unsigned HFETAjs2sGiven:1; |
||||
|
unsigned HFETAm1dGiven:1; |
||||
|
unsigned HFETAm2dGiven:1; |
||||
|
unsigned HFETAm1sGiven:1; |
||||
|
unsigned HFETAm2sGiven:1; |
||||
|
unsigned HFETArdGiven:1; |
||||
|
unsigned HFETArsGiven:1; |
||||
|
unsigned HFETArgGiven:1; |
||||
|
unsigned HFETArdiGiven:1; |
||||
|
unsigned HFETArsiGiven:1; |
||||
|
unsigned HFETArgsGiven:1; |
||||
|
unsigned HFETArgdGiven:1; |
||||
|
unsigned HFETAriGiven:1; |
||||
|
unsigned HFETArfGiven:1; |
||||
|
unsigned HFETAepsiGiven:1; |
||||
|
unsigned HFETAa1Given:1; |
||||
|
unsigned HFETAa2Given:1; |
||||
|
unsigned HFETAmv1Given:1; |
||||
|
unsigned HFETApGiven:1; |
||||
|
unsigned HFETAkappaGiven:1; |
||||
|
unsigned HFETAdelfGiven:1; |
||||
|
unsigned HFETAfgdsGiven:1; |
||||
|
unsigned HFETAtfGiven:1; |
||||
|
unsigned HFETAcdsGiven:1; |
||||
|
unsigned HFETAphibGiven:1; |
||||
|
unsigned HFETAtalphaGiven:1; |
||||
|
unsigned HFETAmt1Given:1; |
||||
|
unsigned HFETAmt2Given:1; |
||||
|
unsigned HFETAck1Given:1; |
||||
|
unsigned HFETAck2Given:1; |
||||
|
unsigned HFETAcm1Given:1; |
||||
|
unsigned HFETAcm2Given:1; |
||||
|
unsigned HFETAcm3Given:1; |
||||
|
unsigned HFETAastarGiven:1; |
||||
|
unsigned HFETAeta1Given:1; |
||||
|
unsigned HFETAd1Given:1; |
||||
|
unsigned HFETAvt1Given:1; |
||||
|
unsigned HFETAeta2Given:1; |
||||
|
unsigned HFETAd2Given:1; |
||||
|
unsigned HFETAvt2Given:1; |
||||
|
unsigned HFETAggrGiven:1; |
||||
|
unsigned HFETAdelGiven:1; |
||||
|
unsigned HFETAklambdaGiven:1; |
||||
|
unsigned HFETAkmuGiven:1; |
||||
|
unsigned HFETAkvtoGiven:1; |
||||
|
|
||||
|
} HFETAmodel; |
||||
|
|
||||
|
#ifndef NHFET |
||||
|
#define NHFET 1 |
||||
|
#define PHFET -1 |
||||
|
#endif |
||||
|
|
||||
|
/* device parameters */ |
||||
|
#define HFETA_LENGTH 1 |
||||
|
#define HFETA_WIDTH 2 |
||||
|
#define HFETA_IC_VDS 3 |
||||
|
#define HFETA_IC_VGS 4 |
||||
|
#define HFETA_TEMP 5 |
||||
|
#define HFETA_IC 6 |
||||
|
#define HFETA_OFF 7 |
||||
|
#define HFETA_CS 8 |
||||
|
#define HFETA_POWER 9 |
||||
|
|
||||
|
/* model parameters */ |
||||
|
#define HFETA_MOD_VTO 101 |
||||
|
#define HFETA_MOD_LAMBDA 102 |
||||
|
#define HFETA_MOD_RD 103 |
||||
|
#define HFETA_MOD_RS 104 |
||||
|
#define HFETA_MOD_RG 105 |
||||
|
#define HFETA_MOD_RGS 106 |
||||
|
#define HFETA_MOD_RGD 107 |
||||
|
#define HFETA_MOD_RI 108 |
||||
|
#define HFETA_MOD_RF 109 |
||||
|
#define HFETA_MOD_ETA 110 |
||||
|
#define HFETA_MOD_M 111 |
||||
|
#define HFETA_MOD_MC 112 |
||||
|
#define HFETA_MOD_GAMMA 113 |
||||
|
#define HFETA_MOD_SIGMA0 114 |
||||
|
#define HFETA_MOD_VSIGMAT 115 |
||||
|
#define HFETA_MOD_VSIGMA 116 |
||||
|
#define HFETA_MOD_MU 117 |
||||
|
#define HFETA_MOD_DI 118 |
||||
|
#define HFETA_MOD_DELTA 119 |
||||
|
#define HFETA_MOD_VS 120 |
||||
|
#define HFETA_MOD_NMAX 121 |
||||
|
#define HFETA_MOD_DELTAD 122 |
||||
|
#define HFETA_MOD_JS1D 123 |
||||
|
#define HFETA_MOD_JS2D 124 |
||||
|
#define HFETA_MOD_JS1S 125 |
||||
|
#define HFETA_MOD_JS2S 126 |
||||
|
#define HFETA_MOD_M1D 127 |
||||
|
#define HFETA_MOD_M2D 128 |
||||
|
#define HFETA_MOD_M1S 129 |
||||
|
#define HFETA_MOD_M2S 130 |
||||
|
#define HFETA_MOD_EPSI 132 |
||||
|
#define HFETA_MOD_RDI 133 |
||||
|
#define HFETA_MOD_RSI 134 |
||||
|
#define HFETA_MOD_A1 135 |
||||
|
#define HFETA_MOD_A2 136 |
||||
|
#define HFETA_MOD_MV1 137 |
||||
|
#define HFETA_MOD_P 138 |
||||
|
#define HFETA_MOD_KAPPA 139 |
||||
|
#define HFETA_MOD_DELF 140 |
||||
|
#define HFETA_MOD_FGDS 141 |
||||
|
#define HFETA_MOD_TF 142 |
||||
|
#define HFETA_MOD_CDS 143 |
||||
|
#define HFETA_MOD_PHIB 144 |
||||
|
#define HFETA_MOD_TALPHA 145 |
||||
|
#define HFETA_MOD_MT1 146 |
||||
|
#define HFETA_MOD_MT2 147 |
||||
|
#define HFETA_MOD_CK1 148 |
||||
|
#define HFETA_MOD_CK2 149 |
||||
|
#define HFETA_MOD_CM1 150 |
||||
|
#define HFETA_MOD_CM2 151 |
||||
|
#define HFETA_MOD_CM3 152 |
||||
|
#define HFETA_MOD_ASTAR 153 |
||||
|
#define HFETA_MOD_ETA1 154 |
||||
|
#define HFETA_MOD_D1 155 |
||||
|
#define HFETA_MOD_VT1 156 |
||||
|
#define HFETA_MOD_ETA2 157 |
||||
|
#define HFETA_MOD_D2 158 |
||||
|
#define HFETA_MOD_VT2 159 |
||||
|
#define HFETA_MOD_GGR 160 |
||||
|
#define HFETA_MOD_DEL 161 |
||||
|
#define HFETA_MOD_GATEMOD 162 |
||||
|
#define HFETA_MOD_KLAMBDA 163 |
||||
|
#define HFETA_MOD_KMU 164 |
||||
|
#define HFETA_MOD_KVTO 165 |
||||
|
#define HFETA_MOD_NHFET 166 |
||||
|
#define HFETA_MOD_PHFET 167 |
||||
|
#define HFETA_MOD_TYPE 168 |
||||
|
|
||||
|
/* device questions */ |
||||
|
|
||||
|
#define HFETA_DRAINNODE 201 |
||||
|
#define HFETA_GATENODE 202 |
||||
|
#define HFETA_SOURCENODE 203 |
||||
|
#define HFETA_DRAINPRIMENODE 204 |
||||
|
#define HFETA_SOURCEPRIMENODE 205 |
||||
|
|
||||
|
#define HFETA_VGS 206 |
||||
|
#define HFETA_VGD 207 |
||||
|
#define HFETA_CG 208 |
||||
|
#define HFETA_CD 209 |
||||
|
#define HFETA_CGD 210 |
||||
|
#define HFETA_GM 211 |
||||
|
#define HFETA_GDS 212 |
||||
|
#define HFETA_GGS 213 |
||||
|
#define HFETA_GGD 214 |
||||
|
#define HFETA_QGS 215 |
||||
|
#define HFETA_CQGS 216 |
||||
|
#define HFETA_QGD 217 |
||||
|
#define HFETA_CQGD 218 |
||||
|
|
||||
|
/* model questions */ |
||||
|
|
||||
|
#define HFETA_MOD_DRAINCONDUCT 301 |
||||
|
#define HFETA_MOD_SOURCECONDUCT 302 |
||||
|
#define HFETA_MOD_DEPLETIONCAP 303 |
||||
|
#define HFETA_MOD_VCRIT 304 |
||||
|
|
||||
|
|
||||
|
#define L (here->HFETAlength) |
||||
|
#define W (here->HFETAwidth) |
||||
|
#define VTO (model->HFETAthreshold) |
||||
|
#define LAMBDA (model->HFETAlambda) |
||||
|
#define RDI (model->HFETArdi) |
||||
|
#define RSI (model->HFETArsi) |
||||
|
#define RD (model->HFETArd) |
||||
|
#define RS (model->HFETArs) |
||||
|
#define RG (model->HFETArg) |
||||
|
#define RF (model->HFETArf) |
||||
|
#define RI (model->HFETAri) |
||||
|
#define RGS (model->HFETArgs) |
||||
|
#define RGD (model->HFETArgd) |
||||
|
#define ETA (model->HFETAeta) |
||||
|
#define M (model->HFETAm) |
||||
|
#define MC (model->HFETAmc) |
||||
|
#define GAMMA (model->HFETAgamma) |
||||
|
#define SIGMA0 (model->HFETAsigma0) |
||||
|
#define VSIGMAT (model->HFETAvsigmat) |
||||
|
#define VSIGMA (model->HFETAvsigma) |
||||
|
#define MU (model->HFETAmu) |
||||
|
#define DI (model->HFETAdi) |
||||
|
#define DELTAD (model->HFETAdeltad) |
||||
|
#define DELTASQR (model->HFETAdeltaSqr) |
||||
|
#define VS (model->HFETAvs) |
||||
|
#define NMAX (model->HFETAnmax) |
||||
|
#define EPSI (model->HFETAepsi) |
||||
|
#define JS1D (model->HFETAjs1d) |
||||
|
#define JS2D (model->HFETAjs2d) |
||||
|
#define JS1S (model->HFETAjs1s) |
||||
|
#define JS2S (model->HFETAjs2s) |
||||
|
#define M1D (model->HFETAm1d) |
||||
|
#define M2D (model->HFETAm2d) |
||||
|
#define M1S (model->HFETAm1s) |
||||
|
#define M2S (model->HFETAm2s) |
||||
|
#define ASTAR (model->HFETAastar) |
||||
|
#define PHIB (model->HFETAphib) |
||||
|
#define TALPHA (model->HFETAtalpha) |
||||
|
#define MT1 (model->HFETAmt1) |
||||
|
#define MT2 (model->HFETAmt2) |
||||
|
#define CK1 (model->HFETAck1) |
||||
|
#define CK2 (model->HFETAck2) |
||||
|
#define CM1 (model->HFETAcm1) |
||||
|
#define CM2 (model->HFETAcm2) |
||||
|
#define CM3 (model->HFETAcm3) |
||||
|
#define A1 (model->HFETAa1) |
||||
|
#define A2 (model->HFETAa2) |
||||
|
#define MV1 (model->HFETAmv1) |
||||
|
#define PM (model->HFETAp) |
||||
|
#define CDS (model->HFETAcds) |
||||
|
#define ETA1 (model->HFETAeta1) |
||||
|
#define D1 (model->HFETAd1) |
||||
|
#define IN_VT1 (model->HFETAvt1) /* VT1 was defined in termios.h */ |
||||
|
#define ETA2 (model->HFETAeta2) |
||||
|
#define D2 (model->HFETAd2) |
||||
|
#define VT2 (model->HFETAvt2) |
||||
|
#define GGR (model->HFETAggr) |
||||
|
#define DEL (model->HFETAdel) |
||||
|
#define KLAMBDA (model->HFETAklambda) |
||||
|
#define KMU (model->HFETAkmu) |
||||
|
#define KVTO (model->HFETAkvto) |
||||
|
|
||||
|
#define GCHI0 (here->HFETAgchi0) |
||||
|
#define N0 (here->HFETAn0) |
||||
|
#define N01 (here->HFETAn01) |
||||
|
#define N02 (here->HFETAn02) |
||||
|
#define CF (here->HFETAcf) |
||||
|
#define IMAX (here->HFETAimax) |
||||
|
#define ISO (here->HFETAiso) |
||||
|
#define TEMP (here->HFETAtemp) |
||||
|
#define IS1D (here->HFETAis1d) |
||||
|
#define IS2D (here->HFETAis2d) |
||||
|
#define IS1S (here->HFETAis1s) |
||||
|
#define IS2S (here->HFETAis2s) |
||||
|
#define FGDS (here->HFETAfgds) |
||||
|
#define DELF (here->HFETAdelf) |
||||
|
#define GGRWL (here->HFETAggrwl) |
||||
|
#define TLAMBDA (here->HFETAtLambda) |
||||
|
#define TMU (here->HFETAtMu) |
||||
|
#define TVTO (here->HFETAtVto) |
||||
|
|
||||
|
#include "hfetext.h" |
||||
|
|
||||
|
#endif /*HFETA*/ |
||||
@ -0,0 +1,39 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 S. Hwang |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into hfeta model: Paolo Nenzi 2001 |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "hfetdefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
HFETAdelete(inModel,name,inst) |
||||
|
GENmodel *inModel; |
||||
|
IFuid name; |
||||
|
GENinstance **inst; |
||||
|
{ |
||||
|
HFETAmodel *model = (HFETAmodel*)inModel; |
||||
|
HFETAinstance **fast = (HFETAinstance**)inst; |
||||
|
HFETAinstance **prev = NULL; |
||||
|
HFETAinstance *here; |
||||
|
|
||||
|
for( ; model ; model = model->HFETAnextModel) { |
||||
|
prev = &(model->HFETAinstances); |
||||
|
for(here = *prev; here ; here = *prev) { |
||||
|
if(here->HFETAname == name || (fast && here==*fast) ) { |
||||
|
*prev= here->HFETAnextInstance; |
||||
|
FREE(here); |
||||
|
return(OK); |
||||
|
} |
||||
|
prev = &(here->HFETAnextInstance); |
||||
|
} |
||||
|
} |
||||
|
return(E_NODEV); |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "hfetdefs.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
void |
||||
|
HFETAdestroy(inModel) |
||||
|
GENmodel **inModel; |
||||
|
{ |
||||
|
HFETAmodel **model = (HFETAmodel**)inModel; |
||||
|
HFETAinstance *here; |
||||
|
HFETAinstance *prev = NULL; |
||||
|
HFETAmodel *mod = *model; |
||||
|
HFETAmodel *oldmod = NULL; |
||||
|
|
||||
|
for( ; mod ; mod = mod->HFETAnextModel) { |
||||
|
if(oldmod) FREE(oldmod); |
||||
|
oldmod = mod; |
||||
|
prev = (HFETAinstance *)NULL; |
||||
|
for(here = mod->HFETAinstances ; here ; here = here->HFETAnextInstance) { |
||||
|
if(prev) FREE(prev); |
||||
|
prev = here; |
||||
|
} |
||||
|
if(prev) FREE(prev); |
||||
|
} |
||||
|
if(oldmod) FREE(oldmod); |
||||
|
*model = NULL; |
||||
|
return; |
||||
|
} |
||||
@ -0,0 +1,34 @@ |
|||||
|
#ifdef __STDC__ |
||||
|
extern int HFETAacLoad(GENmodel*,CKTcircuit*); |
||||
|
extern int HFETAask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); |
||||
|
extern int HFETAdelete(GENmodel*,IFuid,GENinstance**); |
||||
|
extern void HFETAdestroy(GENmodel**); |
||||
|
extern int HFETAgetic(GENmodel*,CKTcircuit*); |
||||
|
extern int HFETAload(GENmodel*,CKTcircuit*); |
||||
|
extern int HFETAmAsk(CKTcircuit*,GENmodel*,int,IFvalue*); |
||||
|
extern int HFETAmDelete(GENmodel**,IFuid,GENmodel*); |
||||
|
extern int HFETAmParam(int,IFvalue*,GENmodel*); |
||||
|
extern int HFETAparam(int,IFvalue*,GENinstance*,IFvalue*); |
||||
|
extern int HFETAsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); |
||||
|
extern int HFETAtemp(GENmodel*,CKTcircuit*); |
||||
|
extern int HFETAtrunc(GENmodel*,CKTcircuit*,double*); |
||||
|
extern int HFETAunsetup(GENmodel*,CKTcircuit*); |
||||
|
|
||||
|
#else /*stdc*/ |
||||
|
extern int HFETAacLoad(); |
||||
|
extern int HFETAask(); |
||||
|
extern int HFETAdelete(); |
||||
|
extern void HFETAdestroy(); |
||||
|
extern int HFETAgetic(); |
||||
|
extern int HFETAload(); |
||||
|
extern int HFETAmAsk(); |
||||
|
extern int HFETAmDelete(); |
||||
|
extern int HFETAmParam(); |
||||
|
extern int HFETAparam(); |
||||
|
extern int HFETAsetup(); |
||||
|
extern int HFETAtemp(); |
||||
|
extern int HFETAtrunc(); |
||||
|
extern int HFETAunsetup(); |
||||
|
|
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,37 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
HFETAgetic(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
HFETAmodel *model = (HFETAmodel*)inModel; |
||||
|
HFETAinstance *here; |
||||
|
/* |
||||
|
* grab initial conditions out of rhs array. User specified, so use |
||||
|
* external nodes to get values |
||||
|
*/ |
||||
|
|
||||
|
for( ; model ; model = model->HFETAnextModel) { |
||||
|
for(here = model->HFETAinstances; here ; here = here->HFETAnextInstance) { |
||||
|
if(!here->HFETAicVDSGiven) { |
||||
|
here->HFETAicVDS = |
||||
|
*(ckt->CKTrhs + here->HFETAdrainNode) - |
||||
|
*(ckt->CKTrhs + here->HFETAsourceNode); |
||||
|
} |
||||
|
if(!here->HFETAicVGSGiven) { |
||||
|
here->HFETAicVGS = |
||||
|
*(ckt->CKTrhs + here->HFETAgateNode) - |
||||
|
*(ckt->CKTrhs + here->HFETAsourceNode); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
#include <config.h> |
||||
|
|
||||
|
#include <devdefs.h> |
||||
|
|
||||
|
#include "hfetitf.h" |
||||
|
#include "hfetext.h" |
||||
|
#include "hfetinit.h" |
||||
|
|
||||
|
|
||||
|
SPICEdev HFETAinfo = { |
||||
|
{ |
||||
|
"HFET1", |
||||
|
"HFET1 Model", |
||||
|
|
||||
|
&HFETAnSize, |
||||
|
&HFETAnSize, |
||||
|
HFETAnames, |
||||
|
|
||||
|
&HFETApTSize, |
||||
|
HFETApTable, |
||||
|
|
||||
|
&HFETAmPTSize, |
||||
|
HFETAmPTable, |
||||
|
DEV_DEFAULT |
||||
|
}, |
||||
|
|
||||
|
DEVparam : HFETAparam, |
||||
|
DEVmodParam : HFETAmParam, |
||||
|
DEVload : HFETAload, |
||||
|
DEVsetup : HFETAsetup, |
||||
|
DEVunsetup : HFETAunsetup, |
||||
|
DEVpzSetup : HFETAsetup, |
||||
|
DEVtemperature: HFETAtemp, |
||||
|
DEVtrunc : HFETAtrunc, |
||||
|
DEVfindBranch : NULL, |
||||
|
DEVacLoad : HFETAacLoad, |
||||
|
DEVaccept : NULL, |
||||
|
DEVdestroy : HFETAdestroy, |
||||
|
DEVmodDelete : HFETAmDelete, |
||||
|
DEVdelete : HFETAdelete, |
||||
|
DEVsetic : HFETAgetic, |
||||
|
DEVask : HFETAask, |
||||
|
DEVmodAsk : HFETAmAsk, |
||||
|
DEVpzLoad : NULL, |
||||
|
DEVconvTest : NULL, |
||||
|
DEVsenSetup : NULL, |
||||
|
DEVsenLoad : NULL, |
||||
|
DEVsenUpdate : NULL, |
||||
|
DEVsenAcLoad : NULL, |
||||
|
DEVsenPrint : NULL, |
||||
|
DEVsenTrunc : NULL, |
||||
|
DEVdisto : NULL, |
||||
|
DEVnoise : NULL, |
||||
|
|
||||
|
DEVinstSize : &HFETAiSize, |
||||
|
DEVmodSize : &HFETAmSize |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
|
||||
|
SPICEdev * |
||||
|
get_hfeta_info(void) |
||||
|
{ |
||||
|
return &HFETAinfo; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#ifndef _HFETAINIT_H |
||||
|
#define _HFETAINIT_H |
||||
|
|
||||
|
extern IFparm HFETApTable[ ]; |
||||
|
extern IFparm HFETAmPTable[ ]; |
||||
|
extern char *HFETAnames[ ]; |
||||
|
extern int HFETApTSize; |
||||
|
extern int HFETAmPTSize; |
||||
|
extern int HFETAnSize; |
||||
|
extern int HFETAiSize; |
||||
|
extern int HFETAmSize; |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,7 @@ |
|||||
|
#ifndef DEV_HFETA |
||||
|
#define DEV_HFETA |
||||
|
|
||||
|
SPICEdev *get_hfeta_info(void); |
||||
|
|
||||
|
#endif |
||||
|
|
||||
@ -0,0 +1,787 @@ |
|||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "devdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "const.h" |
||||
|
#include "trandefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
/* |
||||
|
#define true 1 |
||||
|
#define false 0 |
||||
|
*/ |
||||
|
|
||||
|
//#define PHIB 0.5 |
||||
|
double diode(double); |
||||
|
|
||||
|
static void leak(double gmin, double vt, double v, double rs, double is1, |
||||
|
double is2, double m1, double m2, double *il, double *gl); |
||||
|
|
||||
|
static void hfeta(HFETAmodel *model, HFETAinstance *here, CKTcircuit *ckt, |
||||
|
double vgs, double vds, double *cdrain, double *gm, |
||||
|
double *gds, double *capgs, double *capgd, |
||||
|
double *cgd, double *gmg, double *gmd, |
||||
|
double *cgs, double *ggs); |
||||
|
|
||||
|
void Pause(void); |
||||
|
|
||||
|
int HFETAload(inModel, ckt) |
||||
|
GENmodel *inModel; |
||||
|
register CKTcircuit *ckt; |
||||
|
{ |
||||
|
register HFETAmodel *model = (HFETAmodel*)inModel; |
||||
|
register HFETAinstance *here; |
||||
|
double capgd; |
||||
|
double capgs; |
||||
|
double cd; |
||||
|
double cdhat; |
||||
|
double cdrain; |
||||
|
double cdreq; |
||||
|
double ceq; |
||||
|
double ceqgd; |
||||
|
double ceqgs; |
||||
|
double cg; |
||||
|
double cgd=0; |
||||
|
double cgs=0; |
||||
|
double cghat; |
||||
|
double delvds; |
||||
|
double delvgd; |
||||
|
double delvgs; |
||||
|
double delvgdpp=0; |
||||
|
double delvgspp=0; |
||||
|
double gds; |
||||
|
double geq; |
||||
|
double ggd=0; |
||||
|
double ggs=0; |
||||
|
double gm; |
||||
|
double vcrit; |
||||
|
double vds; |
||||
|
double vgd; |
||||
|
double vgs; |
||||
|
double vgs1; |
||||
|
double vgd1; |
||||
|
double vds1; |
||||
|
double xfact; |
||||
|
double temp; |
||||
|
double vt; |
||||
|
double vgspp=0; |
||||
|
double vgdpp=0; |
||||
|
double cgspp=0; |
||||
|
double cgdpp=0; |
||||
|
double ggspp=0; |
||||
|
double ggdpp=0; |
||||
|
double gmg=0; |
||||
|
double gmd=0; |
||||
|
|
||||
|
int inverse=FALSE; |
||||
|
int icheck; |
||||
|
int error; |
||||
|
|
||||
|
for( ; model != NULL; model = model->HFETAnextModel ) { |
||||
|
for (here = model->HFETAinstances; here != NULL ; |
||||
|
here=here->HFETAnextInstance) { |
||||
|
vcrit = here->HFETAvcrit; |
||||
|
vt = CONSTKoverQ * here->HFETAtemp; |
||||
|
icheck = 0; |
||||
|
if( ckt->CKTmode & MODEINITSMSIG) { |
||||
|
vgs = *(ckt->CKTstate0 + here->HFETAvgs); |
||||
|
vgd = *(ckt->CKTstate0 + here->HFETAvgd); |
||||
|
vgspp = *(ckt->CKTstate0 + here->HFETAvgspp); |
||||
|
vgdpp = *(ckt->CKTstate0 + here->HFETAvgdpp); |
||||
|
} else if (ckt->CKTmode & MODEINITTRAN) { |
||||
|
vgs = *(ckt->CKTstate1 + here->HFETAvgs); |
||||
|
vgd = *(ckt->CKTstate1 + here->HFETAvgd); |
||||
|
vgspp = *(ckt->CKTstate1 + here->HFETAvgspp); |
||||
|
vgdpp = *(ckt->CKTstate1 + here->HFETAvgdpp); |
||||
|
} else if ( (ckt->CKTmode & MODEINITJCT) && |
||||
|
(ckt->CKTmode & MODETRANOP) && |
||||
|
(ckt->CKTmode & MODEUIC) ) { |
||||
|
vds = model->HFETAtype*here->HFETAicVDS; |
||||
|
vgs = model->HFETAtype*here->HFETAicVGS; |
||||
|
vgd = vgs-vds; |
||||
|
vgspp = vgs; |
||||
|
vgdpp = vgd; |
||||
|
} else if ( (ckt->CKTmode & MODEINITJCT) && |
||||
|
(here->HFETAoff == 0) ) { |
||||
|
vgs = -1; |
||||
|
vgd = -1; |
||||
|
vgspp = 0; |
||||
|
vgdpp = 0; |
||||
|
} else if( (ckt->CKTmode & MODEINITJCT) || |
||||
|
((ckt->CKTmode & MODEINITFIX) && (here->HFETAoff))) { |
||||
|
vgs = 0; |
||||
|
vgd = 0; |
||||
|
vgspp = 0; |
||||
|
vgdpp = 0; |
||||
|
} else { |
||||
|
#ifndef PREDICTOR |
||||
|
if(ckt->CKTmode & MODEINITPRED) { |
||||
|
xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2]; |
||||
|
*(ckt->CKTstate0 + here->HFETAvgs) = |
||||
|
*(ckt->CKTstate1 + here->HFETAvgs); |
||||
|
vgs = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgs) - |
||||
|
xfact * *(ckt->CKTstate2 + here->HFETAvgs); |
||||
|
*(ckt->CKTstate0 + here->HFETAvgspp) = |
||||
|
*(ckt->CKTstate1 + here->HFETAvgspp); |
||||
|
vgspp = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgspp) - |
||||
|
xfact * *(ckt->CKTstate2 + here->HFETAvgspp); |
||||
|
*(ckt->CKTstate0 + here->HFETAvgd) = |
||||
|
*(ckt->CKTstate1 + here->HFETAvgd); |
||||
|
vgd = (1+xfact)* *(ckt->CKTstate1 + here->HFETAvgd) - |
||||
|
xfact * *(ckt->CKTstate2 + here->HFETAvgd); |
||||
|
*(ckt->CKTstate0 + here->HFETAvgdpp) = |
||||
|
*(ckt->CKTstate1 + here->HFETAvgdpp); |
||||
|
vgdpp = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgdpp) - |
||||
|
xfact * *(ckt->CKTstate2 + here->HFETAvgdpp); |
||||
|
*(ckt->CKTstate0 + here->HFETAcg) = |
||||
|
*(ckt->CKTstate1 + here->HFETAcg); |
||||
|
*(ckt->CKTstate0 + here->HFETAcd) = |
||||
|
*(ckt->CKTstate1 + here->HFETAcd); |
||||
|
*(ckt->CKTstate0 + here->HFETAcgd) = |
||||
|
*(ckt->CKTstate1 + here->HFETAcgd); |
||||
|
*(ckt->CKTstate0 + here->HFETAcgs) = |
||||
|
*(ckt->CKTstate1 + here->HFETAcgs); |
||||
|
*(ckt->CKTstate0 + here->HFETAcgspp) = |
||||
|
*(ckt->CKTstate1 + here->HFETAcgspp); |
||||
|
*(ckt->CKTstate0 + here->HFETAcgdpp) = |
||||
|
*(ckt->CKTstate1 + here->HFETAcgdpp); |
||||
|
*(ckt->CKTstate0 + here->HFETAgm) = |
||||
|
*(ckt->CKTstate1 + here->HFETAgm); |
||||
|
*(ckt->CKTstate0 + here->HFETAgds) = |
||||
|
*(ckt->CKTstate1 + here->HFETAgds); |
||||
|
*(ckt->CKTstate0 + here->HFETAggs) = |
||||
|
*(ckt->CKTstate1 + here->HFETAggs); |
||||
|
*(ckt->CKTstate0 + here->HFETAggspp) = |
||||
|
*(ckt->CKTstate1 + here->HFETAggspp); |
||||
|
*(ckt->CKTstate0 + here->HFETAggd) = |
||||
|
*(ckt->CKTstate1 + here->HFETAggd); |
||||
|
*(ckt->CKTstate0 + here->HFETAggdpp) = |
||||
|
*(ckt->CKTstate1 + here->HFETAggdpp); |
||||
|
*(ckt->CKTstate0 + here->HFETAgmg) = |
||||
|
*(ckt->CKTstate1 + here->HFETAgmg); |
||||
|
*(ckt->CKTstate0 + here->HFETAgmd) = |
||||
|
*(ckt->CKTstate1 + here->HFETAgmd); |
||||
|
} else { |
||||
|
#endif /* PREDICTOR */ |
||||
|
/* |
||||
|
* compute new nonlinear branch voltages |
||||
|
*/ |
||||
|
vgs = model->HFETAtype* |
||||
|
(*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)- |
||||
|
*(ckt->CKTrhsOld+ |
||||
|
here->HFETAsourcePrimeNode)); |
||||
|
vgd = model->HFETAtype* |
||||
|
(*(ckt->CKTrhsOld+here->HFETAgatePrimeNode)- |
||||
|
*(ckt->CKTrhsOld+ |
||||
|
here->HFETAdrainPrimeNode)); |
||||
|
vgspp = model->HFETAtype* |
||||
|
(*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)- |
||||
|
*(ckt->CKTrhsOld+ |
||||
|
here->HFETAsourcePrmPrmNode)); |
||||
|
vgdpp = model->HFETAtype* |
||||
|
(*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)- |
||||
|
*(ckt->CKTrhsOld+ |
||||
|
here->HFETAdrainPrmPrmNode)); |
||||
|
|
||||
|
#ifndef PREDICTOR |
||||
|
} |
||||
|
#endif /* PREDICTOR */ |
||||
|
delvgs=vgs - *(ckt->CKTstate0 + here->HFETAvgs); |
||||
|
delvgd=vgd - *(ckt->CKTstate0 + here->HFETAvgd); |
||||
|
delvds=delvgs - delvgd; |
||||
|
delvgspp=vgspp - *(ckt->CKTstate0 + here->HFETAvgspp); |
||||
|
delvgdpp=vgdpp - *(ckt->CKTstate0 + here->HFETAvgdpp); |
||||
|
cghat= *(ckt->CKTstate0 + here->HFETAcg) + |
||||
|
*(ckt->CKTstate0 + here->HFETAgmg)*delvgs - |
||||
|
*(ckt->CKTstate0 + here->HFETAgmd)*delvds + |
||||
|
*(ckt->CKTstate0 + here->HFETAggd)*delvgd + |
||||
|
*(ckt->CKTstate0 + here->HFETAggs)*delvgs + |
||||
|
*(ckt->CKTstate0 + here->HFETAggdpp)*delvgdpp + |
||||
|
*(ckt->CKTstate0 + here->HFETAggspp)*delvgspp; |
||||
|
cdhat= *(ckt->CKTstate0 + here->HFETAcd) + |
||||
|
*(ckt->CKTstate0 + here->HFETAgm)*delvgs + |
||||
|
*(ckt->CKTstate0 + here->HFETAgds)*delvds - |
||||
|
*(ckt->CKTstate0 + here->HFETAggd)*delvgd - |
||||
|
(*(ckt->CKTstate0 + here->HFETAgmg)*delvgs - |
||||
|
*(ckt->CKTstate0 + here->HFETAgmd)*delvds); |
||||
|
/* |
||||
|
* bypass if solution has not changed |
||||
|
*/ |
||||
|
if((ckt->CKTbypass) && |
||||
|
(!(ckt->CKTmode & MODEINITPRED)) && |
||||
|
(fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs), |
||||
|
fabs(*(ckt->CKTstate0 + here->HFETAvgs)))+ |
||||
|
ckt->CKTvoltTol) ) |
||||
|
if ( (fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd), |
||||
|
fabs(*(ckt->CKTstate0 + here->HFETAvgd)))+ |
||||
|
ckt->CKTvoltTol)) |
||||
|
if ( (fabs(delvgspp) < ckt->CKTreltol*MAX(fabs(vgspp), |
||||
|
fabs(*(ckt->CKTstate0 + here->HFETAvgspp)))+ |
||||
|
ckt->CKTvoltTol)) |
||||
|
if ( (fabs(delvgdpp) < ckt->CKTreltol*MAX(fabs(vgdpp), |
||||
|
fabs(*(ckt->CKTstate0 + here->HFETAvgdpp)))+ |
||||
|
ckt->CKTvoltTol)) |
||||
|
if ( (fabs(cghat-*(ckt->CKTstate0 + here->HFETAcg)) |
||||
|
< ckt->CKTreltol*MAX(fabs(cghat), |
||||
|
fabs(*(ckt->CKTstate0 + here->HFETAcg)))+ |
||||
|
ckt->CKTabstol) ) if ( /* hack - expression too big */ |
||||
|
(fabs(cdhat-*(ckt->CKTstate0 + here->HFETAcd)) |
||||
|
< ckt->CKTreltol*MAX(fabs(cdhat), |
||||
|
fabs(*(ckt->CKTstate0 + here->HFETAcd)))+ |
||||
|
ckt->CKTabstol) ) { |
||||
|
|
||||
|
/* we can do a bypass */ |
||||
|
vgs = *(ckt->CKTstate0 + here->HFETAvgs); |
||||
|
vgd = *(ckt->CKTstate0 + here->HFETAvgd); |
||||
|
vds = vgs-vgd; |
||||
|
vgspp = *(ckt->CKTstate0 + here->HFETAvgspp); |
||||
|
vgdpp = *(ckt->CKTstate0 + here->HFETAvgdpp); |
||||
|
cg = *(ckt->CKTstate0 + here->HFETAcg); |
||||
|
cd = *(ckt->CKTstate0 + here->HFETAcd); |
||||
|
cgd = *(ckt->CKTstate0 + here->HFETAcgd); |
||||
|
cgs = *(ckt->CKTstate0 + here->HFETAcgs); |
||||
|
cgdpp = *(ckt->CKTstate0 + here->HFETAcgdpp); |
||||
|
cgspp = *(ckt->CKTstate0 + here->HFETAcgspp); |
||||
|
gm = *(ckt->CKTstate0 + here->HFETAgm); |
||||
|
gds = *(ckt->CKTstate0 + here->HFETAgds); |
||||
|
ggs = *(ckt->CKTstate0 + here->HFETAggs); |
||||
|
ggd = *(ckt->CKTstate0 + here->HFETAggd); |
||||
|
ggdpp = *(ckt->CKTstate0 + here->HFETAggdpp); |
||||
|
ggspp = *(ckt->CKTstate0 + here->HFETAggspp); |
||||
|
gmg = *(ckt->CKTstate0 + here->HFETAgmg); |
||||
|
gmd = *(ckt->CKTstate0 + here->HFETAgmd); |
||||
|
goto load; |
||||
|
} |
||||
|
/* |
||||
|
* limit nonlinear branch voltages |
||||
|
*/ |
||||
|
vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->HFETAvgs),TVTO); |
||||
|
vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->HFETAvgd),TVTO); |
||||
|
} |
||||
|
/* |
||||
|
* determine dc current and derivatives |
||||
|
*/ |
||||
|
vds = vgs-vgd; |
||||
|
if(model->HFETAgatemod == 0) { |
||||
|
double arg; |
||||
|
double earg; |
||||
|
if(IS1S == 0 || IS2S == 0) { |
||||
|
cgs = 0; |
||||
|
ggs = 0; |
||||
|
} else |
||||
|
leak(ckt->CKTgmin,vt,vgs,RGS,IS1S,IS2S,M1S,M2S,&cgs,&ggs); |
||||
|
arg = -vgs*DEL/vt; |
||||
|
earg = exp(arg); |
||||
|
cgs += GGRWL*vgs*earg; |
||||
|
ggs += GGRWL*earg*(1-arg); |
||||
|
if(IS1D == 0 || IS2D == 0) { |
||||
|
cgd = 0; |
||||
|
ggd = 0; |
||||
|
} else |
||||
|
leak(ckt->CKTgmin,vt,vgd,RGD,IS1D,IS2D,M1D,M2D,&cgd,&ggd); |
||||
|
arg = -vgd*DEL/vt; |
||||
|
earg = exp(arg); |
||||
|
cgd += GGRWL*vgd*earg; |
||||
|
ggd += GGRWL*earg*(1-arg); |
||||
|
} else |
||||
|
ggd = 0; |
||||
|
if(vds < 0) { |
||||
|
vds = -vds; |
||||
|
inverse = TRUE; |
||||
|
} |
||||
|
hfeta(model,here,ckt,vds>0?vgs:vgd,vds,&cdrain,&gm,&gds,&capgs,&capgd, |
||||
|
&cgd,&gmg,&gmd,&cgs,&ggs); |
||||
|
cg = cgs+cgd; |
||||
|
if(inverse) { |
||||
|
cdrain = -cdrain; |
||||
|
vds = -vds; |
||||
|
temp = capgs; |
||||
|
capgs = capgd; |
||||
|
capgd = temp; |
||||
|
} |
||||
|
/* |
||||
|
* compute equivalent drain current source |
||||
|
*/ |
||||
|
cd = cdrain - cgd; |
||||
|
if ( (ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || |
||||
|
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){ |
||||
|
/* |
||||
|
* charge storage elements |
||||
|
*/ |
||||
|
vgs1 = *(ckt->CKTstate1 + here->HFETAvgspp); |
||||
|
vgd1 = *(ckt->CKTstate1 + here->HFETAvgdpp); |
||||
|
vds1 = *(ckt->CKTstate1 + here->HFETAvgs)- |
||||
|
*(ckt->CKTstate1 + here->HFETAvgd); |
||||
|
|
||||
|
if(ckt->CKTmode & MODEINITTRAN) { |
||||
|
*(ckt->CKTstate1 + here->HFETAqgs) = capgs*vgspp; |
||||
|
*(ckt->CKTstate1 + here->HFETAqgd) = capgd*vgdpp; |
||||
|
*(ckt->CKTstate1 + here->HFETAqds) = CDS*vds; |
||||
|
} |
||||
|
*(ckt->CKTstate0+here->HFETAqgs) = *(ckt->CKTstate1 + here->HFETAqgs) + |
||||
|
capgs*(vgspp-vgs1); |
||||
|
*(ckt->CKTstate0+here->HFETAqgd) = *(ckt->CKTstate1 + here->HFETAqgd) + |
||||
|
capgd*(vgdpp-vgd1); |
||||
|
*(ckt->CKTstate0+here->HFETAqds) = *(ckt->CKTstate1 + here->HFETAqds) + |
||||
|
CDS*(vds-vds1); |
||||
|
|
||||
|
/* |
||||
|
* store small-signal parameters |
||||
|
*/ |
||||
|
if( (!(ckt->CKTmode & MODETRANOP)) || |
||||
|
(!(ckt->CKTmode & MODEUIC)) ) { |
||||
|
if(ckt->CKTmode & MODEINITSMSIG) { |
||||
|
*(ckt->CKTstate0 + here->HFETAqgs) = capgs; |
||||
|
*(ckt->CKTstate0 + here->HFETAqgd) = capgd; |
||||
|
*(ckt->CKTstate0 + here->HFETAqds) = CDS; |
||||
|
continue; /*go to 1000*/ |
||||
|
} |
||||
|
/* |
||||
|
* transient analysis |
||||
|
*/ |
||||
|
if(ckt->CKTmode & MODEINITTRAN) { |
||||
|
*(ckt->CKTstate1 + here->HFETAqgs) = |
||||
|
*(ckt->CKTstate0 + here->HFETAqgs); |
||||
|
*(ckt->CKTstate1 + here->HFETAqgd) = |
||||
|
*(ckt->CKTstate0 + here->HFETAqgd); |
||||
|
*(ckt->CKTstate1 + here->HFETAqds) = |
||||
|
*(ckt->CKTstate0 + here->HFETAqds); |
||||
|
} |
||||
|
error = NIintegrate(ckt,&geq,&ceq,capgs,here->HFETAqgs); |
||||
|
if(error) return(error); |
||||
|
ggspp = geq; |
||||
|
cgspp = *(ckt->CKTstate0 + here->HFETAcqgs); |
||||
|
cg = cg + cgspp; |
||||
|
error = NIintegrate(ckt,&geq,&ceq,capgd,here->HFETAqgd); |
||||
|
if(error) return(error); |
||||
|
ggdpp = geq; |
||||
|
cgdpp = *(ckt->CKTstate0 + here->HFETAcqgd); |
||||
|
cg = cg + cgdpp; |
||||
|
cd = cd - cgdpp; |
||||
|
error = NIintegrate(ckt,&geq,&ceq,CDS,here->HFETAqds); |
||||
|
if(error) return(error); |
||||
|
gds += geq; |
||||
|
cd += *(ckt->CKTstate0 + here->HFETAcqds); |
||||
|
if (ckt->CKTmode & MODEINITTRAN) { |
||||
|
*(ckt->CKTstate1 + here->HFETAcqgs) = |
||||
|
*(ckt->CKTstate0 + here->HFETAcqgs); |
||||
|
*(ckt->CKTstate1 + here->HFETAcqgd) = |
||||
|
*(ckt->CKTstate0 + here->HFETAcqgd); |
||||
|
*(ckt->CKTstate1 + here->HFETAcqds) = |
||||
|
*(ckt->CKTstate0 + here->HFETAcqds); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
/* |
||||
|
* check convergence |
||||
|
*/ |
||||
|
if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) { |
||||
|
if( (icheck == 1) |
||||
|
|| (fabs(cghat-cg) >= ckt->CKTreltol* |
||||
|
MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) || |
||||
|
(fabs(cdhat-cd) > ckt->CKTreltol* |
||||
|
MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol) |
||||
|
|
||||
|
) { |
||||
|
ckt->CKTnoncon++; |
||||
|
ckt->CKTtroubleElt = (GENinstance *) here; |
||||
|
} |
||||
|
} |
||||
|
*(ckt->CKTstate0 + here->HFETAvgs) = vgs; |
||||
|
*(ckt->CKTstate0 + here->HFETAvgd) = vgd; |
||||
|
*(ckt->CKTstate0 + here->HFETAvgspp) = vgspp; |
||||
|
*(ckt->CKTstate0 + here->HFETAvgdpp) = vgdpp; |
||||
|
*(ckt->CKTstate0 + here->HFETAcg) = cg; |
||||
|
*(ckt->CKTstate0 + here->HFETAcd) = cd; |
||||
|
*(ckt->CKTstate0 + here->HFETAcgd) = cgd; |
||||
|
*(ckt->CKTstate0 + here->HFETAcgs) = cgs; |
||||
|
*(ckt->CKTstate0 + here->HFETAcgspp) = cgspp; |
||||
|
*(ckt->CKTstate0 + here->HFETAcgdpp) = cgdpp; |
||||
|
*(ckt->CKTstate0 + here->HFETAgm) = gm; |
||||
|
*(ckt->CKTstate0 + here->HFETAgds) = gds; |
||||
|
*(ckt->CKTstate0 + here->HFETAggs) = ggs; |
||||
|
*(ckt->CKTstate0 + here->HFETAggd) = ggd; |
||||
|
*(ckt->CKTstate0 + here->HFETAggspp) = ggspp; |
||||
|
*(ckt->CKTstate0 + here->HFETAggdpp) = ggdpp; |
||||
|
*(ckt->CKTstate0 + here->HFETAgmg) = gmg; |
||||
|
*(ckt->CKTstate0 + here->HFETAgmd) = gmd; |
||||
|
|
||||
|
/* |
||||
|
* load current vector |
||||
|
*/ |
||||
|
load: |
||||
|
ceqgd = model->HFETAtype*(cgd+cgdpp-ggd*vgd-gmg*vgs-gmd*vds-ggdpp*vgdpp); |
||||
|
ceqgs = model->HFETAtype*(cgs + cgspp - ggs*vgs - ggspp*vgspp); |
||||
|
cdreq = model->HFETAtype*(cd + cgd + cgdpp - gds*vds - gm*vgs); |
||||
|
*(ckt->CKTrhs + here->HFETAgatePrimeNode) += (-ceqgs-ceqgd); |
||||
|
ceqgd = model->HFETAtype*(cgd-ggd*vgd-gmg*vgs-gmd*vds); |
||||
|
*(ckt->CKTrhs + here->HFETAdrainPrimeNode) += (-cdreq+ceqgd); |
||||
|
ceqgd = model->HFETAtype*(cgdpp-ggdpp*vgdpp); |
||||
|
*(ckt->CKTrhs + here->HFETAdrainPrmPrmNode) += ceqgd; |
||||
|
ceqgs = model->HFETAtype*(cgs-ggs*vgs); |
||||
|
*(ckt->CKTrhs + here->HFETAsourcePrimeNode) += (cdreq+ceqgs); |
||||
|
ceqgs = model->HFETAtype*(cgspp-ggspp*vgspp); |
||||
|
*(ckt->CKTrhs + here->HFETAsourcePrmPrmNode) += ceqgs; |
||||
|
|
||||
|
/* |
||||
|
* load y matrix |
||||
|
*/ |
||||
|
|
||||
|
*(here->HFETAdrainDrainPtr) += model->HFETAdrainConduct; |
||||
|
*(here->HFETAsourceSourcePtr) += model->HFETAsourceConduct; |
||||
|
*(here->HFETAgatePrimeGatePrimePtr) += (ggd+ggs+ggspp+ggdpp+gmg+model->HFETAgateConduct); |
||||
|
*(here->HFETAdrainPrimeDrainPrimePtr) += (gds+ggd-gmd+model->HFETAdrainConduct+model->HFETAgf); |
||||
|
*(here->HFETAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+model->HFETAsourceConduct+model->HFETAgi); |
||||
|
*(here->HFETAsourcePrmPrmSourcePrmPrmPtr) += (model->HFETAgi+ggspp); |
||||
|
*(here->HFETAdrainPrmPrmDrainPrmPrmPtr) += (model->HFETAgf+ggdpp); |
||||
|
*(here->HFETAdrainDrainPrimePtr) -= model->HFETAdrainConduct; |
||||
|
*(here->HFETAdrainPrimeDrainPtr) -= model->HFETAdrainConduct; |
||||
|
*(here->HFETAsourceSourcePrimePtr) -= model->HFETAsourceConduct; |
||||
|
*(here->HFETAsourcePrimeSourcePtr) -= model->HFETAsourceConduct; |
||||
|
*(here->HFETAgatePrimeDrainPrimePtr) += -ggd+gmd; |
||||
|
*(here->HFETAdrainPrimeGatePrimePtr) += (gm-ggd-gmg); |
||||
|
*(here->HFETAgatePrimeSourcePrimePtr) -= ggs+gmg+gmd; |
||||
|
*(here->HFETAsourcePrimeGatePrimePtr) += (-ggs-gm); |
||||
|
*(here->HFETAdrainPrimeSourcePrimePtr) += (-gds-gm+gmg+gmd); |
||||
|
*(here->HFETAsourcePrimeDrainPrimePtr) -= gds; |
||||
|
*(here->HFETAsourcePrimeSourcePrmPrmPtr) -= model->HFETAgi; |
||||
|
*(here->HFETAsourcePrmPrmSourcePrimePtr) -= model->HFETAgi; |
||||
|
*(here->HFETAgatePrimeSourcePrmPrmPtr) -= ggspp; |
||||
|
*(here->HFETAsourcePrmPrmGatePrimePtr) -= ggspp; |
||||
|
*(here->HFETAdrainPrimeDrainPrmPrmPtr) -= model->HFETAgf; |
||||
|
*(here->HFETAdrainPrmPrmDrainPrimePtr) -= model->HFETAgf; |
||||
|
*(here->HFETAgatePrimeDrainPrmPrmPtr) -= ggdpp; |
||||
|
*(here->HFETAdrainPrmPrmGatePrimePtr) -= ggdpp; |
||||
|
*(here->HFETAgateGatePtr) += model->HFETAgateConduct; |
||||
|
*(here->HFETAgateGatePrimePtr) -= model->HFETAgateConduct; |
||||
|
*(here->HFETAgatePrimeGatePtr) -= model->HFETAgateConduct; |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
static void leak(double gmin, double vt, double v, double rs, double is1, double is2, |
||||
|
double m1, double m2, double *il, double *gl) |
||||
|
|
||||
|
{ |
||||
|
|
||||
|
double vt1 = vt*m1; |
||||
|
double vt2 = vt*m2; |
||||
|
|
||||
|
if(v > -10*vt1) { |
||||
|
double dvdi0; |
||||
|
double iaprox; |
||||
|
double iaprox1; |
||||
|
double iaprox2; |
||||
|
double v0; |
||||
|
double vteff = vt1 + vt2; |
||||
|
double iseff = is2*pow((is1/is2),(m1/(m1+m2))); |
||||
|
if(rs > 0) { |
||||
|
double unorm = (v + rs*is1)/vt1 + log(rs*is1/vt1); |
||||
|
iaprox1 = vt1*diode(unorm)/rs - is1; |
||||
|
unorm = (v + rs*iseff)/vteff + log(rs*iseff/vteff); |
||||
|
iaprox2 = vteff*diode(unorm)/rs - iseff; |
||||
|
} else { |
||||
|
iaprox1 = is1*(exp(v/vt1) - 1); |
||||
|
iaprox2 = iseff*(exp(v/vteff) - 1); |
||||
|
} |
||||
|
if((iaprox1*iaprox2) != 0.0) |
||||
|
iaprox = 1./(1./iaprox1 + 1./iaprox2); |
||||
|
else |
||||
|
iaprox = 0.5*(iaprox1 + iaprox2); |
||||
|
|
||||
|
dvdi0 = rs + vt1/(iaprox+is1) + vt2/(iaprox+is2); |
||||
|
v0 = rs*iaprox; |
||||
|
v0 += vt1*log(iaprox/is1 + 1) + vt2*log(iaprox/is2 + 1); |
||||
|
//*il = __max(-is1,iaprox + (v - v0)/dvdi0)*0.99999; |
||||
|
*il = MAX(-is1,iaprox + (v - v0)/dvdi0)*0.99999; |
||||
|
*gl = 1./(rs + vt1/(*il+is1) + vt2/(*il+is2)); |
||||
|
} else { |
||||
|
*gl = gmin; |
||||
|
*il = (*gl)*v-is1; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
static void hfeta(HFETAmodel *model, HFETAinstance *here, CKTcircuit *ckt, |
||||
|
double vgs, double vds, double *cdrain, double *gm, |
||||
|
double *gds, double *capgs, double *capgd, |
||||
|
double *cgd, double *gmg, double *gmd, |
||||
|
double *cgs, double *ggs) |
||||
|
|
||||
|
{ |
||||
|
|
||||
|
double vt; |
||||
|
double vgt; |
||||
|
double vgt0; |
||||
|
double sigma; |
||||
|
double vgte; |
||||
|
double isat; |
||||
|
double isatm; |
||||
|
double ns; |
||||
|
double nsm; |
||||
|
double a; |
||||
|
double b; |
||||
|
double c; |
||||
|
double d; |
||||
|
double e; |
||||
|
double f; |
||||
|
double g; |
||||
|
double h; |
||||
|
double p; |
||||
|
double q; |
||||
|
double s; |
||||
|
double t; |
||||
|
double u; |
||||
|
double nsc; |
||||
|
double nsn; |
||||
|
double temp; |
||||
|
double etavth; |
||||
|
double gch; |
||||
|
double gchi; |
||||
|
double gchim; |
||||
|
double vsate; |
||||
|
double vdse; |
||||
|
double cg1; |
||||
|
double cgc; |
||||
|
double rt; |
||||
|
double vl; |
||||
|
double delidgch; |
||||
|
double delgchgchi; |
||||
|
double delgchins; |
||||
|
double delnsnsm; |
||||
|
double delnsmvgt; |
||||
|
double delvgtevgt; |
||||
|
double delidvsate; |
||||
|
double delvsateisat; |
||||
|
double delisatisatm; |
||||
|
double delisatmvgte; |
||||
|
double delisatmgchim; |
||||
|
double delvsategch; |
||||
|
double delidvds; |
||||
|
double delvgtvgs; |
||||
|
double delvsatevgt; |
||||
|
|
||||
|
vt = CONSTKoverQ*TEMP; |
||||
|
etavth = ETA*vt; |
||||
|
vl = VS/TMU*L; |
||||
|
rt = RSI+RDI; |
||||
|
vgt0 = vgs - TVTO; |
||||
|
s = exp((vgt0-VSIGMAT)/VSIGMA); |
||||
|
sigma = SIGMA0/(1+s); |
||||
|
vgt = vgt0+sigma*vds; |
||||
|
u = 0.5*vgt/vt-1; |
||||
|
t = sqrt(model->HFETAdeltaSqr+u*u); |
||||
|
vgte = vt*(2+u+t); |
||||
|
b = exp(vgt/etavth); |
||||
|
if(model->HFETAeta2Given && model->HFETAd2Given) { |
||||
|
nsc = N02*exp((vgt+TVTO-VT2)/(ETA2*vt)); |
||||
|
nsn = 2*N0*log(1+0.5*b); |
||||
|
nsm = nsn*nsc/(nsn+nsc); |
||||
|
} else { |
||||
|
nsm = 2*N0*log(1+0.5*b); |
||||
|
} |
||||
|
if(nsm < 1.0e-38) { |
||||
|
*cdrain = 0; |
||||
|
*gm = 0.0; |
||||
|
*gds = 0.0; |
||||
|
*capgs = CF; |
||||
|
*capgd = CF; |
||||
|
goto cgd_calc; |
||||
|
} |
||||
|
c = pow(nsm/NMAX,GAMMA); |
||||
|
q = pow(1+c,1.0/GAMMA); |
||||
|
ns = nsm/q; |
||||
|
gchi = GCHI0*ns; |
||||
|
gch = gchi/(1+gchi*rt); |
||||
|
gchim = GCHI0*nsm; |
||||
|
h = sqrt(1+2*gchim*RSI + vgte*vgte/(vl*vl)); |
||||
|
p = 1+gchim*RSI+h; |
||||
|
isatm = gchim*vgte/p; |
||||
|
g = pow(isatm/IMAX,GAMMA); |
||||
|
isat = isatm/pow(1+g,1/GAMMA); |
||||
|
vsate = isat/gch; |
||||
|
d = pow(vds/vsate,M); |
||||
|
e = pow(1+d,1.0/M); |
||||
|
delidgch = vds*(1+TLAMBDA*vds)/e; |
||||
|
*cdrain = gch*delidgch; |
||||
|
delidvsate = (*cdrain)*d/vsate/(1+d); |
||||
|
delidvds = gch*(1+2*TLAMBDA*vds)/e-(*cdrain)* |
||||
|
pow(vds/vsate,M-1)/(vsate*(1+d)); |
||||
|
a = 1+gchi*rt; |
||||
|
delgchgchi = 1.0/(a*a); |
||||
|
delgchins = GCHI0; |
||||
|
delnsnsm = ns/nsm*(1-c/(1+c)); |
||||
|
delvgtevgt = 0.5*(1+u/t); |
||||
|
delnsmvgt = N0/etavth/(1.0/b + 0.5); |
||||
|
if(model->HFETAeta2Given && model->HFETAd2Given) |
||||
|
delnsmvgt = nsc*(nsc*delnsmvgt+nsn*nsn/(ETA2*vt))/((nsc+nsn)*(nsc+nsn)); |
||||
|
delvsateisat = 1.0/gch; |
||||
|
delisatisatm = isat/isatm*(1-g/(1+g)); |
||||
|
delisatmvgte = gchim*(p - vgte*vgte/(vl*vl*h))/(p*p); |
||||
|
delvsategch = -vsate/gch; |
||||
|
delisatmgchim = vgte*(p - gchim*RSI*(1+1.0/h))/(p*p); |
||||
|
delvgtvgs = 1-vds*SIGMA0/VSIGMA*s/((1+s)*(1+s)); |
||||
|
p = delgchgchi*delgchins*delnsnsm*delnsmvgt; |
||||
|
delvsatevgt = (delvsateisat*delisatisatm*(delisatmvgte*delvgtevgt + |
||||
|
delisatmgchim*GCHI0*delnsmvgt)+delvsategch*p); |
||||
|
g = delidgch*p + delidvsate*delvsatevgt; |
||||
|
*gm = g*delvgtvgs; |
||||
|
*gds = delidvds + g*sigma; |
||||
|
|
||||
|
// Capacitance calculations |
||||
|
temp = ETA1*vt; |
||||
|
cg1 = 1/(D1/EPSI+temp*exp(-(vgs-IN_VT1)/temp)); |
||||
|
cgc = W*L*(CHARGE*delnsnsm*delnsmvgt*delvgtvgs+cg1); |
||||
|
vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC); |
||||
|
a = (vsate-vdse)/(2*vsate-vdse); |
||||
|
a = a*a; |
||||
|
temp = 2.0/3.0; |
||||
|
p = PM + (1-PM)*exp(-vds/vsate); |
||||
|
*capgs = CF+2*temp*cgc*(1-a)/(1+p); |
||||
|
a = vsate/(2*vsate-vdse); |
||||
|
a = a*a; |
||||
|
*capgd = CF+2*p*temp*cgc*(1-a)/(1+p); |
||||
|
/* |
||||
|
{ |
||||
|
char buf[128]; |
||||
|
FILE *fp; |
||||
|
fp = fopen("d:\\temp\\debug.txt","at"); |
||||
|
sprintf(buf,"%f\t%f\t%e\t%e\n",vgs,vds,W*L*CHARGE*delnsnsm*delnsmvgt*delvgtvgs,cgc); |
||||
|
fputs(buf,fp); |
||||
|
fclose(fp); |
||||
|
} |
||||
|
*/ |
||||
|
cgd_calc: |
||||
|
|
||||
|
if(model->HFETAgatemod != 0) { |
||||
|
// Gate-drain current calculation |
||||
|
double vkneet; |
||||
|
double vmax; |
||||
|
double td; |
||||
|
double delcgdvgs; |
||||
|
double delcgdtd; |
||||
|
double deltdvdse; |
||||
|
double deltdvkneet; |
||||
|
double delvdsevmax; |
||||
|
double delvdsevds; |
||||
|
double dvdsevgs; |
||||
|
double dvdsevds; |
||||
|
double dtdvgs; |
||||
|
double dtdvds; |
||||
|
|
||||
|
vkneet = CK1*vsate+CK2; |
||||
|
vmax = CM1*vsate+CM2; |
||||
|
a = pow(vds/vmax,MT2); |
||||
|
b = pow(1+a,1/MT2); |
||||
|
vdse = vds/b; |
||||
|
c = pow(vdse/vkneet,MT1); |
||||
|
d = pow(1+c,1/MT1); |
||||
|
td = TEMP+TALPHA*vdse*vdse/d; |
||||
|
e = CONSTKoverQ*td*M2D; |
||||
|
p = PHIB/(CONSTboltz*td); |
||||
|
f = exp(-p); |
||||
|
q = (vgs-vdse)/e; |
||||
|
g = exp(q); |
||||
|
h = ISO*td*td*f*g; |
||||
|
*cgd = h - ISO*TEMP*TEMP*exp(-PHIB/(CONSTboltz*TEMP)); |
||||
|
delcgdvgs = h/e; |
||||
|
delcgdtd = h*(p-q+2)/td; |
||||
|
deltdvdse = TALPHA*vdse*(2-c/(1+c))/d; |
||||
|
deltdvkneet = (td-TEMP)*c/((1+c)*vkneet); |
||||
|
delvdsevmax = vdse*a/((1+a)*vmax); |
||||
|
delvdsevds = (1-a/(1+a))/b; |
||||
|
temp = delvsatevgt*delvgtvgs; |
||||
|
dvdsevgs = delvdsevmax*CM1*temp; |
||||
|
dtdvgs = deltdvdse*dvdsevgs+deltdvkneet*CK1*temp; |
||||
|
*gmg = delcgdvgs+delcgdtd*dtdvgs; |
||||
|
temp = delvsatevgt*sigma; |
||||
|
dvdsevds = delvdsevds+delvdsevmax*CM1*temp; |
||||
|
dtdvds = deltdvdse*dvdsevds+deltdvkneet*CK1*temp; |
||||
|
*gmd = -delcgdvgs*dvdsevds+delcgdtd*dtdvds; |
||||
|
} else { |
||||
|
gmg = 0; |
||||
|
gmd = 0; |
||||
|
} |
||||
|
|
||||
|
if(model->HFETAgatemod != 0) { |
||||
|
// Gate-source current calculation |
||||
|
double evgs; |
||||
|
double vtn = vt*M2S; |
||||
|
double csat = ISO*TEMP*TEMP*exp(-PHIB/(CONSTboltz*TEMP)); |
||||
|
if (vgs <= -5*vt) { |
||||
|
*ggs = -csat/vgs+ckt->CKTgmin; |
||||
|
*cgs = (*ggs)*vgs; |
||||
|
} else { |
||||
|
evgs = exp(vgs/vtn); |
||||
|
*ggs = csat*evgs/vtn+ckt->CKTgmin; |
||||
|
*cgs = csat*(evgs-1)+ckt->CKTgmin*vgs; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if(model->HFETAgatemod != 0 && (A1 != 0.0 || A2 != 0.0)) { |
||||
|
// Correction current calculations |
||||
|
double vmax; |
||||
|
double delvdsevmax; |
||||
|
double delvdsevds; |
||||
|
double dvdsevgs; |
||||
|
double dvdsevds; |
||||
|
vmax = CM3*vsate; |
||||
|
a = pow(vds/vmax,MV1); |
||||
|
b = pow(1+a,1/MV1); |
||||
|
vdse = vds/b; |
||||
|
delvdsevmax = vdse*a/((1+a)*vmax); |
||||
|
delvdsevds = (1-a/(1+a))/b; |
||||
|
dvdsevgs = delvdsevmax*CM3*delvsatevgt*delvgtvgs; |
||||
|
dvdsevds = delvdsevds+delvdsevmax*CM3*delvsatevgt*sigma; |
||||
|
c = vgte*vdse; |
||||
|
d = 1+A2*c; |
||||
|
e = vdse*delvgtevgt; |
||||
|
f = A2*(*cgd); |
||||
|
*cdrain += A1*(d*(*cgd) - (*cgs)); |
||||
|
*gds += A1*(d*(*gmd)+f*(vgte*dvdsevds+e*sigma)); |
||||
|
*gm += A1*(d*(*gmg)+f*(vgte*dvdsevgs+e*delvgtvgs) - (*ggs)); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
double diode(double u) |
||||
|
{ |
||||
|
|
||||
|
#define U0 (-2.303) |
||||
|
#define A (2.221) |
||||
|
#define B (6.804) |
||||
|
#define C (1.685) |
||||
|
double it; |
||||
|
double ut; |
||||
|
double b; |
||||
|
double c; |
||||
|
double i; |
||||
|
double expu=exp(u); |
||||
|
|
||||
|
if(u <= U0) |
||||
|
{ |
||||
|
it = expu*(1-expu); |
||||
|
}else |
||||
|
{ |
||||
|
b = 0.5*(u-U0); |
||||
|
it = u + A*exp((U0-u)/B) - log(b+sqrt(b*b + 0.25*C*C)); |
||||
|
} |
||||
|
|
||||
|
ut = it + log(it); |
||||
|
b = u-ut; |
||||
|
c = 1+it; |
||||
|
i = it*(1 + b/c + 0.5*b*b/c/c/c); |
||||
|
return(i); |
||||
|
} |
||||
@ -0,0 +1,245 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1987 Thomas L. Quarles |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into HFETA model: Paolo Nenzi 2001 |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/* ARGSUSED */ |
||||
|
int |
||||
|
HFETAmAsk(ckt,inst,which,value) |
||||
|
CKTcircuit *ckt; |
||||
|
GENmodel *inst; |
||||
|
int which; |
||||
|
IFvalue *value; |
||||
|
{ |
||||
|
HFETAmodel *here = (HFETAmodel*)inst; |
||||
|
switch(which) { |
||||
|
case HFETA_MOD_VTO: |
||||
|
value->rValue = here->HFETAthreshold; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_LAMBDA: |
||||
|
value->rValue = here->HFETAlambda; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_RD: |
||||
|
value->rValue = here->HFETArd; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_RS: |
||||
|
value->rValue = here->HFETArs; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_RG: |
||||
|
value->rValue = here->HFETArg; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_RDI: |
||||
|
value->rValue = here->HFETArdi; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_RSI: |
||||
|
value->rValue = here->HFETArsi; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_RGS: |
||||
|
value->rValue = here->HFETArgs; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_RGD: |
||||
|
value->rValue = here->HFETArgd; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_RI: |
||||
|
value->rValue = here->HFETAri; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_RF: |
||||
|
value->rValue = here->HFETArf; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_ETA: |
||||
|
value->rValue = here->HFETAeta; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_M: |
||||
|
value->rValue = here->HFETAm; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_MC: |
||||
|
value->rValue = here->HFETAmc; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_GAMMA: |
||||
|
value->rValue = here->HFETAgamma; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_SIGMA0: |
||||
|
value->rValue = here->HFETAsigma0; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_VSIGMAT: |
||||
|
value->rValue = here->HFETAvsigmat; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_VSIGMA: |
||||
|
value->rValue = here->HFETAvsigma; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_MU: |
||||
|
value->rValue = here->HFETAmu; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_DI: |
||||
|
value->rValue = here->HFETAdi; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_DELTA: |
||||
|
value->rValue = here->HFETAdelta; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_VS: |
||||
|
value->rValue = here->HFETAvs; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_NMAX: |
||||
|
value->rValue = here->HFETAnmax; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_DELTAD: |
||||
|
value->rValue = here->HFETAdeltad; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_JS1D: |
||||
|
value->rValue = here->HFETAjs1d; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_JS2D: |
||||
|
value->rValue = here->HFETAjs2d; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_JS1S: |
||||
|
value->rValue = here->HFETAjs1s; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_JS2S: |
||||
|
value->rValue = here->HFETAjs2s; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_M1D: |
||||
|
value->rValue = here->HFETAm1d; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_M2D: |
||||
|
value->rValue = here->HFETAm2d; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_M1S: |
||||
|
value->rValue = here->HFETAm1s; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_M2S: |
||||
|
value->rValue = here->HFETAm2s; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_EPSI: |
||||
|
value->rValue = here->HFETAepsi; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_P: |
||||
|
value->rValue = here->HFETAp; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_CM3: |
||||
|
value->rValue = here->HFETAcm3; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_A1: |
||||
|
value->rValue = here->HFETAa1; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_A2: |
||||
|
value->rValue = here->HFETAa2; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_MV1: |
||||
|
value->rValue = here->HFETAmv1; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_KAPPA: |
||||
|
value->rValue = here->HFETAkappa; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_DELF: |
||||
|
value->rValue = here->HFETAdelf; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_FGDS: |
||||
|
value->rValue = here->HFETAfgds; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_TF: |
||||
|
value->rValue = here->HFETAtf; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_CDS: |
||||
|
value->rValue = here->HFETAcds; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_PHIB: |
||||
|
value->rValue = here->HFETAphib; |
||||
|
return (OK); |
||||
|
|
||||
|
case HFETA_MOD_TALPHA: |
||||
|
value->rValue = here->HFETAtalpha; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_MT1: |
||||
|
value->rValue = here->HFETAmt1; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_MT2: |
||||
|
value->rValue = here->HFETAmt2; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_CK1: |
||||
|
value->rValue = here->HFETAck1; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_CK2: |
||||
|
value->rValue = here->HFETAck2; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_CM1: |
||||
|
value->rValue = here->HFETAcm1; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_CM2: |
||||
|
value->rValue = here->HFETAcm2; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_ASTAR: |
||||
|
value->rValue = here->HFETAastar; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_ETA1: |
||||
|
value->rValue = here->HFETAeta1; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_D1: |
||||
|
value->rValue = here->HFETAd1; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_VT1: |
||||
|
value->rValue = here->HFETAvt1; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_ETA2: |
||||
|
value->rValue = here->HFETAeta2; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_D2: |
||||
|
value->rValue = here->HFETAd2; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_VT2: |
||||
|
value->rValue = here->HFETAvt2; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_GGR: |
||||
|
value->rValue = here->HFETAggr; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_DEL: |
||||
|
value->rValue = here->HFETAdel; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_GATEMOD: |
||||
|
value->iValue = here->HFETAgatemod; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_KLAMBDA: |
||||
|
value->rValue = here->HFETAklambda; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_KMU: |
||||
|
value->rValue = here->HFETAkmu; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_KVTO: |
||||
|
value->rValue = here->HFETAkvto; |
||||
|
return (OK); |
||||
|
|
||||
|
case HFETA_MOD_DRAINCONDUCT: |
||||
|
value->rValue = here->HFETAdrainConduct; |
||||
|
return (OK); |
||||
|
case HFETA_MOD_SOURCECONDUCT: |
||||
|
value->rValue = here->HFETAsourceConduct; |
||||
|
return (OK); |
||||
|
/* case HFETA_MOD_DEPLETIONCAP: |
||||
|
value->rValue = here->HFETA???; |
||||
|
return(OK); */ |
||||
|
/* case HFETA_MOD_VCRIT: |
||||
|
value->rValue = here->HFETAvcrit; |
||||
|
return (OK); */ |
||||
|
|
||||
|
case HFETA_MOD_TYPE: |
||||
|
if (here->HFETAtype == NHFET) |
||||
|
value->sValue = "nhfet"; |
||||
|
else |
||||
|
value->sValue = "phfet"; |
||||
|
default: |
||||
|
return (E_BADPARM); |
||||
|
} |
||||
|
/* NOTREACHED */ |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 S. Hwang |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into hfeta model: Paolo Nenzi 2001 |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "hfetdefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
HFETAmDelete(inModel,modname,kill) |
||||
|
GENmodel **inModel; |
||||
|
IFuid modname; |
||||
|
GENmodel *kill; |
||||
|
{ |
||||
|
HFETAmodel **model = (HFETAmodel**)inModel; |
||||
|
HFETAmodel *modfast = (HFETAmodel*)kill; |
||||
|
HFETAinstance *here; |
||||
|
HFETAinstance *prev = NULL; |
||||
|
HFETAmodel **oldmod; |
||||
|
oldmod = model; |
||||
|
for( ; *model ; model = &((*model)->HFETAnextModel)) { |
||||
|
if( (*model)->HFETAmodName == modname || |
||||
|
(modfast && *model == modfast) ) goto delgot; |
||||
|
oldmod = model; |
||||
|
} |
||||
|
return(E_NOMOD); |
||||
|
|
||||
|
delgot: |
||||
|
*oldmod = (*model)->HFETAnextModel; /* cut deleted device out of list */ |
||||
|
for(here = (*model)->HFETAinstances ; here ; here = here->HFETAnextInstance) { |
||||
|
if(prev) FREE(prev); |
||||
|
prev = here; |
||||
|
} |
||||
|
if(prev) FREE(prev); |
||||
|
FREE(*model); |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,290 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "const.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
HFETAmParam(param,value,inModel) |
||||
|
int param; |
||||
|
IFvalue *value; |
||||
|
GENmodel *inModel; |
||||
|
{ |
||||
|
HFETAmodel *model = (HFETAmodel*)inModel; |
||||
|
switch(param) |
||||
|
{ |
||||
|
case HFETA_MOD_VTO: |
||||
|
model->HFETAthresholdGiven = TRUE; |
||||
|
model->HFETAthreshold = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_LAMBDA: |
||||
|
model->HFETAlambdaGiven = TRUE; |
||||
|
model->HFETAlambda = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_RD: |
||||
|
model->HFETArdGiven = TRUE; |
||||
|
model->HFETArd = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_RS: |
||||
|
model->HFETArsGiven = TRUE; |
||||
|
model->HFETArs = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_RG: |
||||
|
model->HFETArgGiven = TRUE; |
||||
|
model->HFETArg = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_RDI: |
||||
|
model->HFETArdiGiven = TRUE; |
||||
|
model->HFETArdi = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_RSI: |
||||
|
model->HFETArsiGiven = TRUE; |
||||
|
model->HFETArsi = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_RGS: |
||||
|
model->HFETArgsGiven = TRUE; |
||||
|
model->HFETArgs = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_RGD: |
||||
|
model->HFETArgdGiven = TRUE; |
||||
|
model->HFETArgd = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_RI: |
||||
|
model->HFETAriGiven = TRUE; |
||||
|
model->HFETAri = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_RF: |
||||
|
model->HFETArfGiven = TRUE; |
||||
|
model->HFETArf = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_ETA: |
||||
|
model->HFETAetaGiven = TRUE; |
||||
|
model->HFETAeta = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_M: |
||||
|
model->HFETAmGiven = TRUE; |
||||
|
model->HFETAm = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_MC: |
||||
|
model->HFETAmcGiven = TRUE; |
||||
|
model->HFETAmc = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_GAMMA: |
||||
|
model->HFETAgammaGiven = TRUE; |
||||
|
model->HFETAgamma = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_SIGMA0: |
||||
|
model->HFETAsigma0Given = TRUE; |
||||
|
model->HFETAsigma0 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_VSIGMAT: |
||||
|
model->HFETAvsigmatGiven = TRUE; |
||||
|
model->HFETAvsigmat = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_VSIGMA: |
||||
|
model->HFETAvsigmaGiven = TRUE; |
||||
|
model->HFETAvsigma = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_MU: |
||||
|
model->HFETAmuGiven = TRUE; |
||||
|
model->HFETAmu = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_DI: |
||||
|
model->HFETAdiGiven = TRUE; |
||||
|
model->HFETAdi = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_DELTA: |
||||
|
model->HFETAdeltaGiven = TRUE; |
||||
|
model->HFETAdelta = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_VS: |
||||
|
model->HFETAvsGiven = TRUE; |
||||
|
model->HFETAvs = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_NMAX: |
||||
|
model->HFETAnmaxGiven = TRUE; |
||||
|
model->HFETAnmax = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_DELTAD: |
||||
|
model->HFETAdeltadGiven = TRUE; |
||||
|
model->HFETAdeltad = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_JS1D: |
||||
|
model->HFETAjs1dGiven = TRUE; |
||||
|
model->HFETAjs1d = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_JS2D: |
||||
|
model->HFETAjs2dGiven = TRUE; |
||||
|
model->HFETAjs2d = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_JS1S: |
||||
|
model->HFETAjs1sGiven = TRUE; |
||||
|
model->HFETAjs1s = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_JS2S: |
||||
|
model->HFETAjs2sGiven = TRUE; |
||||
|
model->HFETAjs2s = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_M1D: |
||||
|
model->HFETAm1dGiven = TRUE; |
||||
|
model->HFETAm1d = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_M2D: |
||||
|
model->HFETAm2dGiven = TRUE; |
||||
|
model->HFETAm2d = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_M1S: |
||||
|
model->HFETAm1sGiven = TRUE; |
||||
|
model->HFETAm1s = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_M2S: |
||||
|
model->HFETAm2sGiven = TRUE; |
||||
|
model->HFETAm2s = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_EPSI: |
||||
|
model->HFETAepsiGiven = TRUE; |
||||
|
model->HFETAepsi = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_A1: |
||||
|
model->HFETAa1Given = TRUE; |
||||
|
model->HFETAa1 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_A2: |
||||
|
model->HFETAa2Given = TRUE; |
||||
|
model->HFETAa2 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_MV1: |
||||
|
model->HFETAmv1Given = TRUE; |
||||
|
model->HFETAmv1 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_P: |
||||
|
model->HFETApGiven = TRUE; |
||||
|
model->HFETAp = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_KAPPA: |
||||
|
model->HFETAkappaGiven = TRUE; |
||||
|
model->HFETAkappa = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_DELF: |
||||
|
model->HFETAdelfGiven = TRUE; |
||||
|
model->HFETAdelf = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_FGDS: |
||||
|
model->HFETAfgdsGiven = TRUE; |
||||
|
model->HFETAfgds = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_TF: |
||||
|
model->HFETAtfGiven = TRUE; |
||||
|
model->HFETAtf = value->rValue+CONSTCtoK; |
||||
|
break; |
||||
|
case HFETA_MOD_CDS: |
||||
|
model->HFETAcdsGiven = TRUE; |
||||
|
model->HFETAcds = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_PHIB: |
||||
|
model->HFETAphibGiven = TRUE; |
||||
|
model->HFETAphib = value->rValue*CHARGE; |
||||
|
break; |
||||
|
case HFETA_MOD_TALPHA: |
||||
|
model->HFETAtalphaGiven = TRUE; |
||||
|
model->HFETAtalpha = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_MT1: |
||||
|
model->HFETAmt1Given = TRUE; |
||||
|
model->HFETAmt1 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_MT2: |
||||
|
model->HFETAmt2Given = TRUE; |
||||
|
model->HFETAmt2 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_CK1: |
||||
|
model->HFETAck1Given = TRUE; |
||||
|
model->HFETAck1 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_CK2: |
||||
|
model->HFETAck2Given = TRUE; |
||||
|
model->HFETAck2 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_CM1: |
||||
|
model->HFETAcm1Given = TRUE; |
||||
|
model->HFETAcm1 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_CM2: |
||||
|
model->HFETAcm2Given = TRUE; |
||||
|
model->HFETAcm2 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_CM3: |
||||
|
model->HFETAcm3Given = TRUE; |
||||
|
model->HFETAcm3 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_ASTAR: |
||||
|
model->HFETAastarGiven = TRUE; |
||||
|
model->HFETAastar = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_ETA1: |
||||
|
model->HFETAeta1Given = TRUE; |
||||
|
model->HFETAeta1 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_D1: |
||||
|
model->HFETAd1Given = TRUE; |
||||
|
model->HFETAd1 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_VT1: |
||||
|
model->HFETAvt1Given = TRUE; |
||||
|
model->HFETAvt1 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_ETA2: |
||||
|
model->HFETAeta2Given = TRUE; |
||||
|
model->HFETAeta2 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_D2: |
||||
|
model->HFETAd2Given = TRUE; |
||||
|
model->HFETAd2 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_VT2: |
||||
|
model->HFETAvt2Given = TRUE; |
||||
|
model->HFETAvt2 = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_GGR: |
||||
|
model->HFETAggrGiven = TRUE; |
||||
|
model->HFETAggr = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_DEL: |
||||
|
model->HFETAdelGiven = TRUE; |
||||
|
model->HFETAdel = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_GATEMOD: |
||||
|
model->HFETAgatemodGiven = TRUE; |
||||
|
model->HFETAgatemod = value->iValue; |
||||
|
break; |
||||
|
case HFETA_MOD_KLAMBDA: |
||||
|
model->HFETAklambdaGiven = TRUE; |
||||
|
KLAMBDA = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_KMU: |
||||
|
model->HFETAkmuGiven = TRUE; |
||||
|
KMU = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_KVTO: |
||||
|
model->HFETAkvtoGiven = TRUE; |
||||
|
KVTO = value->rValue; |
||||
|
break; |
||||
|
case HFETA_MOD_NHFET: |
||||
|
if(value->iValue) { |
||||
|
model->HFETAtype = NHFET; |
||||
|
} |
||||
|
break; |
||||
|
case HFETA_MOD_PHFET: |
||||
|
if(value->iValue) { |
||||
|
model->HFETAtype = PHFET; |
||||
|
} |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "ifsim.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/* ARGSUSED */ |
||||
|
int |
||||
|
HFETAparam(param,value,inst,select) |
||||
|
int param; |
||||
|
IFvalue *value; |
||||
|
GENinstance *inst; |
||||
|
IFvalue *select; |
||||
|
{ |
||||
|
HFETAinstance *here = (HFETAinstance*)inst; |
||||
|
switch(param) { |
||||
|
case HFETA_LENGTH: |
||||
|
here->HFETAlength = value->rValue; |
||||
|
here->HFETAlengthGiven = TRUE; |
||||
|
break; |
||||
|
case HFETA_WIDTH: |
||||
|
here->HFETAwidth = value->rValue; |
||||
|
here->HFETAwidthGiven = TRUE; |
||||
|
break; |
||||
|
case HFETA_IC_VDS: |
||||
|
here->HFETAicVDS = value->rValue; |
||||
|
here->HFETAicVDSGiven = TRUE; |
||||
|
break; |
||||
|
case HFETA_IC_VGS: |
||||
|
here->HFETAicVGS = value->rValue; |
||||
|
here->HFETAicVGSGiven = TRUE; |
||||
|
break; |
||||
|
case HFETA_OFF: |
||||
|
here->HFETAoff = value->iValue; |
||||
|
break; |
||||
|
case HFETA_IC: |
||||
|
switch(value->v.numValue) { |
||||
|
case 2: |
||||
|
here->HFETAicVGS = *(value->v.vec.rVec+1); |
||||
|
here->HFETAicVGSGiven = TRUE; |
||||
|
case 1: |
||||
|
here->HFETAicVDS = *(value->v.vec.rVec); |
||||
|
here->HFETAicVDSGiven = TRUE; |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
break; |
||||
|
case HFETA_TEMP: |
||||
|
here->HFETAtemp = value->rValue+CONSTCtoK; |
||||
|
here->HFETAtempGiven = TRUE; |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,432 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "smpdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "const.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
//#define HFETAphibGiven |
||||
|
//#define CHARGE 1.60219e-19 |
||||
|
|
||||
|
int |
||||
|
HFETAsetup(matrix,inModel,ckt,states) |
||||
|
SMPmatrix *matrix; |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
int *states; |
||||
|
/* load the diode structure with those pointers needed later |
||||
|
* for fast matrix loading |
||||
|
*/ |
||||
|
{ |
||||
|
HFETAmodel *model = (HFETAmodel*)inModel; |
||||
|
HFETAinstance *here; |
||||
|
int error; |
||||
|
CKTnode *tmp; |
||||
|
|
||||
|
|
||||
|
/* loop through all the diode models */ |
||||
|
for( ; model != NULL; model = model->HFETAnextModel ) { |
||||
|
if( (model->HFETAtype != NHFET) && (model->HFETAtype != PHFET) ) { |
||||
|
model->HFETAtype = NHFET; |
||||
|
} |
||||
|
if(!model->HFETAthresholdGiven) { |
||||
|
if(model->HFETAtype == NHFET) |
||||
|
model->HFETAthreshold = 0.15; |
||||
|
else |
||||
|
model->HFETAthreshold = -0.15; |
||||
|
} |
||||
|
if(!model->HFETAdiGiven) { |
||||
|
model->HFETAdi = 0.04e-6; |
||||
|
} |
||||
|
if(!model->HFETAlambdaGiven) { |
||||
|
model->HFETAlambda = 0.15; |
||||
|
} |
||||
|
if(!model->HFETAetaGiven) { |
||||
|
if(model->HFETAtype == NHFET) |
||||
|
model->HFETAeta = 1.28; |
||||
|
else |
||||
|
model->HFETAeta = 1.4; |
||||
|
} |
||||
|
if(!model->HFETAmGiven) { |
||||
|
model->HFETAm = 3.0; |
||||
|
} |
||||
|
if(!model->HFETAmcGiven) { |
||||
|
model->HFETAmc = 3.0; |
||||
|
} |
||||
|
if(!model->HFETAgammaGiven) { |
||||
|
model->HFETAgamma = 3.0; |
||||
|
} |
||||
|
if(!model->HFETAsigma0Given) { |
||||
|
model->HFETAsigma0 = 0.057; |
||||
|
} |
||||
|
if(!model->HFETAvsigmatGiven) { |
||||
|
model->HFETAvsigmat = 0.3; |
||||
|
} |
||||
|
if(!model->HFETAvsigmaGiven) { |
||||
|
model->HFETAvsigma = 0.1; |
||||
|
} |
||||
|
if(!model->HFETAmuGiven) { |
||||
|
if(model->HFETAtype == NHFET) |
||||
|
model->HFETAmu = 0.4; |
||||
|
else |
||||
|
model->HFETAmu = 0.03; |
||||
|
} |
||||
|
if(!model->HFETAdeltaGiven) { |
||||
|
model->HFETAdelta = 3.0; |
||||
|
} |
||||
|
if(!model->HFETAvsGiven) { |
||||
|
if(model->HFETAtype == NHFET) |
||||
|
model->HFETAvs = 1.5e5; |
||||
|
else |
||||
|
model->HFETAvs = 0.8e5; |
||||
|
} |
||||
|
if(!model->HFETAnmaxGiven) { |
||||
|
model->HFETAnmax = 2e16; |
||||
|
} |
||||
|
if(!model->HFETAdeltadGiven) { |
||||
|
model->HFETAdeltad = 4.5e-9; |
||||
|
} |
||||
|
if(!model->HFETAjs1dGiven) { |
||||
|
model->HFETAjs1d = 1.0; |
||||
|
} |
||||
|
if(!model->HFETAjs2dGiven) { |
||||
|
model->HFETAjs2d = 1.15e6; |
||||
|
} |
||||
|
if(!model->HFETAjs1sGiven) { |
||||
|
model->HFETAjs1s = 1.0; |
||||
|
} |
||||
|
if(!model->HFETAjs2sGiven) { |
||||
|
model->HFETAjs2s = 1.15e6; |
||||
|
} |
||||
|
if(!model->HFETAm1dGiven) { |
||||
|
model->HFETAm1d = 1.32; |
||||
|
} |
||||
|
if(!model->HFETAm2dGiven) { |
||||
|
model->HFETAm2d = 6.9; |
||||
|
} |
||||
|
if(!model->HFETAm1sGiven) { |
||||
|
model->HFETAm1s = 1.32; |
||||
|
} |
||||
|
if(!model->HFETAm2sGiven) { |
||||
|
model->HFETAm2s = 6.9; |
||||
|
} |
||||
|
if(!model->HFETArdGiven) { |
||||
|
model->HFETArd = 0; |
||||
|
} |
||||
|
if(!model->HFETArsGiven) { |
||||
|
model->HFETArs = 0; |
||||
|
} |
||||
|
if(!model->HFETArdiGiven) { |
||||
|
model->HFETArdi = 0; |
||||
|
} |
||||
|
if(!model->HFETArsiGiven) { |
||||
|
model->HFETArsi = 0; |
||||
|
} |
||||
|
if(!model->HFETArgsGiven) { |
||||
|
model->HFETArgs = 90; |
||||
|
} |
||||
|
if(!model->HFETArgdGiven) { |
||||
|
model->HFETArgd = 90; |
||||
|
} |
||||
|
if(!model->HFETAriGiven) { |
||||
|
model->HFETAri = 0; |
||||
|
} |
||||
|
if(!model->HFETArfGiven) { |
||||
|
model->HFETArf = 0; |
||||
|
} |
||||
|
if(!model->HFETAepsiGiven) { |
||||
|
model->HFETAepsi = 12.244*8.85418e-12; |
||||
|
} |
||||
|
if(!model->HFETAa1Given) { |
||||
|
model->HFETAa1 = 0; |
||||
|
} |
||||
|
if(!model->HFETAa2Given) { |
||||
|
model->HFETAa2 = 0; |
||||
|
} |
||||
|
if(!model->HFETAmv1Given) { |
||||
|
model->HFETAmv1 = 3; |
||||
|
} |
||||
|
if(!model->HFETApGiven) { |
||||
|
model->HFETAp = 1; |
||||
|
} |
||||
|
if(!model->HFETAkappaGiven) { |
||||
|
model->HFETAkappa = 0; |
||||
|
} |
||||
|
if(!model->HFETAdelfGiven) { |
||||
|
model->HFETAdelf = 0; |
||||
|
} |
||||
|
if(!model->HFETAfgdsGiven) { |
||||
|
model->HFETAfgds = 0; |
||||
|
} |
||||
|
if(!model->HFETAtfGiven) { |
||||
|
model->HFETAtf = ckt->CKTtemp; |
||||
|
} |
||||
|
if(!model->HFETAcdsGiven) { |
||||
|
model->HFETAcds = 0; |
||||
|
} |
||||
|
if(!model->HFETAphibGiven) { |
||||
|
model->HFETAphib = 0.5*CHARGE; |
||||
|
} |
||||
|
if(!model->HFETAtalphaGiven) { |
||||
|
model->HFETAtalpha = 1200; |
||||
|
} |
||||
|
if(!model->HFETAmt1Given) { |
||||
|
model->HFETAmt1 = 3.5; |
||||
|
} |
||||
|
if(!model->HFETAmt2Given) { |
||||
|
model->HFETAmt2 = 9.9; |
||||
|
} |
||||
|
if(!model->HFETAck1Given) { |
||||
|
model->HFETAck1 = 1; |
||||
|
} |
||||
|
if(!model->HFETAck2Given) { |
||||
|
model->HFETAck2 = 0; |
||||
|
} |
||||
|
if(!model->HFETAcm1Given) { |
||||
|
model->HFETAcm1 = 3; |
||||
|
} |
||||
|
if(!model->HFETAcm2Given) { |
||||
|
model->HFETAcm2 = 0; |
||||
|
} |
||||
|
if(!model->HFETAcm3Given) { |
||||
|
model->HFETAcm3 = 0.17; |
||||
|
} |
||||
|
if(!model->HFETAastarGiven) { |
||||
|
model->HFETAastar = 4.0e4; |
||||
|
} |
||||
|
if(!model->HFETAeta1Given) { |
||||
|
model->HFETAeta1 = 2; |
||||
|
} |
||||
|
if(!model->HFETAd1Given) { |
||||
|
model->HFETAd1 = 0.03e-6; |
||||
|
} |
||||
|
if(!model->HFETAeta2Given) { |
||||
|
model->HFETAeta2 = 2; |
||||
|
} |
||||
|
if(!model->HFETAd2Given) { |
||||
|
model->HFETAd2 = 0.2e-6; |
||||
|
} |
||||
|
if(!model->HFETAvt2Given) { |
||||
|
// initialized in HFETAtemp |
||||
|
model->HFETAvt2 = 0; |
||||
|
} |
||||
|
|
||||
|
if(!model->HFETAggrGiven) { |
||||
|
model->HFETAggr = 40; |
||||
|
} |
||||
|
if(!model->HFETAdelGiven) { |
||||
|
model->HFETAdel = 0.04; |
||||
|
} |
||||
|
if(!model->HFETAklambdaGiven) |
||||
|
KLAMBDA = 0; |
||||
|
if(!model->HFETAkmuGiven) |
||||
|
KMU = 0; |
||||
|
if(!model->HFETAkvtoGiven) |
||||
|
KVTO = 0; |
||||
|
|
||||
|
/* loop through all the instances of the model */ |
||||
|
for (here = model->HFETAinstances; here != NULL ; |
||||
|
here=here->HFETAnextInstance) { |
||||
|
|
||||
|
if(!here->HFETAlengthGiven) { |
||||
|
here->HFETAlength = 1e-6; |
||||
|
} |
||||
|
if(!here->HFETAwidthGiven) { |
||||
|
here->HFETAwidth = 20e-6; |
||||
|
} |
||||
|
if(!here->HFETAtempGiven) { |
||||
|
here->HFETAtemp = ckt->CKTtemp; |
||||
|
} |
||||
|
|
||||
|
here->HFETAstate = *states; |
||||
|
// *states += 24; |
||||
|
*states += HFETAnumStates; |
||||
|
|
||||
|
matrixpointers: |
||||
|
if(model->HFETArs != 0 && here->HFETAsourcePrimeNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->HFETAname,"source"); |
||||
|
if(error) return(error); |
||||
|
here->HFETAsourcePrimeNode = tmp->number; |
||||
|
|
||||
|
/* XXX: Applied AlansFixes */ |
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->HFETAsourcePrimeNode = here->HFETAsourceNode; |
||||
|
} |
||||
|
|
||||
|
if(model->HFETArd != 0 && here->HFETAdrainPrimeNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->HFETAname,"drain"); |
||||
|
if(error) return(error); |
||||
|
here->HFETAdrainPrimeNode = tmp->number; |
||||
|
|
||||
|
/* XXX: Applied AlansFixes */ |
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->HFETAdrainPrimeNode = here->HFETAdrainNode; |
||||
|
} |
||||
|
|
||||
|
if(model->HFETArg != 0 && here->HFETAgatePrimeNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gate"); |
||||
|
if(error) return(error); |
||||
|
here->HFETAgatePrimeNode = tmp->number; |
||||
|
|
||||
|
/* XXX: Applied AlansFixes */ |
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->HFETAgatePrimeNode = here->HFETAgateNode; |
||||
|
} |
||||
|
if(model->HFETArf != 0 && here->HFETAdrainPrmPrmNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gd"); |
||||
|
if(error) return(error); |
||||
|
here->HFETAdrainPrmPrmNode = tmp->number; |
||||
|
|
||||
|
/* XXX: Applied AlansFixes */ |
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->HFETAdrainPrmPrmNode = here->HFETAdrainPrimeNode; |
||||
|
} |
||||
|
|
||||
|
if(model->HFETAri != 0 && here->HFETAsourcePrmPrmNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gs"); |
||||
|
if(error) return(error); |
||||
|
here->HFETAsourcePrmPrmNode = tmp->number; |
||||
|
|
||||
|
/* XXX: Applied AlanFixes */ |
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->HFETAsourcePrmPrmNode = here->HFETAsourcePrimeNode; |
||||
|
} |
||||
|
|
||||
|
/* macro to make elements with built in test for out of memory */ |
||||
|
#define TSTALLOC(ptr,first,second) \ |
||||
|
if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ |
||||
|
return(E_NOMEM);\ |
||||
|
} |
||||
|
|
||||
|
TSTALLOC(HFETAdrainDrainPrimePtr,HFETAdrainNode,HFETAdrainPrimeNode) |
||||
|
TSTALLOC(HFETAgatePrimeDrainPrimePtr,HFETAgatePrimeNode,HFETAdrainPrimeNode) |
||||
|
TSTALLOC(HFETAgatePrimeSourcePrimePtr,HFETAgatePrimeNode,HFETAsourcePrimeNode) |
||||
|
TSTALLOC(HFETAsourceSourcePrimePtr,HFETAsourceNode,HFETAsourcePrimeNode) |
||||
|
TSTALLOC(HFETAdrainPrimeDrainPtr,HFETAdrainPrimeNode,HFETAdrainNode) |
||||
|
TSTALLOC(HFETAdrainPrimeGatePrimePtr,HFETAdrainPrimeNode,HFETAgatePrimeNode) |
||||
|
TSTALLOC(HFETAdrainPrimeSourcePrimePtr,HFETAdrainPrimeNode,HFETAsourcePrimeNode) |
||||
|
TSTALLOC(HFETAsourcePrimeGatePrimePtr,HFETAsourcePrimeNode,HFETAgatePrimeNode) |
||||
|
TSTALLOC(HFETAsourcePrimeSourcePtr,HFETAsourcePrimeNode,HFETAsourceNode) |
||||
|
TSTALLOC(HFETAsourcePrimeDrainPrimePtr,HFETAsourcePrimeNode,HFETAdrainPrimeNode) |
||||
|
TSTALLOC(HFETAdrainDrainPtr,HFETAdrainNode,HFETAdrainNode) |
||||
|
TSTALLOC(HFETAgatePrimeGatePrimePtr,HFETAgatePrimeNode,HFETAgatePrimeNode) |
||||
|
TSTALLOC(HFETAsourceSourcePtr,HFETAsourceNode,HFETAsourceNode) |
||||
|
TSTALLOC(HFETAdrainPrimeDrainPrimePtr,HFETAdrainPrimeNode,HFETAdrainPrimeNode) |
||||
|
TSTALLOC(HFETAsourcePrimeSourcePrimePtr,HFETAsourcePrimeNode,HFETAsourcePrimeNode) |
||||
|
TSTALLOC(HFETAdrainPrimeDrainPrmPrmPtr,HFETAdrainPrimeNode,HFETAdrainPrmPrmNode) |
||||
|
TSTALLOC(HFETAdrainPrmPrmDrainPrimePtr,HFETAdrainPrmPrmNode,HFETAdrainPrimeNode) |
||||
|
TSTALLOC(HFETAdrainPrmPrmGatePrimePtr,HFETAdrainPrmPrmNode,HFETAgatePrimeNode) |
||||
|
TSTALLOC(HFETAgatePrimeDrainPrmPrmPtr,HFETAgatePrimeNode,HFETAdrainPrmPrmNode) |
||||
|
TSTALLOC(HFETAdrainPrmPrmDrainPrmPrmPtr,HFETAdrainPrmPrmNode,HFETAdrainPrmPrmNode) |
||||
|
TSTALLOC(HFETAsourcePrimeSourcePrmPrmPtr,HFETAsourcePrimeNode,HFETAsourcePrmPrmNode) |
||||
|
TSTALLOC(HFETAsourcePrmPrmSourcePrimePtr,HFETAsourcePrmPrmNode,HFETAsourcePrimeNode) |
||||
|
TSTALLOC(HFETAsourcePrmPrmGatePrimePtr,HFETAsourcePrmPrmNode,HFETAgatePrimeNode) |
||||
|
TSTALLOC(HFETAgatePrimeSourcePrmPrmPtr,HFETAgatePrimeNode,HFETAsourcePrmPrmNode) |
||||
|
TSTALLOC(HFETAsourcePrmPrmSourcePrmPrmPtr,HFETAsourcePrmPrmNode,HFETAsourcePrmPrmNode) |
||||
|
TSTALLOC(HFETAgateGatePtr,HFETAgateNode,HFETAgateNode) |
||||
|
TSTALLOC(HFETAgateGatePrimePtr,HFETAgateNode,HFETAgatePrimeNode) |
||||
|
TSTALLOC(HFETAgatePrimeGatePtr,HFETAgatePrimeNode,HFETAgateNode) |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
HFETAunsetup(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
HFETAmodel *model; |
||||
|
HFETAinstance *here; |
||||
|
|
||||
|
for (model = (HFETAmodel *)inModel; model != NULL; |
||||
|
model = model->HFETAnextModel) |
||||
|
{ |
||||
|
for (here = model->HFETAinstances; here != NULL; |
||||
|
here=here->HFETAnextInstance) |
||||
|
{ |
||||
|
if (here->HFETAdrainPrimeNode |
||||
|
&& here->HFETAdrainPrimeNode != here->HFETAdrainNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->HFETAdrainPrimeNode); |
||||
|
here->HFETAdrainPrimeNode = 0; |
||||
|
} |
||||
|
if (here->HFETAsourcePrimeNode |
||||
|
&& here->HFETAsourcePrimeNode != here->HFETAsourceNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->HFETAsourcePrimeNode); |
||||
|
here->HFETAsourcePrimeNode = 0; |
||||
|
} |
||||
|
} if (here->HFETAgatePrimeNode |
||||
|
&& here->HFETAgatePrimeNode != here->HFETAgateNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->HFETAgatePrimeNode); |
||||
|
here->HFETAgatePrimeNode = 0; |
||||
|
} |
||||
|
} |
||||
|
return OK; |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,96 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "smpdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "const.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/* ARGSUSED */ |
||||
|
int |
||||
|
HFETAtemp(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
HFETAmodel *model = (HFETAmodel*)inModel; |
||||
|
HFETAinstance *here; |
||||
|
double vt; |
||||
|
double temp; |
||||
|
|
||||
|
/* loop through all the diode models */ |
||||
|
for( ; model != NULL; model = model->HFETAnextModel ) { |
||||
|
if(model->HFETArd != 0) { |
||||
|
model->HFETAdrainConduct = 1/model->HFETArd; |
||||
|
} else { |
||||
|
model->HFETAdrainConduct = 0; |
||||
|
} |
||||
|
if(model->HFETArs != 0) { |
||||
|
model->HFETAsourceConduct = 1/model->HFETArs; |
||||
|
} else { |
||||
|
model->HFETAsourceConduct = 0; |
||||
|
} |
||||
|
if(model->HFETArg != 0) { |
||||
|
model->HFETAgateConduct = 1/model->HFETArg; |
||||
|
} else { |
||||
|
model->HFETAgateConduct = 0; |
||||
|
} |
||||
|
if(model->HFETAri != 0) { |
||||
|
model->HFETAgi = 1/model->HFETAri; |
||||
|
} else { |
||||
|
model->HFETAgi = 0; |
||||
|
} |
||||
|
if(model->HFETArf != 0) { |
||||
|
model->HFETAgf = 1/model->HFETArf; |
||||
|
} else { |
||||
|
model->HFETAgf = 0; |
||||
|
} |
||||
|
model->HFETAdeltaSqr = model->HFETAdelta*model->HFETAdelta; |
||||
|
model->HFETAthreshold *= model->HFETAtype; |
||||
|
|
||||
|
if(!model->HFETAvt2Given) |
||||
|
VT2 = VTO; |
||||
|
if(!model->HFETAvt1Given) |
||||
|
IN_VT1 = VTO+CHARGE*NMAX*DI/EPSI; |
||||
|
|
||||
|
for (here = model->HFETAinstances; here != NULL ; |
||||
|
here=here->HFETAnextInstance) { |
||||
|
vt = CONSTKoverQ*TEMP; |
||||
|
TLAMBDA = LAMBDA + KLAMBDA*(TEMP-ckt->CKTnomTemp); |
||||
|
TMU = MU - KMU*(TEMP-ckt->CKTnomTemp); |
||||
|
TVTO = VTO - KVTO*(TEMP-ckt->CKTnomTemp); |
||||
|
N0 = EPSI*ETA*vt/2/CHARGE/(DI+DELTAD); |
||||
|
N01 = EPSI*ETA1*vt/2/CHARGE/D1; |
||||
|
if(model->HFETAeta2Given) |
||||
|
N02 = EPSI*ETA2*vt/2/CHARGE/D2; |
||||
|
else |
||||
|
N02 = 0.0; |
||||
|
GCHI0 = CHARGE*W*TMU/L; |
||||
|
CF = 0.5*EPSI*W; |
||||
|
IMAX = CHARGE*NMAX*VS*W; |
||||
|
IS1D = JS1D*W*L/2; |
||||
|
IS2D = JS2D*W*L/2; |
||||
|
IS1S = JS1S*W*L/2; |
||||
|
IS2S = JS2S*W*L/2; |
||||
|
ISO = ASTAR*W*L/2; |
||||
|
GGRWL = GGR*L*W/2; |
||||
|
temp = exp(TEMP/model->HFETAtf); |
||||
|
FGDS = model->HFETAfgds*temp; |
||||
|
DELF = model->HFETAdelf*temp; |
||||
|
if(model->HFETAgatemod == 0) { |
||||
|
if(IS1S != 0) |
||||
|
here->HFETAvcrit = vt*log(vt/(CONSTroot2*IS1S)); |
||||
|
else |
||||
|
here->HFETAvcrit = DBL_MAX; |
||||
|
} else { |
||||
|
if(ISO != 0.0) |
||||
|
here->HFETAvcrit = vt*log(vt/(CONSTroot2*ISO)); |
||||
|
else |
||||
|
here->HFETAvcrit = DBL_MAX; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfetdefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
HFETAtrunc(inModel,ckt,timeStep) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
double *timeStep; |
||||
|
{ |
||||
|
HFETAmodel *model = (HFETAmodel*)inModel; |
||||
|
HFETAinstance *here; |
||||
|
|
||||
|
for( ; model != NULL; model = model->HFETAnextModel) { |
||||
|
for(here=model->HFETAinstances;here!=NULL;here = here->HFETAnextInstance){ |
||||
|
CKTterr(here->HFETAqgs,ckt,timeStep); |
||||
|
CKTterr(here->HFETAqgd,ckt,timeStep); |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
## Process this file with automake to produce Makefile.in
|
||||
|
|
||||
|
pkglib_LTLIBRARIES = libhfet2.la |
||||
|
|
||||
|
libhfet2_la_SOURCES = \
|
||||
|
hfet2.c \
|
||||
|
hfet2acl.c \
|
||||
|
hfet2ask.c \
|
||||
|
hfet2defs.h \
|
||||
|
hfet2del.c \
|
||||
|
hfet2dest.c \
|
||||
|
hfet2ext.h \
|
||||
|
hfet2getic.c \
|
||||
|
hfet2init.c \
|
||||
|
hfet2init.h \
|
||||
|
hfet2itf.h \
|
||||
|
hfet2load.c \
|
||||
|
hfet2mask.c \
|
||||
|
hfet2mdel.c \
|
||||
|
hfet2mpar.c \
|
||||
|
hfet2param.c \
|
||||
|
hfet2setup.c \
|
||||
|
hfet2temp.c \
|
||||
|
hfet2trunc.c |
||||
|
|
||||
|
|
||||
|
|
||||
|
INCLUDES = -I$(top_srcdir)/src/include |
||||
|
MAINTAINERCLEANFILES = Makefile.in |
||||
@ -0,0 +1,94 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "ifsim.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
IFparm HFET2pTable[] = { /* parameters */ |
||||
|
OP("off", HFET2_OFF, IF_FLAG ,""), |
||||
|
IOP("l", HFET2_LENGTH, IF_REAL ,""), |
||||
|
IOP("w", HFET2_WIDTH, IF_REAL ,""), |
||||
|
IOP("icvds", HFET2_IC_VDS, IF_REAL ,""), |
||||
|
IOP("icvgs", HFET2_IC_VGS, IF_REAL ,""), |
||||
|
IOP("temp", HFET2_TEMP, IF_REAL ,""), |
||||
|
OP("dnode", HFET2_DRAINNODE, IF_INTEGER ,""), |
||||
|
OP("gnode", HFET2_GATENODE, IF_INTEGER ,""), |
||||
|
OP("snode", HFET2_SOURCENODE, IF_INTEGER ,""), |
||||
|
OP("dprimenode",HFET2_DRAINPRIMENODE, IF_INTEGER ,""), |
||||
|
OP("sprimenode",HFET2_SOURCEPRIMENODE,IF_INTEGER ,""), |
||||
|
OP("vgs", HFET2_VGS, IF_REAL ,""), |
||||
|
OP("vgd", HFET2_VGD, IF_REAL ,""), |
||||
|
OP("cg", HFET2_CG, IF_REAL ,""), |
||||
|
OP("cd", HFET2_CD, IF_REAL ,""), |
||||
|
OP("cgd", HFET2_CGD, IF_REAL ,""), |
||||
|
OP("gm", HFET2_GM, IF_REAL ,""), |
||||
|
OP("gds", HFET2_GDS, IF_REAL ,""), |
||||
|
OP("ggs", HFET2_GGS, IF_REAL ,""), |
||||
|
OP("ggd", HFET2_GGD, IF_REAL ,""), |
||||
|
OP("qgs", HFET2_QGS, IF_REAL ,""), |
||||
|
OP("cqgs", HFET2_CQGS, IF_REAL ,""), |
||||
|
OP("qgd", HFET2_QGD, IF_REAL ,""), |
||||
|
OP("cqgd", HFET2_CQGD, IF_REAL ,""), |
||||
|
OP("cs", HFET2_CS, IF_REAL ,""), |
||||
|
OP("p", HFET2_POWER, IF_REAL ,"") |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
IFparm HFET2mPTable[] = { /* model parameters */ |
||||
|
OP( "type", HFET2_MOD_TYPE, IF_STRING,"NHFET or PHFET"), |
||||
|
IOP( "nhfet", HFET2_MOD_NHFET, IF_FLAG,"N type HFET model"), |
||||
|
IOP( "phfet", HFET2_MOD_PHFET, IF_FLAG,"P type HFET model"), |
||||
|
IOP( "cf", HFET2_MOD_CF, IF_REAL,""), |
||||
|
IOP( "d1", HFET2_MOD_D1, IF_REAL,""), |
||||
|
IOP( "d2", HFET2_MOD_D2, IF_REAL,""), |
||||
|
IOP( "del", HFET2_MOD_DEL, IF_REAL,""), |
||||
|
IOP( "delta", HFET2_MOD_DELTA, IF_REAL,""), |
||||
|
IOP( "deltad", HFET2_MOD_DELTAD, IF_REAL,"Thickness correction"), |
||||
|
IOP( "di", HFET2_MOD_DI, IF_REAL,"Depth of device"), |
||||
|
IOP( "epsi", HFET2_MOD_EPSI, IF_REAL,""), |
||||
|
IOP( "eta", HFET2_MOD_ETA, IF_REAL,"Subthreshold ideality factor"), |
||||
|
IOP( "eta1", HFET2_MOD_ETA1, IF_REAL,""), |
||||
|
IOP( "eta2", HFET2_MOD_ETA2, IF_REAL,""), |
||||
|
IOP( "gamma", HFET2_MOD_GAMMA, IF_REAL,"Knee shape parameter"), |
||||
|
IOP( "ggr", HFET2_MOD_GGR, IF_REAL,""), |
||||
|
IOP( "js", HFET2_MOD_JS, IF_REAL,""), |
||||
|
IOP( "klambda", HFET2_MOD_KLAMBDA, IF_REAL,""), |
||||
|
IOP( "kmu", HFET2_MOD_KMU, IF_REAL,""), |
||||
|
IOP( "knmax", HFET2_MOD_KNMAX, IF_REAL,""), |
||||
|
IOP( "kvto", HFET2_MOD_KVTO, IF_REAL,""), |
||||
|
IOP( "lambda", HFET2_MOD_LAMBDA, IF_REAL,"Output conductance parameter"), |
||||
|
IOP( "m", HFET2_MOD_M, IF_REAL,"Knee shape parameter"), |
||||
|
IOP( "mc", HFET2_MOD_MC, IF_REAL,"Knee shape parameter"), |
||||
|
IOP( "mu", HFET2_MOD_MU, IF_REAL,"Moblity"), |
||||
|
IOP( "n", HFET2_MOD_N, IF_REAL,""), |
||||
|
IOP( "nmax", HFET2_MOD_NMAX, IF_REAL,""), |
||||
|
IOP( "p", HFET2_MOD_P, IF_REAL,""), |
||||
|
IOP( "rd", HFET2_MOD_RD, IF_REAL,"Drain ohmic resistance"), |
||||
|
IOP( "rdi", HFET2_MOD_RDI, IF_REAL,"Drain ohmic resistance"), |
||||
|
IOP( "rs", HFET2_MOD_RS, IF_REAL,"Source ohmic resistance"), |
||||
|
IOP( "rsi", HFET2_MOD_RSI, IF_REAL,"Source ohmic resistance"), |
||||
|
IOP( "sigma0", HFET2_MOD_SIGMA0, IF_REAL,"DIBL parameter"), |
||||
|
IOP( "vs", HFET2_MOD_VS, IF_REAL,"Saturation velocity"), |
||||
|
IOP( "vsigma", HFET2_MOD_VSIGMA, IF_REAL,""), |
||||
|
IOP( "vsigmat", HFET2_MOD_VSIGMAT, IF_REAL,""), |
||||
|
IOP( "vt0", HFET2_MOD_VTO, IF_REAL,""), |
||||
|
IOP( "vt1", HFET2_MOD_VT1, IF_REAL,""), |
||||
|
IOP( "vt2", HFET2_MOD_VT2, IF_REAL,""), |
||||
|
IOP( "vto", HFET2_MOD_VTO, IF_REAL,"") |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
char *HFET2names[] = { |
||||
|
"Drain", |
||||
|
"Gate", |
||||
|
"Source" |
||||
|
}; |
||||
|
|
||||
|
int HFET2nSize = NUMELEMS(HFET2names); |
||||
|
int HFET2pTSize = NUMELEMS(HFET2pTable); |
||||
|
int HFET2mPTSize = NUMELEMS(HFET2mPTable); |
||||
|
int HFET2iSize = sizeof(HFET2instance); |
||||
|
int HFET2mSize = sizeof(HFET2model); |
||||
@ -0,0 +1,64 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int HFET2acLoad(inModel, ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
|
||||
|
HFET2model *model = (HFET2model*)inModel; |
||||
|
HFET2instance *here; |
||||
|
double gdpr; |
||||
|
double gspr; |
||||
|
double gm; |
||||
|
double gds; |
||||
|
double ggs; |
||||
|
double xgs; |
||||
|
double ggd; |
||||
|
double xgd; |
||||
|
|
||||
|
for( ; model != NULL; model = model->HFET2nextModel ) |
||||
|
{ |
||||
|
for( here = model->HFET2instances; here != NULL; here = here->HFET2nextInstance) |
||||
|
{ |
||||
|
gdpr=model->HFET2drainConduct; |
||||
|
gspr=model->HFET2sourceConduct; |
||||
|
gm= *(ckt->CKTstate0 + here->HFET2gm) ; |
||||
|
gds= *(ckt->CKTstate0 + here->HFET2gds) ; |
||||
|
ggs= *(ckt->CKTstate0 + here->HFET2ggs) ; |
||||
|
xgs= *(ckt->CKTstate0 + here->HFET2qgs) * ckt->CKTomega ; |
||||
|
ggd= *(ckt->CKTstate0 + here->HFET2ggd) ; |
||||
|
xgd= *(ckt->CKTstate0 + here->HFET2qgd) * ckt->CKTomega ; |
||||
|
*(here->HFET2drainDrainPtr ) += gdpr; |
||||
|
*(here->HFET2gateGatePtr ) += ggd+ggs; |
||||
|
*(here->HFET2gateGatePtr +1) += xgd+xgs; |
||||
|
*(here->HFET2sourceSourcePtr ) += gspr; |
||||
|
*(here->HFET2drainPrimeDrainPrimePtr ) += gdpr+gds+ggd; |
||||
|
*(here->HFET2drainPrimeDrainPrimePtr +1) += xgd; |
||||
|
*(here->HFET2sourcePriHFET2ourcePrimePtr ) += gspr+gds+gm+ggs; |
||||
|
*(here->HFET2sourcePriHFET2ourcePrimePtr +1) += xgs; |
||||
|
*(here->HFET2drainDrainPrimePtr ) -= gdpr; |
||||
|
*(here->HFET2gateDrainPrimePtr ) -= ggd; |
||||
|
*(here->HFET2gateDrainPrimePtr +1) -= xgd; |
||||
|
*(here->HFET2gateSourcePrimePtr ) -= ggs; |
||||
|
*(here->HFET2gateSourcePrimePtr +1) -= xgs; |
||||
|
*(here->HFET2sourceSourcePrimePtr ) -= gspr; |
||||
|
*(here->HFET2drainPrimeDrainPtr ) -= gdpr; |
||||
|
*(here->HFET2drainPrimeGatePtr ) += (-ggd+gm); |
||||
|
*(here->HFET2drainPrimeGatePtr +1) -= xgd; |
||||
|
*(here->HFET2drainPriHFET2ourcePrimePtr ) += (-gds-gm); |
||||
|
*(here->HFET2sourcePrimeGatePtr ) += (-ggs-gm); |
||||
|
*(here->HFET2sourcePrimeGatePtr +1) -= xgs; |
||||
|
*(here->HFET2sourcePriHFET2ourcePtr ) -= gspr; |
||||
|
*(here->HFET2sourcePrimeDrainPrimePtr ) -= gds; |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,132 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1987 Thomas L. Quarles |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into HFET2 source: Paolo Nenzi 2001 |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/* ARGSUSED */ |
||||
|
int |
||||
|
HFET2ask(ckt,inst,which,value,select) |
||||
|
CKTcircuit *ckt; |
||||
|
GENinstance *inst; |
||||
|
int which; |
||||
|
IFvalue *value; |
||||
|
IFvalue *select; |
||||
|
{ |
||||
|
HFET2instance *here = (HFET2instance*)inst; |
||||
|
static char *msg = "Current and power not available in ac analysis"; |
||||
|
switch(which) { |
||||
|
case HFET2_LENGTH: |
||||
|
value->rValue = here->HFET2length; |
||||
|
return (OK); |
||||
|
case HFET2_WIDTH: |
||||
|
value->rValue = here->HFET2width; |
||||
|
case HFET2_IC_VDS: |
||||
|
value->rValue = here->HFET2icVDS; |
||||
|
return (OK); |
||||
|
case HFET2_IC_VGS: |
||||
|
value->rValue = here->HFET2icVGS; |
||||
|
return (OK); |
||||
|
case HFET2_OFF: |
||||
|
value->iValue = here->HFET2off; |
||||
|
return (OK); |
||||
|
case HFET2_DRAINNODE: |
||||
|
value->iValue = here->HFET2drainNode; |
||||
|
return (OK); |
||||
|
case HFET2_GATENODE: |
||||
|
value->iValue = here->HFET2gateNode; |
||||
|
return (OK); |
||||
|
case HFET2_SOURCENODE: |
||||
|
value->iValue = here->HFET2sourceNode; |
||||
|
return (OK); |
||||
|
case HFET2_DRAINPRIMENODE: |
||||
|
value->iValue = here->HFET2drainPrimeNode; |
||||
|
return (OK); |
||||
|
case HFET2_SOURCEPRIMENODE: |
||||
|
value->iValue = here->HFET2sourcePrimeNode; |
||||
|
return (OK); |
||||
|
case HFET2_TEMP: |
||||
|
value->rValue = here->HFET2temp; |
||||
|
case HFET2_VGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2vgs); |
||||
|
return (OK); |
||||
|
case HFET2_VGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2vgd); |
||||
|
return (OK); |
||||
|
case HFET2_CG: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2cg); |
||||
|
return (OK); |
||||
|
case HFET2_CD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2cd); |
||||
|
return (OK); |
||||
|
case HFET2_CGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2cgd); |
||||
|
return (OK); |
||||
|
case HFET2_GM: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2gm); |
||||
|
return (OK); |
||||
|
case HFET2_GDS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2gds); |
||||
|
return (OK); |
||||
|
case HFET2_GGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2ggs); |
||||
|
return (OK); |
||||
|
case HFET2_GGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2ggd); |
||||
|
return (OK); |
||||
|
case HFET2_QGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2qgs); |
||||
|
return (OK); |
||||
|
case HFET2_CQGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2cqgs); |
||||
|
return (OK); |
||||
|
case HFET2_QGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2qgd); |
||||
|
return (OK); |
||||
|
case HFET2_CQGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2cqgd); |
||||
|
return (OK); |
||||
|
case HFET2_CS : |
||||
|
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
||||
|
errMsg = MALLOC(strlen(msg)+1); |
||||
|
errRtn = "HFET2ask"; |
||||
|
strcpy(errMsg,msg); |
||||
|
return(E_ASKCURRENT); |
||||
|
} else { |
||||
|
value->rValue = -*(ckt->CKTstate0 + here->HFET2cd); |
||||
|
value->rValue -= *(ckt->CKTstate0 + here->HFET2cg); |
||||
|
} |
||||
|
return(OK); |
||||
|
case HFET2_POWER : |
||||
|
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
||||
|
errMsg = MALLOC(strlen(msg)+1); |
||||
|
errRtn = "HFET2ask"; |
||||
|
strcpy(errMsg,msg); |
||||
|
return(E_ASKPOWER); |
||||
|
} else { |
||||
|
value->rValue = *(ckt->CKTstate0 + here->HFET2cd) * |
||||
|
*(ckt->CKTrhsOld + here->HFET2drainNode); |
||||
|
value->rValue += *(ckt->CKTstate0 + here->HFET2cg) * |
||||
|
*(ckt->CKTrhsOld + here->HFET2gateNode); |
||||
|
value->rValue -= (*(ckt->CKTstate0+here->HFET2cd) + |
||||
|
*(ckt->CKTstate0 + here->HFET2cg)) * |
||||
|
*(ckt->CKTrhsOld + here->HFET2sourceNode); |
||||
|
} |
||||
|
return(OK); |
||||
|
default: |
||||
|
return (E_BADPARM); |
||||
|
} |
||||
|
/* NOTREACHED */ |
||||
|
} |
||||
@ -0,0 +1,318 @@ |
|||||
|
|
||||
|
#ifndef HFET2 |
||||
|
#define HFET2 |
||||
|
|
||||
|
#include "ifsim.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "gendefs.h" |
||||
|
#include "complex.h" |
||||
|
#include "noisedef.h" |
||||
|
|
||||
|
|
||||
|
typedef struct sHFET2instance { |
||||
|
struct sHFET2model *HFET2modPtr; |
||||
|
struct sHFET2instance *HFET2nextInstance; |
||||
|
IFuid HFET2name; |
||||
|
int HFET2owner; /* number of owner process */ |
||||
|
int HFET2state; /* index into state table for this device */ |
||||
|
|
||||
|
int HFET2drainNode; |
||||
|
int HFET2gateNode; |
||||
|
int HFET2sourceNode; |
||||
|
int HFET2drainPrimeNode; |
||||
|
int HFET2sourcePrimeNode; |
||||
|
double HFET2length; |
||||
|
double HFET2width; |
||||
|
double HFET2temp; |
||||
|
double HFET2tLambda; |
||||
|
double HFET2tMu; |
||||
|
double HFET2tNmax; |
||||
|
double HFET2tVto; |
||||
|
double HFET2icVDS; |
||||
|
double HFET2icVGS; |
||||
|
double *HFET2drainDrainPrimePtr; |
||||
|
double *HFET2gateDrainPrimePtr; |
||||
|
double *HFET2gateSourcePrimePtr; |
||||
|
double *HFET2sourceSourcePrimePtr; |
||||
|
double *HFET2drainPrimeDrainPtr; |
||||
|
double *HFET2drainPrimeGatePtr; |
||||
|
double *HFET2drainPriHFET2ourcePrimePtr; |
||||
|
double *HFET2sourcePrimeGatePtr; |
||||
|
double *HFET2sourcePriHFET2ourcePtr; |
||||
|
double *HFET2sourcePrimeDrainPrimePtr; |
||||
|
double *HFET2drainDrainPtr; |
||||
|
double *HFET2gateGatePtr; |
||||
|
double *HFET2sourceSourcePtr; |
||||
|
double *HFET2drainPrimeDrainPrimePtr; |
||||
|
double *HFET2sourcePriHFET2ourcePrimePtr; |
||||
|
|
||||
|
|
||||
|
#define HFET2vgs HFET2state |
||||
|
#define HFET2vgd HFET2state+1 |
||||
|
#define HFET2cg HFET2state+2 |
||||
|
#define HFET2cd HFET2state+3 |
||||
|
#define HFET2cgd HFET2state+4 |
||||
|
#define HFET2gm HFET2state+5 |
||||
|
#define HFET2gds HFET2state+6 |
||||
|
#define HFET2ggs HFET2state+7 |
||||
|
#define HFET2ggd HFET2state+8 |
||||
|
#define HFET2qgs HFET2state+9 |
||||
|
#define HFET2cqgs HFET2state+10 |
||||
|
#define HFET2qgd HFET2state+11 |
||||
|
#define HFET2cqgd HFET2state+12 |
||||
|
|
||||
|
int HFET2mode; |
||||
|
int HFET2off; |
||||
|
|
||||
|
unsigned HFET2icVDSGiven : 1; |
||||
|
unsigned HFET2icVGSGiven : 1; |
||||
|
unsigned HFET2lengthGiven : 1; |
||||
|
unsigned HFET2widthGiven : 1; |
||||
|
unsigned HFET2tempGiven : 1; |
||||
|
|
||||
|
double HFET2n0; |
||||
|
double HFET2n01; |
||||
|
double HFET2n02; |
||||
|
double HFET2gchi0; |
||||
|
double HFET2imax; |
||||
|
double HFET2vcrit; |
||||
|
double HFET2ggrlw; |
||||
|
double HFET2jslw; |
||||
|
|
||||
|
} HFET2instance ; |
||||
|
|
||||
|
|
||||
|
|
||||
|
typedef struct sHFET2model { |
||||
|
int HFET2modType; |
||||
|
struct sHFET2model *HFET2nextModel; |
||||
|
HFET2instance * HFET2instances; |
||||
|
IFuid HFET2modName; |
||||
|
int HFET2type; |
||||
|
|
||||
|
double HFET2cf; |
||||
|
double HFET2d1; |
||||
|
double HFET2d2; |
||||
|
double HFET2del; |
||||
|
double HFET2delta; |
||||
|
double HFET2deltad; |
||||
|
double HFET2di; |
||||
|
double HFET2epsi; |
||||
|
double HFET2eta; |
||||
|
double HFET2eta1; |
||||
|
double HFET2eta2; |
||||
|
double HFET2gamma; |
||||
|
double HFET2ggr; |
||||
|
double HFET2js; |
||||
|
double HFET2klambda; |
||||
|
double HFET2kmu; |
||||
|
double HFET2knmax; |
||||
|
double HFET2kvto; |
||||
|
double HFET2lambda; |
||||
|
double HFET2m; |
||||
|
double HFET2mc; |
||||
|
double HFET2mu; |
||||
|
double HFET2n; |
||||
|
double HFET2nmax; |
||||
|
double HFET2p; |
||||
|
double HFET2rd; |
||||
|
double HFET2rdi; |
||||
|
double HFET2rs; |
||||
|
double HFET2rsi; |
||||
|
double HFET2sigma0; |
||||
|
double HFET2vs; |
||||
|
double HFET2vsigma; |
||||
|
double HFET2vsigmat; |
||||
|
double HFET2vt1; |
||||
|
double HFET2vt2; |
||||
|
double HFET2vto; |
||||
|
|
||||
|
double HFET2drainConduct; |
||||
|
double HFET2sourceConduct; |
||||
|
double HFET2deltaSqr; |
||||
|
|
||||
|
unsigned HFET2cfGiven : 1; |
||||
|
unsigned HFET2d1Given : 1; |
||||
|
unsigned HFET2d2Given : 1; |
||||
|
unsigned HFET2delGiven : 1; |
||||
|
unsigned HFET2deltaGiven : 1; |
||||
|
unsigned HFET2deltadGiven : 1; |
||||
|
unsigned HFET2diGiven : 1; |
||||
|
unsigned HFET2epsiGiven : 1; |
||||
|
unsigned HFET2etaGiven : 1; |
||||
|
unsigned HFET2eta1Given : 1; |
||||
|
unsigned HFET2eta2Given : 1; |
||||
|
unsigned HFET2gammaGiven : 1; |
||||
|
unsigned HFET2ggrGiven : 1; |
||||
|
unsigned HFET2jsGiven : 1; |
||||
|
unsigned HFET2klambdaGiven : 1; |
||||
|
unsigned HFET2kmuGiven : 1; |
||||
|
unsigned HFET2knmaxGiven : 1; |
||||
|
unsigned HFET2kvtoGiven : 1; |
||||
|
unsigned HFET2lambdaGiven : 1; |
||||
|
unsigned HFET2mGiven : 1; |
||||
|
unsigned HFET2mcGiven : 1; |
||||
|
unsigned HFET2muGiven : 1; |
||||
|
unsigned HFET2nGiven : 1; |
||||
|
unsigned HFET2nmaxGiven : 1; |
||||
|
unsigned HFET2pGiven : 1; |
||||
|
unsigned HFET2rdGiven : 1; |
||||
|
unsigned HFET2rdiGiven : 1; |
||||
|
unsigned HFET2rsGiven : 1; |
||||
|
unsigned HFET2rsiGiven : 1; |
||||
|
unsigned HFET2sigma0Given : 1; |
||||
|
unsigned HFET2vsGiven : 1; |
||||
|
unsigned HFET2vsigmaGiven : 1; |
||||
|
unsigned HFET2vsigmatGiven : 1; |
||||
|
unsigned HFET2vt1Given : 1; |
||||
|
unsigned HFET2vt2Given : 1; |
||||
|
unsigned HFET2vtoGiven : 1; |
||||
|
|
||||
|
} HFET2model; |
||||
|
|
||||
|
|
||||
|
#ifndef NHFET |
||||
|
#define NHFET 1 |
||||
|
#define PHFET -1 |
||||
|
#endif /*NMF*/ |
||||
|
|
||||
|
/* device parameters */ |
||||
|
#define HFET2_LENGTH 1 |
||||
|
#define HFET2_WIDTH 2 |
||||
|
#define HFET2_IC_VDS 3 |
||||
|
#define HFET2_IC_VGS 4 |
||||
|
#define HFET2_IC 5 |
||||
|
#define HFET2_OFF 6 |
||||
|
#define HFET2_CS 7 |
||||
|
#define HFET2_POWER 8 |
||||
|
#define HFET2_TEMP 9 |
||||
|
|
||||
|
/* model parameters */ |
||||
|
#define HFET2_MOD_NHFET 101 |
||||
|
#define HFET2_MOD_PHFET 102 |
||||
|
#define HFET2_MOD_CF 103 |
||||
|
#define HFET2_MOD_D1 104 |
||||
|
#define HFET2_MOD_D2 105 |
||||
|
#define HFET2_MOD_DEL 106 |
||||
|
#define HFET2_MOD_DELTA 107 |
||||
|
#define HFET2_MOD_DELTAD 108 |
||||
|
#define HFET2_MOD_DI 109 |
||||
|
#define HFET2_MOD_EPSI 110 |
||||
|
#define HFET2_MOD_ETA 111 |
||||
|
#define HFET2_MOD_ETA1 112 |
||||
|
#define HFET2_MOD_ETA2 113 |
||||
|
#define HFET2_MOD_GAMMA 114 |
||||
|
#define HFET2_MOD_GGR 115 |
||||
|
#define HFET2_MOD_JS 116 |
||||
|
#define HFET2_MOD_KLAMBDA 117 |
||||
|
#define HFET2_MOD_KMU 118 |
||||
|
#define HFET2_MOD_KNMAX 119 |
||||
|
#define HFET2_MOD_KVTO 120 |
||||
|
#define HFET2_MOD_LAMBDA 121 |
||||
|
#define HFET2_MOD_M 122 |
||||
|
#define HFET2_MOD_MC 123 |
||||
|
#define HFET2_MOD_MU 124 |
||||
|
#define HFET2_MOD_N 125 |
||||
|
#define HFET2_MOD_NMAX 126 |
||||
|
#define HFET2_MOD_P 127 |
||||
|
#define HFET2_MOD_RD 128 |
||||
|
#define HFET2_MOD_RDI 129 |
||||
|
#define HFET2_MOD_RS 130 |
||||
|
#define HFET2_MOD_RSI 131 |
||||
|
#define HFET2_MOD_SIGMA0 132 |
||||
|
#define HFET2_MOD_VS 133 |
||||
|
#define HFET2_MOD_VSIGMA 134 |
||||
|
#define HFET2_MOD_VSIGMAT 135 |
||||
|
#define HFET2_MOD_VT1 136 |
||||
|
#define HFET2_MOD_VT2 137 |
||||
|
#define HFET2_MOD_VTO 138 |
||||
|
#define HFET2_MOD_TYPE 139 |
||||
|
|
||||
|
/* device questions */ |
||||
|
|
||||
|
#define HFET2_DRAINNODE 201 |
||||
|
#define HFET2_GATENODE 202 |
||||
|
#define HFET2_SOURCENODE 203 |
||||
|
#define HFET2_DRAINPRIMENODE 204 |
||||
|
#define HFET2_SOURCEPRIMENODE 205 |
||||
|
|
||||
|
#define HFET2_VGS 206 |
||||
|
#define HFET2_VGD 207 |
||||
|
#define HFET2_CG 208 |
||||
|
#define HFET2_CD 209 |
||||
|
#define HFET2_CGD 210 |
||||
|
#define HFET2_GM 211 |
||||
|
#define HFET2_GDS 212 |
||||
|
#define HFET2_GGS 213 |
||||
|
#define HFET2_GGD 214 |
||||
|
#define HFET2_QGS 215 |
||||
|
#define HFET2_CQGS 216 |
||||
|
#define HFET2_QGD 217 |
||||
|
#define HFET2_CQGD 218 |
||||
|
|
||||
|
/* model questions */ |
||||
|
|
||||
|
#define HFET2_MOD_DRAINCONDUCT 301 |
||||
|
#define HFET2_MOD_SOURCECONDUCT 302 |
||||
|
#define HFET2_MOD_DEPLETIONCAP 303 |
||||
|
#define HFET2_MOD_VCRIT 304 |
||||
|
|
||||
|
#define CF (model->HFET2cf) |
||||
|
#define D1 (model->HFET2d1) |
||||
|
#define D2 (model->HFET2d2) |
||||
|
#define DEL (model->HFET2del) |
||||
|
#define DELTA (model->HFET2delta) |
||||
|
#define DELTAD (model->HFET2deltad) |
||||
|
#define DI (model->HFET2di) |
||||
|
#define EPSI (model->HFET2epsi) |
||||
|
#define ETA (model->HFET2eta) |
||||
|
#define ETA1 (model->HFET2eta1) |
||||
|
#define ETA2 (model->HFET2eta2) |
||||
|
#define GAMMA (model->HFET2gamma) |
||||
|
#define GGR (model->HFET2ggr) |
||||
|
#define JS (model->HFET2js) |
||||
|
#define KLAMBDA (model->HFET2klambda) |
||||
|
#define KMU (model->HFET2kmu) |
||||
|
#define KNMAX (model->HFET2knmax) |
||||
|
#define KVTO (model->HFET2kvto) |
||||
|
#define LAMBDA (model->HFET2lambda) |
||||
|
#define M (model->HFET2m) |
||||
|
#define MC (model->HFET2mc) |
||||
|
#define MU (model->HFET2mu) |
||||
|
#define N (model->HFET2n) |
||||
|
#define NMAX (model->HFET2nmax) |
||||
|
#define PP (model->HFET2p) |
||||
|
#define RD (model->HFET2rd) |
||||
|
#define RDI (model->HFET2rdi) |
||||
|
#define RS (model->HFET2rs) |
||||
|
#define RSI (model->HFET2rsi) |
||||
|
#define SIGMA0 (model->HFET2sigma0) |
||||
|
#define TYPE (model->HFET2type) |
||||
|
#define VS (model->HFET2vs) |
||||
|
#define VSIGMA (model->HFET2vsigma) |
||||
|
#define VSIGMAT (model->HFET2vsigmat) |
||||
|
#define HFET2_VT1 (model->HFET2vt1) /* Fix a redefinition in include files */ |
||||
|
#define VT2 (model->HFET2vt2) |
||||
|
#define VTO (model->HFET2vto) |
||||
|
|
||||
|
#define DELTA2 (model->HFET2deltaSqr) |
||||
|
|
||||
|
#define GCHI0 (here->HFET2gchi0) |
||||
|
#define GGRLW (here->HFET2ggrlw) |
||||
|
#define JSLW (here->HFET2jslw) |
||||
|
#define IMAX (here->HFET2imax) |
||||
|
#define L (here->HFET2length) |
||||
|
#define N0 (here->HFET2n0) |
||||
|
#define N01 (here->HFET2n01) |
||||
|
#define N02 (here->HFET2n02) |
||||
|
#define TEMP (here->HFET2temp) |
||||
|
#define TLAMBDA (here->HFET2tLambda) |
||||
|
#define TMU (here->HFET2tMu) |
||||
|
#define TNMAX (here->HFET2tNmax) |
||||
|
#define TVTO (here->HFET2tVto) |
||||
|
#define VCRIT (here->HFET2vcrit) |
||||
|
#define W (here->HFET2width) |
||||
|
|
||||
|
#include "hfet2ext.h" |
||||
|
|
||||
|
#endif /*HFET2*/ |
||||
@ -0,0 +1,39 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 S. Hwang |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into hfet2 model: Paolo Nenzi 2001 |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "hfet2defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
HFET2delete(inModel,name,inst) |
||||
|
GENmodel *inModel; |
||||
|
IFuid name; |
||||
|
GENinstance **inst; |
||||
|
{ |
||||
|
HFET2model *model = (HFET2model*)inModel; |
||||
|
HFET2instance **fast = (HFET2instance**)inst; |
||||
|
HFET2instance **prev = NULL; |
||||
|
HFET2instance *here; |
||||
|
|
||||
|
for( ; model ; model = model->HFET2nextModel) { |
||||
|
prev = &(model->HFET2instances); |
||||
|
for(here = *prev; here ; here = *prev) { |
||||
|
if(here->HFET2name == name || (fast && here==*fast) ) { |
||||
|
*prev= here->HFET2nextInstance; |
||||
|
FREE(here); |
||||
|
return(OK); |
||||
|
} |
||||
|
prev = &(here->HFET2nextInstance); |
||||
|
} |
||||
|
} |
||||
|
return(E_NODEV); |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "hfet2defs.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
void HFET2destroy(inModel) |
||||
|
GENmodel **inModel; |
||||
|
{ |
||||
|
|
||||
|
HFET2model **model = (HFET2model**)inModel; |
||||
|
HFET2instance *here; |
||||
|
HFET2instance *prev = NULL; |
||||
|
HFET2model *mod = *model; |
||||
|
HFET2model *oldmod = NULL; |
||||
|
|
||||
|
for( ; mod ; mod = mod->HFET2nextModel) { |
||||
|
if(oldmod) FREE(oldmod); |
||||
|
oldmod = mod; |
||||
|
prev = (HFET2instance *)NULL; |
||||
|
for(here = mod->HFET2instances ; here ; here = here->HFET2nextInstance) { |
||||
|
if(prev) FREE(prev); |
||||
|
prev = here; |
||||
|
} |
||||
|
if(prev) FREE(prev); |
||||
|
} |
||||
|
if(oldmod) FREE(oldmod); |
||||
|
*model = NULL; |
||||
|
return; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#ifdef __STDC__ |
||||
|
extern int HFET2acLoad(GENmodel*,CKTcircuit*); |
||||
|
extern int HFET2ask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); |
||||
|
extern int HFET2delete(GENmodel*,IFuid,GENinstance**); |
||||
|
extern void HFET2destroy(GENmodel**); |
||||
|
extern int HFET2getic(GENmodel*,CKTcircuit*); |
||||
|
extern int HFET2load(GENmodel*,CKTcircuit*); |
||||
|
extern int HFET2mAsk(CKTcircuit*,GENmodel*,int,IFvalue*); |
||||
|
extern int HFET2mDelete(GENmodel**,IFuid,GENmodel*); |
||||
|
extern int HFET2mParam(int,IFvalue*,GENmodel*); |
||||
|
extern int HFET2param(int,IFvalue*,GENinstance*,IFvalue*); |
||||
|
extern int HFET2setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); |
||||
|
extern int HFET2temp(GENmodel*,CKTcircuit*); |
||||
|
extern int HFET2trunc(GENmodel*,CKTcircuit*,double*); |
||||
|
extern int HFET2unsetup( GENmodel*,CKTcircuit*); |
||||
|
|
||||
|
#else /* stdc */ |
||||
|
extern int HFET2acLoad(); |
||||
|
extern int HFET2ask(); |
||||
|
extern int HFET2delete(); |
||||
|
extern void HFET2destroy(); |
||||
|
extern int HFET2getic(); |
||||
|
extern int HFET2load(); |
||||
|
extern int HFETAmAsk(); |
||||
|
extern int HFETAmDelete(); |
||||
|
extern int HFET2mParam(); |
||||
|
extern int HFET2param(); |
||||
|
extern int HFET2setup(); |
||||
|
extern int HFET2temp(); |
||||
|
extern int HFET2trunc(); |
||||
|
extern int HFET2unsetup(); |
||||
|
#endif |
||||
|
|
||||
@ -0,0 +1,32 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int HFET2getic(inModel, ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
|
||||
|
HFET2model *model = (HFET2model*)inModel; |
||||
|
HFET2instance *here; |
||||
|
|
||||
|
for( ; model ; model = model->HFET2nextModel) { |
||||
|
for(here = model->HFET2instances; here ; here = here->HFET2nextInstance) { |
||||
|
if(!here->HFET2icVDSGiven) { |
||||
|
here->HFET2icVDS = *(ckt->CKTrhs + here->HFET2drainNode) - |
||||
|
*(ckt->CKTrhs + here->HFET2sourceNode); |
||||
|
} |
||||
|
if(!here->HFET2icVGSGiven) { |
||||
|
here->HFET2icVGS = *(ckt->CKTrhs + here->HFET2gateNode) - |
||||
|
*(ckt->CKTrhs + here->HFET2sourceNode); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
#include <config.h> |
||||
|
|
||||
|
#include <devdefs.h> |
||||
|
|
||||
|
#include "hfet2itf.h" |
||||
|
#include "hfet2ext.h" |
||||
|
#include "hfet2init.h" |
||||
|
|
||||
|
|
||||
|
SPICEdev HFET2info = { |
||||
|
{ |
||||
|
"HFET2", |
||||
|
"HFET2 Model", |
||||
|
|
||||
|
&HFET2nSize, |
||||
|
&HFET2nSize, |
||||
|
HFET2names, |
||||
|
|
||||
|
&HFET2pTSize, |
||||
|
HFET2pTable, |
||||
|
|
||||
|
&HFET2mPTSize, |
||||
|
HFET2mPTable, |
||||
|
DEV_DEFAULT |
||||
|
}, |
||||
|
|
||||
|
DEVparam : HFET2param, |
||||
|
DEVmodParam : HFET2mParam, |
||||
|
DEVload : HFET2load, |
||||
|
DEVsetup : HFET2setup, |
||||
|
DEVunsetup : HFET2unsetup, |
||||
|
DEVpzSetup : HFET2setup, |
||||
|
DEVtemperature: HFET2temp, |
||||
|
DEVtrunc : HFET2trunc, |
||||
|
DEVfindBranch : NULL, |
||||
|
DEVacLoad : HFET2acLoad, |
||||
|
DEVaccept : NULL, |
||||
|
DEVdestroy : HFET2destroy, |
||||
|
DEVmodDelete : HFET2mDelete, |
||||
|
DEVdelete : HFET2delete, |
||||
|
DEVsetic : HFET2getic, |
||||
|
DEVask : HFET2ask, |
||||
|
DEVmodAsk : HFET2mAsk, |
||||
|
DEVpzLoad : NULL, |
||||
|
DEVconvTest : NULL, |
||||
|
DEVsenSetup : NULL, |
||||
|
DEVsenLoad : NULL, |
||||
|
DEVsenUpdate : NULL, |
||||
|
DEVsenAcLoad : NULL, |
||||
|
DEVsenPrint : NULL, |
||||
|
DEVsenTrunc : NULL, |
||||
|
DEVdisto : NULL, |
||||
|
DEVnoise : NULL, |
||||
|
|
||||
|
DEVinstSize : &HFET2iSize, |
||||
|
DEVmodSize : &HFET2mSize |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
|
||||
|
SPICEdev * |
||||
|
get_hfet2_info(void) |
||||
|
{ |
||||
|
return &HFET2info; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#ifndef _HFET2INIT_H |
||||
|
#define _HFET2INIT_H |
||||
|
|
||||
|
extern IFparm HFET2pTable[ ]; |
||||
|
extern IFparm HFET2mPTable[ ]; |
||||
|
extern char *HFET2names[ ]; |
||||
|
extern int HFET2pTSize; |
||||
|
extern int HFET2mPTSize; |
||||
|
extern int HFET2nSize; |
||||
|
extern int HFET2iSize; |
||||
|
extern int HFET2mSize; |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,7 @@ |
|||||
|
#ifndef DEV_HFET2 |
||||
|
#define DEV_HFET2 |
||||
|
|
||||
|
SPICEdev *get_hfet2_info(void); |
||||
|
|
||||
|
#endif |
||||
|
|
||||
@ -0,0 +1,456 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "devdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "const.h" |
||||
|
#include "trandefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
void Pause(void); |
||||
|
|
||||
|
static void hfeta2(HFET2model *model, HFET2instance *here, CKTcircuit *ckt, |
||||
|
double vgs, double vds, double *cdrain, double *gm, |
||||
|
double *gds, double *capgs, double *capgd); |
||||
|
|
||||
|
|
||||
|
int HFET2load(inModel, ckt) |
||||
|
GENmodel *inModel; |
||||
|
register CKTcircuit *ckt; |
||||
|
{ |
||||
|
|
||||
|
register HFET2model *model = (HFET2model*)inModel; |
||||
|
register HFET2instance *here; |
||||
|
double capgd; |
||||
|
double capgs; |
||||
|
double cd; |
||||
|
double cdhat; |
||||
|
double cdrain; |
||||
|
double cdreq; |
||||
|
double ceq; |
||||
|
double ceqgd; |
||||
|
double ceqgs; |
||||
|
double cg; |
||||
|
double cgd; |
||||
|
double cghat; |
||||
|
double delvds; |
||||
|
double delvgd; |
||||
|
double delvgs; |
||||
|
double gdpr; |
||||
|
double gds; |
||||
|
double geq; |
||||
|
double ggd; |
||||
|
double ggs; |
||||
|
double gm; |
||||
|
double gspr; |
||||
|
double vcrit; |
||||
|
double vds; |
||||
|
double vgd; |
||||
|
double vgd1; |
||||
|
double vgs; |
||||
|
double vgs1; |
||||
|
double vt; |
||||
|
double vto; |
||||
|
double xfact; |
||||
|
int icheck; |
||||
|
int ichk1; |
||||
|
int error; |
||||
|
int inverse; |
||||
|
|
||||
|
for( ; model != NULL; model = model->HFET2nextModel ) { |
||||
|
for(here = model->HFET2instances; here != NULL; here=here->HFET2nextInstance) { |
||||
|
gdpr = model->HFET2drainConduct; |
||||
|
gspr = model->HFET2sourceConduct; |
||||
|
vcrit = VCRIT; |
||||
|
vto = TVTO; |
||||
|
vt = CONSTKoverQ*TEMP; |
||||
|
icheck = 1; |
||||
|
if( ckt->CKTmode & MODEINITSMSIG) { |
||||
|
vgs = *(ckt->CKTstate0 + here->HFET2vgs); |
||||
|
vgd = *(ckt->CKTstate0 + here->HFET2vgd); |
||||
|
} else if(ckt->CKTmode & MODEINITTRAN) { |
||||
|
vgs = *(ckt->CKTstate1 + here->HFET2vgs); |
||||
|
vgd = *(ckt->CKTstate1 + here->HFET2vgd); |
||||
|
} else if((ckt->CKTmode & MODEINITJCT) && (ckt->CKTmode & MODETRANOP) && |
||||
|
(ckt->CKTmode & MODEUIC) ) { |
||||
|
vds = model->HFET2type*here->HFET2icVDS; |
||||
|
vgs = model->HFET2type*here->HFET2icVGS; |
||||
|
vgd = vgs-vds; |
||||
|
} else if ( (ckt->CKTmode & MODEINITJCT) && (here->HFET2off == 0) ) { |
||||
|
vgs = -1; |
||||
|
vgd = -1; |
||||
|
} else if((ckt->CKTmode & MODEINITJCT) || |
||||
|
((ckt->CKTmode & MODEINITFIX) && (here->HFET2off))) { |
||||
|
vgs = 0; |
||||
|
vgd = 0; |
||||
|
} else { |
||||
|
#ifndef PREDICTOR |
||||
|
if(ckt->CKTmode & MODEINITPRED) { |
||||
|
xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2]; |
||||
|
*(ckt->CKTstate0 + here->HFET2vgs) = |
||||
|
*(ckt->CKTstate1 + here->HFET2vgs); |
||||
|
vgs = (1+xfact) * *(ckt->CKTstate1 + here->HFET2vgs) - |
||||
|
xfact * *(ckt->CKTstate2 + here->HFET2vgs); |
||||
|
*(ckt->CKTstate0 + here->HFET2vgd) = |
||||
|
*(ckt->CKTstate1 + here->HFET2vgd); |
||||
|
vgd = (1+xfact)* *(ckt->CKTstate1 + here->HFET2vgd) - |
||||
|
xfact * *(ckt->CKTstate2 + here->HFET2vgd); |
||||
|
*(ckt->CKTstate0 + here->HFET2cg) = |
||||
|
*(ckt->CKTstate1 + here->HFET2cg); |
||||
|
*(ckt->CKTstate0 + here->HFET2cd) = |
||||
|
*(ckt->CKTstate1 + here->HFET2cd); |
||||
|
*(ckt->CKTstate0 + here->HFET2cgd) = |
||||
|
*(ckt->CKTstate1 + here->HFET2cgd); |
||||
|
*(ckt->CKTstate0 + here->HFET2gm) = |
||||
|
*(ckt->CKTstate1 + here->HFET2gm); |
||||
|
*(ckt->CKTstate0 + here->HFET2gds) = |
||||
|
*(ckt->CKTstate1 + here->HFET2gds); |
||||
|
*(ckt->CKTstate0 + here->HFET2ggs) = |
||||
|
*(ckt->CKTstate1 + here->HFET2ggs); |
||||
|
*(ckt->CKTstate0 + here->HFET2ggd) = |
||||
|
*(ckt->CKTstate1 + here->HFET2ggd); |
||||
|
} else { |
||||
|
#endif /* PREDICTOR */ |
||||
|
vgs = model->HFET2type* |
||||
|
(*(ckt->CKTrhsOld+ here->HFET2gateNode)- *(ckt->CKTrhsOld+ |
||||
|
here->HFET2sourcePrimeNode)); |
||||
|
vgd = model->HFET2type* |
||||
|
(*(ckt->CKTrhsOld+here->HFET2gateNode)- *(ckt->CKTrhsOld+ |
||||
|
here->HFET2drainPrimeNode)); |
||||
|
#ifndef PREDICTOR |
||||
|
} |
||||
|
#endif /* PREDICTOR */ |
||||
|
delvgs=vgs - *(ckt->CKTstate0 + here->HFET2vgs); |
||||
|
delvgd=vgd - *(ckt->CKTstate0 + here->HFET2vgd); |
||||
|
delvds=delvgs - delvgd; |
||||
|
cghat= *(ckt->CKTstate0 + here->HFET2cg) + |
||||
|
*(ckt->CKTstate0 + here->HFET2ggd)*delvgd + |
||||
|
*(ckt->CKTstate0 + here->HFET2ggs)*delvgs; |
||||
|
cdhat= *(ckt->CKTstate0 + here->HFET2cd) + |
||||
|
*(ckt->CKTstate0 + here->HFET2gm)*delvgs + |
||||
|
*(ckt->CKTstate0 + here->HFET2gds)*delvds - |
||||
|
*(ckt->CKTstate0 + here->HFET2ggd)*delvgd; |
||||
|
|
||||
|
// bypass if solution has not changed |
||||
|
|
||||
|
if((ckt->CKTbypass) && |
||||
|
(!(ckt->CKTmode & MODEINITPRED)) && |
||||
|
(fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs), |
||||
|
fabs(*(ckt->CKTstate0 + here->HFET2vgs)))+ |
||||
|
ckt->CKTvoltTol) ) |
||||
|
if ( (fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd), |
||||
|
fabs(*(ckt->CKTstate0 + here->HFET2vgd)))+ |
||||
|
ckt->CKTvoltTol)) |
||||
|
if ( (fabs(cghat-*(ckt->CKTstate0 + here->HFET2cg)) |
||||
|
< ckt->CKTreltol*MAX(fabs(cghat), |
||||
|
fabs(*(ckt->CKTstate0 + here->HFET2cg)))+ |
||||
|
ckt->CKTabstol) ) if ( /* hack - expression too big */ |
||||
|
(fabs(cdhat-*(ckt->CKTstate0 + here->HFET2cd)) |
||||
|
< ckt->CKTreltol*MAX(fabs(cdhat), |
||||
|
fabs(*(ckt->CKTstate0 + here->HFET2cd)))+ |
||||
|
ckt->CKTabstol) ) { |
||||
|
|
||||
|
/* we can do a bypass */ |
||||
|
vgs= *(ckt->CKTstate0 + here->HFET2vgs); |
||||
|
vgd= *(ckt->CKTstate0 + here->HFET2vgd); |
||||
|
vds= vgs-vgd; |
||||
|
cg= *(ckt->CKTstate0 + here->HFET2cg); |
||||
|
cd= *(ckt->CKTstate0 + here->HFET2cd); |
||||
|
cgd= *(ckt->CKTstate0 + here->HFET2cgd); |
||||
|
gm= *(ckt->CKTstate0 + here->HFET2gm); |
||||
|
gds= *(ckt->CKTstate0 + here->HFET2gds); |
||||
|
ggs= *(ckt->CKTstate0 + here->HFET2ggs); |
||||
|
ggd= *(ckt->CKTstate0 + here->HFET2ggd); |
||||
|
goto load; |
||||
|
} |
||||
|
|
||||
|
// limit nonlinear branch voltages |
||||
|
|
||||
|
ichk1=1; |
||||
|
vgs = DEVpnjlim(vgs,*(ckt->CKTstate0 + here->HFET2vgs),CONSTvt0,vcrit, &icheck); |
||||
|
vgd = DEVpnjlim(vgd,*(ckt->CKTstate0 + here->HFET2vgd),CONSTvt0,vcrit,&ichk1); |
||||
|
if(ichk1 == 1) { |
||||
|
icheck=1; |
||||
|
} |
||||
|
vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->HFET2vgs),TVTO); |
||||
|
vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->HFET2vgd),TVTO); |
||||
|
} |
||||
|
cg = 0; |
||||
|
cgd = 0; |
||||
|
ggd = 0; |
||||
|
ggs = 0; |
||||
|
vds = vgs-vgd; |
||||
|
{ |
||||
|
double arg = -vgs*DEL/vt; |
||||
|
double earg = exp(arg); |
||||
|
double vtn = N*vt; |
||||
|
double expe = exp(vgs/vtn); |
||||
|
ggs = JSLW*expe/vtn+GGRLW*earg*(1-arg); |
||||
|
cg = JSLW*(expe-1)+GGRLW*vgs*earg; |
||||
|
arg = -vgd*DEL/vt; |
||||
|
earg = exp(arg); |
||||
|
expe = exp(vgd/vtn); |
||||
|
ggd = JSLW*expe/vtn+GGRLW*earg*(1-arg); |
||||
|
cgd = JSLW*(expe-1)+GGRLW*vgd*earg; |
||||
|
cg += cgd; |
||||
|
} |
||||
|
if(vds < 0) { |
||||
|
vds = -vds; |
||||
|
inverse = 1; |
||||
|
} else |
||||
|
inverse = 0; |
||||
|
hfeta2(model,here,ckt,vds>0?vgs:vgd,vds,&cdrain,&gm,&gds,&capgs,&capgd); |
||||
|
if(inverse) { |
||||
|
double temp; |
||||
|
cdrain = -cdrain; |
||||
|
vds = -vds; |
||||
|
temp = capgs; |
||||
|
capgs = capgd; |
||||
|
capgd = temp; |
||||
|
} |
||||
|
cd = cdrain - cgd; |
||||
|
if((ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || ((ckt->CKTmode & MODETRANOP) && |
||||
|
(ckt->CKTmode & MODEUIC)) ){ |
||||
|
// charge storage elements |
||||
|
vgs1 = *(ckt->CKTstate1 + here->HFET2vgs); |
||||
|
vgd1 = *(ckt->CKTstate1 + here->HFET2vgd); |
||||
|
|
||||
|
if(ckt->CKTmode & MODEINITTRAN) { |
||||
|
*(ckt->CKTstate1 + here->HFET2qgs) = capgs*vgs; |
||||
|
*(ckt->CKTstate1 + here->HFET2qgd) = capgd*vgd; |
||||
|
} |
||||
|
*(ckt->CKTstate0+here->HFET2qgs) = *(ckt->CKTstate1+here->HFET2qgs) |
||||
|
+ capgs*(vgs-vgs1); |
||||
|
*(ckt->CKTstate0+here->HFET2qgd) = *(ckt->CKTstate1+here->HFET2qgd) |
||||
|
+ capgd*(vgd-vgd1); |
||||
|
|
||||
|
// store small-signal parameters |
||||
|
|
||||
|
if( (!(ckt->CKTmode & MODETRANOP)) || (!(ckt->CKTmode & MODEUIC)) ) { |
||||
|
if(ckt->CKTmode & MODEINITSMSIG) { |
||||
|
*(ckt->CKTstate0 + here->HFET2qgs) = capgs; |
||||
|
*(ckt->CKTstate0 + here->HFET2qgd) = capgd; |
||||
|
continue; /*go to 1000*/ |
||||
|
} |
||||
|
|
||||
|
// transient analysis |
||||
|
|
||||
|
if(ckt->CKTmode & MODEINITTRAN) { |
||||
|
*(ckt->CKTstate1 + here->HFET2qgs) = *(ckt->CKTstate0 + here->HFET2qgs); |
||||
|
*(ckt->CKTstate1 + here->HFET2qgd) = *(ckt->CKTstate0 + here->HFET2qgd); |
||||
|
} |
||||
|
error = NIintegrate(ckt,&geq,&ceq,capgs,here->HFET2qgs); |
||||
|
if(error) return(error); |
||||
|
ggs = ggs + geq; |
||||
|
cg = cg + *(ckt->CKTstate0 + here->HFET2cqgs); |
||||
|
error = NIintegrate(ckt,&geq,&ceq,capgd,here->HFET2qgd); |
||||
|
if(error) return(error); |
||||
|
ggd = ggd + geq; |
||||
|
cg = cg + *(ckt->CKTstate0 + here->HFET2cqgd); |
||||
|
cd = cd - *(ckt->CKTstate0 + here->HFET2cqgd); |
||||
|
cgd = cgd + *(ckt->CKTstate0 + here->HFET2cqgd); |
||||
|
if (ckt->CKTmode & MODEINITTRAN) { |
||||
|
*(ckt->CKTstate1 + here->HFET2cqgs) = *(ckt->CKTstate0 + here->HFET2cqgs); |
||||
|
*(ckt->CKTstate1 + here->HFET2cqgd) = *(ckt->CKTstate0 + here->HFET2cqgd); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// check convergence |
||||
|
|
||||
|
if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) { |
||||
|
if((icheck == 1) |
||||
|
|| (fabs(cghat-cg) >= ckt->CKTreltol* |
||||
|
MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) || |
||||
|
(fabs(cdhat-cd) > ckt->CKTreltol* |
||||
|
MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol) |
||||
|
) { |
||||
|
ckt->CKTnoncon++; |
||||
|
} |
||||
|
} |
||||
|
*(ckt->CKTstate0 + here->HFET2vgs) = vgs; |
||||
|
*(ckt->CKTstate0 + here->HFET2vgd) = vgd; |
||||
|
*(ckt->CKTstate0 + here->HFET2cg) = cg; |
||||
|
*(ckt->CKTstate0 + here->HFET2cd) = cd; |
||||
|
*(ckt->CKTstate0 + here->HFET2cgd) = cgd; |
||||
|
*(ckt->CKTstate0 + here->HFET2gm) = gm; |
||||
|
*(ckt->CKTstate0 + here->HFET2gds) = gds; |
||||
|
*(ckt->CKTstate0 + here->HFET2ggs) = ggs; |
||||
|
*(ckt->CKTstate0 + here->HFET2ggd) = ggd; |
||||
|
|
||||
|
// load current vector |
||||
|
|
||||
|
load: |
||||
|
ceqgd=model->HFET2type*(cgd-ggd*vgd); |
||||
|
ceqgs=model->HFET2type*((cg-cgd)-ggs*vgs); |
||||
|
cdreq=model->HFET2type*((cd+cgd)-gds*vds-gm*vgs); |
||||
|
*(ckt->CKTrhs + here->HFET2gateNode) += (-ceqgs-ceqgd); |
||||
|
*(ckt->CKTrhs + here->HFET2drainPrimeNode) += (-cdreq+ceqgd); |
||||
|
*(ckt->CKTrhs + here->HFET2sourcePrimeNode) += (cdreq+ceqgs); |
||||
|
|
||||
|
// load y matrix |
||||
|
|
||||
|
*(here->HFET2drainDrainPrimePtr) += (-gdpr); |
||||
|
*(here->HFET2gateDrainPrimePtr) += (-ggd); |
||||
|
*(here->HFET2gateSourcePrimePtr) += (-ggs); |
||||
|
*(here->HFET2sourceSourcePrimePtr) += (-gspr); |
||||
|
*(here->HFET2drainPrimeDrainPtr) += (-gdpr); |
||||
|
*(here->HFET2drainPrimeGatePtr) += (gm-ggd); |
||||
|
*(here->HFET2drainPriHFET2ourcePrimePtr) += (-gds-gm); |
||||
|
*(here->HFET2sourcePrimeGatePtr) += (-ggs-gm); |
||||
|
*(here->HFET2sourcePriHFET2ourcePtr) += (-gspr); |
||||
|
*(here->HFET2sourcePrimeDrainPrimePtr) += (-gds); |
||||
|
*(here->HFET2drainDrainPtr) += (gdpr); |
||||
|
*(here->HFET2gateGatePtr) += (ggd+ggs); |
||||
|
*(here->HFET2sourceSourcePtr) += (gspr); |
||||
|
*(here->HFET2drainPrimeDrainPrimePtr) += (gdpr+gds+ggd); |
||||
|
*(here->HFET2sourcePriHFET2ourcePrimePtr) += (gspr+gds+gm+ggs); |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
static void hfeta2(HFET2model *model, HFET2instance *here, CKTcircuit *ckt, |
||||
|
double vgs, double vds, double *cdrain, double *gm, |
||||
|
double *gds, double *capgs, double *capgd) |
||||
|
|
||||
|
{ |
||||
|
|
||||
|
double vt; |
||||
|
double vgt; |
||||
|
double vgt0; |
||||
|
double sigma; |
||||
|
double vgte; |
||||
|
double isat; |
||||
|
double isatm; |
||||
|
double ns; |
||||
|
double nsm; |
||||
|
double a; |
||||
|
double b; |
||||
|
double c; |
||||
|
double d; |
||||
|
double e; |
||||
|
double g; |
||||
|
double h; |
||||
|
double p; |
||||
|
double q; |
||||
|
double s; |
||||
|
double t; |
||||
|
double u; |
||||
|
double nsc; |
||||
|
double nsn; |
||||
|
double temp; |
||||
|
double etavth; |
||||
|
double gch; |
||||
|
double gchi; |
||||
|
double gchim; |
||||
|
double vsate; |
||||
|
double vdse; |
||||
|
double cg1; |
||||
|
double cgc; |
||||
|
double rt; |
||||
|
double vl; |
||||
|
double delidgch; |
||||
|
double delgchgchi; |
||||
|
double delgchins; |
||||
|
double delnsnsm; |
||||
|
double delnsmvgt; |
||||
|
double delvgtevgt; |
||||
|
double delidvsate; |
||||
|
double delvsateisat; |
||||
|
double delisatisatm; |
||||
|
double delisatmvgte; |
||||
|
double delisatmgchim; |
||||
|
double delvsategch; |
||||
|
double delidvds; |
||||
|
double delvgtvgs; |
||||
|
double delvsatevgt; |
||||
|
|
||||
|
vt = CONSTKoverQ*TEMP; |
||||
|
etavth = ETA*vt; |
||||
|
vl = VS/TMU*L; |
||||
|
rt = RSI+RDI; |
||||
|
vgt0 = vgs - TVTO; |
||||
|
s = exp((vgt0-VSIGMAT)/VSIGMA); |
||||
|
sigma = SIGMA0/(1+s); |
||||
|
vgt = vgt0+sigma*vds; |
||||
|
u = 0.5*vgt/vt-1; |
||||
|
t = sqrt(DELTA2+u*u); |
||||
|
vgte = vt*(2+u+t); |
||||
|
b = exp(vgt/etavth); |
||||
|
if(model->HFET2eta2Given && model->HFET2d2Given) { |
||||
|
nsc = N02*exp((vgt+TVTO-VT2)/(ETA2*vt)); |
||||
|
nsn = 2*N0*log(1+0.5*b); |
||||
|
nsm = nsn*nsc/(nsn+nsc); |
||||
|
} else { |
||||
|
nsm = 2*N0*log(1+0.5*b); |
||||
|
} |
||||
|
if(nsm < 1.0e-38) { |
||||
|
*cdrain = 0; |
||||
|
*gm = 0.0; |
||||
|
*gds = 0.0; |
||||
|
*capgs = CF; |
||||
|
*capgd = CF; |
||||
|
return; |
||||
|
} |
||||
|
c = pow(nsm/TNMAX,GAMMA); |
||||
|
q = pow(1+c,1.0/GAMMA); |
||||
|
ns = nsm/q; |
||||
|
gchi = GCHI0*ns; |
||||
|
gch = gchi/(1+gchi*rt); |
||||
|
gchim = GCHI0*nsm; |
||||
|
h = sqrt(1+2*gchim*RSI + vgte*vgte/(vl*vl)); |
||||
|
p = 1+gchim*RSI+h; |
||||
|
isatm = gchim*vgte/p; |
||||
|
g = pow(isatm/IMAX,GAMMA); |
||||
|
isat = isatm/pow(1+g,1/GAMMA); |
||||
|
vsate = isat/gch; |
||||
|
d = pow(vds/vsate,M); |
||||
|
e = pow(1+d,1.0/M); |
||||
|
delidgch = vds*(1+TLAMBDA*vds)/e; |
||||
|
*cdrain = gch*delidgch; |
||||
|
delidvsate = (*cdrain)*d/vsate/(1+d); |
||||
|
delidvds = gch*(1+2*TLAMBDA*vds)/e-(*cdrain)* |
||||
|
pow(vds/vsate,M-1)/(vsate*(1+d)); |
||||
|
a = 1+gchi*rt; |
||||
|
delgchgchi = 1.0/(a*a); |
||||
|
delgchins = GCHI0; |
||||
|
delnsnsm = ns/nsm*(1-c/(1+c)); |
||||
|
delvgtevgt = 0.5*(1+u/t); |
||||
|
delnsmvgt = N0/etavth/(1.0/b + 0.5); |
||||
|
if(model->HFET2eta2Given && model->HFET2d2Given) |
||||
|
delnsmvgt = nsc*(nsc*delnsmvgt+nsn*nsn/(ETA2*vt))/((nsc+nsn)*(nsc+nsn)); |
||||
|
delvsateisat = 1.0/gch; |
||||
|
delisatisatm = isat/isatm*(1-g/(1+g)); |
||||
|
delisatmvgte = gchim*(p - vgte*vgte/(vl*vl*h))/(p*p); |
||||
|
delvsategch = -vsate/gch; |
||||
|
delisatmgchim = vgte*(p - gchim*RSI*(1+1.0/h))/(p*p); |
||||
|
delvgtvgs = 1-vds*SIGMA0/VSIGMA*s/((1+s)*(1+s)); |
||||
|
p = delgchgchi*delgchins*delnsnsm*delnsmvgt; |
||||
|
delvsatevgt = (delvsateisat*delisatisatm*(delisatmvgte*delvgtevgt + |
||||
|
delisatmgchim*GCHI0*delnsmvgt)+delvsategch*p); |
||||
|
g = delidgch*p + delidvsate*delvsatevgt; |
||||
|
*gm = g*delvgtvgs; |
||||
|
*gds = delidvds + g*sigma; |
||||
|
|
||||
|
// Capacitance calculations |
||||
|
temp = ETA1*vt; |
||||
|
cg1 = 1/(D1/EPSI+temp*exp(-(vgs-HFET2_VT1)/temp)); |
||||
|
cgc = W*L*(CHARGE*delnsnsm*delnsmvgt*delvgtvgs+cg1); |
||||
|
vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC); |
||||
|
a = (vsate-vdse)/(2*vsate-vdse); |
||||
|
a = a*a; |
||||
|
temp = 2.0/3.0; |
||||
|
p = PP + (1-PP)*exp(-vds/vsate); |
||||
|
*capgs = CF+2*temp*cgc*(1-a)/(1+p); |
||||
|
a = vsate/(2*vsate-vdse); |
||||
|
a = a*a; |
||||
|
*capgd = CF+2*p*temp*cgc*(1-a)/(1+p); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,160 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1987 Thomas L. Quarles |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into HFET2 model: Paolo Nenzi 2001 |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/* ARGSUSED */ |
||||
|
int |
||||
|
HFET2mAsk(ckt,inst,which,value) |
||||
|
CKTcircuit *ckt; |
||||
|
GENmodel *inst; |
||||
|
int which; |
||||
|
IFvalue *value; |
||||
|
{ |
||||
|
HFET2model *here = (HFET2model*)inst; |
||||
|
switch(which) { |
||||
|
case HFET2_MOD_VTO: |
||||
|
value->rValue = here->HFET2vto; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_LAMBDA: |
||||
|
value->rValue = here->HFET2lambda; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_RD: |
||||
|
value->rValue = here->HFET2rd; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_RS: |
||||
|
value->rValue = here->HFET2rs; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_RDI: |
||||
|
value->rValue = here->HFET2rdi; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_RSI: |
||||
|
value->rValue = here->HFET2rsi; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_ETA: |
||||
|
value->rValue = here->HFET2eta; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_M: |
||||
|
value->rValue = here->HFET2m; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_MC: |
||||
|
value->rValue = here->HFET2mc; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_GAMMA: |
||||
|
value->rValue = here->HFET2gamma; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_SIGMA0: |
||||
|
value->rValue = here->HFET2sigma0; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_VSIGMAT: |
||||
|
value->rValue = here->HFET2vsigmat; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_VSIGMA: |
||||
|
value->rValue = here->HFET2vsigma; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_MU: |
||||
|
value->rValue = here->HFET2mu; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_DI: |
||||
|
value->rValue = here->HFET2di; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_DELTA: |
||||
|
value->rValue = here->HFET2delta; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_VS: |
||||
|
value->rValue = here->HFET2vs; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_NMAX: |
||||
|
value->rValue = here->HFET2nmax; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_DELTAD: |
||||
|
value->rValue = here->HFET2deltad; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_P: |
||||
|
value->rValue = here->HFET2p; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_JS: |
||||
|
value->rValue = here->HFET2js; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_ETA1: |
||||
|
value->rValue = here->HFET2eta1; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_D1: |
||||
|
value->rValue = here->HFET2d1; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_VT1: |
||||
|
value->rValue = here->HFET2vt1; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_ETA2: |
||||
|
value->rValue = here->HFET2eta2; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_D2: |
||||
|
value->rValue = here->HFET2d2; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_VT2: |
||||
|
value->rValue = here->HFET2vt2; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_GGR: |
||||
|
value->rValue = here->HFET2ggr; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_DEL: |
||||
|
value->rValue = here->HFET2del; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_KLAMBDA: |
||||
|
value->rValue = here->HFET2klambda; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_KMU: |
||||
|
value->rValue = here->HFET2kmu; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_KVTO: |
||||
|
value->rValue = here->HFET2kvto; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_EPSI: |
||||
|
value->rValue = here->HFET2epsi; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_KNMAX: |
||||
|
value->rValue = here->HFET2knmax; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_N: |
||||
|
value->rValue = here->HFET2n; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_CF: |
||||
|
value->rValue = here->HFET2cf; |
||||
|
return (OK); |
||||
|
|
||||
|
case HFET2_MOD_DRAINCONDUCT: |
||||
|
value->rValue = here->HFET2drainConduct; |
||||
|
return (OK); |
||||
|
case HFET2_MOD_SOURCECONDUCT: |
||||
|
value->rValue = here->HFET2sourceConduct; |
||||
|
return (OK); |
||||
|
/* case HFET2_MOD_DEPLETIONCAP: |
||||
|
value->rValue = here->HFET2???; |
||||
|
return(OK); */ |
||||
|
/* case HFET2_MOD_VCRIT: |
||||
|
value->rValue = here->HFET2vcrit; |
||||
|
return (OK); */ |
||||
|
|
||||
|
case HFET2_MOD_TYPE: |
||||
|
if (here->HFET2type == NHFET) |
||||
|
value->sValue = "nhfet"; |
||||
|
else |
||||
|
value->sValue = "phfet"; |
||||
|
default: |
||||
|
return (E_BADPARM); |
||||
|
} |
||||
|
/* NOTREACHED */ |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 S. Hwang |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into hfet2 model: Paolo Nenzi 2001 |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "hfet2defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
HFET2mDelete(inModel,modname,kill) |
||||
|
GENmodel **inModel; |
||||
|
IFuid modname; |
||||
|
GENmodel *kill; |
||||
|
{ |
||||
|
HFET2model **model = (HFET2model**)inModel; |
||||
|
HFET2model *modfast = (HFET2model*)kill; |
||||
|
HFET2instance *here; |
||||
|
HFET2instance *prev = NULL; |
||||
|
HFET2model **oldmod; |
||||
|
oldmod = model; |
||||
|
for( ; *model ; model = &((*model)->HFET2nextModel)) { |
||||
|
if( (*model)->HFET2modName == modname || |
||||
|
(modfast && *model == modfast) ) goto delgot; |
||||
|
oldmod = model; |
||||
|
} |
||||
|
return(E_NOMOD); |
||||
|
|
||||
|
delgot: |
||||
|
*oldmod = (*model)->HFET2nextModel; /* cut deleted device out of list */ |
||||
|
for(here = (*model)->HFET2instances ; here ; here = here->HFET2nextInstance) { |
||||
|
if(prev) FREE(prev); |
||||
|
prev = here; |
||||
|
} |
||||
|
if(prev) FREE(prev); |
||||
|
FREE(*model); |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,177 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "ifsim.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int HFET2mParam(param, value, inModel) |
||||
|
int param; |
||||
|
IFvalue *value; |
||||
|
GENmodel *inModel; |
||||
|
{ |
||||
|
|
||||
|
HFET2model *model = (HFET2model*)inModel; |
||||
|
switch(param) { |
||||
|
case HFET2_MOD_CF: |
||||
|
model->HFET2cfGiven = TRUE; |
||||
|
CF = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_D1: |
||||
|
model->HFET2d1Given = TRUE; |
||||
|
D1 = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_D2: |
||||
|
model->HFET2d2Given = TRUE; |
||||
|
D2 = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_DEL: |
||||
|
model->HFET2delGiven = TRUE; |
||||
|
DEL = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_DELTA: |
||||
|
model->HFET2deltaGiven = TRUE; |
||||
|
DELTA = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_DELTAD: |
||||
|
model->HFET2deltadGiven = TRUE; |
||||
|
DELTAD = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_DI: |
||||
|
model->HFET2diGiven = TRUE; |
||||
|
DI = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_EPSI: |
||||
|
model->HFET2epsiGiven = TRUE; |
||||
|
EPSI = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_ETA: |
||||
|
model->HFET2etaGiven = TRUE; |
||||
|
ETA = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_ETA1: |
||||
|
model->HFET2eta1Given = TRUE; |
||||
|
ETA1 = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_ETA2: |
||||
|
model->HFET2eta2Given = TRUE; |
||||
|
ETA2 = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_GAMMA: |
||||
|
model->HFET2gammaGiven = TRUE; |
||||
|
GAMMA = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_GGR: |
||||
|
model->HFET2ggrGiven = TRUE; |
||||
|
GGR = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_JS: |
||||
|
model->HFET2jsGiven = TRUE; |
||||
|
JS = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_KLAMBDA: |
||||
|
model->HFET2klambdaGiven = TRUE; |
||||
|
KLAMBDA = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_KMU: |
||||
|
model->HFET2kmuGiven = TRUE; |
||||
|
KMU = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_KNMAX: |
||||
|
model->HFET2knmaxGiven = TRUE; |
||||
|
KNMAX = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_KVTO: |
||||
|
model->HFET2kvtoGiven = TRUE; |
||||
|
KVTO = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_LAMBDA: |
||||
|
model->HFET2lambdaGiven = TRUE; |
||||
|
LAMBDA = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_M: |
||||
|
model->HFET2mGiven = TRUE; |
||||
|
M = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_MC: |
||||
|
model->HFET2mcGiven = TRUE; |
||||
|
MC = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_MU: |
||||
|
model->HFET2muGiven = TRUE; |
||||
|
MU = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_N: |
||||
|
model->HFET2nGiven = TRUE; |
||||
|
N = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_NMAX: |
||||
|
model->HFET2nmaxGiven = TRUE; |
||||
|
NMAX = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_P: |
||||
|
model->HFET2pGiven = TRUE; |
||||
|
PP = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_RD: |
||||
|
model->HFET2rdGiven = TRUE; |
||||
|
RD = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_RDI: |
||||
|
model->HFET2rdiGiven = TRUE; |
||||
|
RDI = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_RS: |
||||
|
model->HFET2rsGiven = TRUE; |
||||
|
RS = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_RSI: |
||||
|
model->HFET2rsiGiven = TRUE; |
||||
|
RSI = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_SIGMA0: |
||||
|
model->HFET2sigma0Given = TRUE; |
||||
|
SIGMA0 = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_VS: |
||||
|
model->HFET2vsGiven = TRUE; |
||||
|
VS = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_VSIGMA: |
||||
|
model->HFET2vsigmaGiven = TRUE; |
||||
|
VSIGMA = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_VSIGMAT: |
||||
|
model->HFET2vsigmatGiven = TRUE; |
||||
|
VSIGMAT = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_VT1: |
||||
|
model->HFET2vt1Given = TRUE; |
||||
|
HFET2_VT1 = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_VT2: |
||||
|
model->HFET2vt2Given = TRUE; |
||||
|
VT2 = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_VTO: |
||||
|
model->HFET2vtoGiven = TRUE; |
||||
|
VTO = value->rValue; |
||||
|
break; |
||||
|
case HFET2_MOD_NHFET: |
||||
|
if(value->iValue) { |
||||
|
TYPE = NHFET; |
||||
|
} |
||||
|
break; |
||||
|
case HFET2_MOD_PHFET: |
||||
|
if(value->iValue) { |
||||
|
TYPE = PHFET; |
||||
|
} |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "ifsim.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int HFET2param(param, value, inst, select) |
||||
|
int param; |
||||
|
IFvalue *value; |
||||
|
GENinstance *inst; |
||||
|
IFvalue *select; |
||||
|
{ |
||||
|
|
||||
|
HFET2instance *here = (HFET2instance*)inst; |
||||
|
switch(param) { |
||||
|
case HFET2_LENGTH: |
||||
|
L = value->rValue; |
||||
|
here->HFET2lengthGiven = TRUE; |
||||
|
break; |
||||
|
case HFET2_IC_VDS: |
||||
|
here->HFET2icVDS = value->rValue; |
||||
|
here->HFET2icVDSGiven = TRUE; |
||||
|
break; |
||||
|
case HFET2_IC_VGS: |
||||
|
here->HFET2icVGS = value->rValue; |
||||
|
here->HFET2icVGSGiven = TRUE; |
||||
|
break; |
||||
|
case HFET2_OFF: |
||||
|
here->HFET2off = value->iValue; |
||||
|
break; |
||||
|
case HFET2_IC: |
||||
|
switch(value->v.numValue) { |
||||
|
case 2: |
||||
|
here->HFET2icVGS = *(value->v.vec.rVec+1); |
||||
|
here->HFET2icVGSGiven = TRUE; |
||||
|
case 1: |
||||
|
here->HFET2icVDS = *(value->v.vec.rVec); |
||||
|
here->HFET2icVDSGiven = TRUE; |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
break; |
||||
|
case HFET2_TEMP: |
||||
|
TEMP = value->rValue+CONSTCtoK; |
||||
|
here->HFET2tempGiven = TRUE; |
||||
|
break; |
||||
|
case HFET2_WIDTH: |
||||
|
W = value->rValue; |
||||
|
here->HFET2widthGiven = TRUE; |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,233 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "smpdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "const.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int HFET2setup(matrix, inModel, ckt, states) |
||||
|
SMPmatrix *matrix; |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
int *states; |
||||
|
{ |
||||
|
|
||||
|
HFET2model *model = (HFET2model*)inModel; |
||||
|
HFET2instance *here; |
||||
|
int error; |
||||
|
CKTnode *tmp; |
||||
|
|
||||
|
for( ; model != NULL; model = model->HFET2nextModel ) { |
||||
|
if((TYPE != NHFET) && (TYPE != PHFET) ) |
||||
|
TYPE = NHFET; |
||||
|
if(!model->HFET2cfGiven) |
||||
|
CF = 0; |
||||
|
if(!model->HFET2d1Given) |
||||
|
D1 = 0.03e-6; |
||||
|
if(!model->HFET2d2Given) |
||||
|
D2 = 0.2e-6; |
||||
|
if(!model->HFET2delGiven) |
||||
|
DEL = 0.04; |
||||
|
if(!model->HFET2deltaGiven) |
||||
|
DELTA = 3.0; |
||||
|
if(!model->HFET2deltadGiven) |
||||
|
DELTAD = 4.5e-9; |
||||
|
if(!model->HFET2diGiven) |
||||
|
DI = 0.04e-6; |
||||
|
if(!model->HFET2epsiGiven) |
||||
|
EPSI = 12.244*8.85418e-12; |
||||
|
if(!model->HFET2etaGiven) |
||||
|
if(TYPE == NHFET) |
||||
|
ETA = 1.28; |
||||
|
else |
||||
|
ETA = 1.4; |
||||
|
if(!model->HFET2eta1Given) |
||||
|
ETA1 = 2; |
||||
|
if(!model->HFET2eta2Given) |
||||
|
ETA2 = 2; |
||||
|
if(!model->HFET2gammaGiven) |
||||
|
GAMMA = 3.0; |
||||
|
if(!model->HFET2ggrGiven) |
||||
|
GGR = 0; |
||||
|
if(!model->HFET2jsGiven) |
||||
|
JS = 0; |
||||
|
if(!model->HFET2klambdaGiven) |
||||
|
KLAMBDA = 0; |
||||
|
if(!model->HFET2kmuGiven) |
||||
|
KMU = 0; |
||||
|
if(!model->HFET2knmaxGiven) |
||||
|
KNMAX = 0; |
||||
|
if(!model->HFET2kvtoGiven) |
||||
|
KVTO = 0; |
||||
|
if(!model->HFET2lambdaGiven) |
||||
|
LAMBDA = 0.15; |
||||
|
if(!model->HFET2mGiven) |
||||
|
M = 3.0; |
||||
|
if(!model->HFET2mcGiven) |
||||
|
MC = 3.0; |
||||
|
if(!model->HFET2muGiven) |
||||
|
if(TYPE == NHFET) |
||||
|
MU = 0.4; |
||||
|
else |
||||
|
MU = 0.03; |
||||
|
if(!model->HFET2nGiven) |
||||
|
N = 5.0; |
||||
|
if(!model->HFET2nmaxGiven) |
||||
|
NMAX = 2e16; |
||||
|
if(!model->HFET2pGiven) |
||||
|
PP = 1; |
||||
|
if(!model->HFET2rdGiven) |
||||
|
RD = 0; |
||||
|
if(!model->HFET2rdiGiven) |
||||
|
RDI = 0; |
||||
|
if(!model->HFET2rsGiven) |
||||
|
RS = 0; |
||||
|
if(!model->HFET2rsiGiven) |
||||
|
RSI = 0; |
||||
|
if(!model->HFET2sigma0Given) |
||||
|
SIGMA0 = 0.057; |
||||
|
if(!model->HFET2vsGiven) |
||||
|
if(TYPE == NHFET) |
||||
|
VS = 1.5e5; |
||||
|
else |
||||
|
VS = 0.8e5; |
||||
|
if(!model->HFET2vsigmaGiven) |
||||
|
VSIGMA = 0.1; |
||||
|
if(!model->HFET2vsigmatGiven) |
||||
|
VSIGMAT = 0.3; |
||||
|
if(!model->HFET2vt1Given) |
||||
|
// initialized in HFET2temp |
||||
|
HFET2_VT1 = 0; |
||||
|
if(!model->HFET2vt2Given) |
||||
|
// initialized in HFET2temp |
||||
|
VT2 = 0; |
||||
|
if(!model->HFET2vtoGiven) { |
||||
|
if(model->HFET2type == NHFET) |
||||
|
VTO = 0.15; |
||||
|
else |
||||
|
VTO = -0.15; |
||||
|
} |
||||
|
|
||||
|
/* loop through all the instances of the model */ |
||||
|
|
||||
|
|
||||
|
for (here = model->HFET2instances; here != NULL; here=here->HFET2nextInstance) { |
||||
|
|
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
here->HFET2state = *states; |
||||
|
*states += 13; |
||||
|
|
||||
|
if(!here->HFET2lengthGiven) |
||||
|
L = 1e-6; |
||||
|
if(!here->HFET2tempGiven) |
||||
|
TEMP = ckt->CKTtemp; |
||||
|
if(!here->HFET2widthGiven) |
||||
|
W = 20e-6; |
||||
|
|
||||
|
if(model->HFET2rs != 0 && here->HFET2sourcePrimeNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->HFET2name,"source"); |
||||
|
if(error) return(error); |
||||
|
here->HFET2sourcePrimeNode = tmp->number; |
||||
|
|
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->HFET2sourcePrimeNode = here->HFET2sourceNode; |
||||
|
} |
||||
|
if(model->HFET2rd != 0 && here->HFET2drainPrimeNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->HFET2name,"drain"); |
||||
|
if(error) return(error); |
||||
|
here->HFET2drainPrimeNode = tmp->number; |
||||
|
|
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->HFET2drainPrimeNode = here->HFET2drainNode; |
||||
|
} |
||||
|
|
||||
|
/* macro to make elements with built in test for out of memory */ |
||||
|
#define TSTALLOC(ptr,first,second) \ |
||||
|
if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ |
||||
|
return(E_NOMEM);\ |
||||
|
} |
||||
|
|
||||
|
TSTALLOC(HFET2drainDrainPrimePtr,HFET2drainNode,HFET2drainPrimeNode) |
||||
|
TSTALLOC(HFET2gateDrainPrimePtr,HFET2gateNode,HFET2drainPrimeNode) |
||||
|
TSTALLOC(HFET2gateSourcePrimePtr,HFET2gateNode,HFET2sourcePrimeNode) |
||||
|
TSTALLOC(HFET2sourceSourcePrimePtr,HFET2sourceNode,HFET2sourcePrimeNode) |
||||
|
TSTALLOC(HFET2drainPrimeDrainPtr,HFET2drainPrimeNode,HFET2drainNode) |
||||
|
TSTALLOC(HFET2drainPrimeGatePtr,HFET2drainPrimeNode,HFET2gateNode) |
||||
|
TSTALLOC(HFET2drainPriHFET2ourcePrimePtr,HFET2drainPrimeNode,HFET2sourcePrimeNode) |
||||
|
TSTALLOC(HFET2sourcePrimeGatePtr,HFET2sourcePrimeNode,HFET2gateNode) |
||||
|
TSTALLOC(HFET2sourcePriHFET2ourcePtr,HFET2sourcePrimeNode,HFET2sourceNode) |
||||
|
TSTALLOC(HFET2sourcePrimeDrainPrimePtr,HFET2sourcePrimeNode,HFET2drainPrimeNode) |
||||
|
TSTALLOC(HFET2drainDrainPtr,HFET2drainNode,HFET2drainNode) |
||||
|
TSTALLOC(HFET2gateGatePtr,HFET2gateNode,HFET2gateNode) |
||||
|
TSTALLOC(HFET2sourceSourcePtr,HFET2sourceNode,HFET2sourceNode) |
||||
|
TSTALLOC(HFET2drainPrimeDrainPrimePtr,HFET2drainPrimeNode,HFET2drainPrimeNode) |
||||
|
TSTALLOC(HFET2sourcePriHFET2ourcePrimePtr,HFET2sourcePrimeNode,HFET2sourcePrimeNode) |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
int |
||||
|
HFET2unsetup(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
HFET2model *model; |
||||
|
HFET2instance *here; |
||||
|
|
||||
|
for (model = (HFET2model *)inModel; model != NULL; |
||||
|
model = model->HFET2nextModel) |
||||
|
{ |
||||
|
for (here = model->HFET2instances; here != NULL; |
||||
|
here=here->HFET2nextInstance) |
||||
|
{ |
||||
|
if (here->HFET2drainPrimeNode |
||||
|
&& here->HFET2drainPrimeNode != here->HFET2drainNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->HFET2drainPrimeNode); |
||||
|
here->HFET2drainPrimeNode = 0; |
||||
|
} |
||||
|
if (here->HFET2sourcePrimeNode |
||||
|
&& here->HFET2sourcePrimeNode != here->HFET2sourceNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->HFET2sourcePrimeNode); |
||||
|
here->HFET2sourcePrimeNode = 0; |
||||
|
} |
||||
|
/*if (here->HFET2gateNode |
||||
|
&& here->HFET2gateNode != here->HFET2gateNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->HFET2gateNode); |
||||
|
here->HFET2gateNode = 0; |
||||
|
}*/ |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
return OK; |
||||
|
} |
||||
@ -0,0 +1,56 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "smpdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "const.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int HFET2temp(inModel, ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
|
||||
|
HFET2instance *here; |
||||
|
HFET2model *model = (HFET2model*)inModel; |
||||
|
|
||||
|
for( ; model != NULL; model = model->HFET2nextModel ) { |
||||
|
if(model->HFET2rd != 0) |
||||
|
model->HFET2drainConduct = 1/model->HFET2rd; |
||||
|
else |
||||
|
model->HFET2drainConduct = 0; |
||||
|
if(model->HFET2rs != 0) |
||||
|
model->HFET2sourceConduct = 1/model->HFET2rs; |
||||
|
else |
||||
|
model->HFET2sourceConduct = 0; |
||||
|
if(!model->HFET2vt1Given) |
||||
|
HFET2_VT1 = VTO+CHARGE*NMAX*DI/EPSI; |
||||
|
if(!model->HFET2vt2Given) |
||||
|
VT2 = VTO; |
||||
|
DELTA2 = DELTA*DELTA; |
||||
|
for (here = model->HFET2instances; here != NULL; here=here->HFET2nextInstance) { |
||||
|
double vt = CONSTKoverQ*TEMP; |
||||
|
double tdiff = TEMP - ckt->CKTnomTemp; |
||||
|
TLAMBDA = LAMBDA + KLAMBDA*tdiff; |
||||
|
TMU = MU - KMU*tdiff; |
||||
|
TNMAX = NMAX - KNMAX*tdiff; |
||||
|
TVTO = TYPE*VTO - KVTO*tdiff; |
||||
|
JSLW = JS*L*W/2; |
||||
|
GGRLW = GGR*L*W/2; |
||||
|
N0 = EPSI*ETA*vt/2/CHARGE/(DI+DELTAD); |
||||
|
N01 = EPSI*ETA1*vt/2/CHARGE/D1; |
||||
|
if(model->HFET2eta2Given) |
||||
|
N02 = EPSI*ETA2*vt/2/CHARGE/D2; |
||||
|
else |
||||
|
N02 = 0.0; |
||||
|
GCHI0 = CHARGE*W*TMU/L; |
||||
|
IMAX = CHARGE*TNMAX*VS*W; |
||||
|
VCRIT = vt*log(vt/(CONSTroot2 * 1e-11)); |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "hfet2defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int HFET2trunc(inModel, ckt, tiHFET2tep) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
double *tiHFET2tep; |
||||
|
{ |
||||
|
|
||||
|
HFET2model *model = (HFET2model*)inModel; |
||||
|
HFET2instance *here; |
||||
|
|
||||
|
for( ; model != NULL; model = model->HFET2nextModel) { |
||||
|
for(here=model->HFET2instances;here!=NULL;here = here->HFET2nextInstance){ |
||||
|
CKTterr(here->HFET2qgs,ckt,tiHFET2tep); |
||||
|
CKTterr(here->HFET2qgd,ckt,tiHFET2tep); |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
## Process this file with automake to produce Makefile.in
|
||||
|
|
||||
|
pkglib_LTLIBRARIES = libmesa.la |
||||
|
|
||||
|
libmesa_la_SOURCES = \
|
||||
|
mesa.c \
|
||||
|
mesaacl.c \
|
||||
|
mesaask.c \
|
||||
|
mesadefs.h \
|
||||
|
mesadel.c \
|
||||
|
mesadest.c \
|
||||
|
mesaext.h \
|
||||
|
mesagetic.c \
|
||||
|
mesainit.c \
|
||||
|
mesainit.h \
|
||||
|
mesaitf.h \
|
||||
|
mesaload.c \
|
||||
|
mesamask.c \
|
||||
|
mesamdel.c \
|
||||
|
mesamparam.c \
|
||||
|
mesaparam.c \
|
||||
|
mesasetup.c \
|
||||
|
mesatemp.c \
|
||||
|
mesatrunc.c |
||||
|
|
||||
|
|
||||
|
|
||||
|
INCLUDES = -I$(top_srcdir)/src/include |
||||
|
MAINTAINERCLEANFILES = Makefile.in |
||||
@ -0,0 +1,130 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "ifsim.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
IFparm MESApTable[] = { /* parameters */ |
||||
|
OP("off", MESA_OFF, IF_FLAG ,"Device initially off"), |
||||
|
IOP("l", MESA_LENGTH, IF_REAL ,"Length of device"), |
||||
|
IOP("w", MESA_WIDTH, IF_REAL ,"Width of device"), |
||||
|
IOP("icvds", MESA_IC_VDS, IF_REAL ,"Initial D-S voltage"), |
||||
|
IOP("icvgs", MESA_IC_VGS, IF_REAL ,"Initial G-S voltage"), |
||||
|
IOP("td", MESA_TD, IF_REAL ,"Instance drain temperature"), |
||||
|
IOP("ts", MESA_TS, IF_REAL ,"Instance source temperature"), |
||||
|
OP("dnode", MESA_DRAINNODE, IF_INTEGER,"Number of drain node"), |
||||
|
OP("gnode", MESA_GATENODE, IF_INTEGER,"Number of gate node"), |
||||
|
OP("snode", MESA_SOURCENODE, IF_INTEGER,"Number of source node"), |
||||
|
OP("dprimenode",MESA_DRAINPRIMENODE, IF_INTEGER,"Number of internal drain node"), |
||||
|
OP("sprimenode",MESA_SOURCEPRIMENODE,IF_INTEGER,"Number of internal source node"), |
||||
|
OP("gprimenode",MESA_GATEPRIMENODE, IF_INTEGER,"Number of internal gate node"), |
||||
|
OP("vgs", MESA_VGS, IF_REAL,"Gate-Source voltage"), |
||||
|
OP("vgd", MESA_VGD, IF_REAL,"Gate-Drain voltage"), |
||||
|
OP("cg", MESA_CG, IF_REAL,"Gate capacitance"), |
||||
|
OP("cd", MESA_CD, IF_REAL,"Drain capacitance"), |
||||
|
OP("cgd", MESA_CGD, IF_REAL,"Gate_Drain capacitance"), |
||||
|
OP("gm", MESA_GM, IF_REAL,"Transconductance"), |
||||
|
OP("gds", MESA_GDS, IF_REAL,"Drain-Source conductance"), |
||||
|
OP("ggs", MESA_GGS, IF_REAL,"Gate-Source conductance"), |
||||
|
OP("ggd", MESA_GGD, IF_REAL,"Gate-Drain conductance"), |
||||
|
OP("qgs", MESA_QGS, IF_REAL,"Gate-Source charge storage"), |
||||
|
OP("cqgs", MESA_CQGS, IF_REAL,"Capacitance due to gate-source charge storage"), |
||||
|
OP("qgd", MESA_QGD, IF_REAL,"Gate-Drain charge storage"), |
||||
|
OP("cqgd", MESA_CQGD, IF_REAL,"Capacitance due to gate-drain charge storage"), |
||||
|
OP("cs", MESA_CS, IF_REAL,"Source current"), |
||||
|
OP("p", MESA_POWER, IF_REAL,"Power dissipated by the mesfet") |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
IFparm MESAmPTable[] = { /* model parameters */ |
||||
|
IOP( "vt0", MESA_MOD_VTO, IF_REAL,"Pinch-off voltage"), |
||||
|
IOP( "vto", MESA_MOD_VTO, IF_REAL,"Pinch-off voltage"), |
||||
|
IOP( "lambda", MESA_MOD_LAMBDA, IF_REAL,"Output conductance parameter"), |
||||
|
IOP( "lambdahf",MESA_MOD_LAMBDAHF, IF_REAL,"Output conductance parameter at high frequencies"), |
||||
|
IOP( "beta", MESA_MOD_BETA, IF_REAL,"Transconductance parameter"), |
||||
|
IOP( "vs", MESA_MOD_VS, IF_REAL,"Saturation velocity"), |
||||
|
IOP( "rd", MESA_MOD_RD, IF_REAL,"Drain ohmic resistance"), |
||||
|
IOP( "rs", MESA_MOD_RS, IF_REAL,"Source ohmic resistance"), |
||||
|
IOP( "rg", MESA_MOD_RG, IF_REAL,"Gate ohmic resistance"), |
||||
|
IOP( "ri", MESA_MOD_RI, IF_REAL,"Gate-source ohmic resistance"), |
||||
|
IOP( "rf", MESA_MOD_RF, IF_REAL,"Gate-drain ohmic resistance"), |
||||
|
IOP( "rdi", MESA_MOD_RDI, IF_REAL,"Intrinsic source ohmic resistance"), |
||||
|
IOP( "rsi", MESA_MOD_RSI, IF_REAL,"Intrinsic drain ohmic resistance"), |
||||
|
IOP( "phib", MESA_MOD_PHIB, IF_REAL,"Effective Schottky barrier height at room temperature"), |
||||
|
IOP( "phib1", MESA_MOD_PHIB1, IF_REAL,""), |
||||
|
IOP( "tphib", MESA_MOD_PHIB1, IF_REAL,""), |
||||
|
IOP( "astar", MESA_MOD_ASTAR, IF_REAL,"Effective Richardson constant"), |
||||
|
IOP( "ggr", MESA_MOD_GGR, IF_REAL,"Reverse diode conductance"), |
||||
|
IOP( "del", MESA_MOD_DEL, IF_REAL,""), |
||||
|
IOP( "xchi", MESA_MOD_XCHI, IF_REAL,""), |
||||
|
IOP( "tggr", MESA_MOD_XCHI, IF_REAL,""), |
||||
|
IOP( "n", MESA_MOD_N, IF_REAL,"Emission coefficient"), |
||||
|
IOP( "eta", MESA_MOD_ETA, IF_REAL,"Subthreshold ideality factor"), |
||||
|
IOP( "m", MESA_MOD_M, IF_REAL,"Knee shape parameter"), |
||||
|
IOP( "mc", MESA_MOD_MC, IF_REAL,"Knee shape parameter"), |
||||
|
IOP( "alpha", MESA_MOD_ALPHA, IF_REAL,""), |
||||
|
IOP( "sigma0", MESA_MOD_SIGMA0, IF_REAL,"Threshold voltage coefficient"), |
||||
|
IOP( "vsigmat",MESA_MOD_VSIGMAT,IF_REAL,""), |
||||
|
IOP( "vsigma", MESA_MOD_VSIGMA, IF_REAL,""), |
||||
|
IOP( "mu", MESA_MOD_MU, IF_REAL,"Mobility"), |
||||
|
IOP( "theta", MESA_MOD_THETA, IF_REAL,""), |
||||
|
IOP( "mu1", MESA_MOD_MU1, IF_REAL,"Second moblity parameter"), |
||||
|
IOP( "mu2", MESA_MOD_MU2, IF_REAL,"Third moblity parameter"), |
||||
|
IOP( "d", MESA_MOD_D, IF_REAL,"Depth of device"), |
||||
|
IOP( "nd", MESA_MOD_ND, IF_REAL,"Doping density"), |
||||
|
IOP( "du", MESA_MOD_DU, IF_REAL,"Depth of device"), |
||||
|
IOP( "ndu", MESA_MOD_NDU, IF_REAL,"Doping density"), |
||||
|
IOP( "th", MESA_MOD_TH, IF_REAL,"Thickness of delta doped layer"), |
||||
|
IOP( "ndelta", MESA_MOD_NDELTA, IF_REAL,"Delta doped layer doping density"), |
||||
|
IOP( "delta", MESA_MOD_DELTA, IF_REAL,""), |
||||
|
IOP( "tc", MESA_MOD_TC, IF_REAL,"Transconductance compression factor"), |
||||
|
IOP( "tvto", MESA_MOD_TVTO, IF_REAL,"Temperature coefficient for vto"), |
||||
|
IOP( "alphat", MESA_MOD_TVTO, IF_REAL,""), |
||||
|
IOP( "tlambda",MESA_MOD_TLAMBDA,IF_REAL,"Temperature coefficient for lambda"), |
||||
|
IOP( "teta0", MESA_MOD_TETA0, IF_REAL,"First temperature coefficient for eta"), |
||||
|
IOP( "teta1", MESA_MOD_TETA1, IF_REAL,"Second temperature coefficient for eta"), |
||||
|
IOP( "tmu", MESA_MOD_TMU, IF_REAL,"Temperature coefficient for mobility"), |
||||
|
IOP( "xtm0", MESA_MOD_XTM0, IF_REAL,"First exponent for temp dependence of mobility"), |
||||
|
IOP( "xtm1", MESA_MOD_XTM1, IF_REAL,"Second exponent for temp dependence of mobility"), |
||||
|
IOP( "xtm2", MESA_MOD_XTM2, IF_REAL,"Third exponent for temp dependence of mobility"), |
||||
|
IOP( "ks", MESA_MOD_KS, IF_REAL,"Sidegating coefficient"), |
||||
|
IOP( "vsg", MESA_MOD_VSG, IF_REAL,"Sidegating voltage"), |
||||
|
IOP( "tf", MESA_MOD_TF, IF_REAL,"Characteristic temperature determined by traps"), |
||||
|
IOP( "flo", MESA_MOD_FLO, IF_REAL,""), |
||||
|
IOP( "delfo", MESA_MOD_DELFO, IF_REAL,""), |
||||
|
IOP( "ag", MESA_MOD_AG, IF_REAL,""), |
||||
|
IOP( "rtc1", MESA_MOD_TC1, IF_REAL,""), |
||||
|
IOP( "rtc2", MESA_MOD_TC2, IF_REAL,""), |
||||
|
IOP( "zeta", MESA_MOD_ZETA, IF_REAL,""), |
||||
|
IOP( "level", MESA_MOD_LEVEL, IF_REAL,""), |
||||
|
IOP( "nmax", MESA_MOD_NMAX, IF_REAL,""), |
||||
|
IOP( "gamma", MESA_MOD_GAMMA, IF_REAL,""), |
||||
|
IOP( "epsi", MESA_MOD_EPSI, IF_REAL,""), |
||||
|
IOP( "cas", MESA_MOD_CAS, IF_REAL,""), |
||||
|
IOP( "cbs", MESA_MOD_CBS, IF_REAL,""), |
||||
|
OP( "type", MESA_MOD_TYPE, IF_FLAG,"N-type or P-type MESfet model"), |
||||
|
IP( "pmf", MESA_MOD_PMF, IF_FLAG,"P type MESfet model"), |
||||
|
IP( "nmf", MESA_MOD_NMF, IF_FLAG,"N type MESfet model"), |
||||
|
OP( "gd", MESA_MOD_DRAINCONDUCT, IF_REAL,"Drain conductance"), |
||||
|
OP( "gs", MESA_MOD_SOURCECONDUCT, IF_REAL,"Source conductance"), |
||||
|
OP( "vcrit", MESA_MOD_VCRIT, IF_REAL,"Critical voltage"), |
||||
|
}; |
||||
|
|
||||
|
char *MESAnames[] = { |
||||
|
"Drain", |
||||
|
"Gate", |
||||
|
"Source" |
||||
|
}; |
||||
|
|
||||
|
int MESAnSize = NUMELEMS(MESAnames); |
||||
|
int MESApTSize = NUMELEMS(MESApTable); |
||||
|
int MESAmPTSize = NUMELEMS(MESAmPTable); |
||||
|
int MESAiSize = sizeof(MESAinstance); |
||||
|
int MESAmSize = sizeof(MESAmodel); |
||||
@ -0,0 +1,97 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MESAacLoad(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
MESAmodel *model = (MESAmodel*)inModel; |
||||
|
MESAinstance *here; |
||||
|
double gm; |
||||
|
double gds; |
||||
|
double ggspp; |
||||
|
double ggdpp; |
||||
|
double ggs; |
||||
|
double xgs; |
||||
|
double ggd; |
||||
|
double xgd; |
||||
|
double f; |
||||
|
double lambda; |
||||
|
double vds; |
||||
|
double delidgch; |
||||
|
double delidvds; |
||||
|
|
||||
|
for( ; model != NULL; model = model->MESAnextModel ) { |
||||
|
for( here = model->MESAinstances; here != NULL; |
||||
|
here = here->MESAnextInstance) { |
||||
|
f = ckt->CKTomega/2/M_PI; |
||||
|
if(here->MESAdelf == 0) |
||||
|
lambda = here->MESAtLambda; |
||||
|
else |
||||
|
lambda = here->MESAtLambda+0.5*(here->MESAtLambdahf-here->MESAtLambda)* |
||||
|
(1+tanh((f-here->MESAfl)/here->MESAdelf)); |
||||
|
vds= *(ckt->CKTstate0 + here->MESAvgs) - |
||||
|
*(ckt->CKTstate0 + here->MESAvgd); |
||||
|
delidgch = here->MESAdelidgch0*(1+lambda*vds); |
||||
|
delidvds = here->MESAdelidvds0*(1+2*lambda*vds) - |
||||
|
here->MESAdelidvds1; |
||||
|
gm = (delidgch*here->MESAgm0+here->MESAgm1)*here->MESAgm2; |
||||
|
gds = delidvds+here->MESAgds0; |
||||
|
|
||||
|
ggspp=*(ckt->CKTstate0 + here->MESAggspp); |
||||
|
ggdpp=*(ckt->CKTstate0 + here->MESAggdpp); |
||||
|
ggs= *(ckt->CKTstate0 + here->MESAggs) ; |
||||
|
xgs= *(ckt->CKTstate0 + here->MESAqgs) * ckt->CKTomega ; |
||||
|
ggd= *(ckt->CKTstate0 + here->MESAggd) ; |
||||
|
xgd= *(ckt->CKTstate0 + here->MESAqgd) * ckt->CKTomega ; |
||||
|
|
||||
|
*(here->MESAdrainDrainPtr) += here->MESAdrainConduct; |
||||
|
*(here->MESAsourceSourcePtr) += here->MESAsourceConduct; |
||||
|
*(here->MESAgateGatePtr) += here->MESAgateConduct; |
||||
|
*(here->MESAsourcePrmPrmSourcePrmPrmPtr) += (here->MESAtGi+ggspp); |
||||
|
*(here->MESAdrainPrmPrmDrainPrmPrmPtr) += (here->MESAtGf+ggdpp); |
||||
|
*(here->MESAdrainDrainPrimePtr) -= here->MESAdrainConduct; |
||||
|
*(here->MESAdrainPrimeDrainPtr) -= here->MESAdrainConduct; |
||||
|
*(here->MESAsourceSourcePrimePtr) -= here->MESAsourceConduct; |
||||
|
*(here->MESAsourcePrimeSourcePtr) -= here->MESAsourceConduct; |
||||
|
*(here->MESAgateGatePrimePtr) -= here->MESAgateConduct; |
||||
|
*(here->MESAgatePrimeGatePtr) -= here->MESAgateConduct; |
||||
|
*(here->MESAgatePrimeDrainPrimePtr) += (-ggd); |
||||
|
*(here->MESAgatePrimeSourcePrimePtr) += (-ggs); |
||||
|
*(here->MESAdrainPrimeGatePrimePtr) += (gm-ggd); |
||||
|
*(here->MESAdrainPrimeSourcePrimePtr) += (-gds-gm); |
||||
|
*(here->MESAsourcePrimeGatePrimePtr) += (-ggs-gm); |
||||
|
*(here->MESAsourcePrimeDrainPrimePtr) += (-gds); |
||||
|
*(here->MESAgatePrimeGatePrimePtr) += (ggd+ggs+here->MESAgateConduct+ggspp+ggdpp); |
||||
|
*(here->MESAdrainPrimeDrainPrimePtr) += (gds+ggd+here->MESAdrainConduct+here->MESAtGf); |
||||
|
*(here->MESAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+here->MESAsourceConduct+here->MESAtGi); |
||||
|
*(here->MESAsourcePrimeSourcePrmPrmPtr) -= here->MESAtGi; |
||||
|
*(here->MESAsourcePrmPrmSourcePrimePtr) -= here->MESAtGi; |
||||
|
*(here->MESAgatePrimeSourcePrmPrmPtr) -= ggspp; |
||||
|
*(here->MESAsourcePrmPrmGatePrimePtr) -= ggspp; |
||||
|
*(here->MESAdrainPrimeDrainPrmPrmPtr) -= here->MESAtGf; |
||||
|
*(here->MESAdrainPrmPrmDrainPrimePtr) -= here->MESAtGf; |
||||
|
*(here->MESAgatePrimeDrainPrmPrmPtr) -= ggdpp; |
||||
|
*(here->MESAdrainPrmPrmGatePrimePtr) -= ggdpp; |
||||
|
*(here->MESAsourcePrmPrmSourcePrmPrmPtr+1) += xgs; |
||||
|
*(here->MESAdrainPrmPrmDrainPrmPrmPtr+1) += xgd; |
||||
|
*(here->MESAgatePrimeGatePrimePtr+1) += xgd+xgs; |
||||
|
*(here->MESAgatePrimeDrainPrmPrmPtr+1) -= xgd; |
||||
|
*(here->MESAdrainPrmPrmGatePrimePtr+1) -= xgd; |
||||
|
*(here->MESAgatePrimeSourcePrmPrmPtr+1) -= xgs; |
||||
|
*(here->MESAsourcePrmPrmGatePrimePtr+1) -= xgs; |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,140 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1987 Thomas L. Quarles |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into MESA model: 2001 Paolo Nenzi |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/* ARGSUSED */ |
||||
|
int |
||||
|
MESAask(ckt,inst,which,value,select) |
||||
|
CKTcircuit *ckt; |
||||
|
GENinstance *inst; |
||||
|
int which; |
||||
|
IFvalue *value; |
||||
|
IFvalue *select; |
||||
|
{ |
||||
|
MESAinstance *here = (MESAinstance*)inst; |
||||
|
static char *msg = "Current and power not available in ac analysis"; |
||||
|
switch(which) { |
||||
|
case MESA_LENGTH: |
||||
|
value->rValue = here->MESAlength; |
||||
|
return (OK); |
||||
|
case MESA_WIDTH: |
||||
|
value->rValue = here->MESAwidth; |
||||
|
return (OK); |
||||
|
case MESA_IC_VDS: |
||||
|
value->rValue = here->MESAicVDS; |
||||
|
return (OK); |
||||
|
case MESA_IC_VGS: |
||||
|
value->rValue = here->MESAicVGS; |
||||
|
return (OK); |
||||
|
case MESA_OFF: |
||||
|
value->iValue = here->MESAoff; |
||||
|
return (OK); |
||||
|
case MESA_TD: |
||||
|
value->rValue = here->MESAtd; |
||||
|
return (OK); |
||||
|
case MESA_TS: |
||||
|
value->rValue = here->MESAts; |
||||
|
return (OK); |
||||
|
case MESA_DRAINNODE: |
||||
|
value->iValue = here->MESAdrainNode; |
||||
|
return (OK); |
||||
|
case MESA_GATENODE: |
||||
|
value->iValue = here->MESAgateNode; |
||||
|
return (OK); |
||||
|
case MESA_SOURCENODE: |
||||
|
value->iValue = here->MESAsourceNode; |
||||
|
return (OK); |
||||
|
case MESA_DRAINPRIMENODE: |
||||
|
value->iValue = here->MESAdrainPrimeNode; |
||||
|
return (OK); |
||||
|
case MESA_SOURCEPRIMENODE: |
||||
|
value->iValue = here->MESAsourcePrimeNode; |
||||
|
return (OK); |
||||
|
case MESA_GATEPRIMENODE: |
||||
|
value->iValue = here->MESAgatePrimeNode; |
||||
|
return (OK); |
||||
|
case MESA_VGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAvgs); |
||||
|
return (OK); |
||||
|
case MESA_VGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAvgd); |
||||
|
return (OK); |
||||
|
case MESA_CG: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAcg); |
||||
|
return (OK); |
||||
|
case MESA_CD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAcd); |
||||
|
return (OK); |
||||
|
case MESA_CGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAcgd); |
||||
|
return (OK); |
||||
|
case MESA_GM: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAgm); |
||||
|
return (OK); |
||||
|
case MESA_GDS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAgds); |
||||
|
return (OK); |
||||
|
case MESA_GGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAggs); |
||||
|
return (OK); |
||||
|
case MESA_GGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAggd); |
||||
|
return (OK); |
||||
|
case MESA_QGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAqgs); |
||||
|
return (OK); |
||||
|
case MESA_CQGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAcqgs); |
||||
|
return (OK); |
||||
|
case MESA_QGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAqgd); |
||||
|
return (OK); |
||||
|
case MESA_CQGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAcqgd); |
||||
|
return (OK); |
||||
|
case MESA_CS : |
||||
|
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
||||
|
errMsg = MALLOC(strlen(msg)+1); |
||||
|
errRtn = "MESAask"; |
||||
|
strcpy(errMsg,msg); |
||||
|
return(E_ASKCURRENT); |
||||
|
} else { |
||||
|
value->rValue = -*(ckt->CKTstate0 + here->MESAcd); |
||||
|
value->rValue -= *(ckt->CKTstate0 + here->MESAcg); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MESA_POWER : |
||||
|
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
||||
|
errMsg = MALLOC(strlen(msg)+1); |
||||
|
errRtn = "MESAask"; |
||||
|
strcpy(errMsg,msg); |
||||
|
return(E_ASKPOWER); |
||||
|
} else { |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MESAcd) * |
||||
|
*(ckt->CKTrhsOld + here->MESAdrainNode); |
||||
|
value->rValue += *(ckt->CKTstate0 + here->MESAcg) * |
||||
|
*(ckt->CKTrhsOld + here->MESAgateNode); |
||||
|
value->rValue -= (*(ckt->CKTstate0+here->MESAcd) + |
||||
|
*(ckt->CKTstate0 + here->MESAcg)) * |
||||
|
*(ckt->CKTrhsOld + here->MESAsourceNode); |
||||
|
} |
||||
|
return(OK); |
||||
|
default: |
||||
|
return (E_BADPARM); |
||||
|
} |
||||
|
/* NOTREACHED */ |
||||
|
} |
||||
@ -0,0 +1,467 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#ifndef MESA |
||||
|
#define MESA |
||||
|
|
||||
|
#include "ifsim.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "gendefs.h" |
||||
|
#include "complex.h" |
||||
|
#include "noisedef.h" |
||||
|
|
||||
|
/* structures used to describe MESFET Transistors */ |
||||
|
|
||||
|
|
||||
|
/* information used to describe a single instance */ |
||||
|
|
||||
|
typedef struct sMESAinstance { |
||||
|
struct sMESAmodel *MESAmodPtr; /* backpointer to model */ |
||||
|
struct sMESAinstance *MESAnextInstance; /* pointer to next instance of |
||||
|
* current model*/ |
||||
|
IFuid MESAname; /* pointer to character string naming this instance */ |
||||
|
int MESAowner; /* number of owner process */ |
||||
|
int MESAstate; /* pointer to start of state vector for MESAfet */ |
||||
|
|
||||
|
int MESAdrainNode; /* number of drain node of MESAfet */ |
||||
|
int MESAgateNode; /* number of gate node of MESAfet */ |
||||
|
int MESAsourceNode; /* number of source node of MESAfet */ |
||||
|
int MESAdrainPrimeNode; /* number of internal drain node of MESAfet */ |
||||
|
int MESAgatePrimeNode; /* number of internal gate node of MESAfet */ |
||||
|
int MESAsourcePrimeNode; /* number of internal source node of MESAfet */ |
||||
|
int MESAsourcePrmPrmNode; |
||||
|
int MESAdrainPrmPrmNode; |
||||
|
double MESAlength; /* length of MESAfet */ |
||||
|
double MESAwidth; /* width of MESAfet */ |
||||
|
double MESAicVDS; /* initial condition voltage D-S*/ |
||||
|
double MESAicVGS; /* initial condition voltage G-S*/ |
||||
|
double MESAtd; /* drain temperature */ |
||||
|
double MESAts; /* source temperature */ |
||||
|
double MESAtVto; |
||||
|
double MESAtLambda; |
||||
|
double MESAtLambdahf; |
||||
|
double MESAtEta; |
||||
|
double MESAtMu; |
||||
|
double MESAtPhib; |
||||
|
double MESAtTheta; |
||||
|
double MESAtRsi; |
||||
|
double MESAtRdi; |
||||
|
double MESAtRs; |
||||
|
double MESAtRd; |
||||
|
double MESAtRg; |
||||
|
double MESAtRi; |
||||
|
double MESAtRf; |
||||
|
double MESAtGi; |
||||
|
double MESAtGf; |
||||
|
double MESAdrainConduct; |
||||
|
double MESAsourceConduct; |
||||
|
double MESAgateConduct; |
||||
|
double *MESAdrainDrainPrimePtr; |
||||
|
double *MESAgatePrimeDrainPrimePtr; |
||||
|
double *MESAgatePrimeSourcePrimePtr; |
||||
|
double *MESAsourceSourcePrimePtr; |
||||
|
double *MESAdrainPrimeDrainPtr; |
||||
|
double *MESAdrainPrimeGatePrimePtr; |
||||
|
double *MESAdrainPrimeSourcePrimePtr; |
||||
|
double *MESAsourcePrimeGatePrimePtr; |
||||
|
double *MESAsourcePrimeSourcePtr; |
||||
|
double *MESAsourcePrimeDrainPrimePtr; |
||||
|
double *MESAdrainDrainPtr; |
||||
|
double *MESAgatePrimeGatePrimePtr; |
||||
|
double *MESAsourceSourcePtr; |
||||
|
double *MESAdrainPrimeDrainPrimePtr; |
||||
|
double *MESAsourcePrimeSourcePrimePtr; |
||||
|
double *MESAgateGatePrimePtr; |
||||
|
double *MESAgatePrimeGatePtr; |
||||
|
double *MESAgateGatePtr; |
||||
|
double *MESAsourcePrmPrmSourcePrmPrmPtr; |
||||
|
double *MESAsourcePrmPrmSourcePrimePtr; |
||||
|
double *MESAsourcePrimeSourcePrmPrmPtr; |
||||
|
double *MESAsourcePrmPrmGatePrimePtr; |
||||
|
double *MESAgatePrimeSourcePrmPrmPtr; |
||||
|
double *MESAdrainPrmPrmDrainPrmPrmPtr; |
||||
|
double *MESAdrainPrmPrmDrainPrimePtr; |
||||
|
double *MESAdrainPrimeDrainPrmPrmPtr; |
||||
|
double *MESAdrainPrmPrmGatePrimePtr; |
||||
|
double *MESAgatePrimeDrainPrmPrmPtr; |
||||
|
|
||||
|
#define MESAvgs MESAstate |
||||
|
#define MESAvgd MESAstate+1 |
||||
|
#define MESAcg MESAstate+2 |
||||
|
#define MESAcd MESAstate+3 |
||||
|
#define MESAcgd MESAstate+4 |
||||
|
#define MESAcgs MESAstate+5 |
||||
|
#define MESAgm MESAstate+6 |
||||
|
#define MESAgds MESAstate+7 |
||||
|
#define MESAggs MESAstate+8 |
||||
|
#define MESAggd MESAstate+9 |
||||
|
#define MESAqgs MESAstate+10 |
||||
|
#define MESAcqgs MESAstate+11 |
||||
|
#define MESAqgd MESAstate+12 |
||||
|
#define MESAcqgd MESAstate+13 |
||||
|
#define MESAvgspp MESAstate+14 |
||||
|
#define MESAggspp MESAstate+15 |
||||
|
#define MESAcgspp MESAstate+16 |
||||
|
#define MESAvgdpp MESAstate+17 |
||||
|
#define MESAggdpp MESAstate+18 |
||||
|
#define MESAcgdpp MESAstate+19 |
||||
|
|
||||
|
int MESAoff; |
||||
|
unsigned MESAlengthGiven : 1; |
||||
|
unsigned MESAwidthGiven : 1; |
||||
|
unsigned MESAicVDSGiven : 1; |
||||
|
unsigned MESAicVGSGiven : 1; |
||||
|
unsigned MESAtdGiven : 1; |
||||
|
unsigned MESAtsGiven : 1; |
||||
|
|
||||
|
int MESAmode; |
||||
|
|
||||
|
/* |
||||
|
* naming convention: |
||||
|
* x = vgs |
||||
|
* y = vgd |
||||
|
* z = vds |
||||
|
* cdr = cdrain |
||||
|
*/ |
||||
|
|
||||
|
#define MESANDCOEFFS 27 |
||||
|
|
||||
|
#ifndef NODISTO |
||||
|
double MESAdCoeffs[MESANDCOEFFS]; |
||||
|
#else /* NODISTO */ |
||||
|
double *MESAdCoeffs; |
||||
|
#endif /* NODISTO */ |
||||
|
|
||||
|
#ifndef CONFIG |
||||
|
|
||||
|
#define cdr_x MESAdCoeffs[0] |
||||
|
#define cdr_z MESAdCoeffs[1] |
||||
|
#define cdr_x2 MESAdCoeffs[2] |
||||
|
#define cdr_z2 MESAdCoeffs[3] |
||||
|
#define cdr_xz MESAdCoeffs[4] |
||||
|
#define cdr_x3 MESAdCoeffs[5] |
||||
|
#define cdr_z3 MESAdCoeffs[6] |
||||
|
#define cdr_x2z MESAdCoeffs[7] |
||||
|
#define cdr_xz2 MESAdCoeffs[8] |
||||
|
|
||||
|
#define ggs3 MESAdCoeffs[9] |
||||
|
#define ggd3 MESAdCoeffs[10] |
||||
|
#define ggs2 MESAdCoeffs[11] |
||||
|
#define ggd2 MESAdCoeffs[12] |
||||
|
|
||||
|
#define qgs_x2 MESAdCoeffs[13] |
||||
|
#define qgs_y2 MESAdCoeffs[14] |
||||
|
#define qgs_xy MESAdCoeffs[15] |
||||
|
#define qgs_x3 MESAdCoeffs[16] |
||||
|
#define qgs_y3 MESAdCoeffs[17] |
||||
|
#define qgs_x2y MESAdCoeffs[18] |
||||
|
#define qgs_xy2 MESAdCoeffs[19] |
||||
|
|
||||
|
#define qgd_x2 MESAdCoeffs[20] |
||||
|
#define qgd_y2 MESAdCoeffs[21] |
||||
|
#define qgd_xy MESAdCoeffs[22] |
||||
|
#define qgd_x3 MESAdCoeffs[23] |
||||
|
#define qgd_y3 MESAdCoeffs[24] |
||||
|
#define qgd_x2y MESAdCoeffs[25] |
||||
|
#define qgd_xy2 MESAdCoeffs[26] |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
/* indices to the array of MESAFET noise sources */ |
||||
|
|
||||
|
#define MESARDNOIZ 0 |
||||
|
#define MESARSNOIZ 1 |
||||
|
#define MESAIDNOIZ 2 |
||||
|
#define MESAFLNOIZ 3 |
||||
|
#define MESATOTNOIZ 4 |
||||
|
|
||||
|
#define MESANSRCS 5 /* the number of MESAFET noise sources */ |
||||
|
|
||||
|
#ifndef NONOISE |
||||
|
double MESAnVar[NSTATVARS][MESANSRCS]; |
||||
|
#else /* NONOISE */ |
||||
|
double **MESAnVar; |
||||
|
#endif /* NONOISE */ |
||||
|
double MESAcsatfs; |
||||
|
double MESAcsatfd; |
||||
|
double MESAggrwl; |
||||
|
double MESAgchi0; |
||||
|
double MESAbeta; |
||||
|
double MESAisatb0; |
||||
|
double MESAimax; |
||||
|
double MESAcf; |
||||
|
double MESAfl; |
||||
|
double MESAdelf; |
||||
|
double MESAgds0; |
||||
|
double MESAgm0; |
||||
|
double MESAgm1; |
||||
|
double MESAgm2; |
||||
|
double MESAdelidvds0; |
||||
|
double MESAdelidvds1; |
||||
|
double MESAdelidgch0; |
||||
|
double MESAn0; |
||||
|
double MESAnsb0; |
||||
|
double MESAvcrits; |
||||
|
double MESAvcritd; |
||||
|
} MESAinstance ; |
||||
|
|
||||
|
|
||||
|
/* per model data */ |
||||
|
|
||||
|
typedef struct sMESAmodel { /* model structure for a MESAfet */ |
||||
|
int MESAmodType; /* type index of this device type */ |
||||
|
struct sMESAmodel *MESAnextModel; /* pointer to next possible model in |
||||
|
* linked list */ |
||||
|
MESAinstance * MESAinstances; /* pointer to list of instances |
||||
|
* that have this model */ |
||||
|
IFuid MESAmodName; /* pointer to character string naming this model */ |
||||
|
int MESAtype; |
||||
|
|
||||
|
double MESAthreshold; |
||||
|
double MESAlambda; |
||||
|
double MESAbeta; |
||||
|
double MESAvs; |
||||
|
double MESAeta; |
||||
|
double MESAm; |
||||
|
double MESAmc; |
||||
|
double MESAalpha; |
||||
|
double MESAsigma0; |
||||
|
double MESAvsigmat; |
||||
|
double MESAvsigma; |
||||
|
double MESAmu; |
||||
|
double MESAtheta; |
||||
|
double MESAmu1; |
||||
|
double MESAmu2; |
||||
|
double MESAd; |
||||
|
double MESAnd; |
||||
|
double MESAdu; |
||||
|
double MESAndu; |
||||
|
double MESAth; |
||||
|
double MESAndelta; |
||||
|
double MESAdelta; |
||||
|
double MESAtc; |
||||
|
double MESArdi; |
||||
|
double MESArsi; |
||||
|
double MESAdrainResist; |
||||
|
double MESAsourceResist; |
||||
|
double MESAgateResist; |
||||
|
double MESAri; |
||||
|
double MESArf; |
||||
|
double MESAphib; |
||||
|
double MESAphib1; |
||||
|
double MESAastar; |
||||
|
double MESAggr; |
||||
|
double MESAdel; |
||||
|
double MESAxchi; |
||||
|
double MESAn; |
||||
|
double MESAtvto; |
||||
|
double MESAtlambda; |
||||
|
double MESAteta0; |
||||
|
double MESAteta1; |
||||
|
double MESAtmu; |
||||
|
double MESAxtm0; |
||||
|
double MESAxtm1; |
||||
|
double MESAxtm2; |
||||
|
double MESAks; |
||||
|
double MESAvsg; |
||||
|
double MESAlambdahf; |
||||
|
double MESAtf; |
||||
|
double MESAflo; |
||||
|
double MESAdelfo; |
||||
|
double MESAag; |
||||
|
double MESAtc1; |
||||
|
double MESAtc2; |
||||
|
double MESAzeta; |
||||
|
double MESAlevel; |
||||
|
double MESAnmax; |
||||
|
double MESAgamma; |
||||
|
double MESAepsi; |
||||
|
double MESAcbs; |
||||
|
double MESAcas; |
||||
|
|
||||
|
double MESAsigma; |
||||
|
double MESAvpo; |
||||
|
double MESAvpou; |
||||
|
double MESAvpod; |
||||
|
double MESAdeltaSqr; |
||||
|
|
||||
|
unsigned MESAthresholdGiven:1; |
||||
|
unsigned MESAlambdaGiven:1; |
||||
|
unsigned MESAbetaGiven:1; |
||||
|
unsigned MESAvsGiven:1; |
||||
|
unsigned MESAetaGiven:1; |
||||
|
unsigned MESAmGiven:1; |
||||
|
unsigned MESAmcGiven:1; |
||||
|
unsigned MESAalphaGiven:1; |
||||
|
unsigned MESAsigma0Given:1; |
||||
|
unsigned MESAvsigmatGiven:1; |
||||
|
unsigned MESAvsigmaGiven:1; |
||||
|
unsigned MESAmuGiven:1; |
||||
|
unsigned MESAthetaGiven:1; |
||||
|
unsigned MESAmu1Given:1; |
||||
|
unsigned MESAmu2Given:1; |
||||
|
unsigned MESAdGiven:1; |
||||
|
unsigned MESAndGiven:1; |
||||
|
unsigned MESAduGiven:1; |
||||
|
unsigned MESAnduGiven:1; |
||||
|
unsigned MESAthGiven:1; |
||||
|
unsigned MESAndeltaGiven:1; |
||||
|
unsigned MESAdeltaGiven:1; |
||||
|
unsigned MESAtcGiven:1; |
||||
|
unsigned MESArdiGiven:1; |
||||
|
unsigned MESArsiGiven:1; |
||||
|
unsigned MESAdrainResistGiven:1; |
||||
|
unsigned MESAsourceResistGiven:1; |
||||
|
unsigned MESAgateResistGiven:1; |
||||
|
unsigned MESAriGiven:1; |
||||
|
unsigned MESArfGiven:1; |
||||
|
unsigned MESAphibGiven:1; |
||||
|
unsigned MESAphib1Given:1; |
||||
|
unsigned MESAastarGiven:1; |
||||
|
unsigned MESAggrGiven:1; |
||||
|
unsigned MESAdelGiven:1; |
||||
|
unsigned MESAxchiGiven:1; |
||||
|
unsigned MESAnGiven:1; |
||||
|
unsigned MESAtvtoGiven:1; |
||||
|
unsigned MESAtlambdaGiven:1; |
||||
|
unsigned MESAteta0Given:1; |
||||
|
unsigned MESAteta1Given:1; |
||||
|
unsigned MESAtmuGiven:1; |
||||
|
unsigned MESAxtm0Given:1; |
||||
|
unsigned MESAxtm1Given:1; |
||||
|
unsigned MESAxtm2Given:1; |
||||
|
unsigned MESAksGiven:1; |
||||
|
unsigned MESAvsgGiven:1; |
||||
|
unsigned MESAlambdahfGiven:1; |
||||
|
unsigned MESAtfGiven:1; |
||||
|
unsigned MESAfloGiven:1; |
||||
|
unsigned MESAdelfoGiven:1; |
||||
|
unsigned MESAagGiven:1; |
||||
|
unsigned MESAtc1Given:1; |
||||
|
unsigned MESAtc2Given:1; |
||||
|
unsigned MESAzetaGiven:1; |
||||
|
unsigned MESAlevelGiven:1; |
||||
|
unsigned MESAnmaxGiven:1; |
||||
|
unsigned MESAgammaGiven:1; |
||||
|
unsigned MESAepsiGiven:1; |
||||
|
unsigned MESAcbsGiven:1; |
||||
|
unsigned MESAcasGiven:1; |
||||
|
|
||||
|
} MESAmodel; |
||||
|
|
||||
|
#ifndef NMF |
||||
|
|
||||
|
#define NMF 1 |
||||
|
#define PMF -1 |
||||
|
#endif |
||||
|
|
||||
|
/* device parameters */ |
||||
|
#define MESA_LENGTH 1 |
||||
|
#define MESA_WIDTH 2 |
||||
|
#define MESA_IC_VDS 3 |
||||
|
#define MESA_IC_VGS 4 |
||||
|
#define MESA_TD 5 |
||||
|
#define MESA_TS 6 |
||||
|
#define MESA_IC 7 |
||||
|
#define MESA_OFF 8 |
||||
|
#define MESA_CS 9 |
||||
|
#define MESA_POWER 10 |
||||
|
|
||||
|
/* model parameters */ |
||||
|
#define MESA_MOD_VTO 101 |
||||
|
#define MESA_MOD_VS 102 |
||||
|
#define MESA_MOD_LAMBDA 103 |
||||
|
#define MESA_MOD_RD 104 |
||||
|
#define MESA_MOD_RS 105 |
||||
|
#define MESA_MOD_RG 106 |
||||
|
#define MESA_MOD_RI 107 |
||||
|
#define MESA_MOD_RF 108 |
||||
|
#define MESA_MOD_RDI 109 |
||||
|
#define MESA_MOD_RSI 110 |
||||
|
#define MESA_MOD_PHIB 111 |
||||
|
#define MESA_MOD_PHIB1 112 |
||||
|
#define MESA_MOD_ASTAR 113 |
||||
|
#define MESA_MOD_GGR 114 |
||||
|
#define MESA_MOD_DEL 115 |
||||
|
#define MESA_MOD_XCHI 116 |
||||
|
#define MESA_MOD_N 117 |
||||
|
#define MESA_MOD_ETA 118 |
||||
|
#define MESA_MOD_M 119 |
||||
|
#define MESA_MOD_MC 120 |
||||
|
#define MESA_MOD_SIGMA0 121 |
||||
|
#define MESA_MOD_VSIGMAT 122 |
||||
|
#define MESA_MOD_VSIGMA 123 |
||||
|
#define MESA_MOD_MU 124 |
||||
|
#define MESA_MOD_MU1 125 |
||||
|
#define MESA_MOD_MU2 126 |
||||
|
#define MESA_MOD_D 127 |
||||
|
#define MESA_MOD_ND 128 |
||||
|
#define MESA_MOD_DELTA 129 |
||||
|
#define MESA_MOD_TC 130 |
||||
|
#define MESA_MOD_NMF 131 |
||||
|
#define MESA_MOD_TVTO 132 |
||||
|
#define MESA_MOD_TLAMBDA 134 |
||||
|
#define MESA_MOD_TETA0 135 |
||||
|
#define MESA_MOD_TETA1 136 |
||||
|
#define MESA_MOD_TMU 137 |
||||
|
#define MESA_MOD_XTM0 138 |
||||
|
#define MESA_MOD_XTM1 139 |
||||
|
#define MESA_MOD_XTM2 140 |
||||
|
#define MESA_MOD_KS 141 |
||||
|
#define MESA_MOD_VSG 142 |
||||
|
#define MESA_MOD_LAMBDAHF 143 |
||||
|
#define MESA_MOD_TF 144 |
||||
|
#define MESA_MOD_FLO 145 |
||||
|
#define MESA_MOD_DELFO 146 |
||||
|
#define MESA_MOD_AG 147 |
||||
|
#define MESA_MOD_THETA 148 |
||||
|
#define MESA_MOD_ALPHA 149 |
||||
|
#define MESA_MOD_TC1 150 |
||||
|
#define MESA_MOD_TC2 151 |
||||
|
#define MESA_MOD_ZETA 152 |
||||
|
#define MESA_MOD_BETA 153 |
||||
|
#define MESA_MOD_DU 154 |
||||
|
#define MESA_MOD_NDU 155 |
||||
|
#define MESA_MOD_TH 156 |
||||
|
#define MESA_MOD_NDELTA 157 |
||||
|
#define MESA_MOD_LEVEL 158 |
||||
|
#define MESA_MOD_NMAX 159 |
||||
|
#define MESA_MOD_GAMMA 160 |
||||
|
#define MESA_MOD_EPSI 161 |
||||
|
#define MESA_MOD_CBS 162 |
||||
|
#define MESA_MOD_CAS 163 |
||||
|
#define MESA_MOD_PMF 164 |
||||
|
#define MESA_MOD_TYPE 165 |
||||
|
|
||||
|
#define MESA_DRAINNODE 201 |
||||
|
#define MESA_GATENODE 202 |
||||
|
#define MESA_SOURCENODE 203 |
||||
|
#define MESA_DRAINPRIMENODE 204 |
||||
|
#define MESA_SOURCEPRIMENODE 205 |
||||
|
#define MESA_GATEPRIMENODE 206 |
||||
|
|
||||
|
#define MESA_VGS 207 |
||||
|
#define MESA_VGD 208 |
||||
|
#define MESA_CG 209 |
||||
|
#define MESA_CD 210 |
||||
|
#define MESA_CGD 211 |
||||
|
#define MESA_GM 212 |
||||
|
#define MESA_GDS 213 |
||||
|
#define MESA_GGS 214 |
||||
|
#define MESA_GGD 215 |
||||
|
#define MESA_QGS 216 |
||||
|
#define MESA_CQGS 217 |
||||
|
#define MESA_QGD 218 |
||||
|
#define MESA_CQGD 219 |
||||
|
|
||||
|
#define MESA_MOD_DRAINCONDUCT 301 |
||||
|
#define MESA_MOD_SOURCECONDUCT 302 |
||||
|
#define MESA_MOD_GATECONDUCT 303 |
||||
|
#define MESA_MOD_DEPLETIONCAP 304 |
||||
|
#define MESA_MOD_VCRIT 305 |
||||
|
|
||||
|
#include "mesaext.h" |
||||
|
|
||||
|
#endif /*MESA*/ |
||||
@ -0,0 +1,39 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 S. Hwang |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into mesa model: 2001 Paolo Nenzi |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "mesadefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MESAdelete(inModel,name,inst) |
||||
|
GENmodel *inModel; |
||||
|
IFuid name; |
||||
|
GENinstance **inst; |
||||
|
{ |
||||
|
MESAmodel *model = (MESAmodel*)inModel; |
||||
|
MESAinstance **fast = (MESAinstance**)inst; |
||||
|
MESAinstance **prev = NULL; |
||||
|
MESAinstance *here; |
||||
|
|
||||
|
for( ; model ; model = model->MESAnextModel) { |
||||
|
prev = &(model->MESAinstances); |
||||
|
for(here = *prev; here ; here = *prev) { |
||||
|
if(here->MESAname == name || (fast && here==*fast) ) { |
||||
|
*prev= here->MESAnextInstance; |
||||
|
FREE(here); |
||||
|
return(OK); |
||||
|
} |
||||
|
prev = &(here->MESAnextInstance); |
||||
|
} |
||||
|
} |
||||
|
return(E_NODEV); |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "mesadefs.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
void |
||||
|
MESAdestroy(inModel) |
||||
|
GENmodel **inModel; |
||||
|
{ |
||||
|
MESAmodel **model = (MESAmodel**)inModel; |
||||
|
MESAinstance *here; |
||||
|
MESAinstance *prev = NULL; |
||||
|
MESAmodel *mod = *model; |
||||
|
MESAmodel *oldmod = NULL; |
||||
|
|
||||
|
for( ; mod ; mod = mod->MESAnextModel) { |
||||
|
if(oldmod) FREE(oldmod); |
||||
|
oldmod = mod; |
||||
|
prev = (MESAinstance *)NULL; |
||||
|
for(here = mod->MESAinstances ; here ; here = here->MESAnextInstance) { |
||||
|
if(prev) FREE(prev); |
||||
|
prev = here; |
||||
|
} |
||||
|
if(prev) FREE(prev); |
||||
|
} |
||||
|
if(oldmod) FREE(oldmod); |
||||
|
*model = NULL; |
||||
|
return; |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#ifdef __STDC__ |
||||
|
extern int MESAacLoad(GENmodel*,CKTcircuit*); |
||||
|
extern int MESAask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); |
||||
|
extern int MESAdelete(GENmodel*,IFuid,GENinstance**); |
||||
|
extern void MESAdestroy(GENmodel**); |
||||
|
extern int MESAgetic(GENmodel*,CKTcircuit*); |
||||
|
extern int MESAload(GENmodel*,CKTcircuit*); |
||||
|
extern int MESAmAsk(CKTcircuit*,GENmodel*,int,IFvalue*); |
||||
|
extern int MESAmDelete(GENmodel**,IFuid,GENmodel*); |
||||
|
extern int MESAmParam(int,IFvalue*,GENmodel*); |
||||
|
extern int MESAparam(int,IFvalue*,GENinstance*,IFvalue*); |
||||
|
extern int MESAsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); |
||||
|
extern int MESAtemp(GENmodel*,CKTcircuit*); |
||||
|
extern int MESAtrunc(GENmodel*,CKTcircuit*,double*); |
||||
|
extern int MESAunsetup(GENmodel*,CKTcircuit*); |
||||
|
|
||||
|
#else /*stdc*/ |
||||
|
extern int MESAacLoad(); |
||||
|
extern int MESAask(); |
||||
|
extern int MESAdelete(); |
||||
|
extern void MESAdestroy(); |
||||
|
extern int MESAgetic(); |
||||
|
extern int MESAload(); |
||||
|
extern int MESAmAsk(); |
||||
|
extern int MESAmDelete(); |
||||
|
extern int MESAmParam(); |
||||
|
extern int MESAparam(); |
||||
|
extern int MESAsetup(); |
||||
|
extern int MESAtemp(); |
||||
|
extern int MESAtrunc(); |
||||
|
extern int MESAunsetup(); |
||||
|
#endif |
||||
@ -0,0 +1,41 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MESAgetic(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
MESAmodel *model = (MESAmodel*)inModel; |
||||
|
MESAinstance *here; |
||||
|
/* |
||||
|
* grab initial conditions out of rhs array. User specified, so use |
||||
|
* external nodes to get values |
||||
|
*/ |
||||
|
|
||||
|
for( ; model ; model = model->MESAnextModel) { |
||||
|
for(here = model->MESAinstances; here ; here = here->MESAnextInstance) { |
||||
|
if(!here->MESAicVDSGiven) { |
||||
|
here->MESAicVDS = |
||||
|
*(ckt->CKTrhs + here->MESAdrainNode) - |
||||
|
*(ckt->CKTrhs + here->MESAsourceNode); |
||||
|
} |
||||
|
if(!here->MESAicVGSGiven) { |
||||
|
here->MESAicVGS = |
||||
|
*(ckt->CKTrhs + here->MESAgateNode) - |
||||
|
*(ckt->CKTrhs + here->MESAsourceNode); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
#include <config.h> |
||||
|
|
||||
|
#include <devdefs.h> |
||||
|
|
||||
|
#include "mesaitf.h" |
||||
|
#include "mesaext.h" |
||||
|
#include "mesainit.h" |
||||
|
|
||||
|
|
||||
|
SPICEdev MESAinfo = { |
||||
|
{ |
||||
|
"MESA", |
||||
|
"GaAs MESFET model", |
||||
|
|
||||
|
&MESAnSize, |
||||
|
&MESAnSize, |
||||
|
MESAnames, |
||||
|
|
||||
|
&MESApTSize, |
||||
|
MESApTable, |
||||
|
|
||||
|
&MESAmPTSize, |
||||
|
MESAmPTable, |
||||
|
DEV_DEFAULT |
||||
|
}, |
||||
|
|
||||
|
DEVparam : MESAparam, |
||||
|
DEVmodParam : MESAmParam, |
||||
|
DEVload : MESAload, |
||||
|
DEVsetup : MESAsetup, |
||||
|
DEVunsetup : MESAunsetup, |
||||
|
DEVpzSetup : MESAsetup, |
||||
|
DEVtemperature: MESAtemp, |
||||
|
DEVtrunc : MESAtrunc, |
||||
|
DEVfindBranch : NULL, |
||||
|
DEVacLoad : MESAacLoad, |
||||
|
DEVaccept : NULL, |
||||
|
DEVdestroy : MESAdestroy, |
||||
|
DEVmodDelete : MESAmDelete, |
||||
|
DEVdelete : MESAdelete, |
||||
|
DEVsetic : MESAgetic, |
||||
|
DEVask : MESAask, |
||||
|
DEVmodAsk : MESAmAsk, |
||||
|
DEVpzLoad : NULL, |
||||
|
DEVconvTest : NULL, |
||||
|
DEVsenSetup : NULL, |
||||
|
DEVsenLoad : NULL, |
||||
|
DEVsenUpdate : NULL, |
||||
|
DEVsenAcLoad : NULL, |
||||
|
DEVsenPrint : NULL, |
||||
|
DEVsenTrunc : NULL, |
||||
|
DEVdisto : NULL, |
||||
|
DEVnoise : NULL, |
||||
|
|
||||
|
DEVinstSize : &MESAiSize, |
||||
|
DEVmodSize : &MESAmSize |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
|
||||
|
SPICEdev * |
||||
|
get_mesa_info(void) |
||||
|
{ |
||||
|
return &MESAinfo; |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
#ifndef _MESAINIT_H |
||||
|
#define _MESAINIT_H |
||||
|
|
||||
|
extern IFparm MESApTable[ ]; |
||||
|
extern IFparm MESAmPTable[ ]; |
||||
|
extern char *MESAnames[ ]; |
||||
|
extern int MESApTSize; |
||||
|
extern int MESAmPTSize; |
||||
|
extern int MESAnSize; |
||||
|
extern int MESAiSize; |
||||
|
extern int MESAmSize; |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,9 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
**********/ |
||||
|
#ifndef DEV_MESA |
||||
|
#define DEV_MESA |
||||
|
|
||||
|
SPICEdev *get_mesa_info(void); |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,987 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "devdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "const.h" |
||||
|
#include "trandefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
/* |
||||
|
#define true 1 |
||||
|
#define false 0 |
||||
|
*/ |
||||
|
|
||||
|
#define EPSILONGAAS (12.244*8.85418e-12) |
||||
|
|
||||
|
#define W (here->MESAwidth) |
||||
|
#define L (here->MESAlength) |
||||
|
|
||||
|
static void mesa1(MESAmodel*, MESAinstance*, double, double, double, |
||||
|
double*, double*, double*, double*,double*); |
||||
|
|
||||
|
static void mesa2(MESAmodel*, MESAinstance*, double, double, double, |
||||
|
double*, double*, double*, double*,double*); |
||||
|
|
||||
|
static void mesa3(MESAmodel*, MESAinstance*, double, double, double, |
||||
|
double*, double*, double*, double*,double*); |
||||
|
|
||||
|
void Pause(void); |
||||
|
|
||||
|
int |
||||
|
MESAload(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
//register CKTcircuit *ckt; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
MESAmodel *model = (MESAmodel*)inModel; |
||||
|
MESAinstance *here; |
||||
|
double capgd; |
||||
|
double capgs; |
||||
|
double cd; |
||||
|
double cdhat; |
||||
|
double cdrain; |
||||
|
double cdreq; |
||||
|
double ceq; |
||||
|
double ceqgd; |
||||
|
double ceqgs; |
||||
|
double cg; |
||||
|
double cgd; |
||||
|
double cgs; |
||||
|
double cghat; |
||||
|
double arg; |
||||
|
double earg; |
||||
|
double delvds; |
||||
|
double delvgd; |
||||
|
double delvgs; |
||||
|
double delvgspp=0; |
||||
|
double delvgdpp=0; |
||||
|
double evgd; |
||||
|
double evgs; |
||||
|
double gds; |
||||
|
double geq; |
||||
|
double ggd; |
||||
|
double ggs; |
||||
|
double gm; |
||||
|
double ggspp=0; |
||||
|
double cgspp=0; |
||||
|
double ggdpp=0; |
||||
|
double cgdpp=0; |
||||
|
double vcrits; |
||||
|
double vcritd; |
||||
|
double vds=0; |
||||
|
double vgd=0; |
||||
|
double vgs=0; |
||||
|
double vgspp=0; |
||||
|
double vgdpp=0; |
||||
|
double vgs1=0; |
||||
|
double vgd1=0; |
||||
|
double xfact; |
||||
|
double temp; |
||||
|
double vted; |
||||
|
double vtes; |
||||
|
double vtd; |
||||
|
double vts; |
||||
|
double von; |
||||
|
double ccorr; |
||||
|
int inverse=FALSE; |
||||
|
int icheck; |
||||
|
int ichk1; |
||||
|
int error; |
||||
|
|
||||
|
/* loop through all the models */ |
||||
|
for( ; model != NULL; model = model->MESAnextModel ) { |
||||
|
|
||||
|
/* loop through all the instances of the model */ |
||||
|
for (here = model->MESAinstances; here != NULL ; |
||||
|
here=here->MESAnextInstance) { |
||||
|
|
||||
|
/* |
||||
|
* dc model parameters |
||||
|
*/ |
||||
|
vcrits = here->MESAvcrits; |
||||
|
vcritd = here->MESAvcritd; |
||||
|
vtd = CONSTKoverQ * here->MESAtd; |
||||
|
vts = CONSTKoverQ * here->MESAts; |
||||
|
vted = model->MESAn*vtd; |
||||
|
vtes = model->MESAn*vts; |
||||
|
/* |
||||
|
* initialization |
||||
|
*/ |
||||
|
icheck = 1; |
||||
|
if( ckt->CKTmode & MODEINITSMSIG) { |
||||
|
vgs = *(ckt->CKTstate0 + here->MESAvgs); |
||||
|
vgd = *(ckt->CKTstate0 + here->MESAvgd); |
||||
|
vgspp = *(ckt->CKTstate0 + here->MESAvgspp); |
||||
|
vgdpp = *(ckt->CKTstate0 + here->MESAvgdpp); |
||||
|
} else if (ckt->CKTmode & MODEINITTRAN) { |
||||
|
vgs = *(ckt->CKTstate1 + here->MESAvgs); |
||||
|
vgd = *(ckt->CKTstate1 + here->MESAvgd); |
||||
|
vgspp = *(ckt->CKTstate1 + here->MESAvgspp); |
||||
|
vgdpp = *(ckt->CKTstate1 + here->MESAvgdpp); |
||||
|
} else if ( (ckt->CKTmode & MODEINITJCT) && |
||||
|
(ckt->CKTmode & MODETRANOP) && |
||||
|
(ckt->CKTmode & MODEUIC) ) { |
||||
|
vds = here->MESAicVDS; |
||||
|
vgs = here->MESAicVGS; |
||||
|
vgd = vgs-vds; |
||||
|
vgspp = vgs; |
||||
|
vgdpp = vgd; |
||||
|
} else if ( (ckt->CKTmode & MODEINITJCT) && |
||||
|
(here->MESAoff == 0) ) { |
||||
|
vgs = -1; |
||||
|
vgd = -1; |
||||
|
vgspp = 0; |
||||
|
vgdpp = 0; |
||||
|
} else if( (ckt->CKTmode & MODEINITJCT) || |
||||
|
((ckt->CKTmode & MODEINITFIX) && (here->MESAoff))) { |
||||
|
vgs = 0; |
||||
|
vgd = 0; |
||||
|
vgspp = 0; |
||||
|
vgdpp = 0; |
||||
|
} else { |
||||
|
#ifndef PREDICTOR |
||||
|
if(ckt->CKTmode & MODEINITPRED) { |
||||
|
xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2]; |
||||
|
*(ckt->CKTstate0 + here->MESAvgs) = |
||||
|
*(ckt->CKTstate1 + here->MESAvgs); |
||||
|
vgs = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgs) - |
||||
|
xfact * *(ckt->CKTstate2 + here->MESAvgs); |
||||
|
*(ckt->CKTstate0 + here->MESAvgspp) = |
||||
|
*(ckt->CKTstate1 + here->MESAvgspp); |
||||
|
vgspp = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgspp) - |
||||
|
xfact * *(ckt->CKTstate2 + here->MESAvgspp); |
||||
|
*(ckt->CKTstate0 + here->MESAvgd) = |
||||
|
*(ckt->CKTstate1 + here->MESAvgd); |
||||
|
vgd = (1+xfact)* *(ckt->CKTstate1 + here->MESAvgd) - |
||||
|
xfact * *(ckt->CKTstate2 + here->MESAvgd); |
||||
|
*(ckt->CKTstate0 + here->MESAvgdpp) = |
||||
|
*(ckt->CKTstate1 + here->MESAvgdpp); |
||||
|
vgdpp = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgdpp) - |
||||
|
xfact * *(ckt->CKTstate2 + here->MESAvgdpp); |
||||
|
*(ckt->CKTstate0 + here->MESAcg) = |
||||
|
*(ckt->CKTstate1 + here->MESAcg); |
||||
|
*(ckt->CKTstate0 + here->MESAcd) = |
||||
|
*(ckt->CKTstate1 + here->MESAcd); |
||||
|
*(ckt->CKTstate0 + here->MESAcgd) = |
||||
|
*(ckt->CKTstate1 + here->MESAcgd); |
||||
|
*(ckt->CKTstate0 + here->MESAcgs) = |
||||
|
*(ckt->CKTstate1 + here->MESAcgs); |
||||
|
*(ckt->CKTstate0 + here->MESAgm) = |
||||
|
*(ckt->CKTstate1 + here->MESAgm); |
||||
|
*(ckt->CKTstate0 + here->MESAgds) = |
||||
|
*(ckt->CKTstate1 + here->MESAgds); |
||||
|
*(ckt->CKTstate0 + here->MESAggs) = |
||||
|
*(ckt->CKTstate1 + here->MESAggs); |
||||
|
*(ckt->CKTstate0 + here->MESAggd) = |
||||
|
*(ckt->CKTstate1 + here->MESAggd); |
||||
|
*(ckt->CKTstate0 + here->MESAggspp) = |
||||
|
*(ckt->CKTstate1 + here->MESAggspp); |
||||
|
*(ckt->CKTstate0 + here->MESAcgspp) = |
||||
|
*(ckt->CKTstate1 + here->MESAcgspp); |
||||
|
*(ckt->CKTstate0 + here->MESAggdpp) = |
||||
|
*(ckt->CKTstate1 + here->MESAggdpp); |
||||
|
*(ckt->CKTstate0 + here->MESAcgdpp) = |
||||
|
*(ckt->CKTstate1 + here->MESAcgdpp); |
||||
|
} else { |
||||
|
#endif /* PREDICTOR */ |
||||
|
/* |
||||
|
* compute new nonlinear branch voltages |
||||
|
*/ |
||||
|
vgs = (*(ckt->CKTrhsOld+ here->MESAgatePrimeNode)- |
||||
|
*(ckt->CKTrhsOld+here->MESAsourcePrimeNode)); |
||||
|
vgd = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)- |
||||
|
*(ckt->CKTrhsOld+here->MESAdrainPrimeNode)); |
||||
|
vgspp = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)- |
||||
|
*(ckt->CKTrhsOld+here->MESAsourcePrmPrmNode)); |
||||
|
vgdpp = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)- |
||||
|
*(ckt->CKTrhsOld+here->MESAdrainPrmPrmNode)); |
||||
|
|
||||
|
#ifndef PREDICTOR |
||||
|
} |
||||
|
#endif /* PREDICTOR */ |
||||
|
delvgs=vgs - *(ckt->CKTstate0 + here->MESAvgs); |
||||
|
delvgd=vgd - *(ckt->CKTstate0 + here->MESAvgd); |
||||
|
delvds=delvgs - delvgd; |
||||
|
delvgspp = vgspp - *(ckt->CKTstate0 + here->MESAvgspp); |
||||
|
delvgdpp = vgdpp - *(ckt->CKTstate0 + here->MESAvgdpp); |
||||
|
cghat= *(ckt->CKTstate0 + here->MESAcg) + |
||||
|
*(ckt->CKTstate0 + here->MESAggd)*delvgd + |
||||
|
*(ckt->CKTstate0 + here->MESAggs)*delvgs + |
||||
|
*(ckt->CKTstate0 + here->MESAggspp)*delvgspp+ |
||||
|
*(ckt->CKTstate0 + here->MESAggdpp)*delvgdpp; |
||||
|
cdhat= *(ckt->CKTstate0 + here->MESAcd) + |
||||
|
*(ckt->CKTstate0 + here->MESAgm)*delvgs + |
||||
|
*(ckt->CKTstate0 + here->MESAgds)*delvds - |
||||
|
*(ckt->CKTstate0 + here->MESAggd)*delvgd; |
||||
|
/* |
||||
|
* bypass if solution has not changed |
||||
|
*/ |
||||
|
if((ckt->CKTbypass) && |
||||
|
(!(ckt->CKTmode & MODEINITPRED)) && |
||||
|
(fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs), |
||||
|
fabs(*(ckt->CKTstate0 + here->MESAvgs)))+ |
||||
|
ckt->CKTvoltTol) ) |
||||
|
if((fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd), |
||||
|
fabs(*(ckt->CKTstate0 + here->MESAvgd)))+ |
||||
|
ckt->CKTvoltTol)) |
||||
|
if((fabs(delvgspp) < ckt->CKTreltol*MAX(fabs(vgspp), |
||||
|
fabs(*(ckt->CKTstate0 + here->MESAvgspp)))+ |
||||
|
ckt->CKTvoltTol)) |
||||
|
if((fabs(delvgdpp) < ckt->CKTreltol*MAX(fabs(vgdpp), |
||||
|
fabs(*(ckt->CKTstate0 + here->MESAvgdpp)))+ |
||||
|
ckt->CKTvoltTol)) |
||||
|
if((fabs(cghat-*(ckt->CKTstate0 + here->MESAcg)) |
||||
|
< ckt->CKTreltol*MAX(fabs(cghat), |
||||
|
fabs(*(ckt->CKTstate0 + here->MESAcg)))+ |
||||
|
ckt->CKTabstol)) |
||||
|
if((fabs(cdhat-*(ckt->CKTstate0 + here->MESAcd)) |
||||
|
< ckt->CKTreltol*MAX(fabs(cdhat), |
||||
|
fabs(*(ckt->CKTstate0 + here->MESAcd)))+ |
||||
|
ckt->CKTabstol)) { |
||||
|
|
||||
|
/* we can do a bypass */ |
||||
|
vgs= *(ckt->CKTstate0 + here->MESAvgs); |
||||
|
vgd= *(ckt->CKTstate0 + here->MESAvgd); |
||||
|
vds= vgs-vgd; |
||||
|
vgspp = *(ckt->CKTstate0 + here->MESAvgspp); |
||||
|
vgdpp = *(ckt->CKTstate0 + here->MESAvgdpp); |
||||
|
cg= *(ckt->CKTstate0 + here->MESAcg); |
||||
|
cd= *(ckt->CKTstate0 + here->MESAcd); |
||||
|
cgs= *(ckt->CKTstate0 + here->MESAcgs); |
||||
|
cgd= *(ckt->CKTstate0 + here->MESAcgd); |
||||
|
gm= *(ckt->CKTstate0 + here->MESAgm); |
||||
|
gds= *(ckt->CKTstate0 + here->MESAgds); |
||||
|
ggs= *(ckt->CKTstate0 + here->MESAggs); |
||||
|
ggd= *(ckt->CKTstate0 + here->MESAggd); |
||||
|
ggspp = *(ckt->CKTstate0 + here->MESAggspp); |
||||
|
cgspp = *(ckt->CKTstate0 + here->MESAcgspp); |
||||
|
ggdpp = *(ckt->CKTstate0 + here->MESAggdpp); |
||||
|
cgdpp = *(ckt->CKTstate0 + here->MESAcgdpp); |
||||
|
goto load; |
||||
|
} |
||||
|
/* |
||||
|
* limit nonlinear branch voltages |
||||
|
*/ |
||||
|
ichk1=1; |
||||
|
vgs = DEVpnjlim(vgs,*(ckt->CKTstate0 + here->MESAvgs),vtes, |
||||
|
vcrits, &icheck); |
||||
|
vgd = DEVpnjlim(vgd,*(ckt->CKTstate0 + here->MESAvgd),vted, |
||||
|
vcritd,&ichk1); |
||||
|
if (ichk1 == 1) { |
||||
|
icheck=1; |
||||
|
} |
||||
|
vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->MESAvgs), |
||||
|
here->MESAtVto); |
||||
|
vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->MESAvgd), |
||||
|
here->MESAtVto); |
||||
|
if(here->MESAsourcePrmPrmNode == here->MESAsourcePrimeNode) |
||||
|
vgspp = vgs; |
||||
|
if(here->MESAdrainPrmPrmNode == here->MESAdrainPrimeNode) |
||||
|
vgdpp = vgd; |
||||
|
} |
||||
|
/* |
||||
|
* determine dc current and derivatives |
||||
|
*/ |
||||
|
vds = vgs-vgd; |
||||
|
|
||||
|
arg = -vgs*model->MESAdel/vts; |
||||
|
earg = exp(arg); |
||||
|
evgs = exp(vgs/vtes); |
||||
|
ggs = here->MESAcsatfs*evgs/vtes+here->MESAggrwl*earg*(1-arg)+ckt->CKTgmin; |
||||
|
cgs = here->MESAcsatfs*(evgs-1)+here->MESAggrwl*vgs*earg+ |
||||
|
ckt->CKTgmin*vgs; |
||||
|
cg = cgs; |
||||
|
|
||||
|
arg = -vgd*model->MESAdel/vtd; |
||||
|
earg = exp(arg); |
||||
|
evgd = exp(vgd/vted); |
||||
|
ggd = here->MESAcsatfd*evgd/vted+here->MESAggrwl*earg*(1-arg)+ckt->CKTgmin; |
||||
|
cgd = here->MESAcsatfd*(evgd-1)+here->MESAggrwl*vgd*earg+ |
||||
|
ckt->CKTgmin*vgd; |
||||
|
cg = cg+cgd; |
||||
|
|
||||
|
if(vds < 0) { |
||||
|
vds = -vds; |
||||
|
inverse = TRUE; |
||||
|
} |
||||
|
von = here->MESAtVto+model->MESAks*(*(ckt->CKTrhsOld+here->MESAsourcePrimeNode)-model->MESAvsg); |
||||
|
if(model->MESAlevel == 2) |
||||
|
mesa1(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd); |
||||
|
else if(model->MESAlevel == 3) |
||||
|
mesa2(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd); |
||||
|
else if(model->MESAlevel == 4) |
||||
|
mesa3(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd); |
||||
|
if(inverse) { |
||||
|
cdrain = -cdrain; |
||||
|
vds = -vds; |
||||
|
temp = capgs; |
||||
|
capgs = capgd; |
||||
|
capgd = temp; |
||||
|
} |
||||
|
/* |
||||
|
* compute equivalent drain current source |
||||
|
*/ |
||||
|
cd = cdrain - cgd; |
||||
|
if ( (ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || |
||||
|
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){ |
||||
|
/* |
||||
|
* charge storage elements |
||||
|
*/ |
||||
|
vgs1 = *(ckt->CKTstate1 + here->MESAvgspp); |
||||
|
vgd1 = *(ckt->CKTstate1 + here->MESAvgdpp); |
||||
|
|
||||
|
if(ckt->CKTmode & MODEINITTRAN) { |
||||
|
*(ckt->CKTstate1 + here->MESAqgs) = capgs*vgspp; |
||||
|
*(ckt->CKTstate1 + here->MESAqgd) = capgd*vgdpp; |
||||
|
} |
||||
|
*(ckt->CKTstate0+here->MESAqgs) = *(ckt->CKTstate1 + here->MESAqgs) + |
||||
|
capgs*(vgspp-vgs1); |
||||
|
*(ckt->CKTstate0+here->MESAqgd) = *(ckt->CKTstate1 + here->MESAqgd) + |
||||
|
capgd*(vgdpp-vgd1); |
||||
|
|
||||
|
/* |
||||
|
* store small-signal parameters |
||||
|
*/ |
||||
|
if( (!(ckt->CKTmode & MODETRANOP)) || |
||||
|
(!(ckt->CKTmode & MODEUIC)) ) { |
||||
|
if(ckt->CKTmode & MODEINITSMSIG) { |
||||
|
*(ckt->CKTstate0 + here->MESAqgs) = capgs; |
||||
|
*(ckt->CKTstate0 + here->MESAqgd) = capgd; |
||||
|
continue; /*go to 1000*/ |
||||
|
} |
||||
|
/* |
||||
|
* transient analysis |
||||
|
*/ |
||||
|
if(ckt->CKTmode & MODEINITTRAN) { |
||||
|
*(ckt->CKTstate1 + here->MESAqgs) = |
||||
|
*(ckt->CKTstate0 + here->MESAqgs); |
||||
|
*(ckt->CKTstate1 + here->MESAqgd) = |
||||
|
*(ckt->CKTstate0 + here->MESAqgd); |
||||
|
} |
||||
|
error = NIintegrate(ckt,&geq,&ceq,capgs,here->MESAqgs); |
||||
|
if(error) return(error); |
||||
|
ggspp = geq; |
||||
|
cgspp = *(ckt->CKTstate0 + here->MESAcqgs); |
||||
|
cg = cg + cgspp; |
||||
|
error = NIintegrate(ckt,&geq,&ceq,capgd,here->MESAqgd); |
||||
|
if(error) return(error); |
||||
|
ggdpp = geq; |
||||
|
cgdpp = *(ckt->CKTstate0 + here->MESAcqgd); |
||||
|
cg = cg + cgdpp; |
||||
|
cd = cd - cgdpp; |
||||
|
if (ckt->CKTmode & MODEINITTRAN) { |
||||
|
*(ckt->CKTstate1 + here->MESAcqgs) = |
||||
|
*(ckt->CKTstate0 + here->MESAcqgs); |
||||
|
*(ckt->CKTstate1 + here->MESAcqgd) = |
||||
|
*(ckt->CKTstate0 + here->MESAcqgd); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
/* |
||||
|
* check convergence |
||||
|
*/ |
||||
|
if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) { |
||||
|
if( (icheck == 1) |
||||
|
|| (fabs(cghat-cg) >= ckt->CKTreltol* |
||||
|
MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) || |
||||
|
(fabs(cdhat-cd) > ckt->CKTreltol* |
||||
|
MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol) |
||||
|
) { |
||||
|
ckt->CKTnoncon++; |
||||
|
} |
||||
|
} |
||||
|
*(ckt->CKTstate0 + here->MESAvgs) = vgs; |
||||
|
*(ckt->CKTstate0 + here->MESAvgspp) = vgspp; |
||||
|
*(ckt->CKTstate0 + here->MESAvgd) = vgd; |
||||
|
*(ckt->CKTstate0 + here->MESAvgdpp) = vgdpp; |
||||
|
*(ckt->CKTstate0 + here->MESAcg) = cg; |
||||
|
*(ckt->CKTstate0 + here->MESAcd) = cd; |
||||
|
*(ckt->CKTstate0 + here->MESAcgd) = cgd; |
||||
|
*(ckt->CKTstate0 + here->MESAcgs) = cgs; |
||||
|
*(ckt->CKTstate0 + here->MESAgm) = gm; |
||||
|
*(ckt->CKTstate0 + here->MESAgds) = gds; |
||||
|
*(ckt->CKTstate0 + here->MESAggs) = ggs; |
||||
|
*(ckt->CKTstate0 + here->MESAggd) = ggd; |
||||
|
*(ckt->CKTstate0 + here->MESAggspp) = ggspp; |
||||
|
*(ckt->CKTstate0 + here->MESAcgspp) = cgspp; |
||||
|
*(ckt->CKTstate0 + here->MESAggdpp) = ggdpp; |
||||
|
*(ckt->CKTstate0 + here->MESAcgdpp) = cgdpp; |
||||
|
|
||||
|
/* |
||||
|
* load current vector |
||||
|
*/ |
||||
|
load: |
||||
|
ccorr = model->MESAag*(cgs-cgd); |
||||
|
ceqgd = cgd + cgdpp - ggd*vgd - ggdpp*vgdpp; |
||||
|
ceqgs = cgs + cgspp - ggs*vgs - ggspp*vgspp; |
||||
|
cdreq=((cd+cgd+cgdpp)-gds*vds-gm*vgs); |
||||
|
*(ckt->CKTrhs + here->MESAgatePrimeNode) += (-ceqgs-ceqgd); |
||||
|
ceqgd = (cgd-ggd*vgd); |
||||
|
*(ckt->CKTrhs + here->MESAdrainPrimeNode) += (-cdreq+ceqgd+ccorr); |
||||
|
ceqgd = (cgdpp-ggdpp*vgdpp); |
||||
|
*(ckt->CKTrhs + here->MESAdrainPrmPrmNode) += ceqgd; |
||||
|
ceqgs = (cgs-ggs*vgs); |
||||
|
*(ckt->CKTrhs + here->MESAsourcePrimeNode) += (cdreq+ceqgs-ccorr); |
||||
|
ceqgs = (cgspp-ggspp*vgspp); |
||||
|
*(ckt->CKTrhs + here->MESAsourcePrmPrmNode) += ceqgs; |
||||
|
|
||||
|
/* |
||||
|
* load y matrix |
||||
|
*/ |
||||
|
*(here->MESAdrainDrainPtr) += here->MESAdrainConduct; |
||||
|
*(here->MESAsourceSourcePtr) += here->MESAsourceConduct; |
||||
|
*(here->MESAgateGatePtr) += here->MESAgateConduct; |
||||
|
*(here->MESAsourcePrmPrmSourcePrmPrmPtr) += (here->MESAtGi+ggspp); |
||||
|
*(here->MESAdrainPrmPrmDrainPrmPrmPtr) += (here->MESAtGf+ggdpp); |
||||
|
*(here->MESAgatePrimeGatePrimePtr) += (ggd+ggs+here->MESAgateConduct+ggspp+ggdpp); |
||||
|
*(here->MESAdrainPrimeDrainPrimePtr) += (gds+ggd+here->MESAdrainConduct+here->MESAtGf); |
||||
|
*(here->MESAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+here->MESAsourceConduct+here->MESAtGi); |
||||
|
*(here->MESAdrainDrainPrimePtr) -= here->MESAdrainConduct; |
||||
|
*(here->MESAdrainPrimeDrainPtr) -= here->MESAdrainConduct; |
||||
|
*(here->MESAsourceSourcePrimePtr) -= here->MESAsourceConduct; |
||||
|
*(here->MESAsourcePrimeSourcePtr) -= here->MESAsourceConduct; |
||||
|
*(here->MESAgateGatePrimePtr) -= here->MESAgateConduct; |
||||
|
*(here->MESAgatePrimeGatePtr) -= here->MESAgateConduct; |
||||
|
*(here->MESAgatePrimeDrainPrimePtr) -= ggd; |
||||
|
*(here->MESAgatePrimeSourcePrimePtr) -= ggs; |
||||
|
*(here->MESAdrainPrimeGatePrimePtr) += (gm-ggd); |
||||
|
*(here->MESAdrainPrimeSourcePrimePtr) += (-gds-gm); |
||||
|
*(here->MESAsourcePrimeGatePrimePtr) += (-ggs-gm); |
||||
|
*(here->MESAsourcePrimeDrainPrimePtr) -= gds; |
||||
|
*(here->MESAsourcePrimeSourcePrmPrmPtr) -= here->MESAtGi; |
||||
|
*(here->MESAsourcePrmPrmSourcePrimePtr) -= here->MESAtGi; |
||||
|
*(here->MESAgatePrimeSourcePrmPrmPtr) -= ggspp; |
||||
|
*(here->MESAsourcePrmPrmGatePrimePtr) -= ggspp; |
||||
|
*(here->MESAdrainPrimeDrainPrmPrmPtr) -= here->MESAtGf; |
||||
|
*(here->MESAdrainPrmPrmDrainPrimePtr) -= here->MESAtGf; |
||||
|
*(here->MESAgatePrimeDrainPrmPrmPtr) -= ggdpp; |
||||
|
*(here->MESAdrainPrmPrmGatePrimePtr) -= ggdpp; |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
#define ETA (here->MESAtEta) |
||||
|
#define MU0 (here->MESAtMu) |
||||
|
#define RS (here->MESAtRsi) |
||||
|
#define RD (here->MESAtRdi) |
||||
|
#define SIGMA0 (model->MESAsigma0) |
||||
|
#define VSIGMAT (model->MESAvsigmat) |
||||
|
#define VSIGMA (model->MESAvsigma) |
||||
|
#define THETA (model->MESAtheta) |
||||
|
#define VS (model->MESAvs) |
||||
|
#define ND (model->MESAnd) |
||||
|
#define D (model->MESAd) |
||||
|
#define TC (model->MESAtc) |
||||
|
#define MC (model->MESAmc) |
||||
|
#define M0 (model->MESAm) |
||||
|
#define ALPHA (model->MESAalpha) |
||||
|
#define LAMBDA (here->MESAtLambda) |
||||
|
#define NDELTA (model->MESAndelta) |
||||
|
#define TH (model->MESAth) |
||||
|
#define NDU (model->MESAndu) |
||||
|
#define DU (model->MESAdu) |
||||
|
#define NMAX (model->MESAnmax) |
||||
|
#define GAMMA (model->MESAgamma) |
||||
|
|
||||
|
|
||||
|
static void mesa1(MESAmodel *model, MESAinstance *here, double vgs, |
||||
|
double vds, double von, double *cdrain, |
||||
|
double *gm, double *gds, double *capgs, double *capgd) |
||||
|
|
||||
|
{ |
||||
|
|
||||
|
double vt; |
||||
|
double etavth; |
||||
|
double vl; |
||||
|
double rt; |
||||
|
double mu; |
||||
|
double beta; |
||||
|
double vgt; |
||||
|
double vgt0; |
||||
|
double sigma; |
||||
|
double vgte; |
||||
|
double isat; |
||||
|
double isata; |
||||
|
double isatb; |
||||
|
double ns; |
||||
|
double a; |
||||
|
double b; |
||||
|
double c; |
||||
|
double d; |
||||
|
double e; |
||||
|
double f; |
||||
|
double g; |
||||
|
double h; |
||||
|
double m; |
||||
|
double p; |
||||
|
double q; |
||||
|
double r; |
||||
|
double s; |
||||
|
double t; |
||||
|
double u; |
||||
|
double v; |
||||
|
double w; |
||||
|
double temp; |
||||
|
double gch; |
||||
|
double gchi; |
||||
|
double vsate; |
||||
|
double vdse; |
||||
|
double cgc; |
||||
|
double sqrt1; |
||||
|
double delidgch; |
||||
|
double delgchgchi; |
||||
|
double delgchins; |
||||
|
double delnsvgt; |
||||
|
double delnsvgte; |
||||
|
double delvgtevgt; |
||||
|
double delidvsate; |
||||
|
double delvsateisat; |
||||
|
double delisatisata; |
||||
|
double delisatavgte; |
||||
|
double delisatabeta; |
||||
|
double delisatisatb; |
||||
|
double delvsategch; |
||||
|
double delidvds; |
||||
|
double ddevgte; |
||||
|
double dvgtvgs; |
||||
|
double dgchivgt; |
||||
|
double dvgtevds; |
||||
|
double dgchivds; |
||||
|
double disatavgt; |
||||
|
double disatavds; |
||||
|
double disatbvgt; |
||||
|
double dvsatevgt; |
||||
|
double dvsatevds; |
||||
|
double gmmadd; |
||||
|
double gdsmadd; |
||||
|
|
||||
|
|
||||
|
vt = CONSTKoverQ * here->MESAts; |
||||
|
etavth = ETA*vt; |
||||
|
rt = RS+RD; |
||||
|
vgt0 = vgs - von; |
||||
|
s = exp((vgt0-VSIGMAT)/VSIGMA); |
||||
|
sigma = SIGMA0/(1+s); |
||||
|
vgt = vgt0+sigma*vds; |
||||
|
mu = MU0+THETA*vgt; |
||||
|
vl = VS/mu*here->MESAlength; |
||||
|
beta = here->MESAbeta/(model->MESAvpo+3*vl); |
||||
|
u = vgt/vt-1; |
||||
|
t = sqrt(model->MESAdeltaSqr+u*u); |
||||
|
vgte = 0.5*vt*(2+u+t); |
||||
|
a = 2*beta*vgte; |
||||
|
b = exp(-vgt/etavth); |
||||
|
if(vgte > model->MESAvpo) |
||||
|
sqrt1 = 0; |
||||
|
else |
||||
|
sqrt1 = sqrt(1-vgte/model->MESAvpo); |
||||
|
ns = 1.0/(1.0/ND/D/(1-sqrt1) + 1.0/here->MESAn0*b); |
||||
|
if(ns < 1.0e-38) { |
||||
|
*cdrain = 0; |
||||
|
*gm = 0.0; |
||||
|
*gds = 0.0; |
||||
|
*capgs = here->MESAcf; |
||||
|
*capgd = here->MESAcf; |
||||
|
return; |
||||
|
} |
||||
|
gchi = here->MESAgchi0*mu*ns; |
||||
|
gch = gchi/(1+gchi*rt); |
||||
|
f = sqrt(1+2*a*RS); |
||||
|
d = 1+a*RS + f; |
||||
|
e = 1+TC*vgte; |
||||
|
isata = a*vgte/(d*e); |
||||
|
isatb = here->MESAisatb0*mu*exp(vgt/etavth); |
||||
|
isat = isata*isatb/(isata+isatb); |
||||
|
vsate = isat/gch; |
||||
|
vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC); |
||||
|
m = M0+ALPHA*vgte; |
||||
|
g = pow(vds/vsate,m); |
||||
|
h = pow(1+g,1.0/m); |
||||
|
here->MESAdelidgch0 = vds/h; |
||||
|
delidgch = here->MESAdelidgch0*(1+LAMBDA*vds); |
||||
|
*cdrain = gch*delidgch; |
||||
|
if(vgt > model->MESAvpo) |
||||
|
temp = 0; |
||||
|
else |
||||
|
temp = sqrt(1-vgt/model->MESAvpo); |
||||
|
cgc = W*L*EPSILONGAAS/(temp+b)/D; |
||||
|
c = (vsate-vdse)/(2*vsate-vdse); |
||||
|
c = c*c; |
||||
|
*capgs = here->MESAcf+2.0/3.0*cgc*(1-c); |
||||
|
c = vsate/(2*vsate-vdse); |
||||
|
c = c*c; |
||||
|
*capgd = here->MESAcf+2.0/3.0*cgc*(1-c); |
||||
|
temp = 1+gchi*rt; |
||||
|
delgchgchi = 1.0/(temp*temp); |
||||
|
delgchins = here->MESAgchi0*mu; |
||||
|
delnsvgt = ns*ns*1.0/here->MESAn0/etavth*b; |
||||
|
q = 1 - sqrt1; |
||||
|
if(sqrt1 == 0) |
||||
|
delnsvgte = 0; |
||||
|
else |
||||
|
delnsvgte = 0.5*ns*ns/(model->MESAvpo*ND*D*sqrt1*q*q); |
||||
|
delvgtevgt = 0.5*(1+u/t); |
||||
|
here->MESAdelidvds0 = gch/h; |
||||
|
if(vds != 0.0) |
||||
|
here->MESAdelidvds1 = (*cdrain)*pow(vds/vsate,m-1)/(vsate*(1+g)); |
||||
|
else |
||||
|
here->MESAdelidvds1 = 0.0; |
||||
|
delidvds = here->MESAdelidvds0*(1+2*LAMBDA*vds) - here->MESAdelidvds1; |
||||
|
delidvsate = (*cdrain)*g/(vsate*(1+g)); |
||||
|
delvsateisat = 1.0/gch; |
||||
|
r = isata+isatb; |
||||
|
r = r*r; |
||||
|
delisatisata = isatb*isatb/r; |
||||
|
v = 1.0+1.0/f; |
||||
|
ddevgte = 2*beta*RS*v*e+d*TC; |
||||
|
temp = d*d*e*e; |
||||
|
delisatavgte = (2*a*d*e - a*vgte*ddevgte)/temp; |
||||
|
delisatabeta = 2*vgte*vgte*(d*e-a*e*RS*v)/temp; |
||||
|
delisatisatb = isata*isata/r; |
||||
|
delvsategch = -vsate/gch; |
||||
|
dvgtvgs = 1 - SIGMA0*vds*s/VSIGMA/((1+s)*(1+s)); |
||||
|
temp = here->MESAgchi0*ns*THETA; |
||||
|
dgchivgt = delgchins*(delnsvgte*delvgtevgt+delnsvgt)+temp; |
||||
|
dvgtevds = delvgtevgt*sigma; |
||||
|
dgchivds = delgchins*(delnsvgte*dvgtevds+delnsvgt*sigma)+temp*sigma; |
||||
|
temp = delisatabeta*3*beta*vl*THETA/(mu*(model->MESAvpo+3*vl)); |
||||
|
disatavgt = delisatavgte*delvgtevgt+temp; |
||||
|
disatavds = delisatavgte*dvgtevds+temp*sigma; |
||||
|
disatbvgt = isatb/etavth+isatb/mu*THETA; |
||||
|
p = delgchgchi*dgchivgt; |
||||
|
w = delgchgchi*dgchivds; |
||||
|
dvsatevgt = delvsateisat*(delisatisata*disatavgt+delisatisatb*disatbvgt)+delvsategch*p; |
||||
|
dvsatevds = delvsateisat*(delisatisata*disatavds+delisatisatb*disatbvgt*sigma)+delvsategch*w; |
||||
|
if(ALPHA != 0) { |
||||
|
if(vds == 0) |
||||
|
gmmadd = 0; |
||||
|
else |
||||
|
gmmadd = (*cdrain)*(log(1+g)/(m*m)-g*log(vds/vsate)/(m*(1+g)))* |
||||
|
ALPHA*delvgtevgt; |
||||
|
gdsmadd = gmmadd*sigma; |
||||
|
} else { |
||||
|
gmmadd = 0; |
||||
|
gdsmadd = 0; |
||||
|
} |
||||
|
here->MESAgm0 = p; |
||||
|
here->MESAgm1 = delidvsate*dvsatevgt; |
||||
|
here->MESAgm2 = dvgtvgs; |
||||
|
g = delidgch*p+here->MESAgm1; |
||||
|
*gm = (g+gmmadd)*dvgtvgs; |
||||
|
here->MESAgds0 = delidvsate*dvsatevds+delidgch*w+gdsmadd; |
||||
|
*gds = delidvds+here->MESAgds0; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
static void mesa2(MESAmodel *model, MESAinstance *here, double vgs, |
||||
|
double vds, double von, double *cdrain, double *gm, |
||||
|
double *gds, double *capgs, double *capgd) |
||||
|
|
||||
|
{ |
||||
|
|
||||
|
double vt; |
||||
|
double rt; |
||||
|
double vgt; |
||||
|
double etavth; |
||||
|
double vgt0; |
||||
|
double sigma; |
||||
|
double vgte; |
||||
|
double isat; |
||||
|
double isata; |
||||
|
double isatb; |
||||
|
double nsa; |
||||
|
double nsb; |
||||
|
double ns; |
||||
|
double a; |
||||
|
double b; |
||||
|
double c; |
||||
|
double d; |
||||
|
double e; |
||||
|
double f; |
||||
|
double g; |
||||
|
double h; |
||||
|
double p; |
||||
|
double q; |
||||
|
double r; |
||||
|
double s; |
||||
|
double t; |
||||
|
double gch; |
||||
|
double gchi; |
||||
|
double vsate; |
||||
|
double vdse; |
||||
|
double ca; |
||||
|
double cb; |
||||
|
double cgc; |
||||
|
double delidgch; |
||||
|
double delgchgchi; |
||||
|
double delgchins; |
||||
|
double delnsvgt; |
||||
|
double delnsbvgt; |
||||
|
double delnsavgte; |
||||
|
double delvgtevgt; |
||||
|
double delidvsate; |
||||
|
double delvsateisat; |
||||
|
double delisatisata; |
||||
|
double delisatavgte; |
||||
|
double delisatisatb; |
||||
|
double delvsategch; |
||||
|
double delisatbvgt; |
||||
|
double delvsatevgt; |
||||
|
double delidvds; |
||||
|
double ddevgte; |
||||
|
double delvgtvgs; |
||||
|
|
||||
|
|
||||
|
vt = CONSTKoverQ * here->MESAts; |
||||
|
etavth = ETA*vt; |
||||
|
rt = RS+RD; |
||||
|
vgt0 = vgs - von; |
||||
|
s = exp((vgt0-VSIGMAT)/VSIGMA); |
||||
|
sigma = SIGMA0/(1+s); |
||||
|
vgt = vgt0+sigma*vds; |
||||
|
t = vgt/vt-1; |
||||
|
q = sqrt(model->MESAdeltaSqr+t*t); |
||||
|
vgte = 0.5*vt*(2+t+q); |
||||
|
a = 2*model->MESAbeta*vgte; |
||||
|
if(vgt > model->MESAvpod) { |
||||
|
if(vgte > model->MESAvpo) { |
||||
|
nsa = NDELTA*TH + NDU*DU; |
||||
|
ca = EPSILONGAAS/DU; |
||||
|
delnsavgte = 0; |
||||
|
} else { |
||||
|
r = sqrt((model->MESAvpo-vgte)/model->MESAvpou); |
||||
|
nsa = NDELTA*TH + NDU*DU*(1-r); |
||||
|
ca = EPSILONGAAS/DU/r; |
||||
|
delnsavgte = NDU*DU/model->MESAvpou/2.0/r; |
||||
|
} |
||||
|
} else { |
||||
|
if(model->MESAvpod - vgte < 0) { |
||||
|
nsa = NDELTA*TH*(1-DU/TH); |
||||
|
ca = EPSILONGAAS/DU; |
||||
|
delnsavgte = 0; |
||||
|
} else { |
||||
|
r = sqrt(1+NDU/NDELTA*(model->MESAvpod - vgte)/model->MESAvpou); |
||||
|
nsa = NDELTA*TH*(1-DU/TH*(r-1)); |
||||
|
ca = EPSILONGAAS/DU/r; |
||||
|
delnsavgte = DU*NDU/2.0/model->MESAvpou/r; |
||||
|
} |
||||
|
} |
||||
|
b = exp(vgt/etavth); |
||||
|
cb = EPSILONGAAS/(DU+TH)*b; |
||||
|
nsb = here->MESAnsb0*b; |
||||
|
delnsbvgt = nsb/etavth; |
||||
|
ns = nsa*nsb/(nsa+nsb); |
||||
|
if(ns < 1.0e-38) { |
||||
|
*cdrain = 0; |
||||
|
*gm = 0.0; |
||||
|
*gds = 0.0; |
||||
|
*capgs = here->MESAcf; |
||||
|
*capgd = here->MESAcf; |
||||
|
return; |
||||
|
} |
||||
|
gchi = here->MESAgchi0*ns; |
||||
|
gch = gchi/(1+gchi*rt); |
||||
|
f = sqrt(1+2*a*RS); |
||||
|
d = 1+a*RS + f; |
||||
|
e = 1+TC*vgte; |
||||
|
isata = a*vgte/d/e; |
||||
|
isatb = here->MESAisatb0*b; |
||||
|
isat = isata*isatb/(isata+isatb); |
||||
|
vsate = isat/gch; |
||||
|
vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC); |
||||
|
g = pow(vds/vsate,M0); |
||||
|
h = pow(1+g,1.0/M0); |
||||
|
here->MESAdelidgch0 = vds/h; |
||||
|
delidgch = here->MESAdelidgch0*(1+LAMBDA*vds); |
||||
|
*cdrain = gch*delidgch; |
||||
|
cgc = W*L*ca*cb/(ca+cb); |
||||
|
c = (vsate-vdse)/(2*vsate-vdse); |
||||
|
c = c*c; |
||||
|
*capgs = here->MESAcf+2.0/3.0*cgc*(1-c); |
||||
|
c = vsate/(2*vsate-vdse); |
||||
|
c = c*c; |
||||
|
*capgd = here->MESAcf+2.0/3.0*cgc*(1-c); |
||||
|
c = vgt/vt-1; |
||||
|
delvgtevgt = 0.5*(1+t/q); |
||||
|
here->MESAdelidvds0 = gch/h; |
||||
|
if(vds != 0.0) |
||||
|
here->MESAdelidvds1 = (*cdrain)*pow(vds/vsate,M0-1)/vsate/(1+g); |
||||
|
else |
||||
|
here->MESAdelidvds1 = 0.0; |
||||
|
delidvds = here->MESAdelidvds0*(1+2*LAMBDA*vds) - |
||||
|
here->MESAdelidvds1; |
||||
|
delgchgchi = 1.0/(1+gchi*rt)/(1+gchi*rt); |
||||
|
delgchins = here->MESAgchi0; |
||||
|
r = nsa+nsb; |
||||
|
r = r*r; |
||||
|
delnsvgt = (nsb*nsb*delvgtevgt*delnsavgte + nsa*nsa*delnsbvgt)/r; |
||||
|
delidvsate = (*cdrain)*g/vsate/(1+g); |
||||
|
delvsateisat = 1.0/gch; |
||||
|
r = isata+isatb; |
||||
|
r = r*r; |
||||
|
delisatisata = isatb*isatb/r; |
||||
|
ddevgte = 2*model->MESAbeta*RS*(1+1.0/f)*e+d*TC; |
||||
|
delisatavgte = (2*a*d*e - a*vgte*ddevgte)/d/d/e/e; |
||||
|
delisatisatb = isata*isata/r; |
||||
|
delisatbvgt = isatb/etavth; |
||||
|
delvsategch = -vsate/gch; |
||||
|
delvgtvgs = 1-SIGMA0*vds*s/VSIGMA/(1+s)/(1+s); |
||||
|
p = delgchgchi*delgchins*delnsvgt; |
||||
|
delvsatevgt = delvsateisat*(delisatisata*delisatavgte*delvgtevgt + |
||||
|
delisatisatb*delisatbvgt) + delvsategch*p; |
||||
|
here->MESAgm0 = p; |
||||
|
here->MESAgm1 = delidvsate*delvsatevgt; |
||||
|
here->MESAgm2 = delvgtvgs; |
||||
|
g = delidgch*p + here->MESAgm1; |
||||
|
*gm = g*delvgtvgs; |
||||
|
here->MESAgds0 = g*sigma; |
||||
|
*gds = delidvds+here->MESAgds0; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
static void mesa3(MESAmodel *model, MESAinstance *here, double vgs, |
||||
|
double vds, double von, double *cdrain, double *gm, |
||||
|
double *gds, double *capgs, double *capgd) |
||||
|
|
||||
|
{ |
||||
|
|
||||
|
double vt; |
||||
|
double vgt; |
||||
|
double vgt0; |
||||
|
double sigma; |
||||
|
double vgte; |
||||
|
double isat; |
||||
|
double isatm; |
||||
|
double ns; |
||||
|
double nsm; |
||||
|
double a; |
||||
|
double b; |
||||
|
double c; |
||||
|
double d; |
||||
|
double e; |
||||
|
double g; |
||||
|
double h; |
||||
|
double p; |
||||
|
double q; |
||||
|
double s; |
||||
|
double t; |
||||
|
double u; |
||||
|
double temp; |
||||
|
double etavth; |
||||
|
double gch; |
||||
|
double gchi; |
||||
|
double gchim; |
||||
|
double vsate; |
||||
|
double vdse; |
||||
|
double cgc; |
||||
|
double cgcm; |
||||
|
double rt; |
||||
|
double vl; |
||||
|
double delidgch; |
||||
|
double delgchgchi; |
||||
|
double delgchins; |
||||
|
double delnsnsm; |
||||
|
double delnsmvgt; |
||||
|
double delvgtevgt; |
||||
|
double delidvsate; |
||||
|
double delvsateisat; |
||||
|
double delisatisatm; |
||||
|
double delisatmvgte; |
||||
|
double delisatmgchim; |
||||
|
double delvsategch; |
||||
|
double delidvds; |
||||
|
double delvgtvgs; |
||||
|
double delvsatevgt; |
||||
|
|
||||
|
vt = CONSTKoverQ * here->MESAts; |
||||
|
etavth = ETA*vt; |
||||
|
vl = VS/MU0*L; |
||||
|
rt = RS+RD; |
||||
|
vgt0 = vgs - von; |
||||
|
s = exp((vgt0-VSIGMAT)/VSIGMA); |
||||
|
sigma = SIGMA0/(1+s); |
||||
|
vgt = vgt0+sigma*vds; |
||||
|
u = 0.5*vgt/vt-1; |
||||
|
t = sqrt(model->MESAdeltaSqr+u*u); |
||||
|
vgte = vt*(2+u+t); |
||||
|
b = exp(vgt/etavth); |
||||
|
nsm = 2*here->MESAn0*log(1+0.5*b); |
||||
|
if(nsm < 1.0e-38) { |
||||
|
*cdrain = 0; |
||||
|
*gm = 0.0; |
||||
|
*gds = 0.0; |
||||
|
*capgs = here->MESAcf; |
||||
|
*capgd = here->MESAcf; |
||||
|
return; |
||||
|
} |
||||
|
c = pow(nsm/NMAX,GAMMA); |
||||
|
q = pow(1+c,1.0/GAMMA); |
||||
|
ns = nsm/q; |
||||
|
gchi = here->MESAgchi0*ns; |
||||
|
gch = gchi/(1+gchi*rt); |
||||
|
gchim = here->MESAgchi0*nsm; |
||||
|
h = sqrt(1+2*gchim*model->MESArsi + vgte*vgte/(vl*vl)); |
||||
|
p = 1+gchim*RS+h; |
||||
|
isatm = gchim*vgte/p; |
||||
|
g = pow(isatm/here->MESAimax,GAMMA); |
||||
|
isat = isatm/pow(1+g,1/GAMMA); |
||||
|
vsate = isat/gch; |
||||
|
vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC); |
||||
|
d = pow(vds/vsate,M0); |
||||
|
e = pow(1+d,1.0/M0); |
||||
|
delidgch = vds*(1+LAMBDA*vds)/e; |
||||
|
*cdrain = gch*delidgch; |
||||
|
cgcm = 1.0/(1/model->MESAcas*D/model->MESAepsi + |
||||
|
1/model->MESAcbs*etavth/CHARGE/here->MESAn0*exp(-vgt/etavth)); |
||||
|
cgc = W*L*cgcm/pow(1+c,1+1.0/GAMMA); |
||||
|
/* |
||||
|
{ |
||||
|
char buf[256]; |
||||
|
void far pascal OutputDebugString(char*); |
||||
|
sprintf(buf,"\n%f\t%e\0",vgs,cgc); |
||||
|
OutputDebugString(buf); |
||||
|
} |
||||
|
*/ |
||||
|
a = (vsate-vdse)/(2*vsate-vdse); |
||||
|
a = a*a; |
||||
|
temp = 2.0/3.0; |
||||
|
*capgs = here->MESAcf+temp*cgc*(1-a); |
||||
|
a = vsate/(2*vsate-vdse); |
||||
|
a = a*a; |
||||
|
*capgd = here->MESAcf+temp*cgc*(1-a); |
||||
|
delidvsate = (*cdrain)*d/vsate/(1+d); |
||||
|
delidvds = gch*(1+2*LAMBDA*vds)/e-(*cdrain)* |
||||
|
pow(vds/vsate,M0-1)/(vsate*(1+d)); |
||||
|
a = 1+gchi*rt; |
||||
|
delgchgchi = 1.0/(a*a); |
||||
|
delgchins = here->MESAgchi0; |
||||
|
delnsnsm = ns/nsm*(1-c/(1+c)); |
||||
|
delnsmvgt = here->MESAn0/etavth/(1.0/b + 0.5); |
||||
|
delvgtevgt = 0.5*(1+u/t); |
||||
|
delvsateisat = 1.0/gch; |
||||
|
delisatisatm = isat/isatm*(1-g/(1+g)); |
||||
|
delisatmvgte = gchim*(p - vgte*vgte/(vl*vl*h))/(p*p); |
||||
|
delvsategch = -vsate/gch; |
||||
|
delisatmgchim = vgte*(p - gchim*RS*(1+1.0/h))/(p*p); |
||||
|
delvgtvgs = 1-vds*SIGMA0/VSIGMA*s/((1+s)*(1+s)); |
||||
|
p = delgchgchi*delgchins*delnsnsm*delnsmvgt; |
||||
|
delvsatevgt = (delvsateisat*delisatisatm*(delisatmvgte*delvgtevgt + |
||||
|
delisatmgchim*here->MESAgchi0*delnsmvgt)+delvsategch*p); |
||||
|
g = delidgch*p + delidvsate*delvsatevgt; |
||||
|
*gm = g*delvgtvgs; |
||||
|
*gds = delidvds + g*sigma; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,223 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1987 Thomas L. Quarles |
||||
|
**********/ |
||||
|
/* |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/* ARGSUSED */ |
||||
|
int |
||||
|
MESAmAsk(ckt,inst,which,value) |
||||
|
CKTcircuit *ckt; |
||||
|
GENmodel *inst; |
||||
|
int which; |
||||
|
IFvalue *value; |
||||
|
{ |
||||
|
MESAmodel *here = (MESAmodel*)inst; |
||||
|
switch(which) { |
||||
|
case MESA_MOD_VTO: |
||||
|
value->rValue = here->MESAthreshold; |
||||
|
return (OK); |
||||
|
case MESA_MOD_VS: |
||||
|
value->rValue = here->MESAvs; |
||||
|
return (OK); |
||||
|
case MESA_MOD_ALPHA: |
||||
|
value->rValue = here->MESAalpha; |
||||
|
return (OK); |
||||
|
case MESA_MOD_BETA: |
||||
|
value->rValue = here->MESAbeta; |
||||
|
return (OK); |
||||
|
case MESA_MOD_LAMBDA: |
||||
|
value->rValue = here->MESAlambda; |
||||
|
return (OK); |
||||
|
case MESA_MOD_RG: |
||||
|
value->rValue = here->MESAgateResist; |
||||
|
return (OK); |
||||
|
case MESA_MOD_RD: |
||||
|
value->rValue = here->MESAdrainResist; |
||||
|
return (OK); |
||||
|
case MESA_MOD_RS: |
||||
|
value->rValue = here->MESAsourceResist; |
||||
|
return (OK); |
||||
|
case MESA_MOD_RI: |
||||
|
value->rValue = here->MESAri; |
||||
|
return (OK); |
||||
|
case MESA_MOD_RF: |
||||
|
value->rValue = here->MESArf; |
||||
|
return (OK); |
||||
|
case MESA_MOD_RDI: |
||||
|
value->rValue = here->MESArdi; |
||||
|
return (OK); |
||||
|
case MESA_MOD_RSI: |
||||
|
value->rValue = here->MESArsi; |
||||
|
return (OK); |
||||
|
case MESA_MOD_PHIB: |
||||
|
value->rValue = here->MESAphib; |
||||
|
return (OK); |
||||
|
case MESA_MOD_PHIB1: |
||||
|
value->rValue = here->MESAphib1; |
||||
|
return (OK); |
||||
|
case MESA_MOD_ASTAR: |
||||
|
value->rValue = here->MESAastar; |
||||
|
return (OK); |
||||
|
case MESA_MOD_GGR: |
||||
|
value->rValue = here->MESAggr; |
||||
|
return (OK); |
||||
|
case MESA_MOD_DEL: |
||||
|
value->rValue = here->MESAdel; |
||||
|
return (OK); |
||||
|
case MESA_MOD_XCHI: |
||||
|
value->rValue = here->MESAxchi; |
||||
|
return (OK); |
||||
|
case MESA_MOD_N: |
||||
|
value->rValue = here->MESAn; |
||||
|
return (OK); |
||||
|
case MESA_MOD_ETA: |
||||
|
value->rValue = here->MESAeta; |
||||
|
return (OK); |
||||
|
case MESA_MOD_M: |
||||
|
value->rValue = here->MESAm; |
||||
|
return (OK); |
||||
|
case MESA_MOD_MC: |
||||
|
value->rValue = here->MESAmc; |
||||
|
return (OK); |
||||
|
case MESA_MOD_SIGMA0: |
||||
|
value->rValue = here->MESAsigma0; |
||||
|
return (OK); |
||||
|
case MESA_MOD_VSIGMAT: |
||||
|
value->rValue = here->MESAvsigmat; |
||||
|
return (OK); |
||||
|
case MESA_MOD_VSIGMA: |
||||
|
value->rValue = here->MESAvsigma; |
||||
|
return (OK); |
||||
|
case MESA_MOD_MU: |
||||
|
value->rValue = here->MESAmu; |
||||
|
return (OK); |
||||
|
case MESA_MOD_MU1: |
||||
|
value->rValue = here->MESAmu1; |
||||
|
return (OK); |
||||
|
case MESA_MOD_MU2: |
||||
|
value->rValue = here->MESAmu2; |
||||
|
return (OK); |
||||
|
case MESA_MOD_D: |
||||
|
value->rValue = here->MESAd; |
||||
|
return (OK); |
||||
|
case MESA_MOD_ND: |
||||
|
value->rValue = here->MESAnd; |
||||
|
return (OK); |
||||
|
case MESA_MOD_DELTA: |
||||
|
value->rValue = here->MESAdelta; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TC: |
||||
|
value->rValue = here->MESAtc; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TVTO: |
||||
|
value->rValue = here->MESAtvto; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TLAMBDA: |
||||
|
value->rValue = here->MESAtlambda; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TETA0: |
||||
|
value->rValue = here->MESAteta0; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TETA1: |
||||
|
value->rValue = here->MESAteta1; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TMU: |
||||
|
value->rValue = here->MESAtmu; |
||||
|
return (OK); |
||||
|
case MESA_MOD_XTM0: |
||||
|
value->rValue = here->MESAxtm0; |
||||
|
return (OK); |
||||
|
case MESA_MOD_XTM1: |
||||
|
value->rValue = here->MESAxtm1; |
||||
|
return (OK); |
||||
|
case MESA_MOD_XTM2: |
||||
|
value->rValue = here->MESAxtm2; |
||||
|
return (OK); |
||||
|
case MESA_MOD_KS: |
||||
|
value->rValue = here->MESAks; |
||||
|
return (OK); |
||||
|
case MESA_MOD_VSG: |
||||
|
value->rValue = here->MESAvsg; |
||||
|
return (OK); |
||||
|
case MESA_MOD_LAMBDAHF: |
||||
|
value->rValue = here->MESAlambdahf; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TF: |
||||
|
value->rValue = here->MESAtf; |
||||
|
return (OK); |
||||
|
case MESA_MOD_FLO: |
||||
|
value->rValue = here->MESAflo; |
||||
|
return (OK); |
||||
|
case MESA_MOD_DELFO: |
||||
|
value->rValue = here->MESAdelfo; |
||||
|
return (OK); |
||||
|
case MESA_MOD_AG: |
||||
|
value->rValue = here->MESAag; |
||||
|
return (OK); |
||||
|
case MESA_MOD_THETA: |
||||
|
value->rValue = here->MESAtheta; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TC1: |
||||
|
value->rValue = here->MESAtc1; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TC2: |
||||
|
value->rValue = here->MESAtc2; |
||||
|
return (OK); |
||||
|
case MESA_MOD_ZETA: |
||||
|
value->rValue = here->MESAzeta; |
||||
|
return (OK); |
||||
|
case MESA_MOD_DU: |
||||
|
value->rValue = here->MESAdu; |
||||
|
return (OK); |
||||
|
|
||||
|
|
||||
|
|
||||
|
case MESA_MOD_NDU: |
||||
|
value->rValue = here->MESAndu; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TH: |
||||
|
value->rValue = here->MESAth; |
||||
|
return (OK); |
||||
|
case MESA_MOD_NDELTA: |
||||
|
value->rValue = here->MESAndelta; |
||||
|
return (OK); |
||||
|
case MESA_MOD_LEVEL: |
||||
|
value->rValue = here->MESAlevel; |
||||
|
return (OK); |
||||
|
case MESA_MOD_NMAX: |
||||
|
value->rValue = here->MESAnmax; |
||||
|
return (OK); |
||||
|
case MESA_MOD_GAMMA: |
||||
|
value->rValue = here->MESAgamma; |
||||
|
return (OK); |
||||
|
case MESA_MOD_EPSI: |
||||
|
value->rValue = here->MESAepsi; |
||||
|
return (OK); |
||||
|
case MESA_MOD_CBS: |
||||
|
value->rValue = here->MESAcbs; |
||||
|
return (OK); |
||||
|
case MESA_MOD_CAS: |
||||
|
value->rValue = here->MESAcas; |
||||
|
return (OK); |
||||
|
case MESA_MOD_TYPE: |
||||
|
if (here->MESAtype == NMF) |
||||
|
value->sValue = "nmf"; |
||||
|
else |
||||
|
value->sValue = "pmf"; |
||||
|
default: |
||||
|
return (E_BADPARM); |
||||
|
} |
||||
|
/* NOTREACHED */ |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 S. Hwang |
||||
|
**********/ |
||||
|
/* |
||||
|
Imported into mesa model: 2001 Paolo Nenzi |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "mesadefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MESAmDelete(inModel,modname,kill) |
||||
|
GENmodel **inModel; |
||||
|
IFuid modname; |
||||
|
GENmodel *kill; |
||||
|
{ |
||||
|
MESAmodel **model = (MESAmodel**)inModel; |
||||
|
MESAmodel *modfast = (MESAmodel*)kill; |
||||
|
MESAinstance *here; |
||||
|
MESAinstance *prev = NULL; |
||||
|
MESAmodel **oldmod; |
||||
|
oldmod = model; |
||||
|
for( ; *model ; model = &((*model)->MESAnextModel)) { |
||||
|
if( (*model)->MESAmodName == modname || |
||||
|
(modfast && *model == modfast) ) goto delgot; |
||||
|
oldmod = model; |
||||
|
} |
||||
|
return(E_NOMOD); |
||||
|
|
||||
|
delgot: |
||||
|
*oldmod = (*model)->MESAnextModel; /* cut deleted device out of list */ |
||||
|
for(here = (*model)->MESAinstances ; here ; here = here->MESAnextInstance) { |
||||
|
if(prev) FREE(prev); |
||||
|
prev = here; |
||||
|
} |
||||
|
if(prev) FREE(prev); |
||||
|
FREE(*model); |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,273 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "const.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MESAmParam(param,value,inModel) |
||||
|
int param; |
||||
|
IFvalue *value; |
||||
|
GENmodel *inModel; |
||||
|
{ |
||||
|
MESAmodel *model = (MESAmodel*)inModel; |
||||
|
switch(param) { |
||||
|
case MESA_MOD_VTO: |
||||
|
model->MESAthresholdGiven = TRUE; |
||||
|
model->MESAthreshold = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_BETA: |
||||
|
model->MESAbetaGiven = TRUE; |
||||
|
model->MESAbeta = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_VS: |
||||
|
model->MESAvsGiven = TRUE; |
||||
|
model->MESAvs = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_LAMBDA: |
||||
|
model->MESAlambdaGiven = TRUE; |
||||
|
model->MESAlambda = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_RD: |
||||
|
model->MESAdrainResistGiven = TRUE; |
||||
|
model->MESAdrainResist = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_RS: |
||||
|
model->MESAsourceResistGiven = TRUE; |
||||
|
model->MESAsourceResist = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_RG: |
||||
|
model->MESAgateResistGiven = TRUE; |
||||
|
model->MESAgateResist = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_RI: |
||||
|
model->MESAriGiven = TRUE; |
||||
|
model->MESAri = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_RF: |
||||
|
model->MESArfGiven = TRUE; |
||||
|
model->MESArf = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_RDI: |
||||
|
model->MESArdiGiven = TRUE; |
||||
|
model->MESArdi = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_RSI: |
||||
|
model->MESArsiGiven = TRUE; |
||||
|
model->MESArsi = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_PHIB: |
||||
|
model->MESAphibGiven = TRUE; |
||||
|
model->MESAphib = value->rValue*CHARGE; |
||||
|
break; |
||||
|
case MESA_MOD_PHIB1: |
||||
|
model->MESAphib1Given = TRUE; |
||||
|
model->MESAphib1 = value->rValue*CHARGE; |
||||
|
break; |
||||
|
case MESA_MOD_ASTAR: |
||||
|
model->MESAastarGiven = TRUE; |
||||
|
model->MESAastar = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_GGR: |
||||
|
model->MESAggrGiven = TRUE; |
||||
|
model->MESAggr = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_DEL: |
||||
|
model->MESAdelGiven = TRUE; |
||||
|
model->MESAdel = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_XCHI: |
||||
|
model->MESAxchiGiven = TRUE; |
||||
|
model->MESAxchi = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_N: |
||||
|
model->MESAnGiven = TRUE; |
||||
|
model->MESAn = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_ETA: |
||||
|
model->MESAetaGiven = TRUE; |
||||
|
model->MESAeta = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_M: |
||||
|
model->MESAmGiven = TRUE; |
||||
|
model->MESAm = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_MC: |
||||
|
model->MESAmcGiven = TRUE; |
||||
|
model->MESAmc = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_ALPHA: |
||||
|
model->MESAalphaGiven = TRUE; |
||||
|
model->MESAalpha = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_SIGMA0: |
||||
|
model->MESAsigma0Given = TRUE; |
||||
|
model->MESAsigma0 = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_VSIGMAT: |
||||
|
model->MESAvsigmatGiven = TRUE; |
||||
|
model->MESAvsigmat = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_VSIGMA: |
||||
|
model->MESAvsigmaGiven = TRUE; |
||||
|
model->MESAvsigma = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_MU: |
||||
|
model->MESAmuGiven = TRUE; |
||||
|
model->MESAmu = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_THETA: |
||||
|
model->MESAthetaGiven = TRUE; |
||||
|
model->MESAtheta = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_MU1: |
||||
|
model->MESAmu1Given = TRUE; |
||||
|
model->MESAmu1 = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_MU2: |
||||
|
model->MESAmu2Given = TRUE; |
||||
|
model->MESAmu2 = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_D: |
||||
|
model->MESAdGiven = TRUE; |
||||
|
model->MESAd = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_ND: |
||||
|
model->MESAndGiven = TRUE; |
||||
|
model->MESAnd = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_DU: |
||||
|
model->MESAduGiven = TRUE; |
||||
|
model->MESAdu = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_NDU: |
||||
|
model->MESAnduGiven = TRUE; |
||||
|
model->MESAndu = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_TH: |
||||
|
model->MESAthGiven = TRUE; |
||||
|
model->MESAth = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_NDELTA: |
||||
|
model->MESAndeltaGiven = TRUE; |
||||
|
model->MESAndelta = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_DELTA: |
||||
|
model->MESAdeltaGiven = TRUE; |
||||
|
model->MESAdelta = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_TC: |
||||
|
model->MESAtcGiven = TRUE; |
||||
|
model->MESAtc = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_NMF: |
||||
|
break; |
||||
|
case MESA_MOD_TVTO: |
||||
|
model->MESAtvtoGiven = TRUE; |
||||
|
model->MESAtvto = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_TLAMBDA: |
||||
|
model->MESAtlambdaGiven = TRUE; |
||||
|
model->MESAtlambda = value->rValue+CONSTCtoK; |
||||
|
break; |
||||
|
case MESA_MOD_TETA0: |
||||
|
model->MESAteta0Given = TRUE; |
||||
|
model->MESAteta0 = value->rValue+CONSTCtoK; |
||||
|
break; |
||||
|
case MESA_MOD_TETA1: |
||||
|
model->MESAteta1Given = TRUE; |
||||
|
model->MESAteta1 = value->rValue+CONSTCtoK; |
||||
|
break; |
||||
|
case MESA_MOD_TMU: |
||||
|
model->MESAtmuGiven = TRUE; |
||||
|
model->MESAtmu = value->rValue+CONSTCtoK; |
||||
|
break; |
||||
|
case MESA_MOD_XTM0: |
||||
|
model->MESAxtm0Given = TRUE; |
||||
|
model->MESAxtm0 = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_XTM1: |
||||
|
model->MESAxtm1Given = TRUE; |
||||
|
model->MESAxtm1 = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_XTM2: |
||||
|
model->MESAxtm2Given = TRUE; |
||||
|
model->MESAxtm2 = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_KS: |
||||
|
model->MESAksGiven = TRUE; |
||||
|
model->MESAks = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_VSG: |
||||
|
model->MESAvsgGiven = TRUE; |
||||
|
model->MESAvsg = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_LAMBDAHF: |
||||
|
model->MESAlambdahfGiven = TRUE; |
||||
|
model->MESAlambdahf = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_TF: |
||||
|
model->MESAtfGiven = TRUE; |
||||
|
model->MESAtf = value->rValue+CONSTCtoK; |
||||
|
break; |
||||
|
case MESA_MOD_FLO: |
||||
|
model->MESAfloGiven = TRUE; |
||||
|
model->MESAflo = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_DELFO: |
||||
|
model->MESAdelfoGiven = TRUE; |
||||
|
model->MESAdelfo = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_AG: |
||||
|
model->MESAagGiven = TRUE; |
||||
|
model->MESAag = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_TC1: |
||||
|
model->MESAtc1Given = TRUE; |
||||
|
model->MESAtc1 = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_TC2: |
||||
|
model->MESAtc2Given = TRUE; |
||||
|
model->MESAtc2 = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_ZETA: |
||||
|
model->MESAzetaGiven = TRUE; |
||||
|
model->MESAzeta = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_LEVEL: |
||||
|
model->MESAlevelGiven = TRUE; |
||||
|
model->MESAlevel = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_NMAX: |
||||
|
model->MESAnmaxGiven = TRUE; |
||||
|
model->MESAnmax = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_GAMMA: |
||||
|
model->MESAgammaGiven = TRUE; |
||||
|
model->MESAgamma = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_EPSI: |
||||
|
model->MESAepsiGiven = TRUE; |
||||
|
model->MESAepsi = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_CBS: |
||||
|
model->MESAcbsGiven = TRUE; |
||||
|
model->MESAcbs = value->rValue; |
||||
|
break; |
||||
|
case MESA_MOD_CAS: |
||||
|
model->MESAcasGiven = TRUE; |
||||
|
model->MESAcas = value->rValue; |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "const.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/* ARGSUSED */ |
||||
|
int |
||||
|
MESAparam(param,value,inst,select) |
||||
|
int param; |
||||
|
IFvalue *value; |
||||
|
GENinstance *inst; |
||||
|
IFvalue *select; |
||||
|
{ |
||||
|
MESAinstance *here = (MESAinstance*)inst; |
||||
|
switch(param) { |
||||
|
case MESA_LENGTH: |
||||
|
here->MESAlength = value->rValue; |
||||
|
here->MESAlengthGiven = TRUE; |
||||
|
break; |
||||
|
case MESA_WIDTH: |
||||
|
here->MESAwidth = value->rValue; |
||||
|
here->MESAwidthGiven = TRUE; |
||||
|
break; |
||||
|
case MESA_IC_VDS: |
||||
|
here->MESAicVDS = value->rValue; |
||||
|
here->MESAicVDSGiven = TRUE; |
||||
|
break; |
||||
|
case MESA_IC_VGS: |
||||
|
here->MESAicVGS = value->rValue; |
||||
|
here->MESAicVGSGiven = TRUE; |
||||
|
break; |
||||
|
case MESA_OFF: |
||||
|
here->MESAoff = value->iValue; |
||||
|
break; |
||||
|
case MESA_IC: |
||||
|
switch(value->v.numValue) { |
||||
|
case 2: |
||||
|
here->MESAicVGS = *(value->v.vec.rVec+1); |
||||
|
here->MESAicVGSGiven = TRUE; |
||||
|
case 1: |
||||
|
here->MESAicVDS = *(value->v.vec.rVec); |
||||
|
here->MESAicVDSGiven = TRUE; |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
break; |
||||
|
case MESA_TD: |
||||
|
here->MESAtd = value->rValue+CONSTCtoK; |
||||
|
here->MESAtdGiven = TRUE; |
||||
|
break; |
||||
|
case MESA_TS: |
||||
|
here->MESAts = value->rValue+CONSTCtoK; |
||||
|
here->MESAtsGiven = TRUE; |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,417 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
Modified: 2001 AlansFixes |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "smpdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "const.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MESAsetup(matrix,inModel,ckt,states) |
||||
|
register SMPmatrix *matrix; |
||||
|
register GENmodel *inModel; |
||||
|
register CKTcircuit *ckt; |
||||
|
int *states; |
||||
|
|
||||
|
/* load the diode structure with those pointers needed later |
||||
|
* for fast matrix loading |
||||
|
*/ |
||||
|
{ |
||||
|
register MESAmodel *model = (MESAmodel*)inModel; |
||||
|
register MESAinstance *here; |
||||
|
int error; |
||||
|
CKTnode *tmp; |
||||
|
|
||||
|
|
||||
|
/* loop through all the diode models */ |
||||
|
for( ; model != NULL; model = model->MESAnextModel ) { |
||||
|
if(!model->MESAthresholdGiven) { |
||||
|
model->MESAthreshold = -1.26; |
||||
|
} |
||||
|
if(!model->MESAdGiven) { |
||||
|
model->MESAd = 0.12e-6; |
||||
|
} |
||||
|
if(!model->MESAduGiven) { |
||||
|
model->MESAdu = 0.035e-6; |
||||
|
} |
||||
|
if(!model->MESAlambdaGiven) { |
||||
|
model->MESAlambda = 0.045; |
||||
|
} |
||||
|
if(!model->MESAvsGiven) { |
||||
|
model->MESAvs = 1.5e5; |
||||
|
} |
||||
|
if(!model->MESAbetaGiven) { |
||||
|
model->MESAbeta = 0.0085; |
||||
|
} |
||||
|
if(!model->MESAetaGiven) { |
||||
|
model->MESAeta = 1.73; |
||||
|
} |
||||
|
if(!model->MESAmGiven) { |
||||
|
model->MESAm = 2.5; |
||||
|
} |
||||
|
if(!model->MESAmcGiven) { |
||||
|
model->MESAmc = 3.0; |
||||
|
} |
||||
|
if(!model->MESAalphaGiven) { |
||||
|
model->MESAalpha = 0.0; |
||||
|
} |
||||
|
if(!model->MESAsigma0Given) { |
||||
|
model->MESAsigma0 = 0.081; |
||||
|
} |
||||
|
if(!model->MESAvsigmatGiven) { |
||||
|
model->MESAvsigmat = 1.01; |
||||
|
} |
||||
|
if(!model->MESAvsigmaGiven) { |
||||
|
model->MESAvsigma = 0.1; |
||||
|
} |
||||
|
if(!model->MESAmuGiven) { |
||||
|
model->MESAmu = 0.23; |
||||
|
} |
||||
|
if(!model->MESAthetaGiven) { |
||||
|
model->MESAtheta = 0; |
||||
|
} |
||||
|
if(!model->MESAmu1Given) { |
||||
|
model->MESAmu1 = 0; |
||||
|
} |
||||
|
if(!model->MESAmu2Given) { |
||||
|
model->MESAmu2 = 0; |
||||
|
} |
||||
|
if(!model->MESAndGiven) { |
||||
|
model->MESAnd = 2.0e23; |
||||
|
} |
||||
|
if(!model->MESAnduGiven) { |
||||
|
model->MESAndu = 1e22; |
||||
|
} |
||||
|
if(!model->MESAndeltaGiven) { |
||||
|
model->MESAndelta = 6e24; |
||||
|
} |
||||
|
if(!model->MESAthGiven) { |
||||
|
model->MESAth = 0.01e-6; |
||||
|
} |
||||
|
if(!model->MESAdeltaGiven) { |
||||
|
model->MESAdelta = 5.0; |
||||
|
} |
||||
|
if(!model->MESAtcGiven) { |
||||
|
model->MESAtc = 0.0; |
||||
|
} |
||||
|
if(!model->MESAdrainResistGiven) { |
||||
|
model->MESAdrainResist = 0; |
||||
|
} |
||||
|
if(!model->MESAsourceResistGiven) { |
||||
|
model->MESAsourceResist = 0; |
||||
|
} |
||||
|
if(!model->MESAgateResistGiven) { |
||||
|
model->MESAgateResist = 0; |
||||
|
} |
||||
|
if(!model->MESAriGiven) { |
||||
|
model->MESAri = 0; |
||||
|
} |
||||
|
if(!model->MESArfGiven) { |
||||
|
model->MESArf = 0; |
||||
|
} |
||||
|
if(!model->MESArdiGiven) { |
||||
|
model->MESArdi = 0; |
||||
|
} |
||||
|
if(!model->MESArsiGiven) { |
||||
|
model->MESArsi = 0; |
||||
|
} |
||||
|
if(!model->MESAphibGiven) { |
||||
|
model->MESAphib = 0.5*CHARGE; |
||||
|
} |
||||
|
if(!model->MESAphib1Given) { |
||||
|
model->MESAphib1 = 0; |
||||
|
} |
||||
|
if(!model->MESAastarGiven) { |
||||
|
model->MESAastar = 4.0e4; |
||||
|
} |
||||
|
if(!model->MESAggrGiven) { |
||||
|
model->MESAggr = 40; |
||||
|
} |
||||
|
if(!model->MESAdelGiven) { |
||||
|
model->MESAdel = 0.04; |
||||
|
} |
||||
|
if(!model->MESAxchiGiven) { |
||||
|
model->MESAxchi = 0.033; |
||||
|
} |
||||
|
if(!model->MESAnGiven) { |
||||
|
model->MESAn = 1; |
||||
|
} |
||||
|
if(!model->MESAtvtoGiven) { |
||||
|
model->MESAtvto = 0; |
||||
|
} |
||||
|
if(!model->MESAtlambdaGiven) { |
||||
|
model->MESAtlambda = DBL_MAX; |
||||
|
} |
||||
|
if(!model->MESAteta0Given) { |
||||
|
model->MESAteta0 = DBL_MAX; |
||||
|
} |
||||
|
if(!model->MESAteta1Given) { |
||||
|
model->MESAteta1 = 0; |
||||
|
} |
||||
|
if(!model->MESAtmuGiven) { |
||||
|
model->MESAtmu = 300.15; |
||||
|
} |
||||
|
if(!model->MESAxtm0Given) { |
||||
|
model->MESAxtm0 = 0; |
||||
|
} |
||||
|
if(!model->MESAxtm1Given) { |
||||
|
model->MESAxtm1 = 0; |
||||
|
} |
||||
|
if(!model->MESAxtm2Given) { |
||||
|
model->MESAxtm2 = 0; |
||||
|
} |
||||
|
if(!model->MESAksGiven) { |
||||
|
model->MESAks = 0; |
||||
|
} |
||||
|
if(!model->MESAvsgGiven) { |
||||
|
model->MESAvsg = 0; |
||||
|
} |
||||
|
if(!model->MESAtfGiven) { |
||||
|
model->MESAtf = ckt->CKTtemp; |
||||
|
} |
||||
|
if(!model->MESAfloGiven) { |
||||
|
model->MESAflo = 0; |
||||
|
} |
||||
|
if(!model->MESAdelfoGiven) { |
||||
|
model->MESAdelfo = 0; |
||||
|
} |
||||
|
if(!model->MESAagGiven) { |
||||
|
model->MESAag = 0; |
||||
|
} |
||||
|
if(!model->MESAtc1Given) { |
||||
|
model->MESAtc1 = 0; |
||||
|
} |
||||
|
if(!model->MESAtc2Given) { |
||||
|
model->MESAtc2 = 0; |
||||
|
} |
||||
|
if(!model->MESAzetaGiven) { |
||||
|
model->MESAzeta = 1; |
||||
|
} |
||||
|
if(!model->MESAlevelGiven) { |
||||
|
model->MESAlevel = 2; |
||||
|
} |
||||
|
if(!model->MESAnmaxGiven) { |
||||
|
model->MESAnmax = 2e16; |
||||
|
} |
||||
|
if(!model->MESAgammaGiven) { |
||||
|
model->MESAgamma = 3.0; |
||||
|
} |
||||
|
if(!model->MESAepsiGiven) { |
||||
|
model->MESAepsi = 12.244*8.85418e-12; |
||||
|
} |
||||
|
if(!model->MESAcasGiven) { |
||||
|
model->MESAcas = 1; |
||||
|
} |
||||
|
if(!model->MESAcbsGiven) { |
||||
|
model->MESAcbs = 1; |
||||
|
} |
||||
|
|
||||
|
/* loop through all the instances of the model */ |
||||
|
for (here = model->MESAinstances; here != NULL ; |
||||
|
here=here->MESAnextInstance) { |
||||
|
|
||||
|
if(!here->MESAlengthGiven) { |
||||
|
here->MESAlength = 1e-6; |
||||
|
} |
||||
|
if(!here->MESAwidthGiven) { |
||||
|
here->MESAwidth = 20e-6; |
||||
|
} |
||||
|
if(!here->MESAtdGiven) { |
||||
|
here->MESAtd = ckt->CKTtemp; |
||||
|
} |
||||
|
if(!here->MESAtsGiven) { |
||||
|
here->MESAts = ckt->CKTtemp; |
||||
|
} |
||||
|
|
||||
|
here->MESAstate = *states; |
||||
|
*states += 20; |
||||
|
|
||||
|
if(model->MESAsourceResist != 0 && here->MESAsourcePrimeNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->MESAname,"source"); |
||||
|
if(error) return(error); |
||||
|
here->MESAsourcePrimeNode = tmp->number; |
||||
|
|
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->MESAsourcePrimeNode = here->MESAsourceNode; |
||||
|
} |
||||
|
|
||||
|
if(model->MESAdrainResist != 0 && here->MESAdrainPrimeNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->MESAname,"drain"); |
||||
|
if(error) return(error); |
||||
|
here->MESAdrainPrimeNode = tmp->number; |
||||
|
|
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->MESAdrainPrimeNode = here->MESAdrainNode; |
||||
|
} |
||||
|
if(model->MESAgateResist != 0 && here->MESAgatePrimeNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->MESAname,"gate"); |
||||
|
if(error) return(error); |
||||
|
here->MESAgatePrimeNode = tmp->number; |
||||
|
|
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} else { |
||||
|
here->MESAgatePrimeNode = here->MESAgateNode; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
if(model->MESAri != 0 && here->MESAsourcePrmPrmNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->MESAname,"gs"); |
||||
|
if(error) return(error); |
||||
|
here->MESAsourcePrmPrmNode = tmp->number; |
||||
|
|
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->MESAsourcePrmPrmNode = here->MESAsourcePrimeNode; |
||||
|
} |
||||
|
if(model->MESArf != 0 && here->MESAdrainPrmPrmNode==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->MESAname,"gd"); |
||||
|
if(error) return(error); |
||||
|
here->MESAdrainPrmPrmNode = tmp->number; |
||||
|
|
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
here->MESAdrainPrmPrmNode = here->MESAdrainPrimeNode; |
||||
|
} |
||||
|
|
||||
|
#define TSTALLOC(ptr,first,second) \ |
||||
|
if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ |
||||
|
return(E_NOMEM);\ |
||||
|
} |
||||
|
|
||||
|
TSTALLOC(MESAdrainDrainPtr,MESAdrainNode,MESAdrainNode) |
||||
|
TSTALLOC(MESAdrainPrimeDrainPrimePtr,MESAdrainPrimeNode,MESAdrainPrimeNode) |
||||
|
TSTALLOC(MESAdrainPrmPrmDrainPrmPrmPtr,MESAdrainPrmPrmNode,MESAdrainPrmPrmNode) |
||||
|
TSTALLOC(MESAgateGatePtr,MESAgateNode,MESAgateNode) |
||||
|
TSTALLOC(MESAgatePrimeGatePrimePtr,MESAgatePrimeNode,MESAgatePrimeNode) |
||||
|
TSTALLOC(MESAsourceSourcePtr,MESAsourceNode,MESAsourceNode) |
||||
|
TSTALLOC(MESAsourcePrimeSourcePrimePtr,MESAsourcePrimeNode,MESAsourcePrimeNode) |
||||
|
TSTALLOC(MESAsourcePrmPrmSourcePrmPrmPtr,MESAsourcePrmPrmNode,MESAsourcePrmPrmNode) |
||||
|
TSTALLOC(MESAdrainDrainPrimePtr,MESAdrainNode,MESAdrainPrimeNode) |
||||
|
TSTALLOC(MESAdrainPrimeDrainPtr,MESAdrainPrimeNode,MESAdrainNode) |
||||
|
TSTALLOC(MESAgatePrimeDrainPrimePtr,MESAgatePrimeNode,MESAdrainPrimeNode) |
||||
|
TSTALLOC(MESAdrainPrimeGatePrimePtr,MESAdrainPrimeNode,MESAgatePrimeNode) |
||||
|
TSTALLOC(MESAgatePrimeSourcePrimePtr,MESAgatePrimeNode,MESAsourcePrimeNode) |
||||
|
TSTALLOC(MESAsourcePrimeGatePrimePtr,MESAsourcePrimeNode,MESAgatePrimeNode) |
||||
|
TSTALLOC(MESAsourceSourcePrimePtr,MESAsourceNode,MESAsourcePrimeNode) |
||||
|
TSTALLOC(MESAsourcePrimeSourcePtr,MESAsourcePrimeNode,MESAsourceNode) |
||||
|
TSTALLOC(MESAdrainPrimeSourcePrimePtr,MESAdrainPrimeNode,MESAsourcePrimeNode) |
||||
|
TSTALLOC(MESAsourcePrimeDrainPrimePtr,MESAsourcePrimeNode,MESAdrainPrimeNode) |
||||
|
TSTALLOC(MESAgatePrimeGatePtr,MESAgatePrimeNode,MESAgateNode) |
||||
|
TSTALLOC(MESAgateGatePrimePtr,MESAgateNode,MESAgatePrimeNode) |
||||
|
TSTALLOC(MESAsourcePrmPrmSourcePrimePtr,MESAsourcePrmPrmNode,MESAsourcePrimeNode) |
||||
|
TSTALLOC(MESAsourcePrimeSourcePrmPrmPtr,MESAsourcePrimeNode,MESAsourcePrmPrmNode) |
||||
|
TSTALLOC(MESAsourcePrmPrmGatePrimePtr,MESAsourcePrmPrmNode,MESAgatePrimeNode) |
||||
|
TSTALLOC(MESAgatePrimeSourcePrmPrmPtr,MESAgatePrimeNode,MESAsourcePrmPrmNode) |
||||
|
TSTALLOC(MESAdrainPrmPrmDrainPrimePtr,MESAdrainPrmPrmNode,MESAdrainPrimeNode) |
||||
|
TSTALLOC(MESAdrainPrimeDrainPrmPrmPtr,MESAdrainPrimeNode,MESAdrainPrmPrmNode) |
||||
|
TSTALLOC(MESAdrainPrmPrmGatePrimePtr,MESAdrainPrmPrmNode,MESAgatePrimeNode) |
||||
|
TSTALLOC(MESAgatePrimeDrainPrmPrmPtr,MESAgatePrimeNode,MESAdrainPrmPrmNode) |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MESAunsetup(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
MESAmodel *model; |
||||
|
MESAinstance *here; |
||||
|
|
||||
|
for (model = (MESAmodel *)inModel; model != NULL; |
||||
|
model = model->MESAnextModel) |
||||
|
{ |
||||
|
for (here = model->MESAinstances; here != NULL; |
||||
|
here=here->MESAnextInstance) |
||||
|
{ |
||||
|
if (here->MESAdrainPrimeNode |
||||
|
&& here->MESAdrainPrimeNode != here->MESAdrainNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->MESAdrainPrimeNode); |
||||
|
here->MESAdrainPrimeNode = 0; |
||||
|
} |
||||
|
if (here->MESAsourcePrimeNode |
||||
|
&& here->MESAsourcePrimeNode != here->MESAsourceNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->MESAsourcePrimeNode); |
||||
|
here->MESAsourcePrimeNode = 0; |
||||
|
} |
||||
|
if (here->MESAgatePrimeNode |
||||
|
&& here->MESAgatePrimeNode != here->MESAgateNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->MESAgatePrimeNode); |
||||
|
here->MESAgatePrimeNode = 0; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
return OK; |
||||
|
} |
||||
@ -0,0 +1,177 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "smpdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "const.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
#define EPSILONGAAS (12.244*8.85418e-12) |
||||
|
|
||||
|
int |
||||
|
MESAtemp(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
|
||||
|
register MESAmodel *model = (MESAmodel*)inModel; |
||||
|
register MESAinstance *here; |
||||
|
double temp; |
||||
|
double vt; |
||||
|
double d; |
||||
|
|
||||
|
|
||||
|
for( ; model != NULL; model = model->MESAnextModel ) { |
||||
|
if(!model->MESAlambdahfGiven) |
||||
|
model->MESAlambdahf = model->MESAlambda; |
||||
|
if(model->MESAlevel == 2) |
||||
|
model->MESAvpo = CHARGE*model->MESAnd*model->MESAd*model->MESAd/ |
||||
|
2/EPSILONGAAS; |
||||
|
else { |
||||
|
model->MESAvpou = CHARGE*model->MESAndu*model->MESAdu*model->MESAdu/ |
||||
|
2/EPSILONGAAS; |
||||
|
model->MESAvpod = CHARGE*model->MESAndelta*model->MESAth* |
||||
|
(2*model->MESAdu + model->MESAth)/2/EPSILONGAAS; |
||||
|
model->MESAvpo = model->MESAvpou+model->MESAvpod; |
||||
|
} |
||||
|
model->MESAdeltaSqr = model->MESAdelta*model->MESAdelta; |
||||
|
|
||||
|
for (here = model->MESAinstances; here != NULL ; |
||||
|
here=here->MESAnextInstance) { |
||||
|
vt = CONSTKoverQ * here->MESAts; |
||||
|
if(model->MESAmu1 == 0 && model->MESAmu2 == 0) |
||||
|
here->MESAtMu = model->MESAmu*pow(here->MESAts/ |
||||
|
model->MESAtmu,model->MESAxtm0); |
||||
|
else { |
||||
|
double muimp = model->MESAmu*pow(here->MESAts/ |
||||
|
model->MESAtmu,model->MESAxtm0); |
||||
|
double mupo = model->MESAmu1*pow(model->MESAtmu/ |
||||
|
here->MESAts,model->MESAxtm1) + |
||||
|
model->MESAmu2*pow(model->MESAtmu/ |
||||
|
here->MESAts,model->MESAxtm2); |
||||
|
here->MESAtMu = 1/(1/muimp+1/mupo); |
||||
|
} |
||||
|
here->MESAtTheta = model->MESAtheta; |
||||
|
here->MESAtPhib = model->MESAphib-model->MESAphib1*(here->MESAts-ckt->CKTnomTemp); |
||||
|
here->MESAtVto = model->MESAthreshold-model->MESAtvto*(here->MESAts-ckt->CKTnomTemp); |
||||
|
here->MESAimax = CHARGE*model->MESAnmax*model->MESAvs*here->MESAwidth; |
||||
|
|
||||
|
if(model->MESAlevel == 2) |
||||
|
here->MESAgchi0 = CHARGE*here->MESAwidth/here->MESAlength; |
||||
|
else |
||||
|
here->MESAgchi0 = CHARGE*here->MESAwidth/here->MESAlength*here->MESAtMu; |
||||
|
here->MESAbeta = 2*EPSILONGAAS*model->MESAvs*model->MESAzeta*here->MESAwidth/ |
||||
|
model->MESAd; |
||||
|
here->MESAtEta = model->MESAeta*(1+here->MESAts/model->MESAteta0)+ |
||||
|
model->MESAteta1/here->MESAts; |
||||
|
here->MESAtLambda= model->MESAlambda*(1-here->MESAts/model->MESAtlambda); |
||||
|
here->MESAtLambdahf = model->MESAlambdahf*(1-here->MESAts/model->MESAtlambda); |
||||
|
if(model->MESAlevel == 3) |
||||
|
d = model->MESAdu; |
||||
|
else |
||||
|
d = model->MESAd; |
||||
|
if(model->MESAlevel == 4) |
||||
|
here->MESAn0 = model->MESAepsi*here->MESAtEta*vt/2/CHARGE/d; |
||||
|
else |
||||
|
here->MESAn0 = EPSILONGAAS*here->MESAtEta*vt/CHARGE/d; |
||||
|
here->MESAnsb0 = EPSILONGAAS*here->MESAtEta*vt/CHARGE/ |
||||
|
(model->MESAdu + model->MESAth); |
||||
|
here->MESAisatb0 = CHARGE*here->MESAn0*vt* |
||||
|
here->MESAwidth/here->MESAlength; |
||||
|
if(model->MESAlevel == 4) |
||||
|
here->MESAcf = 0.5*model->MESAepsi*here->MESAwidth; |
||||
|
else |
||||
|
here->MESAcf = 0.5*EPSILONGAAS*here->MESAwidth; |
||||
|
here->MESAcsatfs = 0.5*model->MESAastar*here->MESAts* |
||||
|
here->MESAts*exp(-here->MESAtPhib/(CONSTboltz*here->MESAts))* |
||||
|
here->MESAlength*here->MESAwidth; |
||||
|
here->MESAcsatfd = 0.5*model->MESAastar*here->MESAtd* |
||||
|
here->MESAtd*exp(-here->MESAtPhib/(CONSTboltz*here->MESAtd))* |
||||
|
here->MESAlength*here->MESAwidth; |
||||
|
here->MESAggrwl = model->MESAggr*here->MESAlength*here->MESAwidth* |
||||
|
exp(model->MESAxchi*(here->MESAts-ckt->CKTnomTemp)); |
||||
|
if(here->MESAcsatfs != 0) |
||||
|
here->MESAvcrits = vt*log(vt/(CONSTroot2 * here->MESAcsatfs)); |
||||
|
else |
||||
|
here->MESAvcrits = DBL_MAX; |
||||
|
if(here->MESAcsatfd != 0) { |
||||
|
double vtd = CONSTKoverQ * here->MESAtd; |
||||
|
here->MESAvcritd = vtd*log(vtd/(CONSTroot2 * here->MESAcsatfd)); |
||||
|
} else |
||||
|
here->MESAvcritd = DBL_MAX; |
||||
|
temp = exp(here->MESAts/model->MESAtf); |
||||
|
here->MESAfl = model->MESAflo*temp; |
||||
|
here->MESAdelf = model->MESAdelfo*temp; |
||||
|
if(model->MESArdi != 0.0) |
||||
|
here->MESAtRdi = model->MESArdi*(1+ |
||||
|
model->MESAtc1*(here->MESAtd-ckt->CKTnomTemp)+ |
||||
|
model->MESAtc2*(here->MESAtd-ckt->CKTnomTemp)*(here->MESAtd-ckt->CKTnomTemp)); |
||||
|
else |
||||
|
here->MESAtRdi = 0; |
||||
|
if(model->MESArsi != 0.0) |
||||
|
here->MESAtRsi = model->MESArsi*(1+ |
||||
|
model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+ |
||||
|
model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp)); |
||||
|
else |
||||
|
here->MESAtRsi = 0; |
||||
|
if(model->MESAgateResist != 0.0) |
||||
|
here->MESAtRg = model->MESAgateResist*(1+ |
||||
|
model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+ |
||||
|
model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp)); |
||||
|
else |
||||
|
here->MESAtRg = 0; |
||||
|
if(model->MESAsourceResist != 0.0) |
||||
|
here->MESAtRs = model->MESAsourceResist*(1+ |
||||
|
model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+ |
||||
|
model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp)); |
||||
|
else |
||||
|
here->MESAtRs = 0; |
||||
|
if(model->MESAdrainResist != 0.0) |
||||
|
here->MESAtRd = model->MESAdrainResist*(1+ |
||||
|
model->MESAtc1*(here->MESAtd-ckt->CKTnomTemp)+ |
||||
|
model->MESAtc2*(here->MESAtd-ckt->CKTnomTemp)*(here->MESAtd-ckt->CKTnomTemp)); |
||||
|
else |
||||
|
here->MESAtRd = 0; |
||||
|
if(model->MESAri != 0.0) |
||||
|
here->MESAtRi = model->MESAri*(1+ |
||||
|
model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+ |
||||
|
model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp)); |
||||
|
else |
||||
|
here->MESAtRi = 0; |
||||
|
if(model->MESArf != 0.0) |
||||
|
here->MESAtRf = model->MESArf*(1+ |
||||
|
model->MESAtc1*(here->MESAtd-ckt->CKTnomTemp)+ |
||||
|
model->MESAtc2*(here->MESAtd-ckt->CKTnomTemp)*(here->MESAtd-ckt->CKTnomTemp)); |
||||
|
else |
||||
|
here->MESAtRf = 0; |
||||
|
if(here->MESAtRd != 0) |
||||
|
here->MESAdrainConduct = 1/here->MESAtRd; |
||||
|
else |
||||
|
here->MESAdrainConduct = 0; |
||||
|
if(here->MESAtRs != 0) |
||||
|
here->MESAsourceConduct = 1/here->MESAtRs; |
||||
|
else |
||||
|
here->MESAsourceConduct = 0; |
||||
|
if(here->MESAtRg != 0) |
||||
|
here->MESAgateConduct = 1/here->MESAtRg; |
||||
|
else |
||||
|
here->MESAgateConduct = 0; |
||||
|
if(here->MESAtRi != 0) |
||||
|
here->MESAtGi = 1/here->MESAtRi; |
||||
|
else |
||||
|
here->MESAtGi = 0; |
||||
|
if(here->MESAtRf != 0) |
||||
|
here->MESAtGf = 1/here->MESAtRf; |
||||
|
else |
||||
|
here->MESAtGf = 0; |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
/********** |
||||
|
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. |
||||
|
Author: Trond Ytterdal |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "mesadefs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MESAtrunc(inModel,ckt,timeStep) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
double *timeStep; |
||||
|
{ |
||||
|
MESAmodel *model = (MESAmodel*)inModel; |
||||
|
MESAinstance *here; |
||||
|
|
||||
|
for( ; model != NULL; model = model->MESAnextModel) { |
||||
|
for(here=model->MESAinstances;here!=NULL;here = here->MESAnextInstance){ |
||||
|
CKTterr(here->MESAqgs,ckt,timeStep); |
||||
|
CKTterr(here->MESAqgd,ckt,timeStep); |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue