You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

305 lines
9.4 KiB

/**********
Copyright 1991 Regents of the University of California. All rights reserved.
Author: 1991 David A. Gates, U. C. Berkeley CAD Group
Modified: 2001 Paolo Nenzi
**********/
#include "ngspice/ngspice.h"
#include "ngspice/numcards.h"
#include "ngspice/numgen.h"
#include "ngspice/numenum.h"
#include "ngspice/matldefs.h"
#include "ngspice/devdefs.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
extern int MATLnewCard(GENcard**,GENmodel *);
extern int MATLparam(int,IFvalue*,GENcard *);
IFparm MATLpTable[] = {
IP("number", MATL_NUMBER, IF_INTEGER, "Material ID number"),
IP("insulator",MATL_INSULATOR,IF_FLAG, "Insulator"),
IP("oxide", MATL_OXIDE, IF_FLAG, "Oxide"),
IP("sio2", MATL_OXIDE, IF_FLAG, "Oxide"),
IP("nitride", MATL_NITRIDE, IF_FLAG, "Nitride"),
IP("si3n4", MATL_NITRIDE, IF_FLAG, "Nitride"),
IP("semiconductor",MATL_SEMICON,IF_FLAG, "Semiconductor"),
IP("silicon", MATL_SILICON, IF_FLAG, "Silicon"),
IP("polysilicon",MATL_POLYSIL,IF_FLAG, "Polysilicon"),
IP("gaas", MATL_GAAS, IF_FLAG, "Gallium-Arsenide"),
IP("nc", MATL_NC0, IF_REAL, "Conduction band density"),
IP("nc0", MATL_NC0, IF_REAL, "Conduction band density"),
IP("nc300", MATL_NC0, IF_REAL, "Conduction band density"),
IP("nv", MATL_NV0, IF_REAL, "Valence band density"),
IP("nv0", MATL_NV0, IF_REAL, "Valence band density"),
IP("nv300", MATL_NV0, IF_REAL, "Valence band density"),
IP("eg", MATL_EG0, IF_REAL, "Energy gap"),
IP("eg0", MATL_EG0, IF_REAL, "Energy gap"),
IP("eg300", MATL_EG0, IF_REAL, "Energy gap"),
IP("deg.dt", MATL_DEGDT, IF_REAL, "Bandgap narrowing w/ temp"),
IP("egalpha", MATL_DEGDT, IF_REAL, "Bandgap narrowing w/ temp"),
IP("eg.tref", MATL_TREF_EG, IF_REAL, "E-gap reference temperature"),
IP("egbeta", MATL_TREF_EG, IF_REAL, "E-gap reference temperature"),
IP("deg.dc", MATL_DEGDC, IF_REAL, "Bandgap narrowing w/ N&P doping"),
IP("eg.cref", MATL_CREF_EG, IF_REAL, "E-gap reference conc (N&P type)"),
IP("nbgn", MATL_CREF_EG, IF_REAL, "E-gap reference conc (N&P type)"),
IP("deg.dn", MATL_DEGDN, IF_REAL, "Bandgap narrowing w/ N doping"),
IP("eg.nref", MATL_NREF_EG, IF_REAL, "E-gap reference conc (N type)"),
IP("nbgnn", MATL_NREF_EG, IF_REAL, "E-gap reference conc (N type)"),
IP("deg.dp", MATL_DEGDP, IF_REAL, "Bandgap narrowing w/ P doping"),
IP("eg.pref", MATL_PREF_EG, IF_REAL, "E-gap reference conc (P type)"),
IP("nbgnp", MATL_PREF_EG, IF_REAL, "E-gap reference conc (P type)"),
IP("affinity",MATL_AFFIN, IF_REAL, "Electron affinity"),
IP("permittivity",MATL_PERMIT,IF_REAL, "Dielectric permittivity"),
IP("epsilon", MATL_PERMIT, IF_REAL, "Dielectric permittivity"),
IP("tn", MATL_TAUN0, IF_REAL, "SRH electron lifetime"),
IP("tn0", MATL_TAUN0, IF_REAL, "SRH electron lifetime"),
IP("taun0", MATL_TAUN0, IF_REAL, "SRH electron lifetime"),
IP("tp", MATL_TAUP0, IF_REAL, "SRH hole lifetime"),
IP("tp0", MATL_TAUP0, IF_REAL, "SRH hole lifetime"),
IP("taup0", MATL_TAUP0, IF_REAL, "SRH hole lifetime"),
IP("nsrhn", MATL_NSRHN, IF_REAL, "SRH reference conc (electrons)"),
IP("srh.nref",MATL_NSRHN, IF_REAL, "SRH reference conc (electrons)"),
IP("nsrhp", MATL_NSRHP, IF_REAL, "SRH reference conc (holes)"),
IP("srh.pref",MATL_NSRHP, IF_REAL, "SRH reference conc (holes)"),
IP("cn", MATL_CNAUG, IF_REAL, "Auger coefficient (electrons)"),
IP("cnaug", MATL_CNAUG, IF_REAL, "Auger coefficient (electrons)"),
IP("augn", MATL_CNAUG, IF_REAL, "Auger coefficient (electrons)"),
IP("cp", MATL_CPAUG, IF_REAL, "Auger coefficient (holes)"),
IP("cpaug", MATL_CPAUG, IF_REAL, "Auger coefficient (holes)"),
IP("augp", MATL_CPAUG, IF_REAL, "Auger coefficient (holes)"),
IP("arichn", MATL_ARICHN, IF_REAL, "Richardson constant (electrons)"),
IP("arichp", MATL_ARICHP, IF_REAL, "Richardson constant (holes)")
};
IFcardInfo MATLinfo = {
"material",
"Specify physical properties of a material",
NUMELEMS(MATLpTable),
MATLpTable,
MATLnewCard,
MATLparam,
NULL
};
IFcardInfo PHYSinfo = {
"physics",
"Specify physical properties of a material",
NUMELEMS(MATLpTable),
MATLpTable,
MATLnewCard,
MATLparam,
NULL
};
int
MATLnewCard(GENcard **inCard, GENmodel *inModel)
{
MATLcard *tmpCard, *newCard;
GENnumModel *model = (GENnumModel *)inModel;
newCard = NEW( MATLcard );
if (!newCard) {
*inCard = NULL;
return(E_NOMEM);
}
newCard->MATLnextCard = NULL;
*inCard = (GENcard *) newCard;
tmpCard = model->GENmaterials;
if (!tmpCard) { /* First in list */
model->GENmaterials = newCard;
} else {
/* Go to end of list */
while (tmpCard->MATLnextCard) tmpCard = tmpCard->MATLnextCard;
/* And add new card */
tmpCard->MATLnextCard = newCard;
}
return(OK);
}
int
MATLparam(int param, IFvalue *value, GENcard *inCard)
{
MATLcard *card = (MATLcard *)inCard;
switch (param) {
case MATL_NUMBER:
card->MATLnumber = value->iValue;
card->MATLnumberGiven = TRUE;
break;
case MATL_NC0:
card->MATLnc0 = value->rValue;
card->MATLnc0Given = TRUE;
break;
case MATL_NV0:
card->MATLnv0 = value->rValue;
card->MATLnv0Given = TRUE;
break;
case MATL_EG0:
card->MATLeg0 = value->rValue;
card->MATLeg0Given = TRUE;
break;
case MATL_DEGDT:
card->MATLdEgdT = value->rValue;
card->MATLdEgdTGiven = TRUE;
break;
case MATL_TREF_EG:
card->MATLtrefEg = value->rValue;
card->MATLtrefEgGiven = TRUE;
break;
case MATL_DEGDC:
card->MATLdEgdN = value->rValue;
card->MATLdEgdNGiven = TRUE;
card->MATLdEgdP = value->rValue;
card->MATLdEgdPGiven = TRUE;
break;
case MATL_CREF_EG:
card->MATLnrefEg = value->rValue;
card->MATLnrefEgGiven = TRUE;
card->MATLprefEg = value->rValue;
card->MATLprefEgGiven = TRUE;
break;
case MATL_DEGDN:
card->MATLdEgdN = value->rValue;
card->MATLdEgdNGiven = TRUE;
break;
case MATL_NREF_EG:
card->MATLnrefEg = value->rValue;
card->MATLnrefEgGiven = TRUE;
break;
case MATL_DEGDP:
card->MATLdEgdP = value->rValue;
card->MATLdEgdPGiven = TRUE;
break;
case MATL_PREF_EG:
card->MATLprefEg = value->rValue;
card->MATLprefEgGiven = TRUE;
break;
case MATL_AFFIN:
card->MATLaffinity = value->rValue;
card->MATLaffinityGiven = TRUE;
break;
case MATL_PERMIT:
card->MATLpermittivity = value->rValue;
card->MATLpermittivityGiven = TRUE;
break;
case MATL_TAUN0:
card->MATLtaun0 = value->rValue;
card->MATLtaun0Given = TRUE;
break;
case MATL_TAUP0:
card->MATLtaup0 = value->rValue;
card->MATLtaup0Given = TRUE;
break;
case MATL_NSRHN:
card->MATLnrefSRHn = value->rValue;
card->MATLnrefSRHnGiven = TRUE;
break;
case MATL_NSRHP:
card->MATLnrefSRHp = value->rValue;
card->MATLnrefSRHpGiven = TRUE;
break;
case MATL_CNAUG:
card->MATLcnAug = value->rValue;
card->MATLcnAugGiven = TRUE;
break;
case MATL_CPAUG:
card->MATLcpAug = value->rValue;
card->MATLcpAugGiven = TRUE;
break;
case MATL_ARICHN:
card->MATLaRichN = value->rValue;
card->MATLaRichNGiven = TRUE;
break;
case MATL_ARICHP:
card->MATLaRichP = value->rValue;
card->MATLaRichPGiven = TRUE;
break;
case MATL_INSULATOR:
if ( value->iValue ) {
card->MATLmaterial = INSULATOR;
card->MATLmaterialGiven = TRUE;
} else {
if ( card->MATLmaterial == INSULATOR ) {
card->MATLmaterial = -1;
card->MATLmaterialGiven = FALSE;
}
}
break;
case MATL_OXIDE:
if ( value->iValue ) {
card->MATLmaterial = OXIDE;
card->MATLmaterialGiven = TRUE;
} else {
if ( card->MATLmaterial == OXIDE ) {
card->MATLmaterial = -1;
card->MATLmaterialGiven = FALSE;
}
}
break;
case MATL_NITRIDE:
if ( value->iValue ) {
card->MATLmaterial = NITRIDE;
card->MATLmaterialGiven = TRUE;
} else {
if ( card->MATLmaterial == NITRIDE ) {
card->MATLmaterial = -1;
card->MATLmaterialGiven = FALSE;
}
}
break;
case MATL_SEMICON:
if ( value->iValue ) {
card->MATLmaterial = SEMICON;
card->MATLmaterialGiven = TRUE;
} else {
if ( card->MATLmaterial == SEMICON ) {
card->MATLmaterial = -1;
card->MATLmaterialGiven = FALSE;
}
}
break;
case MATL_SILICON:
if ( value->iValue ) {
card->MATLmaterial = SILICON;
card->MATLmaterialGiven = TRUE;
} else {
if ( card->MATLmaterial == SILICON ) {
card->MATLmaterial = -1;
card->MATLmaterialGiven = FALSE;
}
}
break;
case MATL_POLYSIL:
if ( value->iValue ) {
card->MATLmaterial = POLYSILICON;
card->MATLmaterialGiven = TRUE;
} else {
if ( card->MATLmaterial == POLYSILICON ) {
card->MATLmaterial = -1;
card->MATLmaterialGiven = FALSE;
}
}
break;
case MATL_GAAS:
if ( value->iValue ) {
card->MATLmaterial = GAAS;
card->MATLmaterialGiven = TRUE;
} else {
if ( card->MATLmaterial == GAAS ) {
card->MATLmaterial = -1;
card->MATLmaterialGiven = FALSE;
}
}
break;
default:
return(E_BADPARM);
break;
}
return(OK);
}