Added three new devices from macspice3f4 (A. Wilson). These devices are not yet in a usable state. They seems to be partial porting.
This commit is contained in:
parent
913b715c51
commit
a2ba74bcac
|
|
@ -0,0 +1,29 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
pkglib_LTLIBRARIES = libhfet.la
|
||||
|
||||
libhfet_la_SOURCES = \
|
||||
hfet.c \
|
||||
hfetacl.c \
|
||||
hfetask.c \
|
||||
hfetdefs.h \
|
||||
hfetdel.c \
|
||||
hfetdest.c \
|
||||
hfetext.h \
|
||||
hfetgetic.c \
|
||||
hfetinit.c \
|
||||
hfetinit.h \
|
||||
hfetitf.h \
|
||||
hfetload.c \
|
||||
hfetmask.c \
|
||||
hfetmdel.c \
|
||||
hfetmpar.c \
|
||||
hfetparam.c \
|
||||
hfetsetup.c \
|
||||
hfettemp.c \
|
||||
hfettrunc.c
|
||||
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/include
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "ifsim.h"
|
||||
#include "devdefs.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
IFparm HFETApTable[] = { /* parameters */
|
||||
OP("off", HFETA_OFF, IF_FLAG ,"Device initially off"),
|
||||
IOP("l", HFETA_LENGTH, IF_REAL ,"Length of device"),
|
||||
IOP("w", HFETA_WIDTH, IF_REAL ,"Width of device"),
|
||||
IOP("icvds", HFETA_IC_VDS, IF_REAL ,"Initial D-S voltage"),
|
||||
IOP("icvgs", HFETA_IC_VGS, IF_REAL ,"Initial G-S voltage"),
|
||||
IOP("temp", HFETA_TEMP, IF_REAL ,"Instance temperature"),
|
||||
OP("dnode", HFETA_DRAINNODE, IF_INTEGER,"Number of drain node"),
|
||||
OP("gnode", HFETA_GATENODE, IF_INTEGER,"Number of gate node"),
|
||||
OP("snode", HFETA_SOURCENODE, IF_INTEGER,"Number of source node"),
|
||||
OP("dprimenode",HFETA_DRAINPRIMENODE, IF_INTEGER,"Number of internal drain node"),
|
||||
OP("sprimenode",HFETA_SOURCEPRIMENODE,IF_INTEGER,"Number of internal source node"),
|
||||
OP("vgs", HFETA_VGS, IF_REAL,"Gate-Source voltage"),
|
||||
OP("vgd", HFETA_VGD, IF_REAL,"Gate-Drain voltage"),
|
||||
OP("cg", HFETA_CG, IF_REAL,"Gate capacitance"),
|
||||
OP("cd", HFETA_CD, IF_REAL,"Drain capacitance"),
|
||||
OP("cgd", HFETA_CGD, IF_REAL,"Gate_Drain capacitance"),
|
||||
OP("gm", HFETA_GM, IF_REAL,"Transconductance"),
|
||||
OP("gds", HFETA_GDS, IF_REAL,"Drain-Source conductance"),
|
||||
OP("ggs", HFETA_GGS, IF_REAL,"Gate-Source conductance"),
|
||||
OP("ggd", HFETA_GGD, IF_REAL,"Gate-Drain conductance"),
|
||||
OP("qgs", HFETA_QGS, IF_REAL,"Gate-Source charge storage"),
|
||||
OP("cqgs", HFETA_CQGS, IF_REAL,"Capacitance due to gate-source charge storage"),
|
||||
OP("qgd", HFETA_QGD, IF_REAL,"Gate-Drain charge storage"),
|
||||
OP("cqgd", HFETA_CQGD, IF_REAL,"Capacitance due to gate-drain charge storage"),
|
||||
OP("cs", HFETA_CS, IF_REAL ,"Source current"),
|
||||
OP("p", HFETA_POWER, IF_REAL ,"Power dissipated by the mesfet")
|
||||
|
||||
};
|
||||
|
||||
IFparm HFETAmPTable[] = { /* model parameters */
|
||||
IOP( "vt0", HFETA_MOD_VTO, IF_REAL,"Pinch-off voltage"),
|
||||
IOP( "vto", HFETA_MOD_VTO, IF_REAL,"Pinch-off voltage"),
|
||||
IOP( "lambda", HFETA_MOD_LAMBDA, IF_REAL,"Output conductance parameter"),
|
||||
IOP( "rd", HFETA_MOD_RD, IF_REAL,"Drain ohmic resistance"),
|
||||
IOP( "rs", HFETA_MOD_RS, IF_REAL,"Source ohmic resistance"),
|
||||
IOP( "rg", HFETA_MOD_RG, IF_REAL,"Gate ohmic resistance"),
|
||||
IOP( "rdi", HFETA_MOD_RDI, IF_REAL,"Drain ohmic resistance"),
|
||||
IOP( "rsi", HFETA_MOD_RSI, IF_REAL,"Source ohmic resistance"),
|
||||
IOP( "rgs", HFETA_MOD_RGS, IF_REAL,"Gate-source ohmic resistance"),
|
||||
IOP( "rgd", HFETA_MOD_RGD, IF_REAL,"Gate-drain ohmic resistance"),
|
||||
IOP( "ri", HFETA_MOD_RI, IF_REAL,""),
|
||||
IOP( "rf", HFETA_MOD_RF, IF_REAL,""),
|
||||
IOP( "eta", HFETA_MOD_ETA, IF_REAL,"Subthreshold ideality factor"),
|
||||
IOP( "m", HFETA_MOD_M, IF_REAL,"Knee shape parameter"),
|
||||
IOP( "mc", HFETA_MOD_MC, IF_REAL,"Knee shape parameter"),
|
||||
IOP( "gamma", HFETA_MOD_GAMMA, IF_REAL,"Knee shape parameter"),
|
||||
IOP( "sigma0", HFETA_MOD_SIGMA0, IF_REAL,"Threshold voltage coefficient"),
|
||||
IOP( "vsigmat", HFETA_MOD_VSIGMAT,IF_REAL,""),
|
||||
IOP( "vsigma", HFETA_MOD_VSIGMA, IF_REAL,""),
|
||||
IOP( "mu", HFETA_MOD_MU, IF_REAL,"Moblity"),
|
||||
IOP( "di", HFETA_MOD_DI, IF_REAL,"Depth of device"),
|
||||
IOP( "delta", HFETA_MOD_DELTA, IF_REAL,""),
|
||||
IOP( "vs", HFETA_MOD_VS, IF_REAL,"Saturation velocity"),
|
||||
IOP( "nmax", HFETA_MOD_NMAX, IF_REAL,""),
|
||||
IOP( "deltad", HFETA_MOD_DELTAD, IF_REAL,"Thickness correction"),
|
||||
IOP( "js1d", HFETA_MOD_JS1D, IF_REAL,""),
|
||||
IOP( "js2d", HFETA_MOD_JS2D, IF_REAL,""),
|
||||
IOP( "js1s", HFETA_MOD_JS1S, IF_REAL,""),
|
||||
IOP( "js2s", HFETA_MOD_JS2S, IF_REAL,""),
|
||||
IOP( "m1d", HFETA_MOD_M1D, IF_REAL,""),
|
||||
IOP( "m2d", HFETA_MOD_M2D, IF_REAL,""),
|
||||
IOP( "m1s", HFETA_MOD_M1S, IF_REAL,""),
|
||||
IOP( "m2s", HFETA_MOD_M2S, IF_REAL,""),
|
||||
IOP( "epsi", HFETA_MOD_EPSI, IF_REAL,""),
|
||||
IOP( "p", HFETA_MOD_P, IF_REAL,""),
|
||||
IOP( "cm3", HFETA_MOD_CM3, IF_REAL,""),
|
||||
IOP( "a1", HFETA_MOD_A1, IF_REAL,""),
|
||||
IOP( "a2", HFETA_MOD_A2, IF_REAL,""),
|
||||
IOP( "mv1", HFETA_MOD_MV1, IF_REAL,""),
|
||||
IOP( "kappa", HFETA_MOD_KAPPA, IF_REAL,""),
|
||||
IOP( "delf", HFETA_MOD_DELF, IF_REAL,""),
|
||||
IOP( "fgds", HFETA_MOD_FGDS, IF_REAL,""),
|
||||
IOP( "tf", HFETA_MOD_TF, IF_REAL,""),
|
||||
IOP( "cds", HFETA_MOD_CDS, IF_REAL,""),
|
||||
IOP( "phib", HFETA_MOD_PHIB, IF_REAL,""),
|
||||
IOP( "talpha", HFETA_MOD_TALPHA, IF_REAL,""),
|
||||
IOP( "mt1", HFETA_MOD_MT1, IF_REAL,""),
|
||||
IOP( "mt2", HFETA_MOD_MT2, IF_REAL,""),
|
||||
IOP( "ck1", HFETA_MOD_CK1, IF_REAL,""),
|
||||
IOP( "ck2", HFETA_MOD_CK2, IF_REAL,""),
|
||||
IOP( "cm1", HFETA_MOD_CM1, IF_REAL,""),
|
||||
IOP( "cm2", HFETA_MOD_CM2, IF_REAL,""),
|
||||
IOP( "astar", HFETA_MOD_ASTAR, IF_REAL,""),
|
||||
IOP( "eta1", HFETA_MOD_ETA1, IF_REAL,""),
|
||||
IOP( "d1", HFETA_MOD_D1, IF_REAL,""),
|
||||
IOP( "vt1", HFETA_MOD_VT1, IF_REAL,""),
|
||||
IOP( "eta2", HFETA_MOD_ETA2, IF_REAL,""),
|
||||
IOP( "d2", HFETA_MOD_D2, IF_REAL,""),
|
||||
IOP( "vt2", HFETA_MOD_VT2, IF_REAL,""),
|
||||
IOP( "ggr", HFETA_MOD_GGR, IF_REAL,""),
|
||||
IOP( "del", HFETA_MOD_DEL, IF_REAL,""),
|
||||
IOP( "gatemod", HFETA_MOD_GATEMOD,IF_INTEGER,""),
|
||||
IOP( "klambda", HFETA_MOD_KLAMBDA, IF_REAL,""),
|
||||
IOP( "kmu", HFETA_MOD_KMU, IF_REAL,""),
|
||||
IOP( "kvto", HFETA_MOD_KVTO, IF_REAL,""),
|
||||
OP( "type", HFETA_MOD_TYPE, IF_STRING, "NHFET or PHFET"),
|
||||
IOP( "nhfet", HFETA_MOD_NHFET, IF_FLAG,"N HFET device"),
|
||||
IOP( "phfet", HFETA_MOD_PHFET, IF_FLAG,"P HFET device"),
|
||||
};
|
||||
|
||||
char *HFETAnames[] = {
|
||||
"Drain",
|
||||
"Gate",
|
||||
"Source"
|
||||
};
|
||||
|
||||
int HFETAnSize = NUMELEMS(HFETAnames);
|
||||
int HFETApTSize = NUMELEMS(HFETApTable);
|
||||
int HFETAmPTSize = NUMELEMS(HFETAmPTable);
|
||||
int HFETAiSize = sizeof(HFETAinstance);
|
||||
int HFETAmSize = sizeof(HFETAmodel);
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
HFETAacLoad(inModel,ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
HFETAmodel *model = (HFETAmodel*)inModel;
|
||||
HFETAinstance *here;
|
||||
double gm;
|
||||
double gds;
|
||||
double xds;
|
||||
double ggs;
|
||||
double xgs;
|
||||
double ggd;
|
||||
double xgd;
|
||||
double ggspp;
|
||||
double ggdpp;
|
||||
double f;
|
||||
|
||||
for( ; model != NULL; model = model->HFETAnextModel )
|
||||
{
|
||||
for( here = model->HFETAinstances; here != NULL;
|
||||
here = here->HFETAnextInstance)
|
||||
{
|
||||
gm = *(ckt->CKTstate0 + here->HFETAgm);
|
||||
gds = *(ckt->CKTstate0 + here->HFETAgds);
|
||||
xds = CDS*ckt->CKTomega;
|
||||
ggs = *(ckt->CKTstate0 + here->HFETAggs);
|
||||
xgs = *(ckt->CKTstate0 + here->HFETAqgs) * ckt->CKTomega;
|
||||
ggd = *(ckt->CKTstate0 + here->HFETAggd);
|
||||
xgd = *(ckt->CKTstate0 + here->HFETAqgd) * ckt->CKTomega;
|
||||
ggspp = *(ckt->CKTstate0 + here->HFETAggspp);
|
||||
ggdpp = *(ckt->CKTstate0 + here->HFETAggdpp);
|
||||
if(model->HFETAkappaGiven && here->HFETAdelf != 0.0) {
|
||||
f = ckt->CKTomega/2/M_PI;
|
||||
gds = gds*(1+0.5*model->HFETAkappa*(1+tanh((f-here->HFETAfgds)/here->HFETAdelf)));
|
||||
}
|
||||
*(here->HFETAdrainDrainPtr) += model->HFETAdrainConduct;
|
||||
*(here->HFETAsourceSourcePtr) += model->HFETAsourceConduct;
|
||||
*(here->HFETAgatePrimeGatePrimePtr) += (ggd+ggs+ggspp+ggdpp+model->HFETAgateConduct);
|
||||
*(here->HFETAdrainPrimeDrainPrimePtr) += (gds+ggd+model->HFETAdrainConduct+model->HFETAgf);
|
||||
*(here->HFETAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+model->HFETAsourceConduct+model->HFETAgi);
|
||||
*(here->HFETAsourcePrmPrmSourcePrmPrmPtr) += (model->HFETAgi+ggspp);
|
||||
*(here->HFETAdrainPrmPrmDrainPrmPrmPtr) += (model->HFETAgf+ggdpp);
|
||||
*(here->HFETAdrainDrainPrimePtr) -= model->HFETAdrainConduct;
|
||||
*(here->HFETAdrainPrimeDrainPtr) -= model->HFETAdrainConduct;
|
||||
*(here->HFETAsourceSourcePrimePtr) -= model->HFETAsourceConduct;
|
||||
*(here->HFETAsourcePrimeSourcePtr) -= model->HFETAsourceConduct;
|
||||
*(here->HFETAgatePrimeDrainPrimePtr) -= ggd;
|
||||
*(here->HFETAdrainPrimeGatePrimePtr) += (gm-ggd);
|
||||
*(here->HFETAgatePrimeSourcePrimePtr) -= ggs;
|
||||
*(here->HFETAsourcePrimeGatePrimePtr) += (-ggs-gm);
|
||||
*(here->HFETAdrainPrimeSourcePrimePtr) += (-gds-gm);
|
||||
*(here->HFETAsourcePrimeDrainPrimePtr) -= gds;
|
||||
*(here->HFETAsourcePrimeSourcePrmPrmPtr) -= model->HFETAgi;
|
||||
*(here->HFETAsourcePrmPrmSourcePrimePtr) -= model->HFETAgi;
|
||||
*(here->HFETAgatePrimeSourcePrmPrmPtr) -= ggspp;
|
||||
*(here->HFETAsourcePrmPrmGatePrimePtr) -= ggspp;
|
||||
*(here->HFETAdrainPrimeDrainPrmPrmPtr) -= model->HFETAgf;
|
||||
*(here->HFETAdrainPrmPrmDrainPrimePtr) -= model->HFETAgf;
|
||||
*(here->HFETAgatePrimeDrainPrmPrmPtr) -= ggdpp;
|
||||
*(here->HFETAdrainPrmPrmGatePrimePtr) -= ggdpp;
|
||||
*(here->HFETAgateGatePtr) += model->HFETAgateConduct;
|
||||
*(here->HFETAgateGatePrimePtr) -= model->HFETAgateConduct;
|
||||
*(here->HFETAgatePrimeGatePtr) -= model->HFETAgateConduct;
|
||||
*(here->HFETAgatePrimeGatePrimePtr+1) += xgd+xgs;
|
||||
*(here->HFETAdrainPrmPrmDrainPrmPrmPtr+1) += xgd;
|
||||
*(here->HFETAsourcePrmPrmSourcePrmPrmPtr+1) += xgs;
|
||||
*(here->HFETAgatePrimeDrainPrmPrmPtr+1) -= xgd;
|
||||
*(here->HFETAgatePrimeSourcePrmPrmPtr+1) -= xgs;
|
||||
*(here->HFETAdrainPrmPrmGatePrimePtr+1) -= xgd;
|
||||
*(here->HFETAsourcePrmPrmGatePrimePtr+1) -= xgs;
|
||||
*(here->HFETAdrainPrimeDrainPrimePtr+1) += xds;
|
||||
*(here->HFETAsourcePrimeSourcePrimePtr+1) += xds;
|
||||
*(here->HFETAdrainPrimeSourcePrimePtr+1) -= xds;
|
||||
*(here->HFETAsourcePrimeDrainPrimePtr+1) -= xds;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
**********/
|
||||
/*
|
||||
Imported into HFETA source: Paolo Nenzi 2001
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "devdefs.h"
|
||||
#include "ifsim.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
HFETAask(ckt,inst,which,value,select)
|
||||
CKTcircuit *ckt;
|
||||
GENinstance *inst;
|
||||
int which;
|
||||
IFvalue *value;
|
||||
IFvalue *select;
|
||||
{
|
||||
HFETAinstance *here = (HFETAinstance*)inst;
|
||||
static char *msg = "Current and power not available in ac analysis";
|
||||
switch(which) {
|
||||
case HFETA_LENGTH:
|
||||
value->rValue = here->HFETAlength;
|
||||
return (OK);
|
||||
case HFETA_WIDTH:
|
||||
value->rValue = here->HFETAwidth;
|
||||
case HFETA_IC_VDS:
|
||||
value->rValue = here->HFETAicVDS;
|
||||
return (OK);
|
||||
case HFETA_IC_VGS:
|
||||
value->rValue = here->HFETAicVGS;
|
||||
return (OK);
|
||||
case HFETA_OFF:
|
||||
value->iValue = here->HFETAoff;
|
||||
return (OK);
|
||||
case HFETA_DRAINNODE:
|
||||
value->iValue = here->HFETAdrainNode;
|
||||
return (OK);
|
||||
case HFETA_GATENODE:
|
||||
value->iValue = here->HFETAgateNode;
|
||||
return (OK);
|
||||
case HFETA_SOURCENODE:
|
||||
value->iValue = here->HFETAsourceNode;
|
||||
return (OK);
|
||||
case HFETA_DRAINPRIMENODE:
|
||||
value->iValue = here->HFETAdrainPrimeNode;
|
||||
return (OK);
|
||||
case HFETA_SOURCEPRIMENODE:
|
||||
value->iValue = here->HFETAsourcePrimeNode;
|
||||
return (OK);
|
||||
case HFETA_TEMP:
|
||||
value->rValue = here->HFETAtemp;
|
||||
case HFETA_VGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAvgs);
|
||||
return (OK);
|
||||
case HFETA_VGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAvgd);
|
||||
return (OK);
|
||||
case HFETA_CG:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAcg);
|
||||
return (OK);
|
||||
case HFETA_CD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAcd);
|
||||
return (OK);
|
||||
case HFETA_CGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAcgd);
|
||||
return (OK);
|
||||
case HFETA_GM:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAgm);
|
||||
return (OK);
|
||||
case HFETA_GDS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAgds);
|
||||
return (OK);
|
||||
case HFETA_GGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAggs);
|
||||
return (OK);
|
||||
case HFETA_GGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAggd);
|
||||
return (OK);
|
||||
case HFETA_QGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAqgs);
|
||||
return (OK);
|
||||
case HFETA_CQGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAcqgs);
|
||||
return (OK);
|
||||
case HFETA_QGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAqgd);
|
||||
return (OK);
|
||||
case HFETA_CQGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAcqgd);
|
||||
return (OK);
|
||||
case HFETA_CS :
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = MALLOC(strlen(msg)+1);
|
||||
errRtn = "HFETAask";
|
||||
strcpy(errMsg,msg);
|
||||
return(E_ASKCURRENT);
|
||||
} else {
|
||||
value->rValue = -*(ckt->CKTstate0 + here->HFETAcd);
|
||||
value->rValue -= *(ckt->CKTstate0 + here->HFETAcg);
|
||||
}
|
||||
return(OK);
|
||||
case HFETA_POWER :
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = MALLOC(strlen(msg)+1);
|
||||
errRtn = "HFETAask";
|
||||
strcpy(errMsg,msg);
|
||||
return(E_ASKPOWER);
|
||||
} else {
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFETAcd) *
|
||||
*(ckt->CKTrhsOld + here->HFETAdrainNode);
|
||||
value->rValue += *(ckt->CKTstate0 + here->HFETAcg) *
|
||||
*(ckt->CKTrhsOld + here->HFETAgateNode);
|
||||
value->rValue -= (*(ckt->CKTstate0+here->HFETAcd) +
|
||||
*(ckt->CKTstate0 + here->HFETAcg)) *
|
||||
*(ckt->CKTrhsOld + here->HFETAsourceNode);
|
||||
}
|
||||
return(OK);
|
||||
default:
|
||||
return (E_BADPARM);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
@ -0,0 +1,466 @@
|
|||
#ifndef HFETA
|
||||
#define HFETA
|
||||
|
||||
#include "ifsim.h"
|
||||
#include "cktdefs.h"
|
||||
#include "gendefs.h"
|
||||
#include "complex.h"
|
||||
#include "noisedef.h"
|
||||
|
||||
#define HFETAnumStates 24
|
||||
|
||||
typedef struct sHFETAinstance {
|
||||
struct sHFETAmodel *HFETAmodPtr;
|
||||
struct sHFETAinstance *HFETAnextInstance;
|
||||
IFuid HFETAname;
|
||||
int HFETAowner; /* number of owner process */
|
||||
int HFETAstate; /* index into state table for this device */
|
||||
|
||||
int HFETAdrainNode;
|
||||
int HFETAgateNode;
|
||||
int HFETAsourceNode;
|
||||
int HFETAdrainPrimeNode;
|
||||
int HFETAgatePrimeNode;
|
||||
int HFETAsourcePrimeNode;
|
||||
int HFETAdrainPrmPrmNode;
|
||||
int HFETAsourcePrmPrmNode;
|
||||
double HFETAlength;
|
||||
double HFETAwidth;
|
||||
double HFETAicVDS;
|
||||
double HFETAicVGS;
|
||||
double HFETAtemp;
|
||||
double HFETAtVto;
|
||||
double HFETAtMu;
|
||||
double HFETAtLambda;
|
||||
double HFETAtLambdahf;
|
||||
double *HFETAdrainDrainPrimePtr;
|
||||
double *HFETAgatePrimeDrainPrimePtr;
|
||||
double *HFETAgatePrimeSourcePrimePtr;
|
||||
double *HFETAsourceSourcePrimePtr;
|
||||
double *HFETAdrainPrimeDrainPtr;
|
||||
double *HFETAdrainPrimeGatePrimePtr;
|
||||
double *HFETAdrainPrimeSourcePrimePtr;
|
||||
double *HFETAsourcePrimeGatePrimePtr;
|
||||
double *HFETAsourcePrimeSourcePtr;
|
||||
double *HFETAsourcePrimeDrainPrimePtr;
|
||||
double *HFETAdrainDrainPtr;
|
||||
double *HFETAgatePrimeGatePrimePtr;
|
||||
double *HFETAsourceSourcePtr;
|
||||
double *HFETAdrainPrimeDrainPrimePtr;
|
||||
double *HFETAsourcePrimeSourcePrimePtr;
|
||||
double *HFETAdrainPrmPrmDrainPrmPrmPtr;
|
||||
double *HFETAdrainPrmPrmDrainPrimePtr;
|
||||
double *HFETAdrainPrimeDrainPrmPrmPtr;
|
||||
double *HFETAdrainPrmPrmGatePrimePtr;
|
||||
double *HFETAgatePrimeDrainPrmPrmPtr;
|
||||
double *HFETAsourcePrmPrmSourcePrmPrmPtr;
|
||||
double *HFETAsourcePrmPrmSourcePrimePtr;
|
||||
double *HFETAsourcePrimeSourcePrmPrmPtr;
|
||||
double *HFETAsourcePrmPrmGatePrimePtr;
|
||||
double *HFETAgatePrimeSourcePrmPrmPtr;
|
||||
double *HFETAgateGatePtr;
|
||||
double *HFETAgateGatePrimePtr;
|
||||
double *HFETAgatePrimeGatePtr;
|
||||
|
||||
|
||||
#define HFETAvgs HFETAstate
|
||||
#define HFETAvgd HFETAstate+1
|
||||
#define HFETAcg HFETAstate+2
|
||||
#define HFETAcd HFETAstate+3
|
||||
#define HFETAcgd HFETAstate+4
|
||||
#define HFETAcgs HFETAstate+5
|
||||
#define HFETAgm HFETAstate+6
|
||||
#define HFETAgds HFETAstate+7
|
||||
#define HFETAggs HFETAstate+8
|
||||
#define HFETAggd HFETAstate+9
|
||||
#define HFETAqgs HFETAstate+10
|
||||
#define HFETAcqgs HFETAstate+11
|
||||
#define HFETAqgd HFETAstate+12
|
||||
#define HFETAcqgd HFETAstate+13
|
||||
#define HFETAvgspp HFETAstate+14
|
||||
#define HFETAggspp HFETAstate+15
|
||||
#define HFETAcgspp HFETAstate+16
|
||||
#define HFETAvgdpp HFETAstate+17
|
||||
#define HFETAggdpp HFETAstate+18
|
||||
#define HFETAcgdpp HFETAstate+19
|
||||
#define HFETAqds HFETAstate+20
|
||||
#define HFETAcqds HFETAstate+21
|
||||
#define HFETAgmg HFETAstate+22
|
||||
#define HFETAgmd HFETAstate+23
|
||||
|
||||
|
||||
|
||||
int HFETAoff;
|
||||
unsigned HFETAlengthGiven : 1;
|
||||
unsigned HFETAwidthGiven : 1;
|
||||
unsigned HFETAicVDSGiven : 1;
|
||||
unsigned HFETAicVGSGiven : 1;
|
||||
unsigned HFETAtempGiven : 1;
|
||||
int HFETAmode;
|
||||
|
||||
double HFETAn0;
|
||||
double HFETAn01;
|
||||
double HFETAn02;
|
||||
double HFETAgchi0;
|
||||
double HFETAcf;
|
||||
double HFETAis1d;
|
||||
double HFETAis2d;
|
||||
double HFETAis1s;
|
||||
double HFETAis2s;
|
||||
double HFETAiso;
|
||||
double HFETAimax;
|
||||
double HFETAvcrit;
|
||||
double HFETAdelf;
|
||||
double HFETAfgds;
|
||||
double HFETAggrwl;
|
||||
|
||||
} HFETAinstance ;
|
||||
|
||||
|
||||
/* per model data */
|
||||
|
||||
typedef struct sHFETAmodel {
|
||||
int HFETAmodType;
|
||||
struct sHFETAmodel *HFETAnextModel;
|
||||
HFETAinstance *HFETAinstances;
|
||||
IFuid HFETAmodName;
|
||||
int HFETAtype;
|
||||
int HFETAgatemod;
|
||||
|
||||
double HFETAthreshold;
|
||||
double HFETAlambda;
|
||||
double HFETAeta;
|
||||
double HFETAm;
|
||||
double HFETAmc;
|
||||
double HFETAgamma;
|
||||
double HFETAsigma0;
|
||||
double HFETAvsigmat;
|
||||
double HFETAvsigma;
|
||||
double HFETAmu;
|
||||
double HFETAdi;
|
||||
double HFETAdelta;
|
||||
double HFETAvs;
|
||||
double HFETAnmax;
|
||||
double HFETAdeltad;
|
||||
double HFETAjs1d;
|
||||
double HFETAjs2d;
|
||||
double HFETAjs1s;
|
||||
double HFETAjs2s;
|
||||
double HFETAm1d;
|
||||
double HFETAm2d;
|
||||
double HFETAm1s;
|
||||
double HFETAm2s;
|
||||
double HFETArd;
|
||||
double HFETArs;
|
||||
double HFETArg;
|
||||
double HFETArdi;
|
||||
double HFETArsi;
|
||||
double HFETArgs;
|
||||
double HFETArgd;
|
||||
double HFETAri;
|
||||
double HFETArf;
|
||||
double HFETAepsi;
|
||||
double HFETAa1;
|
||||
double HFETAa2;
|
||||
double HFETAmv1;
|
||||
double HFETAp;
|
||||
double HFETAkappa;
|
||||
double HFETAdelf;
|
||||
double HFETAfgds;
|
||||
double HFETAtf;
|
||||
double HFETAcds;
|
||||
double HFETAphib;
|
||||
double HFETAtalpha;
|
||||
double HFETAmt1;
|
||||
double HFETAmt2;
|
||||
double HFETAck1;
|
||||
double HFETAck2;
|
||||
double HFETAcm1;
|
||||
double HFETAcm2;
|
||||
double HFETAcm3;
|
||||
double HFETAastar;
|
||||
double HFETAeta1;
|
||||
double HFETAd1;
|
||||
double HFETAvt1;
|
||||
double HFETAeta2;
|
||||
double HFETAd2;
|
||||
double HFETAvt2;
|
||||
double HFETAggr;
|
||||
double HFETAdel;
|
||||
double HFETAklambda;
|
||||
double HFETAkmu;
|
||||
double HFETAkvto;
|
||||
|
||||
double HFETAdrainConduct;
|
||||
double HFETAsourceConduct;
|
||||
double HFETAgateConduct;
|
||||
double HFETAgi;
|
||||
double HFETAgf;
|
||||
double HFETAdeltaSqr;
|
||||
|
||||
unsigned HFETAgatemodGiven:1;
|
||||
unsigned HFETAthresholdGiven:1;
|
||||
unsigned HFETAlambdaGiven:1;
|
||||
unsigned HFETAetaGiven:1;
|
||||
unsigned HFETAmGiven:1;
|
||||
unsigned HFETAmcGiven:1;
|
||||
unsigned HFETAgammaGiven:1;
|
||||
unsigned HFETAsigma0Given:1;
|
||||
unsigned HFETAvsigmatGiven:1;
|
||||
unsigned HFETAvsigmaGiven:1;
|
||||
unsigned HFETAmuGiven:1;
|
||||
unsigned HFETAdiGiven:1;
|
||||
unsigned HFETAdeltaGiven:1;
|
||||
unsigned HFETAvsGiven:1;
|
||||
unsigned HFETAnmaxGiven:1;
|
||||
unsigned HFETAdeltadGiven:1;
|
||||
unsigned HFETAjs1dGiven:1;
|
||||
unsigned HFETAjs2dGiven:1;
|
||||
unsigned HFETAjs1sGiven:1;
|
||||
unsigned HFETAjs2sGiven:1;
|
||||
unsigned HFETAm1dGiven:1;
|
||||
unsigned HFETAm2dGiven:1;
|
||||
unsigned HFETAm1sGiven:1;
|
||||
unsigned HFETAm2sGiven:1;
|
||||
unsigned HFETArdGiven:1;
|
||||
unsigned HFETArsGiven:1;
|
||||
unsigned HFETArgGiven:1;
|
||||
unsigned HFETArdiGiven:1;
|
||||
unsigned HFETArsiGiven:1;
|
||||
unsigned HFETArgsGiven:1;
|
||||
unsigned HFETArgdGiven:1;
|
||||
unsigned HFETAriGiven:1;
|
||||
unsigned HFETArfGiven:1;
|
||||
unsigned HFETAepsiGiven:1;
|
||||
unsigned HFETAa1Given:1;
|
||||
unsigned HFETAa2Given:1;
|
||||
unsigned HFETAmv1Given:1;
|
||||
unsigned HFETApGiven:1;
|
||||
unsigned HFETAkappaGiven:1;
|
||||
unsigned HFETAdelfGiven:1;
|
||||
unsigned HFETAfgdsGiven:1;
|
||||
unsigned HFETAtfGiven:1;
|
||||
unsigned HFETAcdsGiven:1;
|
||||
unsigned HFETAphibGiven:1;
|
||||
unsigned HFETAtalphaGiven:1;
|
||||
unsigned HFETAmt1Given:1;
|
||||
unsigned HFETAmt2Given:1;
|
||||
unsigned HFETAck1Given:1;
|
||||
unsigned HFETAck2Given:1;
|
||||
unsigned HFETAcm1Given:1;
|
||||
unsigned HFETAcm2Given:1;
|
||||
unsigned HFETAcm3Given:1;
|
||||
unsigned HFETAastarGiven:1;
|
||||
unsigned HFETAeta1Given:1;
|
||||
unsigned HFETAd1Given:1;
|
||||
unsigned HFETAvt1Given:1;
|
||||
unsigned HFETAeta2Given:1;
|
||||
unsigned HFETAd2Given:1;
|
||||
unsigned HFETAvt2Given:1;
|
||||
unsigned HFETAggrGiven:1;
|
||||
unsigned HFETAdelGiven:1;
|
||||
unsigned HFETAklambdaGiven:1;
|
||||
unsigned HFETAkmuGiven:1;
|
||||
unsigned HFETAkvtoGiven:1;
|
||||
|
||||
} HFETAmodel;
|
||||
|
||||
#ifndef NHFET
|
||||
#define NHFET 1
|
||||
#define PHFET -1
|
||||
#endif
|
||||
|
||||
/* device parameters */
|
||||
#define HFETA_LENGTH 1
|
||||
#define HFETA_WIDTH 2
|
||||
#define HFETA_IC_VDS 3
|
||||
#define HFETA_IC_VGS 4
|
||||
#define HFETA_TEMP 5
|
||||
#define HFETA_IC 6
|
||||
#define HFETA_OFF 7
|
||||
#define HFETA_CS 8
|
||||
#define HFETA_POWER 9
|
||||
|
||||
/* model parameters */
|
||||
#define HFETA_MOD_VTO 101
|
||||
#define HFETA_MOD_LAMBDA 102
|
||||
#define HFETA_MOD_RD 103
|
||||
#define HFETA_MOD_RS 104
|
||||
#define HFETA_MOD_RG 105
|
||||
#define HFETA_MOD_RGS 106
|
||||
#define HFETA_MOD_RGD 107
|
||||
#define HFETA_MOD_RI 108
|
||||
#define HFETA_MOD_RF 109
|
||||
#define HFETA_MOD_ETA 110
|
||||
#define HFETA_MOD_M 111
|
||||
#define HFETA_MOD_MC 112
|
||||
#define HFETA_MOD_GAMMA 113
|
||||
#define HFETA_MOD_SIGMA0 114
|
||||
#define HFETA_MOD_VSIGMAT 115
|
||||
#define HFETA_MOD_VSIGMA 116
|
||||
#define HFETA_MOD_MU 117
|
||||
#define HFETA_MOD_DI 118
|
||||
#define HFETA_MOD_DELTA 119
|
||||
#define HFETA_MOD_VS 120
|
||||
#define HFETA_MOD_NMAX 121
|
||||
#define HFETA_MOD_DELTAD 122
|
||||
#define HFETA_MOD_JS1D 123
|
||||
#define HFETA_MOD_JS2D 124
|
||||
#define HFETA_MOD_JS1S 125
|
||||
#define HFETA_MOD_JS2S 126
|
||||
#define HFETA_MOD_M1D 127
|
||||
#define HFETA_MOD_M2D 128
|
||||
#define HFETA_MOD_M1S 129
|
||||
#define HFETA_MOD_M2S 130
|
||||
#define HFETA_MOD_EPSI 132
|
||||
#define HFETA_MOD_RDI 133
|
||||
#define HFETA_MOD_RSI 134
|
||||
#define HFETA_MOD_A1 135
|
||||
#define HFETA_MOD_A2 136
|
||||
#define HFETA_MOD_MV1 137
|
||||
#define HFETA_MOD_P 138
|
||||
#define HFETA_MOD_KAPPA 139
|
||||
#define HFETA_MOD_DELF 140
|
||||
#define HFETA_MOD_FGDS 141
|
||||
#define HFETA_MOD_TF 142
|
||||
#define HFETA_MOD_CDS 143
|
||||
#define HFETA_MOD_PHIB 144
|
||||
#define HFETA_MOD_TALPHA 145
|
||||
#define HFETA_MOD_MT1 146
|
||||
#define HFETA_MOD_MT2 147
|
||||
#define HFETA_MOD_CK1 148
|
||||
#define HFETA_MOD_CK2 149
|
||||
#define HFETA_MOD_CM1 150
|
||||
#define HFETA_MOD_CM2 151
|
||||
#define HFETA_MOD_CM3 152
|
||||
#define HFETA_MOD_ASTAR 153
|
||||
#define HFETA_MOD_ETA1 154
|
||||
#define HFETA_MOD_D1 155
|
||||
#define HFETA_MOD_VT1 156
|
||||
#define HFETA_MOD_ETA2 157
|
||||
#define HFETA_MOD_D2 158
|
||||
#define HFETA_MOD_VT2 159
|
||||
#define HFETA_MOD_GGR 160
|
||||
#define HFETA_MOD_DEL 161
|
||||
#define HFETA_MOD_GATEMOD 162
|
||||
#define HFETA_MOD_KLAMBDA 163
|
||||
#define HFETA_MOD_KMU 164
|
||||
#define HFETA_MOD_KVTO 165
|
||||
#define HFETA_MOD_NHFET 166
|
||||
#define HFETA_MOD_PHFET 167
|
||||
#define HFETA_MOD_TYPE 168
|
||||
|
||||
/* device questions */
|
||||
|
||||
#define HFETA_DRAINNODE 201
|
||||
#define HFETA_GATENODE 202
|
||||
#define HFETA_SOURCENODE 203
|
||||
#define HFETA_DRAINPRIMENODE 204
|
||||
#define HFETA_SOURCEPRIMENODE 205
|
||||
|
||||
#define HFETA_VGS 206
|
||||
#define HFETA_VGD 207
|
||||
#define HFETA_CG 208
|
||||
#define HFETA_CD 209
|
||||
#define HFETA_CGD 210
|
||||
#define HFETA_GM 211
|
||||
#define HFETA_GDS 212
|
||||
#define HFETA_GGS 213
|
||||
#define HFETA_GGD 214
|
||||
#define HFETA_QGS 215
|
||||
#define HFETA_CQGS 216
|
||||
#define HFETA_QGD 217
|
||||
#define HFETA_CQGD 218
|
||||
|
||||
/* model questions */
|
||||
|
||||
#define HFETA_MOD_DRAINCONDUCT 301
|
||||
#define HFETA_MOD_SOURCECONDUCT 302
|
||||
#define HFETA_MOD_DEPLETIONCAP 303
|
||||
#define HFETA_MOD_VCRIT 304
|
||||
|
||||
|
||||
#define L (here->HFETAlength)
|
||||
#define W (here->HFETAwidth)
|
||||
#define VTO (model->HFETAthreshold)
|
||||
#define LAMBDA (model->HFETAlambda)
|
||||
#define RDI (model->HFETArdi)
|
||||
#define RSI (model->HFETArsi)
|
||||
#define RD (model->HFETArd)
|
||||
#define RS (model->HFETArs)
|
||||
#define RG (model->HFETArg)
|
||||
#define RF (model->HFETArf)
|
||||
#define RI (model->HFETAri)
|
||||
#define RGS (model->HFETArgs)
|
||||
#define RGD (model->HFETArgd)
|
||||
#define ETA (model->HFETAeta)
|
||||
#define M (model->HFETAm)
|
||||
#define MC (model->HFETAmc)
|
||||
#define GAMMA (model->HFETAgamma)
|
||||
#define SIGMA0 (model->HFETAsigma0)
|
||||
#define VSIGMAT (model->HFETAvsigmat)
|
||||
#define VSIGMA (model->HFETAvsigma)
|
||||
#define MU (model->HFETAmu)
|
||||
#define DI (model->HFETAdi)
|
||||
#define DELTAD (model->HFETAdeltad)
|
||||
#define DELTASQR (model->HFETAdeltaSqr)
|
||||
#define VS (model->HFETAvs)
|
||||
#define NMAX (model->HFETAnmax)
|
||||
#define EPSI (model->HFETAepsi)
|
||||
#define JS1D (model->HFETAjs1d)
|
||||
#define JS2D (model->HFETAjs2d)
|
||||
#define JS1S (model->HFETAjs1s)
|
||||
#define JS2S (model->HFETAjs2s)
|
||||
#define M1D (model->HFETAm1d)
|
||||
#define M2D (model->HFETAm2d)
|
||||
#define M1S (model->HFETAm1s)
|
||||
#define M2S (model->HFETAm2s)
|
||||
#define ASTAR (model->HFETAastar)
|
||||
#define PHIB (model->HFETAphib)
|
||||
#define TALPHA (model->HFETAtalpha)
|
||||
#define MT1 (model->HFETAmt1)
|
||||
#define MT2 (model->HFETAmt2)
|
||||
#define CK1 (model->HFETAck1)
|
||||
#define CK2 (model->HFETAck2)
|
||||
#define CM1 (model->HFETAcm1)
|
||||
#define CM2 (model->HFETAcm2)
|
||||
#define CM3 (model->HFETAcm3)
|
||||
#define A1 (model->HFETAa1)
|
||||
#define A2 (model->HFETAa2)
|
||||
#define MV1 (model->HFETAmv1)
|
||||
#define PM (model->HFETAp)
|
||||
#define CDS (model->HFETAcds)
|
||||
#define ETA1 (model->HFETAeta1)
|
||||
#define D1 (model->HFETAd1)
|
||||
#define IN_VT1 (model->HFETAvt1) /* VT1 was defined in termios.h */
|
||||
#define ETA2 (model->HFETAeta2)
|
||||
#define D2 (model->HFETAd2)
|
||||
#define VT2 (model->HFETAvt2)
|
||||
#define GGR (model->HFETAggr)
|
||||
#define DEL (model->HFETAdel)
|
||||
#define KLAMBDA (model->HFETAklambda)
|
||||
#define KMU (model->HFETAkmu)
|
||||
#define KVTO (model->HFETAkvto)
|
||||
|
||||
#define GCHI0 (here->HFETAgchi0)
|
||||
#define N0 (here->HFETAn0)
|
||||
#define N01 (here->HFETAn01)
|
||||
#define N02 (here->HFETAn02)
|
||||
#define CF (here->HFETAcf)
|
||||
#define IMAX (here->HFETAimax)
|
||||
#define ISO (here->HFETAiso)
|
||||
#define TEMP (here->HFETAtemp)
|
||||
#define IS1D (here->HFETAis1d)
|
||||
#define IS2D (here->HFETAis2d)
|
||||
#define IS1S (here->HFETAis1s)
|
||||
#define IS2S (here->HFETAis2s)
|
||||
#define FGDS (here->HFETAfgds)
|
||||
#define DELF (here->HFETAdelf)
|
||||
#define GGRWL (here->HFETAggrwl)
|
||||
#define TLAMBDA (here->HFETAtLambda)
|
||||
#define TMU (here->HFETAtMu)
|
||||
#define TVTO (here->HFETAtVto)
|
||||
|
||||
#include "hfetext.h"
|
||||
|
||||
#endif /*HFETA*/
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 S. Hwang
|
||||
**********/
|
||||
/*
|
||||
Imported into hfeta model: Paolo Nenzi 2001
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "hfetdefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
HFETAdelete(inModel,name,inst)
|
||||
GENmodel *inModel;
|
||||
IFuid name;
|
||||
GENinstance **inst;
|
||||
{
|
||||
HFETAmodel *model = (HFETAmodel*)inModel;
|
||||
HFETAinstance **fast = (HFETAinstance**)inst;
|
||||
HFETAinstance **prev = NULL;
|
||||
HFETAinstance *here;
|
||||
|
||||
for( ; model ; model = model->HFETAnextModel) {
|
||||
prev = &(model->HFETAinstances);
|
||||
for(here = *prev; here ; here = *prev) {
|
||||
if(here->HFETAname == name || (fast && here==*fast) ) {
|
||||
*prev= here->HFETAnextInstance;
|
||||
FREE(here);
|
||||
return(OK);
|
||||
}
|
||||
prev = &(here->HFETAnextInstance);
|
||||
}
|
||||
}
|
||||
return(E_NODEV);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "hfetdefs.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
void
|
||||
HFETAdestroy(inModel)
|
||||
GENmodel **inModel;
|
||||
{
|
||||
HFETAmodel **model = (HFETAmodel**)inModel;
|
||||
HFETAinstance *here;
|
||||
HFETAinstance *prev = NULL;
|
||||
HFETAmodel *mod = *model;
|
||||
HFETAmodel *oldmod = NULL;
|
||||
|
||||
for( ; mod ; mod = mod->HFETAnextModel) {
|
||||
if(oldmod) FREE(oldmod);
|
||||
oldmod = mod;
|
||||
prev = (HFETAinstance *)NULL;
|
||||
for(here = mod->HFETAinstances ; here ; here = here->HFETAnextInstance) {
|
||||
if(prev) FREE(prev);
|
||||
prev = here;
|
||||
}
|
||||
if(prev) FREE(prev);
|
||||
}
|
||||
if(oldmod) FREE(oldmod);
|
||||
*model = NULL;
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#ifdef __STDC__
|
||||
extern int HFETAacLoad(GENmodel*,CKTcircuit*);
|
||||
extern int HFETAask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
||||
extern int HFETAdelete(GENmodel*,IFuid,GENinstance**);
|
||||
extern void HFETAdestroy(GENmodel**);
|
||||
extern int HFETAgetic(GENmodel*,CKTcircuit*);
|
||||
extern int HFETAload(GENmodel*,CKTcircuit*);
|
||||
extern int HFETAmAsk(CKTcircuit*,GENmodel*,int,IFvalue*);
|
||||
extern int HFETAmDelete(GENmodel**,IFuid,GENmodel*);
|
||||
extern int HFETAmParam(int,IFvalue*,GENmodel*);
|
||||
extern int HFETAparam(int,IFvalue*,GENinstance*,IFvalue*);
|
||||
extern int HFETAsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||
extern int HFETAtemp(GENmodel*,CKTcircuit*);
|
||||
extern int HFETAtrunc(GENmodel*,CKTcircuit*,double*);
|
||||
extern int HFETAunsetup(GENmodel*,CKTcircuit*);
|
||||
|
||||
#else /*stdc*/
|
||||
extern int HFETAacLoad();
|
||||
extern int HFETAask();
|
||||
extern int HFETAdelete();
|
||||
extern void HFETAdestroy();
|
||||
extern int HFETAgetic();
|
||||
extern int HFETAload();
|
||||
extern int HFETAmAsk();
|
||||
extern int HFETAmDelete();
|
||||
extern int HFETAmParam();
|
||||
extern int HFETAparam();
|
||||
extern int HFETAsetup();
|
||||
extern int HFETAtemp();
|
||||
extern int HFETAtrunc();
|
||||
extern int HFETAunsetup();
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
HFETAgetic(inModel,ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
HFETAmodel *model = (HFETAmodel*)inModel;
|
||||
HFETAinstance *here;
|
||||
/*
|
||||
* grab initial conditions out of rhs array. User specified, so use
|
||||
* external nodes to get values
|
||||
*/
|
||||
|
||||
for( ; model ; model = model->HFETAnextModel) {
|
||||
for(here = model->HFETAinstances; here ; here = here->HFETAnextInstance) {
|
||||
if(!here->HFETAicVDSGiven) {
|
||||
here->HFETAicVDS =
|
||||
*(ckt->CKTrhs + here->HFETAdrainNode) -
|
||||
*(ckt->CKTrhs + here->HFETAsourceNode);
|
||||
}
|
||||
if(!here->HFETAicVGSGiven) {
|
||||
here->HFETAicVGS =
|
||||
*(ckt->CKTrhs + here->HFETAgateNode) -
|
||||
*(ckt->CKTrhs + here->HFETAsourceNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#include <config.h>
|
||||
|
||||
#include <devdefs.h>
|
||||
|
||||
#include "hfetitf.h"
|
||||
#include "hfetext.h"
|
||||
#include "hfetinit.h"
|
||||
|
||||
|
||||
SPICEdev HFETAinfo = {
|
||||
{
|
||||
"HFET1",
|
||||
"HFET1 Model",
|
||||
|
||||
&HFETAnSize,
|
||||
&HFETAnSize,
|
||||
HFETAnames,
|
||||
|
||||
&HFETApTSize,
|
||||
HFETApTable,
|
||||
|
||||
&HFETAmPTSize,
|
||||
HFETAmPTable,
|
||||
DEV_DEFAULT
|
||||
},
|
||||
|
||||
DEVparam : HFETAparam,
|
||||
DEVmodParam : HFETAmParam,
|
||||
DEVload : HFETAload,
|
||||
DEVsetup : HFETAsetup,
|
||||
DEVunsetup : HFETAunsetup,
|
||||
DEVpzSetup : HFETAsetup,
|
||||
DEVtemperature: HFETAtemp,
|
||||
DEVtrunc : HFETAtrunc,
|
||||
DEVfindBranch : NULL,
|
||||
DEVacLoad : HFETAacLoad,
|
||||
DEVaccept : NULL,
|
||||
DEVdestroy : HFETAdestroy,
|
||||
DEVmodDelete : HFETAmDelete,
|
||||
DEVdelete : HFETAdelete,
|
||||
DEVsetic : HFETAgetic,
|
||||
DEVask : HFETAask,
|
||||
DEVmodAsk : HFETAmAsk,
|
||||
DEVpzLoad : NULL,
|
||||
DEVconvTest : NULL,
|
||||
DEVsenSetup : NULL,
|
||||
DEVsenLoad : NULL,
|
||||
DEVsenUpdate : NULL,
|
||||
DEVsenAcLoad : NULL,
|
||||
DEVsenPrint : NULL,
|
||||
DEVsenTrunc : NULL,
|
||||
DEVdisto : NULL,
|
||||
DEVnoise : NULL,
|
||||
|
||||
DEVinstSize : &HFETAiSize,
|
||||
DEVmodSize : &HFETAmSize
|
||||
|
||||
};
|
||||
|
||||
|
||||
SPICEdev *
|
||||
get_hfeta_info(void)
|
||||
{
|
||||
return &HFETAinfo;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef _HFETAINIT_H
|
||||
#define _HFETAINIT_H
|
||||
|
||||
extern IFparm HFETApTable[ ];
|
||||
extern IFparm HFETAmPTable[ ];
|
||||
extern char *HFETAnames[ ];
|
||||
extern int HFETApTSize;
|
||||
extern int HFETAmPTSize;
|
||||
extern int HFETAnSize;
|
||||
extern int HFETAiSize;
|
||||
extern int HFETAmSize;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef DEV_HFETA
|
||||
#define DEV_HFETA
|
||||
|
||||
SPICEdev *get_hfeta_info(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,787 @@
|
|||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "devdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "const.h"
|
||||
#include "trandefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
/*
|
||||
#define true 1
|
||||
#define false 0
|
||||
*/
|
||||
|
||||
//#define PHIB 0.5
|
||||
double diode(double);
|
||||
|
||||
static void leak(double gmin, double vt, double v, double rs, double is1,
|
||||
double is2, double m1, double m2, double *il, double *gl);
|
||||
|
||||
static void hfeta(HFETAmodel *model, HFETAinstance *here, CKTcircuit *ckt,
|
||||
double vgs, double vds, double *cdrain, double *gm,
|
||||
double *gds, double *capgs, double *capgd,
|
||||
double *cgd, double *gmg, double *gmd,
|
||||
double *cgs, double *ggs);
|
||||
|
||||
void Pause(void);
|
||||
|
||||
int HFETAload(inModel, ckt)
|
||||
GENmodel *inModel;
|
||||
register CKTcircuit *ckt;
|
||||
{
|
||||
register HFETAmodel *model = (HFETAmodel*)inModel;
|
||||
register HFETAinstance *here;
|
||||
double capgd;
|
||||
double capgs;
|
||||
double cd;
|
||||
double cdhat;
|
||||
double cdrain;
|
||||
double cdreq;
|
||||
double ceq;
|
||||
double ceqgd;
|
||||
double ceqgs;
|
||||
double cg;
|
||||
double cgd=0;
|
||||
double cgs=0;
|
||||
double cghat;
|
||||
double delvds;
|
||||
double delvgd;
|
||||
double delvgs;
|
||||
double delvgdpp=0;
|
||||
double delvgspp=0;
|
||||
double gds;
|
||||
double geq;
|
||||
double ggd=0;
|
||||
double ggs=0;
|
||||
double gm;
|
||||
double vcrit;
|
||||
double vds;
|
||||
double vgd;
|
||||
double vgs;
|
||||
double vgs1;
|
||||
double vgd1;
|
||||
double vds1;
|
||||
double xfact;
|
||||
double temp;
|
||||
double vt;
|
||||
double vgspp=0;
|
||||
double vgdpp=0;
|
||||
double cgspp=0;
|
||||
double cgdpp=0;
|
||||
double ggspp=0;
|
||||
double ggdpp=0;
|
||||
double gmg=0;
|
||||
double gmd=0;
|
||||
|
||||
int inverse=FALSE;
|
||||
int icheck;
|
||||
int error;
|
||||
|
||||
for( ; model != NULL; model = model->HFETAnextModel ) {
|
||||
for (here = model->HFETAinstances; here != NULL ;
|
||||
here=here->HFETAnextInstance) {
|
||||
vcrit = here->HFETAvcrit;
|
||||
vt = CONSTKoverQ * here->HFETAtemp;
|
||||
icheck = 0;
|
||||
if( ckt->CKTmode & MODEINITSMSIG) {
|
||||
vgs = *(ckt->CKTstate0 + here->HFETAvgs);
|
||||
vgd = *(ckt->CKTstate0 + here->HFETAvgd);
|
||||
vgspp = *(ckt->CKTstate0 + here->HFETAvgspp);
|
||||
vgdpp = *(ckt->CKTstate0 + here->HFETAvgdpp);
|
||||
} else if (ckt->CKTmode & MODEINITTRAN) {
|
||||
vgs = *(ckt->CKTstate1 + here->HFETAvgs);
|
||||
vgd = *(ckt->CKTstate1 + here->HFETAvgd);
|
||||
vgspp = *(ckt->CKTstate1 + here->HFETAvgspp);
|
||||
vgdpp = *(ckt->CKTstate1 + here->HFETAvgdpp);
|
||||
} else if ( (ckt->CKTmode & MODEINITJCT) &&
|
||||
(ckt->CKTmode & MODETRANOP) &&
|
||||
(ckt->CKTmode & MODEUIC) ) {
|
||||
vds = model->HFETAtype*here->HFETAicVDS;
|
||||
vgs = model->HFETAtype*here->HFETAicVGS;
|
||||
vgd = vgs-vds;
|
||||
vgspp = vgs;
|
||||
vgdpp = vgd;
|
||||
} else if ( (ckt->CKTmode & MODEINITJCT) &&
|
||||
(here->HFETAoff == 0) ) {
|
||||
vgs = -1;
|
||||
vgd = -1;
|
||||
vgspp = 0;
|
||||
vgdpp = 0;
|
||||
} else if( (ckt->CKTmode & MODEINITJCT) ||
|
||||
((ckt->CKTmode & MODEINITFIX) && (here->HFETAoff))) {
|
||||
vgs = 0;
|
||||
vgd = 0;
|
||||
vgspp = 0;
|
||||
vgdpp = 0;
|
||||
} else {
|
||||
#ifndef PREDICTOR
|
||||
if(ckt->CKTmode & MODEINITPRED) {
|
||||
xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2];
|
||||
*(ckt->CKTstate0 + here->HFETAvgs) =
|
||||
*(ckt->CKTstate1 + here->HFETAvgs);
|
||||
vgs = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgs) -
|
||||
xfact * *(ckt->CKTstate2 + here->HFETAvgs);
|
||||
*(ckt->CKTstate0 + here->HFETAvgspp) =
|
||||
*(ckt->CKTstate1 + here->HFETAvgspp);
|
||||
vgspp = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgspp) -
|
||||
xfact * *(ckt->CKTstate2 + here->HFETAvgspp);
|
||||
*(ckt->CKTstate0 + here->HFETAvgd) =
|
||||
*(ckt->CKTstate1 + here->HFETAvgd);
|
||||
vgd = (1+xfact)* *(ckt->CKTstate1 + here->HFETAvgd) -
|
||||
xfact * *(ckt->CKTstate2 + here->HFETAvgd);
|
||||
*(ckt->CKTstate0 + here->HFETAvgdpp) =
|
||||
*(ckt->CKTstate1 + here->HFETAvgdpp);
|
||||
vgdpp = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgdpp) -
|
||||
xfact * *(ckt->CKTstate2 + here->HFETAvgdpp);
|
||||
*(ckt->CKTstate0 + here->HFETAcg) =
|
||||
*(ckt->CKTstate1 + here->HFETAcg);
|
||||
*(ckt->CKTstate0 + here->HFETAcd) =
|
||||
*(ckt->CKTstate1 + here->HFETAcd);
|
||||
*(ckt->CKTstate0 + here->HFETAcgd) =
|
||||
*(ckt->CKTstate1 + here->HFETAcgd);
|
||||
*(ckt->CKTstate0 + here->HFETAcgs) =
|
||||
*(ckt->CKTstate1 + here->HFETAcgs);
|
||||
*(ckt->CKTstate0 + here->HFETAcgspp) =
|
||||
*(ckt->CKTstate1 + here->HFETAcgspp);
|
||||
*(ckt->CKTstate0 + here->HFETAcgdpp) =
|
||||
*(ckt->CKTstate1 + here->HFETAcgdpp);
|
||||
*(ckt->CKTstate0 + here->HFETAgm) =
|
||||
*(ckt->CKTstate1 + here->HFETAgm);
|
||||
*(ckt->CKTstate0 + here->HFETAgds) =
|
||||
*(ckt->CKTstate1 + here->HFETAgds);
|
||||
*(ckt->CKTstate0 + here->HFETAggs) =
|
||||
*(ckt->CKTstate1 + here->HFETAggs);
|
||||
*(ckt->CKTstate0 + here->HFETAggspp) =
|
||||
*(ckt->CKTstate1 + here->HFETAggspp);
|
||||
*(ckt->CKTstate0 + here->HFETAggd) =
|
||||
*(ckt->CKTstate1 + here->HFETAggd);
|
||||
*(ckt->CKTstate0 + here->HFETAggdpp) =
|
||||
*(ckt->CKTstate1 + here->HFETAggdpp);
|
||||
*(ckt->CKTstate0 + here->HFETAgmg) =
|
||||
*(ckt->CKTstate1 + here->HFETAgmg);
|
||||
*(ckt->CKTstate0 + here->HFETAgmd) =
|
||||
*(ckt->CKTstate1 + here->HFETAgmd);
|
||||
} else {
|
||||
#endif /* PREDICTOR */
|
||||
/*
|
||||
* compute new nonlinear branch voltages
|
||||
*/
|
||||
vgs = model->HFETAtype*
|
||||
(*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)-
|
||||
*(ckt->CKTrhsOld+
|
||||
here->HFETAsourcePrimeNode));
|
||||
vgd = model->HFETAtype*
|
||||
(*(ckt->CKTrhsOld+here->HFETAgatePrimeNode)-
|
||||
*(ckt->CKTrhsOld+
|
||||
here->HFETAdrainPrimeNode));
|
||||
vgspp = model->HFETAtype*
|
||||
(*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)-
|
||||
*(ckt->CKTrhsOld+
|
||||
here->HFETAsourcePrmPrmNode));
|
||||
vgdpp = model->HFETAtype*
|
||||
(*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)-
|
||||
*(ckt->CKTrhsOld+
|
||||
here->HFETAdrainPrmPrmNode));
|
||||
|
||||
#ifndef PREDICTOR
|
||||
}
|
||||
#endif /* PREDICTOR */
|
||||
delvgs=vgs - *(ckt->CKTstate0 + here->HFETAvgs);
|
||||
delvgd=vgd - *(ckt->CKTstate0 + here->HFETAvgd);
|
||||
delvds=delvgs - delvgd;
|
||||
delvgspp=vgspp - *(ckt->CKTstate0 + here->HFETAvgspp);
|
||||
delvgdpp=vgdpp - *(ckt->CKTstate0 + here->HFETAvgdpp);
|
||||
cghat= *(ckt->CKTstate0 + here->HFETAcg) +
|
||||
*(ckt->CKTstate0 + here->HFETAgmg)*delvgs -
|
||||
*(ckt->CKTstate0 + here->HFETAgmd)*delvds +
|
||||
*(ckt->CKTstate0 + here->HFETAggd)*delvgd +
|
||||
*(ckt->CKTstate0 + here->HFETAggs)*delvgs +
|
||||
*(ckt->CKTstate0 + here->HFETAggdpp)*delvgdpp +
|
||||
*(ckt->CKTstate0 + here->HFETAggspp)*delvgspp;
|
||||
cdhat= *(ckt->CKTstate0 + here->HFETAcd) +
|
||||
*(ckt->CKTstate0 + here->HFETAgm)*delvgs +
|
||||
*(ckt->CKTstate0 + here->HFETAgds)*delvds -
|
||||
*(ckt->CKTstate0 + here->HFETAggd)*delvgd -
|
||||
(*(ckt->CKTstate0 + here->HFETAgmg)*delvgs -
|
||||
*(ckt->CKTstate0 + here->HFETAgmd)*delvds);
|
||||
/*
|
||||
* bypass if solution has not changed
|
||||
*/
|
||||
if((ckt->CKTbypass) &&
|
||||
(!(ckt->CKTmode & MODEINITPRED)) &&
|
||||
(fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs),
|
||||
fabs(*(ckt->CKTstate0 + here->HFETAvgs)))+
|
||||
ckt->CKTvoltTol) )
|
||||
if ( (fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd),
|
||||
fabs(*(ckt->CKTstate0 + here->HFETAvgd)))+
|
||||
ckt->CKTvoltTol))
|
||||
if ( (fabs(delvgspp) < ckt->CKTreltol*MAX(fabs(vgspp),
|
||||
fabs(*(ckt->CKTstate0 + here->HFETAvgspp)))+
|
||||
ckt->CKTvoltTol))
|
||||
if ( (fabs(delvgdpp) < ckt->CKTreltol*MAX(fabs(vgdpp),
|
||||
fabs(*(ckt->CKTstate0 + here->HFETAvgdpp)))+
|
||||
ckt->CKTvoltTol))
|
||||
if ( (fabs(cghat-*(ckt->CKTstate0 + here->HFETAcg))
|
||||
< ckt->CKTreltol*MAX(fabs(cghat),
|
||||
fabs(*(ckt->CKTstate0 + here->HFETAcg)))+
|
||||
ckt->CKTabstol) ) if ( /* hack - expression too big */
|
||||
(fabs(cdhat-*(ckt->CKTstate0 + here->HFETAcd))
|
||||
< ckt->CKTreltol*MAX(fabs(cdhat),
|
||||
fabs(*(ckt->CKTstate0 + here->HFETAcd)))+
|
||||
ckt->CKTabstol) ) {
|
||||
|
||||
/* we can do a bypass */
|
||||
vgs = *(ckt->CKTstate0 + here->HFETAvgs);
|
||||
vgd = *(ckt->CKTstate0 + here->HFETAvgd);
|
||||
vds = vgs-vgd;
|
||||
vgspp = *(ckt->CKTstate0 + here->HFETAvgspp);
|
||||
vgdpp = *(ckt->CKTstate0 + here->HFETAvgdpp);
|
||||
cg = *(ckt->CKTstate0 + here->HFETAcg);
|
||||
cd = *(ckt->CKTstate0 + here->HFETAcd);
|
||||
cgd = *(ckt->CKTstate0 + here->HFETAcgd);
|
||||
cgs = *(ckt->CKTstate0 + here->HFETAcgs);
|
||||
cgdpp = *(ckt->CKTstate0 + here->HFETAcgdpp);
|
||||
cgspp = *(ckt->CKTstate0 + here->HFETAcgspp);
|
||||
gm = *(ckt->CKTstate0 + here->HFETAgm);
|
||||
gds = *(ckt->CKTstate0 + here->HFETAgds);
|
||||
ggs = *(ckt->CKTstate0 + here->HFETAggs);
|
||||
ggd = *(ckt->CKTstate0 + here->HFETAggd);
|
||||
ggdpp = *(ckt->CKTstate0 + here->HFETAggdpp);
|
||||
ggspp = *(ckt->CKTstate0 + here->HFETAggspp);
|
||||
gmg = *(ckt->CKTstate0 + here->HFETAgmg);
|
||||
gmd = *(ckt->CKTstate0 + here->HFETAgmd);
|
||||
goto load;
|
||||
}
|
||||
/*
|
||||
* limit nonlinear branch voltages
|
||||
*/
|
||||
vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->HFETAvgs),TVTO);
|
||||
vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->HFETAvgd),TVTO);
|
||||
}
|
||||
/*
|
||||
* determine dc current and derivatives
|
||||
*/
|
||||
vds = vgs-vgd;
|
||||
if(model->HFETAgatemod == 0) {
|
||||
double arg;
|
||||
double earg;
|
||||
if(IS1S == 0 || IS2S == 0) {
|
||||
cgs = 0;
|
||||
ggs = 0;
|
||||
} else
|
||||
leak(ckt->CKTgmin,vt,vgs,RGS,IS1S,IS2S,M1S,M2S,&cgs,&ggs);
|
||||
arg = -vgs*DEL/vt;
|
||||
earg = exp(arg);
|
||||
cgs += GGRWL*vgs*earg;
|
||||
ggs += GGRWL*earg*(1-arg);
|
||||
if(IS1D == 0 || IS2D == 0) {
|
||||
cgd = 0;
|
||||
ggd = 0;
|
||||
} else
|
||||
leak(ckt->CKTgmin,vt,vgd,RGD,IS1D,IS2D,M1D,M2D,&cgd,&ggd);
|
||||
arg = -vgd*DEL/vt;
|
||||
earg = exp(arg);
|
||||
cgd += GGRWL*vgd*earg;
|
||||
ggd += GGRWL*earg*(1-arg);
|
||||
} else
|
||||
ggd = 0;
|
||||
if(vds < 0) {
|
||||
vds = -vds;
|
||||
inverse = TRUE;
|
||||
}
|
||||
hfeta(model,here,ckt,vds>0?vgs:vgd,vds,&cdrain,&gm,&gds,&capgs,&capgd,
|
||||
&cgd,&gmg,&gmd,&cgs,&ggs);
|
||||
cg = cgs+cgd;
|
||||
if(inverse) {
|
||||
cdrain = -cdrain;
|
||||
vds = -vds;
|
||||
temp = capgs;
|
||||
capgs = capgd;
|
||||
capgd = temp;
|
||||
}
|
||||
/*
|
||||
* compute equivalent drain current source
|
||||
*/
|
||||
cd = cdrain - cgd;
|
||||
if ( (ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) ||
|
||||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){
|
||||
/*
|
||||
* charge storage elements
|
||||
*/
|
||||
vgs1 = *(ckt->CKTstate1 + here->HFETAvgspp);
|
||||
vgd1 = *(ckt->CKTstate1 + here->HFETAvgdpp);
|
||||
vds1 = *(ckt->CKTstate1 + here->HFETAvgs)-
|
||||
*(ckt->CKTstate1 + here->HFETAvgd);
|
||||
|
||||
if(ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->HFETAqgs) = capgs*vgspp;
|
||||
*(ckt->CKTstate1 + here->HFETAqgd) = capgd*vgdpp;
|
||||
*(ckt->CKTstate1 + here->HFETAqds) = CDS*vds;
|
||||
}
|
||||
*(ckt->CKTstate0+here->HFETAqgs) = *(ckt->CKTstate1 + here->HFETAqgs) +
|
||||
capgs*(vgspp-vgs1);
|
||||
*(ckt->CKTstate0+here->HFETAqgd) = *(ckt->CKTstate1 + here->HFETAqgd) +
|
||||
capgd*(vgdpp-vgd1);
|
||||
*(ckt->CKTstate0+here->HFETAqds) = *(ckt->CKTstate1 + here->HFETAqds) +
|
||||
CDS*(vds-vds1);
|
||||
|
||||
/*
|
||||
* store small-signal parameters
|
||||
*/
|
||||
if( (!(ckt->CKTmode & MODETRANOP)) ||
|
||||
(!(ckt->CKTmode & MODEUIC)) ) {
|
||||
if(ckt->CKTmode & MODEINITSMSIG) {
|
||||
*(ckt->CKTstate0 + here->HFETAqgs) = capgs;
|
||||
*(ckt->CKTstate0 + here->HFETAqgd) = capgd;
|
||||
*(ckt->CKTstate0 + here->HFETAqds) = CDS;
|
||||
continue; /*go to 1000*/
|
||||
}
|
||||
/*
|
||||
* transient analysis
|
||||
*/
|
||||
if(ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->HFETAqgs) =
|
||||
*(ckt->CKTstate0 + here->HFETAqgs);
|
||||
*(ckt->CKTstate1 + here->HFETAqgd) =
|
||||
*(ckt->CKTstate0 + here->HFETAqgd);
|
||||
*(ckt->CKTstate1 + here->HFETAqds) =
|
||||
*(ckt->CKTstate0 + here->HFETAqds);
|
||||
}
|
||||
error = NIintegrate(ckt,&geq,&ceq,capgs,here->HFETAqgs);
|
||||
if(error) return(error);
|
||||
ggspp = geq;
|
||||
cgspp = *(ckt->CKTstate0 + here->HFETAcqgs);
|
||||
cg = cg + cgspp;
|
||||
error = NIintegrate(ckt,&geq,&ceq,capgd,here->HFETAqgd);
|
||||
if(error) return(error);
|
||||
ggdpp = geq;
|
||||
cgdpp = *(ckt->CKTstate0 + here->HFETAcqgd);
|
||||
cg = cg + cgdpp;
|
||||
cd = cd - cgdpp;
|
||||
error = NIintegrate(ckt,&geq,&ceq,CDS,here->HFETAqds);
|
||||
if(error) return(error);
|
||||
gds += geq;
|
||||
cd += *(ckt->CKTstate0 + here->HFETAcqds);
|
||||
if (ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->HFETAcqgs) =
|
||||
*(ckt->CKTstate0 + here->HFETAcqgs);
|
||||
*(ckt->CKTstate1 + here->HFETAcqgd) =
|
||||
*(ckt->CKTstate0 + here->HFETAcqgd);
|
||||
*(ckt->CKTstate1 + here->HFETAcqds) =
|
||||
*(ckt->CKTstate0 + here->HFETAcqds);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* check convergence
|
||||
*/
|
||||
if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) {
|
||||
if( (icheck == 1)
|
||||
|| (fabs(cghat-cg) >= ckt->CKTreltol*
|
||||
MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) ||
|
||||
(fabs(cdhat-cd) > ckt->CKTreltol*
|
||||
MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol)
|
||||
|
||||
) {
|
||||
ckt->CKTnoncon++;
|
||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||
}
|
||||
}
|
||||
*(ckt->CKTstate0 + here->HFETAvgs) = vgs;
|
||||
*(ckt->CKTstate0 + here->HFETAvgd) = vgd;
|
||||
*(ckt->CKTstate0 + here->HFETAvgspp) = vgspp;
|
||||
*(ckt->CKTstate0 + here->HFETAvgdpp) = vgdpp;
|
||||
*(ckt->CKTstate0 + here->HFETAcg) = cg;
|
||||
*(ckt->CKTstate0 + here->HFETAcd) = cd;
|
||||
*(ckt->CKTstate0 + here->HFETAcgd) = cgd;
|
||||
*(ckt->CKTstate0 + here->HFETAcgs) = cgs;
|
||||
*(ckt->CKTstate0 + here->HFETAcgspp) = cgspp;
|
||||
*(ckt->CKTstate0 + here->HFETAcgdpp) = cgdpp;
|
||||
*(ckt->CKTstate0 + here->HFETAgm) = gm;
|
||||
*(ckt->CKTstate0 + here->HFETAgds) = gds;
|
||||
*(ckt->CKTstate0 + here->HFETAggs) = ggs;
|
||||
*(ckt->CKTstate0 + here->HFETAggd) = ggd;
|
||||
*(ckt->CKTstate0 + here->HFETAggspp) = ggspp;
|
||||
*(ckt->CKTstate0 + here->HFETAggdpp) = ggdpp;
|
||||
*(ckt->CKTstate0 + here->HFETAgmg) = gmg;
|
||||
*(ckt->CKTstate0 + here->HFETAgmd) = gmd;
|
||||
|
||||
/*
|
||||
* load current vector
|
||||
*/
|
||||
load:
|
||||
ceqgd = model->HFETAtype*(cgd+cgdpp-ggd*vgd-gmg*vgs-gmd*vds-ggdpp*vgdpp);
|
||||
ceqgs = model->HFETAtype*(cgs + cgspp - ggs*vgs - ggspp*vgspp);
|
||||
cdreq = model->HFETAtype*(cd + cgd + cgdpp - gds*vds - gm*vgs);
|
||||
*(ckt->CKTrhs + here->HFETAgatePrimeNode) += (-ceqgs-ceqgd);
|
||||
ceqgd = model->HFETAtype*(cgd-ggd*vgd-gmg*vgs-gmd*vds);
|
||||
*(ckt->CKTrhs + here->HFETAdrainPrimeNode) += (-cdreq+ceqgd);
|
||||
ceqgd = model->HFETAtype*(cgdpp-ggdpp*vgdpp);
|
||||
*(ckt->CKTrhs + here->HFETAdrainPrmPrmNode) += ceqgd;
|
||||
ceqgs = model->HFETAtype*(cgs-ggs*vgs);
|
||||
*(ckt->CKTrhs + here->HFETAsourcePrimeNode) += (cdreq+ceqgs);
|
||||
ceqgs = model->HFETAtype*(cgspp-ggspp*vgspp);
|
||||
*(ckt->CKTrhs + here->HFETAsourcePrmPrmNode) += ceqgs;
|
||||
|
||||
/*
|
||||
* load y matrix
|
||||
*/
|
||||
|
||||
*(here->HFETAdrainDrainPtr) += model->HFETAdrainConduct;
|
||||
*(here->HFETAsourceSourcePtr) += model->HFETAsourceConduct;
|
||||
*(here->HFETAgatePrimeGatePrimePtr) += (ggd+ggs+ggspp+ggdpp+gmg+model->HFETAgateConduct);
|
||||
*(here->HFETAdrainPrimeDrainPrimePtr) += (gds+ggd-gmd+model->HFETAdrainConduct+model->HFETAgf);
|
||||
*(here->HFETAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+model->HFETAsourceConduct+model->HFETAgi);
|
||||
*(here->HFETAsourcePrmPrmSourcePrmPrmPtr) += (model->HFETAgi+ggspp);
|
||||
*(here->HFETAdrainPrmPrmDrainPrmPrmPtr) += (model->HFETAgf+ggdpp);
|
||||
*(here->HFETAdrainDrainPrimePtr) -= model->HFETAdrainConduct;
|
||||
*(here->HFETAdrainPrimeDrainPtr) -= model->HFETAdrainConduct;
|
||||
*(here->HFETAsourceSourcePrimePtr) -= model->HFETAsourceConduct;
|
||||
*(here->HFETAsourcePrimeSourcePtr) -= model->HFETAsourceConduct;
|
||||
*(here->HFETAgatePrimeDrainPrimePtr) += -ggd+gmd;
|
||||
*(here->HFETAdrainPrimeGatePrimePtr) += (gm-ggd-gmg);
|
||||
*(here->HFETAgatePrimeSourcePrimePtr) -= ggs+gmg+gmd;
|
||||
*(here->HFETAsourcePrimeGatePrimePtr) += (-ggs-gm);
|
||||
*(here->HFETAdrainPrimeSourcePrimePtr) += (-gds-gm+gmg+gmd);
|
||||
*(here->HFETAsourcePrimeDrainPrimePtr) -= gds;
|
||||
*(here->HFETAsourcePrimeSourcePrmPrmPtr) -= model->HFETAgi;
|
||||
*(here->HFETAsourcePrmPrmSourcePrimePtr) -= model->HFETAgi;
|
||||
*(here->HFETAgatePrimeSourcePrmPrmPtr) -= ggspp;
|
||||
*(here->HFETAsourcePrmPrmGatePrimePtr) -= ggspp;
|
||||
*(here->HFETAdrainPrimeDrainPrmPrmPtr) -= model->HFETAgf;
|
||||
*(here->HFETAdrainPrmPrmDrainPrimePtr) -= model->HFETAgf;
|
||||
*(here->HFETAgatePrimeDrainPrmPrmPtr) -= ggdpp;
|
||||
*(here->HFETAdrainPrmPrmGatePrimePtr) -= ggdpp;
|
||||
*(here->HFETAgateGatePtr) += model->HFETAgateConduct;
|
||||
*(here->HFETAgateGatePrimePtr) -= model->HFETAgateConduct;
|
||||
*(here->HFETAgatePrimeGatePtr) -= model->HFETAgateConduct;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void leak(double gmin, double vt, double v, double rs, double is1, double is2,
|
||||
double m1, double m2, double *il, double *gl)
|
||||
|
||||
{
|
||||
|
||||
double vt1 = vt*m1;
|
||||
double vt2 = vt*m2;
|
||||
|
||||
if(v > -10*vt1) {
|
||||
double dvdi0;
|
||||
double iaprox;
|
||||
double iaprox1;
|
||||
double iaprox2;
|
||||
double v0;
|
||||
double vteff = vt1 + vt2;
|
||||
double iseff = is2*pow((is1/is2),(m1/(m1+m2)));
|
||||
if(rs > 0) {
|
||||
double unorm = (v + rs*is1)/vt1 + log(rs*is1/vt1);
|
||||
iaprox1 = vt1*diode(unorm)/rs - is1;
|
||||
unorm = (v + rs*iseff)/vteff + log(rs*iseff/vteff);
|
||||
iaprox2 = vteff*diode(unorm)/rs - iseff;
|
||||
} else {
|
||||
iaprox1 = is1*(exp(v/vt1) - 1);
|
||||
iaprox2 = iseff*(exp(v/vteff) - 1);
|
||||
}
|
||||
if((iaprox1*iaprox2) != 0.0)
|
||||
iaprox = 1./(1./iaprox1 + 1./iaprox2);
|
||||
else
|
||||
iaprox = 0.5*(iaprox1 + iaprox2);
|
||||
|
||||
dvdi0 = rs + vt1/(iaprox+is1) + vt2/(iaprox+is2);
|
||||
v0 = rs*iaprox;
|
||||
v0 += vt1*log(iaprox/is1 + 1) + vt2*log(iaprox/is2 + 1);
|
||||
//*il = __max(-is1,iaprox + (v - v0)/dvdi0)*0.99999;
|
||||
*il = MAX(-is1,iaprox + (v - v0)/dvdi0)*0.99999;
|
||||
*gl = 1./(rs + vt1/(*il+is1) + vt2/(*il+is2));
|
||||
} else {
|
||||
*gl = gmin;
|
||||
*il = (*gl)*v-is1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void hfeta(HFETAmodel *model, HFETAinstance *here, CKTcircuit *ckt,
|
||||
double vgs, double vds, double *cdrain, double *gm,
|
||||
double *gds, double *capgs, double *capgd,
|
||||
double *cgd, double *gmg, double *gmd,
|
||||
double *cgs, double *ggs)
|
||||
|
||||
{
|
||||
|
||||
double vt;
|
||||
double vgt;
|
||||
double vgt0;
|
||||
double sigma;
|
||||
double vgte;
|
||||
double isat;
|
||||
double isatm;
|
||||
double ns;
|
||||
double nsm;
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double f;
|
||||
double g;
|
||||
double h;
|
||||
double p;
|
||||
double q;
|
||||
double s;
|
||||
double t;
|
||||
double u;
|
||||
double nsc;
|
||||
double nsn;
|
||||
double temp;
|
||||
double etavth;
|
||||
double gch;
|
||||
double gchi;
|
||||
double gchim;
|
||||
double vsate;
|
||||
double vdse;
|
||||
double cg1;
|
||||
double cgc;
|
||||
double rt;
|
||||
double vl;
|
||||
double delidgch;
|
||||
double delgchgchi;
|
||||
double delgchins;
|
||||
double delnsnsm;
|
||||
double delnsmvgt;
|
||||
double delvgtevgt;
|
||||
double delidvsate;
|
||||
double delvsateisat;
|
||||
double delisatisatm;
|
||||
double delisatmvgte;
|
||||
double delisatmgchim;
|
||||
double delvsategch;
|
||||
double delidvds;
|
||||
double delvgtvgs;
|
||||
double delvsatevgt;
|
||||
|
||||
vt = CONSTKoverQ*TEMP;
|
||||
etavth = ETA*vt;
|
||||
vl = VS/TMU*L;
|
||||
rt = RSI+RDI;
|
||||
vgt0 = vgs - TVTO;
|
||||
s = exp((vgt0-VSIGMAT)/VSIGMA);
|
||||
sigma = SIGMA0/(1+s);
|
||||
vgt = vgt0+sigma*vds;
|
||||
u = 0.5*vgt/vt-1;
|
||||
t = sqrt(model->HFETAdeltaSqr+u*u);
|
||||
vgte = vt*(2+u+t);
|
||||
b = exp(vgt/etavth);
|
||||
if(model->HFETAeta2Given && model->HFETAd2Given) {
|
||||
nsc = N02*exp((vgt+TVTO-VT2)/(ETA2*vt));
|
||||
nsn = 2*N0*log(1+0.5*b);
|
||||
nsm = nsn*nsc/(nsn+nsc);
|
||||
} else {
|
||||
nsm = 2*N0*log(1+0.5*b);
|
||||
}
|
||||
if(nsm < 1.0e-38) {
|
||||
*cdrain = 0;
|
||||
*gm = 0.0;
|
||||
*gds = 0.0;
|
||||
*capgs = CF;
|
||||
*capgd = CF;
|
||||
goto cgd_calc;
|
||||
}
|
||||
c = pow(nsm/NMAX,GAMMA);
|
||||
q = pow(1+c,1.0/GAMMA);
|
||||
ns = nsm/q;
|
||||
gchi = GCHI0*ns;
|
||||
gch = gchi/(1+gchi*rt);
|
||||
gchim = GCHI0*nsm;
|
||||
h = sqrt(1+2*gchim*RSI + vgte*vgte/(vl*vl));
|
||||
p = 1+gchim*RSI+h;
|
||||
isatm = gchim*vgte/p;
|
||||
g = pow(isatm/IMAX,GAMMA);
|
||||
isat = isatm/pow(1+g,1/GAMMA);
|
||||
vsate = isat/gch;
|
||||
d = pow(vds/vsate,M);
|
||||
e = pow(1+d,1.0/M);
|
||||
delidgch = vds*(1+TLAMBDA*vds)/e;
|
||||
*cdrain = gch*delidgch;
|
||||
delidvsate = (*cdrain)*d/vsate/(1+d);
|
||||
delidvds = gch*(1+2*TLAMBDA*vds)/e-(*cdrain)*
|
||||
pow(vds/vsate,M-1)/(vsate*(1+d));
|
||||
a = 1+gchi*rt;
|
||||
delgchgchi = 1.0/(a*a);
|
||||
delgchins = GCHI0;
|
||||
delnsnsm = ns/nsm*(1-c/(1+c));
|
||||
delvgtevgt = 0.5*(1+u/t);
|
||||
delnsmvgt = N0/etavth/(1.0/b + 0.5);
|
||||
if(model->HFETAeta2Given && model->HFETAd2Given)
|
||||
delnsmvgt = nsc*(nsc*delnsmvgt+nsn*nsn/(ETA2*vt))/((nsc+nsn)*(nsc+nsn));
|
||||
delvsateisat = 1.0/gch;
|
||||
delisatisatm = isat/isatm*(1-g/(1+g));
|
||||
delisatmvgte = gchim*(p - vgte*vgte/(vl*vl*h))/(p*p);
|
||||
delvsategch = -vsate/gch;
|
||||
delisatmgchim = vgte*(p - gchim*RSI*(1+1.0/h))/(p*p);
|
||||
delvgtvgs = 1-vds*SIGMA0/VSIGMA*s/((1+s)*(1+s));
|
||||
p = delgchgchi*delgchins*delnsnsm*delnsmvgt;
|
||||
delvsatevgt = (delvsateisat*delisatisatm*(delisatmvgte*delvgtevgt +
|
||||
delisatmgchim*GCHI0*delnsmvgt)+delvsategch*p);
|
||||
g = delidgch*p + delidvsate*delvsatevgt;
|
||||
*gm = g*delvgtvgs;
|
||||
*gds = delidvds + g*sigma;
|
||||
|
||||
// Capacitance calculations
|
||||
temp = ETA1*vt;
|
||||
cg1 = 1/(D1/EPSI+temp*exp(-(vgs-IN_VT1)/temp));
|
||||
cgc = W*L*(CHARGE*delnsnsm*delnsmvgt*delvgtvgs+cg1);
|
||||
vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC);
|
||||
a = (vsate-vdse)/(2*vsate-vdse);
|
||||
a = a*a;
|
||||
temp = 2.0/3.0;
|
||||
p = PM + (1-PM)*exp(-vds/vsate);
|
||||
*capgs = CF+2*temp*cgc*(1-a)/(1+p);
|
||||
a = vsate/(2*vsate-vdse);
|
||||
a = a*a;
|
||||
*capgd = CF+2*p*temp*cgc*(1-a)/(1+p);
|
||||
/*
|
||||
{
|
||||
char buf[128];
|
||||
FILE *fp;
|
||||
fp = fopen("d:\\temp\\debug.txt","at");
|
||||
sprintf(buf,"%f\t%f\t%e\t%e\n",vgs,vds,W*L*CHARGE*delnsnsm*delnsmvgt*delvgtvgs,cgc);
|
||||
fputs(buf,fp);
|
||||
fclose(fp);
|
||||
}
|
||||
*/
|
||||
cgd_calc:
|
||||
|
||||
if(model->HFETAgatemod != 0) {
|
||||
// Gate-drain current calculation
|
||||
double vkneet;
|
||||
double vmax;
|
||||
double td;
|
||||
double delcgdvgs;
|
||||
double delcgdtd;
|
||||
double deltdvdse;
|
||||
double deltdvkneet;
|
||||
double delvdsevmax;
|
||||
double delvdsevds;
|
||||
double dvdsevgs;
|
||||
double dvdsevds;
|
||||
double dtdvgs;
|
||||
double dtdvds;
|
||||
|
||||
vkneet = CK1*vsate+CK2;
|
||||
vmax = CM1*vsate+CM2;
|
||||
a = pow(vds/vmax,MT2);
|
||||
b = pow(1+a,1/MT2);
|
||||
vdse = vds/b;
|
||||
c = pow(vdse/vkneet,MT1);
|
||||
d = pow(1+c,1/MT1);
|
||||
td = TEMP+TALPHA*vdse*vdse/d;
|
||||
e = CONSTKoverQ*td*M2D;
|
||||
p = PHIB/(CONSTboltz*td);
|
||||
f = exp(-p);
|
||||
q = (vgs-vdse)/e;
|
||||
g = exp(q);
|
||||
h = ISO*td*td*f*g;
|
||||
*cgd = h - ISO*TEMP*TEMP*exp(-PHIB/(CONSTboltz*TEMP));
|
||||
delcgdvgs = h/e;
|
||||
delcgdtd = h*(p-q+2)/td;
|
||||
deltdvdse = TALPHA*vdse*(2-c/(1+c))/d;
|
||||
deltdvkneet = (td-TEMP)*c/((1+c)*vkneet);
|
||||
delvdsevmax = vdse*a/((1+a)*vmax);
|
||||
delvdsevds = (1-a/(1+a))/b;
|
||||
temp = delvsatevgt*delvgtvgs;
|
||||
dvdsevgs = delvdsevmax*CM1*temp;
|
||||
dtdvgs = deltdvdse*dvdsevgs+deltdvkneet*CK1*temp;
|
||||
*gmg = delcgdvgs+delcgdtd*dtdvgs;
|
||||
temp = delvsatevgt*sigma;
|
||||
dvdsevds = delvdsevds+delvdsevmax*CM1*temp;
|
||||
dtdvds = deltdvdse*dvdsevds+deltdvkneet*CK1*temp;
|
||||
*gmd = -delcgdvgs*dvdsevds+delcgdtd*dtdvds;
|
||||
} else {
|
||||
gmg = 0;
|
||||
gmd = 0;
|
||||
}
|
||||
|
||||
if(model->HFETAgatemod != 0) {
|
||||
// Gate-source current calculation
|
||||
double evgs;
|
||||
double vtn = vt*M2S;
|
||||
double csat = ISO*TEMP*TEMP*exp(-PHIB/(CONSTboltz*TEMP));
|
||||
if (vgs <= -5*vt) {
|
||||
*ggs = -csat/vgs+ckt->CKTgmin;
|
||||
*cgs = (*ggs)*vgs;
|
||||
} else {
|
||||
evgs = exp(vgs/vtn);
|
||||
*ggs = csat*evgs/vtn+ckt->CKTgmin;
|
||||
*cgs = csat*(evgs-1)+ckt->CKTgmin*vgs;
|
||||
}
|
||||
}
|
||||
|
||||
if(model->HFETAgatemod != 0 && (A1 != 0.0 || A2 != 0.0)) {
|
||||
// Correction current calculations
|
||||
double vmax;
|
||||
double delvdsevmax;
|
||||
double delvdsevds;
|
||||
double dvdsevgs;
|
||||
double dvdsevds;
|
||||
vmax = CM3*vsate;
|
||||
a = pow(vds/vmax,MV1);
|
||||
b = pow(1+a,1/MV1);
|
||||
vdse = vds/b;
|
||||
delvdsevmax = vdse*a/((1+a)*vmax);
|
||||
delvdsevds = (1-a/(1+a))/b;
|
||||
dvdsevgs = delvdsevmax*CM3*delvsatevgt*delvgtvgs;
|
||||
dvdsevds = delvdsevds+delvdsevmax*CM3*delvsatevgt*sigma;
|
||||
c = vgte*vdse;
|
||||
d = 1+A2*c;
|
||||
e = vdse*delvgtevgt;
|
||||
f = A2*(*cgd);
|
||||
*cdrain += A1*(d*(*cgd) - (*cgs));
|
||||
*gds += A1*(d*(*gmd)+f*(vgte*dvdsevds+e*sigma));
|
||||
*gm += A1*(d*(*gmg)+f*(vgte*dvdsevgs+e*delvgtvgs) - (*ggs));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
double diode(double u)
|
||||
{
|
||||
|
||||
#define U0 (-2.303)
|
||||
#define A (2.221)
|
||||
#define B (6.804)
|
||||
#define C (1.685)
|
||||
double it;
|
||||
double ut;
|
||||
double b;
|
||||
double c;
|
||||
double i;
|
||||
double expu=exp(u);
|
||||
|
||||
if(u <= U0)
|
||||
{
|
||||
it = expu*(1-expu);
|
||||
}else
|
||||
{
|
||||
b = 0.5*(u-U0);
|
||||
it = u + A*exp((U0-u)/B) - log(b+sqrt(b*b + 0.25*C*C));
|
||||
}
|
||||
|
||||
ut = it + log(it);
|
||||
b = u-ut;
|
||||
c = 1+it;
|
||||
i = it*(1 + b/c + 0.5*b*b/c/c/c);
|
||||
return(i);
|
||||
}
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
**********/
|
||||
/*
|
||||
Imported into HFETA model: Paolo Nenzi 2001
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "devdefs.h"
|
||||
#include "ifsim.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
HFETAmAsk(ckt,inst,which,value)
|
||||
CKTcircuit *ckt;
|
||||
GENmodel *inst;
|
||||
int which;
|
||||
IFvalue *value;
|
||||
{
|
||||
HFETAmodel *here = (HFETAmodel*)inst;
|
||||
switch(which) {
|
||||
case HFETA_MOD_VTO:
|
||||
value->rValue = here->HFETAthreshold;
|
||||
return (OK);
|
||||
case HFETA_MOD_LAMBDA:
|
||||
value->rValue = here->HFETAlambda;
|
||||
return (OK);
|
||||
case HFETA_MOD_RD:
|
||||
value->rValue = here->HFETArd;
|
||||
return (OK);
|
||||
case HFETA_MOD_RS:
|
||||
value->rValue = here->HFETArs;
|
||||
return (OK);
|
||||
case HFETA_MOD_RG:
|
||||
value->rValue = here->HFETArg;
|
||||
return (OK);
|
||||
case HFETA_MOD_RDI:
|
||||
value->rValue = here->HFETArdi;
|
||||
return (OK);
|
||||
case HFETA_MOD_RSI:
|
||||
value->rValue = here->HFETArsi;
|
||||
return (OK);
|
||||
case HFETA_MOD_RGS:
|
||||
value->rValue = here->HFETArgs;
|
||||
return (OK);
|
||||
case HFETA_MOD_RGD:
|
||||
value->rValue = here->HFETArgd;
|
||||
return (OK);
|
||||
case HFETA_MOD_RI:
|
||||
value->rValue = here->HFETAri;
|
||||
return (OK);
|
||||
case HFETA_MOD_RF:
|
||||
value->rValue = here->HFETArf;
|
||||
return (OK);
|
||||
case HFETA_MOD_ETA:
|
||||
value->rValue = here->HFETAeta;
|
||||
return (OK);
|
||||
case HFETA_MOD_M:
|
||||
value->rValue = here->HFETAm;
|
||||
return (OK);
|
||||
case HFETA_MOD_MC:
|
||||
value->rValue = here->HFETAmc;
|
||||
return (OK);
|
||||
case HFETA_MOD_GAMMA:
|
||||
value->rValue = here->HFETAgamma;
|
||||
return (OK);
|
||||
case HFETA_MOD_SIGMA0:
|
||||
value->rValue = here->HFETAsigma0;
|
||||
return (OK);
|
||||
case HFETA_MOD_VSIGMAT:
|
||||
value->rValue = here->HFETAvsigmat;
|
||||
return (OK);
|
||||
case HFETA_MOD_VSIGMA:
|
||||
value->rValue = here->HFETAvsigma;
|
||||
return (OK);
|
||||
case HFETA_MOD_MU:
|
||||
value->rValue = here->HFETAmu;
|
||||
return (OK);
|
||||
case HFETA_MOD_DI:
|
||||
value->rValue = here->HFETAdi;
|
||||
return (OK);
|
||||
case HFETA_MOD_DELTA:
|
||||
value->rValue = here->HFETAdelta;
|
||||
return (OK);
|
||||
case HFETA_MOD_VS:
|
||||
value->rValue = here->HFETAvs;
|
||||
return (OK);
|
||||
case HFETA_MOD_NMAX:
|
||||
value->rValue = here->HFETAnmax;
|
||||
return (OK);
|
||||
case HFETA_MOD_DELTAD:
|
||||
value->rValue = here->HFETAdeltad;
|
||||
return (OK);
|
||||
case HFETA_MOD_JS1D:
|
||||
value->rValue = here->HFETAjs1d;
|
||||
return (OK);
|
||||
case HFETA_MOD_JS2D:
|
||||
value->rValue = here->HFETAjs2d;
|
||||
return (OK);
|
||||
case HFETA_MOD_JS1S:
|
||||
value->rValue = here->HFETAjs1s;
|
||||
return (OK);
|
||||
case HFETA_MOD_JS2S:
|
||||
value->rValue = here->HFETAjs2s;
|
||||
return (OK);
|
||||
case HFETA_MOD_M1D:
|
||||
value->rValue = here->HFETAm1d;
|
||||
return (OK);
|
||||
case HFETA_MOD_M2D:
|
||||
value->rValue = here->HFETAm2d;
|
||||
return (OK);
|
||||
case HFETA_MOD_M1S:
|
||||
value->rValue = here->HFETAm1s;
|
||||
return (OK);
|
||||
case HFETA_MOD_M2S:
|
||||
value->rValue = here->HFETAm2s;
|
||||
return (OK);
|
||||
case HFETA_MOD_EPSI:
|
||||
value->rValue = here->HFETAepsi;
|
||||
return (OK);
|
||||
case HFETA_MOD_P:
|
||||
value->rValue = here->HFETAp;
|
||||
return (OK);
|
||||
case HFETA_MOD_CM3:
|
||||
value->rValue = here->HFETAcm3;
|
||||
return (OK);
|
||||
case HFETA_MOD_A1:
|
||||
value->rValue = here->HFETAa1;
|
||||
return (OK);
|
||||
case HFETA_MOD_A2:
|
||||
value->rValue = here->HFETAa2;
|
||||
return (OK);
|
||||
case HFETA_MOD_MV1:
|
||||
value->rValue = here->HFETAmv1;
|
||||
return (OK);
|
||||
case HFETA_MOD_KAPPA:
|
||||
value->rValue = here->HFETAkappa;
|
||||
return (OK);
|
||||
case HFETA_MOD_DELF:
|
||||
value->rValue = here->HFETAdelf;
|
||||
return (OK);
|
||||
case HFETA_MOD_FGDS:
|
||||
value->rValue = here->HFETAfgds;
|
||||
return (OK);
|
||||
case HFETA_MOD_TF:
|
||||
value->rValue = here->HFETAtf;
|
||||
return (OK);
|
||||
case HFETA_MOD_CDS:
|
||||
value->rValue = here->HFETAcds;
|
||||
return (OK);
|
||||
case HFETA_MOD_PHIB:
|
||||
value->rValue = here->HFETAphib;
|
||||
return (OK);
|
||||
|
||||
case HFETA_MOD_TALPHA:
|
||||
value->rValue = here->HFETAtalpha;
|
||||
return (OK);
|
||||
case HFETA_MOD_MT1:
|
||||
value->rValue = here->HFETAmt1;
|
||||
return (OK);
|
||||
case HFETA_MOD_MT2:
|
||||
value->rValue = here->HFETAmt2;
|
||||
return (OK);
|
||||
case HFETA_MOD_CK1:
|
||||
value->rValue = here->HFETAck1;
|
||||
return (OK);
|
||||
case HFETA_MOD_CK2:
|
||||
value->rValue = here->HFETAck2;
|
||||
return (OK);
|
||||
case HFETA_MOD_CM1:
|
||||
value->rValue = here->HFETAcm1;
|
||||
return (OK);
|
||||
case HFETA_MOD_CM2:
|
||||
value->rValue = here->HFETAcm2;
|
||||
return (OK);
|
||||
case HFETA_MOD_ASTAR:
|
||||
value->rValue = here->HFETAastar;
|
||||
return (OK);
|
||||
case HFETA_MOD_ETA1:
|
||||
value->rValue = here->HFETAeta1;
|
||||
return (OK);
|
||||
case HFETA_MOD_D1:
|
||||
value->rValue = here->HFETAd1;
|
||||
return (OK);
|
||||
case HFETA_MOD_VT1:
|
||||
value->rValue = here->HFETAvt1;
|
||||
return (OK);
|
||||
case HFETA_MOD_ETA2:
|
||||
value->rValue = here->HFETAeta2;
|
||||
return (OK);
|
||||
case HFETA_MOD_D2:
|
||||
value->rValue = here->HFETAd2;
|
||||
return (OK);
|
||||
case HFETA_MOD_VT2:
|
||||
value->rValue = here->HFETAvt2;
|
||||
return (OK);
|
||||
case HFETA_MOD_GGR:
|
||||
value->rValue = here->HFETAggr;
|
||||
return (OK);
|
||||
case HFETA_MOD_DEL:
|
||||
value->rValue = here->HFETAdel;
|
||||
return (OK);
|
||||
case HFETA_MOD_GATEMOD:
|
||||
value->iValue = here->HFETAgatemod;
|
||||
return (OK);
|
||||
case HFETA_MOD_KLAMBDA:
|
||||
value->rValue = here->HFETAklambda;
|
||||
return (OK);
|
||||
case HFETA_MOD_KMU:
|
||||
value->rValue = here->HFETAkmu;
|
||||
return (OK);
|
||||
case HFETA_MOD_KVTO:
|
||||
value->rValue = here->HFETAkvto;
|
||||
return (OK);
|
||||
|
||||
case HFETA_MOD_DRAINCONDUCT:
|
||||
value->rValue = here->HFETAdrainConduct;
|
||||
return (OK);
|
||||
case HFETA_MOD_SOURCECONDUCT:
|
||||
value->rValue = here->HFETAsourceConduct;
|
||||
return (OK);
|
||||
/* case HFETA_MOD_DEPLETIONCAP:
|
||||
value->rValue = here->HFETA???;
|
||||
return(OK); */
|
||||
/* case HFETA_MOD_VCRIT:
|
||||
value->rValue = here->HFETAvcrit;
|
||||
return (OK); */
|
||||
|
||||
case HFETA_MOD_TYPE:
|
||||
if (here->HFETAtype == NHFET)
|
||||
value->sValue = "nhfet";
|
||||
else
|
||||
value->sValue = "phfet";
|
||||
default:
|
||||
return (E_BADPARM);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 S. Hwang
|
||||
**********/
|
||||
/*
|
||||
Imported into hfeta model: Paolo Nenzi 2001
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "hfetdefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
HFETAmDelete(inModel,modname,kill)
|
||||
GENmodel **inModel;
|
||||
IFuid modname;
|
||||
GENmodel *kill;
|
||||
{
|
||||
HFETAmodel **model = (HFETAmodel**)inModel;
|
||||
HFETAmodel *modfast = (HFETAmodel*)kill;
|
||||
HFETAinstance *here;
|
||||
HFETAinstance *prev = NULL;
|
||||
HFETAmodel **oldmod;
|
||||
oldmod = model;
|
||||
for( ; *model ; model = &((*model)->HFETAnextModel)) {
|
||||
if( (*model)->HFETAmodName == modname ||
|
||||
(modfast && *model == modfast) ) goto delgot;
|
||||
oldmod = model;
|
||||
}
|
||||
return(E_NOMOD);
|
||||
|
||||
delgot:
|
||||
*oldmod = (*model)->HFETAnextModel; /* cut deleted device out of list */
|
||||
for(here = (*model)->HFETAinstances ; here ; here = here->HFETAnextInstance) {
|
||||
if(prev) FREE(prev);
|
||||
prev = here;
|
||||
}
|
||||
if(prev) FREE(prev);
|
||||
FREE(*model);
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,290 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "const.h"
|
||||
#include "ifsim.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
HFETAmParam(param,value,inModel)
|
||||
int param;
|
||||
IFvalue *value;
|
||||
GENmodel *inModel;
|
||||
{
|
||||
HFETAmodel *model = (HFETAmodel*)inModel;
|
||||
switch(param)
|
||||
{
|
||||
case HFETA_MOD_VTO:
|
||||
model->HFETAthresholdGiven = TRUE;
|
||||
model->HFETAthreshold = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_LAMBDA:
|
||||
model->HFETAlambdaGiven = TRUE;
|
||||
model->HFETAlambda = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_RD:
|
||||
model->HFETArdGiven = TRUE;
|
||||
model->HFETArd = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_RS:
|
||||
model->HFETArsGiven = TRUE;
|
||||
model->HFETArs = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_RG:
|
||||
model->HFETArgGiven = TRUE;
|
||||
model->HFETArg = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_RDI:
|
||||
model->HFETArdiGiven = TRUE;
|
||||
model->HFETArdi = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_RSI:
|
||||
model->HFETArsiGiven = TRUE;
|
||||
model->HFETArsi = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_RGS:
|
||||
model->HFETArgsGiven = TRUE;
|
||||
model->HFETArgs = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_RGD:
|
||||
model->HFETArgdGiven = TRUE;
|
||||
model->HFETArgd = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_RI:
|
||||
model->HFETAriGiven = TRUE;
|
||||
model->HFETAri = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_RF:
|
||||
model->HFETArfGiven = TRUE;
|
||||
model->HFETArf = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_ETA:
|
||||
model->HFETAetaGiven = TRUE;
|
||||
model->HFETAeta = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_M:
|
||||
model->HFETAmGiven = TRUE;
|
||||
model->HFETAm = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_MC:
|
||||
model->HFETAmcGiven = TRUE;
|
||||
model->HFETAmc = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_GAMMA:
|
||||
model->HFETAgammaGiven = TRUE;
|
||||
model->HFETAgamma = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_SIGMA0:
|
||||
model->HFETAsigma0Given = TRUE;
|
||||
model->HFETAsigma0 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_VSIGMAT:
|
||||
model->HFETAvsigmatGiven = TRUE;
|
||||
model->HFETAvsigmat = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_VSIGMA:
|
||||
model->HFETAvsigmaGiven = TRUE;
|
||||
model->HFETAvsigma = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_MU:
|
||||
model->HFETAmuGiven = TRUE;
|
||||
model->HFETAmu = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_DI:
|
||||
model->HFETAdiGiven = TRUE;
|
||||
model->HFETAdi = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_DELTA:
|
||||
model->HFETAdeltaGiven = TRUE;
|
||||
model->HFETAdelta = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_VS:
|
||||
model->HFETAvsGiven = TRUE;
|
||||
model->HFETAvs = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_NMAX:
|
||||
model->HFETAnmaxGiven = TRUE;
|
||||
model->HFETAnmax = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_DELTAD:
|
||||
model->HFETAdeltadGiven = TRUE;
|
||||
model->HFETAdeltad = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_JS1D:
|
||||
model->HFETAjs1dGiven = TRUE;
|
||||
model->HFETAjs1d = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_JS2D:
|
||||
model->HFETAjs2dGiven = TRUE;
|
||||
model->HFETAjs2d = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_JS1S:
|
||||
model->HFETAjs1sGiven = TRUE;
|
||||
model->HFETAjs1s = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_JS2S:
|
||||
model->HFETAjs2sGiven = TRUE;
|
||||
model->HFETAjs2s = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_M1D:
|
||||
model->HFETAm1dGiven = TRUE;
|
||||
model->HFETAm1d = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_M2D:
|
||||
model->HFETAm2dGiven = TRUE;
|
||||
model->HFETAm2d = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_M1S:
|
||||
model->HFETAm1sGiven = TRUE;
|
||||
model->HFETAm1s = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_M2S:
|
||||
model->HFETAm2sGiven = TRUE;
|
||||
model->HFETAm2s = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_EPSI:
|
||||
model->HFETAepsiGiven = TRUE;
|
||||
model->HFETAepsi = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_A1:
|
||||
model->HFETAa1Given = TRUE;
|
||||
model->HFETAa1 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_A2:
|
||||
model->HFETAa2Given = TRUE;
|
||||
model->HFETAa2 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_MV1:
|
||||
model->HFETAmv1Given = TRUE;
|
||||
model->HFETAmv1 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_P:
|
||||
model->HFETApGiven = TRUE;
|
||||
model->HFETAp = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_KAPPA:
|
||||
model->HFETAkappaGiven = TRUE;
|
||||
model->HFETAkappa = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_DELF:
|
||||
model->HFETAdelfGiven = TRUE;
|
||||
model->HFETAdelf = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_FGDS:
|
||||
model->HFETAfgdsGiven = TRUE;
|
||||
model->HFETAfgds = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_TF:
|
||||
model->HFETAtfGiven = TRUE;
|
||||
model->HFETAtf = value->rValue+CONSTCtoK;
|
||||
break;
|
||||
case HFETA_MOD_CDS:
|
||||
model->HFETAcdsGiven = TRUE;
|
||||
model->HFETAcds = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_PHIB:
|
||||
model->HFETAphibGiven = TRUE;
|
||||
model->HFETAphib = value->rValue*CHARGE;
|
||||
break;
|
||||
case HFETA_MOD_TALPHA:
|
||||
model->HFETAtalphaGiven = TRUE;
|
||||
model->HFETAtalpha = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_MT1:
|
||||
model->HFETAmt1Given = TRUE;
|
||||
model->HFETAmt1 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_MT2:
|
||||
model->HFETAmt2Given = TRUE;
|
||||
model->HFETAmt2 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_CK1:
|
||||
model->HFETAck1Given = TRUE;
|
||||
model->HFETAck1 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_CK2:
|
||||
model->HFETAck2Given = TRUE;
|
||||
model->HFETAck2 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_CM1:
|
||||
model->HFETAcm1Given = TRUE;
|
||||
model->HFETAcm1 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_CM2:
|
||||
model->HFETAcm2Given = TRUE;
|
||||
model->HFETAcm2 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_CM3:
|
||||
model->HFETAcm3Given = TRUE;
|
||||
model->HFETAcm3 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_ASTAR:
|
||||
model->HFETAastarGiven = TRUE;
|
||||
model->HFETAastar = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_ETA1:
|
||||
model->HFETAeta1Given = TRUE;
|
||||
model->HFETAeta1 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_D1:
|
||||
model->HFETAd1Given = TRUE;
|
||||
model->HFETAd1 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_VT1:
|
||||
model->HFETAvt1Given = TRUE;
|
||||
model->HFETAvt1 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_ETA2:
|
||||
model->HFETAeta2Given = TRUE;
|
||||
model->HFETAeta2 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_D2:
|
||||
model->HFETAd2Given = TRUE;
|
||||
model->HFETAd2 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_VT2:
|
||||
model->HFETAvt2Given = TRUE;
|
||||
model->HFETAvt2 = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_GGR:
|
||||
model->HFETAggrGiven = TRUE;
|
||||
model->HFETAggr = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_DEL:
|
||||
model->HFETAdelGiven = TRUE;
|
||||
model->HFETAdel = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_GATEMOD:
|
||||
model->HFETAgatemodGiven = TRUE;
|
||||
model->HFETAgatemod = value->iValue;
|
||||
break;
|
||||
case HFETA_MOD_KLAMBDA:
|
||||
model->HFETAklambdaGiven = TRUE;
|
||||
KLAMBDA = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_KMU:
|
||||
model->HFETAkmuGiven = TRUE;
|
||||
KMU = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_KVTO:
|
||||
model->HFETAkvtoGiven = TRUE;
|
||||
KVTO = value->rValue;
|
||||
break;
|
||||
case HFETA_MOD_NHFET:
|
||||
if(value->iValue) {
|
||||
model->HFETAtype = NHFET;
|
||||
}
|
||||
break;
|
||||
case HFETA_MOD_PHFET:
|
||||
if(value->iValue) {
|
||||
model->HFETAtype = PHFET;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "ifsim.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
HFETAparam(param,value,inst,select)
|
||||
int param;
|
||||
IFvalue *value;
|
||||
GENinstance *inst;
|
||||
IFvalue *select;
|
||||
{
|
||||
HFETAinstance *here = (HFETAinstance*)inst;
|
||||
switch(param) {
|
||||
case HFETA_LENGTH:
|
||||
here->HFETAlength = value->rValue;
|
||||
here->HFETAlengthGiven = TRUE;
|
||||
break;
|
||||
case HFETA_WIDTH:
|
||||
here->HFETAwidth = value->rValue;
|
||||
here->HFETAwidthGiven = TRUE;
|
||||
break;
|
||||
case HFETA_IC_VDS:
|
||||
here->HFETAicVDS = value->rValue;
|
||||
here->HFETAicVDSGiven = TRUE;
|
||||
break;
|
||||
case HFETA_IC_VGS:
|
||||
here->HFETAicVGS = value->rValue;
|
||||
here->HFETAicVGSGiven = TRUE;
|
||||
break;
|
||||
case HFETA_OFF:
|
||||
here->HFETAoff = value->iValue;
|
||||
break;
|
||||
case HFETA_IC:
|
||||
switch(value->v.numValue) {
|
||||
case 2:
|
||||
here->HFETAicVGS = *(value->v.vec.rVec+1);
|
||||
here->HFETAicVGSGiven = TRUE;
|
||||
case 1:
|
||||
here->HFETAicVDS = *(value->v.vec.rVec);
|
||||
here->HFETAicVDSGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
break;
|
||||
case HFETA_TEMP:
|
||||
here->HFETAtemp = value->rValue+CONSTCtoK;
|
||||
here->HFETAtempGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,432 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "smpdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "const.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
//#define HFETAphibGiven
|
||||
//#define CHARGE 1.60219e-19
|
||||
|
||||
int
|
||||
HFETAsetup(matrix,inModel,ckt,states)
|
||||
SMPmatrix *matrix;
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
int *states;
|
||||
/* load the diode structure with those pointers needed later
|
||||
* for fast matrix loading
|
||||
*/
|
||||
{
|
||||
HFETAmodel *model = (HFETAmodel*)inModel;
|
||||
HFETAinstance *here;
|
||||
int error;
|
||||
CKTnode *tmp;
|
||||
|
||||
|
||||
/* loop through all the diode models */
|
||||
for( ; model != NULL; model = model->HFETAnextModel ) {
|
||||
if( (model->HFETAtype != NHFET) && (model->HFETAtype != PHFET) ) {
|
||||
model->HFETAtype = NHFET;
|
||||
}
|
||||
if(!model->HFETAthresholdGiven) {
|
||||
if(model->HFETAtype == NHFET)
|
||||
model->HFETAthreshold = 0.15;
|
||||
else
|
||||
model->HFETAthreshold = -0.15;
|
||||
}
|
||||
if(!model->HFETAdiGiven) {
|
||||
model->HFETAdi = 0.04e-6;
|
||||
}
|
||||
if(!model->HFETAlambdaGiven) {
|
||||
model->HFETAlambda = 0.15;
|
||||
}
|
||||
if(!model->HFETAetaGiven) {
|
||||
if(model->HFETAtype == NHFET)
|
||||
model->HFETAeta = 1.28;
|
||||
else
|
||||
model->HFETAeta = 1.4;
|
||||
}
|
||||
if(!model->HFETAmGiven) {
|
||||
model->HFETAm = 3.0;
|
||||
}
|
||||
if(!model->HFETAmcGiven) {
|
||||
model->HFETAmc = 3.0;
|
||||
}
|
||||
if(!model->HFETAgammaGiven) {
|
||||
model->HFETAgamma = 3.0;
|
||||
}
|
||||
if(!model->HFETAsigma0Given) {
|
||||
model->HFETAsigma0 = 0.057;
|
||||
}
|
||||
if(!model->HFETAvsigmatGiven) {
|
||||
model->HFETAvsigmat = 0.3;
|
||||
}
|
||||
if(!model->HFETAvsigmaGiven) {
|
||||
model->HFETAvsigma = 0.1;
|
||||
}
|
||||
if(!model->HFETAmuGiven) {
|
||||
if(model->HFETAtype == NHFET)
|
||||
model->HFETAmu = 0.4;
|
||||
else
|
||||
model->HFETAmu = 0.03;
|
||||
}
|
||||
if(!model->HFETAdeltaGiven) {
|
||||
model->HFETAdelta = 3.0;
|
||||
}
|
||||
if(!model->HFETAvsGiven) {
|
||||
if(model->HFETAtype == NHFET)
|
||||
model->HFETAvs = 1.5e5;
|
||||
else
|
||||
model->HFETAvs = 0.8e5;
|
||||
}
|
||||
if(!model->HFETAnmaxGiven) {
|
||||
model->HFETAnmax = 2e16;
|
||||
}
|
||||
if(!model->HFETAdeltadGiven) {
|
||||
model->HFETAdeltad = 4.5e-9;
|
||||
}
|
||||
if(!model->HFETAjs1dGiven) {
|
||||
model->HFETAjs1d = 1.0;
|
||||
}
|
||||
if(!model->HFETAjs2dGiven) {
|
||||
model->HFETAjs2d = 1.15e6;
|
||||
}
|
||||
if(!model->HFETAjs1sGiven) {
|
||||
model->HFETAjs1s = 1.0;
|
||||
}
|
||||
if(!model->HFETAjs2sGiven) {
|
||||
model->HFETAjs2s = 1.15e6;
|
||||
}
|
||||
if(!model->HFETAm1dGiven) {
|
||||
model->HFETAm1d = 1.32;
|
||||
}
|
||||
if(!model->HFETAm2dGiven) {
|
||||
model->HFETAm2d = 6.9;
|
||||
}
|
||||
if(!model->HFETAm1sGiven) {
|
||||
model->HFETAm1s = 1.32;
|
||||
}
|
||||
if(!model->HFETAm2sGiven) {
|
||||
model->HFETAm2s = 6.9;
|
||||
}
|
||||
if(!model->HFETArdGiven) {
|
||||
model->HFETArd = 0;
|
||||
}
|
||||
if(!model->HFETArsGiven) {
|
||||
model->HFETArs = 0;
|
||||
}
|
||||
if(!model->HFETArdiGiven) {
|
||||
model->HFETArdi = 0;
|
||||
}
|
||||
if(!model->HFETArsiGiven) {
|
||||
model->HFETArsi = 0;
|
||||
}
|
||||
if(!model->HFETArgsGiven) {
|
||||
model->HFETArgs = 90;
|
||||
}
|
||||
if(!model->HFETArgdGiven) {
|
||||
model->HFETArgd = 90;
|
||||
}
|
||||
if(!model->HFETAriGiven) {
|
||||
model->HFETAri = 0;
|
||||
}
|
||||
if(!model->HFETArfGiven) {
|
||||
model->HFETArf = 0;
|
||||
}
|
||||
if(!model->HFETAepsiGiven) {
|
||||
model->HFETAepsi = 12.244*8.85418e-12;
|
||||
}
|
||||
if(!model->HFETAa1Given) {
|
||||
model->HFETAa1 = 0;
|
||||
}
|
||||
if(!model->HFETAa2Given) {
|
||||
model->HFETAa2 = 0;
|
||||
}
|
||||
if(!model->HFETAmv1Given) {
|
||||
model->HFETAmv1 = 3;
|
||||
}
|
||||
if(!model->HFETApGiven) {
|
||||
model->HFETAp = 1;
|
||||
}
|
||||
if(!model->HFETAkappaGiven) {
|
||||
model->HFETAkappa = 0;
|
||||
}
|
||||
if(!model->HFETAdelfGiven) {
|
||||
model->HFETAdelf = 0;
|
||||
}
|
||||
if(!model->HFETAfgdsGiven) {
|
||||
model->HFETAfgds = 0;
|
||||
}
|
||||
if(!model->HFETAtfGiven) {
|
||||
model->HFETAtf = ckt->CKTtemp;
|
||||
}
|
||||
if(!model->HFETAcdsGiven) {
|
||||
model->HFETAcds = 0;
|
||||
}
|
||||
if(!model->HFETAphibGiven) {
|
||||
model->HFETAphib = 0.5*CHARGE;
|
||||
}
|
||||
if(!model->HFETAtalphaGiven) {
|
||||
model->HFETAtalpha = 1200;
|
||||
}
|
||||
if(!model->HFETAmt1Given) {
|
||||
model->HFETAmt1 = 3.5;
|
||||
}
|
||||
if(!model->HFETAmt2Given) {
|
||||
model->HFETAmt2 = 9.9;
|
||||
}
|
||||
if(!model->HFETAck1Given) {
|
||||
model->HFETAck1 = 1;
|
||||
}
|
||||
if(!model->HFETAck2Given) {
|
||||
model->HFETAck2 = 0;
|
||||
}
|
||||
if(!model->HFETAcm1Given) {
|
||||
model->HFETAcm1 = 3;
|
||||
}
|
||||
if(!model->HFETAcm2Given) {
|
||||
model->HFETAcm2 = 0;
|
||||
}
|
||||
if(!model->HFETAcm3Given) {
|
||||
model->HFETAcm3 = 0.17;
|
||||
}
|
||||
if(!model->HFETAastarGiven) {
|
||||
model->HFETAastar = 4.0e4;
|
||||
}
|
||||
if(!model->HFETAeta1Given) {
|
||||
model->HFETAeta1 = 2;
|
||||
}
|
||||
if(!model->HFETAd1Given) {
|
||||
model->HFETAd1 = 0.03e-6;
|
||||
}
|
||||
if(!model->HFETAeta2Given) {
|
||||
model->HFETAeta2 = 2;
|
||||
}
|
||||
if(!model->HFETAd2Given) {
|
||||
model->HFETAd2 = 0.2e-6;
|
||||
}
|
||||
if(!model->HFETAvt2Given) {
|
||||
// initialized in HFETAtemp
|
||||
model->HFETAvt2 = 0;
|
||||
}
|
||||
|
||||
if(!model->HFETAggrGiven) {
|
||||
model->HFETAggr = 40;
|
||||
}
|
||||
if(!model->HFETAdelGiven) {
|
||||
model->HFETAdel = 0.04;
|
||||
}
|
||||
if(!model->HFETAklambdaGiven)
|
||||
KLAMBDA = 0;
|
||||
if(!model->HFETAkmuGiven)
|
||||
KMU = 0;
|
||||
if(!model->HFETAkvtoGiven)
|
||||
KVTO = 0;
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = model->HFETAinstances; here != NULL ;
|
||||
here=here->HFETAnextInstance) {
|
||||
|
||||
if(!here->HFETAlengthGiven) {
|
||||
here->HFETAlength = 1e-6;
|
||||
}
|
||||
if(!here->HFETAwidthGiven) {
|
||||
here->HFETAwidth = 20e-6;
|
||||
}
|
||||
if(!here->HFETAtempGiven) {
|
||||
here->HFETAtemp = ckt->CKTtemp;
|
||||
}
|
||||
|
||||
here->HFETAstate = *states;
|
||||
// *states += 24;
|
||||
*states += HFETAnumStates;
|
||||
|
||||
matrixpointers:
|
||||
if(model->HFETArs != 0 && here->HFETAsourcePrimeNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->HFETAname,"source");
|
||||
if(error) return(error);
|
||||
here->HFETAsourcePrimeNode = tmp->number;
|
||||
|
||||
/* XXX: Applied AlansFixes */
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->HFETAsourcePrimeNode = here->HFETAsourceNode;
|
||||
}
|
||||
|
||||
if(model->HFETArd != 0 && here->HFETAdrainPrimeNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->HFETAname,"drain");
|
||||
if(error) return(error);
|
||||
here->HFETAdrainPrimeNode = tmp->number;
|
||||
|
||||
/* XXX: Applied AlansFixes */
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->HFETAdrainPrimeNode = here->HFETAdrainNode;
|
||||
}
|
||||
|
||||
if(model->HFETArg != 0 && here->HFETAgatePrimeNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gate");
|
||||
if(error) return(error);
|
||||
here->HFETAgatePrimeNode = tmp->number;
|
||||
|
||||
/* XXX: Applied AlansFixes */
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->HFETAgatePrimeNode = here->HFETAgateNode;
|
||||
}
|
||||
if(model->HFETArf != 0 && here->HFETAdrainPrmPrmNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gd");
|
||||
if(error) return(error);
|
||||
here->HFETAdrainPrmPrmNode = tmp->number;
|
||||
|
||||
/* XXX: Applied AlansFixes */
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->HFETAdrainPrmPrmNode = here->HFETAdrainPrimeNode;
|
||||
}
|
||||
|
||||
if(model->HFETAri != 0 && here->HFETAsourcePrmPrmNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gs");
|
||||
if(error) return(error);
|
||||
here->HFETAsourcePrmPrmNode = tmp->number;
|
||||
|
||||
/* XXX: Applied AlanFixes */
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->HFETAsourcePrmPrmNode = here->HFETAsourcePrimeNode;
|
||||
}
|
||||
|
||||
/* macro to make elements with built in test for out of memory */
|
||||
#define TSTALLOC(ptr,first,second) \
|
||||
if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\
|
||||
return(E_NOMEM);\
|
||||
}
|
||||
|
||||
TSTALLOC(HFETAdrainDrainPrimePtr,HFETAdrainNode,HFETAdrainPrimeNode)
|
||||
TSTALLOC(HFETAgatePrimeDrainPrimePtr,HFETAgatePrimeNode,HFETAdrainPrimeNode)
|
||||
TSTALLOC(HFETAgatePrimeSourcePrimePtr,HFETAgatePrimeNode,HFETAsourcePrimeNode)
|
||||
TSTALLOC(HFETAsourceSourcePrimePtr,HFETAsourceNode,HFETAsourcePrimeNode)
|
||||
TSTALLOC(HFETAdrainPrimeDrainPtr,HFETAdrainPrimeNode,HFETAdrainNode)
|
||||
TSTALLOC(HFETAdrainPrimeGatePrimePtr,HFETAdrainPrimeNode,HFETAgatePrimeNode)
|
||||
TSTALLOC(HFETAdrainPrimeSourcePrimePtr,HFETAdrainPrimeNode,HFETAsourcePrimeNode)
|
||||
TSTALLOC(HFETAsourcePrimeGatePrimePtr,HFETAsourcePrimeNode,HFETAgatePrimeNode)
|
||||
TSTALLOC(HFETAsourcePrimeSourcePtr,HFETAsourcePrimeNode,HFETAsourceNode)
|
||||
TSTALLOC(HFETAsourcePrimeDrainPrimePtr,HFETAsourcePrimeNode,HFETAdrainPrimeNode)
|
||||
TSTALLOC(HFETAdrainDrainPtr,HFETAdrainNode,HFETAdrainNode)
|
||||
TSTALLOC(HFETAgatePrimeGatePrimePtr,HFETAgatePrimeNode,HFETAgatePrimeNode)
|
||||
TSTALLOC(HFETAsourceSourcePtr,HFETAsourceNode,HFETAsourceNode)
|
||||
TSTALLOC(HFETAdrainPrimeDrainPrimePtr,HFETAdrainPrimeNode,HFETAdrainPrimeNode)
|
||||
TSTALLOC(HFETAsourcePrimeSourcePrimePtr,HFETAsourcePrimeNode,HFETAsourcePrimeNode)
|
||||
TSTALLOC(HFETAdrainPrimeDrainPrmPrmPtr,HFETAdrainPrimeNode,HFETAdrainPrmPrmNode)
|
||||
TSTALLOC(HFETAdrainPrmPrmDrainPrimePtr,HFETAdrainPrmPrmNode,HFETAdrainPrimeNode)
|
||||
TSTALLOC(HFETAdrainPrmPrmGatePrimePtr,HFETAdrainPrmPrmNode,HFETAgatePrimeNode)
|
||||
TSTALLOC(HFETAgatePrimeDrainPrmPrmPtr,HFETAgatePrimeNode,HFETAdrainPrmPrmNode)
|
||||
TSTALLOC(HFETAdrainPrmPrmDrainPrmPrmPtr,HFETAdrainPrmPrmNode,HFETAdrainPrmPrmNode)
|
||||
TSTALLOC(HFETAsourcePrimeSourcePrmPrmPtr,HFETAsourcePrimeNode,HFETAsourcePrmPrmNode)
|
||||
TSTALLOC(HFETAsourcePrmPrmSourcePrimePtr,HFETAsourcePrmPrmNode,HFETAsourcePrimeNode)
|
||||
TSTALLOC(HFETAsourcePrmPrmGatePrimePtr,HFETAsourcePrmPrmNode,HFETAgatePrimeNode)
|
||||
TSTALLOC(HFETAgatePrimeSourcePrmPrmPtr,HFETAgatePrimeNode,HFETAsourcePrmPrmNode)
|
||||
TSTALLOC(HFETAsourcePrmPrmSourcePrmPrmPtr,HFETAsourcePrmPrmNode,HFETAsourcePrmPrmNode)
|
||||
TSTALLOC(HFETAgateGatePtr,HFETAgateNode,HFETAgateNode)
|
||||
TSTALLOC(HFETAgateGatePrimePtr,HFETAgateNode,HFETAgatePrimeNode)
|
||||
TSTALLOC(HFETAgatePrimeGatePtr,HFETAgatePrimeNode,HFETAgateNode)
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
||||
int
|
||||
HFETAunsetup(inModel,ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
HFETAmodel *model;
|
||||
HFETAinstance *here;
|
||||
|
||||
for (model = (HFETAmodel *)inModel; model != NULL;
|
||||
model = model->HFETAnextModel)
|
||||
{
|
||||
for (here = model->HFETAinstances; here != NULL;
|
||||
here=here->HFETAnextInstance)
|
||||
{
|
||||
if (here->HFETAdrainPrimeNode
|
||||
&& here->HFETAdrainPrimeNode != here->HFETAdrainNode)
|
||||
{
|
||||
CKTdltNNum(ckt, here->HFETAdrainPrimeNode);
|
||||
here->HFETAdrainPrimeNode = 0;
|
||||
}
|
||||
if (here->HFETAsourcePrimeNode
|
||||
&& here->HFETAsourcePrimeNode != here->HFETAsourceNode)
|
||||
{
|
||||
CKTdltNNum(ckt, here->HFETAsourcePrimeNode);
|
||||
here->HFETAsourcePrimeNode = 0;
|
||||
}
|
||||
} if (here->HFETAgatePrimeNode
|
||||
&& here->HFETAgatePrimeNode != here->HFETAgateNode)
|
||||
{
|
||||
CKTdltNNum(ckt, here->HFETAgatePrimeNode);
|
||||
here->HFETAgatePrimeNode = 0;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "smpdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "const.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
HFETAtemp(inModel,ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
HFETAmodel *model = (HFETAmodel*)inModel;
|
||||
HFETAinstance *here;
|
||||
double vt;
|
||||
double temp;
|
||||
|
||||
/* loop through all the diode models */
|
||||
for( ; model != NULL; model = model->HFETAnextModel ) {
|
||||
if(model->HFETArd != 0) {
|
||||
model->HFETAdrainConduct = 1/model->HFETArd;
|
||||
} else {
|
||||
model->HFETAdrainConduct = 0;
|
||||
}
|
||||
if(model->HFETArs != 0) {
|
||||
model->HFETAsourceConduct = 1/model->HFETArs;
|
||||
} else {
|
||||
model->HFETAsourceConduct = 0;
|
||||
}
|
||||
if(model->HFETArg != 0) {
|
||||
model->HFETAgateConduct = 1/model->HFETArg;
|
||||
} else {
|
||||
model->HFETAgateConduct = 0;
|
||||
}
|
||||
if(model->HFETAri != 0) {
|
||||
model->HFETAgi = 1/model->HFETAri;
|
||||
} else {
|
||||
model->HFETAgi = 0;
|
||||
}
|
||||
if(model->HFETArf != 0) {
|
||||
model->HFETAgf = 1/model->HFETArf;
|
||||
} else {
|
||||
model->HFETAgf = 0;
|
||||
}
|
||||
model->HFETAdeltaSqr = model->HFETAdelta*model->HFETAdelta;
|
||||
model->HFETAthreshold *= model->HFETAtype;
|
||||
|
||||
if(!model->HFETAvt2Given)
|
||||
VT2 = VTO;
|
||||
if(!model->HFETAvt1Given)
|
||||
IN_VT1 = VTO+CHARGE*NMAX*DI/EPSI;
|
||||
|
||||
for (here = model->HFETAinstances; here != NULL ;
|
||||
here=here->HFETAnextInstance) {
|
||||
vt = CONSTKoverQ*TEMP;
|
||||
TLAMBDA = LAMBDA + KLAMBDA*(TEMP-ckt->CKTnomTemp);
|
||||
TMU = MU - KMU*(TEMP-ckt->CKTnomTemp);
|
||||
TVTO = VTO - KVTO*(TEMP-ckt->CKTnomTemp);
|
||||
N0 = EPSI*ETA*vt/2/CHARGE/(DI+DELTAD);
|
||||
N01 = EPSI*ETA1*vt/2/CHARGE/D1;
|
||||
if(model->HFETAeta2Given)
|
||||
N02 = EPSI*ETA2*vt/2/CHARGE/D2;
|
||||
else
|
||||
N02 = 0.0;
|
||||
GCHI0 = CHARGE*W*TMU/L;
|
||||
CF = 0.5*EPSI*W;
|
||||
IMAX = CHARGE*NMAX*VS*W;
|
||||
IS1D = JS1D*W*L/2;
|
||||
IS2D = JS2D*W*L/2;
|
||||
IS1S = JS1S*W*L/2;
|
||||
IS2S = JS2S*W*L/2;
|
||||
ISO = ASTAR*W*L/2;
|
||||
GGRWL = GGR*L*W/2;
|
||||
temp = exp(TEMP/model->HFETAtf);
|
||||
FGDS = model->HFETAfgds*temp;
|
||||
DELF = model->HFETAdelf*temp;
|
||||
if(model->HFETAgatemod == 0) {
|
||||
if(IS1S != 0)
|
||||
here->HFETAvcrit = vt*log(vt/(CONSTroot2*IS1S));
|
||||
else
|
||||
here->HFETAvcrit = DBL_MAX;
|
||||
} else {
|
||||
if(ISO != 0.0)
|
||||
here->HFETAvcrit = vt*log(vt/(CONSTroot2*ISO));
|
||||
else
|
||||
here->HFETAvcrit = DBL_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "hfetdefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
HFETAtrunc(inModel,ckt,timeStep)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
double *timeStep;
|
||||
{
|
||||
HFETAmodel *model = (HFETAmodel*)inModel;
|
||||
HFETAinstance *here;
|
||||
|
||||
for( ; model != NULL; model = model->HFETAnextModel) {
|
||||
for(here=model->HFETAinstances;here!=NULL;here = here->HFETAnextInstance){
|
||||
CKTterr(here->HFETAqgs,ckt,timeStep);
|
||||
CKTterr(here->HFETAqgd,ckt,timeStep);
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
pkglib_LTLIBRARIES = libhfet2.la
|
||||
|
||||
libhfet2_la_SOURCES = \
|
||||
hfet2.c \
|
||||
hfet2acl.c \
|
||||
hfet2ask.c \
|
||||
hfet2defs.h \
|
||||
hfet2del.c \
|
||||
hfet2dest.c \
|
||||
hfet2ext.h \
|
||||
hfet2getic.c \
|
||||
hfet2init.c \
|
||||
hfet2init.h \
|
||||
hfet2itf.h \
|
||||
hfet2load.c \
|
||||
hfet2mask.c \
|
||||
hfet2mdel.c \
|
||||
hfet2mpar.c \
|
||||
hfet2param.c \
|
||||
hfet2setup.c \
|
||||
hfet2temp.c \
|
||||
hfet2trunc.c
|
||||
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/include
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "ifsim.h"
|
||||
#include "devdefs.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
IFparm HFET2pTable[] = { /* parameters */
|
||||
OP("off", HFET2_OFF, IF_FLAG ,""),
|
||||
IOP("l", HFET2_LENGTH, IF_REAL ,""),
|
||||
IOP("w", HFET2_WIDTH, IF_REAL ,""),
|
||||
IOP("icvds", HFET2_IC_VDS, IF_REAL ,""),
|
||||
IOP("icvgs", HFET2_IC_VGS, IF_REAL ,""),
|
||||
IOP("temp", HFET2_TEMP, IF_REAL ,""),
|
||||
OP("dnode", HFET2_DRAINNODE, IF_INTEGER ,""),
|
||||
OP("gnode", HFET2_GATENODE, IF_INTEGER ,""),
|
||||
OP("snode", HFET2_SOURCENODE, IF_INTEGER ,""),
|
||||
OP("dprimenode",HFET2_DRAINPRIMENODE, IF_INTEGER ,""),
|
||||
OP("sprimenode",HFET2_SOURCEPRIMENODE,IF_INTEGER ,""),
|
||||
OP("vgs", HFET2_VGS, IF_REAL ,""),
|
||||
OP("vgd", HFET2_VGD, IF_REAL ,""),
|
||||
OP("cg", HFET2_CG, IF_REAL ,""),
|
||||
OP("cd", HFET2_CD, IF_REAL ,""),
|
||||
OP("cgd", HFET2_CGD, IF_REAL ,""),
|
||||
OP("gm", HFET2_GM, IF_REAL ,""),
|
||||
OP("gds", HFET2_GDS, IF_REAL ,""),
|
||||
OP("ggs", HFET2_GGS, IF_REAL ,""),
|
||||
OP("ggd", HFET2_GGD, IF_REAL ,""),
|
||||
OP("qgs", HFET2_QGS, IF_REAL ,""),
|
||||
OP("cqgs", HFET2_CQGS, IF_REAL ,""),
|
||||
OP("qgd", HFET2_QGD, IF_REAL ,""),
|
||||
OP("cqgd", HFET2_CQGD, IF_REAL ,""),
|
||||
OP("cs", HFET2_CS, IF_REAL ,""),
|
||||
OP("p", HFET2_POWER, IF_REAL ,"")
|
||||
|
||||
};
|
||||
|
||||
IFparm HFET2mPTable[] = { /* model parameters */
|
||||
OP( "type", HFET2_MOD_TYPE, IF_STRING,"NHFET or PHFET"),
|
||||
IOP( "nhfet", HFET2_MOD_NHFET, IF_FLAG,"N type HFET model"),
|
||||
IOP( "phfet", HFET2_MOD_PHFET, IF_FLAG,"P type HFET model"),
|
||||
IOP( "cf", HFET2_MOD_CF, IF_REAL,""),
|
||||
IOP( "d1", HFET2_MOD_D1, IF_REAL,""),
|
||||
IOP( "d2", HFET2_MOD_D2, IF_REAL,""),
|
||||
IOP( "del", HFET2_MOD_DEL, IF_REAL,""),
|
||||
IOP( "delta", HFET2_MOD_DELTA, IF_REAL,""),
|
||||
IOP( "deltad", HFET2_MOD_DELTAD, IF_REAL,"Thickness correction"),
|
||||
IOP( "di", HFET2_MOD_DI, IF_REAL,"Depth of device"),
|
||||
IOP( "epsi", HFET2_MOD_EPSI, IF_REAL,""),
|
||||
IOP( "eta", HFET2_MOD_ETA, IF_REAL,"Subthreshold ideality factor"),
|
||||
IOP( "eta1", HFET2_MOD_ETA1, IF_REAL,""),
|
||||
IOP( "eta2", HFET2_MOD_ETA2, IF_REAL,""),
|
||||
IOP( "gamma", HFET2_MOD_GAMMA, IF_REAL,"Knee shape parameter"),
|
||||
IOP( "ggr", HFET2_MOD_GGR, IF_REAL,""),
|
||||
IOP( "js", HFET2_MOD_JS, IF_REAL,""),
|
||||
IOP( "klambda", HFET2_MOD_KLAMBDA, IF_REAL,""),
|
||||
IOP( "kmu", HFET2_MOD_KMU, IF_REAL,""),
|
||||
IOP( "knmax", HFET2_MOD_KNMAX, IF_REAL,""),
|
||||
IOP( "kvto", HFET2_MOD_KVTO, IF_REAL,""),
|
||||
IOP( "lambda", HFET2_MOD_LAMBDA, IF_REAL,"Output conductance parameter"),
|
||||
IOP( "m", HFET2_MOD_M, IF_REAL,"Knee shape parameter"),
|
||||
IOP( "mc", HFET2_MOD_MC, IF_REAL,"Knee shape parameter"),
|
||||
IOP( "mu", HFET2_MOD_MU, IF_REAL,"Moblity"),
|
||||
IOP( "n", HFET2_MOD_N, IF_REAL,""),
|
||||
IOP( "nmax", HFET2_MOD_NMAX, IF_REAL,""),
|
||||
IOP( "p", HFET2_MOD_P, IF_REAL,""),
|
||||
IOP( "rd", HFET2_MOD_RD, IF_REAL,"Drain ohmic resistance"),
|
||||
IOP( "rdi", HFET2_MOD_RDI, IF_REAL,"Drain ohmic resistance"),
|
||||
IOP( "rs", HFET2_MOD_RS, IF_REAL,"Source ohmic resistance"),
|
||||
IOP( "rsi", HFET2_MOD_RSI, IF_REAL,"Source ohmic resistance"),
|
||||
IOP( "sigma0", HFET2_MOD_SIGMA0, IF_REAL,"DIBL parameter"),
|
||||
IOP( "vs", HFET2_MOD_VS, IF_REAL,"Saturation velocity"),
|
||||
IOP( "vsigma", HFET2_MOD_VSIGMA, IF_REAL,""),
|
||||
IOP( "vsigmat", HFET2_MOD_VSIGMAT, IF_REAL,""),
|
||||
IOP( "vt0", HFET2_MOD_VTO, IF_REAL,""),
|
||||
IOP( "vt1", HFET2_MOD_VT1, IF_REAL,""),
|
||||
IOP( "vt2", HFET2_MOD_VT2, IF_REAL,""),
|
||||
IOP( "vto", HFET2_MOD_VTO, IF_REAL,"")
|
||||
|
||||
};
|
||||
|
||||
char *HFET2names[] = {
|
||||
"Drain",
|
||||
"Gate",
|
||||
"Source"
|
||||
};
|
||||
|
||||
int HFET2nSize = NUMELEMS(HFET2names);
|
||||
int HFET2pTSize = NUMELEMS(HFET2pTable);
|
||||
int HFET2mPTSize = NUMELEMS(HFET2mPTable);
|
||||
int HFET2iSize = sizeof(HFET2instance);
|
||||
int HFET2mSize = sizeof(HFET2model);
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int HFET2acLoad(inModel, ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
|
||||
HFET2model *model = (HFET2model*)inModel;
|
||||
HFET2instance *here;
|
||||
double gdpr;
|
||||
double gspr;
|
||||
double gm;
|
||||
double gds;
|
||||
double ggs;
|
||||
double xgs;
|
||||
double ggd;
|
||||
double xgd;
|
||||
|
||||
for( ; model != NULL; model = model->HFET2nextModel )
|
||||
{
|
||||
for( here = model->HFET2instances; here != NULL; here = here->HFET2nextInstance)
|
||||
{
|
||||
gdpr=model->HFET2drainConduct;
|
||||
gspr=model->HFET2sourceConduct;
|
||||
gm= *(ckt->CKTstate0 + here->HFET2gm) ;
|
||||
gds= *(ckt->CKTstate0 + here->HFET2gds) ;
|
||||
ggs= *(ckt->CKTstate0 + here->HFET2ggs) ;
|
||||
xgs= *(ckt->CKTstate0 + here->HFET2qgs) * ckt->CKTomega ;
|
||||
ggd= *(ckt->CKTstate0 + here->HFET2ggd) ;
|
||||
xgd= *(ckt->CKTstate0 + here->HFET2qgd) * ckt->CKTomega ;
|
||||
*(here->HFET2drainDrainPtr ) += gdpr;
|
||||
*(here->HFET2gateGatePtr ) += ggd+ggs;
|
||||
*(here->HFET2gateGatePtr +1) += xgd+xgs;
|
||||
*(here->HFET2sourceSourcePtr ) += gspr;
|
||||
*(here->HFET2drainPrimeDrainPrimePtr ) += gdpr+gds+ggd;
|
||||
*(here->HFET2drainPrimeDrainPrimePtr +1) += xgd;
|
||||
*(here->HFET2sourcePriHFET2ourcePrimePtr ) += gspr+gds+gm+ggs;
|
||||
*(here->HFET2sourcePriHFET2ourcePrimePtr +1) += xgs;
|
||||
*(here->HFET2drainDrainPrimePtr ) -= gdpr;
|
||||
*(here->HFET2gateDrainPrimePtr ) -= ggd;
|
||||
*(here->HFET2gateDrainPrimePtr +1) -= xgd;
|
||||
*(here->HFET2gateSourcePrimePtr ) -= ggs;
|
||||
*(here->HFET2gateSourcePrimePtr +1) -= xgs;
|
||||
*(here->HFET2sourceSourcePrimePtr ) -= gspr;
|
||||
*(here->HFET2drainPrimeDrainPtr ) -= gdpr;
|
||||
*(here->HFET2drainPrimeGatePtr ) += (-ggd+gm);
|
||||
*(here->HFET2drainPrimeGatePtr +1) -= xgd;
|
||||
*(here->HFET2drainPriHFET2ourcePrimePtr ) += (-gds-gm);
|
||||
*(here->HFET2sourcePrimeGatePtr ) += (-ggs-gm);
|
||||
*(here->HFET2sourcePrimeGatePtr +1) -= xgs;
|
||||
*(here->HFET2sourcePriHFET2ourcePtr ) -= gspr;
|
||||
*(here->HFET2sourcePrimeDrainPrimePtr ) -= gds;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
**********/
|
||||
/*
|
||||
Imported into HFET2 source: Paolo Nenzi 2001
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "devdefs.h"
|
||||
#include "ifsim.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
HFET2ask(ckt,inst,which,value,select)
|
||||
CKTcircuit *ckt;
|
||||
GENinstance *inst;
|
||||
int which;
|
||||
IFvalue *value;
|
||||
IFvalue *select;
|
||||
{
|
||||
HFET2instance *here = (HFET2instance*)inst;
|
||||
static char *msg = "Current and power not available in ac analysis";
|
||||
switch(which) {
|
||||
case HFET2_LENGTH:
|
||||
value->rValue = here->HFET2length;
|
||||
return (OK);
|
||||
case HFET2_WIDTH:
|
||||
value->rValue = here->HFET2width;
|
||||
case HFET2_IC_VDS:
|
||||
value->rValue = here->HFET2icVDS;
|
||||
return (OK);
|
||||
case HFET2_IC_VGS:
|
||||
value->rValue = here->HFET2icVGS;
|
||||
return (OK);
|
||||
case HFET2_OFF:
|
||||
value->iValue = here->HFET2off;
|
||||
return (OK);
|
||||
case HFET2_DRAINNODE:
|
||||
value->iValue = here->HFET2drainNode;
|
||||
return (OK);
|
||||
case HFET2_GATENODE:
|
||||
value->iValue = here->HFET2gateNode;
|
||||
return (OK);
|
||||
case HFET2_SOURCENODE:
|
||||
value->iValue = here->HFET2sourceNode;
|
||||
return (OK);
|
||||
case HFET2_DRAINPRIMENODE:
|
||||
value->iValue = here->HFET2drainPrimeNode;
|
||||
return (OK);
|
||||
case HFET2_SOURCEPRIMENODE:
|
||||
value->iValue = here->HFET2sourcePrimeNode;
|
||||
return (OK);
|
||||
case HFET2_TEMP:
|
||||
value->rValue = here->HFET2temp;
|
||||
case HFET2_VGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2vgs);
|
||||
return (OK);
|
||||
case HFET2_VGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2vgd);
|
||||
return (OK);
|
||||
case HFET2_CG:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2cg);
|
||||
return (OK);
|
||||
case HFET2_CD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2cd);
|
||||
return (OK);
|
||||
case HFET2_CGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2cgd);
|
||||
return (OK);
|
||||
case HFET2_GM:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2gm);
|
||||
return (OK);
|
||||
case HFET2_GDS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2gds);
|
||||
return (OK);
|
||||
case HFET2_GGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2ggs);
|
||||
return (OK);
|
||||
case HFET2_GGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2ggd);
|
||||
return (OK);
|
||||
case HFET2_QGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2qgs);
|
||||
return (OK);
|
||||
case HFET2_CQGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2cqgs);
|
||||
return (OK);
|
||||
case HFET2_QGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2qgd);
|
||||
return (OK);
|
||||
case HFET2_CQGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2cqgd);
|
||||
return (OK);
|
||||
case HFET2_CS :
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = MALLOC(strlen(msg)+1);
|
||||
errRtn = "HFET2ask";
|
||||
strcpy(errMsg,msg);
|
||||
return(E_ASKCURRENT);
|
||||
} else {
|
||||
value->rValue = -*(ckt->CKTstate0 + here->HFET2cd);
|
||||
value->rValue -= *(ckt->CKTstate0 + here->HFET2cg);
|
||||
}
|
||||
return(OK);
|
||||
case HFET2_POWER :
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = MALLOC(strlen(msg)+1);
|
||||
errRtn = "HFET2ask";
|
||||
strcpy(errMsg,msg);
|
||||
return(E_ASKPOWER);
|
||||
} else {
|
||||
value->rValue = *(ckt->CKTstate0 + here->HFET2cd) *
|
||||
*(ckt->CKTrhsOld + here->HFET2drainNode);
|
||||
value->rValue += *(ckt->CKTstate0 + here->HFET2cg) *
|
||||
*(ckt->CKTrhsOld + here->HFET2gateNode);
|
||||
value->rValue -= (*(ckt->CKTstate0+here->HFET2cd) +
|
||||
*(ckt->CKTstate0 + here->HFET2cg)) *
|
||||
*(ckt->CKTrhsOld + here->HFET2sourceNode);
|
||||
}
|
||||
return(OK);
|
||||
default:
|
||||
return (E_BADPARM);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
@ -0,0 +1,318 @@
|
|||
|
||||
#ifndef HFET2
|
||||
#define HFET2
|
||||
|
||||
#include "ifsim.h"
|
||||
#include "cktdefs.h"
|
||||
#include "gendefs.h"
|
||||
#include "complex.h"
|
||||
#include "noisedef.h"
|
||||
|
||||
|
||||
typedef struct sHFET2instance {
|
||||
struct sHFET2model *HFET2modPtr;
|
||||
struct sHFET2instance *HFET2nextInstance;
|
||||
IFuid HFET2name;
|
||||
int HFET2owner; /* number of owner process */
|
||||
int HFET2state; /* index into state table for this device */
|
||||
|
||||
int HFET2drainNode;
|
||||
int HFET2gateNode;
|
||||
int HFET2sourceNode;
|
||||
int HFET2drainPrimeNode;
|
||||
int HFET2sourcePrimeNode;
|
||||
double HFET2length;
|
||||
double HFET2width;
|
||||
double HFET2temp;
|
||||
double HFET2tLambda;
|
||||
double HFET2tMu;
|
||||
double HFET2tNmax;
|
||||
double HFET2tVto;
|
||||
double HFET2icVDS;
|
||||
double HFET2icVGS;
|
||||
double *HFET2drainDrainPrimePtr;
|
||||
double *HFET2gateDrainPrimePtr;
|
||||
double *HFET2gateSourcePrimePtr;
|
||||
double *HFET2sourceSourcePrimePtr;
|
||||
double *HFET2drainPrimeDrainPtr;
|
||||
double *HFET2drainPrimeGatePtr;
|
||||
double *HFET2drainPriHFET2ourcePrimePtr;
|
||||
double *HFET2sourcePrimeGatePtr;
|
||||
double *HFET2sourcePriHFET2ourcePtr;
|
||||
double *HFET2sourcePrimeDrainPrimePtr;
|
||||
double *HFET2drainDrainPtr;
|
||||
double *HFET2gateGatePtr;
|
||||
double *HFET2sourceSourcePtr;
|
||||
double *HFET2drainPrimeDrainPrimePtr;
|
||||
double *HFET2sourcePriHFET2ourcePrimePtr;
|
||||
|
||||
|
||||
#define HFET2vgs HFET2state
|
||||
#define HFET2vgd HFET2state+1
|
||||
#define HFET2cg HFET2state+2
|
||||
#define HFET2cd HFET2state+3
|
||||
#define HFET2cgd HFET2state+4
|
||||
#define HFET2gm HFET2state+5
|
||||
#define HFET2gds HFET2state+6
|
||||
#define HFET2ggs HFET2state+7
|
||||
#define HFET2ggd HFET2state+8
|
||||
#define HFET2qgs HFET2state+9
|
||||
#define HFET2cqgs HFET2state+10
|
||||
#define HFET2qgd HFET2state+11
|
||||
#define HFET2cqgd HFET2state+12
|
||||
|
||||
int HFET2mode;
|
||||
int HFET2off;
|
||||
|
||||
unsigned HFET2icVDSGiven : 1;
|
||||
unsigned HFET2icVGSGiven : 1;
|
||||
unsigned HFET2lengthGiven : 1;
|
||||
unsigned HFET2widthGiven : 1;
|
||||
unsigned HFET2tempGiven : 1;
|
||||
|
||||
double HFET2n0;
|
||||
double HFET2n01;
|
||||
double HFET2n02;
|
||||
double HFET2gchi0;
|
||||
double HFET2imax;
|
||||
double HFET2vcrit;
|
||||
double HFET2ggrlw;
|
||||
double HFET2jslw;
|
||||
|
||||
} HFET2instance ;
|
||||
|
||||
|
||||
|
||||
typedef struct sHFET2model {
|
||||
int HFET2modType;
|
||||
struct sHFET2model *HFET2nextModel;
|
||||
HFET2instance * HFET2instances;
|
||||
IFuid HFET2modName;
|
||||
int HFET2type;
|
||||
|
||||
double HFET2cf;
|
||||
double HFET2d1;
|
||||
double HFET2d2;
|
||||
double HFET2del;
|
||||
double HFET2delta;
|
||||
double HFET2deltad;
|
||||
double HFET2di;
|
||||
double HFET2epsi;
|
||||
double HFET2eta;
|
||||
double HFET2eta1;
|
||||
double HFET2eta2;
|
||||
double HFET2gamma;
|
||||
double HFET2ggr;
|
||||
double HFET2js;
|
||||
double HFET2klambda;
|
||||
double HFET2kmu;
|
||||
double HFET2knmax;
|
||||
double HFET2kvto;
|
||||
double HFET2lambda;
|
||||
double HFET2m;
|
||||
double HFET2mc;
|
||||
double HFET2mu;
|
||||
double HFET2n;
|
||||
double HFET2nmax;
|
||||
double HFET2p;
|
||||
double HFET2rd;
|
||||
double HFET2rdi;
|
||||
double HFET2rs;
|
||||
double HFET2rsi;
|
||||
double HFET2sigma0;
|
||||
double HFET2vs;
|
||||
double HFET2vsigma;
|
||||
double HFET2vsigmat;
|
||||
double HFET2vt1;
|
||||
double HFET2vt2;
|
||||
double HFET2vto;
|
||||
|
||||
double HFET2drainConduct;
|
||||
double HFET2sourceConduct;
|
||||
double HFET2deltaSqr;
|
||||
|
||||
unsigned HFET2cfGiven : 1;
|
||||
unsigned HFET2d1Given : 1;
|
||||
unsigned HFET2d2Given : 1;
|
||||
unsigned HFET2delGiven : 1;
|
||||
unsigned HFET2deltaGiven : 1;
|
||||
unsigned HFET2deltadGiven : 1;
|
||||
unsigned HFET2diGiven : 1;
|
||||
unsigned HFET2epsiGiven : 1;
|
||||
unsigned HFET2etaGiven : 1;
|
||||
unsigned HFET2eta1Given : 1;
|
||||
unsigned HFET2eta2Given : 1;
|
||||
unsigned HFET2gammaGiven : 1;
|
||||
unsigned HFET2ggrGiven : 1;
|
||||
unsigned HFET2jsGiven : 1;
|
||||
unsigned HFET2klambdaGiven : 1;
|
||||
unsigned HFET2kmuGiven : 1;
|
||||
unsigned HFET2knmaxGiven : 1;
|
||||
unsigned HFET2kvtoGiven : 1;
|
||||
unsigned HFET2lambdaGiven : 1;
|
||||
unsigned HFET2mGiven : 1;
|
||||
unsigned HFET2mcGiven : 1;
|
||||
unsigned HFET2muGiven : 1;
|
||||
unsigned HFET2nGiven : 1;
|
||||
unsigned HFET2nmaxGiven : 1;
|
||||
unsigned HFET2pGiven : 1;
|
||||
unsigned HFET2rdGiven : 1;
|
||||
unsigned HFET2rdiGiven : 1;
|
||||
unsigned HFET2rsGiven : 1;
|
||||
unsigned HFET2rsiGiven : 1;
|
||||
unsigned HFET2sigma0Given : 1;
|
||||
unsigned HFET2vsGiven : 1;
|
||||
unsigned HFET2vsigmaGiven : 1;
|
||||
unsigned HFET2vsigmatGiven : 1;
|
||||
unsigned HFET2vt1Given : 1;
|
||||
unsigned HFET2vt2Given : 1;
|
||||
unsigned HFET2vtoGiven : 1;
|
||||
|
||||
} HFET2model;
|
||||
|
||||
|
||||
#ifndef NHFET
|
||||
#define NHFET 1
|
||||
#define PHFET -1
|
||||
#endif /*NMF*/
|
||||
|
||||
/* device parameters */
|
||||
#define HFET2_LENGTH 1
|
||||
#define HFET2_WIDTH 2
|
||||
#define HFET2_IC_VDS 3
|
||||
#define HFET2_IC_VGS 4
|
||||
#define HFET2_IC 5
|
||||
#define HFET2_OFF 6
|
||||
#define HFET2_CS 7
|
||||
#define HFET2_POWER 8
|
||||
#define HFET2_TEMP 9
|
||||
|
||||
/* model parameters */
|
||||
#define HFET2_MOD_NHFET 101
|
||||
#define HFET2_MOD_PHFET 102
|
||||
#define HFET2_MOD_CF 103
|
||||
#define HFET2_MOD_D1 104
|
||||
#define HFET2_MOD_D2 105
|
||||
#define HFET2_MOD_DEL 106
|
||||
#define HFET2_MOD_DELTA 107
|
||||
#define HFET2_MOD_DELTAD 108
|
||||
#define HFET2_MOD_DI 109
|
||||
#define HFET2_MOD_EPSI 110
|
||||
#define HFET2_MOD_ETA 111
|
||||
#define HFET2_MOD_ETA1 112
|
||||
#define HFET2_MOD_ETA2 113
|
||||
#define HFET2_MOD_GAMMA 114
|
||||
#define HFET2_MOD_GGR 115
|
||||
#define HFET2_MOD_JS 116
|
||||
#define HFET2_MOD_KLAMBDA 117
|
||||
#define HFET2_MOD_KMU 118
|
||||
#define HFET2_MOD_KNMAX 119
|
||||
#define HFET2_MOD_KVTO 120
|
||||
#define HFET2_MOD_LAMBDA 121
|
||||
#define HFET2_MOD_M 122
|
||||
#define HFET2_MOD_MC 123
|
||||
#define HFET2_MOD_MU 124
|
||||
#define HFET2_MOD_N 125
|
||||
#define HFET2_MOD_NMAX 126
|
||||
#define HFET2_MOD_P 127
|
||||
#define HFET2_MOD_RD 128
|
||||
#define HFET2_MOD_RDI 129
|
||||
#define HFET2_MOD_RS 130
|
||||
#define HFET2_MOD_RSI 131
|
||||
#define HFET2_MOD_SIGMA0 132
|
||||
#define HFET2_MOD_VS 133
|
||||
#define HFET2_MOD_VSIGMA 134
|
||||
#define HFET2_MOD_VSIGMAT 135
|
||||
#define HFET2_MOD_VT1 136
|
||||
#define HFET2_MOD_VT2 137
|
||||
#define HFET2_MOD_VTO 138
|
||||
#define HFET2_MOD_TYPE 139
|
||||
|
||||
/* device questions */
|
||||
|
||||
#define HFET2_DRAINNODE 201
|
||||
#define HFET2_GATENODE 202
|
||||
#define HFET2_SOURCENODE 203
|
||||
#define HFET2_DRAINPRIMENODE 204
|
||||
#define HFET2_SOURCEPRIMENODE 205
|
||||
|
||||
#define HFET2_VGS 206
|
||||
#define HFET2_VGD 207
|
||||
#define HFET2_CG 208
|
||||
#define HFET2_CD 209
|
||||
#define HFET2_CGD 210
|
||||
#define HFET2_GM 211
|
||||
#define HFET2_GDS 212
|
||||
#define HFET2_GGS 213
|
||||
#define HFET2_GGD 214
|
||||
#define HFET2_QGS 215
|
||||
#define HFET2_CQGS 216
|
||||
#define HFET2_QGD 217
|
||||
#define HFET2_CQGD 218
|
||||
|
||||
/* model questions */
|
||||
|
||||
#define HFET2_MOD_DRAINCONDUCT 301
|
||||
#define HFET2_MOD_SOURCECONDUCT 302
|
||||
#define HFET2_MOD_DEPLETIONCAP 303
|
||||
#define HFET2_MOD_VCRIT 304
|
||||
|
||||
#define CF (model->HFET2cf)
|
||||
#define D1 (model->HFET2d1)
|
||||
#define D2 (model->HFET2d2)
|
||||
#define DEL (model->HFET2del)
|
||||
#define DELTA (model->HFET2delta)
|
||||
#define DELTAD (model->HFET2deltad)
|
||||
#define DI (model->HFET2di)
|
||||
#define EPSI (model->HFET2epsi)
|
||||
#define ETA (model->HFET2eta)
|
||||
#define ETA1 (model->HFET2eta1)
|
||||
#define ETA2 (model->HFET2eta2)
|
||||
#define GAMMA (model->HFET2gamma)
|
||||
#define GGR (model->HFET2ggr)
|
||||
#define JS (model->HFET2js)
|
||||
#define KLAMBDA (model->HFET2klambda)
|
||||
#define KMU (model->HFET2kmu)
|
||||
#define KNMAX (model->HFET2knmax)
|
||||
#define KVTO (model->HFET2kvto)
|
||||
#define LAMBDA (model->HFET2lambda)
|
||||
#define M (model->HFET2m)
|
||||
#define MC (model->HFET2mc)
|
||||
#define MU (model->HFET2mu)
|
||||
#define N (model->HFET2n)
|
||||
#define NMAX (model->HFET2nmax)
|
||||
#define PP (model->HFET2p)
|
||||
#define RD (model->HFET2rd)
|
||||
#define RDI (model->HFET2rdi)
|
||||
#define RS (model->HFET2rs)
|
||||
#define RSI (model->HFET2rsi)
|
||||
#define SIGMA0 (model->HFET2sigma0)
|
||||
#define TYPE (model->HFET2type)
|
||||
#define VS (model->HFET2vs)
|
||||
#define VSIGMA (model->HFET2vsigma)
|
||||
#define VSIGMAT (model->HFET2vsigmat)
|
||||
#define HFET2_VT1 (model->HFET2vt1) /* Fix a redefinition in include files */
|
||||
#define VT2 (model->HFET2vt2)
|
||||
#define VTO (model->HFET2vto)
|
||||
|
||||
#define DELTA2 (model->HFET2deltaSqr)
|
||||
|
||||
#define GCHI0 (here->HFET2gchi0)
|
||||
#define GGRLW (here->HFET2ggrlw)
|
||||
#define JSLW (here->HFET2jslw)
|
||||
#define IMAX (here->HFET2imax)
|
||||
#define L (here->HFET2length)
|
||||
#define N0 (here->HFET2n0)
|
||||
#define N01 (here->HFET2n01)
|
||||
#define N02 (here->HFET2n02)
|
||||
#define TEMP (here->HFET2temp)
|
||||
#define TLAMBDA (here->HFET2tLambda)
|
||||
#define TMU (here->HFET2tMu)
|
||||
#define TNMAX (here->HFET2tNmax)
|
||||
#define TVTO (here->HFET2tVto)
|
||||
#define VCRIT (here->HFET2vcrit)
|
||||
#define W (here->HFET2width)
|
||||
|
||||
#include "hfet2ext.h"
|
||||
|
||||
#endif /*HFET2*/
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 S. Hwang
|
||||
**********/
|
||||
/*
|
||||
Imported into hfet2 model: Paolo Nenzi 2001
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "hfet2defs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
HFET2delete(inModel,name,inst)
|
||||
GENmodel *inModel;
|
||||
IFuid name;
|
||||
GENinstance **inst;
|
||||
{
|
||||
HFET2model *model = (HFET2model*)inModel;
|
||||
HFET2instance **fast = (HFET2instance**)inst;
|
||||
HFET2instance **prev = NULL;
|
||||
HFET2instance *here;
|
||||
|
||||
for( ; model ; model = model->HFET2nextModel) {
|
||||
prev = &(model->HFET2instances);
|
||||
for(here = *prev; here ; here = *prev) {
|
||||
if(here->HFET2name == name || (fast && here==*fast) ) {
|
||||
*prev= here->HFET2nextInstance;
|
||||
FREE(here);
|
||||
return(OK);
|
||||
}
|
||||
prev = &(here->HFET2nextInstance);
|
||||
}
|
||||
}
|
||||
return(E_NODEV);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "hfet2defs.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
void HFET2destroy(inModel)
|
||||
GENmodel **inModel;
|
||||
{
|
||||
|
||||
HFET2model **model = (HFET2model**)inModel;
|
||||
HFET2instance *here;
|
||||
HFET2instance *prev = NULL;
|
||||
HFET2model *mod = *model;
|
||||
HFET2model *oldmod = NULL;
|
||||
|
||||
for( ; mod ; mod = mod->HFET2nextModel) {
|
||||
if(oldmod) FREE(oldmod);
|
||||
oldmod = mod;
|
||||
prev = (HFET2instance *)NULL;
|
||||
for(here = mod->HFET2instances ; here ; here = here->HFET2nextInstance) {
|
||||
if(prev) FREE(prev);
|
||||
prev = here;
|
||||
}
|
||||
if(prev) FREE(prev);
|
||||
}
|
||||
if(oldmod) FREE(oldmod);
|
||||
*model = NULL;
|
||||
return;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
extern int HFET2acLoad(GENmodel*,CKTcircuit*);
|
||||
extern int HFET2ask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
||||
extern int HFET2delete(GENmodel*,IFuid,GENinstance**);
|
||||
extern void HFET2destroy(GENmodel**);
|
||||
extern int HFET2getic(GENmodel*,CKTcircuit*);
|
||||
extern int HFET2load(GENmodel*,CKTcircuit*);
|
||||
extern int HFET2mAsk(CKTcircuit*,GENmodel*,int,IFvalue*);
|
||||
extern int HFET2mDelete(GENmodel**,IFuid,GENmodel*);
|
||||
extern int HFET2mParam(int,IFvalue*,GENmodel*);
|
||||
extern int HFET2param(int,IFvalue*,GENinstance*,IFvalue*);
|
||||
extern int HFET2setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||
extern int HFET2temp(GENmodel*,CKTcircuit*);
|
||||
extern int HFET2trunc(GENmodel*,CKTcircuit*,double*);
|
||||
extern int HFET2unsetup( GENmodel*,CKTcircuit*);
|
||||
|
||||
#else /* stdc */
|
||||
extern int HFET2acLoad();
|
||||
extern int HFET2ask();
|
||||
extern int HFET2delete();
|
||||
extern void HFET2destroy();
|
||||
extern int HFET2getic();
|
||||
extern int HFET2load();
|
||||
extern int HFETAmAsk();
|
||||
extern int HFETAmDelete();
|
||||
extern int HFET2mParam();
|
||||
extern int HFET2param();
|
||||
extern int HFET2setup();
|
||||
extern int HFET2temp();
|
||||
extern int HFET2trunc();
|
||||
extern int HFET2unsetup();
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int HFET2getic(inModel, ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
|
||||
HFET2model *model = (HFET2model*)inModel;
|
||||
HFET2instance *here;
|
||||
|
||||
for( ; model ; model = model->HFET2nextModel) {
|
||||
for(here = model->HFET2instances; here ; here = here->HFET2nextInstance) {
|
||||
if(!here->HFET2icVDSGiven) {
|
||||
here->HFET2icVDS = *(ckt->CKTrhs + here->HFET2drainNode) -
|
||||
*(ckt->CKTrhs + here->HFET2sourceNode);
|
||||
}
|
||||
if(!here->HFET2icVGSGiven) {
|
||||
here->HFET2icVGS = *(ckt->CKTrhs + here->HFET2gateNode) -
|
||||
*(ckt->CKTrhs + here->HFET2sourceNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#include <config.h>
|
||||
|
||||
#include <devdefs.h>
|
||||
|
||||
#include "hfet2itf.h"
|
||||
#include "hfet2ext.h"
|
||||
#include "hfet2init.h"
|
||||
|
||||
|
||||
SPICEdev HFET2info = {
|
||||
{
|
||||
"HFET2",
|
||||
"HFET2 Model",
|
||||
|
||||
&HFET2nSize,
|
||||
&HFET2nSize,
|
||||
HFET2names,
|
||||
|
||||
&HFET2pTSize,
|
||||
HFET2pTable,
|
||||
|
||||
&HFET2mPTSize,
|
||||
HFET2mPTable,
|
||||
DEV_DEFAULT
|
||||
},
|
||||
|
||||
DEVparam : HFET2param,
|
||||
DEVmodParam : HFET2mParam,
|
||||
DEVload : HFET2load,
|
||||
DEVsetup : HFET2setup,
|
||||
DEVunsetup : HFET2unsetup,
|
||||
DEVpzSetup : HFET2setup,
|
||||
DEVtemperature: HFET2temp,
|
||||
DEVtrunc : HFET2trunc,
|
||||
DEVfindBranch : NULL,
|
||||
DEVacLoad : HFET2acLoad,
|
||||
DEVaccept : NULL,
|
||||
DEVdestroy : HFET2destroy,
|
||||
DEVmodDelete : HFET2mDelete,
|
||||
DEVdelete : HFET2delete,
|
||||
DEVsetic : HFET2getic,
|
||||
DEVask : HFET2ask,
|
||||
DEVmodAsk : HFET2mAsk,
|
||||
DEVpzLoad : NULL,
|
||||
DEVconvTest : NULL,
|
||||
DEVsenSetup : NULL,
|
||||
DEVsenLoad : NULL,
|
||||
DEVsenUpdate : NULL,
|
||||
DEVsenAcLoad : NULL,
|
||||
DEVsenPrint : NULL,
|
||||
DEVsenTrunc : NULL,
|
||||
DEVdisto : NULL,
|
||||
DEVnoise : NULL,
|
||||
|
||||
DEVinstSize : &HFET2iSize,
|
||||
DEVmodSize : &HFET2mSize
|
||||
|
||||
};
|
||||
|
||||
|
||||
SPICEdev *
|
||||
get_hfet2_info(void)
|
||||
{
|
||||
return &HFET2info;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef _HFET2INIT_H
|
||||
#define _HFET2INIT_H
|
||||
|
||||
extern IFparm HFET2pTable[ ];
|
||||
extern IFparm HFET2mPTable[ ];
|
||||
extern char *HFET2names[ ];
|
||||
extern int HFET2pTSize;
|
||||
extern int HFET2mPTSize;
|
||||
extern int HFET2nSize;
|
||||
extern int HFET2iSize;
|
||||
extern int HFET2mSize;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef DEV_HFET2
|
||||
#define DEV_HFET2
|
||||
|
||||
SPICEdev *get_hfet2_info(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,456 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "devdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "const.h"
|
||||
#include "trandefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
void Pause(void);
|
||||
|
||||
static void hfeta2(HFET2model *model, HFET2instance *here, CKTcircuit *ckt,
|
||||
double vgs, double vds, double *cdrain, double *gm,
|
||||
double *gds, double *capgs, double *capgd);
|
||||
|
||||
|
||||
int HFET2load(inModel, ckt)
|
||||
GENmodel *inModel;
|
||||
register CKTcircuit *ckt;
|
||||
{
|
||||
|
||||
register HFET2model *model = (HFET2model*)inModel;
|
||||
register HFET2instance *here;
|
||||
double capgd;
|
||||
double capgs;
|
||||
double cd;
|
||||
double cdhat;
|
||||
double cdrain;
|
||||
double cdreq;
|
||||
double ceq;
|
||||
double ceqgd;
|
||||
double ceqgs;
|
||||
double cg;
|
||||
double cgd;
|
||||
double cghat;
|
||||
double delvds;
|
||||
double delvgd;
|
||||
double delvgs;
|
||||
double gdpr;
|
||||
double gds;
|
||||
double geq;
|
||||
double ggd;
|
||||
double ggs;
|
||||
double gm;
|
||||
double gspr;
|
||||
double vcrit;
|
||||
double vds;
|
||||
double vgd;
|
||||
double vgd1;
|
||||
double vgs;
|
||||
double vgs1;
|
||||
double vt;
|
||||
double vto;
|
||||
double xfact;
|
||||
int icheck;
|
||||
int ichk1;
|
||||
int error;
|
||||
int inverse;
|
||||
|
||||
for( ; model != NULL; model = model->HFET2nextModel ) {
|
||||
for(here = model->HFET2instances; here != NULL; here=here->HFET2nextInstance) {
|
||||
gdpr = model->HFET2drainConduct;
|
||||
gspr = model->HFET2sourceConduct;
|
||||
vcrit = VCRIT;
|
||||
vto = TVTO;
|
||||
vt = CONSTKoverQ*TEMP;
|
||||
icheck = 1;
|
||||
if( ckt->CKTmode & MODEINITSMSIG) {
|
||||
vgs = *(ckt->CKTstate0 + here->HFET2vgs);
|
||||
vgd = *(ckt->CKTstate0 + here->HFET2vgd);
|
||||
} else if(ckt->CKTmode & MODEINITTRAN) {
|
||||
vgs = *(ckt->CKTstate1 + here->HFET2vgs);
|
||||
vgd = *(ckt->CKTstate1 + here->HFET2vgd);
|
||||
} else if((ckt->CKTmode & MODEINITJCT) && (ckt->CKTmode & MODETRANOP) &&
|
||||
(ckt->CKTmode & MODEUIC) ) {
|
||||
vds = model->HFET2type*here->HFET2icVDS;
|
||||
vgs = model->HFET2type*here->HFET2icVGS;
|
||||
vgd = vgs-vds;
|
||||
} else if ( (ckt->CKTmode & MODEINITJCT) && (here->HFET2off == 0) ) {
|
||||
vgs = -1;
|
||||
vgd = -1;
|
||||
} else if((ckt->CKTmode & MODEINITJCT) ||
|
||||
((ckt->CKTmode & MODEINITFIX) && (here->HFET2off))) {
|
||||
vgs = 0;
|
||||
vgd = 0;
|
||||
} else {
|
||||
#ifndef PREDICTOR
|
||||
if(ckt->CKTmode & MODEINITPRED) {
|
||||
xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2];
|
||||
*(ckt->CKTstate0 + here->HFET2vgs) =
|
||||
*(ckt->CKTstate1 + here->HFET2vgs);
|
||||
vgs = (1+xfact) * *(ckt->CKTstate1 + here->HFET2vgs) -
|
||||
xfact * *(ckt->CKTstate2 + here->HFET2vgs);
|
||||
*(ckt->CKTstate0 + here->HFET2vgd) =
|
||||
*(ckt->CKTstate1 + here->HFET2vgd);
|
||||
vgd = (1+xfact)* *(ckt->CKTstate1 + here->HFET2vgd) -
|
||||
xfact * *(ckt->CKTstate2 + here->HFET2vgd);
|
||||
*(ckt->CKTstate0 + here->HFET2cg) =
|
||||
*(ckt->CKTstate1 + here->HFET2cg);
|
||||
*(ckt->CKTstate0 + here->HFET2cd) =
|
||||
*(ckt->CKTstate1 + here->HFET2cd);
|
||||
*(ckt->CKTstate0 + here->HFET2cgd) =
|
||||
*(ckt->CKTstate1 + here->HFET2cgd);
|
||||
*(ckt->CKTstate0 + here->HFET2gm) =
|
||||
*(ckt->CKTstate1 + here->HFET2gm);
|
||||
*(ckt->CKTstate0 + here->HFET2gds) =
|
||||
*(ckt->CKTstate1 + here->HFET2gds);
|
||||
*(ckt->CKTstate0 + here->HFET2ggs) =
|
||||
*(ckt->CKTstate1 + here->HFET2ggs);
|
||||
*(ckt->CKTstate0 + here->HFET2ggd) =
|
||||
*(ckt->CKTstate1 + here->HFET2ggd);
|
||||
} else {
|
||||
#endif /* PREDICTOR */
|
||||
vgs = model->HFET2type*
|
||||
(*(ckt->CKTrhsOld+ here->HFET2gateNode)- *(ckt->CKTrhsOld+
|
||||
here->HFET2sourcePrimeNode));
|
||||
vgd = model->HFET2type*
|
||||
(*(ckt->CKTrhsOld+here->HFET2gateNode)- *(ckt->CKTrhsOld+
|
||||
here->HFET2drainPrimeNode));
|
||||
#ifndef PREDICTOR
|
||||
}
|
||||
#endif /* PREDICTOR */
|
||||
delvgs=vgs - *(ckt->CKTstate0 + here->HFET2vgs);
|
||||
delvgd=vgd - *(ckt->CKTstate0 + here->HFET2vgd);
|
||||
delvds=delvgs - delvgd;
|
||||
cghat= *(ckt->CKTstate0 + here->HFET2cg) +
|
||||
*(ckt->CKTstate0 + here->HFET2ggd)*delvgd +
|
||||
*(ckt->CKTstate0 + here->HFET2ggs)*delvgs;
|
||||
cdhat= *(ckt->CKTstate0 + here->HFET2cd) +
|
||||
*(ckt->CKTstate0 + here->HFET2gm)*delvgs +
|
||||
*(ckt->CKTstate0 + here->HFET2gds)*delvds -
|
||||
*(ckt->CKTstate0 + here->HFET2ggd)*delvgd;
|
||||
|
||||
// bypass if solution has not changed
|
||||
|
||||
if((ckt->CKTbypass) &&
|
||||
(!(ckt->CKTmode & MODEINITPRED)) &&
|
||||
(fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs),
|
||||
fabs(*(ckt->CKTstate0 + here->HFET2vgs)))+
|
||||
ckt->CKTvoltTol) )
|
||||
if ( (fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd),
|
||||
fabs(*(ckt->CKTstate0 + here->HFET2vgd)))+
|
||||
ckt->CKTvoltTol))
|
||||
if ( (fabs(cghat-*(ckt->CKTstate0 + here->HFET2cg))
|
||||
< ckt->CKTreltol*MAX(fabs(cghat),
|
||||
fabs(*(ckt->CKTstate0 + here->HFET2cg)))+
|
||||
ckt->CKTabstol) ) if ( /* hack - expression too big */
|
||||
(fabs(cdhat-*(ckt->CKTstate0 + here->HFET2cd))
|
||||
< ckt->CKTreltol*MAX(fabs(cdhat),
|
||||
fabs(*(ckt->CKTstate0 + here->HFET2cd)))+
|
||||
ckt->CKTabstol) ) {
|
||||
|
||||
/* we can do a bypass */
|
||||
vgs= *(ckt->CKTstate0 + here->HFET2vgs);
|
||||
vgd= *(ckt->CKTstate0 + here->HFET2vgd);
|
||||
vds= vgs-vgd;
|
||||
cg= *(ckt->CKTstate0 + here->HFET2cg);
|
||||
cd= *(ckt->CKTstate0 + here->HFET2cd);
|
||||
cgd= *(ckt->CKTstate0 + here->HFET2cgd);
|
||||
gm= *(ckt->CKTstate0 + here->HFET2gm);
|
||||
gds= *(ckt->CKTstate0 + here->HFET2gds);
|
||||
ggs= *(ckt->CKTstate0 + here->HFET2ggs);
|
||||
ggd= *(ckt->CKTstate0 + here->HFET2ggd);
|
||||
goto load;
|
||||
}
|
||||
|
||||
// limit nonlinear branch voltages
|
||||
|
||||
ichk1=1;
|
||||
vgs = DEVpnjlim(vgs,*(ckt->CKTstate0 + here->HFET2vgs),CONSTvt0,vcrit, &icheck);
|
||||
vgd = DEVpnjlim(vgd,*(ckt->CKTstate0 + here->HFET2vgd),CONSTvt0,vcrit,&ichk1);
|
||||
if(ichk1 == 1) {
|
||||
icheck=1;
|
||||
}
|
||||
vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->HFET2vgs),TVTO);
|
||||
vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->HFET2vgd),TVTO);
|
||||
}
|
||||
cg = 0;
|
||||
cgd = 0;
|
||||
ggd = 0;
|
||||
ggs = 0;
|
||||
vds = vgs-vgd;
|
||||
{
|
||||
double arg = -vgs*DEL/vt;
|
||||
double earg = exp(arg);
|
||||
double vtn = N*vt;
|
||||
double expe = exp(vgs/vtn);
|
||||
ggs = JSLW*expe/vtn+GGRLW*earg*(1-arg);
|
||||
cg = JSLW*(expe-1)+GGRLW*vgs*earg;
|
||||
arg = -vgd*DEL/vt;
|
||||
earg = exp(arg);
|
||||
expe = exp(vgd/vtn);
|
||||
ggd = JSLW*expe/vtn+GGRLW*earg*(1-arg);
|
||||
cgd = JSLW*(expe-1)+GGRLW*vgd*earg;
|
||||
cg += cgd;
|
||||
}
|
||||
if(vds < 0) {
|
||||
vds = -vds;
|
||||
inverse = 1;
|
||||
} else
|
||||
inverse = 0;
|
||||
hfeta2(model,here,ckt,vds>0?vgs:vgd,vds,&cdrain,&gm,&gds,&capgs,&capgd);
|
||||
if(inverse) {
|
||||
double temp;
|
||||
cdrain = -cdrain;
|
||||
vds = -vds;
|
||||
temp = capgs;
|
||||
capgs = capgd;
|
||||
capgd = temp;
|
||||
}
|
||||
cd = cdrain - cgd;
|
||||
if((ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || ((ckt->CKTmode & MODETRANOP) &&
|
||||
(ckt->CKTmode & MODEUIC)) ){
|
||||
// charge storage elements
|
||||
vgs1 = *(ckt->CKTstate1 + here->HFET2vgs);
|
||||
vgd1 = *(ckt->CKTstate1 + here->HFET2vgd);
|
||||
|
||||
if(ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->HFET2qgs) = capgs*vgs;
|
||||
*(ckt->CKTstate1 + here->HFET2qgd) = capgd*vgd;
|
||||
}
|
||||
*(ckt->CKTstate0+here->HFET2qgs) = *(ckt->CKTstate1+here->HFET2qgs)
|
||||
+ capgs*(vgs-vgs1);
|
||||
*(ckt->CKTstate0+here->HFET2qgd) = *(ckt->CKTstate1+here->HFET2qgd)
|
||||
+ capgd*(vgd-vgd1);
|
||||
|
||||
// store small-signal parameters
|
||||
|
||||
if( (!(ckt->CKTmode & MODETRANOP)) || (!(ckt->CKTmode & MODEUIC)) ) {
|
||||
if(ckt->CKTmode & MODEINITSMSIG) {
|
||||
*(ckt->CKTstate0 + here->HFET2qgs) = capgs;
|
||||
*(ckt->CKTstate0 + here->HFET2qgd) = capgd;
|
||||
continue; /*go to 1000*/
|
||||
}
|
||||
|
||||
// transient analysis
|
||||
|
||||
if(ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->HFET2qgs) = *(ckt->CKTstate0 + here->HFET2qgs);
|
||||
*(ckt->CKTstate1 + here->HFET2qgd) = *(ckt->CKTstate0 + here->HFET2qgd);
|
||||
}
|
||||
error = NIintegrate(ckt,&geq,&ceq,capgs,here->HFET2qgs);
|
||||
if(error) return(error);
|
||||
ggs = ggs + geq;
|
||||
cg = cg + *(ckt->CKTstate0 + here->HFET2cqgs);
|
||||
error = NIintegrate(ckt,&geq,&ceq,capgd,here->HFET2qgd);
|
||||
if(error) return(error);
|
||||
ggd = ggd + geq;
|
||||
cg = cg + *(ckt->CKTstate0 + here->HFET2cqgd);
|
||||
cd = cd - *(ckt->CKTstate0 + here->HFET2cqgd);
|
||||
cgd = cgd + *(ckt->CKTstate0 + here->HFET2cqgd);
|
||||
if (ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->HFET2cqgs) = *(ckt->CKTstate0 + here->HFET2cqgs);
|
||||
*(ckt->CKTstate1 + here->HFET2cqgd) = *(ckt->CKTstate0 + here->HFET2cqgd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check convergence
|
||||
|
||||
if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) {
|
||||
if((icheck == 1)
|
||||
|| (fabs(cghat-cg) >= ckt->CKTreltol*
|
||||
MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) ||
|
||||
(fabs(cdhat-cd) > ckt->CKTreltol*
|
||||
MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol)
|
||||
) {
|
||||
ckt->CKTnoncon++;
|
||||
}
|
||||
}
|
||||
*(ckt->CKTstate0 + here->HFET2vgs) = vgs;
|
||||
*(ckt->CKTstate0 + here->HFET2vgd) = vgd;
|
||||
*(ckt->CKTstate0 + here->HFET2cg) = cg;
|
||||
*(ckt->CKTstate0 + here->HFET2cd) = cd;
|
||||
*(ckt->CKTstate0 + here->HFET2cgd) = cgd;
|
||||
*(ckt->CKTstate0 + here->HFET2gm) = gm;
|
||||
*(ckt->CKTstate0 + here->HFET2gds) = gds;
|
||||
*(ckt->CKTstate0 + here->HFET2ggs) = ggs;
|
||||
*(ckt->CKTstate0 + here->HFET2ggd) = ggd;
|
||||
|
||||
// load current vector
|
||||
|
||||
load:
|
||||
ceqgd=model->HFET2type*(cgd-ggd*vgd);
|
||||
ceqgs=model->HFET2type*((cg-cgd)-ggs*vgs);
|
||||
cdreq=model->HFET2type*((cd+cgd)-gds*vds-gm*vgs);
|
||||
*(ckt->CKTrhs + here->HFET2gateNode) += (-ceqgs-ceqgd);
|
||||
*(ckt->CKTrhs + here->HFET2drainPrimeNode) += (-cdreq+ceqgd);
|
||||
*(ckt->CKTrhs + here->HFET2sourcePrimeNode) += (cdreq+ceqgs);
|
||||
|
||||
// load y matrix
|
||||
|
||||
*(here->HFET2drainDrainPrimePtr) += (-gdpr);
|
||||
*(here->HFET2gateDrainPrimePtr) += (-ggd);
|
||||
*(here->HFET2gateSourcePrimePtr) += (-ggs);
|
||||
*(here->HFET2sourceSourcePrimePtr) += (-gspr);
|
||||
*(here->HFET2drainPrimeDrainPtr) += (-gdpr);
|
||||
*(here->HFET2drainPrimeGatePtr) += (gm-ggd);
|
||||
*(here->HFET2drainPriHFET2ourcePrimePtr) += (-gds-gm);
|
||||
*(here->HFET2sourcePrimeGatePtr) += (-ggs-gm);
|
||||
*(here->HFET2sourcePriHFET2ourcePtr) += (-gspr);
|
||||
*(here->HFET2sourcePrimeDrainPrimePtr) += (-gds);
|
||||
*(here->HFET2drainDrainPtr) += (gdpr);
|
||||
*(here->HFET2gateGatePtr) += (ggd+ggs);
|
||||
*(here->HFET2sourceSourcePtr) += (gspr);
|
||||
*(here->HFET2drainPrimeDrainPrimePtr) += (gdpr+gds+ggd);
|
||||
*(here->HFET2sourcePriHFET2ourcePrimePtr) += (gspr+gds+gm+ggs);
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void hfeta2(HFET2model *model, HFET2instance *here, CKTcircuit *ckt,
|
||||
double vgs, double vds, double *cdrain, double *gm,
|
||||
double *gds, double *capgs, double *capgd)
|
||||
|
||||
{
|
||||
|
||||
double vt;
|
||||
double vgt;
|
||||
double vgt0;
|
||||
double sigma;
|
||||
double vgte;
|
||||
double isat;
|
||||
double isatm;
|
||||
double ns;
|
||||
double nsm;
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double g;
|
||||
double h;
|
||||
double p;
|
||||
double q;
|
||||
double s;
|
||||
double t;
|
||||
double u;
|
||||
double nsc;
|
||||
double nsn;
|
||||
double temp;
|
||||
double etavth;
|
||||
double gch;
|
||||
double gchi;
|
||||
double gchim;
|
||||
double vsate;
|
||||
double vdse;
|
||||
double cg1;
|
||||
double cgc;
|
||||
double rt;
|
||||
double vl;
|
||||
double delidgch;
|
||||
double delgchgchi;
|
||||
double delgchins;
|
||||
double delnsnsm;
|
||||
double delnsmvgt;
|
||||
double delvgtevgt;
|
||||
double delidvsate;
|
||||
double delvsateisat;
|
||||
double delisatisatm;
|
||||
double delisatmvgte;
|
||||
double delisatmgchim;
|
||||
double delvsategch;
|
||||
double delidvds;
|
||||
double delvgtvgs;
|
||||
double delvsatevgt;
|
||||
|
||||
vt = CONSTKoverQ*TEMP;
|
||||
etavth = ETA*vt;
|
||||
vl = VS/TMU*L;
|
||||
rt = RSI+RDI;
|
||||
vgt0 = vgs - TVTO;
|
||||
s = exp((vgt0-VSIGMAT)/VSIGMA);
|
||||
sigma = SIGMA0/(1+s);
|
||||
vgt = vgt0+sigma*vds;
|
||||
u = 0.5*vgt/vt-1;
|
||||
t = sqrt(DELTA2+u*u);
|
||||
vgte = vt*(2+u+t);
|
||||
b = exp(vgt/etavth);
|
||||
if(model->HFET2eta2Given && model->HFET2d2Given) {
|
||||
nsc = N02*exp((vgt+TVTO-VT2)/(ETA2*vt));
|
||||
nsn = 2*N0*log(1+0.5*b);
|
||||
nsm = nsn*nsc/(nsn+nsc);
|
||||
} else {
|
||||
nsm = 2*N0*log(1+0.5*b);
|
||||
}
|
||||
if(nsm < 1.0e-38) {
|
||||
*cdrain = 0;
|
||||
*gm = 0.0;
|
||||
*gds = 0.0;
|
||||
*capgs = CF;
|
||||
*capgd = CF;
|
||||
return;
|
||||
}
|
||||
c = pow(nsm/TNMAX,GAMMA);
|
||||
q = pow(1+c,1.0/GAMMA);
|
||||
ns = nsm/q;
|
||||
gchi = GCHI0*ns;
|
||||
gch = gchi/(1+gchi*rt);
|
||||
gchim = GCHI0*nsm;
|
||||
h = sqrt(1+2*gchim*RSI + vgte*vgte/(vl*vl));
|
||||
p = 1+gchim*RSI+h;
|
||||
isatm = gchim*vgte/p;
|
||||
g = pow(isatm/IMAX,GAMMA);
|
||||
isat = isatm/pow(1+g,1/GAMMA);
|
||||
vsate = isat/gch;
|
||||
d = pow(vds/vsate,M);
|
||||
e = pow(1+d,1.0/M);
|
||||
delidgch = vds*(1+TLAMBDA*vds)/e;
|
||||
*cdrain = gch*delidgch;
|
||||
delidvsate = (*cdrain)*d/vsate/(1+d);
|
||||
delidvds = gch*(1+2*TLAMBDA*vds)/e-(*cdrain)*
|
||||
pow(vds/vsate,M-1)/(vsate*(1+d));
|
||||
a = 1+gchi*rt;
|
||||
delgchgchi = 1.0/(a*a);
|
||||
delgchins = GCHI0;
|
||||
delnsnsm = ns/nsm*(1-c/(1+c));
|
||||
delvgtevgt = 0.5*(1+u/t);
|
||||
delnsmvgt = N0/etavth/(1.0/b + 0.5);
|
||||
if(model->HFET2eta2Given && model->HFET2d2Given)
|
||||
delnsmvgt = nsc*(nsc*delnsmvgt+nsn*nsn/(ETA2*vt))/((nsc+nsn)*(nsc+nsn));
|
||||
delvsateisat = 1.0/gch;
|
||||
delisatisatm = isat/isatm*(1-g/(1+g));
|
||||
delisatmvgte = gchim*(p - vgte*vgte/(vl*vl*h))/(p*p);
|
||||
delvsategch = -vsate/gch;
|
||||
delisatmgchim = vgte*(p - gchim*RSI*(1+1.0/h))/(p*p);
|
||||
delvgtvgs = 1-vds*SIGMA0/VSIGMA*s/((1+s)*(1+s));
|
||||
p = delgchgchi*delgchins*delnsnsm*delnsmvgt;
|
||||
delvsatevgt = (delvsateisat*delisatisatm*(delisatmvgte*delvgtevgt +
|
||||
delisatmgchim*GCHI0*delnsmvgt)+delvsategch*p);
|
||||
g = delidgch*p + delidvsate*delvsatevgt;
|
||||
*gm = g*delvgtvgs;
|
||||
*gds = delidvds + g*sigma;
|
||||
|
||||
// Capacitance calculations
|
||||
temp = ETA1*vt;
|
||||
cg1 = 1/(D1/EPSI+temp*exp(-(vgs-HFET2_VT1)/temp));
|
||||
cgc = W*L*(CHARGE*delnsnsm*delnsmvgt*delvgtvgs+cg1);
|
||||
vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC);
|
||||
a = (vsate-vdse)/(2*vsate-vdse);
|
||||
a = a*a;
|
||||
temp = 2.0/3.0;
|
||||
p = PP + (1-PP)*exp(-vds/vsate);
|
||||
*capgs = CF+2*temp*cgc*(1-a)/(1+p);
|
||||
a = vsate/(2*vsate-vdse);
|
||||
a = a*a;
|
||||
*capgd = CF+2*p*temp*cgc*(1-a)/(1+p);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
**********/
|
||||
/*
|
||||
Imported into HFET2 model: Paolo Nenzi 2001
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "devdefs.h"
|
||||
#include "ifsim.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
HFET2mAsk(ckt,inst,which,value)
|
||||
CKTcircuit *ckt;
|
||||
GENmodel *inst;
|
||||
int which;
|
||||
IFvalue *value;
|
||||
{
|
||||
HFET2model *here = (HFET2model*)inst;
|
||||
switch(which) {
|
||||
case HFET2_MOD_VTO:
|
||||
value->rValue = here->HFET2vto;
|
||||
return (OK);
|
||||
case HFET2_MOD_LAMBDA:
|
||||
value->rValue = here->HFET2lambda;
|
||||
return (OK);
|
||||
case HFET2_MOD_RD:
|
||||
value->rValue = here->HFET2rd;
|
||||
return (OK);
|
||||
case HFET2_MOD_RS:
|
||||
value->rValue = here->HFET2rs;
|
||||
return (OK);
|
||||
case HFET2_MOD_RDI:
|
||||
value->rValue = here->HFET2rdi;
|
||||
return (OK);
|
||||
case HFET2_MOD_RSI:
|
||||
value->rValue = here->HFET2rsi;
|
||||
return (OK);
|
||||
case HFET2_MOD_ETA:
|
||||
value->rValue = here->HFET2eta;
|
||||
return (OK);
|
||||
case HFET2_MOD_M:
|
||||
value->rValue = here->HFET2m;
|
||||
return (OK);
|
||||
case HFET2_MOD_MC:
|
||||
value->rValue = here->HFET2mc;
|
||||
return (OK);
|
||||
case HFET2_MOD_GAMMA:
|
||||
value->rValue = here->HFET2gamma;
|
||||
return (OK);
|
||||
case HFET2_MOD_SIGMA0:
|
||||
value->rValue = here->HFET2sigma0;
|
||||
return (OK);
|
||||
case HFET2_MOD_VSIGMAT:
|
||||
value->rValue = here->HFET2vsigmat;
|
||||
return (OK);
|
||||
case HFET2_MOD_VSIGMA:
|
||||
value->rValue = here->HFET2vsigma;
|
||||
return (OK);
|
||||
case HFET2_MOD_MU:
|
||||
value->rValue = here->HFET2mu;
|
||||
return (OK);
|
||||
case HFET2_MOD_DI:
|
||||
value->rValue = here->HFET2di;
|
||||
return (OK);
|
||||
case HFET2_MOD_DELTA:
|
||||
value->rValue = here->HFET2delta;
|
||||
return (OK);
|
||||
case HFET2_MOD_VS:
|
||||
value->rValue = here->HFET2vs;
|
||||
return (OK);
|
||||
case HFET2_MOD_NMAX:
|
||||
value->rValue = here->HFET2nmax;
|
||||
return (OK);
|
||||
case HFET2_MOD_DELTAD:
|
||||
value->rValue = here->HFET2deltad;
|
||||
return (OK);
|
||||
case HFET2_MOD_P:
|
||||
value->rValue = here->HFET2p;
|
||||
return (OK);
|
||||
case HFET2_MOD_JS:
|
||||
value->rValue = here->HFET2js;
|
||||
return (OK);
|
||||
case HFET2_MOD_ETA1:
|
||||
value->rValue = here->HFET2eta1;
|
||||
return (OK);
|
||||
case HFET2_MOD_D1:
|
||||
value->rValue = here->HFET2d1;
|
||||
return (OK);
|
||||
case HFET2_MOD_VT1:
|
||||
value->rValue = here->HFET2vt1;
|
||||
return (OK);
|
||||
case HFET2_MOD_ETA2:
|
||||
value->rValue = here->HFET2eta2;
|
||||
return (OK);
|
||||
case HFET2_MOD_D2:
|
||||
value->rValue = here->HFET2d2;
|
||||
return (OK);
|
||||
case HFET2_MOD_VT2:
|
||||
value->rValue = here->HFET2vt2;
|
||||
return (OK);
|
||||
case HFET2_MOD_GGR:
|
||||
value->rValue = here->HFET2ggr;
|
||||
return (OK);
|
||||
case HFET2_MOD_DEL:
|
||||
value->rValue = here->HFET2del;
|
||||
return (OK);
|
||||
case HFET2_MOD_KLAMBDA:
|
||||
value->rValue = here->HFET2klambda;
|
||||
return (OK);
|
||||
case HFET2_MOD_KMU:
|
||||
value->rValue = here->HFET2kmu;
|
||||
return (OK);
|
||||
case HFET2_MOD_KVTO:
|
||||
value->rValue = here->HFET2kvto;
|
||||
return (OK);
|
||||
case HFET2_MOD_EPSI:
|
||||
value->rValue = here->HFET2epsi;
|
||||
return (OK);
|
||||
case HFET2_MOD_KNMAX:
|
||||
value->rValue = here->HFET2knmax;
|
||||
return (OK);
|
||||
case HFET2_MOD_N:
|
||||
value->rValue = here->HFET2n;
|
||||
return (OK);
|
||||
case HFET2_MOD_CF:
|
||||
value->rValue = here->HFET2cf;
|
||||
return (OK);
|
||||
|
||||
case HFET2_MOD_DRAINCONDUCT:
|
||||
value->rValue = here->HFET2drainConduct;
|
||||
return (OK);
|
||||
case HFET2_MOD_SOURCECONDUCT:
|
||||
value->rValue = here->HFET2sourceConduct;
|
||||
return (OK);
|
||||
/* case HFET2_MOD_DEPLETIONCAP:
|
||||
value->rValue = here->HFET2???;
|
||||
return(OK); */
|
||||
/* case HFET2_MOD_VCRIT:
|
||||
value->rValue = here->HFET2vcrit;
|
||||
return (OK); */
|
||||
|
||||
case HFET2_MOD_TYPE:
|
||||
if (here->HFET2type == NHFET)
|
||||
value->sValue = "nhfet";
|
||||
else
|
||||
value->sValue = "phfet";
|
||||
default:
|
||||
return (E_BADPARM);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 S. Hwang
|
||||
**********/
|
||||
/*
|
||||
Imported into hfet2 model: Paolo Nenzi 2001
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "hfet2defs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
HFET2mDelete(inModel,modname,kill)
|
||||
GENmodel **inModel;
|
||||
IFuid modname;
|
||||
GENmodel *kill;
|
||||
{
|
||||
HFET2model **model = (HFET2model**)inModel;
|
||||
HFET2model *modfast = (HFET2model*)kill;
|
||||
HFET2instance *here;
|
||||
HFET2instance *prev = NULL;
|
||||
HFET2model **oldmod;
|
||||
oldmod = model;
|
||||
for( ; *model ; model = &((*model)->HFET2nextModel)) {
|
||||
if( (*model)->HFET2modName == modname ||
|
||||
(modfast && *model == modfast) ) goto delgot;
|
||||
oldmod = model;
|
||||
}
|
||||
return(E_NOMOD);
|
||||
|
||||
delgot:
|
||||
*oldmod = (*model)->HFET2nextModel; /* cut deleted device out of list */
|
||||
for(here = (*model)->HFET2instances ; here ; here = here->HFET2nextInstance) {
|
||||
if(prev) FREE(prev);
|
||||
prev = here;
|
||||
}
|
||||
if(prev) FREE(prev);
|
||||
FREE(*model);
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "ifsim.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int HFET2mParam(param, value, inModel)
|
||||
int param;
|
||||
IFvalue *value;
|
||||
GENmodel *inModel;
|
||||
{
|
||||
|
||||
HFET2model *model = (HFET2model*)inModel;
|
||||
switch(param) {
|
||||
case HFET2_MOD_CF:
|
||||
model->HFET2cfGiven = TRUE;
|
||||
CF = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_D1:
|
||||
model->HFET2d1Given = TRUE;
|
||||
D1 = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_D2:
|
||||
model->HFET2d2Given = TRUE;
|
||||
D2 = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_DEL:
|
||||
model->HFET2delGiven = TRUE;
|
||||
DEL = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_DELTA:
|
||||
model->HFET2deltaGiven = TRUE;
|
||||
DELTA = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_DELTAD:
|
||||
model->HFET2deltadGiven = TRUE;
|
||||
DELTAD = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_DI:
|
||||
model->HFET2diGiven = TRUE;
|
||||
DI = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_EPSI:
|
||||
model->HFET2epsiGiven = TRUE;
|
||||
EPSI = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_ETA:
|
||||
model->HFET2etaGiven = TRUE;
|
||||
ETA = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_ETA1:
|
||||
model->HFET2eta1Given = TRUE;
|
||||
ETA1 = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_ETA2:
|
||||
model->HFET2eta2Given = TRUE;
|
||||
ETA2 = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_GAMMA:
|
||||
model->HFET2gammaGiven = TRUE;
|
||||
GAMMA = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_GGR:
|
||||
model->HFET2ggrGiven = TRUE;
|
||||
GGR = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_JS:
|
||||
model->HFET2jsGiven = TRUE;
|
||||
JS = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_KLAMBDA:
|
||||
model->HFET2klambdaGiven = TRUE;
|
||||
KLAMBDA = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_KMU:
|
||||
model->HFET2kmuGiven = TRUE;
|
||||
KMU = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_KNMAX:
|
||||
model->HFET2knmaxGiven = TRUE;
|
||||
KNMAX = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_KVTO:
|
||||
model->HFET2kvtoGiven = TRUE;
|
||||
KVTO = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_LAMBDA:
|
||||
model->HFET2lambdaGiven = TRUE;
|
||||
LAMBDA = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_M:
|
||||
model->HFET2mGiven = TRUE;
|
||||
M = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_MC:
|
||||
model->HFET2mcGiven = TRUE;
|
||||
MC = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_MU:
|
||||
model->HFET2muGiven = TRUE;
|
||||
MU = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_N:
|
||||
model->HFET2nGiven = TRUE;
|
||||
N = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_NMAX:
|
||||
model->HFET2nmaxGiven = TRUE;
|
||||
NMAX = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_P:
|
||||
model->HFET2pGiven = TRUE;
|
||||
PP = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_RD:
|
||||
model->HFET2rdGiven = TRUE;
|
||||
RD = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_RDI:
|
||||
model->HFET2rdiGiven = TRUE;
|
||||
RDI = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_RS:
|
||||
model->HFET2rsGiven = TRUE;
|
||||
RS = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_RSI:
|
||||
model->HFET2rsiGiven = TRUE;
|
||||
RSI = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_SIGMA0:
|
||||
model->HFET2sigma0Given = TRUE;
|
||||
SIGMA0 = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_VS:
|
||||
model->HFET2vsGiven = TRUE;
|
||||
VS = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_VSIGMA:
|
||||
model->HFET2vsigmaGiven = TRUE;
|
||||
VSIGMA = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_VSIGMAT:
|
||||
model->HFET2vsigmatGiven = TRUE;
|
||||
VSIGMAT = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_VT1:
|
||||
model->HFET2vt1Given = TRUE;
|
||||
HFET2_VT1 = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_VT2:
|
||||
model->HFET2vt2Given = TRUE;
|
||||
VT2 = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_VTO:
|
||||
model->HFET2vtoGiven = TRUE;
|
||||
VTO = value->rValue;
|
||||
break;
|
||||
case HFET2_MOD_NHFET:
|
||||
if(value->iValue) {
|
||||
TYPE = NHFET;
|
||||
}
|
||||
break;
|
||||
case HFET2_MOD_PHFET:
|
||||
if(value->iValue) {
|
||||
TYPE = PHFET;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "ifsim.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int HFET2param(param, value, inst, select)
|
||||
int param;
|
||||
IFvalue *value;
|
||||
GENinstance *inst;
|
||||
IFvalue *select;
|
||||
{
|
||||
|
||||
HFET2instance *here = (HFET2instance*)inst;
|
||||
switch(param) {
|
||||
case HFET2_LENGTH:
|
||||
L = value->rValue;
|
||||
here->HFET2lengthGiven = TRUE;
|
||||
break;
|
||||
case HFET2_IC_VDS:
|
||||
here->HFET2icVDS = value->rValue;
|
||||
here->HFET2icVDSGiven = TRUE;
|
||||
break;
|
||||
case HFET2_IC_VGS:
|
||||
here->HFET2icVGS = value->rValue;
|
||||
here->HFET2icVGSGiven = TRUE;
|
||||
break;
|
||||
case HFET2_OFF:
|
||||
here->HFET2off = value->iValue;
|
||||
break;
|
||||
case HFET2_IC:
|
||||
switch(value->v.numValue) {
|
||||
case 2:
|
||||
here->HFET2icVGS = *(value->v.vec.rVec+1);
|
||||
here->HFET2icVGSGiven = TRUE;
|
||||
case 1:
|
||||
here->HFET2icVDS = *(value->v.vec.rVec);
|
||||
here->HFET2icVDSGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
break;
|
||||
case HFET2_TEMP:
|
||||
TEMP = value->rValue+CONSTCtoK;
|
||||
here->HFET2tempGiven = TRUE;
|
||||
break;
|
||||
case HFET2_WIDTH:
|
||||
W = value->rValue;
|
||||
here->HFET2widthGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "smpdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "const.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int HFET2setup(matrix, inModel, ckt, states)
|
||||
SMPmatrix *matrix;
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
int *states;
|
||||
{
|
||||
|
||||
HFET2model *model = (HFET2model*)inModel;
|
||||
HFET2instance *here;
|
||||
int error;
|
||||
CKTnode *tmp;
|
||||
|
||||
for( ; model != NULL; model = model->HFET2nextModel ) {
|
||||
if((TYPE != NHFET) && (TYPE != PHFET) )
|
||||
TYPE = NHFET;
|
||||
if(!model->HFET2cfGiven)
|
||||
CF = 0;
|
||||
if(!model->HFET2d1Given)
|
||||
D1 = 0.03e-6;
|
||||
if(!model->HFET2d2Given)
|
||||
D2 = 0.2e-6;
|
||||
if(!model->HFET2delGiven)
|
||||
DEL = 0.04;
|
||||
if(!model->HFET2deltaGiven)
|
||||
DELTA = 3.0;
|
||||
if(!model->HFET2deltadGiven)
|
||||
DELTAD = 4.5e-9;
|
||||
if(!model->HFET2diGiven)
|
||||
DI = 0.04e-6;
|
||||
if(!model->HFET2epsiGiven)
|
||||
EPSI = 12.244*8.85418e-12;
|
||||
if(!model->HFET2etaGiven)
|
||||
if(TYPE == NHFET)
|
||||
ETA = 1.28;
|
||||
else
|
||||
ETA = 1.4;
|
||||
if(!model->HFET2eta1Given)
|
||||
ETA1 = 2;
|
||||
if(!model->HFET2eta2Given)
|
||||
ETA2 = 2;
|
||||
if(!model->HFET2gammaGiven)
|
||||
GAMMA = 3.0;
|
||||
if(!model->HFET2ggrGiven)
|
||||
GGR = 0;
|
||||
if(!model->HFET2jsGiven)
|
||||
JS = 0;
|
||||
if(!model->HFET2klambdaGiven)
|
||||
KLAMBDA = 0;
|
||||
if(!model->HFET2kmuGiven)
|
||||
KMU = 0;
|
||||
if(!model->HFET2knmaxGiven)
|
||||
KNMAX = 0;
|
||||
if(!model->HFET2kvtoGiven)
|
||||
KVTO = 0;
|
||||
if(!model->HFET2lambdaGiven)
|
||||
LAMBDA = 0.15;
|
||||
if(!model->HFET2mGiven)
|
||||
M = 3.0;
|
||||
if(!model->HFET2mcGiven)
|
||||
MC = 3.0;
|
||||
if(!model->HFET2muGiven)
|
||||
if(TYPE == NHFET)
|
||||
MU = 0.4;
|
||||
else
|
||||
MU = 0.03;
|
||||
if(!model->HFET2nGiven)
|
||||
N = 5.0;
|
||||
if(!model->HFET2nmaxGiven)
|
||||
NMAX = 2e16;
|
||||
if(!model->HFET2pGiven)
|
||||
PP = 1;
|
||||
if(!model->HFET2rdGiven)
|
||||
RD = 0;
|
||||
if(!model->HFET2rdiGiven)
|
||||
RDI = 0;
|
||||
if(!model->HFET2rsGiven)
|
||||
RS = 0;
|
||||
if(!model->HFET2rsiGiven)
|
||||
RSI = 0;
|
||||
if(!model->HFET2sigma0Given)
|
||||
SIGMA0 = 0.057;
|
||||
if(!model->HFET2vsGiven)
|
||||
if(TYPE == NHFET)
|
||||
VS = 1.5e5;
|
||||
else
|
||||
VS = 0.8e5;
|
||||
if(!model->HFET2vsigmaGiven)
|
||||
VSIGMA = 0.1;
|
||||
if(!model->HFET2vsigmatGiven)
|
||||
VSIGMAT = 0.3;
|
||||
if(!model->HFET2vt1Given)
|
||||
// initialized in HFET2temp
|
||||
HFET2_VT1 = 0;
|
||||
if(!model->HFET2vt2Given)
|
||||
// initialized in HFET2temp
|
||||
VT2 = 0;
|
||||
if(!model->HFET2vtoGiven) {
|
||||
if(model->HFET2type == NHFET)
|
||||
VTO = 0.15;
|
||||
else
|
||||
VTO = -0.15;
|
||||
}
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
|
||||
|
||||
for (here = model->HFET2instances; here != NULL; here=here->HFET2nextInstance) {
|
||||
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
here->HFET2state = *states;
|
||||
*states += 13;
|
||||
|
||||
if(!here->HFET2lengthGiven)
|
||||
L = 1e-6;
|
||||
if(!here->HFET2tempGiven)
|
||||
TEMP = ckt->CKTtemp;
|
||||
if(!here->HFET2widthGiven)
|
||||
W = 20e-6;
|
||||
|
||||
if(model->HFET2rs != 0 && here->HFET2sourcePrimeNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->HFET2name,"source");
|
||||
if(error) return(error);
|
||||
here->HFET2sourcePrimeNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->HFET2sourcePrimeNode = here->HFET2sourceNode;
|
||||
}
|
||||
if(model->HFET2rd != 0 && here->HFET2drainPrimeNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->HFET2name,"drain");
|
||||
if(error) return(error);
|
||||
here->HFET2drainPrimeNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->HFET2drainPrimeNode = here->HFET2drainNode;
|
||||
}
|
||||
|
||||
/* macro to make elements with built in test for out of memory */
|
||||
#define TSTALLOC(ptr,first,second) \
|
||||
if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\
|
||||
return(E_NOMEM);\
|
||||
}
|
||||
|
||||
TSTALLOC(HFET2drainDrainPrimePtr,HFET2drainNode,HFET2drainPrimeNode)
|
||||
TSTALLOC(HFET2gateDrainPrimePtr,HFET2gateNode,HFET2drainPrimeNode)
|
||||
TSTALLOC(HFET2gateSourcePrimePtr,HFET2gateNode,HFET2sourcePrimeNode)
|
||||
TSTALLOC(HFET2sourceSourcePrimePtr,HFET2sourceNode,HFET2sourcePrimeNode)
|
||||
TSTALLOC(HFET2drainPrimeDrainPtr,HFET2drainPrimeNode,HFET2drainNode)
|
||||
TSTALLOC(HFET2drainPrimeGatePtr,HFET2drainPrimeNode,HFET2gateNode)
|
||||
TSTALLOC(HFET2drainPriHFET2ourcePrimePtr,HFET2drainPrimeNode,HFET2sourcePrimeNode)
|
||||
TSTALLOC(HFET2sourcePrimeGatePtr,HFET2sourcePrimeNode,HFET2gateNode)
|
||||
TSTALLOC(HFET2sourcePriHFET2ourcePtr,HFET2sourcePrimeNode,HFET2sourceNode)
|
||||
TSTALLOC(HFET2sourcePrimeDrainPrimePtr,HFET2sourcePrimeNode,HFET2drainPrimeNode)
|
||||
TSTALLOC(HFET2drainDrainPtr,HFET2drainNode,HFET2drainNode)
|
||||
TSTALLOC(HFET2gateGatePtr,HFET2gateNode,HFET2gateNode)
|
||||
TSTALLOC(HFET2sourceSourcePtr,HFET2sourceNode,HFET2sourceNode)
|
||||
TSTALLOC(HFET2drainPrimeDrainPrimePtr,HFET2drainPrimeNode,HFET2drainPrimeNode)
|
||||
TSTALLOC(HFET2sourcePriHFET2ourcePrimePtr,HFET2sourcePrimeNode,HFET2sourcePrimeNode)
|
||||
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
HFET2unsetup(inModel,ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
HFET2model *model;
|
||||
HFET2instance *here;
|
||||
|
||||
for (model = (HFET2model *)inModel; model != NULL;
|
||||
model = model->HFET2nextModel)
|
||||
{
|
||||
for (here = model->HFET2instances; here != NULL;
|
||||
here=here->HFET2nextInstance)
|
||||
{
|
||||
if (here->HFET2drainPrimeNode
|
||||
&& here->HFET2drainPrimeNode != here->HFET2drainNode)
|
||||
{
|
||||
CKTdltNNum(ckt, here->HFET2drainPrimeNode);
|
||||
here->HFET2drainPrimeNode = 0;
|
||||
}
|
||||
if (here->HFET2sourcePrimeNode
|
||||
&& here->HFET2sourcePrimeNode != here->HFET2sourceNode)
|
||||
{
|
||||
CKTdltNNum(ckt, here->HFET2sourcePrimeNode);
|
||||
here->HFET2sourcePrimeNode = 0;
|
||||
}
|
||||
/*if (here->HFET2gateNode
|
||||
&& here->HFET2gateNode != here->HFET2gateNode)
|
||||
{
|
||||
CKTdltNNum(ckt, here->HFET2gateNode);
|
||||
here->HFET2gateNode = 0;
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "smpdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "const.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int HFET2temp(inModel, ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
|
||||
HFET2instance *here;
|
||||
HFET2model *model = (HFET2model*)inModel;
|
||||
|
||||
for( ; model != NULL; model = model->HFET2nextModel ) {
|
||||
if(model->HFET2rd != 0)
|
||||
model->HFET2drainConduct = 1/model->HFET2rd;
|
||||
else
|
||||
model->HFET2drainConduct = 0;
|
||||
if(model->HFET2rs != 0)
|
||||
model->HFET2sourceConduct = 1/model->HFET2rs;
|
||||
else
|
||||
model->HFET2sourceConduct = 0;
|
||||
if(!model->HFET2vt1Given)
|
||||
HFET2_VT1 = VTO+CHARGE*NMAX*DI/EPSI;
|
||||
if(!model->HFET2vt2Given)
|
||||
VT2 = VTO;
|
||||
DELTA2 = DELTA*DELTA;
|
||||
for (here = model->HFET2instances; here != NULL; here=here->HFET2nextInstance) {
|
||||
double vt = CONSTKoverQ*TEMP;
|
||||
double tdiff = TEMP - ckt->CKTnomTemp;
|
||||
TLAMBDA = LAMBDA + KLAMBDA*tdiff;
|
||||
TMU = MU - KMU*tdiff;
|
||||
TNMAX = NMAX - KNMAX*tdiff;
|
||||
TVTO = TYPE*VTO - KVTO*tdiff;
|
||||
JSLW = JS*L*W/2;
|
||||
GGRLW = GGR*L*W/2;
|
||||
N0 = EPSI*ETA*vt/2/CHARGE/(DI+DELTAD);
|
||||
N01 = EPSI*ETA1*vt/2/CHARGE/D1;
|
||||
if(model->HFET2eta2Given)
|
||||
N02 = EPSI*ETA2*vt/2/CHARGE/D2;
|
||||
else
|
||||
N02 = 0.0;
|
||||
GCHI0 = CHARGE*W*TMU/L;
|
||||
IMAX = CHARGE*TNMAX*VS*W;
|
||||
VCRIT = vt*log(vt/(CONSTroot2 * 1e-11));
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "hfet2defs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int HFET2trunc(inModel, ckt, tiHFET2tep)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
double *tiHFET2tep;
|
||||
{
|
||||
|
||||
HFET2model *model = (HFET2model*)inModel;
|
||||
HFET2instance *here;
|
||||
|
||||
for( ; model != NULL; model = model->HFET2nextModel) {
|
||||
for(here=model->HFET2instances;here!=NULL;here = here->HFET2nextInstance){
|
||||
CKTterr(here->HFET2qgs,ckt,tiHFET2tep);
|
||||
CKTterr(here->HFET2qgd,ckt,tiHFET2tep);
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
pkglib_LTLIBRARIES = libmesa.la
|
||||
|
||||
libmesa_la_SOURCES = \
|
||||
mesa.c \
|
||||
mesaacl.c \
|
||||
mesaask.c \
|
||||
mesadefs.h \
|
||||
mesadel.c \
|
||||
mesadest.c \
|
||||
mesaext.h \
|
||||
mesagetic.c \
|
||||
mesainit.c \
|
||||
mesainit.h \
|
||||
mesaitf.h \
|
||||
mesaload.c \
|
||||
mesamask.c \
|
||||
mesamdel.c \
|
||||
mesamparam.c \
|
||||
mesaparam.c \
|
||||
mesasetup.c \
|
||||
mesatemp.c \
|
||||
mesatrunc.c
|
||||
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/include
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "ifsim.h"
|
||||
#include "devdefs.h"
|
||||
#include "mesadefs.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
IFparm MESApTable[] = { /* parameters */
|
||||
OP("off", MESA_OFF, IF_FLAG ,"Device initially off"),
|
||||
IOP("l", MESA_LENGTH, IF_REAL ,"Length of device"),
|
||||
IOP("w", MESA_WIDTH, IF_REAL ,"Width of device"),
|
||||
IOP("icvds", MESA_IC_VDS, IF_REAL ,"Initial D-S voltage"),
|
||||
IOP("icvgs", MESA_IC_VGS, IF_REAL ,"Initial G-S voltage"),
|
||||
IOP("td", MESA_TD, IF_REAL ,"Instance drain temperature"),
|
||||
IOP("ts", MESA_TS, IF_REAL ,"Instance source temperature"),
|
||||
OP("dnode", MESA_DRAINNODE, IF_INTEGER,"Number of drain node"),
|
||||
OP("gnode", MESA_GATENODE, IF_INTEGER,"Number of gate node"),
|
||||
OP("snode", MESA_SOURCENODE, IF_INTEGER,"Number of source node"),
|
||||
OP("dprimenode",MESA_DRAINPRIMENODE, IF_INTEGER,"Number of internal drain node"),
|
||||
OP("sprimenode",MESA_SOURCEPRIMENODE,IF_INTEGER,"Number of internal source node"),
|
||||
OP("gprimenode",MESA_GATEPRIMENODE, IF_INTEGER,"Number of internal gate node"),
|
||||
OP("vgs", MESA_VGS, IF_REAL,"Gate-Source voltage"),
|
||||
OP("vgd", MESA_VGD, IF_REAL,"Gate-Drain voltage"),
|
||||
OP("cg", MESA_CG, IF_REAL,"Gate capacitance"),
|
||||
OP("cd", MESA_CD, IF_REAL,"Drain capacitance"),
|
||||
OP("cgd", MESA_CGD, IF_REAL,"Gate_Drain capacitance"),
|
||||
OP("gm", MESA_GM, IF_REAL,"Transconductance"),
|
||||
OP("gds", MESA_GDS, IF_REAL,"Drain-Source conductance"),
|
||||
OP("ggs", MESA_GGS, IF_REAL,"Gate-Source conductance"),
|
||||
OP("ggd", MESA_GGD, IF_REAL,"Gate-Drain conductance"),
|
||||
OP("qgs", MESA_QGS, IF_REAL,"Gate-Source charge storage"),
|
||||
OP("cqgs", MESA_CQGS, IF_REAL,"Capacitance due to gate-source charge storage"),
|
||||
OP("qgd", MESA_QGD, IF_REAL,"Gate-Drain charge storage"),
|
||||
OP("cqgd", MESA_CQGD, IF_REAL,"Capacitance due to gate-drain charge storage"),
|
||||
OP("cs", MESA_CS, IF_REAL,"Source current"),
|
||||
OP("p", MESA_POWER, IF_REAL,"Power dissipated by the mesfet")
|
||||
|
||||
};
|
||||
|
||||
IFparm MESAmPTable[] = { /* model parameters */
|
||||
IOP( "vt0", MESA_MOD_VTO, IF_REAL,"Pinch-off voltage"),
|
||||
IOP( "vto", MESA_MOD_VTO, IF_REAL,"Pinch-off voltage"),
|
||||
IOP( "lambda", MESA_MOD_LAMBDA, IF_REAL,"Output conductance parameter"),
|
||||
IOP( "lambdahf",MESA_MOD_LAMBDAHF, IF_REAL,"Output conductance parameter at high frequencies"),
|
||||
IOP( "beta", MESA_MOD_BETA, IF_REAL,"Transconductance parameter"),
|
||||
IOP( "vs", MESA_MOD_VS, IF_REAL,"Saturation velocity"),
|
||||
IOP( "rd", MESA_MOD_RD, IF_REAL,"Drain ohmic resistance"),
|
||||
IOP( "rs", MESA_MOD_RS, IF_REAL,"Source ohmic resistance"),
|
||||
IOP( "rg", MESA_MOD_RG, IF_REAL,"Gate ohmic resistance"),
|
||||
IOP( "ri", MESA_MOD_RI, IF_REAL,"Gate-source ohmic resistance"),
|
||||
IOP( "rf", MESA_MOD_RF, IF_REAL,"Gate-drain ohmic resistance"),
|
||||
IOP( "rdi", MESA_MOD_RDI, IF_REAL,"Intrinsic source ohmic resistance"),
|
||||
IOP( "rsi", MESA_MOD_RSI, IF_REAL,"Intrinsic drain ohmic resistance"),
|
||||
IOP( "phib", MESA_MOD_PHIB, IF_REAL,"Effective Schottky barrier height at room temperature"),
|
||||
IOP( "phib1", MESA_MOD_PHIB1, IF_REAL,""),
|
||||
IOP( "tphib", MESA_MOD_PHIB1, IF_REAL,""),
|
||||
IOP( "astar", MESA_MOD_ASTAR, IF_REAL,"Effective Richardson constant"),
|
||||
IOP( "ggr", MESA_MOD_GGR, IF_REAL,"Reverse diode conductance"),
|
||||
IOP( "del", MESA_MOD_DEL, IF_REAL,""),
|
||||
IOP( "xchi", MESA_MOD_XCHI, IF_REAL,""),
|
||||
IOP( "tggr", MESA_MOD_XCHI, IF_REAL,""),
|
||||
IOP( "n", MESA_MOD_N, IF_REAL,"Emission coefficient"),
|
||||
IOP( "eta", MESA_MOD_ETA, IF_REAL,"Subthreshold ideality factor"),
|
||||
IOP( "m", MESA_MOD_M, IF_REAL,"Knee shape parameter"),
|
||||
IOP( "mc", MESA_MOD_MC, IF_REAL,"Knee shape parameter"),
|
||||
IOP( "alpha", MESA_MOD_ALPHA, IF_REAL,""),
|
||||
IOP( "sigma0", MESA_MOD_SIGMA0, IF_REAL,"Threshold voltage coefficient"),
|
||||
IOP( "vsigmat",MESA_MOD_VSIGMAT,IF_REAL,""),
|
||||
IOP( "vsigma", MESA_MOD_VSIGMA, IF_REAL,""),
|
||||
IOP( "mu", MESA_MOD_MU, IF_REAL,"Mobility"),
|
||||
IOP( "theta", MESA_MOD_THETA, IF_REAL,""),
|
||||
IOP( "mu1", MESA_MOD_MU1, IF_REAL,"Second moblity parameter"),
|
||||
IOP( "mu2", MESA_MOD_MU2, IF_REAL,"Third moblity parameter"),
|
||||
IOP( "d", MESA_MOD_D, IF_REAL,"Depth of device"),
|
||||
IOP( "nd", MESA_MOD_ND, IF_REAL,"Doping density"),
|
||||
IOP( "du", MESA_MOD_DU, IF_REAL,"Depth of device"),
|
||||
IOP( "ndu", MESA_MOD_NDU, IF_REAL,"Doping density"),
|
||||
IOP( "th", MESA_MOD_TH, IF_REAL,"Thickness of delta doped layer"),
|
||||
IOP( "ndelta", MESA_MOD_NDELTA, IF_REAL,"Delta doped layer doping density"),
|
||||
IOP( "delta", MESA_MOD_DELTA, IF_REAL,""),
|
||||
IOP( "tc", MESA_MOD_TC, IF_REAL,"Transconductance compression factor"),
|
||||
IOP( "tvto", MESA_MOD_TVTO, IF_REAL,"Temperature coefficient for vto"),
|
||||
IOP( "alphat", MESA_MOD_TVTO, IF_REAL,""),
|
||||
IOP( "tlambda",MESA_MOD_TLAMBDA,IF_REAL,"Temperature coefficient for lambda"),
|
||||
IOP( "teta0", MESA_MOD_TETA0, IF_REAL,"First temperature coefficient for eta"),
|
||||
IOP( "teta1", MESA_MOD_TETA1, IF_REAL,"Second temperature coefficient for eta"),
|
||||
IOP( "tmu", MESA_MOD_TMU, IF_REAL,"Temperature coefficient for mobility"),
|
||||
IOP( "xtm0", MESA_MOD_XTM0, IF_REAL,"First exponent for temp dependence of mobility"),
|
||||
IOP( "xtm1", MESA_MOD_XTM1, IF_REAL,"Second exponent for temp dependence of mobility"),
|
||||
IOP( "xtm2", MESA_MOD_XTM2, IF_REAL,"Third exponent for temp dependence of mobility"),
|
||||
IOP( "ks", MESA_MOD_KS, IF_REAL,"Sidegating coefficient"),
|
||||
IOP( "vsg", MESA_MOD_VSG, IF_REAL,"Sidegating voltage"),
|
||||
IOP( "tf", MESA_MOD_TF, IF_REAL,"Characteristic temperature determined by traps"),
|
||||
IOP( "flo", MESA_MOD_FLO, IF_REAL,""),
|
||||
IOP( "delfo", MESA_MOD_DELFO, IF_REAL,""),
|
||||
IOP( "ag", MESA_MOD_AG, IF_REAL,""),
|
||||
IOP( "rtc1", MESA_MOD_TC1, IF_REAL,""),
|
||||
IOP( "rtc2", MESA_MOD_TC2, IF_REAL,""),
|
||||
IOP( "zeta", MESA_MOD_ZETA, IF_REAL,""),
|
||||
IOP( "level", MESA_MOD_LEVEL, IF_REAL,""),
|
||||
IOP( "nmax", MESA_MOD_NMAX, IF_REAL,""),
|
||||
IOP( "gamma", MESA_MOD_GAMMA, IF_REAL,""),
|
||||
IOP( "epsi", MESA_MOD_EPSI, IF_REAL,""),
|
||||
IOP( "cas", MESA_MOD_CAS, IF_REAL,""),
|
||||
IOP( "cbs", MESA_MOD_CBS, IF_REAL,""),
|
||||
OP( "type", MESA_MOD_TYPE, IF_FLAG,"N-type or P-type MESfet model"),
|
||||
IP( "pmf", MESA_MOD_PMF, IF_FLAG,"P type MESfet model"),
|
||||
IP( "nmf", MESA_MOD_NMF, IF_FLAG,"N type MESfet model"),
|
||||
OP( "gd", MESA_MOD_DRAINCONDUCT, IF_REAL,"Drain conductance"),
|
||||
OP( "gs", MESA_MOD_SOURCECONDUCT, IF_REAL,"Source conductance"),
|
||||
OP( "vcrit", MESA_MOD_VCRIT, IF_REAL,"Critical voltage"),
|
||||
};
|
||||
|
||||
char *MESAnames[] = {
|
||||
"Drain",
|
||||
"Gate",
|
||||
"Source"
|
||||
};
|
||||
|
||||
int MESAnSize = NUMELEMS(MESAnames);
|
||||
int MESApTSize = NUMELEMS(MESApTable);
|
||||
int MESAmPTSize = NUMELEMS(MESAmPTable);
|
||||
int MESAiSize = sizeof(MESAinstance);
|
||||
int MESAmSize = sizeof(MESAmodel);
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "mesadefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
MESAacLoad(inModel,ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
MESAmodel *model = (MESAmodel*)inModel;
|
||||
MESAinstance *here;
|
||||
double gm;
|
||||
double gds;
|
||||
double ggspp;
|
||||
double ggdpp;
|
||||
double ggs;
|
||||
double xgs;
|
||||
double ggd;
|
||||
double xgd;
|
||||
double f;
|
||||
double lambda;
|
||||
double vds;
|
||||
double delidgch;
|
||||
double delidvds;
|
||||
|
||||
for( ; model != NULL; model = model->MESAnextModel ) {
|
||||
for( here = model->MESAinstances; here != NULL;
|
||||
here = here->MESAnextInstance) {
|
||||
f = ckt->CKTomega/2/M_PI;
|
||||
if(here->MESAdelf == 0)
|
||||
lambda = here->MESAtLambda;
|
||||
else
|
||||
lambda = here->MESAtLambda+0.5*(here->MESAtLambdahf-here->MESAtLambda)*
|
||||
(1+tanh((f-here->MESAfl)/here->MESAdelf));
|
||||
vds= *(ckt->CKTstate0 + here->MESAvgs) -
|
||||
*(ckt->CKTstate0 + here->MESAvgd);
|
||||
delidgch = here->MESAdelidgch0*(1+lambda*vds);
|
||||
delidvds = here->MESAdelidvds0*(1+2*lambda*vds) -
|
||||
here->MESAdelidvds1;
|
||||
gm = (delidgch*here->MESAgm0+here->MESAgm1)*here->MESAgm2;
|
||||
gds = delidvds+here->MESAgds0;
|
||||
|
||||
ggspp=*(ckt->CKTstate0 + here->MESAggspp);
|
||||
ggdpp=*(ckt->CKTstate0 + here->MESAggdpp);
|
||||
ggs= *(ckt->CKTstate0 + here->MESAggs) ;
|
||||
xgs= *(ckt->CKTstate0 + here->MESAqgs) * ckt->CKTomega ;
|
||||
ggd= *(ckt->CKTstate0 + here->MESAggd) ;
|
||||
xgd= *(ckt->CKTstate0 + here->MESAqgd) * ckt->CKTomega ;
|
||||
|
||||
*(here->MESAdrainDrainPtr) += here->MESAdrainConduct;
|
||||
*(here->MESAsourceSourcePtr) += here->MESAsourceConduct;
|
||||
*(here->MESAgateGatePtr) += here->MESAgateConduct;
|
||||
*(here->MESAsourcePrmPrmSourcePrmPrmPtr) += (here->MESAtGi+ggspp);
|
||||
*(here->MESAdrainPrmPrmDrainPrmPrmPtr) += (here->MESAtGf+ggdpp);
|
||||
*(here->MESAdrainDrainPrimePtr) -= here->MESAdrainConduct;
|
||||
*(here->MESAdrainPrimeDrainPtr) -= here->MESAdrainConduct;
|
||||
*(here->MESAsourceSourcePrimePtr) -= here->MESAsourceConduct;
|
||||
*(here->MESAsourcePrimeSourcePtr) -= here->MESAsourceConduct;
|
||||
*(here->MESAgateGatePrimePtr) -= here->MESAgateConduct;
|
||||
*(here->MESAgatePrimeGatePtr) -= here->MESAgateConduct;
|
||||
*(here->MESAgatePrimeDrainPrimePtr) += (-ggd);
|
||||
*(here->MESAgatePrimeSourcePrimePtr) += (-ggs);
|
||||
*(here->MESAdrainPrimeGatePrimePtr) += (gm-ggd);
|
||||
*(here->MESAdrainPrimeSourcePrimePtr) += (-gds-gm);
|
||||
*(here->MESAsourcePrimeGatePrimePtr) += (-ggs-gm);
|
||||
*(here->MESAsourcePrimeDrainPrimePtr) += (-gds);
|
||||
*(here->MESAgatePrimeGatePrimePtr) += (ggd+ggs+here->MESAgateConduct+ggspp+ggdpp);
|
||||
*(here->MESAdrainPrimeDrainPrimePtr) += (gds+ggd+here->MESAdrainConduct+here->MESAtGf);
|
||||
*(here->MESAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+here->MESAsourceConduct+here->MESAtGi);
|
||||
*(here->MESAsourcePrimeSourcePrmPrmPtr) -= here->MESAtGi;
|
||||
*(here->MESAsourcePrmPrmSourcePrimePtr) -= here->MESAtGi;
|
||||
*(here->MESAgatePrimeSourcePrmPrmPtr) -= ggspp;
|
||||
*(here->MESAsourcePrmPrmGatePrimePtr) -= ggspp;
|
||||
*(here->MESAdrainPrimeDrainPrmPrmPtr) -= here->MESAtGf;
|
||||
*(here->MESAdrainPrmPrmDrainPrimePtr) -= here->MESAtGf;
|
||||
*(here->MESAgatePrimeDrainPrmPrmPtr) -= ggdpp;
|
||||
*(here->MESAdrainPrmPrmGatePrimePtr) -= ggdpp;
|
||||
*(here->MESAsourcePrmPrmSourcePrmPrmPtr+1) += xgs;
|
||||
*(here->MESAdrainPrmPrmDrainPrmPrmPtr+1) += xgd;
|
||||
*(here->MESAgatePrimeGatePrimePtr+1) += xgd+xgs;
|
||||
*(here->MESAgatePrimeDrainPrmPrmPtr+1) -= xgd;
|
||||
*(here->MESAdrainPrmPrmGatePrimePtr+1) -= xgd;
|
||||
*(here->MESAgatePrimeSourcePrmPrmPtr+1) -= xgs;
|
||||
*(here->MESAsourcePrmPrmGatePrimePtr+1) -= xgs;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
**********/
|
||||
/*
|
||||
Imported into MESA model: 2001 Paolo Nenzi
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "devdefs.h"
|
||||
#include "ifsim.h"
|
||||
#include "mesadefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
MESAask(ckt,inst,which,value,select)
|
||||
CKTcircuit *ckt;
|
||||
GENinstance *inst;
|
||||
int which;
|
||||
IFvalue *value;
|
||||
IFvalue *select;
|
||||
{
|
||||
MESAinstance *here = (MESAinstance*)inst;
|
||||
static char *msg = "Current and power not available in ac analysis";
|
||||
switch(which) {
|
||||
case MESA_LENGTH:
|
||||
value->rValue = here->MESAlength;
|
||||
return (OK);
|
||||
case MESA_WIDTH:
|
||||
value->rValue = here->MESAwidth;
|
||||
return (OK);
|
||||
case MESA_IC_VDS:
|
||||
value->rValue = here->MESAicVDS;
|
||||
return (OK);
|
||||
case MESA_IC_VGS:
|
||||
value->rValue = here->MESAicVGS;
|
||||
return (OK);
|
||||
case MESA_OFF:
|
||||
value->iValue = here->MESAoff;
|
||||
return (OK);
|
||||
case MESA_TD:
|
||||
value->rValue = here->MESAtd;
|
||||
return (OK);
|
||||
case MESA_TS:
|
||||
value->rValue = here->MESAts;
|
||||
return (OK);
|
||||
case MESA_DRAINNODE:
|
||||
value->iValue = here->MESAdrainNode;
|
||||
return (OK);
|
||||
case MESA_GATENODE:
|
||||
value->iValue = here->MESAgateNode;
|
||||
return (OK);
|
||||
case MESA_SOURCENODE:
|
||||
value->iValue = here->MESAsourceNode;
|
||||
return (OK);
|
||||
case MESA_DRAINPRIMENODE:
|
||||
value->iValue = here->MESAdrainPrimeNode;
|
||||
return (OK);
|
||||
case MESA_SOURCEPRIMENODE:
|
||||
value->iValue = here->MESAsourcePrimeNode;
|
||||
return (OK);
|
||||
case MESA_GATEPRIMENODE:
|
||||
value->iValue = here->MESAgatePrimeNode;
|
||||
return (OK);
|
||||
case MESA_VGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAvgs);
|
||||
return (OK);
|
||||
case MESA_VGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAvgd);
|
||||
return (OK);
|
||||
case MESA_CG:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAcg);
|
||||
return (OK);
|
||||
case MESA_CD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAcd);
|
||||
return (OK);
|
||||
case MESA_CGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAcgd);
|
||||
return (OK);
|
||||
case MESA_GM:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAgm);
|
||||
return (OK);
|
||||
case MESA_GDS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAgds);
|
||||
return (OK);
|
||||
case MESA_GGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAggs);
|
||||
return (OK);
|
||||
case MESA_GGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAggd);
|
||||
return (OK);
|
||||
case MESA_QGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAqgs);
|
||||
return (OK);
|
||||
case MESA_CQGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAcqgs);
|
||||
return (OK);
|
||||
case MESA_QGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAqgd);
|
||||
return (OK);
|
||||
case MESA_CQGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAcqgd);
|
||||
return (OK);
|
||||
case MESA_CS :
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = MALLOC(strlen(msg)+1);
|
||||
errRtn = "MESAask";
|
||||
strcpy(errMsg,msg);
|
||||
return(E_ASKCURRENT);
|
||||
} else {
|
||||
value->rValue = -*(ckt->CKTstate0 + here->MESAcd);
|
||||
value->rValue -= *(ckt->CKTstate0 + here->MESAcg);
|
||||
}
|
||||
return(OK);
|
||||
case MESA_POWER :
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = MALLOC(strlen(msg)+1);
|
||||
errRtn = "MESAask";
|
||||
strcpy(errMsg,msg);
|
||||
return(E_ASKPOWER);
|
||||
} else {
|
||||
value->rValue = *(ckt->CKTstate0 + here->MESAcd) *
|
||||
*(ckt->CKTrhsOld + here->MESAdrainNode);
|
||||
value->rValue += *(ckt->CKTstate0 + here->MESAcg) *
|
||||
*(ckt->CKTrhsOld + here->MESAgateNode);
|
||||
value->rValue -= (*(ckt->CKTstate0+here->MESAcd) +
|
||||
*(ckt->CKTstate0 + here->MESAcg)) *
|
||||
*(ckt->CKTrhsOld + here->MESAsourceNode);
|
||||
}
|
||||
return(OK);
|
||||
default:
|
||||
return (E_BADPARM);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
@ -0,0 +1,467 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#ifndef MESA
|
||||
#define MESA
|
||||
|
||||
#include "ifsim.h"
|
||||
#include "cktdefs.h"
|
||||
#include "gendefs.h"
|
||||
#include "complex.h"
|
||||
#include "noisedef.h"
|
||||
|
||||
/* structures used to describe MESFET Transistors */
|
||||
|
||||
|
||||
/* information used to describe a single instance */
|
||||
|
||||
typedef struct sMESAinstance {
|
||||
struct sMESAmodel *MESAmodPtr; /* backpointer to model */
|
||||
struct sMESAinstance *MESAnextInstance; /* pointer to next instance of
|
||||
* current model*/
|
||||
IFuid MESAname; /* pointer to character string naming this instance */
|
||||
int MESAowner; /* number of owner process */
|
||||
int MESAstate; /* pointer to start of state vector for MESAfet */
|
||||
|
||||
int MESAdrainNode; /* number of drain node of MESAfet */
|
||||
int MESAgateNode; /* number of gate node of MESAfet */
|
||||
int MESAsourceNode; /* number of source node of MESAfet */
|
||||
int MESAdrainPrimeNode; /* number of internal drain node of MESAfet */
|
||||
int MESAgatePrimeNode; /* number of internal gate node of MESAfet */
|
||||
int MESAsourcePrimeNode; /* number of internal source node of MESAfet */
|
||||
int MESAsourcePrmPrmNode;
|
||||
int MESAdrainPrmPrmNode;
|
||||
double MESAlength; /* length of MESAfet */
|
||||
double MESAwidth; /* width of MESAfet */
|
||||
double MESAicVDS; /* initial condition voltage D-S*/
|
||||
double MESAicVGS; /* initial condition voltage G-S*/
|
||||
double MESAtd; /* drain temperature */
|
||||
double MESAts; /* source temperature */
|
||||
double MESAtVto;
|
||||
double MESAtLambda;
|
||||
double MESAtLambdahf;
|
||||
double MESAtEta;
|
||||
double MESAtMu;
|
||||
double MESAtPhib;
|
||||
double MESAtTheta;
|
||||
double MESAtRsi;
|
||||
double MESAtRdi;
|
||||
double MESAtRs;
|
||||
double MESAtRd;
|
||||
double MESAtRg;
|
||||
double MESAtRi;
|
||||
double MESAtRf;
|
||||
double MESAtGi;
|
||||
double MESAtGf;
|
||||
double MESAdrainConduct;
|
||||
double MESAsourceConduct;
|
||||
double MESAgateConduct;
|
||||
double *MESAdrainDrainPrimePtr;
|
||||
double *MESAgatePrimeDrainPrimePtr;
|
||||
double *MESAgatePrimeSourcePrimePtr;
|
||||
double *MESAsourceSourcePrimePtr;
|
||||
double *MESAdrainPrimeDrainPtr;
|
||||
double *MESAdrainPrimeGatePrimePtr;
|
||||
double *MESAdrainPrimeSourcePrimePtr;
|
||||
double *MESAsourcePrimeGatePrimePtr;
|
||||
double *MESAsourcePrimeSourcePtr;
|
||||
double *MESAsourcePrimeDrainPrimePtr;
|
||||
double *MESAdrainDrainPtr;
|
||||
double *MESAgatePrimeGatePrimePtr;
|
||||
double *MESAsourceSourcePtr;
|
||||
double *MESAdrainPrimeDrainPrimePtr;
|
||||
double *MESAsourcePrimeSourcePrimePtr;
|
||||
double *MESAgateGatePrimePtr;
|
||||
double *MESAgatePrimeGatePtr;
|
||||
double *MESAgateGatePtr;
|
||||
double *MESAsourcePrmPrmSourcePrmPrmPtr;
|
||||
double *MESAsourcePrmPrmSourcePrimePtr;
|
||||
double *MESAsourcePrimeSourcePrmPrmPtr;
|
||||
double *MESAsourcePrmPrmGatePrimePtr;
|
||||
double *MESAgatePrimeSourcePrmPrmPtr;
|
||||
double *MESAdrainPrmPrmDrainPrmPrmPtr;
|
||||
double *MESAdrainPrmPrmDrainPrimePtr;
|
||||
double *MESAdrainPrimeDrainPrmPrmPtr;
|
||||
double *MESAdrainPrmPrmGatePrimePtr;
|
||||
double *MESAgatePrimeDrainPrmPrmPtr;
|
||||
|
||||
#define MESAvgs MESAstate
|
||||
#define MESAvgd MESAstate+1
|
||||
#define MESAcg MESAstate+2
|
||||
#define MESAcd MESAstate+3
|
||||
#define MESAcgd MESAstate+4
|
||||
#define MESAcgs MESAstate+5
|
||||
#define MESAgm MESAstate+6
|
||||
#define MESAgds MESAstate+7
|
||||
#define MESAggs MESAstate+8
|
||||
#define MESAggd MESAstate+9
|
||||
#define MESAqgs MESAstate+10
|
||||
#define MESAcqgs MESAstate+11
|
||||
#define MESAqgd MESAstate+12
|
||||
#define MESAcqgd MESAstate+13
|
||||
#define MESAvgspp MESAstate+14
|
||||
#define MESAggspp MESAstate+15
|
||||
#define MESAcgspp MESAstate+16
|
||||
#define MESAvgdpp MESAstate+17
|
||||
#define MESAggdpp MESAstate+18
|
||||
#define MESAcgdpp MESAstate+19
|
||||
|
||||
int MESAoff;
|
||||
unsigned MESAlengthGiven : 1;
|
||||
unsigned MESAwidthGiven : 1;
|
||||
unsigned MESAicVDSGiven : 1;
|
||||
unsigned MESAicVGSGiven : 1;
|
||||
unsigned MESAtdGiven : 1;
|
||||
unsigned MESAtsGiven : 1;
|
||||
|
||||
int MESAmode;
|
||||
|
||||
/*
|
||||
* naming convention:
|
||||
* x = vgs
|
||||
* y = vgd
|
||||
* z = vds
|
||||
* cdr = cdrain
|
||||
*/
|
||||
|
||||
#define MESANDCOEFFS 27
|
||||
|
||||
#ifndef NODISTO
|
||||
double MESAdCoeffs[MESANDCOEFFS];
|
||||
#else /* NODISTO */
|
||||
double *MESAdCoeffs;
|
||||
#endif /* NODISTO */
|
||||
|
||||
#ifndef CONFIG
|
||||
|
||||
#define cdr_x MESAdCoeffs[0]
|
||||
#define cdr_z MESAdCoeffs[1]
|
||||
#define cdr_x2 MESAdCoeffs[2]
|
||||
#define cdr_z2 MESAdCoeffs[3]
|
||||
#define cdr_xz MESAdCoeffs[4]
|
||||
#define cdr_x3 MESAdCoeffs[5]
|
||||
#define cdr_z3 MESAdCoeffs[6]
|
||||
#define cdr_x2z MESAdCoeffs[7]
|
||||
#define cdr_xz2 MESAdCoeffs[8]
|
||||
|
||||
#define ggs3 MESAdCoeffs[9]
|
||||
#define ggd3 MESAdCoeffs[10]
|
||||
#define ggs2 MESAdCoeffs[11]
|
||||
#define ggd2 MESAdCoeffs[12]
|
||||
|
||||
#define qgs_x2 MESAdCoeffs[13]
|
||||
#define qgs_y2 MESAdCoeffs[14]
|
||||
#define qgs_xy MESAdCoeffs[15]
|
||||
#define qgs_x3 MESAdCoeffs[16]
|
||||
#define qgs_y3 MESAdCoeffs[17]
|
||||
#define qgs_x2y MESAdCoeffs[18]
|
||||
#define qgs_xy2 MESAdCoeffs[19]
|
||||
|
||||
#define qgd_x2 MESAdCoeffs[20]
|
||||
#define qgd_y2 MESAdCoeffs[21]
|
||||
#define qgd_xy MESAdCoeffs[22]
|
||||
#define qgd_x3 MESAdCoeffs[23]
|
||||
#define qgd_y3 MESAdCoeffs[24]
|
||||
#define qgd_x2y MESAdCoeffs[25]
|
||||
#define qgd_xy2 MESAdCoeffs[26]
|
||||
|
||||
#endif
|
||||
|
||||
/* indices to the array of MESAFET noise sources */
|
||||
|
||||
#define MESARDNOIZ 0
|
||||
#define MESARSNOIZ 1
|
||||
#define MESAIDNOIZ 2
|
||||
#define MESAFLNOIZ 3
|
||||
#define MESATOTNOIZ 4
|
||||
|
||||
#define MESANSRCS 5 /* the number of MESAFET noise sources */
|
||||
|
||||
#ifndef NONOISE
|
||||
double MESAnVar[NSTATVARS][MESANSRCS];
|
||||
#else /* NONOISE */
|
||||
double **MESAnVar;
|
||||
#endif /* NONOISE */
|
||||
double MESAcsatfs;
|
||||
double MESAcsatfd;
|
||||
double MESAggrwl;
|
||||
double MESAgchi0;
|
||||
double MESAbeta;
|
||||
double MESAisatb0;
|
||||
double MESAimax;
|
||||
double MESAcf;
|
||||
double MESAfl;
|
||||
double MESAdelf;
|
||||
double MESAgds0;
|
||||
double MESAgm0;
|
||||
double MESAgm1;
|
||||
double MESAgm2;
|
||||
double MESAdelidvds0;
|
||||
double MESAdelidvds1;
|
||||
double MESAdelidgch0;
|
||||
double MESAn0;
|
||||
double MESAnsb0;
|
||||
double MESAvcrits;
|
||||
double MESAvcritd;
|
||||
} MESAinstance ;
|
||||
|
||||
|
||||
/* per model data */
|
||||
|
||||
typedef struct sMESAmodel { /* model structure for a MESAfet */
|
||||
int MESAmodType; /* type index of this device type */
|
||||
struct sMESAmodel *MESAnextModel; /* pointer to next possible model in
|
||||
* linked list */
|
||||
MESAinstance * MESAinstances; /* pointer to list of instances
|
||||
* that have this model */
|
||||
IFuid MESAmodName; /* pointer to character string naming this model */
|
||||
int MESAtype;
|
||||
|
||||
double MESAthreshold;
|
||||
double MESAlambda;
|
||||
double MESAbeta;
|
||||
double MESAvs;
|
||||
double MESAeta;
|
||||
double MESAm;
|
||||
double MESAmc;
|
||||
double MESAalpha;
|
||||
double MESAsigma0;
|
||||
double MESAvsigmat;
|
||||
double MESAvsigma;
|
||||
double MESAmu;
|
||||
double MESAtheta;
|
||||
double MESAmu1;
|
||||
double MESAmu2;
|
||||
double MESAd;
|
||||
double MESAnd;
|
||||
double MESAdu;
|
||||
double MESAndu;
|
||||
double MESAth;
|
||||
double MESAndelta;
|
||||
double MESAdelta;
|
||||
double MESAtc;
|
||||
double MESArdi;
|
||||
double MESArsi;
|
||||
double MESAdrainResist;
|
||||
double MESAsourceResist;
|
||||
double MESAgateResist;
|
||||
double MESAri;
|
||||
double MESArf;
|
||||
double MESAphib;
|
||||
double MESAphib1;
|
||||
double MESAastar;
|
||||
double MESAggr;
|
||||
double MESAdel;
|
||||
double MESAxchi;
|
||||
double MESAn;
|
||||
double MESAtvto;
|
||||
double MESAtlambda;
|
||||
double MESAteta0;
|
||||
double MESAteta1;
|
||||
double MESAtmu;
|
||||
double MESAxtm0;
|
||||
double MESAxtm1;
|
||||
double MESAxtm2;
|
||||
double MESAks;
|
||||
double MESAvsg;
|
||||
double MESAlambdahf;
|
||||
double MESAtf;
|
||||
double MESAflo;
|
||||
double MESAdelfo;
|
||||
double MESAag;
|
||||
double MESAtc1;
|
||||
double MESAtc2;
|
||||
double MESAzeta;
|
||||
double MESAlevel;
|
||||
double MESAnmax;
|
||||
double MESAgamma;
|
||||
double MESAepsi;
|
||||
double MESAcbs;
|
||||
double MESAcas;
|
||||
|
||||
double MESAsigma;
|
||||
double MESAvpo;
|
||||
double MESAvpou;
|
||||
double MESAvpod;
|
||||
double MESAdeltaSqr;
|
||||
|
||||
unsigned MESAthresholdGiven:1;
|
||||
unsigned MESAlambdaGiven:1;
|
||||
unsigned MESAbetaGiven:1;
|
||||
unsigned MESAvsGiven:1;
|
||||
unsigned MESAetaGiven:1;
|
||||
unsigned MESAmGiven:1;
|
||||
unsigned MESAmcGiven:1;
|
||||
unsigned MESAalphaGiven:1;
|
||||
unsigned MESAsigma0Given:1;
|
||||
unsigned MESAvsigmatGiven:1;
|
||||
unsigned MESAvsigmaGiven:1;
|
||||
unsigned MESAmuGiven:1;
|
||||
unsigned MESAthetaGiven:1;
|
||||
unsigned MESAmu1Given:1;
|
||||
unsigned MESAmu2Given:1;
|
||||
unsigned MESAdGiven:1;
|
||||
unsigned MESAndGiven:1;
|
||||
unsigned MESAduGiven:1;
|
||||
unsigned MESAnduGiven:1;
|
||||
unsigned MESAthGiven:1;
|
||||
unsigned MESAndeltaGiven:1;
|
||||
unsigned MESAdeltaGiven:1;
|
||||
unsigned MESAtcGiven:1;
|
||||
unsigned MESArdiGiven:1;
|
||||
unsigned MESArsiGiven:1;
|
||||
unsigned MESAdrainResistGiven:1;
|
||||
unsigned MESAsourceResistGiven:1;
|
||||
unsigned MESAgateResistGiven:1;
|
||||
unsigned MESAriGiven:1;
|
||||
unsigned MESArfGiven:1;
|
||||
unsigned MESAphibGiven:1;
|
||||
unsigned MESAphib1Given:1;
|
||||
unsigned MESAastarGiven:1;
|
||||
unsigned MESAggrGiven:1;
|
||||
unsigned MESAdelGiven:1;
|
||||
unsigned MESAxchiGiven:1;
|
||||
unsigned MESAnGiven:1;
|
||||
unsigned MESAtvtoGiven:1;
|
||||
unsigned MESAtlambdaGiven:1;
|
||||
unsigned MESAteta0Given:1;
|
||||
unsigned MESAteta1Given:1;
|
||||
unsigned MESAtmuGiven:1;
|
||||
unsigned MESAxtm0Given:1;
|
||||
unsigned MESAxtm1Given:1;
|
||||
unsigned MESAxtm2Given:1;
|
||||
unsigned MESAksGiven:1;
|
||||
unsigned MESAvsgGiven:1;
|
||||
unsigned MESAlambdahfGiven:1;
|
||||
unsigned MESAtfGiven:1;
|
||||
unsigned MESAfloGiven:1;
|
||||
unsigned MESAdelfoGiven:1;
|
||||
unsigned MESAagGiven:1;
|
||||
unsigned MESAtc1Given:1;
|
||||
unsigned MESAtc2Given:1;
|
||||
unsigned MESAzetaGiven:1;
|
||||
unsigned MESAlevelGiven:1;
|
||||
unsigned MESAnmaxGiven:1;
|
||||
unsigned MESAgammaGiven:1;
|
||||
unsigned MESAepsiGiven:1;
|
||||
unsigned MESAcbsGiven:1;
|
||||
unsigned MESAcasGiven:1;
|
||||
|
||||
} MESAmodel;
|
||||
|
||||
#ifndef NMF
|
||||
|
||||
#define NMF 1
|
||||
#define PMF -1
|
||||
#endif
|
||||
|
||||
/* device parameters */
|
||||
#define MESA_LENGTH 1
|
||||
#define MESA_WIDTH 2
|
||||
#define MESA_IC_VDS 3
|
||||
#define MESA_IC_VGS 4
|
||||
#define MESA_TD 5
|
||||
#define MESA_TS 6
|
||||
#define MESA_IC 7
|
||||
#define MESA_OFF 8
|
||||
#define MESA_CS 9
|
||||
#define MESA_POWER 10
|
||||
|
||||
/* model parameters */
|
||||
#define MESA_MOD_VTO 101
|
||||
#define MESA_MOD_VS 102
|
||||
#define MESA_MOD_LAMBDA 103
|
||||
#define MESA_MOD_RD 104
|
||||
#define MESA_MOD_RS 105
|
||||
#define MESA_MOD_RG 106
|
||||
#define MESA_MOD_RI 107
|
||||
#define MESA_MOD_RF 108
|
||||
#define MESA_MOD_RDI 109
|
||||
#define MESA_MOD_RSI 110
|
||||
#define MESA_MOD_PHIB 111
|
||||
#define MESA_MOD_PHIB1 112
|
||||
#define MESA_MOD_ASTAR 113
|
||||
#define MESA_MOD_GGR 114
|
||||
#define MESA_MOD_DEL 115
|
||||
#define MESA_MOD_XCHI 116
|
||||
#define MESA_MOD_N 117
|
||||
#define MESA_MOD_ETA 118
|
||||
#define MESA_MOD_M 119
|
||||
#define MESA_MOD_MC 120
|
||||
#define MESA_MOD_SIGMA0 121
|
||||
#define MESA_MOD_VSIGMAT 122
|
||||
#define MESA_MOD_VSIGMA 123
|
||||
#define MESA_MOD_MU 124
|
||||
#define MESA_MOD_MU1 125
|
||||
#define MESA_MOD_MU2 126
|
||||
#define MESA_MOD_D 127
|
||||
#define MESA_MOD_ND 128
|
||||
#define MESA_MOD_DELTA 129
|
||||
#define MESA_MOD_TC 130
|
||||
#define MESA_MOD_NMF 131
|
||||
#define MESA_MOD_TVTO 132
|
||||
#define MESA_MOD_TLAMBDA 134
|
||||
#define MESA_MOD_TETA0 135
|
||||
#define MESA_MOD_TETA1 136
|
||||
#define MESA_MOD_TMU 137
|
||||
#define MESA_MOD_XTM0 138
|
||||
#define MESA_MOD_XTM1 139
|
||||
#define MESA_MOD_XTM2 140
|
||||
#define MESA_MOD_KS 141
|
||||
#define MESA_MOD_VSG 142
|
||||
#define MESA_MOD_LAMBDAHF 143
|
||||
#define MESA_MOD_TF 144
|
||||
#define MESA_MOD_FLO 145
|
||||
#define MESA_MOD_DELFO 146
|
||||
#define MESA_MOD_AG 147
|
||||
#define MESA_MOD_THETA 148
|
||||
#define MESA_MOD_ALPHA 149
|
||||
#define MESA_MOD_TC1 150
|
||||
#define MESA_MOD_TC2 151
|
||||
#define MESA_MOD_ZETA 152
|
||||
#define MESA_MOD_BETA 153
|
||||
#define MESA_MOD_DU 154
|
||||
#define MESA_MOD_NDU 155
|
||||
#define MESA_MOD_TH 156
|
||||
#define MESA_MOD_NDELTA 157
|
||||
#define MESA_MOD_LEVEL 158
|
||||
#define MESA_MOD_NMAX 159
|
||||
#define MESA_MOD_GAMMA 160
|
||||
#define MESA_MOD_EPSI 161
|
||||
#define MESA_MOD_CBS 162
|
||||
#define MESA_MOD_CAS 163
|
||||
#define MESA_MOD_PMF 164
|
||||
#define MESA_MOD_TYPE 165
|
||||
|
||||
#define MESA_DRAINNODE 201
|
||||
#define MESA_GATENODE 202
|
||||
#define MESA_SOURCENODE 203
|
||||
#define MESA_DRAINPRIMENODE 204
|
||||
#define MESA_SOURCEPRIMENODE 205
|
||||
#define MESA_GATEPRIMENODE 206
|
||||
|
||||
#define MESA_VGS 207
|
||||
#define MESA_VGD 208
|
||||
#define MESA_CG 209
|
||||
#define MESA_CD 210
|
||||
#define MESA_CGD 211
|
||||
#define MESA_GM 212
|
||||
#define MESA_GDS 213
|
||||
#define MESA_GGS 214
|
||||
#define MESA_GGD 215
|
||||
#define MESA_QGS 216
|
||||
#define MESA_CQGS 217
|
||||
#define MESA_QGD 218
|
||||
#define MESA_CQGD 219
|
||||
|
||||
#define MESA_MOD_DRAINCONDUCT 301
|
||||
#define MESA_MOD_SOURCECONDUCT 302
|
||||
#define MESA_MOD_GATECONDUCT 303
|
||||
#define MESA_MOD_DEPLETIONCAP 304
|
||||
#define MESA_MOD_VCRIT 305
|
||||
|
||||
#include "mesaext.h"
|
||||
|
||||
#endif /*MESA*/
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 S. Hwang
|
||||
**********/
|
||||
/*
|
||||
Imported into mesa model: 2001 Paolo Nenzi
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "mesadefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
MESAdelete(inModel,name,inst)
|
||||
GENmodel *inModel;
|
||||
IFuid name;
|
||||
GENinstance **inst;
|
||||
{
|
||||
MESAmodel *model = (MESAmodel*)inModel;
|
||||
MESAinstance **fast = (MESAinstance**)inst;
|
||||
MESAinstance **prev = NULL;
|
||||
MESAinstance *here;
|
||||
|
||||
for( ; model ; model = model->MESAnextModel) {
|
||||
prev = &(model->MESAinstances);
|
||||
for(here = *prev; here ; here = *prev) {
|
||||
if(here->MESAname == name || (fast && here==*fast) ) {
|
||||
*prev= here->MESAnextInstance;
|
||||
FREE(here);
|
||||
return(OK);
|
||||
}
|
||||
prev = &(here->MESAnextInstance);
|
||||
}
|
||||
}
|
||||
return(E_NODEV);
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "mesadefs.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
void
|
||||
MESAdestroy(inModel)
|
||||
GENmodel **inModel;
|
||||
{
|
||||
MESAmodel **model = (MESAmodel**)inModel;
|
||||
MESAinstance *here;
|
||||
MESAinstance *prev = NULL;
|
||||
MESAmodel *mod = *model;
|
||||
MESAmodel *oldmod = NULL;
|
||||
|
||||
for( ; mod ; mod = mod->MESAnextModel) {
|
||||
if(oldmod) FREE(oldmod);
|
||||
oldmod = mod;
|
||||
prev = (MESAinstance *)NULL;
|
||||
for(here = mod->MESAinstances ; here ; here = here->MESAnextInstance) {
|
||||
if(prev) FREE(prev);
|
||||
prev = here;
|
||||
}
|
||||
if(prev) FREE(prev);
|
||||
}
|
||||
if(oldmod) FREE(oldmod);
|
||||
*model = NULL;
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
extern int MESAacLoad(GENmodel*,CKTcircuit*);
|
||||
extern int MESAask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
||||
extern int MESAdelete(GENmodel*,IFuid,GENinstance**);
|
||||
extern void MESAdestroy(GENmodel**);
|
||||
extern int MESAgetic(GENmodel*,CKTcircuit*);
|
||||
extern int MESAload(GENmodel*,CKTcircuit*);
|
||||
extern int MESAmAsk(CKTcircuit*,GENmodel*,int,IFvalue*);
|
||||
extern int MESAmDelete(GENmodel**,IFuid,GENmodel*);
|
||||
extern int MESAmParam(int,IFvalue*,GENmodel*);
|
||||
extern int MESAparam(int,IFvalue*,GENinstance*,IFvalue*);
|
||||
extern int MESAsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||
extern int MESAtemp(GENmodel*,CKTcircuit*);
|
||||
extern int MESAtrunc(GENmodel*,CKTcircuit*,double*);
|
||||
extern int MESAunsetup(GENmodel*,CKTcircuit*);
|
||||
|
||||
#else /*stdc*/
|
||||
extern int MESAacLoad();
|
||||
extern int MESAask();
|
||||
extern int MESAdelete();
|
||||
extern void MESAdestroy();
|
||||
extern int MESAgetic();
|
||||
extern int MESAload();
|
||||
extern int MESAmAsk();
|
||||
extern int MESAmDelete();
|
||||
extern int MESAmParam();
|
||||
extern int MESAparam();
|
||||
extern int MESAsetup();
|
||||
extern int MESAtemp();
|
||||
extern int MESAtrunc();
|
||||
extern int MESAunsetup();
|
||||
#endif
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "mesadefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
MESAgetic(inModel,ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
MESAmodel *model = (MESAmodel*)inModel;
|
||||
MESAinstance *here;
|
||||
/*
|
||||
* grab initial conditions out of rhs array. User specified, so use
|
||||
* external nodes to get values
|
||||
*/
|
||||
|
||||
for( ; model ; model = model->MESAnextModel) {
|
||||
for(here = model->MESAinstances; here ; here = here->MESAnextInstance) {
|
||||
if(!here->MESAicVDSGiven) {
|
||||
here->MESAicVDS =
|
||||
*(ckt->CKTrhs + here->MESAdrainNode) -
|
||||
*(ckt->CKTrhs + here->MESAsourceNode);
|
||||
}
|
||||
if(!here->MESAicVGSGiven) {
|
||||
here->MESAicVGS =
|
||||
*(ckt->CKTrhs + here->MESAgateNode) -
|
||||
*(ckt->CKTrhs + here->MESAsourceNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#include <config.h>
|
||||
|
||||
#include <devdefs.h>
|
||||
|
||||
#include "mesaitf.h"
|
||||
#include "mesaext.h"
|
||||
#include "mesainit.h"
|
||||
|
||||
|
||||
SPICEdev MESAinfo = {
|
||||
{
|
||||
"MESA",
|
||||
"GaAs MESFET model",
|
||||
|
||||
&MESAnSize,
|
||||
&MESAnSize,
|
||||
MESAnames,
|
||||
|
||||
&MESApTSize,
|
||||
MESApTable,
|
||||
|
||||
&MESAmPTSize,
|
||||
MESAmPTable,
|
||||
DEV_DEFAULT
|
||||
},
|
||||
|
||||
DEVparam : MESAparam,
|
||||
DEVmodParam : MESAmParam,
|
||||
DEVload : MESAload,
|
||||
DEVsetup : MESAsetup,
|
||||
DEVunsetup : MESAunsetup,
|
||||
DEVpzSetup : MESAsetup,
|
||||
DEVtemperature: MESAtemp,
|
||||
DEVtrunc : MESAtrunc,
|
||||
DEVfindBranch : NULL,
|
||||
DEVacLoad : MESAacLoad,
|
||||
DEVaccept : NULL,
|
||||
DEVdestroy : MESAdestroy,
|
||||
DEVmodDelete : MESAmDelete,
|
||||
DEVdelete : MESAdelete,
|
||||
DEVsetic : MESAgetic,
|
||||
DEVask : MESAask,
|
||||
DEVmodAsk : MESAmAsk,
|
||||
DEVpzLoad : NULL,
|
||||
DEVconvTest : NULL,
|
||||
DEVsenSetup : NULL,
|
||||
DEVsenLoad : NULL,
|
||||
DEVsenUpdate : NULL,
|
||||
DEVsenAcLoad : NULL,
|
||||
DEVsenPrint : NULL,
|
||||
DEVsenTrunc : NULL,
|
||||
DEVdisto : NULL,
|
||||
DEVnoise : NULL,
|
||||
|
||||
DEVinstSize : &MESAiSize,
|
||||
DEVmodSize : &MESAmSize
|
||||
|
||||
};
|
||||
|
||||
|
||||
SPICEdev *
|
||||
get_mesa_info(void)
|
||||
{
|
||||
return &MESAinfo;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef _MESAINIT_H
|
||||
#define _MESAINIT_H
|
||||
|
||||
extern IFparm MESApTable[ ];
|
||||
extern IFparm MESAmPTable[ ];
|
||||
extern char *MESAnames[ ];
|
||||
extern int MESApTSize;
|
||||
extern int MESAmPTSize;
|
||||
extern int MESAnSize;
|
||||
extern int MESAiSize;
|
||||
extern int MESAmSize;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
**********/
|
||||
#ifndef DEV_MESA
|
||||
#define DEV_MESA
|
||||
|
||||
SPICEdev *get_mesa_info(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,987 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "devdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "mesadefs.h"
|
||||
#include "const.h"
|
||||
#include "trandefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
/*
|
||||
#define true 1
|
||||
#define false 0
|
||||
*/
|
||||
|
||||
#define EPSILONGAAS (12.244*8.85418e-12)
|
||||
|
||||
#define W (here->MESAwidth)
|
||||
#define L (here->MESAlength)
|
||||
|
||||
static void mesa1(MESAmodel*, MESAinstance*, double, double, double,
|
||||
double*, double*, double*, double*,double*);
|
||||
|
||||
static void mesa2(MESAmodel*, MESAinstance*, double, double, double,
|
||||
double*, double*, double*, double*,double*);
|
||||
|
||||
static void mesa3(MESAmodel*, MESAinstance*, double, double, double,
|
||||
double*, double*, double*, double*,double*);
|
||||
|
||||
void Pause(void);
|
||||
|
||||
int
|
||||
MESAload(inModel,ckt)
|
||||
GENmodel *inModel;
|
||||
//register CKTcircuit *ckt;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
MESAmodel *model = (MESAmodel*)inModel;
|
||||
MESAinstance *here;
|
||||
double capgd;
|
||||
double capgs;
|
||||
double cd;
|
||||
double cdhat;
|
||||
double cdrain;
|
||||
double cdreq;
|
||||
double ceq;
|
||||
double ceqgd;
|
||||
double ceqgs;
|
||||
double cg;
|
||||
double cgd;
|
||||
double cgs;
|
||||
double cghat;
|
||||
double arg;
|
||||
double earg;
|
||||
double delvds;
|
||||
double delvgd;
|
||||
double delvgs;
|
||||
double delvgspp=0;
|
||||
double delvgdpp=0;
|
||||
double evgd;
|
||||
double evgs;
|
||||
double gds;
|
||||
double geq;
|
||||
double ggd;
|
||||
double ggs;
|
||||
double gm;
|
||||
double ggspp=0;
|
||||
double cgspp=0;
|
||||
double ggdpp=0;
|
||||
double cgdpp=0;
|
||||
double vcrits;
|
||||
double vcritd;
|
||||
double vds=0;
|
||||
double vgd=0;
|
||||
double vgs=0;
|
||||
double vgspp=0;
|
||||
double vgdpp=0;
|
||||
double vgs1=0;
|
||||
double vgd1=0;
|
||||
double xfact;
|
||||
double temp;
|
||||
double vted;
|
||||
double vtes;
|
||||
double vtd;
|
||||
double vts;
|
||||
double von;
|
||||
double ccorr;
|
||||
int inverse=FALSE;
|
||||
int icheck;
|
||||
int ichk1;
|
||||
int error;
|
||||
|
||||
/* loop through all the models */
|
||||
for( ; model != NULL; model = model->MESAnextModel ) {
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = model->MESAinstances; here != NULL ;
|
||||
here=here->MESAnextInstance) {
|
||||
|
||||
/*
|
||||
* dc model parameters
|
||||
*/
|
||||
vcrits = here->MESAvcrits;
|
||||
vcritd = here->MESAvcritd;
|
||||
vtd = CONSTKoverQ * here->MESAtd;
|
||||
vts = CONSTKoverQ * here->MESAts;
|
||||
vted = model->MESAn*vtd;
|
||||
vtes = model->MESAn*vts;
|
||||
/*
|
||||
* initialization
|
||||
*/
|
||||
icheck = 1;
|
||||
if( ckt->CKTmode & MODEINITSMSIG) {
|
||||
vgs = *(ckt->CKTstate0 + here->MESAvgs);
|
||||
vgd = *(ckt->CKTstate0 + here->MESAvgd);
|
||||
vgspp = *(ckt->CKTstate0 + here->MESAvgspp);
|
||||
vgdpp = *(ckt->CKTstate0 + here->MESAvgdpp);
|
||||
} else if (ckt->CKTmode & MODEINITTRAN) {
|
||||
vgs = *(ckt->CKTstate1 + here->MESAvgs);
|
||||
vgd = *(ckt->CKTstate1 + here->MESAvgd);
|
||||
vgspp = *(ckt->CKTstate1 + here->MESAvgspp);
|
||||
vgdpp = *(ckt->CKTstate1 + here->MESAvgdpp);
|
||||
} else if ( (ckt->CKTmode & MODEINITJCT) &&
|
||||
(ckt->CKTmode & MODETRANOP) &&
|
||||
(ckt->CKTmode & MODEUIC) ) {
|
||||
vds = here->MESAicVDS;
|
||||
vgs = here->MESAicVGS;
|
||||
vgd = vgs-vds;
|
||||
vgspp = vgs;
|
||||
vgdpp = vgd;
|
||||
} else if ( (ckt->CKTmode & MODEINITJCT) &&
|
||||
(here->MESAoff == 0) ) {
|
||||
vgs = -1;
|
||||
vgd = -1;
|
||||
vgspp = 0;
|
||||
vgdpp = 0;
|
||||
} else if( (ckt->CKTmode & MODEINITJCT) ||
|
||||
((ckt->CKTmode & MODEINITFIX) && (here->MESAoff))) {
|
||||
vgs = 0;
|
||||
vgd = 0;
|
||||
vgspp = 0;
|
||||
vgdpp = 0;
|
||||
} else {
|
||||
#ifndef PREDICTOR
|
||||
if(ckt->CKTmode & MODEINITPRED) {
|
||||
xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2];
|
||||
*(ckt->CKTstate0 + here->MESAvgs) =
|
||||
*(ckt->CKTstate1 + here->MESAvgs);
|
||||
vgs = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgs) -
|
||||
xfact * *(ckt->CKTstate2 + here->MESAvgs);
|
||||
*(ckt->CKTstate0 + here->MESAvgspp) =
|
||||
*(ckt->CKTstate1 + here->MESAvgspp);
|
||||
vgspp = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgspp) -
|
||||
xfact * *(ckt->CKTstate2 + here->MESAvgspp);
|
||||
*(ckt->CKTstate0 + here->MESAvgd) =
|
||||
*(ckt->CKTstate1 + here->MESAvgd);
|
||||
vgd = (1+xfact)* *(ckt->CKTstate1 + here->MESAvgd) -
|
||||
xfact * *(ckt->CKTstate2 + here->MESAvgd);
|
||||
*(ckt->CKTstate0 + here->MESAvgdpp) =
|
||||
*(ckt->CKTstate1 + here->MESAvgdpp);
|
||||
vgdpp = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgdpp) -
|
||||
xfact * *(ckt->CKTstate2 + here->MESAvgdpp);
|
||||
*(ckt->CKTstate0 + here->MESAcg) =
|
||||
*(ckt->CKTstate1 + here->MESAcg);
|
||||
*(ckt->CKTstate0 + here->MESAcd) =
|
||||
*(ckt->CKTstate1 + here->MESAcd);
|
||||
*(ckt->CKTstate0 + here->MESAcgd) =
|
||||
*(ckt->CKTstate1 + here->MESAcgd);
|
||||
*(ckt->CKTstate0 + here->MESAcgs) =
|
||||
*(ckt->CKTstate1 + here->MESAcgs);
|
||||
*(ckt->CKTstate0 + here->MESAgm) =
|
||||
*(ckt->CKTstate1 + here->MESAgm);
|
||||
*(ckt->CKTstate0 + here->MESAgds) =
|
||||
*(ckt->CKTstate1 + here->MESAgds);
|
||||
*(ckt->CKTstate0 + here->MESAggs) =
|
||||
*(ckt->CKTstate1 + here->MESAggs);
|
||||
*(ckt->CKTstate0 + here->MESAggd) =
|
||||
*(ckt->CKTstate1 + here->MESAggd);
|
||||
*(ckt->CKTstate0 + here->MESAggspp) =
|
||||
*(ckt->CKTstate1 + here->MESAggspp);
|
||||
*(ckt->CKTstate0 + here->MESAcgspp) =
|
||||
*(ckt->CKTstate1 + here->MESAcgspp);
|
||||
*(ckt->CKTstate0 + here->MESAggdpp) =
|
||||
*(ckt->CKTstate1 + here->MESAggdpp);
|
||||
*(ckt->CKTstate0 + here->MESAcgdpp) =
|
||||
*(ckt->CKTstate1 + here->MESAcgdpp);
|
||||
} else {
|
||||
#endif /* PREDICTOR */
|
||||
/*
|
||||
* compute new nonlinear branch voltages
|
||||
*/
|
||||
vgs = (*(ckt->CKTrhsOld+ here->MESAgatePrimeNode)-
|
||||
*(ckt->CKTrhsOld+here->MESAsourcePrimeNode));
|
||||
vgd = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)-
|
||||
*(ckt->CKTrhsOld+here->MESAdrainPrimeNode));
|
||||
vgspp = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)-
|
||||
*(ckt->CKTrhsOld+here->MESAsourcePrmPrmNode));
|
||||
vgdpp = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)-
|
||||
*(ckt->CKTrhsOld+here->MESAdrainPrmPrmNode));
|
||||
|
||||
#ifndef PREDICTOR
|
||||
}
|
||||
#endif /* PREDICTOR */
|
||||
delvgs=vgs - *(ckt->CKTstate0 + here->MESAvgs);
|
||||
delvgd=vgd - *(ckt->CKTstate0 + here->MESAvgd);
|
||||
delvds=delvgs - delvgd;
|
||||
delvgspp = vgspp - *(ckt->CKTstate0 + here->MESAvgspp);
|
||||
delvgdpp = vgdpp - *(ckt->CKTstate0 + here->MESAvgdpp);
|
||||
cghat= *(ckt->CKTstate0 + here->MESAcg) +
|
||||
*(ckt->CKTstate0 + here->MESAggd)*delvgd +
|
||||
*(ckt->CKTstate0 + here->MESAggs)*delvgs +
|
||||
*(ckt->CKTstate0 + here->MESAggspp)*delvgspp+
|
||||
*(ckt->CKTstate0 + here->MESAggdpp)*delvgdpp;
|
||||
cdhat= *(ckt->CKTstate0 + here->MESAcd) +
|
||||
*(ckt->CKTstate0 + here->MESAgm)*delvgs +
|
||||
*(ckt->CKTstate0 + here->MESAgds)*delvds -
|
||||
*(ckt->CKTstate0 + here->MESAggd)*delvgd;
|
||||
/*
|
||||
* bypass if solution has not changed
|
||||
*/
|
||||
if((ckt->CKTbypass) &&
|
||||
(!(ckt->CKTmode & MODEINITPRED)) &&
|
||||
(fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs),
|
||||
fabs(*(ckt->CKTstate0 + here->MESAvgs)))+
|
||||
ckt->CKTvoltTol) )
|
||||
if((fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd),
|
||||
fabs(*(ckt->CKTstate0 + here->MESAvgd)))+
|
||||
ckt->CKTvoltTol))
|
||||
if((fabs(delvgspp) < ckt->CKTreltol*MAX(fabs(vgspp),
|
||||
fabs(*(ckt->CKTstate0 + here->MESAvgspp)))+
|
||||
ckt->CKTvoltTol))
|
||||
if((fabs(delvgdpp) < ckt->CKTreltol*MAX(fabs(vgdpp),
|
||||
fabs(*(ckt->CKTstate0 + here->MESAvgdpp)))+
|
||||
ckt->CKTvoltTol))
|
||||
if((fabs(cghat-*(ckt->CKTstate0 + here->MESAcg))
|
||||
< ckt->CKTreltol*MAX(fabs(cghat),
|
||||
fabs(*(ckt->CKTstate0 + here->MESAcg)))+
|
||||
ckt->CKTabstol))
|
||||
if((fabs(cdhat-*(ckt->CKTstate0 + here->MESAcd))
|
||||
< ckt->CKTreltol*MAX(fabs(cdhat),
|
||||
fabs(*(ckt->CKTstate0 + here->MESAcd)))+
|
||||
ckt->CKTabstol)) {
|
||||
|
||||
/* we can do a bypass */
|
||||
vgs= *(ckt->CKTstate0 + here->MESAvgs);
|
||||
vgd= *(ckt->CKTstate0 + here->MESAvgd);
|
||||
vds= vgs-vgd;
|
||||
vgspp = *(ckt->CKTstate0 + here->MESAvgspp);
|
||||
vgdpp = *(ckt->CKTstate0 + here->MESAvgdpp);
|
||||
cg= *(ckt->CKTstate0 + here->MESAcg);
|
||||
cd= *(ckt->CKTstate0 + here->MESAcd);
|
||||
cgs= *(ckt->CKTstate0 + here->MESAcgs);
|
||||
cgd= *(ckt->CKTstate0 + here->MESAcgd);
|
||||
gm= *(ckt->CKTstate0 + here->MESAgm);
|
||||
gds= *(ckt->CKTstate0 + here->MESAgds);
|
||||
ggs= *(ckt->CKTstate0 + here->MESAggs);
|
||||
ggd= *(ckt->CKTstate0 + here->MESAggd);
|
||||
ggspp = *(ckt->CKTstate0 + here->MESAggspp);
|
||||
cgspp = *(ckt->CKTstate0 + here->MESAcgspp);
|
||||
ggdpp = *(ckt->CKTstate0 + here->MESAggdpp);
|
||||
cgdpp = *(ckt->CKTstate0 + here->MESAcgdpp);
|
||||
goto load;
|
||||
}
|
||||
/*
|
||||
* limit nonlinear branch voltages
|
||||
*/
|
||||
ichk1=1;
|
||||
vgs = DEVpnjlim(vgs,*(ckt->CKTstate0 + here->MESAvgs),vtes,
|
||||
vcrits, &icheck);
|
||||
vgd = DEVpnjlim(vgd,*(ckt->CKTstate0 + here->MESAvgd),vted,
|
||||
vcritd,&ichk1);
|
||||
if (ichk1 == 1) {
|
||||
icheck=1;
|
||||
}
|
||||
vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->MESAvgs),
|
||||
here->MESAtVto);
|
||||
vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->MESAvgd),
|
||||
here->MESAtVto);
|
||||
if(here->MESAsourcePrmPrmNode == here->MESAsourcePrimeNode)
|
||||
vgspp = vgs;
|
||||
if(here->MESAdrainPrmPrmNode == here->MESAdrainPrimeNode)
|
||||
vgdpp = vgd;
|
||||
}
|
||||
/*
|
||||
* determine dc current and derivatives
|
||||
*/
|
||||
vds = vgs-vgd;
|
||||
|
||||
arg = -vgs*model->MESAdel/vts;
|
||||
earg = exp(arg);
|
||||
evgs = exp(vgs/vtes);
|
||||
ggs = here->MESAcsatfs*evgs/vtes+here->MESAggrwl*earg*(1-arg)+ckt->CKTgmin;
|
||||
cgs = here->MESAcsatfs*(evgs-1)+here->MESAggrwl*vgs*earg+
|
||||
ckt->CKTgmin*vgs;
|
||||
cg = cgs;
|
||||
|
||||
arg = -vgd*model->MESAdel/vtd;
|
||||
earg = exp(arg);
|
||||
evgd = exp(vgd/vted);
|
||||
ggd = here->MESAcsatfd*evgd/vted+here->MESAggrwl*earg*(1-arg)+ckt->CKTgmin;
|
||||
cgd = here->MESAcsatfd*(evgd-1)+here->MESAggrwl*vgd*earg+
|
||||
ckt->CKTgmin*vgd;
|
||||
cg = cg+cgd;
|
||||
|
||||
if(vds < 0) {
|
||||
vds = -vds;
|
||||
inverse = TRUE;
|
||||
}
|
||||
von = here->MESAtVto+model->MESAks*(*(ckt->CKTrhsOld+here->MESAsourcePrimeNode)-model->MESAvsg);
|
||||
if(model->MESAlevel == 2)
|
||||
mesa1(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd);
|
||||
else if(model->MESAlevel == 3)
|
||||
mesa2(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd);
|
||||
else if(model->MESAlevel == 4)
|
||||
mesa3(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd);
|
||||
if(inverse) {
|
||||
cdrain = -cdrain;
|
||||
vds = -vds;
|
||||
temp = capgs;
|
||||
capgs = capgd;
|
||||
capgd = temp;
|
||||
}
|
||||
/*
|
||||
* compute equivalent drain current source
|
||||
*/
|
||||
cd = cdrain - cgd;
|
||||
if ( (ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) ||
|
||||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){
|
||||
/*
|
||||
* charge storage elements
|
||||
*/
|
||||
vgs1 = *(ckt->CKTstate1 + here->MESAvgspp);
|
||||
vgd1 = *(ckt->CKTstate1 + here->MESAvgdpp);
|
||||
|
||||
if(ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->MESAqgs) = capgs*vgspp;
|
||||
*(ckt->CKTstate1 + here->MESAqgd) = capgd*vgdpp;
|
||||
}
|
||||
*(ckt->CKTstate0+here->MESAqgs) = *(ckt->CKTstate1 + here->MESAqgs) +
|
||||
capgs*(vgspp-vgs1);
|
||||
*(ckt->CKTstate0+here->MESAqgd) = *(ckt->CKTstate1 + here->MESAqgd) +
|
||||
capgd*(vgdpp-vgd1);
|
||||
|
||||
/*
|
||||
* store small-signal parameters
|
||||
*/
|
||||
if( (!(ckt->CKTmode & MODETRANOP)) ||
|
||||
(!(ckt->CKTmode & MODEUIC)) ) {
|
||||
if(ckt->CKTmode & MODEINITSMSIG) {
|
||||
*(ckt->CKTstate0 + here->MESAqgs) = capgs;
|
||||
*(ckt->CKTstate0 + here->MESAqgd) = capgd;
|
||||
continue; /*go to 1000*/
|
||||
}
|
||||
/*
|
||||
* transient analysis
|
||||
*/
|
||||
if(ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->MESAqgs) =
|
||||
*(ckt->CKTstate0 + here->MESAqgs);
|
||||
*(ckt->CKTstate1 + here->MESAqgd) =
|
||||
*(ckt->CKTstate0 + here->MESAqgd);
|
||||
}
|
||||
error = NIintegrate(ckt,&geq,&ceq,capgs,here->MESAqgs);
|
||||
if(error) return(error);
|
||||
ggspp = geq;
|
||||
cgspp = *(ckt->CKTstate0 + here->MESAcqgs);
|
||||
cg = cg + cgspp;
|
||||
error = NIintegrate(ckt,&geq,&ceq,capgd,here->MESAqgd);
|
||||
if(error) return(error);
|
||||
ggdpp = geq;
|
||||
cgdpp = *(ckt->CKTstate0 + here->MESAcqgd);
|
||||
cg = cg + cgdpp;
|
||||
cd = cd - cgdpp;
|
||||
if (ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->MESAcqgs) =
|
||||
*(ckt->CKTstate0 + here->MESAcqgs);
|
||||
*(ckt->CKTstate1 + here->MESAcqgd) =
|
||||
*(ckt->CKTstate0 + here->MESAcqgd);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* check convergence
|
||||
*/
|
||||
if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) {
|
||||
if( (icheck == 1)
|
||||
|| (fabs(cghat-cg) >= ckt->CKTreltol*
|
||||
MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) ||
|
||||
(fabs(cdhat-cd) > ckt->CKTreltol*
|
||||
MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol)
|
||||
) {
|
||||
ckt->CKTnoncon++;
|
||||
}
|
||||
}
|
||||
*(ckt->CKTstate0 + here->MESAvgs) = vgs;
|
||||
*(ckt->CKTstate0 + here->MESAvgspp) = vgspp;
|
||||
*(ckt->CKTstate0 + here->MESAvgd) = vgd;
|
||||
*(ckt->CKTstate0 + here->MESAvgdpp) = vgdpp;
|
||||
*(ckt->CKTstate0 + here->MESAcg) = cg;
|
||||
*(ckt->CKTstate0 + here->MESAcd) = cd;
|
||||
*(ckt->CKTstate0 + here->MESAcgd) = cgd;
|
||||
*(ckt->CKTstate0 + here->MESAcgs) = cgs;
|
||||
*(ckt->CKTstate0 + here->MESAgm) = gm;
|
||||
*(ckt->CKTstate0 + here->MESAgds) = gds;
|
||||
*(ckt->CKTstate0 + here->MESAggs) = ggs;
|
||||
*(ckt->CKTstate0 + here->MESAggd) = ggd;
|
||||
*(ckt->CKTstate0 + here->MESAggspp) = ggspp;
|
||||
*(ckt->CKTstate0 + here->MESAcgspp) = cgspp;
|
||||
*(ckt->CKTstate0 + here->MESAggdpp) = ggdpp;
|
||||
*(ckt->CKTstate0 + here->MESAcgdpp) = cgdpp;
|
||||
|
||||
/*
|
||||
* load current vector
|
||||
*/
|
||||
load:
|
||||
ccorr = model->MESAag*(cgs-cgd);
|
||||
ceqgd = cgd + cgdpp - ggd*vgd - ggdpp*vgdpp;
|
||||
ceqgs = cgs + cgspp - ggs*vgs - ggspp*vgspp;
|
||||
cdreq=((cd+cgd+cgdpp)-gds*vds-gm*vgs);
|
||||
*(ckt->CKTrhs + here->MESAgatePrimeNode) += (-ceqgs-ceqgd);
|
||||
ceqgd = (cgd-ggd*vgd);
|
||||
*(ckt->CKTrhs + here->MESAdrainPrimeNode) += (-cdreq+ceqgd+ccorr);
|
||||
ceqgd = (cgdpp-ggdpp*vgdpp);
|
||||
*(ckt->CKTrhs + here->MESAdrainPrmPrmNode) += ceqgd;
|
||||
ceqgs = (cgs-ggs*vgs);
|
||||
*(ckt->CKTrhs + here->MESAsourcePrimeNode) += (cdreq+ceqgs-ccorr);
|
||||
ceqgs = (cgspp-ggspp*vgspp);
|
||||
*(ckt->CKTrhs + here->MESAsourcePrmPrmNode) += ceqgs;
|
||||
|
||||
/*
|
||||
* load y matrix
|
||||
*/
|
||||
*(here->MESAdrainDrainPtr) += here->MESAdrainConduct;
|
||||
*(here->MESAsourceSourcePtr) += here->MESAsourceConduct;
|
||||
*(here->MESAgateGatePtr) += here->MESAgateConduct;
|
||||
*(here->MESAsourcePrmPrmSourcePrmPrmPtr) += (here->MESAtGi+ggspp);
|
||||
*(here->MESAdrainPrmPrmDrainPrmPrmPtr) += (here->MESAtGf+ggdpp);
|
||||
*(here->MESAgatePrimeGatePrimePtr) += (ggd+ggs+here->MESAgateConduct+ggspp+ggdpp);
|
||||
*(here->MESAdrainPrimeDrainPrimePtr) += (gds+ggd+here->MESAdrainConduct+here->MESAtGf);
|
||||
*(here->MESAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+here->MESAsourceConduct+here->MESAtGi);
|
||||
*(here->MESAdrainDrainPrimePtr) -= here->MESAdrainConduct;
|
||||
*(here->MESAdrainPrimeDrainPtr) -= here->MESAdrainConduct;
|
||||
*(here->MESAsourceSourcePrimePtr) -= here->MESAsourceConduct;
|
||||
*(here->MESAsourcePrimeSourcePtr) -= here->MESAsourceConduct;
|
||||
*(here->MESAgateGatePrimePtr) -= here->MESAgateConduct;
|
||||
*(here->MESAgatePrimeGatePtr) -= here->MESAgateConduct;
|
||||
*(here->MESAgatePrimeDrainPrimePtr) -= ggd;
|
||||
*(here->MESAgatePrimeSourcePrimePtr) -= ggs;
|
||||
*(here->MESAdrainPrimeGatePrimePtr) += (gm-ggd);
|
||||
*(here->MESAdrainPrimeSourcePrimePtr) += (-gds-gm);
|
||||
*(here->MESAsourcePrimeGatePrimePtr) += (-ggs-gm);
|
||||
*(here->MESAsourcePrimeDrainPrimePtr) -= gds;
|
||||
*(here->MESAsourcePrimeSourcePrmPrmPtr) -= here->MESAtGi;
|
||||
*(here->MESAsourcePrmPrmSourcePrimePtr) -= here->MESAtGi;
|
||||
*(here->MESAgatePrimeSourcePrmPrmPtr) -= ggspp;
|
||||
*(here->MESAsourcePrmPrmGatePrimePtr) -= ggspp;
|
||||
*(here->MESAdrainPrimeDrainPrmPrmPtr) -= here->MESAtGf;
|
||||
*(here->MESAdrainPrmPrmDrainPrimePtr) -= here->MESAtGf;
|
||||
*(here->MESAgatePrimeDrainPrmPrmPtr) -= ggdpp;
|
||||
*(here->MESAdrainPrmPrmGatePrimePtr) -= ggdpp;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
||||
#define ETA (here->MESAtEta)
|
||||
#define MU0 (here->MESAtMu)
|
||||
#define RS (here->MESAtRsi)
|
||||
#define RD (here->MESAtRdi)
|
||||
#define SIGMA0 (model->MESAsigma0)
|
||||
#define VSIGMAT (model->MESAvsigmat)
|
||||
#define VSIGMA (model->MESAvsigma)
|
||||
#define THETA (model->MESAtheta)
|
||||
#define VS (model->MESAvs)
|
||||
#define ND (model->MESAnd)
|
||||
#define D (model->MESAd)
|
||||
#define TC (model->MESAtc)
|
||||
#define MC (model->MESAmc)
|
||||
#define M0 (model->MESAm)
|
||||
#define ALPHA (model->MESAalpha)
|
||||
#define LAMBDA (here->MESAtLambda)
|
||||
#define NDELTA (model->MESAndelta)
|
||||
#define TH (model->MESAth)
|
||||
#define NDU (model->MESAndu)
|
||||
#define DU (model->MESAdu)
|
||||
#define NMAX (model->MESAnmax)
|
||||
#define GAMMA (model->MESAgamma)
|
||||
|
||||
|
||||
static void mesa1(MESAmodel *model, MESAinstance *here, double vgs,
|
||||
double vds, double von, double *cdrain,
|
||||
double *gm, double *gds, double *capgs, double *capgd)
|
||||
|
||||
{
|
||||
|
||||
double vt;
|
||||
double etavth;
|
||||
double vl;
|
||||
double rt;
|
||||
double mu;
|
||||
double beta;
|
||||
double vgt;
|
||||
double vgt0;
|
||||
double sigma;
|
||||
double vgte;
|
||||
double isat;
|
||||
double isata;
|
||||
double isatb;
|
||||
double ns;
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double f;
|
||||
double g;
|
||||
double h;
|
||||
double m;
|
||||
double p;
|
||||
double q;
|
||||
double r;
|
||||
double s;
|
||||
double t;
|
||||
double u;
|
||||
double v;
|
||||
double w;
|
||||
double temp;
|
||||
double gch;
|
||||
double gchi;
|
||||
double vsate;
|
||||
double vdse;
|
||||
double cgc;
|
||||
double sqrt1;
|
||||
double delidgch;
|
||||
double delgchgchi;
|
||||
double delgchins;
|
||||
double delnsvgt;
|
||||
double delnsvgte;
|
||||
double delvgtevgt;
|
||||
double delidvsate;
|
||||
double delvsateisat;
|
||||
double delisatisata;
|
||||
double delisatavgte;
|
||||
double delisatabeta;
|
||||
double delisatisatb;
|
||||
double delvsategch;
|
||||
double delidvds;
|
||||
double ddevgte;
|
||||
double dvgtvgs;
|
||||
double dgchivgt;
|
||||
double dvgtevds;
|
||||
double dgchivds;
|
||||
double disatavgt;
|
||||
double disatavds;
|
||||
double disatbvgt;
|
||||
double dvsatevgt;
|
||||
double dvsatevds;
|
||||
double gmmadd;
|
||||
double gdsmadd;
|
||||
|
||||
|
||||
vt = CONSTKoverQ * here->MESAts;
|
||||
etavth = ETA*vt;
|
||||
rt = RS+RD;
|
||||
vgt0 = vgs - von;
|
||||
s = exp((vgt0-VSIGMAT)/VSIGMA);
|
||||
sigma = SIGMA0/(1+s);
|
||||
vgt = vgt0+sigma*vds;
|
||||
mu = MU0+THETA*vgt;
|
||||
vl = VS/mu*here->MESAlength;
|
||||
beta = here->MESAbeta/(model->MESAvpo+3*vl);
|
||||
u = vgt/vt-1;
|
||||
t = sqrt(model->MESAdeltaSqr+u*u);
|
||||
vgte = 0.5*vt*(2+u+t);
|
||||
a = 2*beta*vgte;
|
||||
b = exp(-vgt/etavth);
|
||||
if(vgte > model->MESAvpo)
|
||||
sqrt1 = 0;
|
||||
else
|
||||
sqrt1 = sqrt(1-vgte/model->MESAvpo);
|
||||
ns = 1.0/(1.0/ND/D/(1-sqrt1) + 1.0/here->MESAn0*b);
|
||||
if(ns < 1.0e-38) {
|
||||
*cdrain = 0;
|
||||
*gm = 0.0;
|
||||
*gds = 0.0;
|
||||
*capgs = here->MESAcf;
|
||||
*capgd = here->MESAcf;
|
||||
return;
|
||||
}
|
||||
gchi = here->MESAgchi0*mu*ns;
|
||||
gch = gchi/(1+gchi*rt);
|
||||
f = sqrt(1+2*a*RS);
|
||||
d = 1+a*RS + f;
|
||||
e = 1+TC*vgte;
|
||||
isata = a*vgte/(d*e);
|
||||
isatb = here->MESAisatb0*mu*exp(vgt/etavth);
|
||||
isat = isata*isatb/(isata+isatb);
|
||||
vsate = isat/gch;
|
||||
vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC);
|
||||
m = M0+ALPHA*vgte;
|
||||
g = pow(vds/vsate,m);
|
||||
h = pow(1+g,1.0/m);
|
||||
here->MESAdelidgch0 = vds/h;
|
||||
delidgch = here->MESAdelidgch0*(1+LAMBDA*vds);
|
||||
*cdrain = gch*delidgch;
|
||||
if(vgt > model->MESAvpo)
|
||||
temp = 0;
|
||||
else
|
||||
temp = sqrt(1-vgt/model->MESAvpo);
|
||||
cgc = W*L*EPSILONGAAS/(temp+b)/D;
|
||||
c = (vsate-vdse)/(2*vsate-vdse);
|
||||
c = c*c;
|
||||
*capgs = here->MESAcf+2.0/3.0*cgc*(1-c);
|
||||
c = vsate/(2*vsate-vdse);
|
||||
c = c*c;
|
||||
*capgd = here->MESAcf+2.0/3.0*cgc*(1-c);
|
||||
temp = 1+gchi*rt;
|
||||
delgchgchi = 1.0/(temp*temp);
|
||||
delgchins = here->MESAgchi0*mu;
|
||||
delnsvgt = ns*ns*1.0/here->MESAn0/etavth*b;
|
||||
q = 1 - sqrt1;
|
||||
if(sqrt1 == 0)
|
||||
delnsvgte = 0;
|
||||
else
|
||||
delnsvgte = 0.5*ns*ns/(model->MESAvpo*ND*D*sqrt1*q*q);
|
||||
delvgtevgt = 0.5*(1+u/t);
|
||||
here->MESAdelidvds0 = gch/h;
|
||||
if(vds != 0.0)
|
||||
here->MESAdelidvds1 = (*cdrain)*pow(vds/vsate,m-1)/(vsate*(1+g));
|
||||
else
|
||||
here->MESAdelidvds1 = 0.0;
|
||||
delidvds = here->MESAdelidvds0*(1+2*LAMBDA*vds) - here->MESAdelidvds1;
|
||||
delidvsate = (*cdrain)*g/(vsate*(1+g));
|
||||
delvsateisat = 1.0/gch;
|
||||
r = isata+isatb;
|
||||
r = r*r;
|
||||
delisatisata = isatb*isatb/r;
|
||||
v = 1.0+1.0/f;
|
||||
ddevgte = 2*beta*RS*v*e+d*TC;
|
||||
temp = d*d*e*e;
|
||||
delisatavgte = (2*a*d*e - a*vgte*ddevgte)/temp;
|
||||
delisatabeta = 2*vgte*vgte*(d*e-a*e*RS*v)/temp;
|
||||
delisatisatb = isata*isata/r;
|
||||
delvsategch = -vsate/gch;
|
||||
dvgtvgs = 1 - SIGMA0*vds*s/VSIGMA/((1+s)*(1+s));
|
||||
temp = here->MESAgchi0*ns*THETA;
|
||||
dgchivgt = delgchins*(delnsvgte*delvgtevgt+delnsvgt)+temp;
|
||||
dvgtevds = delvgtevgt*sigma;
|
||||
dgchivds = delgchins*(delnsvgte*dvgtevds+delnsvgt*sigma)+temp*sigma;
|
||||
temp = delisatabeta*3*beta*vl*THETA/(mu*(model->MESAvpo+3*vl));
|
||||
disatavgt = delisatavgte*delvgtevgt+temp;
|
||||
disatavds = delisatavgte*dvgtevds+temp*sigma;
|
||||
disatbvgt = isatb/etavth+isatb/mu*THETA;
|
||||
p = delgchgchi*dgchivgt;
|
||||
w = delgchgchi*dgchivds;
|
||||
dvsatevgt = delvsateisat*(delisatisata*disatavgt+delisatisatb*disatbvgt)+delvsategch*p;
|
||||
dvsatevds = delvsateisat*(delisatisata*disatavds+delisatisatb*disatbvgt*sigma)+delvsategch*w;
|
||||
if(ALPHA != 0) {
|
||||
if(vds == 0)
|
||||
gmmadd = 0;
|
||||
else
|
||||
gmmadd = (*cdrain)*(log(1+g)/(m*m)-g*log(vds/vsate)/(m*(1+g)))*
|
||||
ALPHA*delvgtevgt;
|
||||
gdsmadd = gmmadd*sigma;
|
||||
} else {
|
||||
gmmadd = 0;
|
||||
gdsmadd = 0;
|
||||
}
|
||||
here->MESAgm0 = p;
|
||||
here->MESAgm1 = delidvsate*dvsatevgt;
|
||||
here->MESAgm2 = dvgtvgs;
|
||||
g = delidgch*p+here->MESAgm1;
|
||||
*gm = (g+gmmadd)*dvgtvgs;
|
||||
here->MESAgds0 = delidvsate*dvsatevds+delidgch*w+gdsmadd;
|
||||
*gds = delidvds+here->MESAgds0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void mesa2(MESAmodel *model, MESAinstance *here, double vgs,
|
||||
double vds, double von, double *cdrain, double *gm,
|
||||
double *gds, double *capgs, double *capgd)
|
||||
|
||||
{
|
||||
|
||||
double vt;
|
||||
double rt;
|
||||
double vgt;
|
||||
double etavth;
|
||||
double vgt0;
|
||||
double sigma;
|
||||
double vgte;
|
||||
double isat;
|
||||
double isata;
|
||||
double isatb;
|
||||
double nsa;
|
||||
double nsb;
|
||||
double ns;
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double f;
|
||||
double g;
|
||||
double h;
|
||||
double p;
|
||||
double q;
|
||||
double r;
|
||||
double s;
|
||||
double t;
|
||||
double gch;
|
||||
double gchi;
|
||||
double vsate;
|
||||
double vdse;
|
||||
double ca;
|
||||
double cb;
|
||||
double cgc;
|
||||
double delidgch;
|
||||
double delgchgchi;
|
||||
double delgchins;
|
||||
double delnsvgt;
|
||||
double delnsbvgt;
|
||||
double delnsavgte;
|
||||
double delvgtevgt;
|
||||
double delidvsate;
|
||||
double delvsateisat;
|
||||
double delisatisata;
|
||||
double delisatavgte;
|
||||
double delisatisatb;
|
||||
double delvsategch;
|
||||
double delisatbvgt;
|
||||
double delvsatevgt;
|
||||
double delidvds;
|
||||
double ddevgte;
|
||||
double delvgtvgs;
|
||||
|
||||
|
||||
vt = CONSTKoverQ * here->MESAts;
|
||||
etavth = ETA*vt;
|
||||
rt = RS+RD;
|
||||
vgt0 = vgs - von;
|
||||
s = exp((vgt0-VSIGMAT)/VSIGMA);
|
||||
sigma = SIGMA0/(1+s);
|
||||
vgt = vgt0+sigma*vds;
|
||||
t = vgt/vt-1;
|
||||
q = sqrt(model->MESAdeltaSqr+t*t);
|
||||
vgte = 0.5*vt*(2+t+q);
|
||||
a = 2*model->MESAbeta*vgte;
|
||||
if(vgt > model->MESAvpod) {
|
||||
if(vgte > model->MESAvpo) {
|
||||
nsa = NDELTA*TH + NDU*DU;
|
||||
ca = EPSILONGAAS/DU;
|
||||
delnsavgte = 0;
|
||||
} else {
|
||||
r = sqrt((model->MESAvpo-vgte)/model->MESAvpou);
|
||||
nsa = NDELTA*TH + NDU*DU*(1-r);
|
||||
ca = EPSILONGAAS/DU/r;
|
||||
delnsavgte = NDU*DU/model->MESAvpou/2.0/r;
|
||||
}
|
||||
} else {
|
||||
if(model->MESAvpod - vgte < 0) {
|
||||
nsa = NDELTA*TH*(1-DU/TH);
|
||||
ca = EPSILONGAAS/DU;
|
||||
delnsavgte = 0;
|
||||
} else {
|
||||
r = sqrt(1+NDU/NDELTA*(model->MESAvpod - vgte)/model->MESAvpou);
|
||||
nsa = NDELTA*TH*(1-DU/TH*(r-1));
|
||||
ca = EPSILONGAAS/DU/r;
|
||||
delnsavgte = DU*NDU/2.0/model->MESAvpou/r;
|
||||
}
|
||||
}
|
||||
b = exp(vgt/etavth);
|
||||
cb = EPSILONGAAS/(DU+TH)*b;
|
||||
nsb = here->MESAnsb0*b;
|
||||
delnsbvgt = nsb/etavth;
|
||||
ns = nsa*nsb/(nsa+nsb);
|
||||
if(ns < 1.0e-38) {
|
||||
*cdrain = 0;
|
||||
*gm = 0.0;
|
||||
*gds = 0.0;
|
||||
*capgs = here->MESAcf;
|
||||
*capgd = here->MESAcf;
|
||||
return;
|
||||
}
|
||||
gchi = here->MESAgchi0*ns;
|
||||
gch = gchi/(1+gchi*rt);
|
||||
f = sqrt(1+2*a*RS);
|
||||
d = 1+a*RS + f;
|
||||
e = 1+TC*vgte;
|
||||
isata = a*vgte/d/e;
|
||||
isatb = here->MESAisatb0*b;
|
||||
isat = isata*isatb/(isata+isatb);
|
||||
vsate = isat/gch;
|
||||
vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC);
|
||||
g = pow(vds/vsate,M0);
|
||||
h = pow(1+g,1.0/M0);
|
||||
here->MESAdelidgch0 = vds/h;
|
||||
delidgch = here->MESAdelidgch0*(1+LAMBDA*vds);
|
||||
*cdrain = gch*delidgch;
|
||||
cgc = W*L*ca*cb/(ca+cb);
|
||||
c = (vsate-vdse)/(2*vsate-vdse);
|
||||
c = c*c;
|
||||
*capgs = here->MESAcf+2.0/3.0*cgc*(1-c);
|
||||
c = vsate/(2*vsate-vdse);
|
||||
c = c*c;
|
||||
*capgd = here->MESAcf+2.0/3.0*cgc*(1-c);
|
||||
c = vgt/vt-1;
|
||||
delvgtevgt = 0.5*(1+t/q);
|
||||
here->MESAdelidvds0 = gch/h;
|
||||
if(vds != 0.0)
|
||||
here->MESAdelidvds1 = (*cdrain)*pow(vds/vsate,M0-1)/vsate/(1+g);
|
||||
else
|
||||
here->MESAdelidvds1 = 0.0;
|
||||
delidvds = here->MESAdelidvds0*(1+2*LAMBDA*vds) -
|
||||
here->MESAdelidvds1;
|
||||
delgchgchi = 1.0/(1+gchi*rt)/(1+gchi*rt);
|
||||
delgchins = here->MESAgchi0;
|
||||
r = nsa+nsb;
|
||||
r = r*r;
|
||||
delnsvgt = (nsb*nsb*delvgtevgt*delnsavgte + nsa*nsa*delnsbvgt)/r;
|
||||
delidvsate = (*cdrain)*g/vsate/(1+g);
|
||||
delvsateisat = 1.0/gch;
|
||||
r = isata+isatb;
|
||||
r = r*r;
|
||||
delisatisata = isatb*isatb/r;
|
||||
ddevgte = 2*model->MESAbeta*RS*(1+1.0/f)*e+d*TC;
|
||||
delisatavgte = (2*a*d*e - a*vgte*ddevgte)/d/d/e/e;
|
||||
delisatisatb = isata*isata/r;
|
||||
delisatbvgt = isatb/etavth;
|
||||
delvsategch = -vsate/gch;
|
||||
delvgtvgs = 1-SIGMA0*vds*s/VSIGMA/(1+s)/(1+s);
|
||||
p = delgchgchi*delgchins*delnsvgt;
|
||||
delvsatevgt = delvsateisat*(delisatisata*delisatavgte*delvgtevgt +
|
||||
delisatisatb*delisatbvgt) + delvsategch*p;
|
||||
here->MESAgm0 = p;
|
||||
here->MESAgm1 = delidvsate*delvsatevgt;
|
||||
here->MESAgm2 = delvgtvgs;
|
||||
g = delidgch*p + here->MESAgm1;
|
||||
*gm = g*delvgtvgs;
|
||||
here->MESAgds0 = g*sigma;
|
||||
*gds = delidvds+here->MESAgds0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void mesa3(MESAmodel *model, MESAinstance *here, double vgs,
|
||||
double vds, double von, double *cdrain, double *gm,
|
||||
double *gds, double *capgs, double *capgd)
|
||||
|
||||
{
|
||||
|
||||
double vt;
|
||||
double vgt;
|
||||
double vgt0;
|
||||
double sigma;
|
||||
double vgte;
|
||||
double isat;
|
||||
double isatm;
|
||||
double ns;
|
||||
double nsm;
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double g;
|
||||
double h;
|
||||
double p;
|
||||
double q;
|
||||
double s;
|
||||
double t;
|
||||
double u;
|
||||
double temp;
|
||||
double etavth;
|
||||
double gch;
|
||||
double gchi;
|
||||
double gchim;
|
||||
double vsate;
|
||||
double vdse;
|
||||
double cgc;
|
||||
double cgcm;
|
||||
double rt;
|
||||
double vl;
|
||||
double delidgch;
|
||||
double delgchgchi;
|
||||
double delgchins;
|
||||
double delnsnsm;
|
||||
double delnsmvgt;
|
||||
double delvgtevgt;
|
||||
double delidvsate;
|
||||
double delvsateisat;
|
||||
double delisatisatm;
|
||||
double delisatmvgte;
|
||||
double delisatmgchim;
|
||||
double delvsategch;
|
||||
double delidvds;
|
||||
double delvgtvgs;
|
||||
double delvsatevgt;
|
||||
|
||||
vt = CONSTKoverQ * here->MESAts;
|
||||
etavth = ETA*vt;
|
||||
vl = VS/MU0*L;
|
||||
rt = RS+RD;
|
||||
vgt0 = vgs - von;
|
||||
s = exp((vgt0-VSIGMAT)/VSIGMA);
|
||||
sigma = SIGMA0/(1+s);
|
||||
vgt = vgt0+sigma*vds;
|
||||
u = 0.5*vgt/vt-1;
|
||||
t = sqrt(model->MESAdeltaSqr+u*u);
|
||||
vgte = vt*(2+u+t);
|
||||
b = exp(vgt/etavth);
|
||||
nsm = 2*here->MESAn0*log(1+0.5*b);
|
||||
if(nsm < 1.0e-38) {
|
||||
*cdrain = 0;
|
||||
*gm = 0.0;
|
||||
*gds = 0.0;
|
||||
*capgs = here->MESAcf;
|
||||
*capgd = here->MESAcf;
|
||||
return;
|
||||
}
|
||||
c = pow(nsm/NMAX,GAMMA);
|
||||
q = pow(1+c,1.0/GAMMA);
|
||||
ns = nsm/q;
|
||||
gchi = here->MESAgchi0*ns;
|
||||
gch = gchi/(1+gchi*rt);
|
||||
gchim = here->MESAgchi0*nsm;
|
||||
h = sqrt(1+2*gchim*model->MESArsi + vgte*vgte/(vl*vl));
|
||||
p = 1+gchim*RS+h;
|
||||
isatm = gchim*vgte/p;
|
||||
g = pow(isatm/here->MESAimax,GAMMA);
|
||||
isat = isatm/pow(1+g,1/GAMMA);
|
||||
vsate = isat/gch;
|
||||
vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC);
|
||||
d = pow(vds/vsate,M0);
|
||||
e = pow(1+d,1.0/M0);
|
||||
delidgch = vds*(1+LAMBDA*vds)/e;
|
||||
*cdrain = gch*delidgch;
|
||||
cgcm = 1.0/(1/model->MESAcas*D/model->MESAepsi +
|
||||
1/model->MESAcbs*etavth/CHARGE/here->MESAn0*exp(-vgt/etavth));
|
||||
cgc = W*L*cgcm/pow(1+c,1+1.0/GAMMA);
|
||||
/*
|
||||
{
|
||||
char buf[256];
|
||||
void far pascal OutputDebugString(char*);
|
||||
sprintf(buf,"\n%f\t%e\0",vgs,cgc);
|
||||
OutputDebugString(buf);
|
||||
}
|
||||
*/
|
||||
a = (vsate-vdse)/(2*vsate-vdse);
|
||||
a = a*a;
|
||||
temp = 2.0/3.0;
|
||||
*capgs = here->MESAcf+temp*cgc*(1-a);
|
||||
a = vsate/(2*vsate-vdse);
|
||||
a = a*a;
|
||||
*capgd = here->MESAcf+temp*cgc*(1-a);
|
||||
delidvsate = (*cdrain)*d/vsate/(1+d);
|
||||
delidvds = gch*(1+2*LAMBDA*vds)/e-(*cdrain)*
|
||||
pow(vds/vsate,M0-1)/(vsate*(1+d));
|
||||
a = 1+gchi*rt;
|
||||
delgchgchi = 1.0/(a*a);
|
||||
delgchins = here->MESAgchi0;
|
||||
delnsnsm = ns/nsm*(1-c/(1+c));
|
||||
delnsmvgt = here->MESAn0/etavth/(1.0/b + 0.5);
|
||||
delvgtevgt = 0.5*(1+u/t);
|
||||
delvsateisat = 1.0/gch;
|
||||
delisatisatm = isat/isatm*(1-g/(1+g));
|
||||
delisatmvgte = gchim*(p - vgte*vgte/(vl*vl*h))/(p*p);
|
||||
delvsategch = -vsate/gch;
|
||||
delisatmgchim = vgte*(p - gchim*RS*(1+1.0/h))/(p*p);
|
||||
delvgtvgs = 1-vds*SIGMA0/VSIGMA*s/((1+s)*(1+s));
|
||||
p = delgchgchi*delgchins*delnsnsm*delnsmvgt;
|
||||
delvsatevgt = (delvsateisat*delisatisatm*(delisatmvgte*delvgtevgt +
|
||||
delisatmgchim*here->MESAgchi0*delnsmvgt)+delvsategch*p);
|
||||
g = delidgch*p + delidvsate*delvsatevgt;
|
||||
*gm = g*delvgtvgs;
|
||||
*gds = delidvds + g*sigma;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "devdefs.h"
|
||||
#include "ifsim.h"
|
||||
#include "mesadefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
MESAmAsk(ckt,inst,which,value)
|
||||
CKTcircuit *ckt;
|
||||
GENmodel *inst;
|
||||
int which;
|
||||
IFvalue *value;
|
||||
{
|
||||
MESAmodel *here = (MESAmodel*)inst;
|
||||
switch(which) {
|
||||
case MESA_MOD_VTO:
|
||||
value->rValue = here->MESAthreshold;
|
||||
return (OK);
|
||||
case MESA_MOD_VS:
|
||||
value->rValue = here->MESAvs;
|
||||
return (OK);
|
||||
case MESA_MOD_ALPHA:
|
||||
value->rValue = here->MESAalpha;
|
||||
return (OK);
|
||||
case MESA_MOD_BETA:
|
||||
value->rValue = here->MESAbeta;
|
||||
return (OK);
|
||||
case MESA_MOD_LAMBDA:
|
||||
value->rValue = here->MESAlambda;
|
||||
return (OK);
|
||||
case MESA_MOD_RG:
|
||||
value->rValue = here->MESAgateResist;
|
||||
return (OK);
|
||||
case MESA_MOD_RD:
|
||||
value->rValue = here->MESAdrainResist;
|
||||
return (OK);
|
||||
case MESA_MOD_RS:
|
||||
value->rValue = here->MESAsourceResist;
|
||||
return (OK);
|
||||
case MESA_MOD_RI:
|
||||
value->rValue = here->MESAri;
|
||||
return (OK);
|
||||
case MESA_MOD_RF:
|
||||
value->rValue = here->MESArf;
|
||||
return (OK);
|
||||
case MESA_MOD_RDI:
|
||||
value->rValue = here->MESArdi;
|
||||
return (OK);
|
||||
case MESA_MOD_RSI:
|
||||
value->rValue = here->MESArsi;
|
||||
return (OK);
|
||||
case MESA_MOD_PHIB:
|
||||
value->rValue = here->MESAphib;
|
||||
return (OK);
|
||||
case MESA_MOD_PHIB1:
|
||||
value->rValue = here->MESAphib1;
|
||||
return (OK);
|
||||
case MESA_MOD_ASTAR:
|
||||
value->rValue = here->MESAastar;
|
||||
return (OK);
|
||||
case MESA_MOD_GGR:
|
||||
value->rValue = here->MESAggr;
|
||||
return (OK);
|
||||
case MESA_MOD_DEL:
|
||||
value->rValue = here->MESAdel;
|
||||
return (OK);
|
||||
case MESA_MOD_XCHI:
|
||||
value->rValue = here->MESAxchi;
|
||||
return (OK);
|
||||
case MESA_MOD_N:
|
||||
value->rValue = here->MESAn;
|
||||
return (OK);
|
||||
case MESA_MOD_ETA:
|
||||
value->rValue = here->MESAeta;
|
||||
return (OK);
|
||||
case MESA_MOD_M:
|
||||
value->rValue = here->MESAm;
|
||||
return (OK);
|
||||
case MESA_MOD_MC:
|
||||
value->rValue = here->MESAmc;
|
||||
return (OK);
|
||||
case MESA_MOD_SIGMA0:
|
||||
value->rValue = here->MESAsigma0;
|
||||
return (OK);
|
||||
case MESA_MOD_VSIGMAT:
|
||||
value->rValue = here->MESAvsigmat;
|
||||
return (OK);
|
||||
case MESA_MOD_VSIGMA:
|
||||
value->rValue = here->MESAvsigma;
|
||||
return (OK);
|
||||
case MESA_MOD_MU:
|
||||
value->rValue = here->MESAmu;
|
||||
return (OK);
|
||||
case MESA_MOD_MU1:
|
||||
value->rValue = here->MESAmu1;
|
||||
return (OK);
|
||||
case MESA_MOD_MU2:
|
||||
value->rValue = here->MESAmu2;
|
||||
return (OK);
|
||||
case MESA_MOD_D:
|
||||
value->rValue = here->MESAd;
|
||||
return (OK);
|
||||
case MESA_MOD_ND:
|
||||
value->rValue = here->MESAnd;
|
||||
return (OK);
|
||||
case MESA_MOD_DELTA:
|
||||
value->rValue = here->MESAdelta;
|
||||
return (OK);
|
||||
case MESA_MOD_TC:
|
||||
value->rValue = here->MESAtc;
|
||||
return (OK);
|
||||
case MESA_MOD_TVTO:
|
||||
value->rValue = here->MESAtvto;
|
||||
return (OK);
|
||||
case MESA_MOD_TLAMBDA:
|
||||
value->rValue = here->MESAtlambda;
|
||||
return (OK);
|
||||
case MESA_MOD_TETA0:
|
||||
value->rValue = here->MESAteta0;
|
||||
return (OK);
|
||||
case MESA_MOD_TETA1:
|
||||
value->rValue = here->MESAteta1;
|
||||
return (OK);
|
||||
case MESA_MOD_TMU:
|
||||
value->rValue = here->MESAtmu;
|
||||
return (OK);
|
||||
case MESA_MOD_XTM0:
|
||||
value->rValue = here->MESAxtm0;
|
||||
return (OK);
|
||||
case MESA_MOD_XTM1:
|
||||
value->rValue = here->MESAxtm1;
|
||||
return (OK);
|
||||
case MESA_MOD_XTM2:
|
||||
value->rValue = here->MESAxtm2;
|
||||
return (OK);
|
||||
case MESA_MOD_KS:
|
||||
value->rValue = here->MESAks;
|
||||
return (OK);
|
||||
case MESA_MOD_VSG:
|
||||
value->rValue = here->MESAvsg;
|
||||
return (OK);
|
||||
case MESA_MOD_LAMBDAHF:
|
||||
value->rValue = here->MESAlambdahf;
|
||||
return (OK);
|
||||
case MESA_MOD_TF:
|
||||
value->rValue = here->MESAtf;
|
||||
return (OK);
|
||||
case MESA_MOD_FLO:
|
||||
value->rValue = here->MESAflo;
|
||||
return (OK);
|
||||
case MESA_MOD_DELFO:
|
||||
value->rValue = here->MESAdelfo;
|
||||
return (OK);
|
||||
case MESA_MOD_AG:
|
||||
value->rValue = here->MESAag;
|
||||
return (OK);
|
||||
case MESA_MOD_THETA:
|
||||
value->rValue = here->MESAtheta;
|
||||
return (OK);
|
||||
case MESA_MOD_TC1:
|
||||
value->rValue = here->MESAtc1;
|
||||
return (OK);
|
||||
case MESA_MOD_TC2:
|
||||
value->rValue = here->MESAtc2;
|
||||
return (OK);
|
||||
case MESA_MOD_ZETA:
|
||||
value->rValue = here->MESAzeta;
|
||||
return (OK);
|
||||
case MESA_MOD_DU:
|
||||
value->rValue = here->MESAdu;
|
||||
return (OK);
|
||||
|
||||
|
||||
|
||||
case MESA_MOD_NDU:
|
||||
value->rValue = here->MESAndu;
|
||||
return (OK);
|
||||
case MESA_MOD_TH:
|
||||
value->rValue = here->MESAth;
|
||||
return (OK);
|
||||
case MESA_MOD_NDELTA:
|
||||
value->rValue = here->MESAndelta;
|
||||
return (OK);
|
||||
case MESA_MOD_LEVEL:
|
||||
value->rValue = here->MESAlevel;
|
||||
return (OK);
|
||||
case MESA_MOD_NMAX:
|
||||
value->rValue = here->MESAnmax;
|
||||
return (OK);
|
||||
case MESA_MOD_GAMMA:
|
||||
value->rValue = here->MESAgamma;
|
||||
return (OK);
|
||||
case MESA_MOD_EPSI:
|
||||
value->rValue = here->MESAepsi;
|
||||
return (OK);
|
||||
case MESA_MOD_CBS:
|
||||
value->rValue = here->MESAcbs;
|
||||
return (OK);
|
||||
case MESA_MOD_CAS:
|
||||
value->rValue = here->MESAcas;
|
||||
return (OK);
|
||||
case MESA_MOD_TYPE:
|
||||
if (here->MESAtype == NMF)
|
||||
value->sValue = "nmf";
|
||||
else
|
||||
value->sValue = "pmf";
|
||||
default:
|
||||
return (E_BADPARM);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 S. Hwang
|
||||
**********/
|
||||
/*
|
||||
Imported into mesa model: 2001 Paolo Nenzi
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "mesadefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
MESAmDelete(inModel,modname,kill)
|
||||
GENmodel **inModel;
|
||||
IFuid modname;
|
||||
GENmodel *kill;
|
||||
{
|
||||
MESAmodel **model = (MESAmodel**)inModel;
|
||||
MESAmodel *modfast = (MESAmodel*)kill;
|
||||
MESAinstance *here;
|
||||
MESAinstance *prev = NULL;
|
||||
MESAmodel **oldmod;
|
||||
oldmod = model;
|
||||
for( ; *model ; model = &((*model)->MESAnextModel)) {
|
||||
if( (*model)->MESAmodName == modname ||
|
||||
(modfast && *model == modfast) ) goto delgot;
|
||||
oldmod = model;
|
||||
}
|
||||
return(E_NOMOD);
|
||||
|
||||
delgot:
|
||||
*oldmod = (*model)->MESAnextModel; /* cut deleted device out of list */
|
||||
for(here = (*model)->MESAinstances ; here ; here = here->MESAnextInstance) {
|
||||
if(prev) FREE(prev);
|
||||
prev = here;
|
||||
}
|
||||
if(prev) FREE(prev);
|
||||
FREE(*model);
|
||||
return(OK);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "const.h"
|
||||
#include "ifsim.h"
|
||||
#include "mesadefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
MESAmParam(param,value,inModel)
|
||||
int param;
|
||||
IFvalue *value;
|
||||
GENmodel *inModel;
|
||||
{
|
||||
MESAmodel *model = (MESAmodel*)inModel;
|
||||
switch(param) {
|
||||
case MESA_MOD_VTO:
|
||||
model->MESAthresholdGiven = TRUE;
|
||||
model->MESAthreshold = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_BETA:
|
||||
model->MESAbetaGiven = TRUE;
|
||||
model->MESAbeta = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_VS:
|
||||
model->MESAvsGiven = TRUE;
|
||||
model->MESAvs = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_LAMBDA:
|
||||
model->MESAlambdaGiven = TRUE;
|
||||
model->MESAlambda = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_RD:
|
||||
model->MESAdrainResistGiven = TRUE;
|
||||
model->MESAdrainResist = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_RS:
|
||||
model->MESAsourceResistGiven = TRUE;
|
||||
model->MESAsourceResist = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_RG:
|
||||
model->MESAgateResistGiven = TRUE;
|
||||
model->MESAgateResist = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_RI:
|
||||
model->MESAriGiven = TRUE;
|
||||
model->MESAri = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_RF:
|
||||
model->MESArfGiven = TRUE;
|
||||
model->MESArf = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_RDI:
|
||||
model->MESArdiGiven = TRUE;
|
||||
model->MESArdi = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_RSI:
|
||||
model->MESArsiGiven = TRUE;
|
||||
model->MESArsi = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_PHIB:
|
||||
model->MESAphibGiven = TRUE;
|
||||
model->MESAphib = value->rValue*CHARGE;
|
||||
break;
|
||||
case MESA_MOD_PHIB1:
|
||||
model->MESAphib1Given = TRUE;
|
||||
model->MESAphib1 = value->rValue*CHARGE;
|
||||
break;
|
||||
case MESA_MOD_ASTAR:
|
||||
model->MESAastarGiven = TRUE;
|
||||
model->MESAastar = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_GGR:
|
||||
model->MESAggrGiven = TRUE;
|
||||
model->MESAggr = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_DEL:
|
||||
model->MESAdelGiven = TRUE;
|
||||
model->MESAdel = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_XCHI:
|
||||
model->MESAxchiGiven = TRUE;
|
||||
model->MESAxchi = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_N:
|
||||
model->MESAnGiven = TRUE;
|
||||
model->MESAn = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_ETA:
|
||||
model->MESAetaGiven = TRUE;
|
||||
model->MESAeta = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_M:
|
||||
model->MESAmGiven = TRUE;
|
||||
model->MESAm = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_MC:
|
||||
model->MESAmcGiven = TRUE;
|
||||
model->MESAmc = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_ALPHA:
|
||||
model->MESAalphaGiven = TRUE;
|
||||
model->MESAalpha = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_SIGMA0:
|
||||
model->MESAsigma0Given = TRUE;
|
||||
model->MESAsigma0 = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_VSIGMAT:
|
||||
model->MESAvsigmatGiven = TRUE;
|
||||
model->MESAvsigmat = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_VSIGMA:
|
||||
model->MESAvsigmaGiven = TRUE;
|
||||
model->MESAvsigma = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_MU:
|
||||
model->MESAmuGiven = TRUE;
|
||||
model->MESAmu = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_THETA:
|
||||
model->MESAthetaGiven = TRUE;
|
||||
model->MESAtheta = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_MU1:
|
||||
model->MESAmu1Given = TRUE;
|
||||
model->MESAmu1 = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_MU2:
|
||||
model->MESAmu2Given = TRUE;
|
||||
model->MESAmu2 = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_D:
|
||||
model->MESAdGiven = TRUE;
|
||||
model->MESAd = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_ND:
|
||||
model->MESAndGiven = TRUE;
|
||||
model->MESAnd = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_DU:
|
||||
model->MESAduGiven = TRUE;
|
||||
model->MESAdu = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_NDU:
|
||||
model->MESAnduGiven = TRUE;
|
||||
model->MESAndu = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_TH:
|
||||
model->MESAthGiven = TRUE;
|
||||
model->MESAth = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_NDELTA:
|
||||
model->MESAndeltaGiven = TRUE;
|
||||
model->MESAndelta = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_DELTA:
|
||||
model->MESAdeltaGiven = TRUE;
|
||||
model->MESAdelta = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_TC:
|
||||
model->MESAtcGiven = TRUE;
|
||||
model->MESAtc = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_NMF:
|
||||
break;
|
||||
case MESA_MOD_TVTO:
|
||||
model->MESAtvtoGiven = TRUE;
|
||||
model->MESAtvto = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_TLAMBDA:
|
||||
model->MESAtlambdaGiven = TRUE;
|
||||
model->MESAtlambda = value->rValue+CONSTCtoK;
|
||||
break;
|
||||
case MESA_MOD_TETA0:
|
||||
model->MESAteta0Given = TRUE;
|
||||
model->MESAteta0 = value->rValue+CONSTCtoK;
|
||||
break;
|
||||
case MESA_MOD_TETA1:
|
||||
model->MESAteta1Given = TRUE;
|
||||
model->MESAteta1 = value->rValue+CONSTCtoK;
|
||||
break;
|
||||
case MESA_MOD_TMU:
|
||||
model->MESAtmuGiven = TRUE;
|
||||
model->MESAtmu = value->rValue+CONSTCtoK;
|
||||
break;
|
||||
case MESA_MOD_XTM0:
|
||||
model->MESAxtm0Given = TRUE;
|
||||
model->MESAxtm0 = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_XTM1:
|
||||
model->MESAxtm1Given = TRUE;
|
||||
model->MESAxtm1 = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_XTM2:
|
||||
model->MESAxtm2Given = TRUE;
|
||||
model->MESAxtm2 = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_KS:
|
||||
model->MESAksGiven = TRUE;
|
||||
model->MESAks = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_VSG:
|
||||
model->MESAvsgGiven = TRUE;
|
||||
model->MESAvsg = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_LAMBDAHF:
|
||||
model->MESAlambdahfGiven = TRUE;
|
||||
model->MESAlambdahf = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_TF:
|
||||
model->MESAtfGiven = TRUE;
|
||||
model->MESAtf = value->rValue+CONSTCtoK;
|
||||
break;
|
||||
case MESA_MOD_FLO:
|
||||
model->MESAfloGiven = TRUE;
|
||||
model->MESAflo = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_DELFO:
|
||||
model->MESAdelfoGiven = TRUE;
|
||||
model->MESAdelfo = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_AG:
|
||||
model->MESAagGiven = TRUE;
|
||||
model->MESAag = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_TC1:
|
||||
model->MESAtc1Given = TRUE;
|
||||
model->MESAtc1 = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_TC2:
|
||||
model->MESAtc2Given = TRUE;
|
||||
model->MESAtc2 = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_ZETA:
|
||||
model->MESAzetaGiven = TRUE;
|
||||
model->MESAzeta = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_LEVEL:
|
||||
model->MESAlevelGiven = TRUE;
|
||||
model->MESAlevel = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_NMAX:
|
||||
model->MESAnmaxGiven = TRUE;
|
||||
model->MESAnmax = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_GAMMA:
|
||||
model->MESAgammaGiven = TRUE;
|
||||
model->MESAgamma = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_EPSI:
|
||||
model->MESAepsiGiven = TRUE;
|
||||
model->MESAepsi = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_CBS:
|
||||
model->MESAcbsGiven = TRUE;
|
||||
model->MESAcbs = value->rValue;
|
||||
break;
|
||||
case MESA_MOD_CAS:
|
||||
model->MESAcasGiven = TRUE;
|
||||
model->MESAcas = value->rValue;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "const.h"
|
||||
#include "ifsim.h"
|
||||
#include "mesadefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
MESAparam(param,value,inst,select)
|
||||
int param;
|
||||
IFvalue *value;
|
||||
GENinstance *inst;
|
||||
IFvalue *select;
|
||||
{
|
||||
MESAinstance *here = (MESAinstance*)inst;
|
||||
switch(param) {
|
||||
case MESA_LENGTH:
|
||||
here->MESAlength = value->rValue;
|
||||
here->MESAlengthGiven = TRUE;
|
||||
break;
|
||||
case MESA_WIDTH:
|
||||
here->MESAwidth = value->rValue;
|
||||
here->MESAwidthGiven = TRUE;
|
||||
break;
|
||||
case MESA_IC_VDS:
|
||||
here->MESAicVDS = value->rValue;
|
||||
here->MESAicVDSGiven = TRUE;
|
||||
break;
|
||||
case MESA_IC_VGS:
|
||||
here->MESAicVGS = value->rValue;
|
||||
here->MESAicVGSGiven = TRUE;
|
||||
break;
|
||||
case MESA_OFF:
|
||||
here->MESAoff = value->iValue;
|
||||
break;
|
||||
case MESA_IC:
|
||||
switch(value->v.numValue) {
|
||||
case 2:
|
||||
here->MESAicVGS = *(value->v.vec.rVec+1);
|
||||
here->MESAicVGSGiven = TRUE;
|
||||
case 1:
|
||||
here->MESAicVDS = *(value->v.vec.rVec);
|
||||
here->MESAicVDSGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
break;
|
||||
case MESA_TD:
|
||||
here->MESAtd = value->rValue+CONSTCtoK;
|
||||
here->MESAtdGiven = TRUE;
|
||||
break;
|
||||
case MESA_TS:
|
||||
here->MESAts = value->rValue+CONSTCtoK;
|
||||
here->MESAtsGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,417 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
Modified: 2001 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "smpdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "mesadefs.h"
|
||||
#include "const.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
MESAsetup(matrix,inModel,ckt,states)
|
||||
register SMPmatrix *matrix;
|
||||
register GENmodel *inModel;
|
||||
register CKTcircuit *ckt;
|
||||
int *states;
|
||||
|
||||
/* load the diode structure with those pointers needed later
|
||||
* for fast matrix loading
|
||||
*/
|
||||
{
|
||||
register MESAmodel *model = (MESAmodel*)inModel;
|
||||
register MESAinstance *here;
|
||||
int error;
|
||||
CKTnode *tmp;
|
||||
|
||||
|
||||
/* loop through all the diode models */
|
||||
for( ; model != NULL; model = model->MESAnextModel ) {
|
||||
if(!model->MESAthresholdGiven) {
|
||||
model->MESAthreshold = -1.26;
|
||||
}
|
||||
if(!model->MESAdGiven) {
|
||||
model->MESAd = 0.12e-6;
|
||||
}
|
||||
if(!model->MESAduGiven) {
|
||||
model->MESAdu = 0.035e-6;
|
||||
}
|
||||
if(!model->MESAlambdaGiven) {
|
||||
model->MESAlambda = 0.045;
|
||||
}
|
||||
if(!model->MESAvsGiven) {
|
||||
model->MESAvs = 1.5e5;
|
||||
}
|
||||
if(!model->MESAbetaGiven) {
|
||||
model->MESAbeta = 0.0085;
|
||||
}
|
||||
if(!model->MESAetaGiven) {
|
||||
model->MESAeta = 1.73;
|
||||
}
|
||||
if(!model->MESAmGiven) {
|
||||
model->MESAm = 2.5;
|
||||
}
|
||||
if(!model->MESAmcGiven) {
|
||||
model->MESAmc = 3.0;
|
||||
}
|
||||
if(!model->MESAalphaGiven) {
|
||||
model->MESAalpha = 0.0;
|
||||
}
|
||||
if(!model->MESAsigma0Given) {
|
||||
model->MESAsigma0 = 0.081;
|
||||
}
|
||||
if(!model->MESAvsigmatGiven) {
|
||||
model->MESAvsigmat = 1.01;
|
||||
}
|
||||
if(!model->MESAvsigmaGiven) {
|
||||
model->MESAvsigma = 0.1;
|
||||
}
|
||||
if(!model->MESAmuGiven) {
|
||||
model->MESAmu = 0.23;
|
||||
}
|
||||
if(!model->MESAthetaGiven) {
|
||||
model->MESAtheta = 0;
|
||||
}
|
||||
if(!model->MESAmu1Given) {
|
||||
model->MESAmu1 = 0;
|
||||
}
|
||||
if(!model->MESAmu2Given) {
|
||||
model->MESAmu2 = 0;
|
||||
}
|
||||
if(!model->MESAndGiven) {
|
||||
model->MESAnd = 2.0e23;
|
||||
}
|
||||
if(!model->MESAnduGiven) {
|
||||
model->MESAndu = 1e22;
|
||||
}
|
||||
if(!model->MESAndeltaGiven) {
|
||||
model->MESAndelta = 6e24;
|
||||
}
|
||||
if(!model->MESAthGiven) {
|
||||
model->MESAth = 0.01e-6;
|
||||
}
|
||||
if(!model->MESAdeltaGiven) {
|
||||
model->MESAdelta = 5.0;
|
||||
}
|
||||
if(!model->MESAtcGiven) {
|
||||
model->MESAtc = 0.0;
|
||||
}
|
||||
if(!model->MESAdrainResistGiven) {
|
||||
model->MESAdrainResist = 0;
|
||||
}
|
||||
if(!model->MESAsourceResistGiven) {
|
||||
model->MESAsourceResist = 0;
|
||||
}
|
||||
if(!model->MESAgateResistGiven) {
|
||||
model->MESAgateResist = 0;
|
||||
}
|
||||
if(!model->MESAriGiven) {
|
||||
model->MESAri = 0;
|
||||
}
|
||||
if(!model->MESArfGiven) {
|
||||
model->MESArf = 0;
|
||||
}
|
||||
if(!model->MESArdiGiven) {
|
||||
model->MESArdi = 0;
|
||||
}
|
||||
if(!model->MESArsiGiven) {
|
||||
model->MESArsi = 0;
|
||||
}
|
||||
if(!model->MESAphibGiven) {
|
||||
model->MESAphib = 0.5*CHARGE;
|
||||
}
|
||||
if(!model->MESAphib1Given) {
|
||||
model->MESAphib1 = 0;
|
||||
}
|
||||
if(!model->MESAastarGiven) {
|
||||
model->MESAastar = 4.0e4;
|
||||
}
|
||||
if(!model->MESAggrGiven) {
|
||||
model->MESAggr = 40;
|
||||
}
|
||||
if(!model->MESAdelGiven) {
|
||||
model->MESAdel = 0.04;
|
||||
}
|
||||
if(!model->MESAxchiGiven) {
|
||||
model->MESAxchi = 0.033;
|
||||
}
|
||||
if(!model->MESAnGiven) {
|
||||
model->MESAn = 1;
|
||||
}
|
||||
if(!model->MESAtvtoGiven) {
|
||||
model->MESAtvto = 0;
|
||||
}
|
||||
if(!model->MESAtlambdaGiven) {
|
||||
model->MESAtlambda = DBL_MAX;
|
||||
}
|
||||
if(!model->MESAteta0Given) {
|
||||
model->MESAteta0 = DBL_MAX;
|
||||
}
|
||||
if(!model->MESAteta1Given) {
|
||||
model->MESAteta1 = 0;
|
||||
}
|
||||
if(!model->MESAtmuGiven) {
|
||||
model->MESAtmu = 300.15;
|
||||
}
|
||||
if(!model->MESAxtm0Given) {
|
||||
model->MESAxtm0 = 0;
|
||||
}
|
||||
if(!model->MESAxtm1Given) {
|
||||
model->MESAxtm1 = 0;
|
||||
}
|
||||
if(!model->MESAxtm2Given) {
|
||||
model->MESAxtm2 = 0;
|
||||
}
|
||||
if(!model->MESAksGiven) {
|
||||
model->MESAks = 0;
|
||||
}
|
||||
if(!model->MESAvsgGiven) {
|
||||
model->MESAvsg = 0;
|
||||
}
|
||||
if(!model->MESAtfGiven) {
|
||||
model->MESAtf = ckt->CKTtemp;
|
||||
}
|
||||
if(!model->MESAfloGiven) {
|
||||
model->MESAflo = 0;
|
||||
}
|
||||
if(!model->MESAdelfoGiven) {
|
||||
model->MESAdelfo = 0;
|
||||
}
|
||||
if(!model->MESAagGiven) {
|
||||
model->MESAag = 0;
|
||||
}
|
||||
if(!model->MESAtc1Given) {
|
||||
model->MESAtc1 = 0;
|
||||
}
|
||||
if(!model->MESAtc2Given) {
|
||||
model->MESAtc2 = 0;
|
||||
}
|
||||
if(!model->MESAzetaGiven) {
|
||||
model->MESAzeta = 1;
|
||||
}
|
||||
if(!model->MESAlevelGiven) {
|
||||
model->MESAlevel = 2;
|
||||
}
|
||||
if(!model->MESAnmaxGiven) {
|
||||
model->MESAnmax = 2e16;
|
||||
}
|
||||
if(!model->MESAgammaGiven) {
|
||||
model->MESAgamma = 3.0;
|
||||
}
|
||||
if(!model->MESAepsiGiven) {
|
||||
model->MESAepsi = 12.244*8.85418e-12;
|
||||
}
|
||||
if(!model->MESAcasGiven) {
|
||||
model->MESAcas = 1;
|
||||
}
|
||||
if(!model->MESAcbsGiven) {
|
||||
model->MESAcbs = 1;
|
||||
}
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = model->MESAinstances; here != NULL ;
|
||||
here=here->MESAnextInstance) {
|
||||
|
||||
if(!here->MESAlengthGiven) {
|
||||
here->MESAlength = 1e-6;
|
||||
}
|
||||
if(!here->MESAwidthGiven) {
|
||||
here->MESAwidth = 20e-6;
|
||||
}
|
||||
if(!here->MESAtdGiven) {
|
||||
here->MESAtd = ckt->CKTtemp;
|
||||
}
|
||||
if(!here->MESAtsGiven) {
|
||||
here->MESAts = ckt->CKTtemp;
|
||||
}
|
||||
|
||||
here->MESAstate = *states;
|
||||
*states += 20;
|
||||
|
||||
if(model->MESAsourceResist != 0 && here->MESAsourcePrimeNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->MESAname,"source");
|
||||
if(error) return(error);
|
||||
here->MESAsourcePrimeNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->MESAsourcePrimeNode = here->MESAsourceNode;
|
||||
}
|
||||
|
||||
if(model->MESAdrainResist != 0 && here->MESAdrainPrimeNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->MESAname,"drain");
|
||||
if(error) return(error);
|
||||
here->MESAdrainPrimeNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->MESAdrainPrimeNode = here->MESAdrainNode;
|
||||
}
|
||||
if(model->MESAgateResist != 0 && here->MESAgatePrimeNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->MESAname,"gate");
|
||||
if(error) return(error);
|
||||
here->MESAgatePrimeNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
here->MESAgatePrimeNode = here->MESAgateNode;
|
||||
}
|
||||
|
||||
|
||||
if(model->MESAri != 0 && here->MESAsourcePrmPrmNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->MESAname,"gs");
|
||||
if(error) return(error);
|
||||
here->MESAsourcePrmPrmNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->MESAsourcePrmPrmNode = here->MESAsourcePrimeNode;
|
||||
}
|
||||
if(model->MESArf != 0 && here->MESAdrainPrmPrmNode==0) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->MESAname,"gd");
|
||||
if(error) return(error);
|
||||
here->MESAdrainPrmPrmNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->MESAdrainPrmPrmNode = here->MESAdrainPrimeNode;
|
||||
}
|
||||
|
||||
#define TSTALLOC(ptr,first,second) \
|
||||
if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\
|
||||
return(E_NOMEM);\
|
||||
}
|
||||
|
||||
TSTALLOC(MESAdrainDrainPtr,MESAdrainNode,MESAdrainNode)
|
||||
TSTALLOC(MESAdrainPrimeDrainPrimePtr,MESAdrainPrimeNode,MESAdrainPrimeNode)
|
||||
TSTALLOC(MESAdrainPrmPrmDrainPrmPrmPtr,MESAdrainPrmPrmNode,MESAdrainPrmPrmNode)
|
||||
TSTALLOC(MESAgateGatePtr,MESAgateNode,MESAgateNode)
|
||||
TSTALLOC(MESAgatePrimeGatePrimePtr,MESAgatePrimeNode,MESAgatePrimeNode)
|
||||
TSTALLOC(MESAsourceSourcePtr,MESAsourceNode,MESAsourceNode)
|
||||
TSTALLOC(MESAsourcePrimeSourcePrimePtr,MESAsourcePrimeNode,MESAsourcePrimeNode)
|
||||
TSTALLOC(MESAsourcePrmPrmSourcePrmPrmPtr,MESAsourcePrmPrmNode,MESAsourcePrmPrmNode)
|
||||
TSTALLOC(MESAdrainDrainPrimePtr,MESAdrainNode,MESAdrainPrimeNode)
|
||||
TSTALLOC(MESAdrainPrimeDrainPtr,MESAdrainPrimeNode,MESAdrainNode)
|
||||
TSTALLOC(MESAgatePrimeDrainPrimePtr,MESAgatePrimeNode,MESAdrainPrimeNode)
|
||||
TSTALLOC(MESAdrainPrimeGatePrimePtr,MESAdrainPrimeNode,MESAgatePrimeNode)
|
||||
TSTALLOC(MESAgatePrimeSourcePrimePtr,MESAgatePrimeNode,MESAsourcePrimeNode)
|
||||
TSTALLOC(MESAsourcePrimeGatePrimePtr,MESAsourcePrimeNode,MESAgatePrimeNode)
|
||||
TSTALLOC(MESAsourceSourcePrimePtr,MESAsourceNode,MESAsourcePrimeNode)
|
||||
TSTALLOC(MESAsourcePrimeSourcePtr,MESAsourcePrimeNode,MESAsourceNode)
|
||||
TSTALLOC(MESAdrainPrimeSourcePrimePtr,MESAdrainPrimeNode,MESAsourcePrimeNode)
|
||||
TSTALLOC(MESAsourcePrimeDrainPrimePtr,MESAsourcePrimeNode,MESAdrainPrimeNode)
|
||||
TSTALLOC(MESAgatePrimeGatePtr,MESAgatePrimeNode,MESAgateNode)
|
||||
TSTALLOC(MESAgateGatePrimePtr,MESAgateNode,MESAgatePrimeNode)
|
||||
TSTALLOC(MESAsourcePrmPrmSourcePrimePtr,MESAsourcePrmPrmNode,MESAsourcePrimeNode)
|
||||
TSTALLOC(MESAsourcePrimeSourcePrmPrmPtr,MESAsourcePrimeNode,MESAsourcePrmPrmNode)
|
||||
TSTALLOC(MESAsourcePrmPrmGatePrimePtr,MESAsourcePrmPrmNode,MESAgatePrimeNode)
|
||||
TSTALLOC(MESAgatePrimeSourcePrmPrmPtr,MESAgatePrimeNode,MESAsourcePrmPrmNode)
|
||||
TSTALLOC(MESAdrainPrmPrmDrainPrimePtr,MESAdrainPrmPrmNode,MESAdrainPrimeNode)
|
||||
TSTALLOC(MESAdrainPrimeDrainPrmPrmPtr,MESAdrainPrimeNode,MESAdrainPrmPrmNode)
|
||||
TSTALLOC(MESAdrainPrmPrmGatePrimePtr,MESAdrainPrmPrmNode,MESAgatePrimeNode)
|
||||
TSTALLOC(MESAgatePrimeDrainPrmPrmPtr,MESAgatePrimeNode,MESAdrainPrmPrmNode)
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
MESAunsetup(inModel,ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
MESAmodel *model;
|
||||
MESAinstance *here;
|
||||
|
||||
for (model = (MESAmodel *)inModel; model != NULL;
|
||||
model = model->MESAnextModel)
|
||||
{
|
||||
for (here = model->MESAinstances; here != NULL;
|
||||
here=here->MESAnextInstance)
|
||||
{
|
||||
if (here->MESAdrainPrimeNode
|
||||
&& here->MESAdrainPrimeNode != here->MESAdrainNode)
|
||||
{
|
||||
CKTdltNNum(ckt, here->MESAdrainPrimeNode);
|
||||
here->MESAdrainPrimeNode = 0;
|
||||
}
|
||||
if (here->MESAsourcePrimeNode
|
||||
&& here->MESAsourcePrimeNode != here->MESAsourceNode)
|
||||
{
|
||||
CKTdltNNum(ckt, here->MESAsourcePrimeNode);
|
||||
here->MESAsourcePrimeNode = 0;
|
||||
}
|
||||
if (here->MESAgatePrimeNode
|
||||
&& here->MESAgatePrimeNode != here->MESAgateNode)
|
||||
{
|
||||
CKTdltNNum(ckt, here->MESAgatePrimeNode);
|
||||
here->MESAgatePrimeNode = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "smpdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "mesadefs.h"
|
||||
#include "const.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
#define EPSILONGAAS (12.244*8.85418e-12)
|
||||
|
||||
int
|
||||
MESAtemp(inModel,ckt)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
{
|
||||
|
||||
register MESAmodel *model = (MESAmodel*)inModel;
|
||||
register MESAinstance *here;
|
||||
double temp;
|
||||
double vt;
|
||||
double d;
|
||||
|
||||
|
||||
for( ; model != NULL; model = model->MESAnextModel ) {
|
||||
if(!model->MESAlambdahfGiven)
|
||||
model->MESAlambdahf = model->MESAlambda;
|
||||
if(model->MESAlevel == 2)
|
||||
model->MESAvpo = CHARGE*model->MESAnd*model->MESAd*model->MESAd/
|
||||
2/EPSILONGAAS;
|
||||
else {
|
||||
model->MESAvpou = CHARGE*model->MESAndu*model->MESAdu*model->MESAdu/
|
||||
2/EPSILONGAAS;
|
||||
model->MESAvpod = CHARGE*model->MESAndelta*model->MESAth*
|
||||
(2*model->MESAdu + model->MESAth)/2/EPSILONGAAS;
|
||||
model->MESAvpo = model->MESAvpou+model->MESAvpod;
|
||||
}
|
||||
model->MESAdeltaSqr = model->MESAdelta*model->MESAdelta;
|
||||
|
||||
for (here = model->MESAinstances; here != NULL ;
|
||||
here=here->MESAnextInstance) {
|
||||
vt = CONSTKoverQ * here->MESAts;
|
||||
if(model->MESAmu1 == 0 && model->MESAmu2 == 0)
|
||||
here->MESAtMu = model->MESAmu*pow(here->MESAts/
|
||||
model->MESAtmu,model->MESAxtm0);
|
||||
else {
|
||||
double muimp = model->MESAmu*pow(here->MESAts/
|
||||
model->MESAtmu,model->MESAxtm0);
|
||||
double mupo = model->MESAmu1*pow(model->MESAtmu/
|
||||
here->MESAts,model->MESAxtm1) +
|
||||
model->MESAmu2*pow(model->MESAtmu/
|
||||
here->MESAts,model->MESAxtm2);
|
||||
here->MESAtMu = 1/(1/muimp+1/mupo);
|
||||
}
|
||||
here->MESAtTheta = model->MESAtheta;
|
||||
here->MESAtPhib = model->MESAphib-model->MESAphib1*(here->MESAts-ckt->CKTnomTemp);
|
||||
here->MESAtVto = model->MESAthreshold-model->MESAtvto*(here->MESAts-ckt->CKTnomTemp);
|
||||
here->MESAimax = CHARGE*model->MESAnmax*model->MESAvs*here->MESAwidth;
|
||||
|
||||
if(model->MESAlevel == 2)
|
||||
here->MESAgchi0 = CHARGE*here->MESAwidth/here->MESAlength;
|
||||
else
|
||||
here->MESAgchi0 = CHARGE*here->MESAwidth/here->MESAlength*here->MESAtMu;
|
||||
here->MESAbeta = 2*EPSILONGAAS*model->MESAvs*model->MESAzeta*here->MESAwidth/
|
||||
model->MESAd;
|
||||
here->MESAtEta = model->MESAeta*(1+here->MESAts/model->MESAteta0)+
|
||||
model->MESAteta1/here->MESAts;
|
||||
here->MESAtLambda= model->MESAlambda*(1-here->MESAts/model->MESAtlambda);
|
||||
here->MESAtLambdahf = model->MESAlambdahf*(1-here->MESAts/model->MESAtlambda);
|
||||
if(model->MESAlevel == 3)
|
||||
d = model->MESAdu;
|
||||
else
|
||||
d = model->MESAd;
|
||||
if(model->MESAlevel == 4)
|
||||
here->MESAn0 = model->MESAepsi*here->MESAtEta*vt/2/CHARGE/d;
|
||||
else
|
||||
here->MESAn0 = EPSILONGAAS*here->MESAtEta*vt/CHARGE/d;
|
||||
here->MESAnsb0 = EPSILONGAAS*here->MESAtEta*vt/CHARGE/
|
||||
(model->MESAdu + model->MESAth);
|
||||
here->MESAisatb0 = CHARGE*here->MESAn0*vt*
|
||||
here->MESAwidth/here->MESAlength;
|
||||
if(model->MESAlevel == 4)
|
||||
here->MESAcf = 0.5*model->MESAepsi*here->MESAwidth;
|
||||
else
|
||||
here->MESAcf = 0.5*EPSILONGAAS*here->MESAwidth;
|
||||
here->MESAcsatfs = 0.5*model->MESAastar*here->MESAts*
|
||||
here->MESAts*exp(-here->MESAtPhib/(CONSTboltz*here->MESAts))*
|
||||
here->MESAlength*here->MESAwidth;
|
||||
here->MESAcsatfd = 0.5*model->MESAastar*here->MESAtd*
|
||||
here->MESAtd*exp(-here->MESAtPhib/(CONSTboltz*here->MESAtd))*
|
||||
here->MESAlength*here->MESAwidth;
|
||||
here->MESAggrwl = model->MESAggr*here->MESAlength*here->MESAwidth*
|
||||
exp(model->MESAxchi*(here->MESAts-ckt->CKTnomTemp));
|
||||
if(here->MESAcsatfs != 0)
|
||||
here->MESAvcrits = vt*log(vt/(CONSTroot2 * here->MESAcsatfs));
|
||||
else
|
||||
here->MESAvcrits = DBL_MAX;
|
||||
if(here->MESAcsatfd != 0) {
|
||||
double vtd = CONSTKoverQ * here->MESAtd;
|
||||
here->MESAvcritd = vtd*log(vtd/(CONSTroot2 * here->MESAcsatfd));
|
||||
} else
|
||||
here->MESAvcritd = DBL_MAX;
|
||||
temp = exp(here->MESAts/model->MESAtf);
|
||||
here->MESAfl = model->MESAflo*temp;
|
||||
here->MESAdelf = model->MESAdelfo*temp;
|
||||
if(model->MESArdi != 0.0)
|
||||
here->MESAtRdi = model->MESArdi*(1+
|
||||
model->MESAtc1*(here->MESAtd-ckt->CKTnomTemp)+
|
||||
model->MESAtc2*(here->MESAtd-ckt->CKTnomTemp)*(here->MESAtd-ckt->CKTnomTemp));
|
||||
else
|
||||
here->MESAtRdi = 0;
|
||||
if(model->MESArsi != 0.0)
|
||||
here->MESAtRsi = model->MESArsi*(1+
|
||||
model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+
|
||||
model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp));
|
||||
else
|
||||
here->MESAtRsi = 0;
|
||||
if(model->MESAgateResist != 0.0)
|
||||
here->MESAtRg = model->MESAgateResist*(1+
|
||||
model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+
|
||||
model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp));
|
||||
else
|
||||
here->MESAtRg = 0;
|
||||
if(model->MESAsourceResist != 0.0)
|
||||
here->MESAtRs = model->MESAsourceResist*(1+
|
||||
model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+
|
||||
model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp));
|
||||
else
|
||||
here->MESAtRs = 0;
|
||||
if(model->MESAdrainResist != 0.0)
|
||||
here->MESAtRd = model->MESAdrainResist*(1+
|
||||
model->MESAtc1*(here->MESAtd-ckt->CKTnomTemp)+
|
||||
model->MESAtc2*(here->MESAtd-ckt->CKTnomTemp)*(here->MESAtd-ckt->CKTnomTemp));
|
||||
else
|
||||
here->MESAtRd = 0;
|
||||
if(model->MESAri != 0.0)
|
||||
here->MESAtRi = model->MESAri*(1+
|
||||
model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+
|
||||
model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp));
|
||||
else
|
||||
here->MESAtRi = 0;
|
||||
if(model->MESArf != 0.0)
|
||||
here->MESAtRf = model->MESArf*(1+
|
||||
model->MESAtc1*(here->MESAtd-ckt->CKTnomTemp)+
|
||||
model->MESAtc2*(here->MESAtd-ckt->CKTnomTemp)*(here->MESAtd-ckt->CKTnomTemp));
|
||||
else
|
||||
here->MESAtRf = 0;
|
||||
if(here->MESAtRd != 0)
|
||||
here->MESAdrainConduct = 1/here->MESAtRd;
|
||||
else
|
||||
here->MESAdrainConduct = 0;
|
||||
if(here->MESAtRs != 0)
|
||||
here->MESAsourceConduct = 1/here->MESAtRs;
|
||||
else
|
||||
here->MESAsourceConduct = 0;
|
||||
if(here->MESAtRg != 0)
|
||||
here->MESAgateConduct = 1/here->MESAtRg;
|
||||
else
|
||||
here->MESAgateConduct = 0;
|
||||
if(here->MESAtRi != 0)
|
||||
here->MESAtGi = 1/here->MESAtRi;
|
||||
else
|
||||
here->MESAtGi = 0;
|
||||
if(here->MESAtRf != 0)
|
||||
here->MESAtGf = 1/here->MESAtRf;
|
||||
else
|
||||
here->MESAtGf = 0;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/**********
|
||||
Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.
|
||||
Author: Trond Ytterdal
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "mesadefs.h"
|
||||
#include "sperror.h"
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
int
|
||||
MESAtrunc(inModel,ckt,timeStep)
|
||||
GENmodel *inModel;
|
||||
CKTcircuit *ckt;
|
||||
double *timeStep;
|
||||
{
|
||||
MESAmodel *model = (MESAmodel*)inModel;
|
||||
MESAinstance *here;
|
||||
|
||||
for( ; model != NULL; model = model->MESAnextModel) {
|
||||
for(here=model->MESAinstances;here!=NULL;here = here->MESAnextInstance){
|
||||
CKTterr(here->MESAqgs,ckt,timeStep);
|
||||
CKTterr(here->MESAqgd,ckt,timeStep);
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
Loading…
Reference in New Issue