Alan fixed some typo introduced in the last commits.
This commit is contained in:
parent
19f387a1c6
commit
ac84baab65
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
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 "jobdefs.h"
|
||||
#include "iferrmsg.h"
|
||||
#include "cktdefs.h"
|
||||
|
||||
#include "circuits.h"
|
||||
#include "outitf.h"
|
||||
#include "variable.h"
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include "cktdefs.h"
|
||||
|
||||
|
||||
extern void gr_end_iplot(void);
|
||||
extern char *spice_analysis_get_name(int index);
|
||||
extern char *spice_analysis_get_description(int index);
|
||||
|
||||
|
||||
/* static declarations */
|
||||
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 addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind);
|
||||
static void fileInit(runDesc *run);
|
||||
|
|
@ -61,10 +65,9 @@ static clock_t lastclock, currclock;
|
|||
static float *rowbuf;
|
||||
static int column, rowbuflen;
|
||||
|
||||
|
||||
|
||||
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... */
|
||||
|
||||
|
|
@ -115,14 +118,14 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
int numsaves;
|
||||
int i, j, depind;
|
||||
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;
|
||||
|
||||
/* Check to see if we want to print informational data. */
|
||||
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);
|
||||
|
||||
|
|
@ -147,23 +150,23 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
saveall = FALSE;
|
||||
for (i = 0; i < numsaves; i++) {
|
||||
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;
|
||||
savesused[i] = TRUE;
|
||||
saves[i].used = 1;
|
||||
saves[i].used = 1;
|
||||
continue;
|
||||
}
|
||||
if (cieq(saves[i].name, "alli")) { /*AF */
|
||||
if (cieq(saves[i].name, "alli")) {
|
||||
savealli = TRUE;
|
||||
savesused[i] = TRUE;
|
||||
saves[i].used = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass 0. */
|
||||
|
|
@ -172,7 +175,7 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
for (i = 0; i < numsaves; i++)
|
||||
if (!savesused[i] && name_eq(saves[i].name, refName)) {
|
||||
savesused[i] = TRUE;
|
||||
saves[i].used = 1;
|
||||
saves[i].used = 1;
|
||||
}
|
||||
} else {
|
||||
run->refIndex = -1;
|
||||
|
|
@ -182,32 +185,31 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
/* Pass 1. */
|
||||
if (numsaves && !saveall) {
|
||||
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 {
|
||||
for (i = 0; i < numNames; i++)
|
||||
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], "#drain") &&
|
||||
!strstr(dataNames[i], "#collector") &&
|
||||
!strstr(dataNames[i], "#emitter") &&
|
||||
!strstr(dataNames[i], "#base")) {
|
||||
addDataDesc(run, dataNames[i], dataType, i);
|
||||
}
|
||||
addDataDesc(run, dataNames[i], dataType, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Pass 1 and a bit. */
|
||||
if (savealli) {
|
||||
depind=0;
|
||||
|
|
@ -263,17 +265,16 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Pass 2. */
|
||||
for (i = 0; i < numsaves; i++) {
|
||||
if (savesused[i])
|
||||
continue;
|
||||
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;
|
||||
}
|
||||
/* 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);
|
||||
savesused[i] = TRUE;
|
||||
saves[i].used = 1;
|
||||
saves[i].used = 1;
|
||||
depind = j;
|
||||
} else
|
||||
depind = run->data[j].outIndex;
|
||||
|
|
@ -303,22 +304,19 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -331,8 +329,8 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
fileInit(run);
|
||||
else {
|
||||
plotInit(run);
|
||||
if (refName)
|
||||
run->runPlot->pl_ndims = 1;
|
||||
if (refName)
|
||||
run->runPlot->pl_ndims = 1;
|
||||
}
|
||||
|
||||
return (OK);
|
||||
|
|
@ -403,7 +401,7 @@ addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind)
|
|||
return (OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
||||
|
|
@ -418,28 +416,28 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
run->pointCount++;
|
||||
|
||||
if (run->writeOut) {
|
||||
if (run->pointCount == 1)
|
||||
fileInit_pass2(plotPtr);
|
||||
if (run->pointCount == 1)
|
||||
fileInit_pass2(plotPtr);
|
||||
fileStartPoint(run->fp, run->binary, run->pointCount);
|
||||
|
||||
if (run->refIndex != -1) {
|
||||
if (run->isComplex) {
|
||||
if (run->isComplex){
|
||||
fileAddComplexValue(run->fp, run->binary, refValue->cValue);
|
||||
currclock = clock();
|
||||
if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) {
|
||||
fprintf(stderr, " Reference value : % 12.5e\r",
|
||||
refValue->cValue.real);
|
||||
lastclock = currclock;
|
||||
}
|
||||
lastclock = currclock;
|
||||
}
|
||||
} else {
|
||||
fileAddRealValue(run->fp, run->binary, refValue->rValue);
|
||||
currclock = clock();
|
||||
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++) {
|
||||
/* we've already printed reference vec first */
|
||||
if (run->data[i].outIndex == -1) continue;
|
||||
|
|
@ -458,8 +456,7 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
} else {
|
||||
/* should pre-check instance */
|
||||
if (!getSpecial(&run->data[i], run, &val))
|
||||
|
||||
{
|
||||
{
|
||||
if (run->pointCount==1)
|
||||
fprintf(stderr, "Warning: unrecognized variable - %s\n",
|
||||
run->data[i].name);
|
||||
|
|
@ -475,7 +472,6 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
};
|
||||
continue;
|
||||
};
|
||||
|
||||
if (run->data[i].type == IF_REAL)
|
||||
fileAddRealValue(run->fp, run->binary,
|
||||
val.rValue);
|
||||
|
|
@ -489,7 +485,7 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
fileEndPoint(run->fp, run->binary);
|
||||
if (ferror(run->fp)) {
|
||||
fprintf(stderr, "Warning: rawfile write error !!\n");
|
||||
shouldstop=TRUE;
|
||||
shouldstop = TRUE;
|
||||
};
|
||||
} else {
|
||||
for (i = 0; i < run->numData; i++) {
|
||||
|
|
@ -532,7 +528,7 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
return (OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ARGSUSED */ /* until some code gets written */
|
||||
int
|
||||
|
|
@ -554,7 +550,7 @@ OUTwEnd(void *plotPtr)
|
|||
return (OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
OUTendPlot(void *plotPtr)
|
||||
|
|
@ -577,7 +573,7 @@ OUTendPlot(void *plotPtr)
|
|||
return (OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ARGSUSED */ /* until some code gets written */
|
||||
int
|
||||
|
|
@ -593,7 +589,7 @@ OUTendDomain(void *plotPtr)
|
|||
return (OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ARGSUSED */ /* until some code gets written */
|
||||
int
|
||||
|
|
@ -605,34 +601,34 @@ OUTattributes(void *plotPtr, char *varName, int param, IFvalue *value)
|
|||
int i;
|
||||
|
||||
if (param == OUT_SCALE_LIN)
|
||||
type = GRID_LIN;
|
||||
type = GRID_LIN;
|
||||
else if (param == OUT_SCALE_LOG)
|
||||
type = GRID_XLOG;
|
||||
type = GRID_XLOG;
|
||||
else
|
||||
return E_UNSUPP;
|
||||
return E_UNSUPP;
|
||||
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* The file writing routines. */
|
||||
|
||||
|
|
@ -644,9 +640,9 @@ fileInit(runDesc *run)
|
|||
float ftmp;
|
||||
time_t time_of_day;
|
||||
CKTcircuit *ckt;
|
||||
|
||||
lastclock = clock();
|
||||
|
||||
lastclock = clock();
|
||||
|
||||
/* This is a hack. */
|
||||
run->isComplex = FALSE;
|
||||
for (i = 0; i < run->numData; i++)
|
||||
|
|
@ -655,8 +651,6 @@ fileInit(runDesc *run)
|
|||
|
||||
i = 0;
|
||||
|
||||
|
||||
|
||||
/* Write PROBE version marker */
|
||||
|
||||
tmp=0xFFFFFFFF;
|
||||
|
|
@ -666,37 +660,32 @@ fileInit(runDesc *run)
|
|||
fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
|
||||
i += sizeof(tmp);
|
||||
|
||||
|
||||
/* Write Title String */
|
||||
/* Write Title String */
|
||||
|
||||
sprintf(buf, "Title: %s\n", run->name);
|
||||
i += strlen(buf);
|
||||
fputs(buf, run->fp);
|
||||
|
||||
|
||||
/* Write \0 for Title string and \0 for empty SubTitle string */
|
||||
|
||||
tmp=0;
|
||||
fwrite((char *)&tmp,2,1,run->fp);
|
||||
i += 2;
|
||||
|
||||
|
||||
/* get the time and date */
|
||||
|
||||
time_of_day = time( NULL );
|
||||
|
||||
|
||||
/* Write Time String */
|
||||
|
||||
/* Write Time String */
|
||||
|
||||
strftime( buf, 9, "%H:%M:%S",
|
||||
localtime( &time_of_day ) );
|
||||
|
||||
|
||||
i += strlen(buf);
|
||||
fputs(buf, run->fp);
|
||||
tmp=0;
|
||||
fwrite((char *)&tmp,1,1,run->fp);
|
||||
i += 1;
|
||||
|
||||
i += 1;
|
||||
|
||||
/* Write Date String */
|
||||
|
||||
|
|
@ -708,9 +697,8 @@ fileInit(runDesc *run)
|
|||
tmp=0;
|
||||
fwrite((char *)&tmp,1,1,run->fp);
|
||||
i += 1;
|
||||
|
||||
|
||||
/* Write Temperature */
|
||||
|
||||
/* Write Temperature */
|
||||
|
||||
ckt=run->circuit;
|
||||
ftmp=ckt->CKTtemp-273.15;
|
||||
|
|
@ -732,45 +720,44 @@ fileInit(runDesc *run)
|
|||
};
|
||||
i += strlen(buf);
|
||||
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;
|
||||
fwrite((char *)&tmp,2,1,run->fp);
|
||||
i += 2;
|
||||
|
||||
/* Write Program ID */
|
||||
/* Write Program ID */
|
||||
|
||||
tmp=0x00011A22;
|
||||
fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
|
||||
i += sizeof(tmp);
|
||||
|
||||
/* Write All-Columns Flag */
|
||||
/* Write All-Columns Flag */
|
||||
|
||||
tmp=0;
|
||||
fwrite((char *)&tmp,2,1,run->fp);
|
||||
i += 2;
|
||||
|
||||
/* Write Complex-Data Flag */
|
||||
/* Write Complex-Data Flag */
|
||||
|
||||
tmp = run->isComplex ? 2 : 1;
|
||||
fwrite((char *)&tmp,2,1,run->fp);
|
||||
i += 2;
|
||||
|
||||
/* Write Datatype Flag (PROBE_ANALOG) */
|
||||
/* Write Datatype Flag (PROBE_ANALOG) */
|
||||
|
||||
tmp = 0;
|
||||
fwrite((char *)&tmp,2,1,run->fp);
|
||||
i += 2;
|
||||
|
||||
/* Write Digital Data Length (meaningless if analogue data) */
|
||||
/* Write Digital Data Length (meaningless if analogue data) */
|
||||
|
||||
tmp=0;
|
||||
fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
|
||||
i += sizeof(tmp);
|
||||
|
||||
/* Write space for no. of rows */
|
||||
/* Write space for no. of rows */
|
||||
|
||||
fflush(run->fp); /* Gotta do this for LATTICE. */
|
||||
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);
|
||||
i += sizeof(tmp);
|
||||
|
||||
/* Write no. of cols */
|
||||
/* Write no. of cols */
|
||||
|
||||
fwrite(&(run->numData),2,1,run->fp);
|
||||
i += 2;
|
||||
#ifdef AlansFixes
|
||||
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);
|
||||
i += 2;
|
||||
|
|
@ -796,20 +785,19 @@ fileInit(runDesc *run)
|
|||
fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp);
|
||||
i += sizeof(ftmp);
|
||||
|
||||
/* Write sweep variable end value */
|
||||
/* Write sweep variable end value */
|
||||
|
||||
ftmp=0;
|
||||
fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp);
|
||||
i += sizeof(ftmp);
|
||||
|
||||
/* Write Secondary Sweep Variable name (null string) */
|
||||
/* Write Secondary Sweep Variable name (null string) */
|
||||
|
||||
tmp=0;
|
||||
fwrite((char *)&tmp,1,1,run->fp);
|
||||
i += 1;
|
||||
|
||||
|
||||
/* Write Digital Section Flag */
|
||||
/* Write Digital Section Flag */
|
||||
|
||||
tmp = 0;
|
||||
fwrite((char *)&tmp,2,1,run->fp);
|
||||
|
|
@ -818,11 +806,9 @@ fileInit(runDesc *run)
|
|||
fflush(run->fp); /* Make sure this gets to disk */
|
||||
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
fileInit_pass2(runDesc *run)
|
||||
{
|
||||
|
|
@ -830,108 +816,106 @@ fileInit_pass2(runDesc *run)
|
|||
char *ch, *end, name[BSIZE_SP], buf[BSIZE_SP];
|
||||
|
||||
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, "sweep") ||
|
||||
cieq(run->data[i].name, "frequency"))
|
||||
(void) sprintf(name, "%s", run->data[i].name);
|
||||
(void) sprintf(name, "%s", run->data[i].name);
|
||||
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';
|
||||
*ch++=')';
|
||||
*ch='\0';
|
||||
*ch='\0';
|
||||
type = SV_CURRENT;
|
||||
}
|
||||
}
|
||||
else if (cieq(name, "time"))
|
||||
type = SV_TIME;
|
||||
else if (cieq(name, "frequency"))
|
||||
type = SV_FREQUENCY;
|
||||
else
|
||||
type = SV_VOLTAGE;
|
||||
|
||||
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) {
|
||||
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);
|
||||
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 */
|
||||
|
||||
/* Allocate Row buffer */
|
||||
/* Allocate Row buffer */
|
||||
|
||||
rowbuflen=(run->numData)*sizeof(float);
|
||||
if (run->isComplex) rowbuflen *=2;
|
||||
rowbuf=(float *)tmalloc(rowbuflen);
|
||||
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fileStartPoint(FILE *fp, bool bin, int num)
|
||||
{
|
||||
if (!bin)
|
||||
fprintf(fp, "%d\t", num - 1);
|
||||
|
||||
/* reset set buffer pointer to zero */
|
||||
/* reset set buffer pointer to zero */
|
||||
|
||||
column = 0;
|
||||
|
||||
column=0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
fileAddRealValue( FILE *fp, bool bin, double value)
|
||||
fileAddRealValue(FILE *fp, bool bin, double value)
|
||||
{
|
||||
if (bin) {
|
||||
if (bin) {
|
||||
if (value<(-FLT_MAX)) {
|
||||
fprintf(stderr,
|
||||
"Warning, double to float conversion overflow !\n");
|
||||
|
|
@ -949,15 +933,11 @@ fileAddRealValue( FILE *fp, bool bin, double value)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
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)) {
|
||||
fprintf(stderr,
|
||||
"Warning, double to float conversion overflow !\n");
|
||||
|
|
@ -987,16 +967,12 @@ fileAddComplexValue(fp, bin, value)
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ARGSUSED */ /* until some code gets written */
|
||||
static void
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1007,28 +983,29 @@ fileEnd(runDesc *run)
|
|||
{
|
||||
long place;
|
||||
int nrows;
|
||||
|
||||
|
||||
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 {
|
||||
/* 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);
|
||||
|
||||
/* deallocate row buffer */
|
||||
|
||||
/* deallocate row buffer */
|
||||
|
||||
tfree(rowbuf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* The plot maintenance routines. */
|
||||
|
||||
|
|
@ -1132,7 +1109,7 @@ plotEnd(runDesc *run)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ParseSpecial takes something of the form "@name[param,index]" and rips
|
||||
* out name, param, andstrchr.
|
||||
|
|
@ -1146,7 +1123,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
|
|||
*dev = *param = *ind = '\0';
|
||||
|
||||
if (*name != '@')
|
||||
return (FALSE);
|
||||
return FALSE;
|
||||
name++;
|
||||
|
||||
s = dev;
|
||||
|
|
@ -1154,7 +1131,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
|
|||
*s++ = *name++;
|
||||
*s = '\0';
|
||||
if (!*name)
|
||||
return (TRUE);
|
||||
return TRUE;
|
||||
name++;
|
||||
|
||||
s = param;
|
||||
|
|
@ -1164,7 +1141,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
|
|||
if (*name == ']')
|
||||
return (!name[1] ? TRUE : FALSE);
|
||||
else if (!*name)
|
||||
return (FALSE);
|
||||
return FALSE;
|
||||
name++;
|
||||
|
||||
s = ind;
|
||||
|
|
@ -1172,9 +1149,9 @@ parseSpecial(char *name, char *dev, char *param, char *ind)
|
|||
*s++ = *name++;
|
||||
*s = '\0';
|
||||
if (*name && !name[1])
|
||||
return (TRUE);
|
||||
return TRUE;
|
||||
else
|
||||
return (FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 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, '('))) {
|
||||
strcpy(buf1, s);
|
||||
if (!(s =strchr(buf1, ')')))
|
||||
return (FALSE);
|
||||
return FALSE;
|
||||
*s = '\0';
|
||||
n1 = buf1;
|
||||
}
|
||||
if ((s =strchr(n2, '('))) {
|
||||
strcpy(buf2, s);
|
||||
if (!(s =strchr(buf2, ')')))
|
||||
return (FALSE);
|
||||
return FALSE;
|
||||
*s = '\0';
|
||||
n2 = buf2;
|
||||
}
|
||||
|
|
@ -1213,24 +1190,24 @@ getSpecial(dataDesc *desc, runDesc *run, IFvalue *val)
|
|||
desc->specName, &desc->specFast, ft_sim, &desc->type,
|
||||
&selector) == OK) {
|
||||
desc->type &= (IF_REAL | IF_COMPLEX); /* mask out other bits */
|
||||
return(TRUE);
|
||||
return TRUE;
|
||||
} else if ((vv = if_getstat(run->circuit, &desc->name[1]))) {
|
||||
/* skip @ sign */
|
||||
/* skip @ sign */
|
||||
desc->type = IF_REAL;
|
||||
if (vv->va_type == VT_REAL)
|
||||
val->rValue = vv->va_real;
|
||||
val->rValue = vv->va_real;
|
||||
else if (vv->va_type == VT_NUM)
|
||||
val->rValue = vv->va_num;
|
||||
val->rValue = vv->va_num;
|
||||
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 {
|
||||
return (FALSE); /* not a real */
|
||||
return FALSE; /* not a real */
|
||||
}
|
||||
tfree(vv);
|
||||
return(TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1288,8 +1265,8 @@ OUTerror(int flags, char *format, IFuid *names)
|
|||
int nindex = 0;
|
||||
|
||||
if ((flags == ERR_INFO) && cp_getvar("printinfo", VT_BOOL,
|
||||
(char *) &printinfo))
|
||||
return;
|
||||
(char *) &printinfo))
|
||||
return;
|
||||
|
||||
for (m = msgs; m->flag; m++)
|
||||
if (flags & m->flag)
|
||||
|
|
@ -1297,10 +1274,10 @@ OUTerror(int flags, char *format, IFuid *names)
|
|||
|
||||
for (s = format, bptr = buf; *s; 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);
|
||||
s++;
|
||||
nindex++;
|
||||
|
|
@ -1312,4 +1289,4 @@ OUTerror(int flags, char *format, IFuid *names)
|
|||
fprintf(cp_err, "%s\n", buf);
|
||||
fflush(cp_err);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ DEVfetlim(double vnew,
|
|||
double vtemp;
|
||||
|
||||
vtsthi = fabs(2*(vold-vto))+2;
|
||||
vtstlo = fabs(vold-vto)*1;
|
||||
vtstlo = fabs(vold-vto)+1;
|
||||
vtox = vto + 3.5;
|
||||
delv = vnew-vold;
|
||||
|
||||
|
|
@ -251,7 +251,10 @@ DEVqmeyer(double vgs, /* initial voltage gate-source */
|
|||
double vddif2;
|
||||
double vgst;
|
||||
|
||||
#define MAGIC_VDS 0.025
|
||||
|
||||
vgst = vgs-von;
|
||||
vdsat = MAX(vdsat, MAGIC_VDS);
|
||||
if (vgst <= -phi) {
|
||||
*capgb = cox/2;
|
||||
*capgs = 0;
|
||||
|
|
@ -263,9 +266,19 @@ DEVqmeyer(double vgs, /* initial voltage gate-source */
|
|||
} else if (vgst <= 0) {
|
||||
*capgb = -vgst*cox/(2*phi);
|
||||
*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 {
|
||||
vds = vgs-vgd;
|
||||
vdsat = MAX(vdsat, MAGIC_VDS);
|
||||
if (vdsat <= vds) {
|
||||
*capgs = cox/3;
|
||||
*capgd = 0;
|
||||
|
|
|
|||
|
|
@ -400,16 +400,16 @@ MOS3load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
* 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) {
|
||||
arg=3*vt/(vbd*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
|
|
@ -717,7 +717,7 @@ MOS3load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
if ( (here->MOS3mode*vds) <= vdsat ) {
|
||||
if ( (model->MOS3maxDriftVel > 0.0) ||
|
||||
(model->MOS3alpha == 0.0) ||
|
||||
(ckt->CKTbadMos3) ) goto line700;
|
||||
(ckt->CKTbadMos3) ) goto line700;
|
||||
else {
|
||||
arga = (here->MOS3mode*vds)/vdsat;
|
||||
delxl = sqrt(model->MOS3kappa*model->MOS3alpha*vdsat/8);
|
||||
|
|
@ -730,133 +730,134 @@ MOS3load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
ddldvb = 0.0;
|
||||
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;
|
||||
else
|
||||
else
|
||||
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);
|
||||
dldem = 0.5*(arga/argb-1.0)*model->MOS3alpha;
|
||||
} else {
|
||||
} else {
|
||||
dldvd = 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)*
|
||||
model->MOS3alpha);
|
||||
dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat);
|
||||
} else {
|
||||
delxl = sqrt(model->MOS3kappa*model->MOS3alpha*
|
||||
((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/
|
||||
(4.0*delxl));
|
||||
arga = 4.0*(EffectiveLength-delxl)*(EffectiveLength-delxl)/
|
||||
(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)));*/
|
||||
|
||||
/*
|
||||
*.....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;
|
||||
}
|
||||
/*
|
||||
*.....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
|
||||
*/
|
||||
}
|
||||
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);
|
||||
dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat);
|
||||
} else {
|
||||
delxl = sqrt(model->MOS3kappa*model->MOS3alpha*
|
||||
((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/
|
||||
(4.0*delxl));
|
||||
arga = 4.0*(EffectiveLength-delxl)*(EffectiveLength-delxl)/
|
||||
(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)));*/
|
||||
|
||||
/*
|
||||
*.....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;
|
||||
}
|
||||
/*
|
||||
*.....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 */
|
||||
|
|
@ -1239,7 +1240,6 @@ MOS3load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
*(here->MOS3SPdpPtr) += (-here->MOS3gds-
|
||||
xrev*(here->MOS3gm+here->MOS3gmbs));
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue