Added patches extracted from Alan Gillespie's code. Documentation and
author's file not updated.
This commit is contained in:
parent
37fe87bb96
commit
0875108157
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -76,7 +77,7 @@ all_show(wordlist *wl, int mode)
|
|||
|
||||
if (!cp_getvar("width", VT_NUM, (char *) &screen_width))
|
||||
screen_width = DEF_WIDTH;
|
||||
count = screen_width / 11 - 1;
|
||||
count = (screen_width - LEFT_WIDTH) / (DEV_WIDTH + 1);
|
||||
|
||||
n = 0;
|
||||
do {
|
||||
|
|
@ -168,7 +169,7 @@ all_show(wordlist *wl, int mode)
|
|||
|
||||
i = 0;
|
||||
do {
|
||||
printf(" device ");
|
||||
printf("%*s", LEFT_WIDTH, "device");
|
||||
j = dgen_for_n(dg, count, printstr, "n", i);
|
||||
i += 1;
|
||||
printf("\n");
|
||||
|
|
@ -177,7 +178,7 @@ all_show(wordlist *wl, int mode)
|
|||
if (ft_sim->devices[dg->dev_type_no]->numModelParms) {
|
||||
i = 0;
|
||||
do {
|
||||
printf(" model ");
|
||||
printf("%*s", LEFT_WIDTH, "model");
|
||||
j = dgen_for_n(dg, count, printstr, "m", i);
|
||||
i += 1;
|
||||
printf("\n");
|
||||
|
|
@ -200,7 +201,7 @@ all_show(wordlist *wl, int mode)
|
|||
n += 1;
|
||||
i = 0;
|
||||
do {
|
||||
printf(" model ");
|
||||
printf("%*s", LEFT_WIDTH, "model");
|
||||
j = dgen_for_n(dg, count, printstr, "m", i);
|
||||
i += 1;
|
||||
printf("\n");
|
||||
|
|
@ -236,16 +237,16 @@ printstr(dgen *dg, char *name)
|
|||
{
|
||||
if (*name == 'n') {
|
||||
if (dg->instance)
|
||||
printf(" %9.9s", dg->instance->GENname);
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname);
|
||||
else
|
||||
printf(" <???????>");
|
||||
printf(" %*s", DEV_WIDTH, "<???????>");
|
||||
} else if (*name == 'm') {
|
||||
if (dg->model)
|
||||
printf(" %9.9s", dg->model->GENmodName);
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName);
|
||||
else
|
||||
printf(" <???????>");
|
||||
printf(" %*s", DEV_WIDTH, "<???????>");
|
||||
} else
|
||||
printf(" <error> ");
|
||||
printf(" %*s", DEV_WIDTH, "<error>");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -278,9 +279,10 @@ param_forall(dgen *dg, int flags)
|
|||
j = 0;
|
||||
do {
|
||||
if (!j)
|
||||
printf("%10.10s", plist[i].keyword);
|
||||
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH,
|
||||
plist[i].keyword);
|
||||
else
|
||||
printf(" ");
|
||||
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, " ");
|
||||
k = dgen_for_n(dg, count, printvals,
|
||||
(char *) (plist + i), j);
|
||||
printf("\n");
|
||||
|
|
@ -323,9 +325,9 @@ listparam(wordlist *p, dgen *dg)
|
|||
j = 0;
|
||||
do {
|
||||
if (!j)
|
||||
printf("%10.10s", p->wl_word);
|
||||
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
|
||||
else
|
||||
printf(" ");
|
||||
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, " ");
|
||||
k = dgen_for_n(dg, count, printvals, plist + i, j);
|
||||
printf("\n");
|
||||
j += 1;
|
||||
|
|
@ -334,9 +336,9 @@ listparam(wordlist *p, dgen *dg)
|
|||
j = 0;
|
||||
do {
|
||||
if (!j)
|
||||
printf("%10.10s", p->wl_word);
|
||||
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
|
||||
else
|
||||
printf(" ");
|
||||
printf("%*s", LEFT_WIDTH, " ");
|
||||
k = dgen_for_n(dg, count, bogus1, 0, j);
|
||||
printf("\n");
|
||||
j += 1;
|
||||
|
|
@ -346,9 +348,9 @@ listparam(wordlist *p, dgen *dg)
|
|||
j = 0;
|
||||
do {
|
||||
if (!j)
|
||||
printf("%10.10s", p->wl_word);
|
||||
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
|
||||
else
|
||||
printf(" ");
|
||||
printf("%*s", LEFT_WIDTH, " ");
|
||||
k = dgen_for_n(dg, count, bogus2, 0, j);
|
||||
printf("\n");
|
||||
j += 1;
|
||||
|
|
@ -358,13 +360,13 @@ listparam(wordlist *p, dgen *dg)
|
|||
|
||||
int bogus1(dgen *dg)
|
||||
{
|
||||
printf(" ---------");
|
||||
printf(" %*s", DEV_WIDTH, "---------");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bogus2(dgen *dg)
|
||||
{
|
||||
printf(" ?????????");
|
||||
printf(" %*s", DEV_WIDTH, "?????????");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -400,54 +402,54 @@ printvals(dgen *dg, IFparm *p, int i)
|
|||
if (p->dataType & IF_VECTOR) {
|
||||
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
|
||||
case IF_FLAG:
|
||||
printf(" % 9d", val.v.vec.iVec[i]);
|
||||
printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]);
|
||||
break;
|
||||
case IF_INTEGER:
|
||||
printf(" % 9d", val.v.vec.iVec[i]);
|
||||
printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]);
|
||||
break;
|
||||
case IF_REAL:
|
||||
printf(" % 9.3g", val.v.vec.rVec[i]);
|
||||
printf(" % *.6g", DEV_WIDTH, val.v.vec.rVec[i]);
|
||||
break;
|
||||
case IF_COMPLEX:
|
||||
if (!(i % 2))
|
||||
printf(" % 9.3g", val.v.vec.cVec[i / 2].real);
|
||||
printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].real);
|
||||
else
|
||||
printf(" % 9.3g", val.v.vec.cVec[i / 2].imag);
|
||||
printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].imag);
|
||||
break;
|
||||
case IF_STRING:
|
||||
printf(" %9.9s", val.v.vec.sVec[i]);
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]);
|
||||
break;
|
||||
case IF_INSTANCE:
|
||||
printf(" %9.9s", val.v.vec.uVec[i]);
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]);
|
||||
break;
|
||||
default:
|
||||
printf(" ******** ");
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
|
||||
}
|
||||
} else {
|
||||
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
|
||||
case IF_FLAG:
|
||||
printf(" % 9d", val.iValue);
|
||||
printf(" % *d", DEV_WIDTH, val.iValue);
|
||||
break;
|
||||
case IF_INTEGER:
|
||||
printf(" % 9d", val.iValue);
|
||||
printf(" % *d", DEV_WIDTH, val.iValue);
|
||||
break;
|
||||
case IF_REAL:
|
||||
printf(" % 9.3g", val.rValue);
|
||||
printf(" % *.6g", DEV_WIDTH, val.rValue);
|
||||
break;
|
||||
case IF_COMPLEX:
|
||||
if (i % 2)
|
||||
printf(" % 9.3g", val.cValue.real);
|
||||
printf(" % *.6g", DEV_WIDTH, val.cValue.real);
|
||||
else
|
||||
printf(" % 9.3g", val.cValue.imag);
|
||||
printf(" % *.6g", DEV_WIDTH, val.cValue.imag);
|
||||
break;
|
||||
case IF_STRING:
|
||||
printf(" %9.9s", val.sValue);
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.sValue);
|
||||
break;
|
||||
case IF_INSTANCE:
|
||||
printf(" %9.9s ", val.uValue);
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.uValue);
|
||||
break;
|
||||
default:
|
||||
printf(" ******** ");
|
||||
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
/*************
|
||||
* Header file for device.c
|
||||
* 1999 E. Rouat
|
||||
* Modified: 2000 AlansFixes
|
||||
************/
|
||||
|
||||
#ifndef DEVICE_H_INCLUDED
|
||||
#define DEVICE_H_INCLUDED
|
||||
|
||||
#define LEFT_WIDTH 11
|
||||
#define DEV_WIDTH 21
|
||||
|
||||
void com_showmod(wordlist *wl);
|
||||
void com_show(wordlist *wl);
|
||||
int printstr(dgen *dg, char *name);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -154,19 +155,14 @@ ft_cktcoms(bool terse)
|
|||
|
||||
if (!ft_curckt)
|
||||
return 1;
|
||||
if (!ft_curckt->ci_commands)
|
||||
if (!ft_curckt->ci_commands && !setcplot("op"))
|
||||
goto nocmds;
|
||||
coms = ft_curckt->ci_commands;
|
||||
cp_interactive = FALSE;
|
||||
|
||||
/* Circuit name */
|
||||
fprintf(cp_out, "Circuit: %s\nDate: %s\n\n", ft_curckt->ci_name,
|
||||
datestring());
|
||||
fprintf(cp_out, "\n");
|
||||
|
||||
/* Listing */
|
||||
if (ft_listprint) {
|
||||
if (terse)
|
||||
if (FALSE)
|
||||
fprintf(cp_err, ".options: no listing, rawfile was generated.\n");
|
||||
else
|
||||
inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options,
|
||||
|
|
@ -174,12 +170,12 @@ ft_cktcoms(bool terse)
|
|||
}
|
||||
|
||||
/* If there was a .op line, then we have to do the .op output. */
|
||||
if (setcplot("op")) {
|
||||
if (terse) {
|
||||
if (setcplot("op") && (plot_cur->pl_dvecs->v_realdata!=NULL)) {
|
||||
if (FALSE) {
|
||||
fprintf(cp_out, "OP information in rawfile.\n");
|
||||
} else {
|
||||
fprintf(cp_out, "\nOperating point information:\n\n");
|
||||
fprintf(cp_out, "\tNode\tVoltage\n");
|
||||
fprintf(cp_out, "\t%-30s%15s\n", "Node", "Voltage");
|
||||
fprintf(cp_out, "\t%-30s%15s\n", "----", "-------");
|
||||
fprintf(cp_out, "\t----\t-------\n");
|
||||
for (v = plot_cur->pl_dvecs; v; v = v->v_next) {
|
||||
if (!isreal(v)) {
|
||||
|
|
@ -188,17 +184,17 @@ ft_cktcoms(bool terse)
|
|||
v->v_name);
|
||||
continue;
|
||||
}
|
||||
if (v->v_type == SV_VOLTAGE)
|
||||
fprintf(cp_out, "\t%s\t%s\n", v->v_name,
|
||||
if ((v->v_type == SV_VOLTAGE) && (*(v->v_name)!='@'))
|
||||
fprintf(cp_out, "\t%-30s%15s\n", v->v_name,
|
||||
printnum(v->v_realdata[0]));
|
||||
}
|
||||
fprintf(cp_out, "\n\tSource\tCurrent\n");
|
||||
fprintf(cp_out, "\t------\t-------\n\n");
|
||||
for (v = plot_cur->pl_dvecs; v; v = v->v_next)
|
||||
if (v->v_type == SV_CURRENT)
|
||||
fprintf(cp_out, "\t%s\t%s\n", v->v_name,
|
||||
printnum(v->v_realdata[0]));
|
||||
fprintf(cp_out, "\n");
|
||||
fprintf(cp_out, "\t%-30s%15s\n", v->v_name,
|
||||
printnum(v->v_realdata[0]));
|
||||
fprintf(cp_out, "\n");
|
||||
|
||||
if (!ft_nomod)
|
||||
com_showmod(&all);
|
||||
|
|
@ -320,7 +316,7 @@ nocmds:
|
|||
|
||||
/* The options */
|
||||
if (ft_optsprint) {
|
||||
fprintf(cp_err, "Options:\n\n");
|
||||
fprintf(cp_out, "Options:\n\n");
|
||||
cp_vprint();
|
||||
(void) putc('\n', cp_out);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,10 +21,12 @@ Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "ifsim.h"
|
||||
#include "jobdefs.h"
|
||||
#include "iferrmsg.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);
|
||||
|
|
@ -56,11 +59,14 @@ static void freeRun(runDesc *run);
|
|||
#define DOUBLE_PRECISION 15
|
||||
|
||||
|
||||
|
||||
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". */
|
||||
|
||||
|
||||
/* The two "begin plot" routines share all their internals... */
|
||||
|
||||
|
||||
|
|
@ -110,7 +116,9 @@ 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];
|
||||
bool saveall = TRUE;
|
||||
char *ch, tmpname[BSIZE_SP];
|
||||
bool saveall = TRUE;
|
||||
bool savealli = FALSE;
|
||||
char *an_name;
|
||||
|
||||
/* Check to see if we want to print informational data. */
|
||||
|
|
@ -144,12 +152,18 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
savesused[i] = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (cieq(saves[i].name, "all")) {
|
||||
if (cieq(saves[i].name, "all") || cieq(saves[i].name, "allv")) {
|
||||
saveall = TRUE;
|
||||
savesused[i] = TRUE;
|
||||
saves[i].used = 1;
|
||||
continue;
|
||||
}
|
||||
if (cieq(saves[i].name, "alli")) {
|
||||
savealli = true;
|
||||
savesused[i] = true;
|
||||
saves[i].used = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -183,10 +197,73 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
|
|||
} else {
|
||||
for (i = 0; i < numNames; i++)
|
||||
if (!refName || !name_eq(dataNames[i], refName)) {
|
||||
addDataDesc(run, dataNames[i], dataType, i);
|
||||
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")) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass 1 and a bit. */
|
||||
if (savealli) {
|
||||
depind=0;
|
||||
for (i = 0; i < numNames; i++) {
|
||||
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")) {
|
||||
tmpname[0]='@';
|
||||
tmpname[1]='\0';
|
||||
strncat(tmpname, dataNames[i], BSIZE_SP-1);
|
||||
ch=strchr(tmpname, '#');
|
||||
|
||||
if (strstr(ch, "#collector")!=NULL) {
|
||||
strcpy(ch, "[ic]");
|
||||
} else if (strstr(ch, "#base")!=NULL) {
|
||||
strcpy(ch, "[ib]");
|
||||
} else if (strstr(ch, "#emitter")!=NULL) {
|
||||
strcpy(ch, "[ie]");
|
||||
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) {
|
||||
addSpecialDesc(run, tmpname, namebuf, parambuf, depind);
|
||||
};
|
||||
strcpy(ch, "[is]");
|
||||
} else if (strstr(ch, "#drain")!=NULL) {
|
||||
strcpy(ch, "[id]");
|
||||
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) {
|
||||
addSpecialDesc(run, tmpname, namebuf, parambuf, depind);
|
||||
};
|
||||
strcpy(ch, "[ig]");
|
||||
} else if (strstr(ch, "#source")!=NULL) {
|
||||
strcpy(ch, "[is]");
|
||||
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) {
|
||||
addSpecialDesc(run, tmpname, namebuf, parambuf, depind);
|
||||
};
|
||||
strcpy(ch, "[ib]");
|
||||
} else
|
||||
if ((strstr(ch, "#internal")!=NULL)&&(tmpname[1]=='d')) {
|
||||
strcpy(ch, "[id]");
|
||||
} else {
|
||||
fprintf(cp_err,
|
||||
"Debug: could output current for %s\n", tmpname);
|
||||
continue;
|
||||
};
|
||||
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) {
|
||||
if (*depbuf) { fprintf( stderr,
|
||||
"Warning : unexpected dependant variable on %s\n", tmpname);
|
||||
} else {
|
||||
addSpecialDesc(run, tmpname, namebuf, parambuf, depind);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Pass 2. */
|
||||
for (i = 0; i < numsaves; i++) {
|
||||
if (savesused[i])
|
||||
|
|
@ -265,7 +342,9 @@ addDataDesc(runDesc *run, char *name, int type, int ind)
|
|||
dataDesc *data;
|
||||
|
||||
if (!run->numData)
|
||||
run->data = (dataDesc *) tmalloc(sizeof (dataDesc));
|
||||
{run->data = (dataDesc *) tmalloc(32768);
|
||||
run->data = (dataDesc *) trealloc(run->data, sizeof (dataDesc));
|
||||
}
|
||||
else
|
||||
run->data = (dataDesc *) trealloc((char *) run->data,
|
||||
sizeof (dataDesc) * (run->numData + 1));
|
||||
|
|
@ -296,7 +375,8 @@ addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind)
|
|||
char *unique; /* unique char * from back-end */
|
||||
|
||||
if (!run->numData)
|
||||
run->data = (dataDesc *) tmalloc(sizeof (dataDesc));
|
||||
{run->data = (dataDesc *) tmalloc(32768);
|
||||
run->data = (dataDesc *) trealloc(run->data, sizeof (dataDesc));}
|
||||
else
|
||||
run->data = (dataDesc *) trealloc((char *) run->data,
|
||||
sizeof (dataDesc) * (run->numData + 1));
|
||||
|
|
@ -344,12 +424,23 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
fileStartPoint(run->fp, run->binary, run->pointCount);
|
||||
|
||||
if (run->refIndex != -1) {
|
||||
if (run->isComplex)
|
||||
if (run->isComplex){
|
||||
fileAddComplexValue(run->fp, run->binary, refValue->cValue);
|
||||
else
|
||||
currclock = clock();
|
||||
if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) {
|
||||
fprintf(stderr, " Reference value : % 12.5e\r",
|
||||
refValue->cValue.real);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for (i = 0; i < run->numData; i++) {
|
||||
/* we've already printed reference vec first */
|
||||
if (run->data[i].outIndex == -1) continue;
|
||||
|
|
@ -368,7 +459,22 @@ 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);
|
||||
if (run->isComplex) {
|
||||
val.cValue.real=0;
|
||||
val.cValue.imag=0;
|
||||
fileAddComplexValue(run->fp, run->binary,
|
||||
val.cValue);
|
||||
} else {
|
||||
val.rValue=0;
|
||||
fileAddRealValue(run->fp, run->binary,
|
||||
val.rValue);
|
||||
};
|
||||
continue;
|
||||
};
|
||||
if (run->data[i].type == IF_REAL)
|
||||
fileAddRealValue(run->fp, run->binary,
|
||||
val.rValue);
|
||||
|
|
@ -380,6 +486,10 @@ 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;
|
||||
};
|
||||
} else {
|
||||
for (i = 0; i < run->numData; i++) {
|
||||
if (run->data[i].outIndex == -1) {
|
||||
|
|
@ -529,7 +639,12 @@ static void
|
|||
fileInit(runDesc *run)
|
||||
{
|
||||
char buf[513];
|
||||
int i;
|
||||
int i, tmp, sweep;
|
||||
float ftmp;
|
||||
time_t time_of_day;
|
||||
CKTcircuit *ckt;
|
||||
|
||||
lastclock = clock();
|
||||
|
||||
/* This is a hack. */
|
||||
run->isComplex = FALSE;
|
||||
|
|
@ -538,34 +653,163 @@ fileInit(runDesc *run)
|
|||
run->isComplex = TRUE;
|
||||
|
||||
i = 0;
|
||||
|
||||
/* Write PROBE version marker */
|
||||
|
||||
tmp=0xFFFFFFFF;
|
||||
fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
|
||||
i += sizeof(tmp);
|
||||
tmp=0xF3FFFFFF;
|
||||
fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
|
||||
i += sizeof(tmp);
|
||||
|
||||
/* Write Title String */
|
||||
|
||||
sprintf(buf, "Title: %s\n", run->name);
|
||||
i += strlen(buf);
|
||||
fputs(buf, run->fp);
|
||||
sprintf(buf, "Date: %s\n", datestring());
|
||||
|
||||
/* 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 */
|
||||
|
||||
strftime( buf, 9, "%H:%M:%S",
|
||||
localtime( &time_of_day ) );
|
||||
|
||||
i += strlen(buf);
|
||||
fputs(buf, run->fp);
|
||||
sprintf(buf, "Plotname: %s\n", run->type);
|
||||
tmp=0;
|
||||
fwrite((char *)&tmp,1,1,run->fp);
|
||||
i += 1;
|
||||
|
||||
/* Write Date String */
|
||||
|
||||
strftime( buf, 9, "%d/%m/%y",
|
||||
localtime( &time_of_day ) );
|
||||
|
||||
i += strlen(buf);
|
||||
fputs(buf, run->fp);
|
||||
sprintf(buf, "Flags: %s\n", run->isComplex ? "complex" : "real");
|
||||
i += strlen(buf);
|
||||
fputs(buf, run->fp);
|
||||
sprintf(buf, "No. Variables: %d\n", run->numData);
|
||||
i += strlen(buf);
|
||||
fputs(buf, run->fp);
|
||||
sprintf(buf, "No. Points: ");
|
||||
tmp=0;
|
||||
fwrite((char *)&tmp,1,1,run->fp);
|
||||
i += 1;
|
||||
|
||||
/* Write Temperature */
|
||||
|
||||
ckt=run->circuit;
|
||||
ftmp=ckt->CKTtemp-273.15;
|
||||
fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp);
|
||||
i += sizeof(ftmp);
|
||||
|
||||
|
||||
/* Write Analysis Type */
|
||||
|
||||
if (strnicmp(run->type,"AC",2)==0) {
|
||||
sprintf(buf, "AC Sweep");
|
||||
sweep=2;
|
||||
} else if (strnicmp(run->type,"DC",2)==0) {
|
||||
sprintf(buf, "DC Sweep");
|
||||
sweep=1;
|
||||
} else if (strnicmp(run->type,"Tran",4)==0) {
|
||||
sprintf(buf, "Transient Analysis");
|
||||
sweep=4;
|
||||
};
|
||||
i += strlen(buf);
|
||||
fputs(buf, run->fp);
|
||||
|
||||
/* 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 */
|
||||
|
||||
tmp=0x00011A22;
|
||||
fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
|
||||
i += sizeof(tmp);
|
||||
|
||||
/* Write All-Columns Flag */
|
||||
|
||||
tmp=0;
|
||||
fwrite((char *)&tmp,2,1,run->fp);
|
||||
i += 2;
|
||||
|
||||
/* Write Complex-Data Flag */
|
||||
|
||||
tmp = run->isComplex ? 2 : 1;
|
||||
fwrite((char *)&tmp,2,1,run->fp);
|
||||
i += 2;
|
||||
|
||||
/* Write Datatype Flag (PROBE_ANALOG) */
|
||||
|
||||
tmp = 0;
|
||||
fwrite((char *)&tmp,2,1,run->fp);
|
||||
i += 2;
|
||||
|
||||
/* 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 */
|
||||
|
||||
fflush(run->fp); /* Gotta do this for LATTICE. */
|
||||
if (run->fp == stdout || (run->pointPos = ftell(run->fp)) <= 0)
|
||||
run->pointPos = i;
|
||||
fprintf(run->fp, "0 \n"); /* Save 8 spaces here. */
|
||||
tmp=0;
|
||||
fwrite((char *)&tmp,sizeof(tmp),1,run->fp);
|
||||
i += sizeof(tmp);
|
||||
|
||||
fprintf(run->fp, "Command: version %s\n", ft_sim->version);
|
||||
fprintf(run->fp, "Variables:\n");
|
||||
/* 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 */
|
||||
|
||||
fwrite((char *)&sweep,2,1,run->fp);
|
||||
i += 2;
|
||||
|
||||
/* Write sweep variable start value */
|
||||
|
||||
ftmp=0;
|
||||
fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp);
|
||||
i += sizeof(ftmp);
|
||||
|
||||
/* 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) */
|
||||
|
||||
tmp=0;
|
||||
fwrite((char *)&tmp,1,1,run->fp);
|
||||
i += 1;
|
||||
|
||||
/* Write Digital Section Flag */
|
||||
|
||||
tmp = 0;
|
||||
fwrite((char *)&tmp,2,1,run->fp);
|
||||
i += 2;
|
||||
|
||||
fflush(run->fp); /* Make sure this gets to disk */
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -573,34 +817,88 @@ fileInit_pass2(runDesc *run)
|
|||
{
|
||||
int i, type;
|
||||
char *name, buf[BSIZE_SP];
|
||||
char *ch, *end;
|
||||
|
||||
for (i = 0; i < run->numData; i++) {
|
||||
if (isdigit(*run->data[i].name)) {
|
||||
(void) sprintf(buf, "V(%s)", run->data[i].name);
|
||||
name = buf;
|
||||
} else {
|
||||
name = run->data[i].name;
|
||||
}
|
||||
if (substring("#branch", name))
|
||||
|
||||
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);
|
||||
else
|
||||
(void) sprintf(name, "V(%s)", run->data[i].name);
|
||||
|
||||
if (ch=strstr(name, "#branch")) {
|
||||
name[0]='I';
|
||||
*ch++=')';
|
||||
*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);
|
||||
};
|
||||
|
||||
fprintf(run->fp, "\t%d\t%s\t%s", i, name,
|
||||
ft_typenames(type));
|
||||
if (run->data[i].gtype == GRID_XLOG)
|
||||
fprintf(run->fp, "\tgrid=3");
|
||||
fprintf(run->fp, "\n");
|
||||
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++;
|
||||
};
|
||||
};
|
||||
|
||||
fprintf(run->fp, "%s", name);
|
||||
tmp=0;
|
||||
fwrite((char*)&tmp,1,1,run->fp);
|
||||
|
||||
}
|
||||
|
||||
fprintf(run->fp, "%s:\n", run->binary ? "Binary" : "Values");
|
||||
fflush(run->fp); /* Make all sure this gets to disk */
|
||||
|
||||
/* Allocate Row buffer */
|
||||
|
||||
rowbuflen=(run->numData)*sizeof(float);
|
||||
if (run->isComplex) rowbuflen *=2;
|
||||
rowbuf=(float *)tmalloc(rowbuflen);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -608,6 +906,11 @@ fileStartPoint(FILE *fp, bool bin, int num)
|
|||
{
|
||||
if (!bin)
|
||||
fprintf(fp, "%d\t", num - 1);
|
||||
|
||||
/* reset set buffer pointer to zero */
|
||||
|
||||
column = 0;
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -615,23 +918,53 @@ fileStartPoint(FILE *fp, bool bin, int num)
|
|||
static void
|
||||
fileAddRealValue(FILE *fp, bool bin, double value)
|
||||
{
|
||||
if (bin)
|
||||
fwrite((char *) &value, sizeof (double), 1, fp);
|
||||
else
|
||||
fprintf(fp, "\t%.*e\n", DOUBLE_PRECISION, value);
|
||||
|
||||
return;
|
||||
if (bin) {
|
||||
if (value<(-FLT_MAX)) {
|
||||
fprintf(stderr,
|
||||
"Warning, double to float conversion overflow !\n");
|
||||
rowbuf[column++]=(-FLT_MAX);
|
||||
} else if (value>(FLT_MAX)) {
|
||||
fprintf(stderr,
|
||||
"Warning, double to float conversion overflow !\n");
|
||||
rowbuf[column++]=FLT_MAX;
|
||||
} else {
|
||||
rowbuf[column++]=value;
|
||||
};
|
||||
} else
|
||||
fprintf(fp, "\t%.*e\n", DOUBLE_PRECISION, value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
fileAddComplexValue(FILE *fp, bool bin, IFcomplex value)
|
||||
{
|
||||
|
||||
if (bin) {
|
||||
fwrite((char *) &value.real, sizeof (double), 1, fp);
|
||||
fwrite((char *) &value.imag, sizeof (double), 1, fp);
|
||||
} else {
|
||||
fprintf(fp, "\t%.*e,%.*e\n", DOUBLE_PRECISION, value.real,
|
||||
if (bin) {
|
||||
if (value.real<(-FLT_MAX)) {
|
||||
fprintf(stderr,
|
||||
"Warning, double to float conversion overflow !\n");
|
||||
rowbuf[column++]=(-FLT_MAX);
|
||||
} else if (value.real>(FLT_MAX)) {
|
||||
fprintf(stderr,
|
||||
"Warning, double to float conversion overflow !\n");
|
||||
rowbuf[column++]=FLT_MAX;
|
||||
} else {
|
||||
rowbuf[column++]=value.real;
|
||||
};
|
||||
if (value.imag<(-FLT_MAX)) {
|
||||
fprintf(stderr,
|
||||
"Warning, double to float conversion overflow !\n");
|
||||
rowbuf[column++]=(-FLT_MAX);
|
||||
} else if (value.imag>(FLT_MAX)) {
|
||||
fprintf(stderr,
|
||||
"Warning, double to float conversion overflow !\n");
|
||||
rowbuf[column++]=FLT_MAX;
|
||||
} else {
|
||||
rowbuf[column++]=value.imag;
|
||||
};
|
||||
} else {
|
||||
fprintf(fp, "\t%.*e,%.*e\n", DOUBLE_PRECISION, value.real,
|
||||
DOUBLE_PRECISION, value.imag);
|
||||
}
|
||||
|
||||
|
|
@ -641,6 +974,8 @@ fileAddComplexValue(FILE *fp, bool bin, IFcomplex value)
|
|||
static void
|
||||
fileEndPoint(FILE *fp, bool bin)
|
||||
{
|
||||
/* write row buffer to file */
|
||||
fwrite((char *)rowbuf, rowbuflen, 1, fp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -650,11 +985,15 @@ static void
|
|||
fileEnd(runDesc *run)
|
||||
{
|
||||
long place;
|
||||
int nrows;
|
||||
|
||||
|
||||
if (run->fp != stdout) {
|
||||
place = ftell(run->fp);
|
||||
fseek(run->fp, run->pointPos, 0);
|
||||
fprintf(run->fp, "%d", run->pointCount);
|
||||
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 */
|
||||
|
|
@ -662,6 +1001,10 @@ fileEnd(runDesc *run)
|
|||
}
|
||||
fflush(run->fp);
|
||||
|
||||
/* deallocate row buffer */
|
||||
|
||||
tfree(rowbuf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -34,6 +35,8 @@ extern struct dbcomm *dbs;
|
|||
|
||||
FILE *rawfileFp;
|
||||
bool rawfileBinary;
|
||||
#define RAWBUF_SIZE 32768
|
||||
char rawfileBuf[RAWBUF_SIZE];
|
||||
|
||||
void
|
||||
com_scirc(wordlist *wl)
|
||||
|
|
@ -212,6 +215,7 @@ dosim(char *what, wordlist *wl)
|
|||
if (!*wl->wl_word)
|
||||
rawfileFp = stdout;
|
||||
else if (!(rawfileFp = fopen(wl->wl_word, "w"))) {
|
||||
setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE);
|
||||
perror(wl->wl_word);
|
||||
ft_setflag = FALSE;
|
||||
return 1;
|
||||
|
|
@ -249,7 +253,12 @@ dosim(char *what, wordlist *wl)
|
|||
ft_curckt->ci_inprogress = FALSE;
|
||||
}
|
||||
if (rawfileFp)
|
||||
(void) fclose(rawfileFp);
|
||||
if (ftell(rawfileFp)==0) {
|
||||
(void) fclose(rawfileFp);
|
||||
(void) remove(wl->wl_word);
|
||||
} else {
|
||||
(void) fclose(rawfileFp);
|
||||
};
|
||||
ft_curckt->ci_runonce = TRUE;
|
||||
ft_setflag = FALSE;
|
||||
return err;
|
||||
|
|
@ -284,6 +293,14 @@ bool
|
|||
ft_getOutReq(FILE **fpp, struct plot **plotp, bool *binp, char *name, char *title)
|
||||
{
|
||||
/*struct plot *pl;*/
|
||||
#ifndef BATCH
|
||||
struct plot *pl;
|
||||
|
||||
if ( (strcmp(name, "Operating Point")==0) ||
|
||||
(strcmp(name, "AC Operating Point")==0) ) {
|
||||
return (false);
|
||||
};
|
||||
#endif
|
||||
|
||||
if (rawfileFp) {
|
||||
*fpp = rawfileFp;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -92,6 +93,15 @@ if_inpdeck(struct line *deck, INPtables **tab)
|
|||
INPpas2((void *) ckt, (card *) deck->li_next,
|
||||
(INPtables *) *tab,ft_curckt->ci_defTask);
|
||||
INPkillMods();
|
||||
|
||||
/* INPpas2 has been modified to ignore .NODESET and .IC cards. These are
|
||||
* left till INPpas3 so that we can check for nodeset/ic of non-existant
|
||||
* nodes.
|
||||
*/
|
||||
|
||||
INPpas3((GENERIC *) ckt, (card *) deck->li_next,
|
||||
(INPtables *) *tab,ft_curckt->ci_defTask);
|
||||
|
||||
return (ckt);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -114,6 +115,14 @@ inp_subcktexpand(struct line *deck)
|
|||
|
||||
ll = doit(deck);
|
||||
|
||||
/* Now check to see if there are still subckt instances undefined... */
|
||||
if (ll!=NULL) for (c = ll; c; c = c->li_next)
|
||||
if (ciprefix(invoke, c->li_line)) {
|
||||
fprintf(cp_err, "Error: unknown subckt: %s\n",
|
||||
c->li_line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (ll);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 1985 Thomas L. Quarles
|
||||
* Modified 1999 Paolo Nenzi - Removed non STDC definitions
|
||||
* Modified 2000 AlansFixes
|
||||
*/
|
||||
#ifndef CKT
|
||||
#define CKT "CKTdefs.h $Revision$ on $Date$ "
|
||||
|
|
@ -173,6 +174,7 @@ typedef struct {
|
|||
double CKTlteAbstol;
|
||||
#endif /* NEWTRUNC */
|
||||
double CKTgmin; /* Parallel Conductance --- */
|
||||
double CKTgshunt;
|
||||
double CKTdelmin; /* ??? */
|
||||
double CKTtrtol; /* ??? */
|
||||
double CKTfinalTime; /* ??? */
|
||||
|
|
@ -184,7 +186,9 @@ typedef struct {
|
|||
double CKTdiagGmin; /* ??? */
|
||||
int CKTnumSrcSteps; /* ??? */
|
||||
int CKTnumGminSteps; /* ??? */
|
||||
double CKTgminFactor;
|
||||
int CKTnoncon; /* ??? */
|
||||
double CKTdefaultMosM;
|
||||
double CKTdefaultMosL; /* Default Channel Lenght of MOS devices */
|
||||
double CKTdefaultMosW; /* Default Channel Width of MOS devics */
|
||||
double CKTdefaultMosAD; /* Default Drain Area of MOS */
|
||||
|
|
@ -211,6 +215,7 @@ typedef struct {
|
|||
lines */
|
||||
unsigned int CKTbadMos3:1; /* Use old, unfixed MOS3 equations */
|
||||
unsigned int CKTkeepOpInfo:1; /* flag for small signal analyses */
|
||||
unsigned int CKTcopyNodesets:1; /* NodesetFIX */
|
||||
int CKTtroubleNode; /* Non-convergent node number */
|
||||
GENinstance *CKTtroubleElt; /* Non-convergent device instance */
|
||||
|
||||
|
|
@ -289,7 +294,7 @@ extern int CKTsetBreak( CKTcircuit *, double );
|
|||
extern int CKTsetNodPm( void *, void *, int , IFvalue *, IFvalue *);
|
||||
extern int CKTsetOpt( void *, void *, int , IFvalue *);
|
||||
extern int CKTsetup( CKTcircuit *);
|
||||
extern int CKTunsetup(CKTcircuit *ckt);
|
||||
extern int CKTunsetup(CKTcircuit *);
|
||||
extern int CKTtemp( CKTcircuit *);
|
||||
extern char *CKTtrouble(void *, char *);
|
||||
extern void CKTterr( int , CKTcircuit *, double *);
|
||||
|
|
@ -333,6 +338,8 @@ extern int NIpzSym(PZtrial **, PZtrial *);
|
|||
extern int NIpzSym2(PZtrial **, PZtrial *);
|
||||
extern int NIreinit( CKTcircuit *);
|
||||
extern int NIsenReinit( CKTcircuit *);
|
||||
extern int NIdIter (CKTcircuit *);
|
||||
extern int NInzIter (CKTcircuit *, int, int );
|
||||
extern IFfrontEnd *SPfrontEnd;
|
||||
|
||||
#endif /*CKT*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -128,6 +129,7 @@ extern bool out_isatty;
|
|||
extern void out_init();
|
||||
#ifndef out_printf
|
||||
/* don't want to declare it if we have #define'ed it */
|
||||
|
||||
extern void out_printf();
|
||||
#endif
|
||||
extern void out_send();
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ typedef struct SPICEdev {
|
|||
} SPICEdev; /* instance of structure for each possible type of device */
|
||||
|
||||
|
||||
/* IOP( ) Input/output parameter
|
||||
/* IOP( ) Input/output parameter
|
||||
* IOPP( ) IO parameter which the principle value of a device (used
|
||||
* for naming output variables in sensetivity)
|
||||
* IOPA( ) IO parameter significant for time-varying (non-dc) analyses
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1988 Jaijeet S Roychowdhury
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifndef DISTODEF
|
||||
|
|
@ -198,18 +199,18 @@ extern double DFiF12(double, double, double, double,
|
|||
extern double DFn2F12(DpassStr*);
|
||||
extern double DFi2F12(DpassStr*);
|
||||
|
||||
extern void EqualDeriv(Dderivs *new, Dderivs *old);
|
||||
extern void TimesDeriv(Dderivs *new, Dderivs *old, double k);
|
||||
extern void InvDeriv(Dderivs *new, Dderivs *old);
|
||||
extern void MultDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2);
|
||||
extern void CubeDeriv(Dderivs *new, Dderivs *old);
|
||||
extern void PlusDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2);
|
||||
extern void SqrtDeriv(Dderivs *new, Dderivs *old);
|
||||
extern void DivDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2);
|
||||
extern void PowDeriv(Dderivs *new, Dderivs *old, double emm);
|
||||
extern void AtanDeriv(Dderivs *new, Dderivs *old);
|
||||
extern void CosDeriv(Dderivs *new, Dderivs *old);
|
||||
extern void ExpDeriv(Dderivs *new, Dderivs *old);
|
||||
extern void EqualDeriv(Dderivs *, Dderivs *);
|
||||
extern void TimesDeriv(Dderivs *, Dderivs *, double);
|
||||
extern void InvDeriv(Dderivs *, Dderivs *);
|
||||
extern void MultDeriv(Dderivs *, Dderivs *, Dderivs *);
|
||||
extern void CubeDeriv(Dderivs *, Dderivs *);
|
||||
extern void PlusDeriv(Dderivs *, Dderivs *, Dderivs *);
|
||||
extern void SqrtDeriv(Dderivs *, Dderivs *);
|
||||
extern void DivDeriv(Dderivs *, Dderivs *, Dderivs *);
|
||||
extern void PowDeriv(Dderivs *, Dderivs *, double);
|
||||
extern void AtanDeriv(Dderivs *, Dderivs *);
|
||||
extern void CosDeriv(Dderivs *, Dderivs *);
|
||||
extern void ExpDeriv(Dderivs *, Dderivs *);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
Modified: 1999 Paolo Nenzi
|
||||
Modified: 1999 Paolo Nenzi - 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -49,6 +49,7 @@ extern bool ft_bpcheck();
|
|||
extern void com_delete();
|
||||
extern void com_iplot();
|
||||
extern void com_save();
|
||||
extern void com_save2(wordlist *, char *); /* AlansFixes */
|
||||
extern void com_step();
|
||||
extern void com_stop();
|
||||
extern void com_sttus();
|
||||
|
|
@ -56,6 +57,12 @@ extern void com_trce();
|
|||
extern void ft_trquery();
|
||||
extern void dbfree( );
|
||||
|
||||
|
||||
/* breakp2.c */
|
||||
|
||||
extern int ft_getSaves(struct save_info **); /* AlanFixes */
|
||||
|
||||
|
||||
/* circuits.c */
|
||||
|
||||
extern struct circ *ft_curckt;
|
||||
|
|
@ -180,6 +187,10 @@ extern void fatal();
|
|||
extern void fperror();
|
||||
extern void ft_sperror();
|
||||
extern char ErrorMessage[];
|
||||
extern int internalerror(char *);
|
||||
extern int externalerror(char *);
|
||||
|
||||
|
||||
|
||||
/* evaluate.c */
|
||||
|
||||
|
|
@ -309,6 +320,7 @@ extern void com_ghelp();
|
|||
extern void com_help();
|
||||
extern void com_quit();
|
||||
extern void com_version();
|
||||
extern int hcomp();
|
||||
extern void com_where();
|
||||
|
||||
/* numparse.c */
|
||||
|
|
@ -337,14 +349,14 @@ extern int cp_userset();
|
|||
extern struct func ft_funcs[];
|
||||
extern struct func func_not;
|
||||
extern struct func func_uminus;
|
||||
struct pnode * ft_getpnames(wordlist *wl, bool check);
|
||||
struct struct pnode * ft_getpnames(wordlist *wl, bool check);
|
||||
extern void free_pnode();
|
||||
|
||||
/* plotcurve.c */
|
||||
|
||||
int ft_findpoint(double pt, double *lims, int maxp, int minp, bool islog);
|
||||
double * ft_minmax(struct dvec *v, bool real);
|
||||
void ft_graf(struct dvec *v, struct dvec *xs, bool nostart);
|
||||
/* AlansFixes */
|
||||
extern int ft_findpoint(double pt, double *lims, int maxp, int minp, bool islog);
|
||||
extern double * ft_minmax(struct dvec *v, bool real);
|
||||
extern void ft_graf(struct dvec *v, struct dvec *xs, bool nostart);
|
||||
|
||||
/* plotinterface.c */
|
||||
|
||||
|
|
@ -374,9 +386,8 @@ extern void com_setscale();
|
|||
extern void com_transpose();
|
||||
|
||||
/* rawfile.c */
|
||||
|
||||
extern int raw_prec;
|
||||
void raw_write(char *name, struct plot *pl, bool app, bool binary);
|
||||
extern void raw_write(char *name, struct plot *pl, bool app, bool binary);
|
||||
extern struct plot *raw_read();
|
||||
|
||||
/* resource.c */
|
||||
|
|
@ -402,6 +413,8 @@ extern void com_disto();
|
|||
extern void com_noise();
|
||||
extern int ft_dorun();
|
||||
|
||||
extern bool ft_getOutReq(FILE **, struct plot **, bool *, char *, char *);
|
||||
|
||||
/* spice.c & nutmeg.c */
|
||||
|
||||
extern bool ft_nutmeg;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
Modified 1999 Emmanuel Rouat
|
||||
Modified 1999 Emmanuel Rouat - 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -118,6 +118,7 @@ extern void hlp_pathfix(char *buf);
|
|||
extern topic *hlp_read(fplace *place);
|
||||
extern void hlp_free(void);
|
||||
extern long findsubject(char *filename, char *subject);
|
||||
extern bool hlp_approvedfile();
|
||||
|
||||
/* provide.c */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifndef INP
|
||||
|
|
@ -103,6 +104,7 @@ int INPmakeMod(char*,int,card*);
|
|||
char *INPmkTemp(char*);
|
||||
void INPpas1(void*,card*,INPtables*);
|
||||
void INPpas2(void*,card*,INPtables*,void *);
|
||||
void INPpas3(void*,card*,INPtables*,void *);
|
||||
int INPpName(char*,IFvalue*,void*,int,void*);
|
||||
int INPtermInsert(void*,char**,INPtables*,void**);
|
||||
int INPmkTerm(void*,char**,INPtables*,void**);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifndef OPT
|
||||
|
|
@ -104,4 +105,15 @@ typedef struct {
|
|||
#define OPT_TRANSYNC 59
|
||||
#define OPT_ACSYNC 60
|
||||
|
||||
/* AlansFixes: It is not possible to use the same numbers of the
|
||||
original Alan code. The following options are all AlansFixes */
|
||||
|
||||
#define OPT_GSHUNT 61 /* Original: 48 */
|
||||
#define OPT_DEFM 62 /* Original: 46 */
|
||||
#define OPT_GMINFACT 63 /* Original: 47 */
|
||||
#define OPT_COPYNODESETS 64 /* Original: 49 (NodesetFix) */
|
||||
#define OPT_NODEDAMPING 65 /* Original: 50 (Node_Damping) */
|
||||
#define OPT_ABSDV 66 /* Original: 51 (Node_Damping) */
|
||||
#define OPT_RELDV 67 /* Original: 52 (Node_Damping) */
|
||||
|
||||
#endif /*OPT*/
|
||||
|
|
|
|||
|
|
@ -18,3 +18,4 @@ struct s_sgen {
|
|||
|
||||
extern sgen *sgen_init( );
|
||||
extern int sgen_next( );
|
||||
extern int sgen_setp(sgen*, CKTcircuit*, IFvalue* ); /* AlansFixes */
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ typedef struct MatrixElement *SMPelement;
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "complex.h"
|
||||
|
|
@ -36,6 +37,7 @@ SMPelement * SMPfindElt( SMPmatrix *, int , int , int );
|
|||
int SMPcZeroCol(SMPmatrix *eMatrix, int Col);
|
||||
int SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col);
|
||||
int SMPzeroRow(SMPmatrix *eMatrix, int Row);
|
||||
void spConstMult(SMPmatrix*, double);
|
||||
#ifdef PARALLEL_ARCH
|
||||
void SMPcombine(SMPmatrix *Matrix, double RHS[], double Spare[]);
|
||||
void SMPcCombine(SMPmatrix *Matrix, double RHS[], double Spare[],
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -45,8 +46,10 @@ typedef struct {
|
|||
double TSKlteAbstol;
|
||||
#endif /* NEWTRUNC */
|
||||
double TSKgmin;
|
||||
double TSKgshunt; /* shunt conductance (CKTdiagGmin) */
|
||||
double TSKdelmin;
|
||||
double TSKtrtol;
|
||||
double TSKdefaultMosM;
|
||||
double TSKdefaultMosL;
|
||||
double TSKdefaultMosW;
|
||||
double TSKdefaultMosAD;
|
||||
|
|
@ -56,6 +59,11 @@ typedef struct {
|
|||
unsigned int TSKtryToCompact:1; /* flag for LTRA lines */
|
||||
unsigned int TSKbadMos3:1; /* flag for MOS3 models */
|
||||
unsigned int TSKkeepOpInfo:1; /* flag for small signal analyses */
|
||||
unsigned int TSKcopyNodesets:1; /* flag for nodeset copy */
|
||||
unsigned int TSKnodeDamping:1; /* flag for node damping */
|
||||
double TSKabsDv; /* abs limit for iter-iter voltage change */
|
||||
double TSKrelDv; /* rel limit for iter-iter voltage change */
|
||||
|
||||
}TSKtask;
|
||||
|
||||
#endif /*TSK*/
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/* Modified: 2000 AlansFixes */
|
||||
#include <config.h>
|
||||
#include "ngspice.h"
|
||||
#include "dup2.h"
|
||||
|
|
@ -16,5 +17,5 @@ dup2(int oldd, int newd)
|
|||
return 0;
|
||||
}
|
||||
#else
|
||||
int Dummy_Symbol;
|
||||
int Dummy_Symbol_2;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -47,6 +48,7 @@ CKTdoJob(void *inCkt, int reset, void *inTask)
|
|||
ckt->CKTtranMaxIter = task->TSKtranMaxIter;
|
||||
ckt->CKTnumSrcSteps = task->TSKnumSrcSteps;
|
||||
ckt->CKTnumGminSteps = task->TSKnumGminSteps;
|
||||
ckt->CKTgminFactor = task->TSKgminFactor;
|
||||
ckt->CKTminBreak = task->TSKminBreak;
|
||||
ckt->CKTabstol = task->TSKabstol;
|
||||
ckt->CKTpivotAbsTol = task->TSKpivotAbsTol;
|
||||
|
|
@ -55,8 +57,10 @@ CKTdoJob(void *inCkt, int reset, void *inTask)
|
|||
ckt->CKTchgtol = task->TSKchgtol;
|
||||
ckt->CKTvoltTol = task->TSKvoltTol;
|
||||
ckt->CKTgmin = task->TSKgmin;
|
||||
ckt->CKTgshunt = task->TSKgshunt;
|
||||
ckt->CKTdelmin = task->TSKdelmin;
|
||||
ckt->CKTtrtol = task->TSKtrtol;
|
||||
ckt->CKTdefaultMosM = task->TSKdefaultMosM;
|
||||
ckt->CKTdefaultMosL = task->TSKdefaultMosL;
|
||||
ckt->CKTdefaultMosW = task->TSKdefaultMosW;
|
||||
ckt->CKTdefaultMosAD = task->TSKdefaultMosAD;
|
||||
|
|
@ -66,6 +70,10 @@ CKTdoJob(void *inCkt, int reset, void *inTask)
|
|||
ckt->CKTtryToCompact = task->TSKtryToCompact;
|
||||
ckt->CKTbadMos3 = task->TSKbadMos3;
|
||||
ckt->CKTkeepOpInfo = task->TSKkeepOpInfo;
|
||||
ckt->CKTcopyNodesets = task->TSKcopyNodesets;
|
||||
ckt->CKTnodeDamping = task->TSKnodeDamping;
|
||||
ckt->CKTabsDv = task->TSKabsDv;
|
||||
ckt->CKTrelDv = task->TSKrelDv;
|
||||
ckt->CKTtroubleNode = 0;
|
||||
ckt->CKTtroubleElt = NULL;
|
||||
#ifdef NEWTRUNC
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFIxes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -76,10 +77,12 @@ CKTload(CKTcircuit *ckt)
|
|||
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes,
|
||||
node->number))
|
||||
{
|
||||
*(ckt->CKTrhs+node->number) = 1.0e10 * node->nodeset;
|
||||
*(ckt->CKTrhs+node->number) = 1.0e10 * node->nodeset *
|
||||
ckt->CKTsrcFact;
|
||||
*(node->ptr) = 1e10;
|
||||
} else {
|
||||
*(ckt->CKTrhs+node->number) = node->nodeset;
|
||||
*(ckt->CKTrhs+node->number) = node->nodeset *
|
||||
ckt->CKTsrcFact;
|
||||
*(node->ptr) = 1;
|
||||
}
|
||||
/* DAG: Original CIDER fix. If above fix doesn't work,
|
||||
|
|
@ -98,10 +101,17 @@ CKTload(CKTcircuit *ckt)
|
|||
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes,
|
||||
node->number))
|
||||
{
|
||||
*(ckt->CKTrhs+node->number) += 1.0e10 * node->ic;
|
||||
/* Original code:
|
||||
*(ckt->CKTrhs+node->number) += 1.0e10 * node->ic;
|
||||
*/
|
||||
*(ckt->CKTrhs+node->number) = 1.0e10 * node->ic *
|
||||
ckt->CKTsrcFact; /* AlansFixes */
|
||||
*(node->ptr) += 1.0e10;
|
||||
} else {
|
||||
*(ckt->CKTrhs+node->number) = node->ic;
|
||||
/* Original code:
|
||||
*(ckt->CKTrhs+node->number) = node->ic;
|
||||
*/
|
||||
*(ckt->CKTrhs+node->number) = node->ic*ckt->CKTsrcFact; /* AlansFixes */
|
||||
*(node->ptr) = 1;
|
||||
}
|
||||
/* DAG: Original CIDER fix. If above fix doesn't work,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -24,6 +25,7 @@ CKTnewTask(void *ckt, void **taskPtr, IFuid taskName)
|
|||
tsk = *(TSKtask **)taskPtr;
|
||||
tsk->TSKname = taskName;
|
||||
tsk->TSKgmin = 1e-12;
|
||||
tsk->TSKgshunt = 0;
|
||||
tsk->TSKabstol = 1e-12;
|
||||
tsk->TSKreltol = 1e-3;
|
||||
tsk->TSKchgtol = 1e-14;
|
||||
|
|
@ -39,12 +41,16 @@ CKTnewTask(void *ckt, void **taskPtr, IFuid taskName)
|
|||
tsk->TSKdcTrcvMaxIter = 50;
|
||||
tsk->TSKintegrateMethod = TRAPEZOIDAL;
|
||||
tsk->TSKmaxOrder = 2;
|
||||
tsk->TSKnumSrcSteps = 1;
|
||||
tsk->TSKnumGminSteps = 1;
|
||||
tsk->TSKnumSrcSteps = 10;
|
||||
tsk->TSKnumGminSteps = 10;
|
||||
tsk->TSKgminFactor = 10;
|
||||
tsk->TSKpivotAbsTol = 1e-13;
|
||||
tsk->TSKpivotRelTol = 1e-3;
|
||||
tsk->TSKtemp = 300.15;
|
||||
tsk->TSKnomTemp = 300.15;
|
||||
tsk->TSKdefaultMosM = 1;
|
||||
tsk->TSKdefaultMosL = 1e-4;
|
||||
tsk->TSKdefaultMosW = 1e-4;
|
||||
tsk->TSKdefaultMosAD = 0;
|
||||
|
|
@ -53,5 +59,9 @@ CKTnewTask(void *ckt, void **taskPtr, IFuid taskName)
|
|||
tsk->TSKtryToCompact=0;
|
||||
tsk->TSKbadMos3=0;
|
||||
tsk->TSKkeepOpInfo=0;
|
||||
tsk->TSKcopyNodesets=0;
|
||||
tsk->TSKnodeDamping=0;
|
||||
tsk->TSKabsDv=0.5;
|
||||
tsk->TSKrelDv=2.0;
|
||||
return(OK);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -15,7 +16,11 @@ CKTop(CKTcircuit *ckt, long int firstmode, long int continuemode, int iterlim)
|
|||
{
|
||||
int converged;
|
||||
int i;
|
||||
|
||||
CKTnode *n; /* AlansFixes */
|
||||
double raise, ConvFact, NumNodes; /* AlansFixes */
|
||||
double *OldRhsOld, *OldCKTstate0; /* AlansFixes */
|
||||
int iters;
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
if(!ckt->CKTnoOpIter) {
|
||||
converged = NIiter(ckt,iterlim);
|
||||
|
|
@ -28,29 +33,138 @@ CKTop(CKTcircuit *ckt, long int firstmode, long int continuemode, int iterlim)
|
|||
/* note that no path out of this code allows ckt->CKTdiagGmin to be
|
||||
* anything but 0.000000000
|
||||
*/
|
||||
if(ckt->CKTnumGminSteps >1) {
|
||||
|
||||
if(ckt->CKTnumGminSteps ==1) {
|
||||
|
||||
double OldGmin, gtarget, factor;
|
||||
int success, failed;
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"trying dynamic Gmin stepping",(IFuid *)NULL);
|
||||
NumNodes=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
NumNodes++;
|
||||
};
|
||||
OldRhsOld=(double *)MALLOC((NumNodes+1)*sizeof(double));
|
||||
OldCKTstate0=(double *)
|
||||
MALLOC((ckt->CKTnumStates+1)*sizeof(double));
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
*(ckt->CKTrhsOld+n->number)=0;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(ckt->CKTstate0+i) = 0;
|
||||
};
|
||||
factor = ckt->CKTgminFactor;
|
||||
OldGmin = 1e-2;
|
||||
ckt->CKTdiagGmin = OldGmin / factor;
|
||||
gtarget = MAX(ckt->CKTgmin,ckt->CKTgshunt);
|
||||
success = failed = 0;
|
||||
|
||||
while ( (!success) && (!failed) ) {
|
||||
fprintf(stderr, "\rTrying gmin = %12.4E ", ckt->CKTdiagGmin);
|
||||
ckt->CKTnoncon =1;
|
||||
iters = ckt->CKTstat->STATnumIter;
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
iters = (ckt->CKTstat->STATnumIter)-iters;
|
||||
if(converged == 0) {
|
||||
ckt->CKTmode=continuemode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful Gmin step",(IFuid *)NULL);
|
||||
if (ckt->CKTdiagGmin <= gtarget) {
|
||||
success = 1;
|
||||
} else {
|
||||
i=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
OldRhsOld[i]=*(ckt->CKTrhsOld+n->number);
|
||||
i++;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(OldCKTstate0+i) = *(ckt->CKTstate0+i);
|
||||
};
|
||||
if (iters <= (ckt->CKTdcTrcvMaxIter/4)) {
|
||||
factor *= sqrt(factor);
|
||||
if (factor > ckt->CKTgminFactor)
|
||||
factor = ckt->CKTgminFactor;
|
||||
};
|
||||
if (iters > (3*ckt->CKTdcTrcvMaxIter/4)) {
|
||||
factor = sqrt(factor);
|
||||
};
|
||||
OldGmin = ckt->CKTdiagGmin;
|
||||
if ((ckt->CKTdiagGmin) < (factor*gtarget)) {
|
||||
factor = ckt->CKTdiagGmin / gtarget;
|
||||
ckt->CKTdiagGmin = gtarget;
|
||||
} else {
|
||||
ckt->CKTdiagGmin /= factor;
|
||||
};
|
||||
};
|
||||
} else {
|
||||
if (factor < 1.00005) {
|
||||
failed = 1;
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"last gmin step failed",(IFuid *)NULL);
|
||||
} else {
|
||||
factor=sqrt(sqrt(factor));
|
||||
ckt->CKTdiagGmin = OldGmin / factor;
|
||||
i=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
*(ckt->CKTrhsOld+n->number)=OldRhsOld[i];
|
||||
i++;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(ckt->CKTstate0+i) = *(OldCKTstate0+i);
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
ckt->CKTdiagGmin=ckt->CKTgshunt;
|
||||
FREE(OldRhsOld);
|
||||
FREE(OldCKTstate0);
|
||||
converged = NIiter(ckt,iterlim);
|
||||
if (converged!=0) {
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"dynamic gmin stepping failed",(IFuid *)NULL);
|
||||
} else {
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"Dynamic gmin stepping completed",(IFuid *)NULL);
|
||||
return(0);
|
||||
};
|
||||
|
||||
} else if(ckt->CKTnumGminSteps >1) {
|
||||
|
||||
ckt->CKTmode = firstmode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"starting Gmin stepping",(IFuid *)NULL);
|
||||
ckt->CKTdiagGmin = ckt->CKTgmin;
|
||||
|
||||
if (ckt->CKTgshunt==0) {
|
||||
ckt->CKTdiagGmin = ckt->CKTgmin;
|
||||
} else {
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
};
|
||||
|
||||
|
||||
for(i=0;i<ckt->CKTnumGminSteps;i++) {
|
||||
ckt->CKTdiagGmin *= 10;
|
||||
ckt->CKTdiagGmin *= ckt->CKTgminFactor;
|
||||
|
||||
|
||||
}
|
||||
for(i=0;i<=ckt->CKTnumGminSteps;i++) {
|
||||
fprintf(stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
|
||||
ckt->CKTnoncon =1;
|
||||
converged = NIiter(ckt,iterlim);
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
if(converged != 0) {
|
||||
ckt->CKTdiagGmin = 0;
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"Gmin step failed",(IFuid *)NULL);
|
||||
break;
|
||||
}
|
||||
ckt->CKTdiagGmin /= 10;
|
||||
ckt->CKTdiagGmin /= ckt->CKTgminFactor;
|
||||
ckt->CKTmode=continuemode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful Gmin step",(IFuid *)NULL);
|
||||
}
|
||||
ckt->CKTdiagGmin = 0;
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
converged = NIiter(ckt,iterlim);
|
||||
if(converged == 0) {
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
|
|
@ -68,28 +182,162 @@ CKTop(CKTcircuit *ckt, long int firstmode, long int continuemode, int iterlim)
|
|||
* note that no path out of this code allows ckt->CKTsrcFact to be
|
||||
* anything but 1.000000000
|
||||
*/
|
||||
if(ckt->CKTnumSrcSteps >1) {
|
||||
|
||||
|
||||
if(ckt->CKTnumSrcSteps >=1) {
|
||||
ckt->CKTmode = firstmode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"starting source stepping",(IFuid *)NULL);
|
||||
for(i=0;i<=ckt->CKTnumSrcSteps;i++) {
|
||||
ckt->CKTsrcFact = ((double)i)/((double)ckt->CKTnumSrcSteps);
|
||||
converged = NIiter(ckt,iterlim);
|
||||
ckt->CKTmode = continuemode;
|
||||
if(ckt->CKTnumSrcSteps==1) {
|
||||
ckt->CKTsrcFact=0; raise=0.001; ConvFact=0;
|
||||
NumNodes=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
NumNodes++;
|
||||
};
|
||||
OldRhsOld=(double *)MALLOC((NumNodes+1)*sizeof(double));
|
||||
OldCKTstate0=(double *)
|
||||
MALLOC((ckt->CKTnumStates+1)*sizeof(double));
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
*(ckt->CKTrhsOld+n->number)=0;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(ckt->CKTstate0+i) = 0;
|
||||
};
|
||||
|
||||
/* First, try a straight solution with all sources at zero */
|
||||
|
||||
fprintf(stderr, "\rSupplies reduced to %8.4f%% ",
|
||||
ckt->CKTsrcFact*100);
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
|
||||
/* If this doesn't work, try gmin stepping as well for the first solution */
|
||||
|
||||
if(converged != 0) {
|
||||
ckt->CKTsrcFact = 1;
|
||||
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"source stepping failed",(IFuid *)NULL);
|
||||
return(converged);
|
||||
fprintf(stderr, "\n");
|
||||
if (ckt->CKTgshunt<=0) {
|
||||
ckt->CKTdiagGmin = ckt->CKTgmin;
|
||||
} else {
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
};
|
||||
for(i=0;i<10;i++) {
|
||||
ckt->CKTdiagGmin *= 10;
|
||||
}
|
||||
for(i=0;i<=10;i++) {
|
||||
fprintf(stderr, "Trying gmin = %12.4E ",
|
||||
ckt->CKTdiagGmin);
|
||||
ckt->CKTnoncon =1;
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
if(converged != 0) {
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"Gmin step failed",(IFuid *)NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
ckt->CKTdiagGmin /= 10;
|
||||
ckt->CKTmode=continuemode;
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful Gmin step",(IFuid *)NULL);
|
||||
}
|
||||
ckt->CKTdiagGmin = ckt->CKTgshunt;
|
||||
};
|
||||
|
||||
/* If we've got convergence, then try stepping up the sources */
|
||||
|
||||
if(converged == 0) {
|
||||
i=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
OldRhsOld[i]=*(ckt->CKTrhsOld+n->number);
|
||||
i++;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(OldCKTstate0+i) = *(ckt->CKTstate0+i);
|
||||
};
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful source step",(IFuid *)NULL);
|
||||
ckt->CKTsrcFact=ConvFact+raise;
|
||||
};
|
||||
|
||||
if(converged == 0) do {
|
||||
fprintf(stderr, "\rSupplies reduced to %8.4f%% ",
|
||||
ckt->CKTsrcFact*100);
|
||||
|
||||
iters = ckt->CKTstat->STATnumIter;
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
iters = (ckt->CKTstat->STATnumIter)-iters;
|
||||
|
||||
ckt->CKTmode = continuemode;
|
||||
if (converged == 0) {
|
||||
ConvFact=ckt->CKTsrcFact;
|
||||
i=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
OldRhsOld[i]=*(ckt->CKTrhsOld+n->number);
|
||||
i++;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(OldCKTstate0+i) = *(ckt->CKTstate0+i);
|
||||
};
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful source step",(IFuid *)NULL);
|
||||
ckt->CKTsrcFact=ConvFact+raise;
|
||||
if (iters <= (ckt->CKTdcTrcvMaxIter/4)) {
|
||||
raise=raise*1.5;
|
||||
};
|
||||
if (iters > (3*ckt->CKTdcTrcvMaxIter/4)) {
|
||||
raise=raise*0.5;
|
||||
};
|
||||
/* if (raise>0.01) raise=0.01; */
|
||||
} else {
|
||||
if ((ckt->CKTsrcFact-ConvFact)<1e-8) break;
|
||||
raise=raise/10;
|
||||
if (raise>0.01) raise=0.01;
|
||||
ckt->CKTsrcFact=ConvFact;
|
||||
i=0;
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
*(ckt->CKTrhsOld+n->number)=OldRhsOld[i];
|
||||
i++;
|
||||
};
|
||||
for(i=0;i<ckt->CKTnumStates;i++) {
|
||||
*(ckt->CKTstate0+i) = *(OldCKTstate0+i);
|
||||
};
|
||||
};
|
||||
if ((ckt->CKTsrcFact)>1) ckt->CKTsrcFact=1;
|
||||
} while ((raise>=1e-7) && (ConvFact<1));
|
||||
|
||||
FREE(OldRhsOld);
|
||||
FREE(OldCKTstate0);
|
||||
ckt->CKTsrcFact = 1;
|
||||
if (ConvFact!=1) {
|
||||
ckt->CKTsrcFact = 1;
|
||||
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"source stepping failed",(IFuid *)NULL);
|
||||
return(E_ITERLIM);
|
||||
} else {
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"Source stepping completed",(IFuid *)NULL);
|
||||
return(0);
|
||||
};
|
||||
} else {
|
||||
for(i=0;i<=ckt->CKTnumSrcSteps;i++) {
|
||||
ckt->CKTsrcFact = ((double)i)/((double)ckt->CKTnumSrcSteps);
|
||||
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
|
||||
ckt->CKTmode = continuemode;
|
||||
if(converged != 0) {
|
||||
ckt->CKTsrcFact = 1;
|
||||
ckt->CKTcurrentAnalysis = DOING_TRAN;
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"source stepping failed",(IFuid *)NULL);
|
||||
return(converged);
|
||||
}
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful source step",(IFuid *)NULL);
|
||||
}
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"One successful source step",(IFuid *)NULL);
|
||||
}
|
||||
(*(SPfrontEnd->IFerror))(ERR_INFO,
|
||||
"Source stepping completed",(IFuid *)NULL);
|
||||
ckt->CKTsrcFact = 1;
|
||||
return(0);
|
||||
"Source stepping completed",(IFuid *)NULL);
|
||||
ckt->CKTsrcFact = 1;
|
||||
return(0);
|
||||
};
|
||||
} else {
|
||||
return(converged);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/**********
|
||||
Copyright 1991 Regents of the University of California. All rights reserved.
|
||||
Modified: 2000 AlanFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -549,7 +550,9 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
|||
nvalue.v.vec.cVec = output_cvalues;
|
||||
|
||||
value.rValue = freq;
|
||||
OUTpData(sen_data, &value, &nvalue);
|
||||
|
||||
(*(SPfrontEnd->OUTpData))(sen_data, &value, &nvalue);
|
||||
|
||||
freq = inc_freq(freq, sen_info->step_type, step_size);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -33,6 +34,9 @@ CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
|
|||
case OPT_GMIN:
|
||||
task->TSKgmin = val->rValue;
|
||||
break;
|
||||
case OPT_GSHUNT:
|
||||
task->TSKgshunt = val->rValue;
|
||||
break;
|
||||
case OPT_RELTOL:
|
||||
task->TSKreltol = val->rValue;
|
||||
break;
|
||||
|
|
@ -79,6 +83,12 @@ CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
|
|||
case OPT_GMINSTEPS:
|
||||
task->TSKnumGminSteps = val->iValue;
|
||||
break;
|
||||
case OPT_GMINFACT:
|
||||
task->TSKgminFactor = val->rValue;
|
||||
break;
|
||||
case OPT_DEFM:
|
||||
task->TSKdefaultMosM = val->rValue;
|
||||
break;
|
||||
case OPT_DEFL:
|
||||
task->TSKdefaultMosL = val->rValue;
|
||||
break;
|
||||
|
|
@ -119,6 +129,18 @@ CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
|
|||
case OPT_KEEPOPINFO:
|
||||
task->TSKkeepOpInfo = val->iValue;
|
||||
break;
|
||||
case OPT_COPYNODESETS:
|
||||
task->TSKcopyNodesets = val->iValue;
|
||||
break;
|
||||
case OPT_NODEDAMPING:
|
||||
task->TSKnodeDamping = val->iValue;
|
||||
break;
|
||||
case OPT_ABSDV:
|
||||
task->TSKabsDv = val->rValue;
|
||||
break;
|
||||
case OPT_RELDV:
|
||||
task->TSKrelDv = val->rValue;
|
||||
break;
|
||||
default:
|
||||
return(-1);
|
||||
}
|
||||
|
|
@ -127,6 +149,7 @@ CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
|
|||
static IFparm OPTtbl[] = {
|
||||
{ "noopiter", OPT_NOOPITER,IF_SET|IF_FLAG,"Go directly to gmin stepping" },
|
||||
{ "gmin", OPT_GMIN,IF_SET|IF_REAL,"Minimum conductance" },
|
||||
{ "gshunt", OPT_GSHUNT,IF_SET|IF_REAL,"Shunt conductance" },
|
||||
{ "reltol", OPT_RELTOL,IF_SET|IF_REAL ,"Relative error tolerence"},
|
||||
{ "abstol", OPT_ABSTOL,IF_SET|IF_REAL,"Absolute error tolerence" },
|
||||
{ "vntol", OPT_VNTOL,IF_SET|IF_REAL,"Voltage error tolerence" },
|
||||
|
|
@ -144,6 +167,7 @@ static IFparm OPTtbl[] = {
|
|||
{ "itl6", OPT_SRCSTEPS, IF_SET|IF_INTEGER,"number of source steps"},
|
||||
{ "srcsteps", OPT_SRCSTEPS, IF_SET|IF_INTEGER,"number of source steps"},
|
||||
{ "gminsteps", OPT_GMINSTEPS, IF_SET|IF_INTEGER,"number of Gmin steps"},
|
||||
{ "gminfactor", OPT_GMINFACT, IF_SET|IF_REAL,"factor per Gmin step"},
|
||||
{ "acct", 0, IF_FLAG ,"Print accounting"},
|
||||
{ "list", 0, IF_FLAG, "Print a listing" },
|
||||
{ "nomod", 0, IF_FLAG, "Don't print a model summary" },
|
||||
|
|
@ -159,6 +183,7 @@ static IFparm OPTtbl[] = {
|
|||
{ "lvltim", 0, IF_INTEGER,"Type of timestep control" },
|
||||
{ "method", OPT_METHOD, IF_SET|IF_STRING,"Integration method" },
|
||||
{ "maxord", OPT_MAXORD, IF_SET|IF_INTEGER,"Maximum integration order" },
|
||||
{ "defm", OPT_DEFM,IF_SET|IF_REAL,"Default MOSfet Multiplier" },
|
||||
{ "defl", OPT_DEFL,IF_SET|IF_REAL,"Default MOSfet length" },
|
||||
{ "defw", OPT_DEFW,IF_SET|IF_REAL,"Default MOSfet width" },
|
||||
{ "minbreak", OPT_MINBREAK,IF_SET|IF_REAL,"Minimum time between breakpoints" },
|
||||
|
|
@ -201,7 +226,15 @@ static IFparm OPTtbl[] = {
|
|||
{ "badmos3", OPT_BADMOS3, IF_SET|IF_FLAG,
|
||||
"use old mos3 model (discontinuous with respect to kappa)" },
|
||||
{ "keepopinfo", OPT_KEEPOPINFO, IF_SET|IF_FLAG,
|
||||
"Record operating point for each small-signal analysis" }
|
||||
"Record operating point for each small-signal analysis" },
|
||||
{ "copynodesets", OPT_COPYNODESETS, IF_SET|IF_FLAG,
|
||||
"Copy nodesets from device terminals to internal nodes" },
|
||||
{ "nodedamping", OPT_NODEDAMPING, IF_SET|IF_FLAG,
|
||||
"Limit iter-iter change in node voltages" },
|
||||
{ "absdv", OPT_ABSDV, IF_SET|IF_REAL,
|
||||
"Maximum absolute iter-iter node voltage change" },
|
||||
{ "reldv", OPT_RELDV, IF_SET|IF_REAL,
|
||||
"Maximum relative iter-iter node voltage change" }
|
||||
};
|
||||
|
||||
int OPTcount = sizeof(OPTtbl)/sizeof(IFparm);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Author: 1985 Thomas L. Quarles
|
|||
**********/
|
||||
|
||||
/* look up the 'type' in the device description struct and return the
|
||||
* appropriatestrchr for the device found, or -1 for not found
|
||||
* appropriate strchr for the device found, or -1 for not found
|
||||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -31,7 +32,42 @@ DCop(CKTcircuit *ckt)
|
|||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter);
|
||||
if(converged != 0) return(converged);
|
||||
if(converged != 0) {
|
||||
|
||||
CKTnode *node;
|
||||
double new, old, tol;
|
||||
int i=1;
|
||||
|
||||
fprintf(stdout,"\nDC solution failed -\n\n");
|
||||
fprintf(stdout,"Last Node Voltages\n");
|
||||
fprintf(stdout,"------------------\n\n");
|
||||
fprintf(stdout,"%-30s %20s %20s\n", "Node", "Last Voltage",
|
||||
"Previous Iter");
|
||||
fprintf(stdout,"%-30s %20s %20s\n", "----", "------------",
|
||||
"-------------");
|
||||
for(node=ckt->CKTnodes->next;node;node=node->next) {
|
||||
if (strstr(node->name, "#branch") || !strstr(node->name, "#")) {
|
||||
new = *((ckt->CKTrhsOld) + i ) ;
|
||||
old = *((ckt->CKTrhs) + i ) ;
|
||||
fprintf(stdout,"%-30s %20g %20g", node->name, new, old);
|
||||
if(node->type == 3) {
|
||||
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
|
||||
ckt->CKTvoltTol;
|
||||
} else {
|
||||
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
|
||||
ckt->CKTabstol;
|
||||
}
|
||||
if (fabs(new-old) >tol ) {
|
||||
fprintf(stdout," *");
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
};
|
||||
i++;
|
||||
};
|
||||
fprintf(stdout,"\n");
|
||||
(*(SPfrontEnd->OUTendPlot))(plot);
|
||||
return(converged);
|
||||
};
|
||||
|
||||
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
||||
|
||||
|
|
@ -57,7 +93,11 @@ DCop(CKTcircuit *ckt)
|
|||
}
|
||||
#endif
|
||||
converged = CKTload(ckt);
|
||||
CKTdump(ckt,(double)0,plot);
|
||||
if(converged == 0) {
|
||||
CKTdump(ckt,(double)0,plot);
|
||||
} else {
|
||||
fprintf(stderr,"error: circuit reload failed.\n");
|
||||
};
|
||||
(*(SPfrontEnd->OUTendPlot))(plot);
|
||||
return(converged);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/* subroutine to do DC TRANSIENT analysis
|
||||
|
|
@ -44,12 +45,13 @@ DCtran(CKTcircuit *ckt,
|
|||
double maxstepsize=0.0;
|
||||
|
||||
int ltra_num;
|
||||
CKTnode *node;
|
||||
#ifdef PARALLEL_ARCH
|
||||
long type = MT_TRANAN, length = 1;
|
||||
#endif /* PARALLEL_ARCH */
|
||||
|
||||
if(restart || ckt->CKTtime == 0) {
|
||||
delta=MIN(ckt->CKTfinalTime/50,ckt->CKTstep)/10;
|
||||
delta=MIN(ckt->CKTfinalTime/100,ckt->CKTstep)/10;
|
||||
|
||||
/* begin LTRA code addition */
|
||||
if (ckt->CKTtimePoints != NULL)
|
||||
|
|
@ -96,6 +98,52 @@ DCtran(CKTcircuit *ckt,
|
|||
(ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITJCT,
|
||||
(ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT,
|
||||
ckt->CKTdcMaxIter);
|
||||
|
||||
if(converged != 0) {
|
||||
|
||||
CKTnode *node;
|
||||
double new, old, tol;
|
||||
int i=1;
|
||||
|
||||
fprintf(stdout,"\nTransient solution failed -\n\n");
|
||||
fprintf(stdout,"Last Node Voltages\n");
|
||||
fprintf(stdout,"------------------\n\n");
|
||||
fprintf(stdout,"%-30s %20s %20s\n", "Node", "Last Voltage",
|
||||
"Previous Iter");
|
||||
fprintf(stdout,"%-30s %20s %20s\n", "----", "------------",
|
||||
"-------------");
|
||||
for(node=ckt->CKTnodes->next;node;node=node->next) {
|
||||
if (strstr(node->name, "#branch") || !strstr(node->name, "#")) {
|
||||
new = *((ckt->CKTrhsOld) + i ) ;
|
||||
old = *((ckt->CKTrhs) + i ) ;
|
||||
fprintf(stdout,"%-30s %20g %20g", node->name, new, old);
|
||||
if(node->type == 3) {
|
||||
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
|
||||
ckt->CKTvoltTol;
|
||||
} else {
|
||||
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
|
||||
ckt->CKTabstol;
|
||||
}
|
||||
if (fabs(new-old) >tol ) {
|
||||
fprintf(stdout," *");
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
};
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
fprintf(stdout,"\nInitial Transient Solution\n");
|
||||
fprintf(stdout,"--------------------------\n\n");
|
||||
fprintf(stdout,"%-30s %15s\n", "Node", "Voltage");
|
||||
fprintf(stdout,"%-30s %15s\n", "----", "-------");
|
||||
for(node=ckt->CKTnodes->next;node;node=node->next) {
|
||||
if (strstr(node->name, "#branch") || !strstr(node->name, "#"))
|
||||
fprintf(stdout,"%-30s %15g\n", node->name,
|
||||
*(ckt->CKTrhsOld+node->number));
|
||||
};
|
||||
};
|
||||
fprintf(stdout,"\n");
|
||||
fflush(stdout);
|
||||
if(converged != 0) return(converged);
|
||||
ckt->CKTstat->STATtimePts ++;
|
||||
ckt->CKTorder=1;
|
||||
|
|
@ -198,7 +246,8 @@ nextTime:
|
|||
*/
|
||||
|
||||
#ifdef STEPDEBUG
|
||||
printf("accepted at %g\n",ckt->CKTtime);
|
||||
printf("Delta %g accepted at time %g\n",ckt->CKTdelta,ckt->CKTtime);
|
||||
fflush(stdout);
|
||||
#endif /* STEPDEBUG */
|
||||
ckt->CKTstat->STATaccepted ++;
|
||||
ckt->CKTbreak=0;
|
||||
|
|
@ -317,7 +366,8 @@ resume:
|
|||
ckt->CKTsaveDelta = ckt->CKTdelta;
|
||||
ckt->CKTdelta = *(ckt->CKTbreaks) - ckt->CKTtime;
|
||||
#ifdef STEPDEBUG
|
||||
(void)printf("delta cut to hit breakpoint\n");
|
||||
(void)printf("delta cut to %g to hit breakpoint\n",ckt->CKTdelta);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
|
||||
}
|
||||
|
|
@ -363,7 +413,8 @@ resume:
|
|||
ckt->CKTstat->STATrejected ++;
|
||||
ckt->CKTdelta = ckt->CKTdelta/8;
|
||||
#ifdef STEPDEBUG
|
||||
(void)printf("delta cut for non-convergence\n");
|
||||
(void)printf("delta cut to %g for non-convergance\n",ckt->CKTdelta);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
if(firsttime) {
|
||||
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN;
|
||||
|
|
@ -437,8 +488,10 @@ resume:
|
|||
/* time point OK - 630*/
|
||||
ckt->CKTdelta = new;
|
||||
#ifdef STEPDEBUG
|
||||
(void)printf(
|
||||
"delta set to truncation error result:point accepted\n");
|
||||
(void)printf(
|
||||
"delta set to truncation error result: %g. Point accepted\n",
|
||||
ckt->CKTdelta);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
#ifdef WANT_SENSE2
|
||||
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/**********
|
||||
Copyright 1991 Regents of the University of California. All rights reserved.
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -39,12 +40,12 @@ int TRANinit(CKTcircuit *ckt, JOB *job)
|
|||
#else
|
||||
/* The original spice code */
|
||||
if(ckt->CKTmaxStep == 0) {
|
||||
ckt->CKTmaxStep = (ckt->CKTfinalTime-ckt->CKTinitTime)/50;
|
||||
ckt->CKTmaxStep = (ckt->CKTfinalTime-ckt->CKTinitTime)/100;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ckt->CKTdelmin = 1e-9*ckt->CKTmaxStep; /* XXX */
|
||||
ckt->CKTdelmin = 1e-11*ckt->CKTmaxStep; /* XXX */
|
||||
ckt->CKTmode = ((TRANan*)job)->TRANmode;
|
||||
|
||||
return OK;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1988 Jaijeet S Roychowdhury
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -45,7 +46,7 @@ BJTdisto(int mode, GENmodel *genmodel, CKTcircuit *ckt)
|
|||
#endif
|
||||
|
||||
if (mode == D_SETUP)
|
||||
return(BJTdSetup(model,ckt));
|
||||
return(BJTdSetup((GENmodel *)model,ckt));
|
||||
|
||||
if ((mode == D_TWOF1) || (mode == D_THRF1) ||
|
||||
(mode == D_F1PF2) || (mode == D_F1MF2) ||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AnalsFixes
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
|
|
@ -27,6 +28,9 @@ extern int BJTtemp(GENmodel*,CKTcircuit*);
|
|||
extern int BJTtrunc(GENmodel*,CKTcircuit*,double*);
|
||||
extern int BJTdisto(int,GENmodel*,CKTcircuit*);
|
||||
extern int BJTnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
|
||||
extern int BJTdSetup(GENmodel*, register CKTcircuit*);
|
||||
|
||||
#else /* stdc */
|
||||
extern int BJTacLoad();
|
||||
extern int BJTask();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -369,43 +370,65 @@ BJTload(inModel,ckt)
|
|||
* determine dc current and derivitives
|
||||
*/
|
||||
next1: vtn=vt*model->BJTemissionCoeffF;
|
||||
if(vbe > -5*vtn){
|
||||
|
||||
if(vbe >= -3*vtn){
|
||||
evbe=exp(vbe/vtn);
|
||||
cbe=csat*(evbe-1)+ckt->CKTgmin*vbe;
|
||||
gbe=csat*evbe/vtn+ckt->CKTgmin;
|
||||
if (c2 == 0) {
|
||||
cben=0;
|
||||
gben=0;
|
||||
} else {
|
||||
cbe=csat*(evbe-1);
|
||||
gbe=csat*evbe/vtn;
|
||||
} else {
|
||||
arg=3*vtn/(vbe*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cbe = -csat*(1+arg);
|
||||
gbe = csat*3*arg/vbe;
|
||||
}
|
||||
if (c2 == 0) {
|
||||
cben=0;
|
||||
gben=0;
|
||||
} else {
|
||||
if(vbe >= -3*vte){
|
||||
evben=exp(vbe/vte);
|
||||
cben=c2*(evben-1);
|
||||
gben=c2*evben/vte;
|
||||
}
|
||||
} else {
|
||||
gbe = -csat/vbe+ckt->CKTgmin;
|
||||
cbe=gbe*vbe;
|
||||
gben = -c2/vbe;
|
||||
cben=gben*vbe;
|
||||
}
|
||||
vtn=vt*model->BJTemissionCoeffR;
|
||||
if(vbc > -5*vtn) {
|
||||
evbc=exp(vbc/vtn);
|
||||
cbc=csat*(evbc-1)+ckt->CKTgmin*vbc;
|
||||
gbc=csat*evbc/vtn+ckt->CKTgmin;
|
||||
if (c4 == 0) {
|
||||
cbcn=0;
|
||||
gbcn=0;
|
||||
} else {
|
||||
arg=3*vte/(vbe*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cben = -c2*(1+arg);
|
||||
gben = c2*3*arg/vbe;
|
||||
}
|
||||
}
|
||||
gben+=ckt->CKTgmin;
|
||||
cben+=ckt->CKTgmin*vbe;
|
||||
|
||||
vtn=vt*model->BJTemissionCoeffR;
|
||||
|
||||
if(vbc >= -3*vtn) {
|
||||
evbc=exp(vbc/vtn);
|
||||
cbc=csat*(evbc-1);
|
||||
gbc=csat*evbc/vtn;
|
||||
} else {
|
||||
arg=3*vtn/(vbc*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cbc = -csat*(1+arg);
|
||||
gbc = csat*3*arg/vbc;
|
||||
}
|
||||
if (c4 == 0) {
|
||||
cbcn=0;
|
||||
gbcn=0;
|
||||
} else {
|
||||
if(vbc >= -3*vtc) {
|
||||
evbcn=exp(vbc/vtc);
|
||||
cbcn=c4*(evbcn-1);
|
||||
gbcn=c4*evbcn/vtc;
|
||||
} else {
|
||||
arg=3*vtc/(vbc*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cbcn = -c4*(1+arg);
|
||||
gbcn = c4*3*arg/vbc;
|
||||
}
|
||||
} else {
|
||||
gbc = -csat/vbc+ckt->CKTgmin;
|
||||
cbc = gbc*vbc;
|
||||
gbcn = -c4/vbc;
|
||||
cbcn=gbcn*vbc;
|
||||
}
|
||||
gbcn+=ckt->CKTgmin;
|
||||
cbcn+=ckt->CKTgmin*vbc;
|
||||
|
||||
/*
|
||||
* determine base charge terms
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/*
|
||||
|
|
@ -149,6 +150,9 @@ BJTsetup(matrix,inModel,ckt,states)
|
|||
for (here = model->BJTinstances; here != NULL ;
|
||||
here=here->BJTnextInstance) {
|
||||
if (here->BJTowner != ARCHme) goto matrixpointers;
|
||||
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if(!here->BJTareaGiven) {
|
||||
here->BJTarea = 1;
|
||||
|
|
@ -166,6 +170,18 @@ matrixpointers:
|
|||
error = CKTmkVolt(ckt,&tmp,here->BJTname,"collector");
|
||||
if(error) return(error);
|
||||
here->BJTcolPrimeNode = tmp->number;
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
/* fprintf(stderr, "Nodeset copied from %s\n", tmpName);
|
||||
fprintf(stderr, " to %s\n", tmp->name);
|
||||
fprintf(stderr, " value %g\n",
|
||||
tmp->nodeset);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(model->BJTbaseResist == 0) {
|
||||
here->BJTbasePrimeNode = here->BJTbaseNode;
|
||||
|
|
@ -173,6 +189,18 @@ matrixpointers:
|
|||
error = CKTmkVolt(ckt,&tmp,here->BJTname, "base");
|
||||
if(error) return(error);
|
||||
here->BJTbasePrimeNode = tmp->number;
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,2,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
/* fprintf(stderr, "Nodeset copied from %s\n", tmpName);
|
||||
fprintf(stderr, " to %s\n", tmp->name);
|
||||
fprintf(stderr, " value %g\n",
|
||||
tmp->nodeset);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(model->BJTemitterResist == 0) {
|
||||
here->BJTemitPrimeNode = here->BJTemitNode;
|
||||
|
|
@ -180,6 +208,19 @@ matrixpointers:
|
|||
error = CKTmkVolt(ckt,&tmp,here->BJTname, "emitter");
|
||||
if(error) return(error);
|
||||
here->BJTemitPrimeNode = tmp->number;
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
/* fprintf(stderr, "Nodeset copied from %s\n", tmpName);
|
||||
fprintf(stderr, " to %s\n", tmp->name);
|
||||
fprintf(stderr, " value %g\n",
|
||||
tmp->nodeset);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* macro to make elements with built in test for out of memory */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -185,7 +186,8 @@ BJTtemp(inModel,ckt)
|
|||
here->BJTtf5 = here->BJTtBCpot * (1 - exp((1 -
|
||||
model->BJTjunctionExpBC) * xfc)) /
|
||||
(1 - model->BJTjunctionExpBC);
|
||||
here->BJTtVcrit = vt * log(vt / (CONSTroot2*model->BJTsatCur));
|
||||
here->BJTtVcrit = vt *
|
||||
log(vt / (CONSTroot2*here->BJTtSatCur*here->BJTarea));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1988 Jaijeet S Roychowdhury
|
||||
Modified: AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -43,7 +44,7 @@ B1disto(mode,genmodel,ckt)
|
|||
B1instance *here;
|
||||
|
||||
if (mode == D_SETUP)
|
||||
return(B1dSetup(model,ckt));
|
||||
return(B1dSetup((GENmodel *)model,ckt));
|
||||
|
||||
if ((mode == D_TWOF1) || (mode == D_THRF1) ||
|
||||
(mode == D_F1PF2) || (mode == D_F1MF2) ||
|
||||
|
|
|
|||
|
|
@ -271,6 +271,9 @@ B1setup(matrix,inModel,ckt,states)
|
|||
for (here = model->B1instances; here != NULL ;
|
||||
here=here->B1nextInstance) {
|
||||
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (here->B1owner == ARCHme) {
|
||||
/* allocate a chunk of the state vector */
|
||||
here->B1states = *states;
|
||||
|
|
@ -325,6 +328,14 @@ B1setup(matrix,inModel,ckt,states)
|
|||
error = CKTmkVolt(ckt,&tmp,here->B1name,"drain");
|
||||
if(error) return(error);
|
||||
here->B1dNodePrime = tmp->number;
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
here->B1dNodePrime = here->B1dNode;
|
||||
}
|
||||
|
|
@ -337,6 +348,14 @@ B1setup(matrix,inModel,ckt,states)
|
|||
error = CKTmkVolt(ckt,&tmp,here->B1name,"source");
|
||||
if(error) return(error);
|
||||
here->B1sNodePrime = tmp->number;
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
here->B1sNodePrime = here->B1sNode;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Hong June Park, Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
|
|
@ -26,6 +27,7 @@ extern int B1unsetup(GENmodel*,CKTcircuit*);
|
|||
extern int B1temp(GENmodel*,CKTcircuit*);
|
||||
extern int B1trunc(GENmodel*,CKTcircuit*,double*);
|
||||
extern int B1disto(int,GENmodel*,CKTcircuit*);
|
||||
extern int B1dSetup(GENmodel*, register CKTcircuit*);
|
||||
#else /* stdc */
|
||||
extern int B1acLoad();
|
||||
extern int B1ask();
|
||||
|
|
|
|||
|
|
@ -494,6 +494,14 @@ B2setup(matrix,inModel,ckt,states)
|
|||
error = CKTmkVolt(ckt,&tmp,here->B2name,"drain");
|
||||
if(error) return(error);
|
||||
here->B2dNodePrime = tmp->number;
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
here->B2dNodePrime = here->B2dNode;
|
||||
}
|
||||
|
|
@ -506,6 +514,14 @@ B2setup(matrix,inModel,ckt,states)
|
|||
error = CKTmkVolt(ckt,&tmp,here->B2name,"source");
|
||||
if(error) return(error);
|
||||
here->B2sNodePrime = tmp->number;
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
here->B2sNodePrime = here->B2sNode;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Copyright 1999 Regents of the University of California. All rights reserved.
|
||||
Author: 1995 Min-Chie Jeng and Mansun Chan.
|
||||
Author: 1997-1999 Weidong Liu.
|
||||
Modified: 2000 AlansFixes
|
||||
File: b3.c
|
||||
**********/
|
||||
|
||||
|
|
@ -14,6 +15,7 @@ File: b3.c
|
|||
IFparm BSIM3pTable[] = { /* parameters */
|
||||
IOP( "l", BSIM3_L, IF_REAL , "Length"),
|
||||
IOP( "w", BSIM3_W, IF_REAL , "Width"),
|
||||
IOP( "m", BSIM3_M, IF_REAL , "Parallel multiplier"),
|
||||
IOP( "ad", BSIM3_AD, IF_REAL , "Drain area"),
|
||||
IOP( "as", BSIM3_AS, IF_REAL , "Source area"),
|
||||
IOP( "pd", BSIM3_PD, IF_REAL , "Drain perimeter"),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Copyright 1999 Regents of the University of California. All rights reserved.
|
||||
Author: 1995 Min-Chie Jeng and Mansun Chan.
|
||||
Author: 1997-1999 Weidong Liu.
|
||||
Modified: 2000 AlansFixes
|
||||
File: b3acld.c
|
||||
**********/
|
||||
|
||||
|
|
@ -259,76 +260,79 @@ double ScalingFactor = 1.0e-9;
|
|||
xcbdb = (cbdb - capbd ) * omega;
|
||||
xcbsb = (cbsb - capbs ) * omega;
|
||||
|
||||
*(here->BSIM3GgPtr +1) += xcggb;
|
||||
|
||||
m = here->BSIM3m;
|
||||
|
||||
*(here->BSIM3GgPtr +1) += m * xcggb;
|
||||
*(here->BSIM3BbPtr +1) -= xcbgb + xcbdb + xcbsb;
|
||||
*(here->BSIM3DPdpPtr +1) += xcddb;
|
||||
*(here->BSIM3SPspPtr +1) += xcssb;
|
||||
*(here->BSIM3DPdpPtr +1) += m * xcddb;
|
||||
*(here->BSIM3SPspPtr +1) += m * xcssb;
|
||||
*(here->BSIM3GbPtr +1) -= xcggb + xcgdb + xcgsb;
|
||||
*(here->BSIM3GdpPtr +1) += xcgdb;
|
||||
*(here->BSIM3GspPtr +1) += xcgsb;
|
||||
*(here->BSIM3BgPtr +1) += xcbgb;
|
||||
*(here->BSIM3BdpPtr +1) += xcbdb;
|
||||
*(here->BSIM3BspPtr +1) += xcbsb;
|
||||
*(here->BSIM3DPgPtr +1) += xcdgb;
|
||||
*(here->BSIM3GdpPtr +1) += m * xcgdb;
|
||||
*(here->BSIM3GspPtr +1) += m * xcgsb;
|
||||
*(here->BSIM3BgPtr +1) += m * xcbgb;
|
||||
*(here->BSIM3BdpPtr +1) += m * xcbdb;
|
||||
*(here->BSIM3BspPtr +1) += m * xcbsb;
|
||||
*(here->BSIM3DPgPtr +1) += m * xcdgb;
|
||||
*(here->BSIM3DPbPtr +1) -= xcdgb + xcddb + xcdsb;
|
||||
*(here->BSIM3DPspPtr +1) += xcdsb;
|
||||
*(here->BSIM3SPgPtr +1) += xcsgb;
|
||||
*(here->BSIM3DPspPtr +1) += m * xcdsb;
|
||||
*(here->BSIM3SPgPtr +1) += m * xcsgb;
|
||||
*(here->BSIM3SPbPtr +1) -= xcsgb + xcsdb + xcssb;
|
||||
*(here->BSIM3SPdpPtr +1) += xcsdb;
|
||||
*(here->BSIM3SPdpPtr +1) += m * xcsdb;
|
||||
|
||||
*(here->BSIM3DdPtr) += gdpr;
|
||||
*(here->BSIM3SsPtr) += gspr;
|
||||
*(here->BSIM3BbPtr) += gbd + gbs - here->BSIM3gbbs;
|
||||
*(here->BSIM3DPdpPtr) += gdpr + gds + gbd + RevSum
|
||||
+ dxpart * xgtd + T1 * ddxpart_dVd + gbdpdp;
|
||||
*(here->BSIM3SPspPtr) += gspr + gds + gbs + FwdSum
|
||||
+ sxpart * xgts + T1 * dsxpart_dVs + gbspsp;
|
||||
*(here->BSIM3DdPtr) += m * gdpr;
|
||||
*(here->BSIM3SsPtr) += m * gspr;
|
||||
*(here->BSIM3BbPtr) += m * (gbd + gbs - here->BSIM3gbbs);
|
||||
*(here->BSIM3DPdpPtr) += m * (gdpr + gds + gbd + RevSum
|
||||
+dxpart * xgtd + T1 * ddxpart_dVd + gbdpdp);
|
||||
*(here->BSIM3SPspPtr) += m * (gspr + gds + gbs + FwdSum
|
||||
+sxpart * xgts + T1 * dsxpart_dVs + gbspsp);
|
||||
|
||||
*(here->BSIM3DdpPtr) -= gdpr;
|
||||
*(here->BSIM3SspPtr) -= gspr;
|
||||
*(here->BSIM3DdpPtr) -= m * gdpr;
|
||||
*(here->BSIM3SspPtr) -= m * gspr;
|
||||
|
||||
*(here->BSIM3BgPtr) -= here->BSIM3gbgs;
|
||||
*(here->BSIM3BdpPtr) -= gbd - gbbdp;
|
||||
*(here->BSIM3BspPtr) -= gbs - gbbsp;
|
||||
*(here->BSIM3BgPtr) -= m * here->BSIM3gbgs;
|
||||
*(here->BSIM3BdpPtr) -= m * (gbd - gbbdp);
|
||||
*(here->BSIM3BspPtr) -= m * (gbs - gbbsp);
|
||||
|
||||
*(here->BSIM3DPdPtr) -= gdpr;
|
||||
*(here->BSIM3DPgPtr) += Gm + dxpart * xgtg + T1 * ddxpart_dVg
|
||||
+ gbdpg;
|
||||
*(here->BSIM3DPbPtr) -= gbd - Gmbs - dxpart * xgtb
|
||||
- T1 * ddxpart_dVb - gbdpb;
|
||||
*(here->BSIM3DPspPtr) -= gds + FwdSum - dxpart * xgts
|
||||
- T1 * ddxpart_dVs - gbdpsp;
|
||||
*(here->BSIM3DPdPtr) -= m * gdpr;
|
||||
*(here->BSIM3DPgPtr) += m * (Gm + dxpart * xgtg + T1 * ddxpart_dVg
|
||||
+ gbdpg);
|
||||
*(here->BSIM3DPbPtr) -= m * (gbd - Gmbs - dxpart * xgtb
|
||||
- T1 * ddxpart_dVb - gbdpb);
|
||||
*(here->BSIM3DPspPtr) -= m * (gds + FwdSum - dxpart * xgts
|
||||
- T1 * ddxpart_dVs - gbdpsp);
|
||||
|
||||
*(here->BSIM3SPgPtr) -= Gm - sxpart * xgtg - T1 * dsxpart_dVg
|
||||
- gbspg;
|
||||
*(here->BSIM3SPsPtr) -= gspr;
|
||||
*(here->BSIM3SPbPtr) -= gbs + Gmbs - sxpart * xgtb
|
||||
- T1 * dsxpart_dVb - gbspb;
|
||||
*(here->BSIM3SPdpPtr) -= gds + RevSum - sxpart * xgtd
|
||||
- T1 * dsxpart_dVd - gbspdp;
|
||||
*(here->BSIM3SPgPtr) -= m * (Gm - sxpart * xgtg - T1 * dsxpart_dVg
|
||||
- gbspg);
|
||||
*(here->BSIM3SPsPtr) -= m * gspr;
|
||||
*(here->BSIM3SPbPtr) -= m * (gbs + Gmbs - sxpart * xgtb
|
||||
- T1 * dsxpart_dVb - gbspb);
|
||||
*(here->BSIM3SPdpPtr) -= m * (gds + RevSum - sxpart * xgtd
|
||||
- T1 * dsxpart_dVd - gbspdp);
|
||||
|
||||
*(here->BSIM3GgPtr) -= xgtg;
|
||||
*(here->BSIM3GbPtr) -= xgtb;
|
||||
*(here->BSIM3GdpPtr) -= xgtd;
|
||||
*(here->BSIM3GspPtr) -= xgts;
|
||||
*(here->BSIM3GgPtr) -= m * xgtg;
|
||||
*(here->BSIM3GbPtr) -= m * xgtb;
|
||||
*(here->BSIM3GdpPtr) -= m * xgtd;
|
||||
*(here->BSIM3GspPtr) -= m * xgts;
|
||||
|
||||
if (here->BSIM3nqsMod)
|
||||
{ *(here->BSIM3QqPtr +1) += omega * ScalingFactor;
|
||||
*(here->BSIM3QgPtr +1) -= xcqgb;
|
||||
*(here->BSIM3QdpPtr +1) -= xcqdb;
|
||||
*(here->BSIM3QspPtr +1) -= xcqsb;
|
||||
*(here->BSIM3QbPtr +1) -= xcqbb;
|
||||
{ *(here->BSIM3QqPtr +1) += m * (omega * ScalingFactor);
|
||||
*(here->BSIM3QgPtr +1) -= m * xcqgb;
|
||||
*(here->BSIM3QdpPtr +1) -= m * xcqdb;
|
||||
*(here->BSIM3QspPtr +1) -= m * xcqsb;
|
||||
*(here->BSIM3QbPtr +1) -= m * xcqbb;
|
||||
|
||||
*(here->BSIM3QqPtr) += here->BSIM3gtau;
|
||||
*(here->BSIM3QqPtr) += m * here->BSIM3gtau;
|
||||
|
||||
*(here->BSIM3DPqPtr) += dxpart * here->BSIM3gtau;
|
||||
*(here->BSIM3SPqPtr) += sxpart * here->BSIM3gtau;
|
||||
*(here->BSIM3GqPtr) -= here->BSIM3gtau;
|
||||
*(here->BSIM3DPqPtr) += m * (dxpart * here->BSIM3gtau);
|
||||
*(here->BSIM3SPqPtr) += m * (sxpart * here->BSIM3gtau);
|
||||
*(here->BSIM3GqPtr) -= m * here->BSIM3gtau;
|
||||
|
||||
*(here->BSIM3QgPtr) += xgtg;
|
||||
*(here->BSIM3QdpPtr) += xgtd;
|
||||
*(here->BSIM3QspPtr) += xgts;
|
||||
*(here->BSIM3QbPtr) += xgtb;
|
||||
*(here->BSIM3QgPtr) += m * xgtg;
|
||||
*(here->BSIM3QdpPtr) += m * xgtd;
|
||||
*(here->BSIM3QspPtr) += m * xgts;
|
||||
*(here->BSIM3QbPtr) += m * xgtb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
|||
case BSIM3_W:
|
||||
value->rValue = here->BSIM3w;
|
||||
return(OK);
|
||||
case BSIM3_M:
|
||||
value->rValue = here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_AS:
|
||||
value->rValue = here->BSIM3sourceArea;
|
||||
return(OK);
|
||||
|
|
@ -85,9 +88,11 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
|||
return(OK);
|
||||
case BSIM3_SOURCECONDUCT:
|
||||
value->rValue = here->BSIM3sourceConductance;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_DRAINCONDUCT:
|
||||
value->rValue = here->BSIM3drainConductance;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_VBD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3vbd);
|
||||
|
|
@ -103,78 +108,103 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
|||
return(OK);
|
||||
case BSIM3_CD:
|
||||
value->rValue = here->BSIM3cd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CBS:
|
||||
value->rValue = here->BSIM3cbs;
|
||||
value->rValue = here->BSIM3cbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CBD:
|
||||
value->rValue = here->BSIM3cbd;
|
||||
value->rValue = here->BSIM3cbd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_GM:
|
||||
value->rValue = here->BSIM3gm;
|
||||
value->rValue = here->BSIM3gm;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_GDS:
|
||||
value->rValue = here->BSIM3gds;
|
||||
value->rValue = here->BSIM3gds;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_GMBS:
|
||||
value->rValue = here->BSIM3gmbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_GBD:
|
||||
value->rValue = here->BSIM3gbd;
|
||||
value->rValue = here->BSIM3gbd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_GBS:
|
||||
value->rValue = here->BSIM3gbs;
|
||||
value->rValue = here->BSIM3gbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_QB:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qb);
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qb);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CQB:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqb);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_QG:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qg);
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qg);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CQG:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqg);
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqg);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_QD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qd);
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qd);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CQD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqd);
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqd);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CGG:
|
||||
value->rValue = here->BSIM3cggb;
|
||||
value->rValue = here->BSIM3cggb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CGD:
|
||||
value->rValue = here->BSIM3cgdb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CGS:
|
||||
value->rValue = here->BSIM3cgsb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CDG:
|
||||
value->rValue = here->BSIM3cdgb;
|
||||
value->rValue = here->BSIM3cdgb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CDD:
|
||||
value->rValue = here->BSIM3cddb;
|
||||
value->rValue = here->BSIM3cddb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CDS:
|
||||
value->rValue = here->BSIM3cdsb;
|
||||
value->rValue = here->BSIM3cdsb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CBG:
|
||||
value->rValue = here->BSIM3cbgb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CBDB:
|
||||
value->rValue = here->BSIM3cbdb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CBSB:
|
||||
value->rValue = here->BSIM3cbsb;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CAPBD:
|
||||
value->rValue = here->BSIM3capbd;
|
||||
value->rValue = here->BSIM3capbd;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_CAPBS:
|
||||
value->rValue = here->BSIM3capbs;
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_VON:
|
||||
value->rValue = here->BSIM3von;
|
||||
|
|
@ -183,10 +213,12 @@ BSIM3instance *here = (BSIM3instance*)inst;
|
|||
value->rValue = here->BSIM3vdsat;
|
||||
return(OK);
|
||||
case BSIM3_QBS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs);
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
case BSIM3_QBD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd);
|
||||
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd);
|
||||
value->rValue *= here->BSIM3m;
|
||||
return(OK);
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ Copyright 1999 Regents of the University of California. All rights reserved.
|
|||
Author: 1991 JianHui Huang and Min-Chie Jeng.
|
||||
Modified by Mansun Chan (1995).
|
||||
Author: 1997-1999 Weidong Liu.
|
||||
Modified: 2000 AlansFixes
|
||||
File: b3ld.c
|
||||
**********/
|
||||
|
||||
|
|
@ -118,6 +119,8 @@ double Cgg, Cgd, Cgb, Cdg, Cdd, Cds;
|
|||
double Csg, Csd, Css, Csb, Cbg, Cbd, Cbb;
|
||||
double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0;
|
||||
double dQac0_dVg, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb;
|
||||
|
||||
double m;
|
||||
|
||||
struct bsim3SizeDependParam *pParam;
|
||||
int ByPass, Check, ChargeComputationNeeded, error;
|
||||
|
|
@ -318,6 +321,8 @@ for (; model != NULL; model = model->BSIM3nextModel)
|
|||
vbd = vbs - vds;
|
||||
vgd = vgs - vds;
|
||||
vgb = vgs - vbs;
|
||||
|
||||
m=here->BSIM3m;
|
||||
|
||||
/* Source/drain junction diode DC model begins */
|
||||
Nvtm = model->BSIM3vtm * model->BSIM3jctEmissionCoeff;
|
||||
|
|
@ -331,29 +336,29 @@ for (; model != NULL; model = model->BSIM3nextModel)
|
|||
* model->BSIM3jctSidewallTempSatCurDensity;
|
||||
}
|
||||
if (SourceSatCurrent <= 0.0)
|
||||
{ here->BSIM3gbs = ckt->CKTgmin;
|
||||
{ here->BSIM3gbs = ckt->CKTgmin/m;
|
||||
here->BSIM3cbs = here->BSIM3gbs * vbs;
|
||||
}
|
||||
else
|
||||
{ if (model->BSIM3ijth == 0.0)
|
||||
{ evbs = exp(vbs / Nvtm);
|
||||
here->BSIM3gbs = SourceSatCurrent * evbs / Nvtm + ckt->CKTgmin;
|
||||
here->BSIM3gbs = SourceSatCurrent * evbs / Nvtm + (ckt->CKTgmin/m);
|
||||
here->BSIM3cbs = SourceSatCurrent * (evbs - 1.0)
|
||||
+ ckt->CKTgmin * vbs;
|
||||
+ (ckt->CKTgmin/m) * vbs;
|
||||
}
|
||||
else
|
||||
{ if (vbs < here->BSIM3vjsm)
|
||||
{ evbs = exp(vbs / Nvtm);
|
||||
here->BSIM3gbs = SourceSatCurrent * evbs / Nvtm + ckt->CKTgmin;
|
||||
here->BSIM3gbs = SourceSatCurrent * evbs / Nvtm + (ckt->CKTgmin/m);
|
||||
here->BSIM3cbs = SourceSatCurrent * (evbs - 1.0)
|
||||
+ ckt->CKTgmin * vbs;
|
||||
+ (ckt->CKTgmin/m) * vbs;
|
||||
}
|
||||
else
|
||||
{ T0 = here->BSIM3IsEvjsm / Nvtm;
|
||||
here->BSIM3gbs = T0 + ckt->CKTgmin;
|
||||
here->BSIM3gbs = T0 + (ckt->CKTgmin/m);
|
||||
here->BSIM3cbs = here->BSIM3IsEvjsm - SourceSatCurrent
|
||||
+ T0 * (vbs - here->BSIM3vjsm)
|
||||
+ ckt->CKTgmin * vbs;
|
||||
+ (ckt->CKTgmin/m) * vbs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -368,29 +373,29 @@ for (; model != NULL; model = model->BSIM3nextModel)
|
|||
* model->BSIM3jctSidewallTempSatCurDensity;
|
||||
}
|
||||
if (DrainSatCurrent <= 0.0)
|
||||
{ here->BSIM3gbd = ckt->CKTgmin;
|
||||
{ here->BSIM3gbd = (ckt->CKTgmin/m);
|
||||
here->BSIM3cbd = here->BSIM3gbd * vbd;
|
||||
}
|
||||
else
|
||||
{ if (model->BSIM3ijth == 0.0)
|
||||
{ evbd = exp(vbd / Nvtm);
|
||||
here->BSIM3gbd = DrainSatCurrent * evbd / Nvtm + ckt->CKTgmin;
|
||||
here->BSIM3gbd = DrainSatCurrent * evbd / Nvtm + (ckt->CKTgmin/m);
|
||||
here->BSIM3cbd = DrainSatCurrent * (evbd - 1.0)
|
||||
+ ckt->CKTgmin * vbd;
|
||||
+ (ckt->CKTgmin/m) * vbd;
|
||||
}
|
||||
else
|
||||
{ if (vbd < here->BSIM3vjdm)
|
||||
{ evbd = exp(vbd / Nvtm);
|
||||
here->BSIM3gbd = DrainSatCurrent * evbd / Nvtm + ckt->CKTgmin;
|
||||
here->BSIM3gbd = DrainSatCurrent * evbd / Nvtm + (ckt->CKTgmin/m);
|
||||
here->BSIM3cbd = DrainSatCurrent * (evbd - 1.0)
|
||||
+ ckt->CKTgmin * vbd;
|
||||
+ (ckt->CKTgmin/m) * vbd;
|
||||
}
|
||||
else
|
||||
{ T0 = here->BSIM3IsEvjdm / Nvtm;
|
||||
here->BSIM3gbd = T0 + ckt->CKTgmin;
|
||||
here->BSIM3gbd = T0 + (ckt->CKTgmin/m);
|
||||
here->BSIM3cbd = here->BSIM3IsEvjdm - DrainSatCurrent
|
||||
+ T0 * (vbd - here->BSIM3vjdm)
|
||||
+ ckt->CKTgmin * vbd;
|
||||
+ (ckt->CKTgmin/m) * vbd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2833,71 +2838,71 @@ line900:
|
|||
cqdef = -cqdef;
|
||||
cqcheq = -cqcheq;
|
||||
}
|
||||
|
||||
(*(ckt->CKTrhs + here->BSIM3gNode) -= ceqqg);
|
||||
(*(ckt->CKTrhs + here->BSIM3bNode) -=(ceqbs + ceqbd + ceqqb));
|
||||
(*(ckt->CKTrhs + here->BSIM3dNodePrime) += (ceqbd - cdreq - ceqqd));
|
||||
(*(ckt->CKTrhs + here->BSIM3sNodePrime) += (cdreq + ceqbs + ceqqg
|
||||
|
||||
(*(ckt->CKTrhs + here->BSIM3gNode) -= m*ceqqg);
|
||||
(*(ckt->CKTrhs + here->BSIM3bNode) -= m*(ceqbs + ceqbd + ceqqb));
|
||||
(*(ckt->CKTrhs + here->BSIM3dNodePrime) +=m*(ceqbd - cdreq - ceqqd));
|
||||
(*(ckt->CKTrhs + here->BSIM3sNodePrime) += m*(cdreq + ceqbs + ceqqg
|
||||
+ ceqqb + ceqqd));
|
||||
if (here->BSIM3nqsMod)
|
||||
*(ckt->CKTrhs + here->BSIM3qNode) += (cqcheq - cqdef);
|
||||
*(ckt->CKTrhs + here->BSIM3qNode) += m*(cqcheq - cqdef);
|
||||
|
||||
/*
|
||||
* load y matrix
|
||||
*/
|
||||
|
||||
T1 = qdef * here->BSIM3gtau;
|
||||
(*(here->BSIM3DdPtr) += here->BSIM3drainConductance);
|
||||
(*(here->BSIM3GgPtr) += gcggb - ggtg);
|
||||
(*(here->BSIM3SsPtr) += here->BSIM3sourceConductance);
|
||||
(*(here->BSIM3BbPtr) += here->BSIM3gbd + here->BSIM3gbs
|
||||
- gcbgb - gcbdb - gcbsb - here->BSIM3gbbs);
|
||||
(*(here->BSIM3DPdpPtr) += here->BSIM3drainConductance
|
||||
(*(here->BSIM3DdPtr) += m*here->BSIM3drainConductance);
|
||||
(*(here->BSIM3GgPtr) += m*(gcggb - ggtg));
|
||||
(*(here->BSIM3SsPtr) += m*here->BSIM3sourceConductance);
|
||||
(*(here->BSIM3BbPtr) += m*(here->BSIM3gbd + here->BSIM3gbs
|
||||
- gcbgb - gcbdb - gcbsb - here->BSIM3gbbs));
|
||||
(*(here->BSIM3DPdpPtr) += m*(here->BSIM3drainConductance
|
||||
+ here->BSIM3gds + here->BSIM3gbd
|
||||
+ RevSum + gcddb + dxpart * ggtd
|
||||
+ T1 * ddxpart_dVd + gbdpdp);
|
||||
(*(here->BSIM3SPspPtr) += here->BSIM3sourceConductance
|
||||
+ T1 * ddxpart_dVd + gbdpdp));
|
||||
(*(here->BSIM3SPspPtr) += m*(here->BSIM3sourceConductance
|
||||
+ here->BSIM3gds + here->BSIM3gbs
|
||||
+ FwdSum + gcssb + sxpart * ggts
|
||||
+ T1 * dsxpart_dVs + gbspsp);
|
||||
(*(here->BSIM3DdpPtr) -= here->BSIM3drainConductance);
|
||||
(*(here->BSIM3GbPtr) -= gcggb + gcgdb + gcgsb + ggtb);
|
||||
(*(here->BSIM3GdpPtr) += gcgdb - ggtd);
|
||||
(*(here->BSIM3GspPtr) += gcgsb - ggts);
|
||||
(*(here->BSIM3SspPtr) -= here->BSIM3sourceConductance);
|
||||
(*(here->BSIM3BgPtr) += gcbgb - here->BSIM3gbgs);
|
||||
(*(here->BSIM3BdpPtr) += gcbdb - here->BSIM3gbd + gbbdp);
|
||||
(*(here->BSIM3BspPtr) += gcbsb - here->BSIM3gbs + gbbsp);
|
||||
(*(here->BSIM3DPdPtr) -= here->BSIM3drainConductance);
|
||||
(*(here->BSIM3DPgPtr) += Gm + gcdgb + dxpart * ggtg
|
||||
+ T1 * ddxpart_dVg + gbdpg);
|
||||
(*(here->BSIM3DPbPtr) -= here->BSIM3gbd - Gmbs + gcdgb + gcddb
|
||||
+ T1 * dsxpart_dVs + gbspsp));
|
||||
(*(here->BSIM3DdpPtr) -= m*here->BSIM3drainConductance);
|
||||
(*(here->BSIM3GbPtr) -= m*(gcggb + gcgdb + gcgsb + ggtb));
|
||||
(*(here->BSIM3GdpPtr) += m*(gcgdb - ggtd));
|
||||
(*(here->BSIM3GspPtr) += m*(gcgsb - ggts));
|
||||
(*(here->BSIM3SspPtr) -= m*here->BSIM3sourceConductance);
|
||||
(*(here->BSIM3BgPtr) += m*(gcbgb - here->BSIM3gbgs));
|
||||
(*(here->BSIM3BdpPtr) += m*(gcbdb - here->BSIM3gbd + gbbdp));
|
||||
(*(here->BSIM3BspPtr) += m*(gcbsb - here->BSIM3gbs + gbbsp));
|
||||
(*(here->BSIM3DPdPtr) -= m*here->BSIM3drainConductance);
|
||||
(*(here->BSIM3DPgPtr) += m*(Gm + gcdgb + dxpart * ggtg
|
||||
+ T1 * ddxpart_dVg + gbdpg));
|
||||
(*(here->BSIM3DPbPtr) -= m*(here->BSIM3gbd - Gmbs + gcdgb + gcddb
|
||||
+ gcdsb - dxpart * ggtb
|
||||
- T1 * ddxpart_dVb - gbdpb);
|
||||
(*(here->BSIM3DPspPtr) -= here->BSIM3gds + FwdSum - gcdsb
|
||||
- dxpart * ggts - T1 * ddxpart_dVs - gbdpsp);
|
||||
(*(here->BSIM3SPgPtr) += gcsgb - Gm + sxpart * ggtg
|
||||
+ T1 * dsxpart_dVg + gbspg);
|
||||
(*(here->BSIM3SPsPtr) -= here->BSIM3sourceConductance);
|
||||
(*(here->BSIM3SPbPtr) -= here->BSIM3gbs + Gmbs + gcsgb + gcsdb
|
||||
- T1 * ddxpart_dVb - gbdpb));
|
||||
(*(here->BSIM3DPspPtr) -= m*(here->BSIM3gds + FwdSum - gcdsb
|
||||
- dxpart * ggts - T1 * ddxpart_dVs - gbdpsp));
|
||||
(*(here->BSIM3SPgPtr) += m*(gcsgb - Gm + sxpart * ggtg
|
||||
+ T1 * dsxpart_dVg + gbspg));
|
||||
(*(here->BSIM3SPsPtr) -= m*here->BSIM3sourceConductance);
|
||||
(*(here->BSIM3SPbPtr) -= m*(here->BSIM3gbs + Gmbs + gcsgb + gcsdb
|
||||
+ gcssb - sxpart * ggtb
|
||||
- T1 * dsxpart_dVb - gbspb);
|
||||
(*(here->BSIM3SPdpPtr) -= here->BSIM3gds + RevSum - gcsdb
|
||||
- sxpart * ggtd - T1 * dsxpart_dVd - gbspdp);
|
||||
- T1 * dsxpart_dVb - gbspb));
|
||||
(*(here->BSIM3SPdpPtr) -= m*(here->BSIM3gds + RevSum - gcsdb
|
||||
- sxpart * ggtd - T1 * dsxpart_dVd - gbspdp));
|
||||
|
||||
if (here->BSIM3nqsMod)
|
||||
{ *(here->BSIM3QqPtr) += (gqdef + here->BSIM3gtau);
|
||||
{ *(here->BSIM3QqPtr) += m*(gqdef + here->BSIM3gtau);
|
||||
|
||||
*(here->BSIM3DPqPtr) += (dxpart * here->BSIM3gtau);
|
||||
*(here->BSIM3SPqPtr) += (sxpart * here->BSIM3gtau);
|
||||
*(here->BSIM3GqPtr) -= here->BSIM3gtau;
|
||||
*(here->BSIM3DPqPtr) += m*(dxpart * here->BSIM3gtau);
|
||||
*(here->BSIM3SPqPtr) += m*(sxpart * here->BSIM3gtau);
|
||||
*(here->BSIM3GqPtr) -= m*here->BSIM3gtau;
|
||||
|
||||
*(here->BSIM3QgPtr) += (ggtg - gcqgb);
|
||||
*(here->BSIM3QdpPtr) += (ggtd - gcqdb);
|
||||
*(here->BSIM3QspPtr) += (ggts - gcqsb);
|
||||
*(here->BSIM3QbPtr) += (ggtb - gcqbb);
|
||||
*(here->BSIM3QgPtr) += m*(ggtg - gcqgb);
|
||||
*(here->BSIM3QdpPtr) += m*(ggtd - gcqdb);
|
||||
*(here->BSIM3QspPtr) += m*(ggts - gcqsb);
|
||||
*(here->BSIM3QbPtr) += m*(ggtb - gcqbb);
|
||||
}
|
||||
|
||||
|
||||
line1000: ;
|
||||
|
||||
} /* End of Mosfet Instance */
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Copyright 1999 Regents of the University of California. All rights reserved.
|
||||
Author: 1995 Min-Chie Jeng and Mansun Chan.
|
||||
Author: 1997-1999 Weidong Liu.
|
||||
Modified: 2000 AlansFixes
|
||||
File: b3par.c
|
||||
**********/
|
||||
|
||||
|
|
@ -29,6 +30,10 @@ IFvalue *select;
|
|||
here->BSIM3l = value->rValue;
|
||||
here->BSIM3lGiven = TRUE;
|
||||
break;
|
||||
case BSIM3_M:
|
||||
here->BSIM3m = value->rValue;
|
||||
here->BSIM3mGiven = TRUE;
|
||||
break;
|
||||
case BSIM3_AS:
|
||||
here->BSIM3sourceArea = value->rValue;
|
||||
here->BSIM3sourceAreaGiven = TRUE;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
Copyright 1999 Regents of the University of California. All rights reserved.
|
||||
Author: 1995 Min-Chie Jeng and Mansun Chan.
|
||||
Author: 1997-1999 Weidong Liu.
|
||||
|
||||
Modified: 2000 AlansFixes
|
||||
File: b3set.c
|
||||
**********/
|
||||
|
||||
|
|
@ -848,6 +850,10 @@ CKTnode *tmp;
|
|||
{
|
||||
if (here->BSIM3owner == ARCHme) {
|
||||
/* allocate a chunk of the state vector */
|
||||
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
here->BSIM3states = *states;
|
||||
*states += BSIM3numStates;
|
||||
}
|
||||
|
|
@ -877,7 +883,10 @@ CKTnode *tmp;
|
|||
here->BSIM3w = 5.0e-6;
|
||||
if (!here->BSIM3nqsModGiven)
|
||||
here->BSIM3nqsMod = 0;
|
||||
|
||||
|
||||
if (!here->BSIM3mGiven)
|
||||
here->BSIM3m = 1;
|
||||
|
||||
/* process drain series resistance */
|
||||
if ((model->BSIM3sheetResistance > 0.0) &&
|
||||
(here->BSIM3drainSquares > 0.0 ) &&
|
||||
|
|
@ -885,6 +894,14 @@ CKTnode *tmp;
|
|||
{ error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain");
|
||||
if(error) return(error);
|
||||
here->BSIM3dNodePrime = tmp->number;
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ here->BSIM3dNodePrime = here->BSIM3dNode;
|
||||
|
|
@ -897,6 +914,14 @@ CKTnode *tmp;
|
|||
{ error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source");
|
||||
if(error) return(error);
|
||||
here->BSIM3sNodePrime = tmp->number;
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ here->BSIM3sNodePrime = here->BSIM3sNode;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Copyright 1999 Regents of the University of California. All rights reserved.
|
||||
Author: 1995 Min-Chie Jeng and Mansun Chan.
|
||||
Author: 1997-1999 Weidong Liu.
|
||||
Modified: 2000 AlansFixes
|
||||
File: bsim3def.h
|
||||
**********/
|
||||
|
||||
|
|
@ -106,6 +107,7 @@ typedef struct sBSIM3instance
|
|||
|
||||
unsigned BSIM3lGiven :1;
|
||||
unsigned BSIM3wGiven :1;
|
||||
unsigned BSIM3mGiven :1;
|
||||
unsigned BSIM3drainAreaGiven :1;
|
||||
unsigned BSIM3sourceAreaGiven :1;
|
||||
unsigned BSIM3drainSquaresGiven :1;
|
||||
|
|
@ -152,7 +154,7 @@ typedef struct sBSIM3instance
|
|||
double *BSIM3SPqPtr;
|
||||
double *BSIM3BqPtr;
|
||||
|
||||
/* int BSIM3states; index into state table for this device */
|
||||
int BSIM3states; /* index into state table for this device */
|
||||
#define BSIM3vbd BSIM3states+ 0
|
||||
#define BSIM3vbs BSIM3states+ 1
|
||||
#define BSIM3vgs BSIM3states+ 2
|
||||
|
|
@ -1213,6 +1215,7 @@ typedef struct sBSIM3model
|
|||
/* device parameters */
|
||||
#define BSIM3_W 1
|
||||
#define BSIM3_L 2
|
||||
#define BSIM3_M 15
|
||||
#define BSIM3_AS 3
|
||||
#define BSIM3_AD 4
|
||||
#define BSIM3_PS 5
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ CAPask(ckt,inst, which, value, select)
|
|||
} else {
|
||||
value->rValue = *(ckt->CKTstate0 + here->CAPccap);
|
||||
}
|
||||
}
|
||||
} else value->rValue = *(ckt->CKTstate0 + here->CAPccap);
|
||||
return(OK);
|
||||
case CAP_POWER:
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
|
|
@ -74,7 +74,9 @@ CAPask(ckt,inst, which, value, select)
|
|||
(*(ckt->CKTrhsOld + here->CAPposNode) -
|
||||
*(ckt->CKTrhsOld + here->CAPnegNode));
|
||||
}
|
||||
}
|
||||
} else value->rValue = *(ckt->CKTstate0 + here->CAPccap) *
|
||||
(*(ckt->CKTrhsOld + here->CAPposNode) -
|
||||
*(ckt->CKTrhsOld + here->CAPnegNode));
|
||||
return(OK);
|
||||
case CAP_QUEST_SENS_DC:
|
||||
if(ckt->CKTsenInfo){
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modifed: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include <config.h>
|
||||
|
|
@ -30,12 +31,13 @@ CKTinit(void **ckt) /* new circuit to create */
|
|||
sckt->CKTmatrix = NULL;
|
||||
|
||||
sckt->CKTgmin = 1e-12;
|
||||
sckt->CKTgshunt=0;
|
||||
sckt->CKTabstol = 1e-12;
|
||||
sckt->CKTreltol = 1e-3;
|
||||
sckt->CKTchgtol = 1e-14;
|
||||
sckt->CKTvoltTol = 1e-6;
|
||||
sckt->CKTtrtol = 7;
|
||||
sckt->CKTbypass = 1;
|
||||
sckt->CKTbypass = 0;
|
||||
sckt->CKTisSetup = 0;
|
||||
sckt->CKTtranMaxIter = 10;
|
||||
sckt->CKTdcMaxIter = 100;
|
||||
|
|
@ -47,6 +49,7 @@ CKTinit(void **ckt) /* new circuit to create */
|
|||
sckt->CKTpivotRelTol = 1e-3;
|
||||
sckt->CKTtemp = 300.15;
|
||||
sckt->CKTnomTemp = 300.15;
|
||||
sckt->CKTdefaultMosM = 1;
|
||||
sckt->CKTdefaultMosL = 1e-4;
|
||||
sckt->CKTdefaultMosW = 1e-4;
|
||||
sckt->CKTdefaultMosAD = 0;
|
||||
|
|
@ -59,6 +62,9 @@ CKTinit(void **ckt) /* new circuit to create */
|
|||
sckt->CKTtimePoints = NULL;
|
||||
if (sckt->CKTstat == (STATistics *)NULL)
|
||||
return E_NOMEM;
|
||||
sckt->CKTnodeDamping = 0;
|
||||
sckt->CKTabsDv = 0.5;
|
||||
sckt->CKTrelDv = 2.0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ libcsw_la_SOURCES = \
|
|||
cswnoise.c \
|
||||
cswparam.c \
|
||||
cswpzld.c \
|
||||
cswsetup.c
|
||||
cswsetup.c \
|
||||
cswtrunc.c
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon M. Jacobs
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifndef CSW
|
||||
|
|
@ -54,7 +55,7 @@ typedef struct sCSWinstance {
|
|||
|
||||
#define CSW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */
|
||||
#define CSW_OFF_CONDUCTANCE ckt->CKTgmin /* default off conductance */
|
||||
#define CSW_NUM_STATES 1
|
||||
#define CSW_NUM_STATES 2
|
||||
|
||||
typedef struct sCSWmodel { /* model structure for a switch */
|
||||
int CSWmodType; /* type index of this device type */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon M. Jacobs
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
|
|
@ -16,6 +17,9 @@ extern int CSWparam(int,IFvalue*,GENinstance*,IFvalue*);
|
|||
extern int CSWpzLoad(GENmodel*,CKTcircuit*,SPcomplex*);
|
||||
extern int CSWsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||
extern int CSWnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
|
||||
extern int CSWtrunc(GENmodel*,CKTcircuit*,double*);
|
||||
|
||||
#else /* stdc */
|
||||
extern int CSWask();
|
||||
extern int CSWacLoad();
|
||||
|
|
@ -29,5 +33,6 @@ extern int CSWparam();
|
|||
extern int CSWpzLoad();
|
||||
extern int CSWsetup();
|
||||
extern int CSWnoise();
|
||||
extern int CSWtrunc();
|
||||
#endif /* stdc */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
/* Modified: 2000 AlansFixes */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <devdefs.h>
|
||||
|
|
@ -31,7 +33,7 @@ SPICEdev CSWinfo = {
|
|||
DEVunsetup : NULL,
|
||||
DEVpzSetup : CSWsetup,
|
||||
DEVtemperature: NULL,
|
||||
DEVtrunc : NULL,
|
||||
DEVtrunc :CSWtrunc,
|
||||
DEVfindBranch : NULL,
|
||||
DEVacLoad : CSWacLoad,
|
||||
DEVaccept : NULL,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon Jacobs
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -47,6 +48,9 @@ CSWload(inModel,ckt)
|
|||
*(ckt->CKTstate0 + here->CSWstate) = 0.0;
|
||||
current_state = 0.0;
|
||||
}
|
||||
|
||||
*(ckt->CKTstate0 + (here->CSWstate+1)) = 0;
|
||||
|
||||
} else if (ckt->CKTmode & (MODEINITSMSIG)) {
|
||||
|
||||
previous_state = *(ckt->CKTstate0 + here->CSWstate);
|
||||
|
|
@ -70,6 +74,8 @@ CSWload(inModel,ckt)
|
|||
current_state = previous_state;
|
||||
}
|
||||
|
||||
*(ckt->CKTstate0 + (here->CSWstate+1)) = i_ctrl;
|
||||
|
||||
if(current_state != previous_state) {
|
||||
ckt->CKTnoncon++; /* ensure one more iteration */
|
||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||
|
|
@ -96,6 +102,8 @@ CSWload(inModel,ckt)
|
|||
*(ckt->CKTstate0 + here->CSWstate) = 1.0;
|
||||
}
|
||||
|
||||
*(ckt->CKTstate0 + (here->CSWstate+1)) = i_ctrl;
|
||||
|
||||
}
|
||||
|
||||
g_now = current_state?(model->CSWonConduct):(model->CSWoffConduct);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/* support routines for device models */
|
||||
|
|
@ -47,18 +48,32 @@ DEVpnjlim(double vnew,
|
|||
|
||||
if((vnew > vcrit) && (fabs(vnew - vold) > (vt + vt))) {
|
||||
if(vold > 0) {
|
||||
arg = 1 + (vnew - vold) / vt;
|
||||
arg = (vnew - vold) / vt;
|
||||
if(arg > 0) {
|
||||
vnew = vold + vt * log(arg);
|
||||
vnew = vold + vt * (2+log(arg-2));
|
||||
} else {
|
||||
vnew = vcrit;
|
||||
vnew = vold - vt * (2+log(2-arg));
|
||||
}
|
||||
} else {
|
||||
vnew = vt *log(vnew/vt);
|
||||
}
|
||||
*icheck = 1;
|
||||
} else {
|
||||
*icheck = 0;
|
||||
if (vnew < 0) {
|
||||
if (vold > 0) {
|
||||
arg = -1*vold-1;
|
||||
} else {
|
||||
arg = 2*vold-1;
|
||||
}
|
||||
if (vnew < arg) {
|
||||
vnew = arg;
|
||||
*icheck = 1;
|
||||
} else {
|
||||
*icheck = 0;
|
||||
};
|
||||
} else {
|
||||
*icheck = 0;
|
||||
}
|
||||
}
|
||||
return(vnew);
|
||||
}
|
||||
|
|
@ -76,7 +91,7 @@ DEVfetlim(double vnew,
|
|||
double vtemp;
|
||||
|
||||
vtsthi = fabs(2*(vold-vto))+2;
|
||||
vtstlo = vtsthi/2 +2;
|
||||
vtstlo = fabs(vold-vto)*1;
|
||||
vtox = vto + 3.5;
|
||||
delv = vnew-vold;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
|
|
@ -29,6 +30,9 @@ extern int DIOtrunc(GENmodel*,CKTcircuit*,double*);
|
|||
extern int DIOdisto(int,GENmodel*,CKTcircuit*);
|
||||
extern int DIOnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
|
||||
extern int DIOdSetup(DIOmodel*,CKTcircuit*);
|
||||
|
||||
|
||||
#else /* stdc */
|
||||
|
||||
extern int DIOacLoad();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -176,7 +177,7 @@ next1: if (vd >= -3*vte) {
|
|||
evd = exp(vd/vte);
|
||||
cd = csat*(evd-1)+ckt->CKTgmin*vd;
|
||||
gd = csat*evd/vte+ckt->CKTgmin;
|
||||
} else if((!(here->DIOtBrkdwnV))||
|
||||
} else if((!(model->DIObreakdownVoltageGiven)) ||
|
||||
vd >= -here->DIOtBrkdwnV) {
|
||||
arg=3*vte/(vd*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
|
|
@ -194,10 +195,10 @@ next1: if (vd >= -3*vte) {
|
|||
*/
|
||||
czero=here->DIOtJctCap*here->DIOarea;
|
||||
if (vd < here->DIOtDepCap){
|
||||
arg=1-vd/model->DIOjunctionPot;
|
||||
arg=1-vd/here->DIOtJctPot;
|
||||
sarg=exp(-model->DIOgradingCoeff*log(arg));
|
||||
*(ckt->CKTstate0 + here->DIOcapCharge) =
|
||||
model->DIOtransitTime*cd+model->DIOjunctionPot*
|
||||
model->DIOtransitTime*cd+here->DIOtJctPot*
|
||||
czero* (1-arg*sarg)/(1-model->DIOgradingCoeff);
|
||||
capd=model->DIOtransitTime*gd+czero*sarg;
|
||||
} else {
|
||||
|
|
@ -205,11 +206,11 @@ next1: if (vd >= -3*vte) {
|
|||
*(ckt->CKTstate0 + here->DIOcapCharge) =
|
||||
model->DIOtransitTime*cd+czero*here->DIOtF1+czof2*
|
||||
(model->DIOf3*(vd-here->DIOtDepCap)+
|
||||
(model->DIOgradingCoeff/(model->DIOjunctionPot+
|
||||
model->DIOjunctionPot))*(vd*vd-here->DIOtDepCap*
|
||||
(model->DIOgradingCoeff/(here->DIOtJctPot+
|
||||
here->DIOtJctPot))*(vd*vd-here->DIOtDepCap*
|
||||
here->DIOtDepCap));
|
||||
capd=model->DIOtransitTime*gd+czof2*(model->DIOf3+
|
||||
model->DIOgradingCoeff*vd/model->DIOjunctionPot);
|
||||
model->DIOgradingCoeff*vd/here->DIOtJctPot);
|
||||
}
|
||||
here->DIOcap = capd;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/* load the diode structure with those pointers needed later
|
||||
|
|
@ -86,9 +87,21 @@ matrixpointers:
|
|||
if(model->DIOresist == 0) {
|
||||
here->DIOposPrimeNode = here->DIOposNode;
|
||||
} else if(here->DIOposPrimeNode == 0) {
|
||||
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
error = CKTmkVolt(ckt,&tmp,here->DIOname,"internal");
|
||||
if(error) return(error);
|
||||
here->DIOposPrimeNode = tmp->number;
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* macro to make elements with built in test for out of memory */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/* perform the temperature update to the diode */
|
||||
|
|
@ -111,7 +112,10 @@ DIOtemp(inModel,ckt)
|
|||
here->DIOtJctPot;
|
||||
/* and Vcrit */
|
||||
vte=model->DIOemissionCoeff*vt;
|
||||
here->DIOtVcrit=vte*log(vte/(CONSTroot2*here->DIOtSatCur));
|
||||
|
||||
here->DIOtVcrit=vte*
|
||||
log(vte/(CONSTroot2*here->DIOtSatCur*here->DIOarea));
|
||||
|
||||
/* and now to copute the breakdown voltage, again, using
|
||||
* temperature adjusted basic parameters */
|
||||
if (model->DIObreakdownVoltageGiven){
|
||||
|
|
@ -121,12 +125,12 @@ DIOtemp(inModel,ckt)
|
|||
emsg = MALLOC(100);
|
||||
if(emsg == (char *)NULL) return(E_NOMEM);
|
||||
(void)sprintf(emsg,
|
||||
"%%s: breakdown current increased to %g to resolve incompatability",
|
||||
"%%s: breakdown current increased to %g to resolve",
|
||||
cbv);
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,emsg,&(here->DIOname));
|
||||
FREE(emsg);
|
||||
(*(SPfrontEnd->IFerror))(ERR_WARNING,
|
||||
"with specified saturation current",(IFuid*)NULL);
|
||||
"incompatibility with specified saturation current",(IFuid*)NULL);
|
||||
xbv=model->DIObreakdownVoltage;
|
||||
} else {
|
||||
tol=ckt->CKTreltol*cbv;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 Alansfixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -187,6 +188,7 @@ ISRCload(inModel,ckt)
|
|||
}
|
||||
}
|
||||
loadDone:
|
||||
if (ckt->CKTmode & MODETRANOP) value *= ckt->CKTsrcFact;
|
||||
*(ckt->CKTrhs + (here->ISRCposNode)) += value;
|
||||
*(ckt->CKTrhs + (here->ISRCnegNode)) -= value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -21,6 +22,8 @@ ISRCparam(param,value,inst,select)
|
|||
GENinstance *inst;
|
||||
IFvalue *select;
|
||||
{
|
||||
|
||||
int i;
|
||||
ISRCinstance *here = (ISRCinstance*)inst;
|
||||
switch(param) {
|
||||
case ISRC_DC:
|
||||
|
|
@ -83,6 +86,15 @@ ISRCparam(param,value,inst,select)
|
|||
here->ISRCcoeffs = value->v.vec.rVec;
|
||||
here->ISRCfunctionOrder = value->v.numValue;
|
||||
here->ISRCcoeffsGiven = TRUE;
|
||||
|
||||
for (i=0;i<((here->ISRCfunctionOrder/2)-1);i++) {
|
||||
if (*(here->ISRCcoeffs+2*(i+1))<=*(here->ISRCcoeffs+2*i)) {
|
||||
fprintf(stderr, "Warning : current source %s",
|
||||
here->ISRCname);
|
||||
fprintf(stderr, " has non-increasing PWL time points.\n");
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case ISRC_SFFM:
|
||||
if(value->v.numValue <2) return(E_BADPARM);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
|
|
@ -22,6 +23,8 @@ extern int JFETtrunc(GENmodel*,CKTcircuit*,double*);
|
|||
extern int JFETdisto(int,GENmodel*,CKTcircuit*);
|
||||
extern int JFETnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
|
||||
extern int JFETdSetup(GENmodel*,CKTcircuit*);
|
||||
|
||||
#else /* stdc */
|
||||
extern int JFETacLoad();
|
||||
extern int JFETask();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
Sydney University mods Copyright(c) 1989 Anthony E. Parker, David J. Skellern
|
||||
Laboratory for Communication Science Engineering
|
||||
Sydney University Department of Electrical Engineering, Australia
|
||||
|
|
@ -74,6 +75,8 @@ JFETload(inModel,ckt)
|
|||
int icheck;
|
||||
int ichk1;
|
||||
int error;
|
||||
|
||||
double arg, vt_temp;
|
||||
|
||||
/* loop through all the models */
|
||||
for( ; model != NULL; model = model->JFETnextModel ) {
|
||||
|
|
@ -219,22 +222,30 @@ JFETload(inModel,ckt)
|
|||
* determine dc current and derivatives
|
||||
*/
|
||||
vds=vgs-vgd;
|
||||
if (vgs <= -5*here->JFETtemp*CONSTKoverQ) {
|
||||
ggs = -csat/vgs+ckt->CKTgmin;
|
||||
cg = ggs*vgs;
|
||||
|
||||
vt_temp=here->JFETtemp*CONSTKoverQ;
|
||||
if (vgs < -3*vt_temp) {
|
||||
arg=3*vt_temp/(vgs*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cg = -csat*(1+arg)+ckt->CKTgmin*vgs;
|
||||
ggs = csat*3*arg/vgs+ckt->CKTgmin;
|
||||
} else {
|
||||
evgs = exp(vgs/(here->JFETtemp*CONSTKoverQ));
|
||||
ggs = csat*evgs/(here->JFETtemp*CONSTKoverQ)+ckt->CKTgmin;
|
||||
evgs = exp(vgs/vt_temp);
|
||||
ggs = csat*evgs/vt_temp+ckt->CKTgmin;
|
||||
cg = csat*(evgs-1)+ckt->CKTgmin*vgs;
|
||||
}
|
||||
if (vgd <= -5*(here->JFETtemp*CONSTKoverQ)) {
|
||||
ggd = -csat/vgd+ckt->CKTgmin;
|
||||
cgd = ggd*vgd;
|
||||
|
||||
if (vgd < -3*vt_temp) {
|
||||
arg=3*vt_temp/(vgd*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cgd = -csat*(1+arg)+ckt->CKTgmin*vgd;
|
||||
ggd = csat*3*arg/vgd+ckt->CKTgmin;
|
||||
} else {
|
||||
evgd = exp(vgd/(here->JFETtemp*CONSTKoverQ));
|
||||
ggd = csat*evgd/(here->JFETtemp*CONSTKoverQ)+ckt->CKTgmin;
|
||||
evgd = exp(vgd/vt_temp);
|
||||
ggd = csat*evgd/vt_temp+ckt->CKTgmin;
|
||||
cgd = csat*(evgd-1)+ckt->CKTgmin*vgd;
|
||||
}
|
||||
|
||||
cg = cg+cgd;
|
||||
|
||||
/* Modification for Sydney University JFET model */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
Sydney University mods Copyright(c) 1989 Anthony E. Parker, David J. Skellern
|
||||
Laboratory for Communication Science Engineering
|
||||
Sydney University Department of Electrical Engineering, Australia
|
||||
|
|
@ -95,6 +96,9 @@ JFETsetup(matrix,inModel,ckt,states)
|
|||
here=here->JFETnextInstance) {
|
||||
if (here->JFETowner != ARCHme) goto matrixpointers;
|
||||
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if(!here->JFETareaGiven) {
|
||||
here->JFETarea = 1;
|
||||
}
|
||||
|
|
@ -106,6 +110,16 @@ matrixpointers:
|
|||
error = CKTmkVolt(ckt,&tmp,here->JFETname,"source");
|
||||
if(error) return(error);
|
||||
here->JFETsourcePrimeNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->JFETsourcePrimeNode = here->JFETsourceNode;
|
||||
}
|
||||
|
|
@ -113,6 +127,16 @@ matrixpointers:
|
|||
error = CKTmkVolt(ckt,&tmp,here->JFETname,"drain");
|
||||
if(error) return(error);
|
||||
here->JFETdrainPrimeNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->JFETdrainPrimeNode = here->JFETdrainNode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1990 Jaijeet S. Roychowdhury
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
|
|
@ -19,6 +20,8 @@ extern int LTRAunsetup(GENmodel*,CKTcircuit*);
|
|||
extern int LTRAtemp(GENmodel*,CKTcircuit*);
|
||||
extern int LTRAtrunc(GENmodel*,CKTcircuit*,double*);
|
||||
|
||||
extern int LTRAlinInterp(double,double,double,double*,double*);
|
||||
|
||||
extern int LTRAquadInterp(double,double,double,double,double*,double*,double*);
|
||||
/*
|
||||
extern double LTRAcoeffSetup(double*,int,double,double,double*,double,double*,int,int*);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 S. Hwang
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
|
|
@ -22,6 +23,8 @@ extern int MEStrunc(GENmodel*,CKTcircuit*,double*);
|
|||
extern int MESdisto(int,GENmodel*,CKTcircuit*);
|
||||
extern int MESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
|
||||
extern int MESdSetup(GENmodel*,CKTcircuit*);
|
||||
|
||||
#else /* stdc */
|
||||
extern int MESacLoad();
|
||||
extern int MESask();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 S. Hwang
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -80,6 +81,7 @@ MESload(inModel,ckt)
|
|||
double vgst;
|
||||
double vto;
|
||||
double xfact;
|
||||
double arg;
|
||||
int icheck;
|
||||
int ichk1;
|
||||
int error;
|
||||
|
|
@ -230,22 +232,28 @@ MESload(inModel,ckt)
|
|||
* determine dc current and derivatives
|
||||
*/
|
||||
vds = vgs-vgd;
|
||||
if (vgs <= -5*CONSTvt0) {
|
||||
ggs = -csat/vgs+ckt->CKTgmin;
|
||||
cg = ggs*vgs;
|
||||
|
||||
if (vgs <= -3*CONSTvt0) {
|
||||
arg=3*CONSTvt0/(vgs*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cg = -csat*(1+arg)+ckt->CKTgmin*vgs;
|
||||
ggs = csat*3*arg/vgs+ckt->CKTgmin;
|
||||
} else {
|
||||
evgs = exp(vgs/CONSTvt0);
|
||||
ggs = csat*evgs/CONSTvt0+ckt->CKTgmin;
|
||||
cg = csat*(evgs-1)+ckt->CKTgmin*vgs;
|
||||
}
|
||||
if (vgd <= -5*CONSTvt0) {
|
||||
ggd = -csat/vgd+ckt->CKTgmin;
|
||||
cgd = ggd*vgd;
|
||||
if (vgd <= -3*CONSTvt0) {
|
||||
arg=3*CONSTvt0/(vgd*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cgd = -csat*(1+arg)+ckt->CKTgmin*vgd;
|
||||
ggd = csat*3*arg/vgd+ckt->CKTgmin;
|
||||
} else {
|
||||
evgd = exp(vgd/CONSTvt0);
|
||||
ggd = csat*evgd/CONSTvt0+ckt->CKTgmin;
|
||||
cgd = csat*(evgd-1)+ckt->CKTgmin*vgd;
|
||||
}
|
||||
|
||||
cg = cg+cgd;
|
||||
/*
|
||||
* compute drain current and derivitives for normal mode
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 S. Hwang
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -81,6 +82,9 @@ MESsetup(matrix,inModel,ckt,states)
|
|||
here=here->MESnextInstance) {
|
||||
if (here->MESowner != ARCHme) goto matrixpointers;
|
||||
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if(!here->MESareaGiven) {
|
||||
here->MESarea = 1;
|
||||
}
|
||||
|
|
@ -92,6 +96,16 @@ matrixpointers:
|
|||
error = CKTmkVolt(ckt,&tmp,here->MESname,"source");
|
||||
if(error) return(error);
|
||||
here->MESsourcePrimeNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->MESsourcePrimeNode = here->MESsourceNode;
|
||||
}
|
||||
|
|
@ -99,6 +113,16 @@ matrixpointers:
|
|||
error = CKTmkVolt(ckt,&tmp,here->MESname,"drain");
|
||||
if(error) return(error);
|
||||
here->MESdrainPrimeNode = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->MESdrainPrimeNode = here->MESdrainNode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -11,6 +12,7 @@ Author: 1987 Thomas L. Quarles
|
|||
#include "suffix.h"
|
||||
|
||||
IFparm MOS1pTable[] = { /* parameters */
|
||||
IOPU("m", MOS1_M, IF_REAL , "Multiplier"),
|
||||
IOPU("l", MOS1_L, IF_REAL , "Length"),
|
||||
IOPU("w", MOS1_W, IF_REAL , "Width"),
|
||||
IOPU("ad", MOS1_AD, IF_REAL , "Drain area"),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -51,12 +52,14 @@ MOS1acLoad(inModel,ckt)
|
|||
* meyer's model parameters
|
||||
*/
|
||||
EffectiveLength=here->MOS1l - 2*model->MOS1latDiff;
|
||||
|
||||
GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor *
|
||||
here->MOS1w;
|
||||
here->MOS1m * here->MOS1w;
|
||||
GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor *
|
||||
here->MOS1w;
|
||||
here->MOS1m * here->MOS1w;
|
||||
GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
here->MOS1m * EffectiveLength;
|
||||
|
||||
capgs = ( *(ckt->CKTstate0+here->MOS1capgs)+
|
||||
*(ckt->CKTstate0+here->MOS1capgs) +
|
||||
GateSourceOverlapCap );
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -34,11 +35,14 @@ MOS1ask(ckt,inst,which,value,select)
|
|||
value->rValue = here->MOS1temp-CONSTCtoK;
|
||||
return(OK);
|
||||
case MOS1_CGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS1capgs);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgs);
|
||||
return(OK);
|
||||
case MOS1_CGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS1capgd);
|
||||
return(OK);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgd);
|
||||
return(OK);
|
||||
case MOS1_M:
|
||||
value->rValue = here->MOS1m;
|
||||
return(OK);
|
||||
case MOS1_L:
|
||||
value->rValue = here->MOS1l;
|
||||
return(OK);
|
||||
|
|
@ -178,7 +182,11 @@ MOS1ask(ckt,inst,which,value,select)
|
|||
value->rValue = *(ckt->CKTstate0 + here->MOS1vds);
|
||||
return(OK);
|
||||
case MOS1_CAPGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS1capgs);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgs);
|
||||
/* add overlap capacitance */
|
||||
value->rValue += (here->sMOS1modPtr->MOS1gateSourceOverlapCapFactor)
|
||||
* here->MOS1m
|
||||
* (here->MOS1w);
|
||||
return(OK);
|
||||
case MOS1_QGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS1qgs);
|
||||
|
|
@ -187,7 +195,11 @@ MOS1ask(ckt,inst,which,value,select)
|
|||
value->rValue = *(ckt->CKTstate0 + here->MOS1cqgs);
|
||||
return(OK);
|
||||
case MOS1_CAPGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS1capgd);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgd);
|
||||
* add overlap capacitance */
|
||||
value->rValue += (here->sMOS1modPtr->MOS1gateSourceOverlapCapFactor)
|
||||
* here->MOS1m
|
||||
* (here->MOS1w);
|
||||
return(OK);
|
||||
case MOS1_QGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS1qgd);
|
||||
|
|
@ -196,7 +208,12 @@ MOS1ask(ckt,inst,which,value,select)
|
|||
value->rValue = *(ckt->CKTstate0 + here->MOS1cqgd);
|
||||
return(OK);
|
||||
case MOS1_CAPGB:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS1capgb);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgb);
|
||||
/* add overlap capacitance */
|
||||
value->rValue += (here->sMOS1modPtr->MOS1gateBulkOverlapCapFactor)
|
||||
* here->MOS1m
|
||||
* (here->MOS1l
|
||||
-2*(here->sMOS1modPtr->MOS1latDiff));
|
||||
return(OK);
|
||||
case MOS1_QGB:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS1qgb);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifndef MOS1
|
||||
|
|
@ -30,6 +31,8 @@ typedef struct sMOS1instance {
|
|||
int MOS1bNode; /* number of the bulk node of the mosfet */
|
||||
int MOS1dNodePrime; /* number of the internal drain node of the mosfet */
|
||||
int MOS1sNodePrime; /* number of the internal source node of the mosfet */
|
||||
|
||||
double MOS1m; /* parallel device multiplier */
|
||||
|
||||
double MOS1l; /* the length of the channel region */
|
||||
double MOS1w; /* the width of the channel region */
|
||||
|
|
@ -156,6 +159,7 @@ typedef struct sMOS1instance {
|
|||
|
||||
unsigned MOS1off:1; /* non-zero to indicate device is off for dc analysis*/
|
||||
unsigned MOS1tempGiven :1; /* instance temperature specified */
|
||||
unsigned MOS1mGiven :1;
|
||||
unsigned MOS1lGiven :1;
|
||||
unsigned MOS1wGiven :1;
|
||||
unsigned MOS1drainAreaGiven :1;
|
||||
|
|
@ -406,7 +410,7 @@ typedef struct sMOS1model { /* model structure for a resistor */
|
|||
#define MOS1_CS 18
|
||||
#define MOS1_POWER 19
|
||||
#define MOS1_TEMP 20
|
||||
|
||||
#define MOS1_M 21
|
||||
/* model paramerers */
|
||||
#define MOS1_MOD_VTO 101
|
||||
#define MOS1_MOD_KP 102
|
||||
|
|
|
|||
|
|
@ -91,26 +91,28 @@ MOS1dSetup(inModel,ckt)
|
|||
|
||||
vt = CONSTKoverQ * here->MOS1temp;
|
||||
EffectiveLength=here->MOS1l - 2*model->MOS1latDiff;
|
||||
if( (here->MOS1tSatCurDens == 0) ||
|
||||
|
||||
if( (here->MOS1tSatCurDens == 0) ||
|
||||
(here->MOS1drainArea == 0) ||
|
||||
(here->MOS1sourceArea == 0)) {
|
||||
DrainSatCur = here->MOS1tSatCur;
|
||||
SourceSatCur = here->MOS1tSatCur;
|
||||
DrainSatCur = here->MOS1m * here->MOS1tSatCur;
|
||||
SourceSatCur = here->MOS1m * here->MOS1tSatCur;
|
||||
} else {
|
||||
DrainSatCur = here->MOS1tSatCurDens *
|
||||
here->MOS1drainArea;
|
||||
here->MOS1m * here->MOS1drainArea;
|
||||
SourceSatCur = here->MOS1tSatCurDens *
|
||||
here->MOS1sourceArea;
|
||||
here->MOS1m * here->MOS1sourceArea;
|
||||
}
|
||||
GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor *
|
||||
here->MOS1w;
|
||||
here->MOS1m * here->MOS1w;
|
||||
GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor *
|
||||
here->MOS1w;
|
||||
here->MOS1m * here->MOS1w;
|
||||
GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
Beta = here->MOS1tTransconductance * here->MOS1w/EffectiveLength;
|
||||
here->MOS1m * EffectiveLength;
|
||||
Beta = here->MOS1tTransconductance * here->MOS1m *
|
||||
here->MOS1w/EffectiveLength;
|
||||
OxideCap = model->MOS1oxideCapFactor * EffectiveLength *
|
||||
here->MOS1w;
|
||||
here->MOS1m * here->MOS1w;
|
||||
|
||||
vbs = model->MOS1type * (
|
||||
*(ckt->CKTrhsOld+here->MOS1bNode) -
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
|
|
@ -27,6 +28,7 @@ extern int MOS1trunc(GENmodel*,CKTcircuit*,double*);
|
|||
extern int MOS1convTest(GENmodel*,CKTcircuit*);
|
||||
extern int MOS1disto(int,GENmodel*,CKTcircuit*);
|
||||
extern int MOS1noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
extern int MOS1dSetup(GENmodel*,CKTcircuit*);
|
||||
|
||||
#else /* stdc */
|
||||
extern int MOS1acLoad();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -111,26 +112,29 @@ MOS1load(inModel,ckt)
|
|||
*/
|
||||
|
||||
EffectiveLength=here->MOS1l - 2*model->MOS1latDiff;
|
||||
|
||||
if( (here->MOS1tSatCurDens == 0) ||
|
||||
(here->MOS1drainArea == 0) ||
|
||||
(here->MOS1sourceArea == 0)) {
|
||||
DrainSatCur = here->MOS1tSatCur;
|
||||
SourceSatCur = here->MOS1tSatCur;
|
||||
(here->MOS1drainArea == 0) ||
|
||||
(here->MOS1sourceArea == 0)) {
|
||||
DrainSatCur = here->MOS1m * here->MOS1tSatCur;
|
||||
SourceSatCur = here->MOS1m * here->MOS1tSatCur;
|
||||
} else {
|
||||
DrainSatCur = here->MOS1tSatCurDens *
|
||||
here->MOS1drainArea;
|
||||
here->MOS1m * here->MOS1drainArea;
|
||||
SourceSatCur = here->MOS1tSatCurDens *
|
||||
here->MOS1sourceArea;
|
||||
here->MOS1m * here->MOS1sourceArea;
|
||||
}
|
||||
GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor *
|
||||
here->MOS1w;
|
||||
here->MOS1m * here->MOS1w;
|
||||
GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor *
|
||||
here->MOS1w;
|
||||
here->MOS1m * here->MOS1w;
|
||||
GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
Beta = here->MOS1tTransconductance * here->MOS1w/EffectiveLength;
|
||||
here->MOS1m * EffectiveLength;
|
||||
Beta = here->MOS1tTransconductance * here->MOS1m *
|
||||
here->MOS1w/EffectiveLength;
|
||||
OxideCap = model->MOS1oxideCapFactor * EffectiveLength *
|
||||
here->MOS1w;
|
||||
here->MOS1m * here->MOS1w;
|
||||
|
||||
/*
|
||||
* ok - now to do the start-up operations
|
||||
*
|
||||
|
|
@ -412,25 +416,22 @@ MOS1load(inModel,ckt)
|
|||
* here we just evaluate the ideal diode current and the
|
||||
* corresponding derivative (conductance).
|
||||
*/
|
||||
next1: if(vbs <= 0) {
|
||||
here->MOS1gbs = SourceSatCur/vt;
|
||||
here->MOS1cbs = here->MOS1gbs*vbs;
|
||||
here->MOS1gbs += ckt->CKTgmin;
|
||||
} else {
|
||||
evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));
|
||||
here->MOS1gbs = SourceSatCur*evbs/vt + ckt->CKTgmin;
|
||||
here->MOS1cbs = SourceSatCur * (evbs-1);
|
||||
}
|
||||
if(vbd <= 0) {
|
||||
here->MOS1gbd = DrainSatCur/vt;
|
||||
here->MOS1cbd = here->MOS1gbd *vbd;
|
||||
here->MOS1gbd += ckt->CKTgmin;
|
||||
next1: if(vbs <= -3*vt) {
|
||||
here->MOS1gbs = ckt->CKTgmin;
|
||||
here->MOS1cbs = here->MOS1gbs*vbs-SourceSatCur;
|
||||
} else {
|
||||
evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));
|
||||
here->MOS1gbs = SourceSatCur*evbs/vt + ckt->CKTgmin;
|
||||
here->MOS1cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs;
|
||||
}
|
||||
if(vbd <= -3*vt) {
|
||||
here->MOS1gbd = ckt->CKTgmin;
|
||||
here->MOS1cbd = here->MOS1gbd*vbd-DrainSatCur;
|
||||
} else {
|
||||
evbd = exp(MIN(MAX_EXP_ARG,vbd/vt));
|
||||
here->MOS1gbd = DrainSatCur*evbd/vt +ckt->CKTgmin;
|
||||
here->MOS1cbd = DrainSatCur *(evbd-1);
|
||||
here->MOS1gbd = DrainSatCur*evbd/vt + ckt->CKTgmin;
|
||||
here->MOS1cbd = DrainSatCur*(evbd-1) + ckt->CKTgmin*vbd;
|
||||
}
|
||||
|
||||
/* now to determine whether the user was able to correctly
|
||||
* identify the source and drain of his device
|
||||
*/
|
||||
|
|
@ -861,9 +862,9 @@ MOS1load(inModel,ckt)
|
|||
* load current vector
|
||||
*/
|
||||
ceqbs = model->MOS1type *
|
||||
(here->MOS1cbs-(here->MOS1gbs-ckt->CKTgmin)*vbs);
|
||||
(here->MOS1cbs-(here->MOS1gbs)*vbs);
|
||||
ceqbd = model->MOS1type *
|
||||
(here->MOS1cbd-(here->MOS1gbd-ckt->CKTgmin)*vbd);
|
||||
(here->MOS1cbd-(here->MOS1gbd)*vbd);
|
||||
if (here->MOS1mode >= 0) {
|
||||
xnrm=1;
|
||||
xrev=0;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Gary W. Ng
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -145,6 +146,7 @@ if (!data->namelist) return(E_NOMEM);
|
|||
exp(model->MOS1fNexp *
|
||||
log(MAX(fabs(inst->MOS1cd),N_MINLOG))) /
|
||||
(data->freq * inst->MOS1w *
|
||||
inst->MOS1m *
|
||||
(inst->MOS1l - 2*model->MOS1latDiff) * coxSquared);
|
||||
lnNdens[MOS1FLNOIZ] =
|
||||
log(MAX(noizDens[MOS1FLNOIZ],N_MINLOG));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -28,6 +29,10 @@ MOS1param(param,value,inst,select)
|
|||
here->MOS1temp = value->rValue+CONSTCtoK;
|
||||
here->MOS1tempGiven = TRUE;
|
||||
break;
|
||||
case MOS1_M:
|
||||
here->MOS1m = value->rValue;
|
||||
here->MOS1mGiven = TRUE;
|
||||
break;
|
||||
case MOS1_W:
|
||||
here->MOS1w = value->rValue;
|
||||
here->MOS1wGiven = TRUE;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -53,12 +54,14 @@ MOS1pzLoad(inModel,ckt,s)
|
|||
* meyer's model parameters
|
||||
*/
|
||||
EffectiveLength=here->MOS1l - 2*model->MOS1latDiff;
|
||||
|
||||
GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor *
|
||||
here->MOS1w;
|
||||
here->MOS1m * here->MOS1w;
|
||||
GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor *
|
||||
here->MOS1w;
|
||||
here->MOS1m * here->MOS1w;
|
||||
GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
here->MOS1m * EffectiveLength;
|
||||
|
||||
capgs = ( 2* *(ckt->CKTstate0+here->MOS1capgs)+
|
||||
GateSourceOverlapCap );
|
||||
capgd = ( 2* *(ckt->CKTstate0+here->MOS1capgd)+
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/* load the MOS1 device structure with those pointers needed later
|
||||
|
|
@ -104,6 +105,9 @@ MOS1setup(matrix,inModel,ckt,states)
|
|||
}
|
||||
}
|
||||
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if(!here->MOS1drainPerimiterGiven) {
|
||||
here->MOS1drainPerimiter = 0;
|
||||
}
|
||||
|
|
@ -139,6 +143,16 @@ MOS1setup(matrix,inModel,ckt,states)
|
|||
error = CKTmkVolt(ckt,&tmp,here->MOS1name,"drain");
|
||||
if(error) return(error);
|
||||
here->MOS1dNodePrime = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->MOS1dNodePrime = here->MOS1dNode;
|
||||
}
|
||||
|
|
@ -150,6 +164,16 @@ MOS1setup(matrix,inModel,ckt,states)
|
|||
error = CKTmkVolt(ckt,&tmp,here->MOS1name,"source");
|
||||
if(error) return(error);
|
||||
here->MOS1sNodePrime = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->MOS1sNodePrime = here->MOS1sNode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
/* Pretty print the sensitivity info for all
|
||||
|
|
@ -41,7 +42,10 @@ CKTcircuit *ckt;
|
|||
printf(" Drain, Gate , Source nodes: %s, %s ,%s\n",
|
||||
CKTnodName(ckt,here->MOS1dNode),CKTnodName(ckt,here->MOS1gNode),
|
||||
CKTnodName(ckt,here->MOS1sNode));
|
||||
|
||||
|
||||
printf(" Multiplier: %g ",here->MOS1m);
|
||||
printf(here->MOS1mGiven ? "(specified)\n" : "(default)\n");
|
||||
|
||||
printf(" Length: %g ",here->MOS1l);
|
||||
printf(here->MOS1lGiven ? "(specified)\n" : "(default)\n");
|
||||
printf(" Width: %g ",here->MOS1w);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -137,6 +138,9 @@ MOS1temp(inModel,ckt)
|
|||
if(!here->MOS1drainAreaGiven) {
|
||||
here->MOS1drainArea = ckt->CKTdefaultMosAD;
|
||||
}
|
||||
if(!here->MOS1mGiven) {
|
||||
here->MOS1m = ckt->CKTdefaultMosM;
|
||||
}
|
||||
if(!here->MOS1lGiven) {
|
||||
here->MOS1l = ckt->CKTdefaultMosL;
|
||||
}
|
||||
|
|
@ -193,27 +197,30 @@ MOS1temp(inModel,ckt)
|
|||
(here->MOS1drainArea == 0) ||
|
||||
(here->MOS1sourceArea == 0) ) {
|
||||
here->MOS1sourceVcrit = here->MOS1drainVcrit =
|
||||
vt*log(vt/(CONSTroot2*here->MOS1tSatCur));
|
||||
vt*log(vt/(CONSTroot2*here->MOS1m*here->MOS1tSatCur));
|
||||
} else {
|
||||
here->MOS1drainVcrit =
|
||||
vt * log( vt / (CONSTroot2 *
|
||||
here->MOS1m *
|
||||
here->MOS1tSatCurDens * here->MOS1drainArea));
|
||||
here->MOS1sourceVcrit =
|
||||
vt * log( vt / (CONSTroot2 *
|
||||
here->MOS1m *
|
||||
here->MOS1tSatCurDens * here->MOS1sourceArea));
|
||||
}
|
||||
|
||||
if(model->MOS1capBDGiven) {
|
||||
czbd = here->MOS1tCbd;
|
||||
czbd = here->MOS1tCbd * here->MOS1m;
|
||||
} else {
|
||||
if(model->MOS1bulkCapFactorGiven) {
|
||||
czbd=here->MOS1tCj*here->MOS1drainArea;
|
||||
if(model->MOS1bulkCapFactorGiven) {
|
||||
czbd=here->MOS1tCj*here->MOS1m*here->MOS1drainArea;
|
||||
} else {
|
||||
czbd=0;
|
||||
}
|
||||
}
|
||||
if(model->MOS1sideWallCapFactorGiven) {
|
||||
czbdsw= here->MOS1tCjsw * here->MOS1drainPerimiter;
|
||||
czbdsw= here->MOS1tCjsw * here->MOS1drainPerimiter *
|
||||
here->MOS1m;
|
||||
} else {
|
||||
czbdsw=0;
|
||||
}
|
||||
|
|
@ -239,16 +246,17 @@ MOS1temp(inModel,ckt)
|
|||
(here->MOS1tDepCap*here->MOS1tDepCap)
|
||||
-here->MOS1tDepCap * here->MOS1f2d;
|
||||
if(model->MOS1capBSGiven) {
|
||||
czbs=here->MOS1tCbs;
|
||||
czbs=here->MOS1tCbs * here->MOS1m;
|
||||
} else {
|
||||
if(model->MOS1bulkCapFactorGiven) {
|
||||
czbs=here->MOS1tCj*here->MOS1sourceArea;
|
||||
czbs=here->MOS1tCj*here->MOS1sourceArea * here->MOS1m;
|
||||
} else {
|
||||
czbs=0;
|
||||
}
|
||||
}
|
||||
if(model->MOS1sideWallCapFactorGiven) {
|
||||
czbssw = here->MOS1tCjsw * here->MOS1sourcePerimiter;
|
||||
czbssw = here->MOS1tCjsw * here->MOS1sourcePerimiter *
|
||||
here->MOS1m;
|
||||
} else {
|
||||
czbssw=0;
|
||||
}
|
||||
|
|
@ -277,14 +285,16 @@ MOS1temp(inModel,ckt)
|
|||
|
||||
if(model->MOS1drainResistanceGiven) {
|
||||
if(model->MOS1drainResistance != 0) {
|
||||
here->MOS1drainConductance = 1/model->MOS1drainResistance;
|
||||
here->MOS1drainConductance = here->MOS1m /
|
||||
model->MOS1drainResistance;
|
||||
} else {
|
||||
here->MOS1drainConductance = 0;
|
||||
}
|
||||
} else if (model->MOS1sheetResistanceGiven) {
|
||||
if(model->MOS1sheetResistance != 0) {
|
||||
here->MOS1drainConductance =
|
||||
1/(model->MOS1sheetResistance*here->MOS1drainSquares);
|
||||
here->MOS1m /
|
||||
(model->MOS1sheetResistance*here->MOS1drainSquares);
|
||||
} else {
|
||||
here->MOS1drainConductance = 0;
|
||||
}
|
||||
|
|
@ -293,14 +303,18 @@ MOS1temp(inModel,ckt)
|
|||
}
|
||||
if(model->MOS1sourceResistanceGiven) {
|
||||
if(model->MOS1sourceResistance != 0) {
|
||||
here->MOS1sourceConductance = 1/model->MOS1sourceResistance;
|
||||
here->MOS1sourceConductance = here->MOS1m /
|
||||
model->MOS1sourceResistance;
|
||||
} else {
|
||||
here->MOS1sourceConductance = 0;
|
||||
}
|
||||
} else if (model->MOS1sheetResistanceGiven) {
|
||||
if(model->MOS1sheetResistance != 0) {
|
||||
if ((model->MOS1sheetResistance != 0) &&
|
||||
(here->MOS1sourceSquares != 0)) {
|
||||
#else
|
||||
here->MOS1sourceConductance =
|
||||
1/(model->MOS1sheetResistance*here->MOS1sourceSquares);
|
||||
here->MOS1m /
|
||||
(model->MOS1sheetResistance*here->MOS1sourceSquares);
|
||||
} else {
|
||||
here->MOS1sourceConductance = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFIxes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -11,6 +12,7 @@ Author: 1985 Thomas L. Quarles
|
|||
#include "suffix.h"
|
||||
|
||||
IFparm MOS2pTable[] = { /* parameters */
|
||||
IOPU("m", MOS2_M, IF_REAL , "Multiplier"),
|
||||
IOPU("l", MOS2_L, IF_REAL , "Length"),
|
||||
IOPU("w", MOS2_W, IF_REAL , "Width"),
|
||||
IOPU("ad", MOS2_AD, IF_REAL , "Drain area"),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -52,11 +53,11 @@ MOS2acLoad(inModel,ckt)
|
|||
*/
|
||||
EffectiveLength=here->MOS2l - 2*model->MOS2latDiff;
|
||||
GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor *
|
||||
here->MOS2w;
|
||||
here->MOS2m * here->MOS2w;
|
||||
GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor *
|
||||
here->MOS2w;
|
||||
here->MOS2m * here->MOS2w;
|
||||
GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
here->MOS2m * EffectiveLength;
|
||||
capgs = ( *(ckt->CKTstate0+here->MOS2capgs)+
|
||||
*(ckt->CKTstate0+here->MOS2capgs) +
|
||||
GateSourceOverlapCap );
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Mathew Lew and Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -34,14 +35,17 @@ MOS2ask(ckt,inst,which,value,select)
|
|||
value->rValue = here->MOS2temp-CONSTCtoK;
|
||||
return(OK);
|
||||
case MOS2_CGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS2capgs);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgs);
|
||||
return(OK);
|
||||
case MOS2_CGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS2capgd);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgd);
|
||||
return(OK);
|
||||
case MOS2_M:
|
||||
value->rValue = here->MOS2m;
|
||||
return(OK);
|
||||
case MOS2_L:
|
||||
value->rValue = here->MOS2l;
|
||||
return(OK);
|
||||
return(OK);
|
||||
case MOS2_W:
|
||||
value->rValue = here->MOS2w;
|
||||
return(OK);
|
||||
|
|
@ -178,7 +182,11 @@ MOS2ask(ckt,inst,which,value,select)
|
|||
value->rValue = *(ckt->CKTstate0 + here->MOS2vds);
|
||||
return(OK);
|
||||
case MOS2_CAPGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS2capgs);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgs);
|
||||
/* add overlap capacitance */
|
||||
value->rValue += (here->MOS2modPtr->MOS2gateSourceOverlapCapFactor)
|
||||
* here->MOS2m
|
||||
* (here->MOS2w);
|
||||
return(OK);
|
||||
case MOS2_QGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS2qgs);
|
||||
|
|
@ -187,7 +195,11 @@ MOS2ask(ckt,inst,which,value,select)
|
|||
value->rValue = *(ckt->CKTstate0 + here->MOS2cqgs);
|
||||
return(OK);
|
||||
case MOS2_CAPGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS2capgd);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgd);
|
||||
/* add overlap capacitance */
|
||||
value->rValue += (here->MOS2modPtr->MOS2gateSourceOverlapCapFactor)
|
||||
* here->MOS2m
|
||||
* (here->MOS2w);
|
||||
return(OK);
|
||||
case MOS2_QGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS2qgd);
|
||||
|
|
@ -196,7 +208,12 @@ MOS2ask(ckt,inst,which,value,select)
|
|||
value->rValue = *(ckt->CKTstate0 + here->MOS2cqgd);
|
||||
return(OK);
|
||||
case MOS2_CAPGB:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS2capgb);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgb);
|
||||
/* add overlap capacitance */
|
||||
value->rValue += (here->MOS2modPtr->MOS2gateBulkOverlapCapFactor)
|
||||
* here->MOS2m
|
||||
* (here->MOS2l
|
||||
-2*(here->MOS2modPtr->MOS2latDiff));
|
||||
return(OK);
|
||||
case MOS2_QGB:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS2qgb);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFIxes
|
||||
**********/
|
||||
|
||||
#ifndef MOS2
|
||||
|
|
@ -33,6 +34,8 @@ typedef struct sMOS2instance {
|
|||
|
||||
int MOS2mode; /* device mode : 1 = normal, -1 = inverse */
|
||||
|
||||
unsigned MOS2mGiven :1;
|
||||
|
||||
unsigned MOS2off :1;/* non-zero to indicate device is off for dc analysis*/
|
||||
unsigned MOS2lGiven :1;
|
||||
unsigned MOS2wGiven :1;
|
||||
|
|
@ -151,6 +154,8 @@ typedef struct sMOS2instance {
|
|||
/* the cureve matching Fc * Vj */
|
||||
double MOS2tVbi; /* temperature adjusted Vbi */
|
||||
|
||||
double MOS2m; /* parallel device multiplier */
|
||||
|
||||
double MOS2l; /* the length of the channel region */
|
||||
double MOS2w; /* the width of the channel region */
|
||||
double MOS2drainArea; /* the area of the drain diffusion */
|
||||
|
|
@ -489,6 +494,7 @@ typedef struct sMOS2model { /* model structure for a resistor */
|
|||
#define MOS2_TEMP 77
|
||||
#define MOS2_SOURCERESIST 78
|
||||
#define MOS2_DRAINRESIST 79
|
||||
#define MOS2_M 80
|
||||
|
||||
/* model paramerers */
|
||||
#define MOS2_MOD_VTO 101
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1988 Jaijeet S Roychowdhury
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -82,26 +83,28 @@ double gmbds;
|
|||
vt = CONSTKoverQ * here->MOS2temp;
|
||||
|
||||
EffectiveLength=here->MOS2l - 2*model->MOS2latDiff;
|
||||
if( (here->MOS2tSatCurDens == 0) ||
|
||||
|
||||
if( (here->MOS2tSatCurDens == 0) ||
|
||||
(here->MOS2drainArea == 0) ||
|
||||
(here->MOS2sourceArea == 0)) {
|
||||
DrainSatCur = here->MOS2tSatCur;
|
||||
SourceSatCur = here->MOS2tSatCur;
|
||||
DrainSatCur = here->MOS2m * here->MOS2tSatCur;
|
||||
SourceSatCur = here->MOS2m * here->MOS2tSatCur;
|
||||
} else {
|
||||
DrainSatCur = here->MOS2tSatCurDens *
|
||||
here->MOS2drainArea;
|
||||
here->MOS2m * here->MOS2drainArea;
|
||||
SourceSatCur = here->MOS2tSatCurDens *
|
||||
here->MOS2sourceArea;
|
||||
here->MOS2m * here->MOS2sourceArea;
|
||||
}
|
||||
GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor *
|
||||
here->MOS2w;
|
||||
here->MOS2m * here->MOS2w;
|
||||
GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor *
|
||||
here->MOS2w;
|
||||
here->MOS2m * here->MOS2w;
|
||||
GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
Beta = here->MOS2tTransconductance * here->MOS2w/EffectiveLength;
|
||||
here->MOS2m * EffectiveLength;
|
||||
Beta = here->MOS2tTransconductance * here->MOS2m *
|
||||
here->MOS2w/EffectiveLength;
|
||||
OxideCap = model->MOS2oxideCapFactor * EffectiveLength *
|
||||
here->MOS2w;
|
||||
here->MOS2m * here->MOS2w;
|
||||
|
||||
|
||||
|
||||
|
|
@ -481,7 +484,7 @@ d_p.d3_pqr = 0.0;
|
|||
PlusDeriv(&d_cdonco,&d_cdonco,&d_dummy);
|
||||
TimesDeriv(&d_cdonco,&d_cdonco,-1.0);
|
||||
d_cdonco.value += factor;
|
||||
xn = 1.0+cfs/OxideCap*here->MOS2w*EffectiveLength+cdonco;
|
||||
xn = 1.0+cfs/OxideCap*here->MOS2m*here->MOS2w*EffectiveLength+cdonco;
|
||||
EqualDeriv(&d_xn,&d_cdonco);
|
||||
d_xn.value = xn;
|
||||
tmp = vt*xn;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
|
|
@ -27,6 +28,9 @@ extern int MOS2temp(GENmodel*,CKTcircuit*);
|
|||
extern int MOS2trunc(GENmodel*,CKTcircuit*,double*);
|
||||
extern int MOS2disto(int,GENmodel*,CKTcircuit*);
|
||||
extern int MOS2noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
|
||||
extern int MOS2dSetup(GENmodel*,CKTcircuit*);
|
||||
|
||||
#else /* stdc */
|
||||
extern int MOS2acLoad();
|
||||
extern int MOS2ask();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 alansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -108,26 +109,28 @@ MOS2load(inModel,ckt)
|
|||
}
|
||||
|
||||
EffectiveLength=here->MOS2l - 2*model->MOS2latDiff;
|
||||
|
||||
if( (here->MOS2tSatCurDens == 0) ||
|
||||
(here->MOS2drainArea == 0) ||
|
||||
(here->MOS2sourceArea == 0)) {
|
||||
DrainSatCur = here->MOS2tSatCur;
|
||||
SourceSatCur = here->MOS2tSatCur;
|
||||
DrainSatCur = here->MOS2m * here->MOS2tSatCur;
|
||||
SourceSatCur = here->MOS2m * here->MOS2tSatCur;
|
||||
} else {
|
||||
DrainSatCur = here->MOS2tSatCurDens *
|
||||
DrainSatCur = here->MOS2m * here->MOS2tSatCurDens *
|
||||
here->MOS2drainArea;
|
||||
SourceSatCur = here->MOS2tSatCurDens *
|
||||
SourceSatCur = here->MOS2m * here->MOS2tSatCurDens *
|
||||
here->MOS2sourceArea;
|
||||
}
|
||||
GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor *
|
||||
here->MOS2w;
|
||||
here->MOS2m * here->MOS2w;
|
||||
GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor *
|
||||
here->MOS2w;
|
||||
here->MOS2m * here->MOS2w;
|
||||
GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
Beta = here->MOS2tTransconductance * here->MOS2w/EffectiveLength;
|
||||
here->MOS2m * EffectiveLength;
|
||||
Beta = here->MOS2tTransconductance * here->MOS2w *
|
||||
here->MOS2m/EffectiveLength;
|
||||
OxideCap = model->MOS2oxideCapFactor * EffectiveLength *
|
||||
here->MOS2w;
|
||||
here->MOS2m * here->MOS2w;
|
||||
|
||||
|
||||
if(SenCond){
|
||||
|
|
@ -374,24 +377,23 @@ MOS2load(inModel,ckt)
|
|||
* correspoinding derivative (conductance).
|
||||
*/
|
||||
|
||||
next1: if(vbs <= 0) {
|
||||
here->MOS2gbs = SourceSatCur/vt;
|
||||
here->MOS2cbs = here->MOS2gbs*vbs;
|
||||
here->MOS2gbs += ckt->CKTgmin;
|
||||
next1: if(vbs <= -3*vt) {
|
||||
here->MOS2gbs = ckt->CKTgmin;
|
||||
here->MOS2cbs = here->MOS2gbs*vbs-SourceSatCur;
|
||||
} else {
|
||||
evbs = exp(vbs/vt);
|
||||
evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));
|
||||
here->MOS2gbs = SourceSatCur*evbs/vt + ckt->CKTgmin;
|
||||
here->MOS2cbs = SourceSatCur * (evbs-1);
|
||||
here->MOS2cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs;
|
||||
}
|
||||
if(vbd <= 0) {
|
||||
here->MOS2gbd = DrainSatCur/vt;
|
||||
here->MOS2cbd = here->MOS2gbd *vbd;
|
||||
here->MOS2gbd += ckt->CKTgmin;
|
||||
if(vbd <= -3*vt) {
|
||||
here->MOS2gbd = ckt->CKTgmin;
|
||||
here->MOS2cbd = here->MOS2gbd*vbd-DrainSatCur;
|
||||
} else {
|
||||
evbd = exp(vbd/vt);
|
||||
here->MOS2gbd = DrainSatCur*evbd/vt +ckt->CKTgmin;
|
||||
here->MOS2cbd = DrainSatCur *(evbd-1);
|
||||
evbd = exp(MIN(MAX_EXP_ARG,vbd/vt));
|
||||
here->MOS2gbd = DrainSatCur*evbd/vt + ckt->CKTgmin;
|
||||
here->MOS2cbd = DrainSatCur*(evbd-1) + ckt->CKTgmin*vbd;
|
||||
}
|
||||
|
||||
if(vds >= 0) {
|
||||
/* normal mode */
|
||||
here->MOS2mode = 1;
|
||||
|
|
@ -561,7 +563,7 @@ next1: if(vbs <= 0) {
|
|||
dsrgdb = -0.5*sarg*tmp;
|
||||
d2sdb2 = -dsrgdb*tmp;
|
||||
}
|
||||
if ((lvds-lvbs) >= 0) {
|
||||
if ((lvbs-lvds) <= 0) {
|
||||
barg = sqrt(phiMinVbs+lvds);
|
||||
dbrgdb = -0.5/barg;
|
||||
d2bdb2 = 0.5*dbrgdb/(phiMinVbs+lvds);
|
||||
|
|
@ -642,14 +644,17 @@ next1: if(vbs <= 0) {
|
|||
cfs = CHARGE*model->MOS2fastSurfaceStateDensity*
|
||||
1e4 /*(cm**2/m**2)*/;
|
||||
cdonco = -(gamasd*dsrgdb+dgddvb*sarg)+factor;
|
||||
xn = 1.0+cfs/OxideCap*here->MOS2w*EffectiveLength+cdonco;
|
||||
|
||||
xn = 1.0+cfs/OxideCap*here->MOS2m*
|
||||
here->MOS2w*EffectiveLength+cdonco;
|
||||
|
||||
tmp = vt*xn;
|
||||
von = von+tmp;
|
||||
argg = 1.0/tmp;
|
||||
vgst = lvgs-von;
|
||||
} else {
|
||||
vgst = lvgs-von;
|
||||
if (lvgs <= von) {
|
||||
if (lvgs <= vbin) {
|
||||
/*
|
||||
* cutoff region
|
||||
*/
|
||||
|
|
@ -899,6 +904,13 @@ line610:
|
|||
goto line1050;
|
||||
}
|
||||
|
||||
if (model->MOS2fastSurfaceStateDensity != 0 && OxideCap != 0) {
|
||||
if (lvgs > von) goto line900;
|
||||
} else {
|
||||
if (lvgs > vbin) goto line900;
|
||||
goto doneval;
|
||||
}
|
||||
|
||||
if (lvgs > von) goto line900;
|
||||
/*
|
||||
* subthreshold region
|
||||
|
|
@ -1285,9 +1297,9 @@ bypass:
|
|||
* load current vector
|
||||
*/
|
||||
ceqbs = model->MOS2type *
|
||||
(here->MOS2cbs-(here->MOS2gbs-ckt->CKTgmin)*vbs);
|
||||
(here->MOS2cbs-(here->MOS2gbs)*vbs);
|
||||
ceqbd = model->MOS2type *
|
||||
(here->MOS2cbd-(here->MOS2gbd-ckt->CKTgmin)*vbd);
|
||||
(here->MOS2cbd-(here->MOS2gbd)*vbd);
|
||||
if (here->MOS2mode >= 0) {
|
||||
xnrm=1;
|
||||
xrev=0;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Gary W. Ng
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -134,7 +135,8 @@ if (!data->namelist) return(E_NOMEM);
|
|||
noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef *
|
||||
exp(model->MOS2fNexp *
|
||||
log(MAX(fabs(inst->MOS2cd),N_MINLOG))) /
|
||||
(data->freq * inst->MOS2w *
|
||||
(data->freq * inst->MOS2w *
|
||||
inst->MOS2m *
|
||||
(inst->MOS2l - 2*model->MOS2latDiff) *
|
||||
model->MOS2oxideCapFactor * model->MOS2oxideCapFactor);
|
||||
lnNdens[MOS2FLNOIZ] =
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -28,6 +29,10 @@ MOS2param(param,value,inst,select)
|
|||
here->MOS2temp = value->rValue+CONSTCtoK;
|
||||
here->MOS2tempGiven = TRUE;
|
||||
break;
|
||||
case MOS2_M:
|
||||
here->MOS2m = value->rValue;
|
||||
here->MOS2mGiven = TRUE;
|
||||
break;
|
||||
case MOS2_W:
|
||||
here->MOS2w = value->rValue;
|
||||
here->MOS2wGiven = TRUE;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -53,12 +54,14 @@ MOS2pzLoad(inModel,ckt,s)
|
|||
* meyer's model parameters
|
||||
*/
|
||||
EffectiveLength=here->MOS2l - 2*model->MOS2latDiff;
|
||||
|
||||
GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor *
|
||||
here->MOS2w;
|
||||
here->MOS2m * here->MOS2w;
|
||||
GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor *
|
||||
here->MOS2w;
|
||||
here->MOS2m * here->MOS2w;
|
||||
GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
here->MOS2m * EffectiveLength;
|
||||
|
||||
capgs = ( 2* *(ckt->CKTstate0+here->MOS2capgs)+
|
||||
GateSourceOverlapCap );
|
||||
capgd = ( 2* *(ckt->CKTstate0+here->MOS2capgd)+
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -124,7 +125,10 @@ MOS2setup(matrix,inModel,ckt,states)
|
|||
/* loop through all the instances of the model */
|
||||
for (here = model->MOS2instances; here != NULL ;
|
||||
here=here->MOS2nextInstance) {
|
||||
|
||||
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (here->MOS2owner == ARCHme) {
|
||||
/* allocate a chunk of the state vector */
|
||||
here->MOS2states = *states;
|
||||
|
|
@ -165,6 +169,16 @@ MOS2setup(matrix,inModel,ckt,states)
|
|||
error = CKTmkVolt(ckt,&tmp,here->MOS2name,"internal#drain");
|
||||
if(error) return(error);
|
||||
here->MOS2dNodePrime = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->MOS2dNodePrime = here->MOS2dNode;
|
||||
}
|
||||
|
|
@ -176,6 +190,16 @@ MOS2setup(matrix,inModel,ckt,states)
|
|||
error = CKTmkVolt(ckt,&tmp,here->MOS2name,"internal#source");
|
||||
if(error) return(error);
|
||||
here->MOS2sNodePrime = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset=tmpNode->nodeset;
|
||||
tmp->nsGiven=tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
here->MOS2sNodePrime = here->MOS2sNode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -22,7 +23,7 @@ MOS2sPrint(inModel,ckt)
|
|||
MOS2model *model = (MOS2model *)inModel;
|
||||
MOS2instance *here;
|
||||
|
||||
printf("LEVEL 1 MOSFETS-----------------\n");
|
||||
printf("LEVEL 2 MOSFETS-----------------\n");
|
||||
/* loop through all the MOS2 models */
|
||||
for( ; model != NULL; model = model->MOS2nextModel ) {
|
||||
|
||||
|
|
@ -38,6 +39,8 @@ MOS2sPrint(inModel,ckt)
|
|||
CKTnodName(ckt,here->MOS2dNode),CKTnodName(ckt,here->MOS2gNode),
|
||||
CKTnodName(ckt,here->MOS2sNode));
|
||||
|
||||
printf(" Multiplier: %g ",here->MOS2m);
|
||||
printf(here->MOS2mGiven ? "(specified)\n" : "(default)\n");
|
||||
printf(" Length: %g ",here->MOS2l);
|
||||
printf(here->MOS2lGiven ? "(specified)\n" : "(default)\n");
|
||||
printf(" Width: %g ",here->MOS2w);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -147,6 +148,9 @@ MOS2temp(inModel,ckt)
|
|||
|
||||
if(!here->MOS2drainAreaGiven) {
|
||||
here->MOS2drainArea = ckt->CKTdefaultMosAD;
|
||||
}
|
||||
if(!here->MOS2mGiven) {
|
||||
here->MOS2m = ckt->CKTdefaultMosM;
|
||||
}
|
||||
if(!here->MOS2lGiven) {
|
||||
here->MOS2l = ckt->CKTdefaultMosL;
|
||||
|
|
@ -159,14 +163,17 @@ MOS2temp(inModel,ckt)
|
|||
}
|
||||
if(model->MOS2drainResistanceGiven) {
|
||||
if(model->MOS2drainResistance != 0) {
|
||||
here->MOS2drainConductance = 1/model->MOS2drainResistance;
|
||||
here->MOS2drainConductance = here->MOS2m /
|
||||
model->MOS2drainResistance;
|
||||
} else {
|
||||
here->MOS2drainConductance = 0;
|
||||
}
|
||||
} else if (model->MOS2sheetResistanceGiven) {
|
||||
if(model->MOS2sheetResistance != 0) {
|
||||
if((model->MOS2sheetResistance != 0) &&
|
||||
(here->MOS2drainSquares != 0)) {
|
||||
here->MOS2drainConductance =
|
||||
1/(model->MOS2sheetResistance*here->MOS2drainSquares);
|
||||
here->MOS2m /
|
||||
(model->MOS2sheetResistance*here->MOS2drainSquares);
|
||||
} else {
|
||||
here->MOS2drainConductance = 0;
|
||||
}
|
||||
|
|
@ -175,14 +182,17 @@ MOS2temp(inModel,ckt)
|
|||
}
|
||||
if(model->MOS2sourceResistanceGiven) {
|
||||
if(model->MOS2sourceResistance != 0) {
|
||||
here->MOS2sourceConductance = 1/model->MOS2sourceResistance;
|
||||
here->MOS2sourceConductance = here->MOS2m /
|
||||
model->MOS2sourceResistance;
|
||||
} else {
|
||||
here->MOS2sourceConductance = 0;
|
||||
}
|
||||
} else if (model->MOS2sheetResistanceGiven) {
|
||||
if(model->MOS2sheetResistance != 0) {
|
||||
if ((model->MOS2sheetResistance != 0) &&
|
||||
(here->MOS2sourceSquares != 0)) {
|
||||
here->MOS2sourceConductance =
|
||||
1/(model->MOS2sheetResistance*here->MOS2sourceSquares);
|
||||
here->MOS2m /
|
||||
(model->MOS2sheetResistance*here->MOS2sourceSquares);
|
||||
} else {
|
||||
here->MOS2sourceConductance = 0;
|
||||
}
|
||||
|
|
@ -238,26 +248,29 @@ MOS2temp(inModel,ckt)
|
|||
(here->MOS2drainArea == 0) ||
|
||||
(here->MOS2sourceArea == 0) ) {
|
||||
here->MOS2sourceVcrit = here->MOS2drainVcrit =
|
||||
vt*log(vt/(CONSTroot2*here->MOS2tSatCur));
|
||||
vt*log(vt/(CONSTroot2*here->MOS2m*here->MOS2tSatCur));
|
||||
} else {
|
||||
here->MOS2drainVcrit =
|
||||
vt * log( vt / (CONSTroot2 *
|
||||
here->MOS2m *
|
||||
here->MOS2tSatCurDens * here->MOS2drainArea));
|
||||
here->MOS2sourceVcrit =
|
||||
vt * log( vt / (CONSTroot2 *
|
||||
here->MOS2m *
|
||||
here->MOS2tSatCurDens * here->MOS2sourceArea));
|
||||
}
|
||||
if(model->MOS2capBDGiven) {
|
||||
czbd = here->MOS2tCbd;
|
||||
czbd = here->MOS2tCbd * here->MOS2m;
|
||||
} else {
|
||||
if(model->MOS2bulkCapFactorGiven) {
|
||||
czbd=here->MOS2tCj*here->MOS2drainArea;
|
||||
czbd=here->MOS2tCj*here->MOS2drainArea * here->MOS2m;
|
||||
} else {
|
||||
czbd=0;
|
||||
}
|
||||
}
|
||||
if(model->MOS2sideWallCapFactorGiven) {
|
||||
czbdsw= here->MOS2tCjsw * here->MOS2drainPerimiter;
|
||||
czbdsw= here->MOS2tCjsw * here->MOS2drainPerimiter *
|
||||
here->MOS2m;;
|
||||
} else {
|
||||
czbdsw=0;
|
||||
}
|
||||
|
|
@ -283,16 +296,17 @@ MOS2temp(inModel,ckt)
|
|||
(here->MOS2tDepCap*here->MOS2tDepCap)
|
||||
-here->MOS2tDepCap * here->MOS2f2d;
|
||||
if(model->MOS2capBSGiven) {
|
||||
czbs=here->MOS2tCbs;
|
||||
czbs=here->MOS2tCbs * here->MOS2m;
|
||||
} else {
|
||||
if(model->MOS2bulkCapFactorGiven) {
|
||||
czbs=here->MOS2tCj*here->MOS2sourceArea;
|
||||
czbs=here->MOS2tCj*here->MOS2sourceArea * here->MOS2m;
|
||||
} else {
|
||||
czbs=0;
|
||||
}
|
||||
}
|
||||
if(model->MOS2sideWallCapFactorGiven) {
|
||||
czbssw = here->MOS2tCjsw * here->MOS2sourcePerimiter;
|
||||
czbssw = here->MOS2tCjsw * here->MOS2sourcePerimiter *
|
||||
here->MOS2m;
|
||||
} else {
|
||||
czbssw=0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -11,6 +12,7 @@ Author: 1987 Thomas L. Quarles
|
|||
#include "suffix.h"
|
||||
|
||||
IFparm MOS3pTable[] = { /* parameters */
|
||||
IOPU("m", MOS3_M, IF_REAL , "Multiplier"),
|
||||
IOPU("l", MOS3_L, IF_REAL , "Length"),
|
||||
IOPU("w", MOS3_W, IF_REAL , "Width"),
|
||||
IOPU("ad", MOS3_AD, IF_REAL , "Drain area"),
|
||||
|
|
@ -131,6 +133,11 @@ IFparm MOS3mPTable[] = { /* model parameters */
|
|||
IOPU("js", MOS3_MOD_JS, IF_REAL ,"Bulk jct. sat. current density"),
|
||||
IOP("tox", MOS3_MOD_TOX, IF_REAL ,"Oxide thickness"),
|
||||
IOP("ld", MOS3_MOD_LD, IF_REAL ,"Lateral diffusion"),
|
||||
IOP("xl", MOS3_MOD_XL, IF_REAL ,"Length mask adjustment"),
|
||||
IOP("wd", MOS3_MOD_WD, IF_REAL ,"Width Narrowing (Diffusion)"),
|
||||
IOP("xw", MOS3_MOD_XW, IF_REAL ,"Width mask adjustment"),
|
||||
IOPU("delvto", MOS3_MOD_DELVTO, IF_REAL ,"Threshold voltage Adjust"),
|
||||
IOPR("delvt0", MOS3_MOD_DELVTO, IF_REAL ,"Threshold voltage Adjust"),
|
||||
IOP("u0", MOS3_MOD_U0, IF_REAL ,"Surface mobility"),
|
||||
IOPR("uo", MOS3_MOD_U0, IF_REAL ,"Surface mobility"),
|
||||
IOP("fc", MOS3_MOD_FC, IF_REAL ,"Forward bias jct. fit parm."),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -23,6 +24,7 @@ MOS3acLoad(inModel,ckt)
|
|||
int xnrm;
|
||||
int xrev;
|
||||
double EffectiveLength;
|
||||
double EffectiveWidth;
|
||||
double xgs;
|
||||
double xgd;
|
||||
double xgb;
|
||||
|
|
@ -50,13 +52,17 @@ MOS3acLoad(inModel,ckt)
|
|||
/*
|
||||
* charge oriented model parameters
|
||||
*/
|
||||
EffectiveLength=here->MOS3l-2*model->MOS3latDiff;
|
||||
EffectiveWidth=here->MOS3w-2*model->MOS3widthNarrow+
|
||||
model->MOS3widthAdjust;
|
||||
EffectiveLength=here->MOS3l - 2*model->MOS3latDiff+
|
||||
model->MOS3lengthAdjust;
|
||||
|
||||
GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor *
|
||||
here->MOS3w;
|
||||
here->MOS3m * EffectiveWidth;
|
||||
GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor *
|
||||
here->MOS3w;
|
||||
here->MOS3m * EffectiveWidth;
|
||||
GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
here->MOS3m * EffectiveLength;
|
||||
/*
|
||||
* meyer"s model parameters
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Mathew Lew and Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -34,10 +35,13 @@ MOS3ask(ckt,inst,which,value,select)
|
|||
value->rValue = here->MOS3temp-CONSTCtoK;
|
||||
return(OK);
|
||||
case MOS3_CGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS3capgs);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgs);
|
||||
return(OK);
|
||||
case MOS3_CGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS3capgd);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgd);
|
||||
return(OK);
|
||||
case MOS3_M:
|
||||
value->rValue = here->MOS3m;
|
||||
return(OK);
|
||||
case MOS3_L:
|
||||
value->rValue = here->MOS3l;
|
||||
|
|
@ -178,7 +182,13 @@ MOS3ask(ckt,inst,which,value,select)
|
|||
value->rValue = *(ckt->CKTstate0 + here->MOS3vds);
|
||||
return(OK);
|
||||
case MOS3_CAPGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS3capgs);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgs);
|
||||
/* add overlap capacitance */
|
||||
value->rValue += (here->MOS3modPtr->MOS3gateSourceOverlapCapFactor)
|
||||
* here->MOS3m
|
||||
* (here->MOS3w
|
||||
+here->MOS3modPtr->MOS3widthAdjust
|
||||
-2*(here->MOS3modPtr->MOS3widthNarrow));
|
||||
return(OK);
|
||||
case MOS3_QGS:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS3qgs);
|
||||
|
|
@ -187,7 +197,13 @@ MOS3ask(ckt,inst,which,value,select)
|
|||
value->rValue = *(ckt->CKTstate0 + here->MOS3cqgs);
|
||||
return(OK);
|
||||
case MOS3_CAPGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS3capgd);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgd);
|
||||
/* add overlap capacitance */
|
||||
value->rValue += (here->MOS3modPtr->MOS3gateDrainOverlapCapFactor)
|
||||
* here->MOS3m
|
||||
* (here->MOS3w
|
||||
+here->MOS3modPtr->MOS3widthAdjust
|
||||
-2*(here->MOS3modPtr->MOS3widthNarrow));
|
||||
return(OK);
|
||||
case MOS3_QGD:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS3qgd);
|
||||
|
|
@ -196,7 +212,13 @@ MOS3ask(ckt,inst,which,value,select)
|
|||
value->rValue = *(ckt->CKTstate0 + here->MOS3cqgd);
|
||||
return(OK);
|
||||
case MOS3_CAPGB:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS3capgb);
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgb);
|
||||
/* add overlap capacitance */
|
||||
value->rValue += (here->MOS3modPtr->MOS3gateBulkOverlapCapFactor)
|
||||
* here->MOS3m
|
||||
* (here->MOS3l
|
||||
+here->MOS3modPtr->MOS3lengthAdjust
|
||||
-2*(here->MOS3modPtr->MOS3latDiff));
|
||||
return(OK);
|
||||
case MOS3_QGB:
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS3qgb);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlanFixes
|
||||
**********/
|
||||
|
||||
#ifndef MOS3
|
||||
|
|
@ -30,6 +31,7 @@ typedef struct sMOS3instance {
|
|||
int MOS3dNodePrime; /* number of the internal drain node of the mosfet */
|
||||
int MOS3sNodePrime; /* number of the internal source node of the mosfet */
|
||||
|
||||
double MOS3m; /* parallel device multiplier */
|
||||
double MOS3l; /* the length of the channel region */
|
||||
double MOS3w; /* the width of the channel region */
|
||||
double MOS3drainArea; /* the area of the drain diffusion */
|
||||
|
|
@ -89,6 +91,7 @@ typedef struct sMOS3instance {
|
|||
|
||||
unsigned MOS3off :1;/* non-zero to indicate device is off for dc analysis*/
|
||||
unsigned MOS3tempGiven :1; /* instance temperature specified */
|
||||
unsigned MOS3mGiven :1;
|
||||
unsigned MOS3lGiven :1;
|
||||
unsigned MOS3wGiven :1;
|
||||
unsigned MOS3drainAreaGiven :1;
|
||||
|
|
@ -321,6 +324,10 @@ typedef struct sMOS3model { /* model structure for a resistor */
|
|||
int MOS3type; /* device type : 1 = nmos, -1 = pmos */
|
||||
double MOS3tnom; /* temperature at which parameters measured */
|
||||
double MOS3latDiff;
|
||||
double MOS3lengthAdjust; /* New parm: mask adjustment to length */
|
||||
double MOS3widthNarrow; /* New parm to reduce effective width */
|
||||
double MOS3widthAdjust; /* New parm: mask adjustment to width */
|
||||
double MOS3delvt0; /* New parm: adjustment calculated vtO */
|
||||
double MOS3jctSatCurDensity; /* input - use tSatCurDens*/
|
||||
double MOS3jctSatCur; /* input - use tSatCur instead */
|
||||
double MOS3drainResistance;
|
||||
|
|
@ -362,6 +369,10 @@ typedef struct sMOS3model { /* model structure for a resistor */
|
|||
|
||||
unsigned MOS3typeGiven :1;
|
||||
unsigned MOS3latDiffGiven :1;
|
||||
unsigned MOS3lengthAdjustGiven :1;
|
||||
unsigned MOS3widthNarrowGiven :1;
|
||||
unsigned MOS3widthAdjustGiven :1;
|
||||
unsigned MOS3delvt0Given :1;
|
||||
unsigned MOS3jctSatCurDensityGiven :1;
|
||||
unsigned MOS3jctSatCurGiven :1;
|
||||
unsigned MOS3drainResistanceGiven :1;
|
||||
|
|
@ -485,6 +496,7 @@ typedef struct sMOS3model { /* model structure for a resistor */
|
|||
#define MOS3_TEMP 77
|
||||
#define MOS3_SOURCERESIST 78
|
||||
#define MOS3_DRAINRESIST 79
|
||||
#define MOS3_M 80
|
||||
|
||||
/* model parameters */
|
||||
#define MOS3_MOD_VTO 101
|
||||
|
|
@ -532,6 +544,11 @@ typedef struct sMOS3model { /* model structure for a resistor */
|
|||
#define MOS3_MOD_AF 143
|
||||
#define MOS3_MOD_TYPE 144
|
||||
|
||||
#define MOS3_MOD_XL 145
|
||||
#define MOS3_MOD_WD 146
|
||||
#define MOS3_MOD_XW 147
|
||||
#define MOS3_MOD_DELVTO 148
|
||||
|
||||
/* device questions */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1988 Jaijeet S Roychowdhury
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -27,6 +28,7 @@ MOS3dSetup(inModel,ckt)
|
|||
double Beta;
|
||||
double DrainSatCur;
|
||||
double EffectiveLength;
|
||||
double EffectiveWidth;
|
||||
double GateBulkOverlapCap;
|
||||
double GateDrainOverlapCap;
|
||||
double GateSourceOverlapCap;
|
||||
|
|
@ -76,29 +78,32 @@ MOS3dSetup(inModel,ckt)
|
|||
* here. They may be moved at the expense of instance size
|
||||
*/
|
||||
|
||||
EffectiveLength=here->MOS3l - 2*model->MOS3latDiff;
|
||||
EffectiveWidth=here->MOS3w-2*model->MOS3widthNarrow+
|
||||
model->MOS3widthAdjust;
|
||||
EffectiveLength=here->MOS3l - 2*model->MOS3latDiff+
|
||||
model->MOS3lengthAdjust;
|
||||
|
||||
if( (here->MOS3tSatCurDens == 0) ||
|
||||
(here->MOS3drainArea == 0) ||
|
||||
(here->MOS3sourceArea == 0)) {
|
||||
DrainSatCur = here->MOS3tSatCur;
|
||||
SourceSatCur = here->MOS3tSatCur;
|
||||
DrainSatCur = here->MOS3m * here->MOS3tSatCur;
|
||||
SourceSatCur = here->MOS3m * here->MOS3tSatCur;
|
||||
} else {
|
||||
DrainSatCur = here->MOS3tSatCurDens *
|
||||
here->MOS3drainArea;
|
||||
here->MOS3m * here->MOS3drainArea;
|
||||
SourceSatCur = here->MOS3tSatCurDens *
|
||||
here->MOS3sourceArea;
|
||||
here->MOS3m * here->MOS3sourceArea;
|
||||
}
|
||||
GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor *
|
||||
here->MOS3w;
|
||||
here->MOS3m * EffectiveWidth;
|
||||
GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor *
|
||||
here->MOS3w;
|
||||
here->MOS3m * EffectiveWidth;
|
||||
GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
Beta = here->MOS3tTransconductance * here->MOS3w/EffectiveLength;
|
||||
here->MOS3m * EffectiveLength;
|
||||
Beta = here->MOS3tTransconductance * here->MOS3m *
|
||||
EffectiveWidth/EffectiveLength;
|
||||
OxideCap = model->MOS3oxideCapFactor * EffectiveLength *
|
||||
here->MOS3w;
|
||||
|
||||
|
||||
here->MOS3m * EffectiveWidth;
|
||||
|
||||
/*
|
||||
* ok - now to do the start-up operations
|
||||
|
|
@ -381,7 +386,7 @@ d_p.d3_pqr = 0.0;
|
|||
fbodys = 0.5*gammas/(sqphbs+sqphbs);
|
||||
DivDeriv(&d_fbodys,&d_gammas,&d_sqphbs);
|
||||
TimesDeriv(&d_fbodys,&d_fbodys,0.25);
|
||||
fbody = fbodys+model->MOS3narrowFactor/here->MOS3w;
|
||||
fbody = fbodys+model->MOS3narrowFactor/EffectiveWidth;
|
||||
EqualDeriv(&d_fbody,&d_fbodys);
|
||||
d_fbody.value += fbody - fbodys;
|
||||
|
||||
|
|
@ -389,9 +394,10 @@ d_p.d3_pqr = 0.0;
|
|||
EqualDeriv(&d_onfbdy,&d_fbody);
|
||||
d_onfbdy.value += 1.0;
|
||||
InvDeriv(&d_onfbdy,&d_onfbdy);
|
||||
qbonco =gammas*sqphbs+model->MOS3narrowFactor*phibs/here->MOS3w;
|
||||
qbonco =gammas*sqphbs+model->MOS3narrowFactor*phibs/EffectiveWidth;
|
||||
EqualDeriv(&d_dummy,&d_phibs);
|
||||
TimesDeriv(&d_dummy,&d_dummy,model->MOS3narrowFactor*here->MOS3w);
|
||||
TimesDeriv(&d_dummy,&d_dummy,model->
|
||||
MOS3narrowFactor*EffectiveWidth);
|
||||
MultDeriv(&d_qbonco,&d_gammas,&d_sqphbs);
|
||||
PlusDeriv(&d_qbonco,&d_qbonco,&d_dummy);
|
||||
/*
|
||||
|
|
@ -412,7 +418,8 @@ d_p.d3_pqr = 0.0;
|
|||
EqualDeriv(&d_von,&d_vth);
|
||||
if ( model->MOS3fastSurfaceStateDensity != 0.0 ) {
|
||||
csonco = CHARGE*model->MOS3fastSurfaceStateDensity *
|
||||
1e4 /*(cm**2/m**2)*/ *EffectiveLength*here->MOS3w/OxideCap;/*const*/
|
||||
1e4 /*(cm**2/m**2)*/ *EffectiveLength*EffectiveWidth *
|
||||
here->MOS3m/OxideCap; /*const*/
|
||||
cdonco = 0.5*qbonco/phibs;
|
||||
DivDeriv(&d_cdonco,&d_qbonco,&d_phibs);
|
||||
TimesDeriv(&d_cdonco,&d_cdonco,0.5);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#ifdef __STDC__
|
||||
|
|
@ -27,6 +28,7 @@ extern int MOS3temp(GENmodel*,CKTcircuit*);
|
|||
extern int MOS3trunc(GENmodel*,CKTcircuit*,double*);
|
||||
extern int MOS3disto(int,GENmodel*,CKTcircuit*);
|
||||
extern int MOS3noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
extern int MOS3dSetup(GENmodel*,CKTcircuit*);
|
||||
#else /* stdc */
|
||||
extern int MOS3acLoad();
|
||||
extern int MOS3ask();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -26,6 +27,7 @@ MOS3load(inModel,ckt)
|
|||
double Beta;
|
||||
double DrainSatCur;
|
||||
double EffectiveLength;
|
||||
double EffectiveWidth;
|
||||
double GateBulkOverlapCap;
|
||||
double GateDrainOverlapCap;
|
||||
double GateSourceOverlapCap;
|
||||
|
|
@ -117,28 +119,33 @@ next:
|
|||
* here. They may be moved at the expense of instance size
|
||||
*/
|
||||
|
||||
EffectiveLength=here->MOS3l - 2*model->MOS3latDiff;
|
||||
if( (here->MOS3tSatCurDens == 0) ||
|
||||
EffectiveWidth=here->MOS3w-2*model->MOS3widthNarrow+
|
||||
model->MOS3widthAdjust;
|
||||
EffectiveLength=here->MOS3l - 2*model->MOS3latDiff+
|
||||
model->MOS3lengthAdjust;
|
||||
|
||||
if( (here->MOS3tSatCurDens == 0) ||
|
||||
(here->MOS3drainArea == 0) ||
|
||||
(here->MOS3sourceArea == 0)) {
|
||||
DrainSatCur = here->MOS3tSatCur;
|
||||
SourceSatCur = here->MOS3tSatCur;
|
||||
DrainSatCur = here->MOS3m * here->MOS3tSatCur;
|
||||
SourceSatCur = here->MOS3m * here->MOS3tSatCur;
|
||||
} else {
|
||||
DrainSatCur = here->MOS3tSatCurDens *
|
||||
DrainSatCur = here->MOS3m * here->MOS3tSatCurDens *
|
||||
here->MOS3drainArea;
|
||||
SourceSatCur = here->MOS3tSatCurDens *
|
||||
SourceSatCur = here->MOS3m * here->MOS3tSatCurDens *
|
||||
here->MOS3sourceArea;
|
||||
}
|
||||
GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor *
|
||||
here->MOS3w;
|
||||
here->MOS3m * EffectiveWidth;
|
||||
GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor *
|
||||
here->MOS3w;
|
||||
here->MOS3m * EffectiveWidth;
|
||||
GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor *
|
||||
EffectiveLength;
|
||||
Beta = here->MOS3tTransconductance * here->MOS3w/EffectiveLength;
|
||||
here->MOS3m * EffectiveLength;
|
||||
Beta = here->MOS3tTransconductance *
|
||||
here->MOS3m * EffectiveWidth/EffectiveLength;
|
||||
OxideCap = model->MOS3oxideCapFactor * EffectiveLength *
|
||||
here->MOS3w;
|
||||
|
||||
here->MOS3m * EffectiveWidth;
|
||||
|
||||
if(SenCond){
|
||||
#ifdef SENSDEBUG
|
||||
printf("MOS3senPertFlag = ON \n");
|
||||
|
|
@ -395,23 +402,26 @@ next:
|
|||
* here we just evaluate the ideal diode current and the
|
||||
* corresponding derivative (conductance).
|
||||
*/
|
||||
next1: if(vbs <= 0) {
|
||||
here->MOS3gbs = SourceSatCur/vt;
|
||||
here->MOS3cbs = here->MOS3gbs*vbs;
|
||||
here->MOS3gbs += ckt->CKTgmin;
|
||||
|
||||
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);
|
||||
here->MOS3cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs;
|
||||
}
|
||||
if(vbd <= 0) {
|
||||
here->MOS3gbd = DrainSatCur/vt;
|
||||
here->MOS3cbd = here->MOS3gbd *vbd;
|
||||
here->MOS3gbd += ckt->CKTgmin;
|
||||
if(vbd <= -3*vt) {
|
||||
arg=3*vt/(vbd*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
here->MOS3cbd = -DrainSatCur*(1+arg)+ckt->CKTgmin*vbd;
|
||||
here->MOS3gbd = DrainSatCur*3*arg/vbd+ckt->CKTgmin;
|
||||
} else {
|
||||
evbd = exp(MIN(MAX_EXP_ARG,vbd/vt));
|
||||
here->MOS3gbd = DrainSatCur*evbd/vt +ckt->CKTgmin;
|
||||
here->MOS3cbd = DrainSatCur *(evbd-1);
|
||||
here->MOS3gbd = DrainSatCur*evbd/vt + ckt->CKTgmin;
|
||||
here->MOS3cbd = DrainSatCur*(evbd-1) + ckt->CKTgmin*vbd;
|
||||
}
|
||||
|
||||
/* now to determine whether the user was able to correctly
|
||||
|
|
@ -600,12 +610,12 @@ next1: if(vbs <= 0) {
|
|||
*/
|
||||
gammas = model->MOS3gamma*fshort;
|
||||
fbodys = 0.5*gammas/(sqphbs+sqphbs);
|
||||
fbody = fbodys+model->MOS3narrowFactor/here->MOS3w;
|
||||
fbody = fbodys+model->MOS3narrowFactor/EffectiveWidth;
|
||||
onfbdy = 1.0/(1.0+fbody);
|
||||
dfbdvb = -fbodys*dsqdvb/sqphbs+fbodys*dfsdvb/fshort;
|
||||
qbonco =gammas*sqphbs+model->MOS3narrowFactor*phibs/here->MOS3w;
|
||||
qbonco =gammas*sqphbs+model->MOS3narrowFactor*phibs/EffectiveWidth;
|
||||
dqbdvb = gammas*dsqdvb+model->MOS3gamma*dfsdvb*sqphbs-
|
||||
model->MOS3narrowFactor/here->MOS3w;
|
||||
model->MOS3narrowFactor/EffectiveWidth;
|
||||
/*
|
||||
*.....static feedback effect
|
||||
*/
|
||||
|
|
@ -622,7 +632,8 @@ next1: if(vbs <= 0) {
|
|||
von = vth;
|
||||
if ( model->MOS3fastSurfaceStateDensity != 0.0 ) {
|
||||
csonco = CHARGE*model->MOS3fastSurfaceStateDensity *
|
||||
1e4 /*(cm**2/m**2)*/ *EffectiveLength*here->MOS3w/OxideCap;
|
||||
1e4 /*(cm**2/m**2)*/ *EffectiveLength*EffectiveWidth *
|
||||
here->MOS3m/OxideCap;
|
||||
cdonco = qbonco/(phibs+phibs);
|
||||
xn = 1.0+csonco+cdonco;
|
||||
von = vth+vt*xn;
|
||||
|
|
@ -685,7 +696,8 @@ next1: if(vbs <= 0) {
|
|||
*/
|
||||
cdnorm = cdo*vdsx;
|
||||
here->MOS3gm = vdsx;
|
||||
here->MOS3gds = vgsx-vth-(1.0+fbody+dvtdvd)*vdsx;
|
||||
if ((here->MOS3mode*vds) > vdsat) here->MOS3gds = -dvtdvd*vdsx;
|
||||
else here->MOS3gds = vgsx-vth-(1.0+fbody+dvtdvd)*vdsx;
|
||||
here->MOS3gmbs = dcodvb*vdsx;
|
||||
/*
|
||||
*.....drain current without velocity saturation effect
|
||||
|
|
@ -695,16 +707,17 @@ next1: if(vbs <= 0) {
|
|||
cdrain = Beta*cdnorm;
|
||||
here->MOS3gm = Beta*here->MOS3gm+dfgdvg*cd1;
|
||||
here->MOS3gds = Beta*here->MOS3gds+dfgdvd*cd1;
|
||||
here->MOS3gmbs = Beta*here->MOS3gmbs;
|
||||
here->MOS3gmbs = Beta*here->MOS3gmbs+dfgdvb*cd1;
|
||||
/*
|
||||
*.....velocity saturation factor
|
||||
*/
|
||||
if ( model->MOS3maxDriftVel != 0.0 ) {
|
||||
if ( model->MOS3maxDriftVel > 0.0 ) {
|
||||
fdrain = 1.0/(1.0+vdsx*onvdsc);
|
||||
fd2 = fdrain*fdrain;
|
||||
arga = fd2*vdsx*onvdsc*onfg;
|
||||
dfddvg = -dfgdvg*arga;
|
||||
dfddvd = -dfgdvd*arga-fd2*onvdsc;
|
||||
if ((here->MOS3mode*vds) > vdsat) dfddvd = -dfgdvd*arga;
|
||||
else dfddvd = -dfgdvd*arga-fd2*onvdsc;
|
||||
dfddvb = -dfgdvb*arga;
|
||||
/*
|
||||
*.....drain current
|
||||
|
|
@ -718,7 +731,24 @@ next1: if(vbs <= 0) {
|
|||
/*
|
||||
*.....channel length modulation
|
||||
*/
|
||||
if ( (here->MOS3mode*vds) <= vdsat ) goto line700;
|
||||
|
||||
if ( (here->MOS3mode*vds) <= vdsat ) {
|
||||
if ( (model->MOS3maxDriftVel > 0.0) ||
|
||||
(model->MOS3alpha == 0.0) ||
|
||||
(ckt->CKTbadMos3) ) goto line700;
|
||||
else {
|
||||
arga = (here->MOS3mode*vds)/vdsat;
|
||||
delxl = sqrt(model->MOS3kappa*model->MOS3alpha*vdsat/8);
|
||||
dldvd = 4*delxl*arga*arga*arga/vdsat;
|
||||
arga *= arga;
|
||||
arga *= arga;
|
||||
delxl *= arga;
|
||||
ddldvg = 0.0;
|
||||
ddldvd = -dldvd;
|
||||
ddldvb = 0.0;
|
||||
goto line520;
|
||||
};
|
||||
|
||||
if ( model->MOS3maxDriftVel <= 0.0 ) goto line510;
|
||||
if (model->MOS3alpha == 0.0) goto line700;
|
||||
cdsat = cdrain;
|
||||
|
|
@ -757,9 +787,15 @@ next1: if(vbs <= 0) {
|
|||
ddldvb = dldem*demdvb;
|
||||
goto line520;
|
||||
line510:
|
||||
delxl = sqrt(model->MOS3kappa*((here->MOS3mode*vds)-vdsat)*
|
||||
model->MOS3alpha);
|
||||
dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat);
|
||||
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;
|
||||
|
|
@ -782,14 +818,19 @@ line520:
|
|||
*/
|
||||
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;
|
||||
gds0 = here->MOS3gds*xlfact+diddl*ddldvd;
|
||||
here->MOS3gmbs = here->MOS3gmbs*xlfact+diddl*ddldvb;
|
||||
gds0 = diddl*ddldvd;
|
||||
here->MOS3gm = here->MOS3gm+gds0*dvsdvg;
|
||||
here->MOS3gmbs = here->MOS3gmbs+gds0*dvsdvb;
|
||||
here->MOS3gds = gds0*dvsdvd+diddl*dldvd;
|
||||
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
|
||||
*/
|
||||
|
|
@ -1162,9 +1203,9 @@ bypass:
|
|||
* load current vector
|
||||
*/
|
||||
ceqbs = model->MOS3type *
|
||||
(here->MOS3cbs-(here->MOS3gbs-ckt->CKTgmin)*vbs);
|
||||
(here->MOS3cbs-(here->MOS3gbs)*vbs);
|
||||
ceqbd = model->MOS3type *
|
||||
(here->MOS3cbd-(here->MOS3gbd-ckt->CKTgmin)*vbd);
|
||||
(here->MOS3cbd-(here->MOS3gbd)*vbd);
|
||||
if (here->MOS3mode >= 0) {
|
||||
xnrm=1;
|
||||
xrev=0;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -89,6 +90,18 @@ MOS3mAsk(ckt,inst,which,value)
|
|||
case MOS3_MOD_LD:
|
||||
value->rValue = here->MOS3latDiff;
|
||||
return(OK);
|
||||
case MOS3_MOD_XL:
|
||||
value->rValue = here->MOS3lengthAdjust;
|
||||
return(OK);
|
||||
case MOS3_MOD_WD:
|
||||
value->rValue = here->MOS3widthNarrow;
|
||||
return(OK);
|
||||
case MOS3_MOD_XW:
|
||||
value->rValue = here->MOS3widthAdjust;
|
||||
return(OK);
|
||||
case MOS3_MOD_DELVTO:
|
||||
value->rValue = here->MOS3delvt0;
|
||||
return(OK);
|
||||
case MOS3_MOD_RSH:
|
||||
value->rValue = here->MOS3sheetResistance;
|
||||
return(OK);
|
||||
|
|
@ -136,7 +149,13 @@ MOS3mAsk(ckt,inst,which,value)
|
|||
return(OK);
|
||||
case MOS3_MOD_KAPPA:
|
||||
value->rValue = here->MOS3kappa;
|
||||
return(OK);
|
||||
case MOS3_MOD_KF:
|
||||
value->rValue = here->MOS3fNcoef;
|
||||
return(OK);
|
||||
case MOS3_MOD_AF:
|
||||
value->rValue = here->MOS3fNexp;
|
||||
return(OK);
|
||||
case MOS3_MOD_TYPE:
|
||||
if (here->MOS3type > 0)
|
||||
value->sValue = "nmos";
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue