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
pnenzi 25 years ago
parent
commit
a2ba74bcac
  1. 29
      src/spicelib/devices/hfet1/Makefile.am
  2. 120
      src/spicelib/devices/hfet1/hfet.c
  3. 88
      src/spicelib/devices/hfet1/hfetacl.c
  4. 132
      src/spicelib/devices/hfet1/hfetask.c
  5. 466
      src/spicelib/devices/hfet1/hfetdefs.h
  6. 39
      src/spicelib/devices/hfet1/hfetdel.c
  7. 31
      src/spicelib/devices/hfet1/hfetdest.c
  8. 34
      src/spicelib/devices/hfet1/hfetext.h
  9. 37
      src/spicelib/devices/hfet1/hfetgetic.c
  10. 65
      src/spicelib/devices/hfet1/hfetinit.c
  11. 13
      src/spicelib/devices/hfet1/hfetinit.h
  12. 7
      src/spicelib/devices/hfet1/hfetitf.h
  13. 787
      src/spicelib/devices/hfet1/hfetload.c
  14. 245
      src/spicelib/devices/hfet1/hfetmask.c
  15. 45
      src/spicelib/devices/hfet1/hfetmdel.c
  16. 290
      src/spicelib/devices/hfet1/hfetmpar.c
  17. 60
      src/spicelib/devices/hfet1/hfetparam.c
  18. 432
      src/spicelib/devices/hfet1/hfetsetup.c
  19. 96
      src/spicelib/devices/hfet1/hfettemp.c
  20. 26
      src/spicelib/devices/hfet1/hfettrunc.c
  21. 29
      src/spicelib/devices/hfet2/Makefile.am
  22. 94
      src/spicelib/devices/hfet2/hfet2.c
  23. 64
      src/spicelib/devices/hfet2/hfet2acl.c
  24. 132
      src/spicelib/devices/hfet2/hfet2ask.c
  25. 318
      src/spicelib/devices/hfet2/hfet2defs.h
  26. 39
      src/spicelib/devices/hfet2/hfet2del.c
  27. 32
      src/spicelib/devices/hfet2/hfet2dest.c
  28. 38
      src/spicelib/devices/hfet2/hfet2ext.h
  29. 32
      src/spicelib/devices/hfet2/hfet2getic.c
  30. 65
      src/spicelib/devices/hfet2/hfet2init.c
  31. 13
      src/spicelib/devices/hfet2/hfet2init.h
  32. 7
      src/spicelib/devices/hfet2/hfet2itf.h
  33. 456
      src/spicelib/devices/hfet2/hfet2load.c
  34. 160
      src/spicelib/devices/hfet2/hfet2mask.c
  35. 45
      src/spicelib/devices/hfet2/hfet2mdel.c
  36. 177
      src/spicelib/devices/hfet2/hfet2mpar.c
  37. 60
      src/spicelib/devices/hfet2/hfet2param.c
  38. 233
      src/spicelib/devices/hfet2/hfet2setup.c
  39. 56
      src/spicelib/devices/hfet2/hfet2temp.c
  40. 27
      src/spicelib/devices/hfet2/hfet2trunc.c
  41. 29
      src/spicelib/devices/mesa/Makefile.am
  42. 130
      src/spicelib/devices/mesa/mesa.c
  43. 97
      src/spicelib/devices/mesa/mesaacl.c
  44. 140
      src/spicelib/devices/mesa/mesaask.c
  45. 467
      src/spicelib/devices/mesa/mesadefs.h
  46. 39
      src/spicelib/devices/mesa/mesadel.c
  47. 35
      src/spicelib/devices/mesa/mesadest.c
  48. 37
      src/spicelib/devices/mesa/mesaext.h
  49. 41
      src/spicelib/devices/mesa/mesagetic.c
  50. 65
      src/spicelib/devices/mesa/mesainit.c
  51. 13
      src/spicelib/devices/mesa/mesainit.h
  52. 9
      src/spicelib/devices/mesa/mesaitf.h
  53. 987
      src/spicelib/devices/mesa/mesaload.c
  54. 223
      src/spicelib/devices/mesa/mesamask.c
  55. 45
      src/spicelib/devices/mesa/mesamdel.c
  56. 273
      src/spicelib/devices/mesa/mesamparam.c
  57. 69
      src/spicelib/devices/mesa/mesaparam.c
  58. 417
      src/spicelib/devices/mesa/mesasetup.c
  59. 177
      src/spicelib/devices/mesa/mesatemp.c
  60. 30
      src/spicelib/devices/mesa/mesatrunc.c

29
src/spicelib/devices/hfet1/Makefile.am

@ -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

120
src/spicelib/devices/hfet1/hfet.c

@ -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);

88
src/spicelib/devices/hfet1/hfetacl.c

@ -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);
}

132
src/spicelib/devices/hfet1/hfetask.c

@ -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 */
}

466
src/spicelib/devices/hfet1/hfetdefs.h

@ -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*/

39
src/spicelib/devices/hfet1/hfetdel.c

@ -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);
}

31
src/spicelib/devices/hfet1/hfetdest.c

@ -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;
}

34
src/spicelib/devices/hfet1/hfetext.h

@ -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

37
src/spicelib/devices/hfet1/hfetgetic.c

@ -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);
}

65
src/spicelib/devices/hfet1/hfetinit.c

@ -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;
}

13
src/spicelib/devices/hfet1/hfetinit.h

@ -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

7
src/spicelib/devices/hfet1/hfetitf.h

@ -0,0 +1,7 @@
#ifndef DEV_HFETA
#define DEV_HFETA
SPICEdev *get_hfeta_info(void);
#endif

787
src/spicelib/devices/hfet1/hfetload.c

@ -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);
}

245
src/spicelib/devices/hfet1/hfetmask.c

@ -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 */
}

45
src/spicelib/devices/hfet1/hfetmdel.c

@ -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);
}

290
src/spicelib/devices/hfet1/hfetmpar.c

@ -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);
}

60
src/spicelib/devices/hfet1/hfetparam.c

@ -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);
}

432
src/spicelib/devices/hfet1/hfetsetup.c

@ -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;
}

96
src/spicelib/devices/hfet1/hfettemp.c

@ -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);
}

26
src/spicelib/devices/hfet1/hfettrunc.c

@ -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);
}

29
src/spicelib/devices/hfet2/Makefile.am

@ -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

94
src/spicelib/devices/hfet2/hfet2.c

@ -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);

64
src/spicelib/devices/hfet2/hfet2acl.c

@ -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);
}

132
src/spicelib/devices/hfet2/hfet2ask.c

@ -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 */
}

318
src/spicelib/devices/hfet2/hfet2defs.h

@ -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*/

39
src/spicelib/devices/hfet2/hfet2del.c

@ -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);
}

32
src/spicelib/devices/hfet2/hfet2dest.c

@ -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;
}

38
src/spicelib/devices/hfet2/hfet2ext.h

@ -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

32
src/spicelib/devices/hfet2/hfet2getic.c

@ -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);
}

65
src/spicelib/devices/hfet2/hfet2init.c

@ -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;
}

13
src/spicelib/devices/hfet2/hfet2init.h

@ -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

7
src/spicelib/devices/hfet2/hfet2itf.h

@ -0,0 +1,7 @@
#ifndef DEV_HFET2
#define DEV_HFET2
SPICEdev *get_hfet2_info(void);
#endif

456
src/spicelib/devices/hfet2/hfet2load.c

@ -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);
}

160
src/spicelib/devices/hfet2/hfet2mask.c

@ -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 */
}

45
src/spicelib/devices/hfet2/hfet2mdel.c

@ -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);
}

177
src/spicelib/devices/hfet2/hfet2mpar.c

@ -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);
}

60
src/spicelib/devices/hfet2/hfet2param.c

@ -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);
}

233
src/spicelib/devices/hfet2/hfet2setup.c

@ -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;
}

56
src/spicelib/devices/hfet2/hfet2temp.c

@ -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);
}

27
src/spicelib/devices/hfet2/hfet2trunc.c

@ -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);
}

29
src/spicelib/devices/mesa/Makefile.am

@ -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

130
src/spicelib/devices/mesa/mesa.c

@ -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);

97
src/spicelib/devices/mesa/mesaacl.c

@ -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);
}

140
src/spicelib/devices/mesa/mesaask.c

@ -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 */
}

467
src/spicelib/devices/mesa/mesadefs.h

@ -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*/

39
src/spicelib/devices/mesa/mesadel.c

@ -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);
}

35
src/spicelib/devices/mesa/mesadest.c

@ -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;
}

37
src/spicelib/devices/mesa/mesaext.h

@ -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

41
src/spicelib/devices/mesa/mesagetic.c

@ -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);
}

65
src/spicelib/devices/mesa/mesainit.c

@ -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;
}

13
src/spicelib/devices/mesa/mesainit.h

@ -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

9
src/spicelib/devices/mesa/mesaitf.h

@ -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

987
src/spicelib/devices/mesa/mesaload.c

@ -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;
}

223
src/spicelib/devices/mesa/mesamask.c

@ -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 */
}

45
src/spicelib/devices/mesa/mesamdel.c

@ -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);
}

273
src/spicelib/devices/mesa/mesamparam.c

@ -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);
}

69
src/spicelib/devices/mesa/mesaparam.c

@ -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);
}

417
src/spicelib/devices/mesa/mesasetup.c

@ -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;
}

177
src/spicelib/devices/mesa/mesatemp.c

@ -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);
}

30
src/spicelib/devices/mesa/mesatrunc.c

@ -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);
}
Loading…
Cancel
Save