Removed a bug in the model that caused different results in repeated analyses.

This commit is contained in:
pnenzi 2001-02-06 18:05:18 +00:00
parent 7ec1d5d3d1
commit ef0b33fdde
2 changed files with 2611 additions and 2590 deletions

File diff suppressed because it is too large Load Diff

View File

@ -27,19 +27,19 @@ File: b3set.c
#define Meter2Micron 1.0e6 #define Meter2Micron 1.0e6
int int
BSIM3setup(matrix,inModel,ckt,states) BSIM3setup (matrix, inModel, ckt, states)
SMPmatrix *matrix; SMPmatrix *matrix;
GENmodel *inModel; GENmodel *inModel;
CKTcircuit *ckt; CKTcircuit *ckt;
int *states; int *states;
{ {
BSIM3model *model = (BSIM3model*)inModel; BSIM3model *model = (BSIM3model *) inModel;
BSIM3instance *here; BSIM3instance *here;
int error; int error;
CKTnode *tmp; CKTnode *tmp;
/* loop through all the BSIM3 device models */ /* loop through all the BSIM3 device models */
for( ; model != NULL; model = model->BSIM3nextModel ) for (; model != NULL; model = model->BSIM3nextModel)
{ {
/* Default value Processing for BSIM3 MOSFET Models */ /* Default value Processing for BSIM3 MOSFET Models */
if (!model->BSIM3typeGiven) if (!model->BSIM3typeGiven)
@ -714,8 +714,8 @@ CKTnode *tmp;
/* unit degree celcius */ /* unit degree celcius */
if (!model->BSIM3tnomGiven) if (!model->BSIM3tnomGiven)
model->BSIM3tnom = ckt->CKTnomTemp; model->BSIM3tnom = ckt->CKTnomTemp;
else /* else
model->BSIM3tnom = model->BSIM3tnom + 273.15; model->BSIM3tnom = model->BSIM3tnom + 273.15; */
if (!model->BSIM3LintGiven) if (!model->BSIM3LintGiven)
model->BSIM3Lint = 0.0; model->BSIM3Lint = 0.0;
if (!model->BSIM3LlGiven) if (!model->BSIM3LlGiven)
@ -766,26 +766,31 @@ CKTnode *tmp;
model->BSIM3dlc = model->BSIM3Lint; model->BSIM3dlc = model->BSIM3Lint;
if (!model->BSIM3cfGiven) if (!model->BSIM3cfGiven)
model->BSIM3cf = 2.0 * EPSOX / M_PI model->BSIM3cf = 2.0 * EPSOX / M_PI
* log(1.0 + 0.4e-6 / model->BSIM3tox); * log (1.0 + 0.4e-6 / model->BSIM3tox);
if (!model->BSIM3cgdoGiven) if (!model->BSIM3cgdoGiven)
{ if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0)) {
{ model->BSIM3cgdo = model->BSIM3dlc * model->BSIM3cox if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0))
- model->BSIM3cgdl ; {
model->BSIM3cgdo = model->BSIM3dlc * model->BSIM3cox
- model->BSIM3cgdl;
} }
else else
model->BSIM3cgdo = 0.6 * model->BSIM3xj * model->BSIM3cox; model->BSIM3cgdo = 0.6 * model->BSIM3xj * model->BSIM3cox;
} }
if (!model->BSIM3cgsoGiven) if (!model->BSIM3cgsoGiven)
{ if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0)) {
{ model->BSIM3cgso = model->BSIM3dlc * model->BSIM3cox if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0))
- model->BSIM3cgsl ; {
model->BSIM3cgso = model->BSIM3dlc * model->BSIM3cox
- model->BSIM3cgsl;
} }
else else
model->BSIM3cgso = 0.6 * model->BSIM3xj * model->BSIM3cox; model->BSIM3cgso = 0.6 * model->BSIM3xj * model->BSIM3cox;
} }
if (!model->BSIM3cgboGiven) if (!model->BSIM3cgboGiven)
{ model->BSIM3cgbo = 2.0 * model->BSIM3dwc * model->BSIM3cox; {
model->BSIM3cgbo = 2.0 * model->BSIM3dwc * model->BSIM3cox;
} }
if (!model->BSIM3xpartGiven) if (!model->BSIM3xpartGiven)
model->BSIM3xpart = 0.0; model->BSIM3xpart = 0.0;
@ -796,7 +801,8 @@ CKTnode *tmp;
if (!model->BSIM3unitLengthSidewallJctCapGiven) if (!model->BSIM3unitLengthSidewallJctCapGiven)
model->BSIM3unitLengthSidewallJctCap = 5.0E-10; model->BSIM3unitLengthSidewallJctCap = 5.0E-10;
if (!model->BSIM3unitLengthGateSidewallJctCapGiven) if (!model->BSIM3unitLengthGateSidewallJctCapGiven)
model->BSIM3unitLengthGateSidewallJctCap = model->BSIM3unitLengthSidewallJctCap ; model->BSIM3unitLengthGateSidewallJctCap =
model->BSIM3unitLengthSidewallJctCap;
if (!model->BSIM3jctSatCurDensityGiven) if (!model->BSIM3jctSatCurDensityGiven)
model->BSIM3jctSatCurDensity = 1.0E-4; model->BSIM3jctSatCurDensity = 1.0E-4;
if (!model->BSIM3jctSidewallSatCurDensityGiven) if (!model->BSIM3jctSidewallSatCurDensityGiven)
@ -806,31 +812,36 @@ CKTnode *tmp;
if (!model->BSIM3sidewallJctPotentialGiven) if (!model->BSIM3sidewallJctPotentialGiven)
model->BSIM3sidewallJctPotential = 1.0; model->BSIM3sidewallJctPotential = 1.0;
if (!model->BSIM3GatesidewallJctPotentialGiven) if (!model->BSIM3GatesidewallJctPotentialGiven)
model->BSIM3GatesidewallJctPotential = model->BSIM3sidewallJctPotential; model->BSIM3GatesidewallJctPotential =
model->BSIM3sidewallJctPotential;
if (!model->BSIM3bulkJctBotGradingCoeffGiven) if (!model->BSIM3bulkJctBotGradingCoeffGiven)
model->BSIM3bulkJctBotGradingCoeff = 0.5; model->BSIM3bulkJctBotGradingCoeff = 0.5;
if (!model->BSIM3bulkJctSideGradingCoeffGiven) if (!model->BSIM3bulkJctSideGradingCoeffGiven)
model->BSIM3bulkJctSideGradingCoeff = 0.33; model->BSIM3bulkJctSideGradingCoeff = 0.33;
if (!model->BSIM3bulkJctGateSideGradingCoeffGiven) if (!model->BSIM3bulkJctGateSideGradingCoeffGiven)
model->BSIM3bulkJctGateSideGradingCoeff = model->BSIM3bulkJctSideGradingCoeff; model->BSIM3bulkJctGateSideGradingCoeff =
model->BSIM3bulkJctSideGradingCoeff;
if (!model->BSIM3jctEmissionCoeffGiven) if (!model->BSIM3jctEmissionCoeffGiven)
model->BSIM3jctEmissionCoeff = 1.0; model->BSIM3jctEmissionCoeff = 1.0;
if (!model->BSIM3jctTempExponentGiven) if (!model->BSIM3jctTempExponentGiven)
model->BSIM3jctTempExponent = 3.0; model->BSIM3jctTempExponent = 3.0;
if (!model->BSIM3oxideTrapDensityAGiven) if (!model->BSIM3oxideTrapDensityAGiven)
{ if (model->BSIM3type == NMOS) {
if (model->BSIM3type == NMOS)
model->BSIM3oxideTrapDensityA = 1e20; model->BSIM3oxideTrapDensityA = 1e20;
else else
model->BSIM3oxideTrapDensityA=9.9e18; model->BSIM3oxideTrapDensityA = 9.9e18;
} }
if (!model->BSIM3oxideTrapDensityBGiven) if (!model->BSIM3oxideTrapDensityBGiven)
{ if (model->BSIM3type == NMOS) {
if (model->BSIM3type == NMOS)
model->BSIM3oxideTrapDensityB = 5e4; model->BSIM3oxideTrapDensityB = 5e4;
else else
model->BSIM3oxideTrapDensityB = 2.4e3; model->BSIM3oxideTrapDensityB = 2.4e3;
} }
if (!model->BSIM3oxideTrapDensityCGiven) if (!model->BSIM3oxideTrapDensityCGiven)
{ if (model->BSIM3type == NMOS) {
if (model->BSIM3type == NMOS)
model->BSIM3oxideTrapDensityC = -1.4e-12; model->BSIM3oxideTrapDensityC = -1.4e-12;
else else
model->BSIM3oxideTrapDensityC = 1.4e-12; model->BSIM3oxideTrapDensityC = 1.4e-12;
@ -845,10 +856,11 @@ CKTnode *tmp;
if (!model->BSIM3kfGiven) if (!model->BSIM3kfGiven)
model->BSIM3kf = 0.0; model->BSIM3kf = 0.0;
/* loop through all the instances of the model */ /* loop through all the instances of the model */
for (here = model->BSIM3instances; here != NULL ; for (here = model->BSIM3instances; here != NULL;
here=here->BSIM3nextInstance) here = here->BSIM3nextInstance)
{
if (here->BSIM3owner == ARCHme)
{ {
if (here->BSIM3owner == ARCHme) {
/* allocate a chunk of the state vector */ /* allocate a chunk of the state vector */
here->BSIM3states = *states; here->BSIM3states = *states;
@ -886,60 +898,73 @@ CKTnode *tmp;
/* process drain series resistance */ /* process drain series resistance */
if ((model->BSIM3sheetResistance > 0.0) && if ((model->BSIM3sheetResistance > 0.0) &&
(here->BSIM3drainSquares > 0.0 ) && (here->BSIM3drainSquares > 0.0) && (here->BSIM3dNodePrime == 0))
(here->BSIM3dNodePrime == 0))
{ {
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain"); error = CKTmkVolt (ckt, &tmp, here->BSIM3name, "drain");
if(error) return(error); if (error)
return (error);
here->BSIM3dNodePrime = tmp->number; here->BSIM3dNodePrime = tmp->number;
if (ckt->CKTcopyNodesets) { if (ckt->CKTcopyNodesets)
{
CKTnode *tmpNode; CKTnode *tmpNode;
IFuid tmpName; IFuid tmpName;
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (CKTinst2Node (ckt, here, 1, &tmpNode, &tmpName) == OK)
if (tmpNode->nsGiven) { {
tmp->nodeset=tmpNode->nodeset; if (tmpNode->nsGiven)
tmp->nsGiven=tmpNode->nsGiven; {
tmp->nodeset = tmpNode->nodeset;
tmp->nsGiven = tmpNode->nsGiven;
} }
} }
} }
} }
else else
{ here->BSIM3dNodePrime = here->BSIM3dNode; {
here->BSIM3dNodePrime = here->BSIM3dNode;
} }
/* process source series resistance */ /* process source series resistance */
if ((model->BSIM3sheetResistance > 0.0) && if ((model->BSIM3sheetResistance > 0.0) &&
(here->BSIM3sourceSquares > 0.0 ) && (here->BSIM3sourceSquares > 0.0) &&
(here->BSIM3sNodePrime == 0)) (here->BSIM3sNodePrime == 0))
{ error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source"); {
if(error) return(error); error = CKTmkVolt (ckt, &tmp, here->BSIM3name, "source");
if (error)
return (error);
here->BSIM3sNodePrime = tmp->number; here->BSIM3sNodePrime = tmp->number;
if (ckt->CKTcopyNodesets) { if (ckt->CKTcopyNodesets)
{
CKTnode *tmpNode; CKTnode *tmpNode;
IFuid tmpName; IFuid tmpName;
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (CKTinst2Node (ckt, here, 3, &tmpNode, &tmpName) == OK)
if (tmpNode->nsGiven) { {
tmp->nodeset=tmpNode->nodeset; if (tmpNode->nsGiven)
tmp->nsGiven=tmpNode->nsGiven; {
tmp->nodeset = tmpNode->nodeset;
tmp->nsGiven = tmpNode->nsGiven;
} }
} }
} }
} }
else else
{ here->BSIM3sNodePrime = here->BSIM3sNode; {
here->BSIM3sNodePrime = here->BSIM3sNode;
} }
/* internal charge node */ /* internal charge node */
if ((here->BSIM3nqsMod) && (here->BSIM3qNode == 0)) if ((here->BSIM3nqsMod) && (here->BSIM3qNode == 0))
{ error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"charge"); {
if(error) return(error); error = CKTmkVolt (ckt, &tmp, here->BSIM3name, "charge");
if (error)
return (error);
here->BSIM3qNode = tmp->number; here->BSIM3qNode = tmp->number;
} }
else else
{ here->BSIM3qNode = 0; {
here->BSIM3qNode = 0;
} }
/* set Sparse Matrix Pointers */ /* set Sparse Matrix Pointers */
@ -950,75 +975,70 @@ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\
return(E_NOMEM);\ return(E_NOMEM);\
} }
TSTALLOC(BSIM3DdPtr, BSIM3dNode, BSIM3dNode) TSTALLOC (BSIM3DdPtr, BSIM3dNode, BSIM3dNode)
TSTALLOC(BSIM3GgPtr, BSIM3gNode, BSIM3gNode) TSTALLOC (BSIM3GgPtr, BSIM3gNode, BSIM3gNode)
TSTALLOC(BSIM3SsPtr, BSIM3sNode, BSIM3sNode) TSTALLOC (BSIM3SsPtr, BSIM3sNode, BSIM3sNode)
TSTALLOC(BSIM3BbPtr, BSIM3bNode, BSIM3bNode) TSTALLOC (BSIM3BbPtr, BSIM3bNode, BSIM3bNode)
TSTALLOC(BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime) TSTALLOC (BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime)
TSTALLOC(BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime) TSTALLOC (BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime)
TSTALLOC(BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime) TSTALLOC (BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime)
TSTALLOC(BSIM3GbPtr, BSIM3gNode, BSIM3bNode) TSTALLOC (BSIM3GbPtr, BSIM3gNode, BSIM3bNode)
TSTALLOC(BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime) TSTALLOC (BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime)
TSTALLOC(BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime) TSTALLOC (BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime)
TSTALLOC(BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime) TSTALLOC (BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime)
TSTALLOC(BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime) TSTALLOC (BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime)
TSTALLOC(BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime) TSTALLOC (BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime)
TSTALLOC(BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime) TSTALLOC (BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime)
TSTALLOC(BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode) TSTALLOC (BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode)
TSTALLOC(BSIM3BgPtr, BSIM3bNode, BSIM3gNode) TSTALLOC (BSIM3BgPtr, BSIM3bNode, BSIM3gNode)
TSTALLOC(BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode) TSTALLOC (BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode)
TSTALLOC(BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode) TSTALLOC (BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode)
TSTALLOC(BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode) TSTALLOC (BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode)
TSTALLOC(BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode) TSTALLOC (BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode)
TSTALLOC(BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode) TSTALLOC (BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode)
TSTALLOC(BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime) TSTALLOC (BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime)
TSTALLOC (BSIM3QqPtr, BSIM3qNode, BSIM3qNode)
TSTALLOC(BSIM3QqPtr, BSIM3qNode, BSIM3qNode) TSTALLOC (BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime)
TSTALLOC (BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime)
TSTALLOC(BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime) TSTALLOC (BSIM3QgPtr, BSIM3qNode, BSIM3gNode)
TSTALLOC(BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime) TSTALLOC (BSIM3QbPtr, BSIM3qNode, BSIM3bNode)
TSTALLOC(BSIM3QgPtr, BSIM3qNode, BSIM3gNode) TSTALLOC (BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode)
TSTALLOC(BSIM3QbPtr, BSIM3qNode, BSIM3bNode) TSTALLOC (BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode)
TSTALLOC(BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode) TSTALLOC (BSIM3GqPtr, BSIM3gNode, BSIM3qNode)
TSTALLOC(BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode) TSTALLOC (BSIM3BqPtr, BSIM3bNode, BSIM3qNode)}
TSTALLOC(BSIM3GqPtr, BSIM3gNode, BSIM3qNode)
TSTALLOC(BSIM3BqPtr, BSIM3bNode, BSIM3qNode)
} }
} return (OK);
return(OK);
} }
int int
BSIM3unsetup(inModel,ckt) BSIM3unsetup (inModel, ckt)
GENmodel *inModel; GENmodel *inModel;
CKTcircuit *ckt; CKTcircuit *ckt;
{ {
BSIM3model *model; BSIM3model *model;
BSIM3instance *here; BSIM3instance *here;
for (model = (BSIM3model *)inModel; model != NULL; for (model = (BSIM3model *) inModel; model != NULL;
model = model->BSIM3nextModel) model = model->BSIM3nextModel)
{ {
for (here = model->BSIM3instances; here != NULL; for (here = model->BSIM3instances; here != NULL;
here=here->BSIM3nextInstance) here = here->BSIM3nextInstance)
{ {
if (here->BSIM3dNodePrime if (here->BSIM3dNodePrime
&& here->BSIM3dNodePrime != here->BSIM3dNode) && here->BSIM3dNodePrime != here->BSIM3dNode)
{ {
CKTdltNNum(ckt, here->BSIM3dNodePrime); CKTdltNNum (ckt, here->BSIM3dNodePrime);
here->BSIM3dNodePrime = 0; here->BSIM3dNodePrime = 0;
} }
if (here->BSIM3sNodePrime if (here->BSIM3sNodePrime
&& here->BSIM3sNodePrime != here->BSIM3sNode) && here->BSIM3sNodePrime != here->BSIM3sNode)
{ {
CKTdltNNum(ckt, here->BSIM3sNodePrime); CKTdltNNum (ckt, here->BSIM3sNodePrime);
here->BSIM3sNodePrime = 0; here->BSIM3sNodePrime = 0;
} }
} }
} }
return OK; return OK;
} }