Added patches extracted from Alan Gillespie's code. Documentation and

author's file not updated.
This commit is contained in:
pnenzi 2000-09-03 09:00:08 +00:00
parent 37fe87bb96
commit 0875108157
127 changed files with 2313 additions and 668 deletions

View File

@ -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, " ******** ");
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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*/

View File

@ -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();

View File

@ -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

View File

@ -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 *);

View File

@ -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;

View File

@ -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 */

View File

@ -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**);

View File

@ -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*/

View File

@ -18,3 +18,4 @@ struct s_sgen {
extern sgen *sgen_init( );
extern int sgen_next( );
extern int sgen_setp(sgen*, CKTcircuit*, IFvalue* ); /* AlansFixes */

View File

@ -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[],

View File

@ -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*/

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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"

View File

@ -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);
}

View File

@ -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)){

View File

@ -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;

View File

@ -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) ||

View File

@ -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();

View File

@ -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
*/

View File

@ -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 */

View File

@ -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));
}
}

View File

@ -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) ||

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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"),

View File

@ -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;
}
}
}

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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){

View File

@ -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;
}

View File

@ -20,7 +20,8 @@ libcsw_la_SOURCES = \
cswnoise.c \
cswparam.c \
cswpzld.c \
cswsetup.c
cswsetup.c \
cswtrunc.c

View File

@ -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 */

View File

@ -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 */

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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();

View File

@ -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 */

View File

@ -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;
}

View File

@ -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*);

View File

@ -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();

View File

@ -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

View File

@ -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;
}

View File

@ -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"),

View File

@ -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 );

View File

@ -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);

View File

@ -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

View File

@ -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) -

View File

@ -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();

View File

@ -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;

View File

@ -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));

View File

@ -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;

View File

@ -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)+

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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"),

View File

@ -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 );

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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] =

View File

@ -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;

View File

@ -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)+

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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."),

View File

@ -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
*/

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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