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