diff --git a/ChangeLog b/ChangeLog
index 099a65b6d..f760862f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,14 @@
* Updated and corrected test files in "tests" directory. Added
"examples" directory.
+
+ * src/spicelib/devices/bsim3/b3set.c: Added Dietmar Warning patch
+ to solve a bug that shows up when acm=2 was used. From Dietmar's
+ mail:
+ if we use the acm=2 option we must set the nrd and nrs
+ defaults to 0.
+
2004-07-08 Paolo Nenzi
* Applied Al Niessner negabyte patch
diff --git a/src/spicelib/devices/bsim3/b3set.c b/src/spicelib/devices/bsim3/b3set.c
index bf9ea062b..6cdf86ef7 100644
--- a/src/spicelib/devices/bsim3/b3set.c
+++ b/src/spicelib/devices/bsim3/b3set.c
@@ -28,7 +28,7 @@
int
BSIM3setup (SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
- int *states)
+ int *states)
{
BSIM3model *model = (BSIM3model*)inModel;
BSIM3instance *here;
@@ -53,35 +53,35 @@ IFuid tmpName;
if (!model->BSIM3capModGiven)
model->BSIM3capMod = 3;
if (!model->BSIM3acmModGiven)
- model->BSIM3acmMod = 0;
+ model->BSIM3acmMod = 0;
if (!model->BSIM3noiModGiven)
model->BSIM3noiMod = 1;
- /* If the user does not provide the model revision,
- * we always choose the most recent.
- */
- if (!model->BSIM3versionGiven)
- model->BSIM3version = "3.2.4";
+ /* If the user does not provide the model revision,
+ * we always choose the most recent.
+ */
+ if (!model->BSIM3versionGiven)
+ model->BSIM3version = "3.2.4";
- /* I have added below the code that translate model string
- * into an integer. This trick is meant to speed up the
- * revision testing instruction, since comparing integer
- * is faster than comparing strings.
- * Paolo Nenzi 2002
- */
- if (!strcmp (model->BSIM3version, "3.2.4"))
- model->BSIM3intVersion = BSIM3V324;
- else if (!strcmp (model->BSIM3version, "3.2.3"))
- model->BSIM3intVersion = BSIM3V323;
- else if (!strcmp (model->BSIM3version, "3.2.2"))
- model->BSIM3intVersion = BSIM3V322;
- else if (!strcmp (model->BSIM3version, "3.2"))
- model->BSIM3intVersion = BSIM3V32;
- else
- model->BSIM3intVersion = BSIM3V3OLD;
- /* BSIM3V3OLD is a placeholder for pre 3.2 revision
- * This model should not be used for pre 3.2 models.
- */
+ /* I have added below the code that translate model string
+ * into an integer. This trick is meant to speed up the
+ * revision testing instruction, since comparing integer
+ * is faster than comparing strings.
+ * Paolo Nenzi 2002
+ */
+ if (!strcmp (model->BSIM3version, "3.2.4"))
+ model->BSIM3intVersion = BSIM3V324;
+ else if (!strcmp (model->BSIM3version, "3.2.3"))
+ model->BSIM3intVersion = BSIM3V323;
+ else if (!strcmp (model->BSIM3version, "3.2.2"))
+ model->BSIM3intVersion = BSIM3V322;
+ else if (!strcmp (model->BSIM3version, "3.2"))
+ model->BSIM3intVersion = BSIM3V32;
+ else
+ model->BSIM3intVersion = BSIM3V3OLD;
+ /* BSIM3V3OLD is a placeholder for pre 3.2 revision
+ * This model should not be used for pre 3.2 models.
+ */
if (!model->BSIM3toxGiven)
model->BSIM3tox = 150.0e-10;
@@ -90,15 +90,15 @@ IFuid tmpName;
model->BSIM3toxm = model->BSIM3tox;
if (!model->BSIM3cdscGiven)
- model->BSIM3cdsc = 2.4e-4; /* unit Q/V/m^2 */
+ model->BSIM3cdsc = 2.4e-4; /* unit Q/V/m^2 */
if (!model->BSIM3cdscbGiven)
- model->BSIM3cdscb = 0.0; /* unit Q/V/m^2 */
- if (!model->BSIM3cdscdGiven)
- model->BSIM3cdscd = 0.0; /* unit Q/V/m^2 */
+ model->BSIM3cdscb = 0.0; /* unit Q/V/m^2 */
+ if (!model->BSIM3cdscdGiven)
+ model->BSIM3cdscd = 0.0; /* unit Q/V/m^2 */
if (!model->BSIM3citGiven)
- model->BSIM3cit = 0.0; /* unit Q/V/m^2 */
+ model->BSIM3cit = 0.0; /* unit Q/V/m^2 */
if (!model->BSIM3nfactorGiven)
- model->BSIM3nfactor = 1;
+ model->BSIM3nfactor = 1;
if (!model->BSIM3xjGiven)
model->BSIM3xj = .15e-6;
if (!model->BSIM3vsatGiven)
@@ -122,9 +122,9 @@ IFuid tmpName;
if (!model->BSIM3ngateGiven)
model->BSIM3ngate = 0; /* unit 1/cm3 */
if (!model->BSIM3vbmGiven)
- model->BSIM3vbm = -3.0;
+ model->BSIM3vbm = -3.0;
if (!model->BSIM3xtGiven)
- model->BSIM3xt = 1.55e-7;
+ model->BSIM3xt = 1.55e-7;
if (!model->BSIM3kt1Given)
model->BSIM3kt1 = -0.11; /* unit V */
if (!model->BSIM3kt1lGiven)
@@ -174,9 +174,9 @@ IFuid tmpName;
if (!model->BSIM3u0Given)
model->BSIM3u0 = (model->BSIM3type == NMOS) ? 0.067 : 0.025;
if (!model->BSIM3uteGiven)
- model->BSIM3ute = -1.5;
+ model->BSIM3ute = -1.5;
if (!model->BSIM3voffGiven)
- model->BSIM3voff = -0.08;
+ model->BSIM3voff = -0.08;
if (!model->BSIM3deltaGiven)
model->BSIM3delta = 0.01;
if (!model->BSIM3rdswGiven)
@@ -262,31 +262,31 @@ IFuid tmpName;
/* acm model */
if (!model->BSIM3hdifGiven)
- model->BSIM3hdif = 0.0;
+ model->BSIM3hdif = 0.0;
if (!model->BSIM3ldifGiven)
- model->BSIM3ldif = 0.0;
+ model->BSIM3ldif = 0.0;
if (!model->BSIM3ldGiven)
- model->BSIM3ld = 0.0;
+ model->BSIM3ld = 0.0;
if (!model->BSIM3rdGiven)
- model->BSIM3rd = 0.0;
+ model->BSIM3rd = 0.0;
if (!model->BSIM3rsGiven)
- model->BSIM3rs = 0.0;
+ model->BSIM3rs = 0.0;
if (!model->BSIM3rdcGiven)
- model->BSIM3rdc = 0.0;
+ model->BSIM3rdc = 0.0;
if (!model->BSIM3rscGiven)
- model->BSIM3rsc = 0.0;
+ model->BSIM3rsc = 0.0;
- /* Length dependence */
+ /* Length dependence */
if (!model->BSIM3lcdscGiven)
- model->BSIM3lcdsc = 0.0;
+ model->BSIM3lcdsc = 0.0;
if (!model->BSIM3lcdscbGiven)
- model->BSIM3lcdscb = 0.0;
- if (!model->BSIM3lcdscdGiven)
- model->BSIM3lcdscd = 0.0;
+ model->BSIM3lcdscb = 0.0;
+ if (!model->BSIM3lcdscdGiven)
+ model->BSIM3lcdscd = 0.0;
if (!model->BSIM3lcitGiven)
- model->BSIM3lcit = 0.0;
+ model->BSIM3lcit = 0.0;
if (!model->BSIM3lnfactorGiven)
- model->BSIM3lnfactor = 0.0;
+ model->BSIM3lnfactor = 0.0;
if (!model->BSIM3lxjGiven)
model->BSIM3lxj = 0.0;
if (!model->BSIM3lvsatGiven)
@@ -310,9 +310,9 @@ IFuid tmpName;
if (!model->BSIM3lngateGiven)
model->BSIM3lngate = 0.0;
if (!model->BSIM3lvbmGiven)
- model->BSIM3lvbm = 0.0;
+ model->BSIM3lvbm = 0.0;
if (!model->BSIM3lxtGiven)
- model->BSIM3lxt = 0.0;
+ model->BSIM3lxt = 0.0;
if (!model->BSIM3lkt1Given)
model->BSIM3lkt1 = 0.0;
if (!model->BSIM3lkt1lGiven)
@@ -360,9 +360,9 @@ IFuid tmpName;
if (!model->BSIM3lu0Given)
model->BSIM3lu0 = 0.0;
if (!model->BSIM3luteGiven)
- model->BSIM3lute = 0.0;
+ model->BSIM3lute = 0.0;
if (!model->BSIM3lvoffGiven)
- model->BSIM3lvoff = 0.0;
+ model->BSIM3lvoff = 0.0;
if (!model->BSIM3ldeltaGiven)
model->BSIM3ldelta = 0.0;
if (!model->BSIM3lrdswGiven)
@@ -435,17 +435,17 @@ IFuid tmpName;
if (!model->BSIM3lvoffcvGiven)
model->BSIM3lvoffcv = 0.0;
- /* Width dependence */
+ /* Width dependence */
if (!model->BSIM3wcdscGiven)
- model->BSIM3wcdsc = 0.0;
+ model->BSIM3wcdsc = 0.0;
if (!model->BSIM3wcdscbGiven)
- model->BSIM3wcdscb = 0.0;
- if (!model->BSIM3wcdscdGiven)
- model->BSIM3wcdscd = 0.0;
+ model->BSIM3wcdscb = 0.0;
+ if (!model->BSIM3wcdscdGiven)
+ model->BSIM3wcdscd = 0.0;
if (!model->BSIM3wcitGiven)
- model->BSIM3wcit = 0.0;
+ model->BSIM3wcit = 0.0;
if (!model->BSIM3wnfactorGiven)
- model->BSIM3wnfactor = 0.0;
+ model->BSIM3wnfactor = 0.0;
if (!model->BSIM3wxjGiven)
model->BSIM3wxj = 0.0;
if (!model->BSIM3wvsatGiven)
@@ -469,9 +469,9 @@ IFuid tmpName;
if (!model->BSIM3wngateGiven)
model->BSIM3wngate = 0.0;
if (!model->BSIM3wvbmGiven)
- model->BSIM3wvbm = 0.0;
+ model->BSIM3wvbm = 0.0;
if (!model->BSIM3wxtGiven)
- model->BSIM3wxt = 0.0;
+ model->BSIM3wxt = 0.0;
if (!model->BSIM3wkt1Given)
model->BSIM3wkt1 = 0.0;
if (!model->BSIM3wkt1lGiven)
@@ -519,9 +519,9 @@ IFuid tmpName;
if (!model->BSIM3wu0Given)
model->BSIM3wu0 = 0.0;
if (!model->BSIM3wuteGiven)
- model->BSIM3wute = 0.0;
+ model->BSIM3wute = 0.0;
if (!model->BSIM3wvoffGiven)
- model->BSIM3wvoff = 0.0;
+ model->BSIM3wvoff = 0.0;
if (!model->BSIM3wdeltaGiven)
model->BSIM3wdelta = 0.0;
if (!model->BSIM3wrdswGiven)
@@ -594,17 +594,17 @@ IFuid tmpName;
if (!model->BSIM3wvoffcvGiven)
model->BSIM3wvoffcv = 0.0;
- /* Cross-term dependence */
+ /* Cross-term dependence */
if (!model->BSIM3pcdscGiven)
- model->BSIM3pcdsc = 0.0;
+ model->BSIM3pcdsc = 0.0;
if (!model->BSIM3pcdscbGiven)
- model->BSIM3pcdscb = 0.0;
- if (!model->BSIM3pcdscdGiven)
- model->BSIM3pcdscd = 0.0;
+ model->BSIM3pcdscb = 0.0;
+ if (!model->BSIM3pcdscdGiven)
+ model->BSIM3pcdscd = 0.0;
if (!model->BSIM3pcitGiven)
- model->BSIM3pcit = 0.0;
+ model->BSIM3pcit = 0.0;
if (!model->BSIM3pnfactorGiven)
- model->BSIM3pnfactor = 0.0;
+ model->BSIM3pnfactor = 0.0;
if (!model->BSIM3pxjGiven)
model->BSIM3pxj = 0.0;
if (!model->BSIM3pvsatGiven)
@@ -629,9 +629,9 @@ IFuid tmpName;
if (!model->BSIM3pngateGiven)
model->BSIM3pngate = 0.0;
if (!model->BSIM3pvbmGiven)
- model->BSIM3pvbm = 0.0;
+ model->BSIM3pvbm = 0.0;
if (!model->BSIM3pxtGiven)
- model->BSIM3pxt = 0.0;
+ model->BSIM3pxt = 0.0;
if (!model->BSIM3pkt1Given)
model->BSIM3pkt1 = 0.0;
if (!model->BSIM3pkt1lGiven)
@@ -679,9 +679,9 @@ IFuid tmpName;
if (!model->BSIM3pu0Given)
model->BSIM3pu0 = 0.0;
if (!model->BSIM3puteGiven)
- model->BSIM3pute = 0.0;
+ model->BSIM3pute = 0.0;
if (!model->BSIM3pvoffGiven)
- model->BSIM3pvoff = 0.0;
+ model->BSIM3pvoff = 0.0;
if (!model->BSIM3pdeltaGiven)
model->BSIM3pdelta = 0.0;
if (!model->BSIM3prdswGiven)
@@ -756,7 +756,9 @@ IFuid tmpName;
/* unit degree celcius */
if (!model->BSIM3tnomGiven)
- model->BSIM3tnom = ckt->CKTnomTemp;
+ model->BSIM3tnom = ckt->CKTnomTemp;
+/* else
+ model->BSIM3tnom = model->BSIM3tnom + 273.15; */
if (!model->BSIM3LintGiven)
model->BSIM3Lint = 0.0;
if (!model->BSIM3LlGiven)
@@ -807,33 +809,33 @@ IFuid tmpName;
model->BSIM3dlc = model->BSIM3Lint;
if (!model->BSIM3xlGiven)
- model->BSIM3xl = 0.0;
+ model->BSIM3xl = 0.0;
if (!model->BSIM3xwGiven)
- model->BSIM3xw = 0.0;
+ model->BSIM3xw = 0.0;
- if (!model->BSIM3cfGiven)
+ if (!model->BSIM3cfGiven)
model->BSIM3cf = 2.0 * EPSOX / PI
- * log(1.0 + 0.4e-6 / model->BSIM3tox);
+ * log(1.0 + 0.4e-6 / model->BSIM3tox);
if (!model->BSIM3cgdoGiven)
- { if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0))
- { model->BSIM3cgdo = model->BSIM3dlc * model->BSIM3cox
- - model->BSIM3cgdl ;
- }
- else
- model->BSIM3cgdo = 0.6 * model->BSIM3xj * model->BSIM3cox;
- }
+ { if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0))
+ { model->BSIM3cgdo = model->BSIM3dlc * model->BSIM3cox
+ - model->BSIM3cgdl ;
+ }
+ else
+ model->BSIM3cgdo = 0.6 * model->BSIM3xj * model->BSIM3cox;
+ }
if (!model->BSIM3cgsoGiven)
- { if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0))
- { model->BSIM3cgso = model->BSIM3dlc * model->BSIM3cox
- - model->BSIM3cgsl ;
- }
- else
- model->BSIM3cgso = 0.6 * model->BSIM3xj * model->BSIM3cox;
- }
+ { if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0))
+ { model->BSIM3cgso = model->BSIM3dlc * model->BSIM3cox
+ - model->BSIM3cgsl ;
+ }
+ else
+ model->BSIM3cgso = 0.6 * model->BSIM3xj * model->BSIM3cox;
+ }
if (!model->BSIM3cgboGiven)
- { model->BSIM3cgbo = 2.0 * model->BSIM3dwc * model->BSIM3cox;
- }
+ { model->BSIM3cgbo = 2.0 * model->BSIM3dwc * model->BSIM3cox;
+ }
if (!model->BSIM3xpartGiven)
model->BSIM3xpart = 0.0;
if (!model->BSIM3sheetResistanceGiven)
@@ -865,24 +867,24 @@ IFuid tmpName;
if (!model->BSIM3jctTempExponentGiven)
model->BSIM3jctTempExponent = 3.0;
if (!model->BSIM3oxideTrapDensityAGiven)
- { if (model->BSIM3type == NMOS)
+ { if (model->BSIM3type == NMOS)
model->BSIM3oxideTrapDensityA = 1e20;
else
model->BSIM3oxideTrapDensityA=9.9e18;
- }
+ }
if (!model->BSIM3oxideTrapDensityBGiven)
- { if (model->BSIM3type == NMOS)
+ { if (model->BSIM3type == NMOS)
model->BSIM3oxideTrapDensityB = 5e4;
else
model->BSIM3oxideTrapDensityB = 2.4e3;
- }
+ }
if (!model->BSIM3oxideTrapDensityCGiven)
- { if (model->BSIM3type == NMOS)
+ { if (model->BSIM3type == NMOS)
model->BSIM3oxideTrapDensityC = -1.4e-12;
else
model->BSIM3oxideTrapDensityC = 1.4e-12;
- }
+ }
if (!model->BSIM3emGiven)
model->BSIM3em = 4.1e7; /* V/m */
if (!model->BSIM3efGiven)
@@ -894,13 +896,13 @@ IFuid tmpName;
/* loop through all the instances of the model */
for (here = model->BSIM3instances; here != NULL ;
here=here->BSIM3nextInstance)
- {
- if (here->BSIM3owner == ARCHme)
- {
- /* allocate a chunk of the state vector */
- here->BSIM3states = *states;
- *states += BSIM3numStates;
- }
+ {
+ if (here->BSIM3owner == ARCHme)
+ {
+ /* allocate a chunk of the state vector */
+ here->BSIM3states = *states;
+ *states += BSIM3numStates;
+ }
/* perform the parameter defaulting */
if (!here->BSIM3drainAreaGiven)
@@ -908,7 +910,10 @@ IFuid tmpName;
if (!here->BSIM3drainPerimeterGiven)
here->BSIM3drainPerimeter = 0.0;
if (!here->BSIM3drainSquaresGiven)
- here->BSIM3drainSquares = 1.0;
+ if (model->BSIM3acmMod == 0)
+ here->BSIM3drainSquares = 1.0;
+ else
+ here->BSIM3drainSquares = 0.0;
if (!here->BSIM3icVBSGiven)
here->BSIM3icVBS = 0.0;
if (!here->BSIM3icVDSGiven)
@@ -922,30 +927,32 @@ IFuid tmpName;
if (!here->BSIM3sourcePerimeterGiven)
here->BSIM3sourcePerimeter = 0.0;
if (!here->BSIM3sourceSquaresGiven)
- here->BSIM3sourceSquares = 1.0;
+ if (model->BSIM3acmMod == 0)
+ here->BSIM3sourceSquares = 1.0;
+ else
+ here->BSIM3sourceSquares = 0.0;
if (!here->BSIM3wGiven)
here->BSIM3w = 5.0e-6;
if (!here->BSIM3nqsModGiven)
here->BSIM3nqsMod = 0;
- if (!here->BSIM3mGiven)
- here->BSIM3m = 1;
+ if (!here->BSIM3mGiven)
+ here->BSIM3m = 1;
/* process drain series resistance */
- if ( ((model->BSIM3sheetResistance > 0.0) &&
- (here->BSIM3drainSquares > 0.0) && (here->BSIM3dNodePrime == 0))
- ||((model->BSIM3sheetResistance > 0.0) &&
- (model->BSIM3hdif > 0.0) && (here->BSIM3dNodePrime == 0))
- ||((model->BSIM3rd > 0.0) &&
- (model->BSIM3ldif > 0.0) && (here->BSIM3dNodePrime == 0))
- ||((model->BSIM3rd > 0.0) &&
- (model->BSIM3ld > 0.0) && (here->BSIM3dNodePrime == 0))
- ||((model->BSIM3rsc > 0.0) && (here->BSIM3dNodePrime == 0))
+ if ( ((model->BSIM3sheetResistance > 0.0) &&
+ (here->BSIM3drainSquares > 0.0) && (here->BSIM3dNodePrime == 0))
+ ||((model->BSIM3sheetResistance > 0.0) &&
+ (model->BSIM3hdif > 0.0) && (here->BSIM3dNodePrime == 0))
+ ||((model->BSIM3rd > 0.0) &&
+ (model->BSIM3ldif > 0.0) && (here->BSIM3dNodePrime == 0))
+ ||((model->BSIM3rd > 0.0) &&
+ (model->BSIM3ld > 0.0) && (here->BSIM3dNodePrime == 0))
+ ||((model->BSIM3rsc > 0.0) && (here->BSIM3dNodePrime == 0))
)
- { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain");
+ { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain");
if(error) return(error);
- here->BSIM3dNodePrime = tmp->number;
-
+ here->BSIM3dNodePrime = tmp->number;
if (ckt->CKTcopyNodesets) {
if (CKTinst2Node(ckt,here,1,(void **)tmpNode,&tmpName)==OK) {
if (tmpNode[0]->nsGiven) {
@@ -954,24 +961,23 @@ IFuid tmpName;
}
}
}
-
}
- else
- { here->BSIM3dNodePrime = here->BSIM3dNode;
+ else
+ { here->BSIM3dNodePrime = here->BSIM3dNode;
}
/* process source series resistance */
- if ( ((model->BSIM3sheetResistance > 0.0) &&
- (here->BSIM3sourceSquares > 0.0) && (here->BSIM3sNodePrime == 0))
- ||((model->BSIM3sheetResistance > 0.0) &&
- (model->BSIM3hdif > 0.0) && (here->BSIM3sNodePrime == 0))
- ||((model->BSIM3rs > 0.0) &&
- (model->BSIM3ldif > 0.0) && (here->BSIM3sNodePrime == 0))
- ||((model->BSIM3rs > 0.0) &&
- (model->BSIM3ld > 0.0) && (here->BSIM3sNodePrime == 0))
- ||((model->BSIM3rsc > 0.0) && (here->BSIM3sNodePrime == 0))
+ if ( ((model->BSIM3sheetResistance > 0.0) &&
+ (here->BSIM3sourceSquares > 0.0) && (here->BSIM3sNodePrime == 0))
+ ||((model->BSIM3sheetResistance > 0.0) &&
+ (model->BSIM3hdif > 0.0) && (here->BSIM3sNodePrime == 0))
+ ||((model->BSIM3rs > 0.0) &&
+ (model->BSIM3ldif > 0.0) && (here->BSIM3sNodePrime == 0))
+ ||((model->BSIM3rs > 0.0) &&
+ (model->BSIM3ld > 0.0) && (here->BSIM3sNodePrime == 0))
+ ||((model->BSIM3rsc > 0.0) && (here->BSIM3sNodePrime == 0))
)
- { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source");
+ { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source");
if(error) return(error);
here->BSIM3sNodePrime = tmp->number;
@@ -985,19 +991,19 @@ IFuid tmpName;
}
}
- else
- { here->BSIM3sNodePrime = here->BSIM3sNode;
+ else
+ { here->BSIM3sNodePrime = here->BSIM3sNode;
}
/* internal charge node */
if ((here->BSIM3nqsMod) && (here->BSIM3qNode == 0))
- { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"charge");
+ { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"charge");
if(error) return(error);
here->BSIM3qNode = tmp->number;
}
- else
- { here->BSIM3qNode = 0;
+ else
+ { here->BSIM3qNode = 0;
}
/* set Sparse Matrix Pointers */