Browse Source

Alan fixed some typo introduced in the last commits.

pre-master-46
pnenzi 26 years ago
parent
commit
ac84baab65
  1. 427
      src/frontend/outitf.c
  2. 17
      src/spicelib/devices/devsup.c
  3. 246
      src/spicelib/devices/mos3/mos3load.c

427
src/frontend/outitf.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/ **********/
/* /*
@ -20,20 +21,23 @@ Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ifsim.h" #include "ifsim.h"
#include "jobdefs.h" #include "jobdefs.h"
#include "iferrmsg.h" #include "iferrmsg.h"
#include "cktdefs.h"
#include "circuits.h" #include "circuits.h"
#include "outitf.h" #include "outitf.h"
#include "variable.h" #include "variable.h"
#include <fcntl.h>
#include <time.h>
#include "cktdefs.h"
extern void gr_end_iplot(void); extern void gr_end_iplot(void);
extern char *spice_analysis_get_name(int index); extern char *spice_analysis_get_name(int index);
extern char *spice_analysis_get_description(int index); extern char *spice_analysis_get_description(int index);
/* static declarations */ /* static declarations */
static int beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, static int beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName,
char *refName, int refType, int numNames, char **dataNames, int dataType,
bool windowed, runDesc **runp);
char *refName, int refType, int numNames, char **dataNames, int dataType,
bool windowed, runDesc **runp);
static int addDataDesc(runDesc *run, char *name, int type, int ind); static int addDataDesc(runDesc *run, char *name, int type, int ind);
static int addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind); static int addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind);
static void fileInit(runDesc *run); static void fileInit(runDesc *run);
@ -61,10 +65,9 @@ static clock_t lastclock, currclock;
static float *rowbuf; static float *rowbuf;
static int column, rowbuflen; static int column, rowbuflen;
static bool shouldstop = FALSE; /* Tell simulator to stop next time it asks. */ static bool shouldstop = FALSE; /* Tell simulator to stop next time it asks. */
static bool printinfo = FALSE; /* Print informational "error messages". */
static bool printinfo = FALSE; /* Print informational "error messages". */
/* The two "begin plot" routines share all their internals... */ /* The two "begin plot" routines share all their internals... */
@ -115,14 +118,14 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
int numsaves; int numsaves;
int i, j, depind; int i, j, depind;
char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP]; char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP];
char *ch, tmpname[BSIZE_SP]; /* AF */
bool saveall = TRUE;
bool savealli = TRUE; /* AF */
char *ch, tmpname[BSIZE_SP];
bool saveall = TRUE;
bool savealli = FALSE;
char *an_name; char *an_name;
/* Check to see if we want to print informational data. */ /* Check to see if we want to print informational data. */
if (cp_getvar("printinfo", VT_BOOL, (char *) &printinfo)) if (cp_getvar("printinfo", VT_BOOL, (char *) &printinfo))
fprintf(cp_err, "(debug printing enabled)\n");
fprintf(cp_err, "(debug printing enabled)\n");
*runp = run = alloc(struct runDesc); *runp = run = alloc(struct runDesc);
@ -147,23 +150,23 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
saveall = FALSE; saveall = FALSE;
for (i = 0; i < numsaves; i++) { for (i = 0; i < numsaves; i++) {
if (saves[i].analysis && !cieq(saves[i].analysis, an_name)) { if (saves[i].analysis && !cieq(saves[i].analysis, an_name)) {
/* ignore this one this time around */
savesused[i] = TRUE;
continue;
}
if (cieq(saves[i].name, "all") || cieq(saves[i].name, "allv" )) {
/* ignore this one this time around */
savesused[i] = TRUE;
continue;
}
if (cieq(saves[i].name, "all") || cieq(saves[i].name, "allv")) {
saveall = TRUE; saveall = TRUE;
savesused[i] = TRUE; savesused[i] = TRUE;
saves[i].used = 1;
saves[i].used = 1;
continue; continue;
} }
if (cieq(saves[i].name, "alli")) { /*AF */
if (cieq(saves[i].name, "alli")) {
savealli = TRUE; savealli = TRUE;
savesused[i] = TRUE; savesused[i] = TRUE;
saves[i].used = 1; saves[i].used = 1;
continue; continue;
} }
}
}
} }
/* Pass 0. */ /* Pass 0. */
@ -172,7 +175,7 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
for (i = 0; i < numsaves; i++) for (i = 0; i < numsaves; i++)
if (!savesused[i] && name_eq(saves[i].name, refName)) { if (!savesused[i] && name_eq(saves[i].name, refName)) {
savesused[i] = TRUE; savesused[i] = TRUE;
saves[i].used = 1;
saves[i].used = 1;
} }
} else { } else {
run->refIndex = -1; run->refIndex = -1;
@ -182,32 +185,31 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
/* Pass 1. */ /* Pass 1. */
if (numsaves && !saveall) { if (numsaves && !saveall) {
for (i = 0; i < numsaves; i++) { for (i = 0; i < numsaves; i++) {
if (!savesused[i]) {
for (j = 0; j < numNames; j++) {
if (name_eq(saves[i].name, dataNames[j])) {
addDataDesc(run, dataNames[j], dataType, j);
savesused[i] = TRUE;
saves[i].used = 1;
break;
}
}
}
if (!savesused[i]) {
for (j = 0; j < numNames; j++) {
if (name_eq(saves[i].name, dataNames[j])) {
addDataDesc(run, dataNames[j], dataType, j);
savesused[i] = TRUE;
saves[i].used = 1;
break;
}
}
}
} }
} else { } else {
for (i = 0; i < numNames; i++) for (i = 0; i < numNames; i++)
if (!refName || !name_eq(dataNames[i], refName)) { if (!refName || !name_eq(dataNames[i], refName)) {
if (!strstr(dataNames[i], "#internal") && /* AF */
if (!strstr(dataNames[i], "#internal") &&
!strstr(dataNames[i], "#source") && !strstr(dataNames[i], "#source") &&
!strstr(dataNames[i], "#drain") && !strstr(dataNames[i], "#drain") &&
!strstr(dataNames[i], "#collector") && !strstr(dataNames[i], "#collector") &&
!strstr(dataNames[i], "#emitter") && !strstr(dataNames[i], "#emitter") &&
!strstr(dataNames[i], "#base")) { !strstr(dataNames[i], "#base")) {
addDataDesc(run, dataNames[i], dataType, i);
}
addDataDesc(run, dataNames[i], dataType, i);
}
} }
} }
/* Pass 1 and a bit. */ /* Pass 1 and a bit. */
if (savealli) { if (savealli) {
depind=0; depind=0;
@ -263,17 +265,16 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
} }
} }
} }
/* Pass 2. */ /* Pass 2. */
for (i = 0; i < numsaves; i++) { for (i = 0; i < numsaves; i++) {
if (savesused[i]) if (savesused[i])
continue; continue;
if (!parseSpecial(saves[i].name, namebuf, parambuf, depbuf)) { if (!parseSpecial(saves[i].name, namebuf, parambuf, depbuf)) {
if (saves[i].analysis)
fprintf(cp_err, "Warning: can't parse '%s': ignored\n",
saves[i].name);
if (saves[i].analysis)
fprintf(cp_err, "Warning: can't parse '%s': ignored\n",
saves[i].name);
continue; continue;
} }
/* Now, if there's a dep variable, do we already have it? */ /* Now, if there's a dep variable, do we already have it? */
@ -294,7 +295,7 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
} }
addDataDesc(run, dataNames[j], dataType, j); addDataDesc(run, dataNames[j], dataType, j);
savesused[i] = TRUE; savesused[i] = TRUE;
saves[i].used = 1;
saves[i].used = 1;
depind = j; depind = j;
} else } else
depind = run->data[j].outIndex; depind = run->data[j].outIndex;
@ -303,22 +304,19 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
} }
if (numsaves) { if (numsaves) {
for (i = 0; i < numsaves; i++) {
tfree(saves[i].analysis);
tfree(saves[i].name);
}
for (i = 0; i < numsaves; i++) {
tfree(saves[i].analysis);
tfree(saves[i].name);
}
tfree(savesused); tfree(savesused);
} }
if (numNames
&& (run->numData == 1
&& (run->refIndex != -1
|| run->numData == 0)
&& run->refIndex == -1))
if (numNames && (run->numData == 1 && run->refIndex != -1
|| run->numData == 0 && run->refIndex == -1))
{ {
fprintf(cp_err, "Error: no data saved for %s; analysis not run\n",
spice_analysis_get_description(((JOB *) analysisPtr)->JOBtype));
return E_NOTFOUND;
fprintf(cp_err, "Error: no data saved for %s; analysis not run\n",
spice_analysis_get_description(((JOB *) analysisPtr)->JOBtype));
return E_NOTFOUND;
} }
/* Now that we have our own data structures built up, let's see what /* Now that we have our own data structures built up, let's see what
@ -331,8 +329,8 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
fileInit(run); fileInit(run);
else { else {
plotInit(run); plotInit(run);
if (refName)
run->runPlot->pl_ndims = 1;
if (refName)
run->runPlot->pl_ndims = 1;
} }
return (OK); return (OK);
@ -403,7 +401,7 @@ addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind)
return (OK); return (OK);
} }
int int
OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
@ -418,28 +416,28 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
run->pointCount++; run->pointCount++;
if (run->writeOut) { if (run->writeOut) {
if (run->pointCount == 1)
fileInit_pass2(plotPtr);
if (run->pointCount == 1)
fileInit_pass2(plotPtr);
fileStartPoint(run->fp, run->binary, run->pointCount); fileStartPoint(run->fp, run->binary, run->pointCount);
if (run->refIndex != -1) { if (run->refIndex != -1) {
if (run->isComplex) {
if (run->isComplex){
fileAddComplexValue(run->fp, run->binary, refValue->cValue); fileAddComplexValue(run->fp, run->binary, refValue->cValue);
currclock = clock(); currclock = clock();
if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) { if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) {
fprintf(stderr, " Reference value : % 12.5e\r", fprintf(stderr, " Reference value : % 12.5e\r",
refValue->cValue.real); refValue->cValue.real);
lastclock = currclock;
}
lastclock = currclock;
}
} else { } else {
fileAddRealValue(run->fp, run->binary, refValue->rValue); fileAddRealValue(run->fp, run->binary, refValue->rValue);
currclock = clock(); currclock = clock();
if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) { if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) {
fprintf(stderr, " Reference value : % 12.5e\r", refValue->rValue);
lastclock = currclock;
}
fprintf(stderr, " Reference value : % 12.5e\r", refValue->rValue);
lastclock = currclock;
}
} }
}
}
for (i = 0; i < run->numData; i++) { for (i = 0; i < run->numData; i++) {
/* we've already printed reference vec first */ /* we've already printed reference vec first */
if (run->data[i].outIndex == -1) continue; if (run->data[i].outIndex == -1) continue;
@ -458,8 +456,7 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
} else { } else {
/* should pre-check instance */ /* should pre-check instance */
if (!getSpecial(&run->data[i], run, &val)) if (!getSpecial(&run->data[i], run, &val))
{
{
if (run->pointCount==1) if (run->pointCount==1)
fprintf(stderr, "Warning: unrecognized variable - %s\n", fprintf(stderr, "Warning: unrecognized variable - %s\n",
run->data[i].name); run->data[i].name);
@ -475,7 +472,6 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
}; };
continue; continue;
}; };
if (run->data[i].type == IF_REAL) if (run->data[i].type == IF_REAL)
fileAddRealValue(run->fp, run->binary, fileAddRealValue(run->fp, run->binary,
val.rValue); val.rValue);
@ -489,7 +485,7 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
fileEndPoint(run->fp, run->binary); fileEndPoint(run->fp, run->binary);
if (ferror(run->fp)) { if (ferror(run->fp)) {
fprintf(stderr, "Warning: rawfile write error !!\n"); fprintf(stderr, "Warning: rawfile write error !!\n");
shouldstop=TRUE;
shouldstop = TRUE;
}; };
} else { } else {
for (i = 0; i < run->numData; i++) { for (i = 0; i < run->numData; i++) {
@ -532,7 +528,7 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
return (OK); return (OK);
} }
/* ARGSUSED */ /* until some code gets written */ /* ARGSUSED */ /* until some code gets written */
int int
@ -554,7 +550,7 @@ OUTwEnd(void *plotPtr)
return (OK); return (OK);
} }
int int
OUTendPlot(void *plotPtr) OUTendPlot(void *plotPtr)
@ -577,7 +573,7 @@ OUTendPlot(void *plotPtr)
return (OK); return (OK);
} }
/* ARGSUSED */ /* until some code gets written */ /* ARGSUSED */ /* until some code gets written */
int int
@ -593,7 +589,7 @@ OUTendDomain(void *plotPtr)
return (OK); return (OK);
} }
/* ARGSUSED */ /* until some code gets written */ /* ARGSUSED */ /* until some code gets written */
int int
@ -605,34 +601,34 @@ OUTattributes(void *plotPtr, char *varName, int param, IFvalue *value)
int i; int i;
if (param == OUT_SCALE_LIN) if (param == OUT_SCALE_LIN)
type = GRID_LIN;
type = GRID_LIN;
else if (param == OUT_SCALE_LOG) else if (param == OUT_SCALE_LOG)
type = GRID_XLOG;
type = GRID_XLOG;
else else
return E_UNSUPP;
return E_UNSUPP;
if (run->writeOut) { if (run->writeOut) {
if (varName) {
for (i = 0; i < run->numData; i++)
if (!strcmp(varName, run->data[i].name))
run->data[i].gtype = type;
} else {
run->data[run->refIndex].gtype = type;
}
if (varName) {
for (i = 0; i < run->numData; i++)
if (!strcmp(varName, run->data[i].name))
run->data[i].gtype = type;
} else {
run->data[run->refIndex].gtype = type;
}
} else { } else {
if (varName) {
for (d = run->runPlot->pl_dvecs; d; d = d->v_next)
if (!strcmp(varName, d->v_name))
d->v_gridtype = type;
} else {
run->runPlot->pl_scale->v_gridtype = type;
}
if (varName) {
for (d = run->runPlot->pl_dvecs; d; d = d->v_next)
if (!strcmp(varName, d->v_name))
d->v_gridtype = type;
} else {
run->runPlot->pl_scale->v_gridtype = type;
}
} }
return (OK); return (OK);
} }
/* The file writing routines. */ /* The file writing routines. */
@ -644,9 +640,9 @@ fileInit(runDesc *run)
float ftmp; float ftmp;
time_t time_of_day; time_t time_of_day;
CKTcircuit *ckt; CKTcircuit *ckt;
lastclock = clock();
lastclock = clock();
/* This is a hack. */ /* This is a hack. */
run->isComplex = FALSE; run->isComplex = FALSE;
for (i = 0; i < run->numData; i++) for (i = 0; i < run->numData; i++)
@ -655,8 +651,6 @@ fileInit(runDesc *run)
i = 0; i = 0;
/* Write PROBE version marker */ /* Write PROBE version marker */
tmp=0xFFFFFFFF; tmp=0xFFFFFFFF;
@ -666,37 +660,32 @@ fileInit(runDesc *run)
fwrite((char *)&tmp,sizeof(tmp),1,run->fp); fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
i += sizeof(tmp); i += sizeof(tmp);
/* Write Title String */
/* Write Title String */
sprintf(buf, "Title: %s\n", run->name); sprintf(buf, "Title: %s\n", run->name);
i += strlen(buf); i += strlen(buf);
fputs(buf, run->fp); fputs(buf, run->fp);
/* Write \0 for Title string and \0 for empty SubTitle string */ /* Write \0 for Title string and \0 for empty SubTitle string */
tmp=0; tmp=0;
fwrite((char *)&tmp,2,1,run->fp); fwrite((char *)&tmp,2,1,run->fp);
i += 2; i += 2;
/* get the time and date */ /* get the time and date */
time_of_day = time( NULL ); time_of_day = time( NULL );
/* Write Time String */
/* Write Time String */
strftime( buf, 9, "%H:%M:%S", strftime( buf, 9, "%H:%M:%S",
localtime( &time_of_day ) ); localtime( &time_of_day ) );
i += strlen(buf); i += strlen(buf);
fputs(buf, run->fp); fputs(buf, run->fp);
tmp=0; tmp=0;
fwrite((char *)&tmp,1,1,run->fp); fwrite((char *)&tmp,1,1,run->fp);
i += 1;
i += 1;
/* Write Date String */ /* Write Date String */
@ -708,9 +697,8 @@ fileInit(runDesc *run)
tmp=0; tmp=0;
fwrite((char *)&tmp,1,1,run->fp); fwrite((char *)&tmp,1,1,run->fp);
i += 1; i += 1;
/* Write Temperature */
/* Write Temperature */
ckt=run->circuit; ckt=run->circuit;
ftmp=ckt->CKTtemp-273.15; ftmp=ckt->CKTtemp-273.15;
@ -732,45 +720,44 @@ fileInit(runDesc *run)
}; };
i += strlen(buf); i += strlen(buf);
fputs(buf, run->fp); fputs(buf, run->fp);
/* Write \0 for Analysis Type string and \0 for empty Comment string */
/* Write \0 for Analysis Type string and \0 for empty Comment string */
tmp=0; tmp=0;
fwrite((char *)&tmp,2,1,run->fp); fwrite((char *)&tmp,2,1,run->fp);
i += 2; i += 2;
/* Write Program ID */
/* Write Program ID */
tmp=0x00011A22; tmp=0x00011A22;
fwrite((char *)&tmp,sizeof(tmp),1,run->fp); fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
i += sizeof(tmp); i += sizeof(tmp);
/* Write All-Columns Flag */
/* Write All-Columns Flag */
tmp=0; tmp=0;
fwrite((char *)&tmp,2,1,run->fp); fwrite((char *)&tmp,2,1,run->fp);
i += 2; i += 2;
/* Write Complex-Data Flag */
/* Write Complex-Data Flag */
tmp = run->isComplex ? 2 : 1; tmp = run->isComplex ? 2 : 1;
fwrite((char *)&tmp,2,1,run->fp); fwrite((char *)&tmp,2,1,run->fp);
i += 2; i += 2;
/* Write Datatype Flag (PROBE_ANALOG) */
/* Write Datatype Flag (PROBE_ANALOG) */
tmp = 0; tmp = 0;
fwrite((char *)&tmp,2,1,run->fp); fwrite((char *)&tmp,2,1,run->fp);
i += 2; i += 2;
/* Write Digital Data Length (meaningless if analogue data) */
/* Write Digital Data Length (meaningless if analogue data) */
tmp=0; tmp=0;
fwrite((char *)&tmp,sizeof(tmp),1,run->fp); fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
i += sizeof(tmp); i += sizeof(tmp);
/* Write space for no. of rows */
/* Write space for no. of rows */
fflush(run->fp); /* Gotta do this for LATTICE. */ fflush(run->fp); /* Gotta do this for LATTICE. */
if (run->fp == stdout || (run->pointPos = ftell(run->fp)) <= 0) if (run->fp == stdout || (run->pointPos = ftell(run->fp)) <= 0)
@ -779,13 +766,15 @@ fileInit(runDesc *run)
fwrite((char *)&tmp,sizeof(tmp),1,run->fp); fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
i += sizeof(tmp); i += sizeof(tmp);
/* Write no. of cols */
/* Write no. of cols */
fwrite(&(run->numData),2,1,run->fp); fwrite(&(run->numData),2,1,run->fp);
i += 2; i += 2;
#ifdef AlansFixes
fprintf(stderr, "No. of Data Columns : %d \n", run->numData); fprintf(stderr, "No. of Data Columns : %d \n", run->numData);
#endif
/* Write Sweep Mode Flag */
/* Write Sweep Mode Flag */
fwrite((char *)&sweep,2,1,run->fp); fwrite((char *)&sweep,2,1,run->fp);
i += 2; i += 2;
@ -796,20 +785,19 @@ fileInit(runDesc *run)
fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp); fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp);
i += sizeof(ftmp); i += sizeof(ftmp);
/* Write sweep variable end value */
/* Write sweep variable end value */
ftmp=0; ftmp=0;
fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp); fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp);
i += sizeof(ftmp); i += sizeof(ftmp);
/* Write Secondary Sweep Variable name (null string) */
/* Write Secondary Sweep Variable name (null string) */
tmp=0; tmp=0;
fwrite((char *)&tmp,1,1,run->fp); fwrite((char *)&tmp,1,1,run->fp);
i += 1; i += 1;
/* Write Digital Section Flag */
/* Write Digital Section Flag */
tmp = 0; tmp = 0;
fwrite((char *)&tmp,2,1,run->fp); fwrite((char *)&tmp,2,1,run->fp);
@ -818,11 +806,9 @@ fileInit(runDesc *run)
fflush(run->fp); /* Make sure this gets to disk */ fflush(run->fp); /* Make sure this gets to disk */
return; return;
} }
static void static void
fileInit_pass2(runDesc *run) fileInit_pass2(runDesc *run)
{ {
@ -830,108 +816,106 @@ fileInit_pass2(runDesc *run)
char *ch, *end, name[BSIZE_SP], buf[BSIZE_SP]; char *ch, *end, name[BSIZE_SP], buf[BSIZE_SP];
for (i = 0; i < run->numData; i++) { for (i = 0; i < run->numData; i++) {
if ((run->data[i].regular==FALSE) ||
if ((run->data[i].regular == FALSE) ||
cieq(run->data[i].name, "time") || cieq(run->data[i].name, "time") ||
cieq(run->data[i].name, "sweep") || cieq(run->data[i].name, "sweep") ||
cieq(run->data[i].name, "frequency")) cieq(run->data[i].name, "frequency"))
(void) sprintf(name, "%s", run->data[i].name);
(void) sprintf(name, "%s", run->data[i].name);
else else
(void) sprintf(name, "V(%s)", run->data[i].name);
(void) sprintf(name, "V(%s)", run->data[i].name);
if (ch=strstr(name, "#branch")) {
if (ch=strstr(name, "#branch")) {
name[0]='I'; name[0]='I';
*ch++=')'; *ch++=')';
*ch='\0';
*ch='\0';
type = SV_CURRENT; type = SV_CURRENT;
}
}
else if (cieq(name, "time")) else if (cieq(name, "time"))
type = SV_TIME; type = SV_TIME;
else if (cieq(name, "frequency")) else if (cieq(name, "frequency"))
type = SV_FREQUENCY; type = SV_FREQUENCY;
else else
type = SV_VOLTAGE; type = SV_VOLTAGE;
if (*name=='@') { if (*name=='@') {
type = SV_CURRENT;
memmove(name, &name[1], strlen(name)-1);
if ((ch=strchr(name, '['))!=NULL) {
ch++;
strncpy(buf, ch, BSIZE_SP);
ch--;
*ch='\0';
if ((ch=strchr(buf, ']'))!=NULL) *ch='\0';
strcat(buf, "(");
if ((ch=strchr(name, ':'))!=NULL) {
ch++;
strncat(buf, ch, BSIZE_SP-strlen(buf));
ch--;
*ch='\0';
if ((ch=strrchr(buf, ':'))!=NULL) {
ch++;
memmove(&ch[strlen(name)], ch, strlen(ch)+1);
memmove(ch, name, strlen(name));
};
} else {
strncat(buf, name, BSIZE_SP-strlen(buf));
};
strcat(buf, ")");
};
strncpy(name, buf, BSIZE_SP);
type = SV_CURRENT;
memmove(name, &name[1], strlen(name)-1);
if ((ch=strchr(name, '['))!=NULL) {
ch++;
strncpy(buf, ch, BSIZE_SP);
ch--;
*ch='\0';
if ((ch=strchr(buf, ']'))!=NULL) *ch='\0';
strcat(buf, "(");
if ((ch=strchr(name, ':'))!=NULL) {
ch++;
strncat(buf, ch, BSIZE_SP-strlen(buf));
ch--;
*ch='\0';
if ((ch=strrchr(buf, ':'))!=NULL) {
ch++;
memmove(&ch[strlen(name)], ch, strlen(ch)+1);
memmove(ch, name, strlen(name));
};
} else {
strncat(buf, name, BSIZE_SP-strlen(buf));
};
strcat(buf, ")");
};
strncpy(name, buf, BSIZE_SP);
}; };
while ((ch=strchr(name, ':'))!=NULL) *ch='.';
while ((ch=strchr(name, ':'))!=NULL)
*ch='.';
if ((ch=strchr(name, '('))!=NULL) { if ((ch=strchr(name, '('))!=NULL) {
ch++;
end=(char *)memchr(name, '\0', BSIZE_SP);
while (strchr(ch, '.')!=NULL) {
memmove(ch+1, ch, end-ch+1);
end++;
*ch='x';
ch=strchr(ch, '.');
ch++;
};
ch++;
end=(char *)memchr(name, '\0', BSIZE_SP);
while (strchr(ch, '.')!=NULL) {
memmove(ch+1, ch, end-ch+1);
end++;
*ch='x';
ch=strchr(ch, '.');
ch++;
};
}; };
fprintf(run->fp, "%s", name); fprintf(run->fp, "%s", name);
tmp=0; tmp=0;
fwrite((char*)&tmp,1,1,run->fp);
fwrite((void *)&tmp,1,1,run->fp);
} }
fflush(run->fp); /* Make all sure this gets to disk */ fflush(run->fp); /* Make all sure this gets to disk */
/* Allocate Row buffer */
/* Allocate Row buffer */
rowbuflen=(run->numData)*sizeof(float); rowbuflen=(run->numData)*sizeof(float);
if (run->isComplex) rowbuflen *=2; if (run->isComplex) rowbuflen *=2;
rowbuf=(float *)tmalloc(rowbuflen); rowbuf=(float *)tmalloc(rowbuflen);
return; return;
} }
static void static void
fileStartPoint(FILE *fp, bool bin, int num) fileStartPoint(FILE *fp, bool bin, int num)
{ {
if (!bin) if (!bin)
fprintf(fp, "%d\t", num - 1); fprintf(fp, "%d\t", num - 1);
/* reset set buffer pointer to zero */
/* reset set buffer pointer to zero */
column = 0;
column=0;
return; return;
} }
static void static void
fileAddRealValue( FILE *fp, bool bin, double value)
fileAddRealValue(FILE *fp, bool bin, double value)
{ {
if (bin) {
if (bin) {
if (value<(-FLT_MAX)) { if (value<(-FLT_MAX)) {
fprintf(stderr, fprintf(stderr,
"Warning, double to float conversion overflow !\n"); "Warning, double to float conversion overflow !\n");
@ -949,15 +933,11 @@ fileAddRealValue( FILE *fp, bool bin, double value)
return; return;
} }
static void static void
fileAddComplexValue(fp, bin, value)
FILE *fp;
bool bin;
IFcomplex value;
fileAddComplexValue(FILE *fp, bool bin, IFcomplex value)
{ {
if (bin) {
if (bin) {
if (value.real<(-FLT_MAX)) { if (value.real<(-FLT_MAX)) {
fprintf(stderr, fprintf(stderr,
"Warning, double to float conversion overflow !\n"); "Warning, double to float conversion overflow !\n");
@ -987,16 +967,12 @@ fileAddComplexValue(fp, bin, value)
} }
/* ARGSUSED */ /* until some code gets written */ /* ARGSUSED */ /* until some code gets written */
static void static void
fileEndPoint(FILE *fp, bool bin) fileEndPoint(FILE *fp, bool bin)
{ {
/* write row buffer to file */
fwrite((char *)rowbuf, rowbuflen, 1, fp);
/* write row buffer to file */
fwrite((char *)rowbuf, rowbuflen, 1, fp);
return; return;
} }
@ -1007,28 +983,29 @@ fileEnd(runDesc *run)
{ {
long place; long place;
int nrows; int nrows;
if (run->fp != stdout) { if (run->fp != stdout) {
place = ftell(run->fp);
fseek(run->fp, run->pointPos, 0);
nrows=run->pointCount;
fprintf(stderr, "\nNo. of Data Rows : %d\n", nrows);
fwrite(&nrows,sizeof(nrows),1,run->fp);
fseek(run->fp, place, 0);
place = ftell(run->fp);
fseek(run->fp, run->pointPos, 0);
nrows=run->pointCount;
fprintf(stderr, "\nNo. of Data Rows : %d\n", nrows);
fwrite(&nrows,sizeof(nrows),1,run->fp);
fseek(run->fp, place, 0);
} else { } else {
/* Yet another hack-around */
fprintf(stderr, "@@@ %ld %d\n", run->pointPos, run->pointCount);
/* Yet another hack-around */
fprintf(stderr, "@@@ %ld %d\n", run->pointPos, run->pointCount);
} }
fflush(run->fp); fflush(run->fp);
/* deallocate row buffer */
/* deallocate row buffer */
tfree(rowbuf); tfree(rowbuf);
return; return;
} }
/* The plot maintenance routines. */ /* The plot maintenance routines. */
@ -1132,7 +1109,7 @@ plotEnd(runDesc *run)
return; return;
} }
/* ParseSpecial takes something of the form "@name[param,index]" and rips /* ParseSpecial takes something of the form "@name[param,index]" and rips
* out name, param, andstrchr. * out name, param, andstrchr.
@ -1146,7 +1123,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
*dev = *param = *ind = '\0'; *dev = *param = *ind = '\0';
if (*name != '@') if (*name != '@')
return (FALSE);
return FALSE;
name++; name++;
s = dev; s = dev;
@ -1154,7 +1131,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
*s++ = *name++; *s++ = *name++;
*s = '\0'; *s = '\0';
if (!*name) if (!*name)
return (TRUE);
return TRUE;
name++; name++;
s = param; s = param;
@ -1164,7 +1141,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
if (*name == ']') if (*name == ']')
return (!name[1] ? TRUE : FALSE); return (!name[1] ? TRUE : FALSE);
else if (!*name) else if (!*name)
return (FALSE);
return FALSE;
name++; name++;
s = ind; s = ind;
@ -1172,9 +1149,9 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
*s++ = *name++; *s++ = *name++;
*s = '\0'; *s = '\0';
if (*name && !name[1]) if (*name && !name[1])
return (TRUE);
return TRUE;
else else
return (FALSE);
return FALSE;
} }
/* This routine must match two names with or without a V() around them. */ /* This routine must match two names with or without a V() around them. */
@ -1187,14 +1164,14 @@ name_eq(char *n1, char *n2)
if ((s =strchr(n1, '('))) { if ((s =strchr(n1, '('))) {
strcpy(buf1, s); strcpy(buf1, s);
if (!(s =strchr(buf1, ')'))) if (!(s =strchr(buf1, ')')))
return (FALSE);
return FALSE;
*s = '\0'; *s = '\0';
n1 = buf1; n1 = buf1;
} }
if ((s =strchr(n2, '('))) { if ((s =strchr(n2, '('))) {
strcpy(buf2, s); strcpy(buf2, s);
if (!(s =strchr(buf2, ')'))) if (!(s =strchr(buf2, ')')))
return (FALSE);
return FALSE;
*s = '\0'; *s = '\0';
n2 = buf2; n2 = buf2;
} }
@ -1213,24 +1190,24 @@ getSpecial(dataDesc *desc, runDesc *run, IFvalue *val)
desc->specName, &desc->specFast, ft_sim, &desc->type, desc->specName, &desc->specFast, ft_sim, &desc->type,
&selector) == OK) { &selector) == OK) {
desc->type &= (IF_REAL | IF_COMPLEX); /* mask out other bits */ desc->type &= (IF_REAL | IF_COMPLEX); /* mask out other bits */
return(TRUE);
return TRUE;
} else if ((vv = if_getstat(run->circuit, &desc->name[1]))) { } else if ((vv = if_getstat(run->circuit, &desc->name[1]))) {
/* skip @ sign */
/* skip @ sign */
desc->type = IF_REAL; desc->type = IF_REAL;
if (vv->va_type == VT_REAL) if (vv->va_type == VT_REAL)
val->rValue = vv->va_real;
val->rValue = vv->va_real;
else if (vv->va_type == VT_NUM) else if (vv->va_type == VT_NUM)
val->rValue = vv->va_num;
val->rValue = vv->va_num;
else if (vv->va_type == VT_BOOL) else if (vv->va_type == VT_BOOL)
val->rValue = (vv->va_bool ? 1.0 : 0.0);
val->rValue = (vv->va_bool ? 1.0 : 0.0);
else { else {
return (FALSE); /* not a real */
return FALSE; /* not a real */
} }
tfree(vv); tfree(vv);
return(TRUE);
return TRUE;
} }
return (FALSE);
return FALSE;
} }
static void static void
@ -1288,8 +1265,8 @@ OUTerror(int flags, char *format, IFuid *names)
int nindex = 0; int nindex = 0;
if ((flags == ERR_INFO) && cp_getvar("printinfo", VT_BOOL, if ((flags == ERR_INFO) && cp_getvar("printinfo", VT_BOOL,
(char *) &printinfo))
return;
(char *) &printinfo))
return;
for (m = msgs; m->flag; m++) for (m = msgs; m->flag; m++)
if (flags & m->flag) if (flags & m->flag)
@ -1297,10 +1274,10 @@ OUTerror(int flags, char *format, IFuid *names)
for (s = format, bptr = buf; *s; s++) { for (s = format, bptr = buf; *s; s++) {
if (*s == '%' && (s == format || *(s-1) != '%') && *(s+1) == 's') { if (*s == '%' && (s == format || *(s-1) != '%') && *(s+1) == 's') {
if (names[nindex])
strcpy(bptr, names[nindex]);
else
strcpy(bptr, "(null)");
if (names[nindex])
strcpy(bptr, names[nindex]);
else
strcpy(bptr, "(null)");
bptr += strlen(bptr); bptr += strlen(bptr);
s++; s++;
nindex++; nindex++;
@ -1312,4 +1289,4 @@ OUTerror(int flags, char *format, IFuid *names)
fprintf(cp_err, "%s\n", buf); fprintf(cp_err, "%s\n", buf);
fflush(cp_err); fflush(cp_err);
}
}

17
src/spicelib/devices/devsup.c

@ -91,7 +91,7 @@ DEVfetlim(double vnew,
double vtemp; double vtemp;
vtsthi = fabs(2*(vold-vto))+2; vtsthi = fabs(2*(vold-vto))+2;
vtstlo = fabs(vold-vto)*1;
vtstlo = fabs(vold-vto)+1;
vtox = vto + 3.5; vtox = vto + 3.5;
delv = vnew-vold; delv = vnew-vold;
@ -251,7 +251,10 @@ DEVqmeyer(double vgs, /* initial voltage gate-source */
double vddif2; double vddif2;
double vgst; double vgst;
#define MAGIC_VDS 0.025
vgst = vgs-von; vgst = vgs-von;
vdsat = MAX(vdsat, MAGIC_VDS);
if (vgst <= -phi) { if (vgst <= -phi) {
*capgb = cox/2; *capgb = cox/2;
*capgs = 0; *capgs = 0;
@ -263,9 +266,19 @@ DEVqmeyer(double vgs, /* initial voltage gate-source */
} else if (vgst <= 0) { } else if (vgst <= 0) {
*capgb = -vgst*cox/(2*phi); *capgb = -vgst*cox/(2*phi);
*capgs = vgst*cox/(1.5*phi)+cox/3; *capgs = vgst*cox/(1.5*phi)+cox/3;
*capgd = 0;
vds = vgs-vgd;
if (vds>=vdsat) {
*capgd = 0;
} else {
vddif = 2.0*vdsat-vds;
vddif1 = vdsat-vds/*-1.0e-12*/;
vddif2 = vddif*vddif;
*capgd = *capgs*(1.0-vdsat*vdsat/vddif2);
*capgs = *capgs*(1.0-vddif1*vddif1/vddif2);
}
} else { } else {
vds = vgs-vgd; vds = vgs-vgd;
vdsat = MAX(vdsat, MAGIC_VDS);
if (vdsat <= vds) { if (vdsat <= vds) {
*capgs = cox/3; *capgs = cox/3;
*capgd = 0; *capgd = 0;

246
src/spicelib/devices/mos3/mos3load.c

@ -400,16 +400,16 @@ MOS3load(GENmodel *inModel, CKTcircuit *ckt)
* corresponding derivative (conductance). * corresponding derivative (conductance).
*/ */
next1: if(vbs <= -3*vt) {
arg=3*vt/(vbs*CONSTe);
arg = arg * arg * arg;
here->MOS3cbs = -SourceSatCur*(1+arg)+ckt->CKTgmin*vbs;
here->MOS3gbs = SourceSatCur*3*arg/vbs+ckt->CKTgmin;
} else {
evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));
here->MOS3gbs = SourceSatCur*evbs/vt + ckt->CKTgmin;
here->MOS3cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs;
}
next1: if(vbs <= -3*vt) {
arg=3*vt/(vbs*CONSTe);
arg = arg * arg * arg;
here->MOS3cbs = -SourceSatCur*(1+arg)+ckt->CKTgmin*vbs;
here->MOS3gbs = SourceSatCur*3*arg/vbs+ckt->CKTgmin;
} else {
evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));
here->MOS3gbs = SourceSatCur*evbs/vt + ckt->CKTgmin;
here->MOS3cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs;
}
if(vbd <= -3*vt) { if(vbd <= -3*vt) {
arg=3*vt/(vbd*CONSTe); arg=3*vt/(vbd*CONSTe);
arg = arg * arg * arg; arg = arg * arg * arg;
@ -717,7 +717,7 @@ MOS3load(GENmodel *inModel, CKTcircuit *ckt)
if ( (here->MOS3mode*vds) <= vdsat ) { if ( (here->MOS3mode*vds) <= vdsat ) {
if ( (model->MOS3maxDriftVel > 0.0) || if ( (model->MOS3maxDriftVel > 0.0) ||
(model->MOS3alpha == 0.0) || (model->MOS3alpha == 0.0) ||
(ckt->CKTbadMos3) ) goto line700;
(ckt->CKTbadMos3) ) goto line700;
else { else {
arga = (here->MOS3mode*vds)/vdsat; arga = (here->MOS3mode*vds)/vdsat;
delxl = sqrt(model->MOS3kappa*model->MOS3alpha*vdsat/8); delxl = sqrt(model->MOS3kappa*model->MOS3alpha*vdsat/8);
@ -730,133 +730,134 @@ MOS3load(GENmodel *inModel, CKTcircuit *ckt)
ddldvb = 0.0; ddldvb = 0.0;
goto line520; goto line520;
}; };
};
if ( model->MOS3maxDriftVel <= 0.0 ) goto line510;
if (model->MOS3alpha == 0.0) goto line700;
cdsat = cdrain;
gdsat = cdsat*(1.0-fdrain)*onvdsc;
gdsat = MAX(1.0e-12,gdsat);
gdoncd = gdsat/cdsat;
gdonfd = gdsat/(1.0-fdrain);
gdonfg = gdsat*onfg;
dgdvg = gdoncd*here->MOS3gm-gdonfd*dfddvg+gdonfg*dfgdvg;
dgdvd = gdoncd*here->MOS3gds-gdonfd*dfddvd+gdonfg*dfgdvd;
dgdvb = gdoncd*here->MOS3gmbs-gdonfd*dfddvb+gdonfg*dfgdvb;
if ( model->MOS3maxDriftVel <= 0.0 ) goto line510;
if (model->MOS3alpha == 0.0) goto line700;
cdsat = cdrain;
gdsat = cdsat*(1.0-fdrain)*onvdsc;
gdsat = MAX(1.0e-12,gdsat);
gdoncd = gdsat/cdsat;
gdonfd = gdsat/(1.0-fdrain);
gdonfg = gdsat*onfg;
dgdvg = gdoncd*here->MOS3gm-gdonfd*dfddvg+gdonfg*dfgdvg;
dgdvd = gdoncd*here->MOS3gds-gdonfd*dfddvd+gdonfg*dfgdvd;
dgdvb = gdoncd*here->MOS3gmbs-gdonfd*dfddvb+gdonfg*dfgdvb;
if (ckt->CKTbadMos3)
if (ckt->CKTbadMos3)
emax = cdsat*oneoverxl/gdsat; emax = cdsat*oneoverxl/gdsat;
else
else
emax = model->MOS3kappa * cdsat*oneoverxl/gdsat; emax = model->MOS3kappa * cdsat*oneoverxl/gdsat;
emoncd = emax/cdsat;
emongd = emax/gdsat;
demdvg = emoncd*here->MOS3gm-emongd*dgdvg;
demdvd = emoncd*here->MOS3gds-emongd*dgdvd;
demdvb = emoncd*here->MOS3gmbs-emongd*dgdvb;
emoncd = emax/cdsat;
emongd = emax/gdsat;
demdvg = emoncd*here->MOS3gm-emongd*dgdvg;
demdvd = emoncd*here->MOS3gds-emongd*dgdvd;
demdvb = emoncd*here->MOS3gmbs-emongd*dgdvb;
arga = 0.5*emax*model->MOS3alpha;
argc = model->MOS3kappa*model->MOS3alpha;
argb = sqrt(arga*arga+argc*((here->MOS3mode*vds)-vdsat));
delxl = argb-arga;
if (argb != 0.0) {
arga = 0.5*emax*model->MOS3alpha;
argc = model->MOS3kappa*model->MOS3alpha;
argb = sqrt(arga*arga+argc*((here->MOS3mode*vds)-vdsat));
delxl = argb-arga;
if (argb != 0.0) {
dldvd = argc/(argb+argb); dldvd = argc/(argb+argb);
dldem = 0.5*(arga/argb-1.0)*model->MOS3alpha; dldem = 0.5*(arga/argb-1.0)*model->MOS3alpha;
} else {
} else {
dldvd = 0.0; dldvd = 0.0;
dldem = 0.0; dldem = 0.0;
}
ddldvg = dldem*demdvg;
ddldvd = dldem*demdvd-dldvd;
ddldvb = dldem*demdvb;
goto line520;
line510:
if (ckt->CKTbadMos3) {
delxl = sqrt(model->MOS3kappa*((here->MOS3mode*vds)-vdsat)*
}
ddldvg = dldem*demdvg;
ddldvd = dldem*demdvd-dldvd;
ddldvb = dldem*demdvb;
goto line520;
line510:
if (ckt->CKTbadMos3) {
delxl = sqrt(model->MOS3kappa*((here->MOS3mode*vds)-vdsat)*
model->MOS3alpha); model->MOS3alpha);
dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat);
} else {
delxl = sqrt(model->MOS3kappa*model->MOS3alpha*
dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat);
} else {
delxl = sqrt(model->MOS3kappa*model->MOS3alpha*
((here->MOS3mode*vds)-vdsat+(vdsat/8))); ((here->MOS3mode*vds)-vdsat+(vdsat/8)));
dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat+(vdsat/8));
};
ddldvg = 0.0;
ddldvd = -dldvd;
ddldvb = 0.0;
/*
*.....punch through approximation
*/
line520:
if ( delxl > (0.5*EffectiveLength) ) {
delxl = EffectiveLength-(EffectiveLength*EffectiveLength/
dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat+(vdsat/8));
};
ddldvg = 0.0;
ddldvd = -dldvd;
ddldvb = 0.0;
/*
*.....punch through approximation
*/
line520:
if ( delxl > (0.5*EffectiveLength) ) {
delxl = EffectiveLength-(EffectiveLength*EffectiveLength/
(4.0*delxl)); (4.0*delxl));
arga = 4.0*(EffectiveLength-delxl)*(EffectiveLength-delxl)/
arga = 4.0*(EffectiveLength-delxl)*(EffectiveLength-delxl)/
(EffectiveLength*EffectiveLength); (EffectiveLength*EffectiveLength);
ddldvg = ddldvg*arga;
ddldvd = ddldvd*arga;
ddldvb = ddldvb*arga;
dldvd = dldvd*arga;
}
/*
*.....saturation region
*/
dlonxl = delxl*oneoverxl;
xlfact = 1.0/(1.0-dlonxl);
cd1 = cdrain;
cdrain = cdrain*xlfact;
diddl = cdrain/(EffectiveLength-delxl);
here->MOS3gm = here->MOS3gm*xlfact+diddl*ddldvg;
here->MOS3gmbs = here->MOS3gmbs*xlfact+diddl*ddldvb;
gds0 = diddl*ddldvd;
here->MOS3gm = here->MOS3gm+gds0*dvsdvg;
here->MOS3gmbs = here->MOS3gmbs+gds0*dvsdvb;
here->MOS3gds = here->MOS3gds*xlfact+diddl*dldvd+gds0*dvsdvd;
/* here->MOS3gds = (here->MOS3gds*xlfact)+gds0*dvsdvd-
(cd1*ddldvd/(EffectiveLength*(1-2*dlonxl+dlonxl*dlonxl)));*/
ddldvg = ddldvg*arga;
ddldvd = ddldvd*arga;
ddldvb = ddldvb*arga;
dldvd = dldvd*arga;
}
/*
*.....saturation region
*/
dlonxl = delxl*oneoverxl;
xlfact = 1.0/(1.0-dlonxl);
cd1 = cdrain;
cdrain = cdrain*xlfact;
diddl = cdrain/(EffectiveLength-delxl);
here->MOS3gm = here->MOS3gm*xlfact+diddl*ddldvg;
here->MOS3gmbs = here->MOS3gmbs*xlfact+diddl*ddldvb;
gds0 = diddl*ddldvd;
here->MOS3gm = here->MOS3gm+gds0*dvsdvg;
here->MOS3gmbs = here->MOS3gmbs+gds0*dvsdvb;
here->MOS3gds = here->MOS3gds*xlfact+diddl*dldvd+gds0*dvsdvd;
/* here->MOS3gds = (here->MOS3gds*xlfact)+gds0*dvsdvd-
(cd1*ddldvd/(EffectiveLength*(1-2*dlonxl+dlonxl*dlonxl)));*/
/*
*.....finish strong inversion case
*/
line700:
if ( (here->MOS3mode==1?vgs:vgd) < von ) {
/*
*.....weak inversion
*/
onxn = 1.0/xn;
ondvt = onxn/vt;
wfact = exp( ((here->MOS3mode==1?vgs:vgd)-von)*ondvt );
cdrain = cdrain*wfact;
gms = here->MOS3gm*wfact;
gmw = cdrain*ondvt;
here->MOS3gm = gmw;
if ((here->MOS3mode*vds) > vdsat) {
here->MOS3gm = here->MOS3gm+gds0*dvsdvg*wfact;
}
here->MOS3gds = here->MOS3gds*wfact+(gms-gmw)*dvodvd;
here->MOS3gmbs = here->MOS3gmbs*wfact+(gms-gmw)*dvodvb-gmw*
/*
*.....finish strong inversion case
*/
line700:
if ( (here->MOS3mode==1?vgs:vgd) < von ) {
/*
*.....weak inversion
*/
onxn = 1.0/xn;
ondvt = onxn/vt;
wfact = exp( ((here->MOS3mode==1?vgs:vgd)-von)*ondvt );
cdrain = cdrain*wfact;
gms = here->MOS3gm*wfact;
gmw = cdrain*ondvt;
here->MOS3gm = gmw;
if ((here->MOS3mode*vds) > vdsat) {
here->MOS3gm = here->MOS3gm+gds0*dvsdvg*wfact;
}
here->MOS3gds = here->MOS3gds*wfact+(gms-gmw)*dvodvd;
here->MOS3gmbs = here->MOS3gmbs*wfact+(gms-gmw)*dvodvb-gmw*
((here->MOS3mode==1?vgs:vgd)-von)*onxn*dxndvb; ((here->MOS3mode==1?vgs:vgd)-von)*onxn*dxndvb;
}
/*
*.....charge computation
*/
goto innerline1000;
/*
*.....special case of vds = 0.0d0
*/
line900:
Beta = Beta*fgate;
cdrain = 0.0;
here->MOS3gm = 0.0;
here->MOS3gds = Beta*(vgsx-vth);
here->MOS3gmbs = 0.0;
if ( (model->MOS3fastSurfaceStateDensity != 0.0) &&
((here->MOS3mode==1?vgs:vgd) < von) ) {
here->MOS3gds *=exp(((here->MOS3mode==1?vgs:vgd)-von)/(vt*xn));
}
innerline1000:;
/*
*.....done
*/
} }
/*
*.....charge computation
*/
goto innerline1000;
/*
*.....special case of vds = 0.0d0
*/
line900:
Beta = Beta*fgate;
cdrain = 0.0;
here->MOS3gm = 0.0;
here->MOS3gds = Beta*(vgsx-vth);
here->MOS3gmbs = 0.0;
if ( (model->MOS3fastSurfaceStateDensity != 0.0) &&
((here->MOS3mode==1?vgs:vgd) < von) ) {
here->MOS3gds *=exp(((here->MOS3mode==1?vgs:vgd)-von)/(vt*xn));
}
innerline1000:;
/*
*.....done
*/
}
/* now deal with n vs p polarity */ /* now deal with n vs p polarity */
@ -1239,7 +1240,6 @@ MOS3load(GENmodel *inModel, CKTcircuit *ckt)
*(here->MOS3SPdpPtr) += (-here->MOS3gds- *(here->MOS3SPdpPtr) += (-here->MOS3gds-
xrev*(here->MOS3gm+here->MOS3gmbs)); xrev*(here->MOS3gm+here->MOS3gmbs));
} }
}
} }
return(OK); return(OK);
} }

Loading…
Cancel
Save