Browse Source

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


			
			
				pre-master-46
			
			
		
pnenzi 26 years ago
parent
commit
0875108157
  1. 72
      src/frontend/device.c
  2. 4
      src/frontend/device.h
  3. 30
      src/frontend/dotcards.c
  4. 441
      src/frontend/outitf.c
  5. 19
      src/frontend/runcoms.c
  6. 10
      src/frontend/spiceif.c
  7. 9
      src/frontend/subckt.c
  8. 9
      src/include/cktdefs.h
  9. 2
      src/include/cpextern.h
  10. 2
      src/include/devdefs.h
  11. 25
      src/include/distodef.h
  12. 29
      src/include/fteext.h
  13. 3
      src/include/hlpdefs.h
  14. 2
      src/include/inpdefs.h
  15. 12
      src/include/optdefs.h
  16. 1
      src/include/sensgen.h
  17. 2
      src/include/smpdefs.h
  18. 8
      src/include/tskdefs.h
  19. 3
      src/misc/dup2.c
  20. 8
      src/spicelib/analysis/cktdojob.c
  21. 18
      src/spicelib/analysis/cktload.c
  22. 10
      src/spicelib/analysis/cktntask.c
  23. 296
      src/spicelib/analysis/cktop.c
  24. 5
      src/spicelib/analysis/cktsens.c
  25. 35
      src/spicelib/analysis/cktsopt.c
  26. 2
      src/spicelib/analysis/ckttyplk.c
  27. 44
      src/spicelib/analysis/dcop.c
  28. 65
      src/spicelib/analysis/dctran.c
  29. 5
      src/spicelib/analysis/traninit.c
  30. 3
      src/spicelib/devices/bjt/bjtdisto.c
  31. 4
      src/spicelib/devices/bjt/bjtext.h
  32. 71
      src/spicelib/devices/bjt/bjtload.c
  33. 41
      src/spicelib/devices/bjt/bjtsetup.c
  34. 4
      src/spicelib/devices/bjt/bjttemp.c
  35. 3
      src/spicelib/devices/bsim1/b1disto.c
  36. 19
      src/spicelib/devices/bsim1/b1set.c
  37. 2
      src/spicelib/devices/bsim1/bsim1ext.h
  38. 16
      src/spicelib/devices/bsim2/b2set.c
  39. 2
      src/spicelib/devices/bsim3/b3.c
  40. 132
      src/spicelib/devices/bsim3/b3acld.c
  41. 68
      src/spicelib/devices/bsim3/b3ask.c
  42. 125
      src/spicelib/devices/bsim3/b3ld.c
  43. 5
      src/spicelib/devices/bsim3/b3par.c
  44. 27
      src/spicelib/devices/bsim3/b3set.c
  45. 5
      src/spicelib/devices/bsim3/bsim3def.h
  46. 6
      src/spicelib/devices/cap/capask.c
  47. 8
      src/spicelib/devices/cktinit.c
  48. 3
      src/spicelib/devices/csw/Makefile.am
  49. 3
      src/spicelib/devices/csw/cswdefs.h
  50. 5
      src/spicelib/devices/csw/cswext.h
  51. 4
      src/spicelib/devices/csw/cswinit.c
  52. 8
      src/spicelib/devices/csw/cswload.c
  53. 25
      src/spicelib/devices/devsup.c
  54. 4
      src/spicelib/devices/dio/dioext.h
  55. 13
      src/spicelib/devices/dio/dioload.c
  56. 13
      src/spicelib/devices/dio/diosetup.c
  57. 10
      src/spicelib/devices/dio/diotemp.c
  58. 2
      src/spicelib/devices/isrc/isrcload.c
  59. 12
      src/spicelib/devices/isrc/isrcpar.c
  60. 3
      src/spicelib/devices/jfet/jfetext.h
  61. 31
      src/spicelib/devices/jfet/jfetload.c
  62. 24
      src/spicelib/devices/jfet/jfetset.c
  63. 3
      src/spicelib/devices/ltra/ltraext.h
  64. 3
      src/spicelib/devices/mes/mesext.h
  65. 20
      src/spicelib/devices/mes/mesload.c
  66. 24
      src/spicelib/devices/mes/messetup.c
  67. 2
      src/spicelib/devices/mos1/mos1.c
  68. 9
      src/spicelib/devices/mos1/mos1acld.c
  69. 29
      src/spicelib/devices/mos1/mos1ask.c
  70. 6
      src/spicelib/devices/mos1/mos1defs.h
  71. 22
      src/spicelib/devices/mos1/mos1dset.c
  72. 2
      src/spicelib/devices/mos1/mos1ext.h
  73. 59
      src/spicelib/devices/mos1/mos1load.c
  74. 2
      src/spicelib/devices/mos1/mos1noi.c
  75. 5
      src/spicelib/devices/mos1/mos1par.c
  76. 9
      src/spicelib/devices/mos1/mos1pzld.c
  77. 24
      src/spicelib/devices/mos1/mos1set.c
  78. 6
      src/spicelib/devices/mos1/mos1sprt.c
  79. 40
      src/spicelib/devices/mos1/mos1temp.c
  80. 2
      src/spicelib/devices/mos2/mos2.c
  81. 7
      src/spicelib/devices/mos2/mos2acld.c
  82. 29
      src/spicelib/devices/mos2/mos2ask.c
  83. 6
      src/spicelib/devices/mos2/mos2defs.h
  84. 25
      src/spicelib/devices/mos2/mos2dset.c
  85. 4
      src/spicelib/devices/mos2/mos2ext.h
  86. 66
      src/spicelib/devices/mos2/mos2load.c
  87. 4
      src/spicelib/devices/mos2/mos2noi.c
  88. 5
      src/spicelib/devices/mos2/mos2par.c
  89. 9
      src/spicelib/devices/mos2/mos2pzld.c
  90. 26
      src/spicelib/devices/mos2/mos2set.c
  91. 5
      src/spicelib/devices/mos2/mos2sprt.c
  92. 40
      src/spicelib/devices/mos2/mos2temp.c
  93. 7
      src/spicelib/devices/mos3/mos3.c
  94. 14
      src/spicelib/devices/mos3/mos3acld.c
  95. 32
      src/spicelib/devices/mos3/mos3ask.c
  96. 17
      src/spicelib/devices/mos3/mos3defs.h
  97. 39
      src/spicelib/devices/mos3/mos3dset.c
  98. 2
      src/spicelib/devices/mos3/mos3ext.h
  99. 119
      src/spicelib/devices/mos3/mos3load.c
  100. 19
      src/spicelib/devices/mos3/mos3mask.c

72
src/frontend/device.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group 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)) if (!cp_getvar("width", VT_NUM, (char *) &screen_width))
screen_width = DEF_WIDTH; screen_width = DEF_WIDTH;
count = screen_width / 11 - 1;
count = (screen_width - LEFT_WIDTH) / (DEV_WIDTH + 1);
n = 0; n = 0;
do { do {
@ -168,7 +169,7 @@ all_show(wordlist *wl, int mode)
i = 0; i = 0;
do { do {
printf(" device ");
printf("%*s", LEFT_WIDTH, "device");
j = dgen_for_n(dg, count, printstr, "n", i); j = dgen_for_n(dg, count, printstr, "n", i);
i += 1; i += 1;
printf("\n"); printf("\n");
@ -177,7 +178,7 @@ all_show(wordlist *wl, int mode)
if (ft_sim->devices[dg->dev_type_no]->numModelParms) { if (ft_sim->devices[dg->dev_type_no]->numModelParms) {
i = 0; i = 0;
do { do {
printf(" model ");
printf("%*s", LEFT_WIDTH, "model");
j = dgen_for_n(dg, count, printstr, "m", i); j = dgen_for_n(dg, count, printstr, "m", i);
i += 1; i += 1;
printf("\n"); printf("\n");
@ -200,7 +201,7 @@ all_show(wordlist *wl, int mode)
n += 1; n += 1;
i = 0; i = 0;
do { do {
printf(" model ");
printf("%*s", LEFT_WIDTH, "model");
j = dgen_for_n(dg, count, printstr, "m", i); j = dgen_for_n(dg, count, printstr, "m", i);
i += 1; i += 1;
printf("\n"); printf("\n");
@ -236,16 +237,16 @@ printstr(dgen *dg, char *name)
{ {
if (*name == 'n') { if (*name == 'n') {
if (dg->instance) if (dg->instance)
printf(" %9.9s", dg->instance->GENname);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname);
else else
printf(" <???????>");
printf(" %*s", DEV_WIDTH, "<???????>");
} else if (*name == 'm') { } else if (*name == 'm') {
if (dg->model) if (dg->model)
printf(" %9.9s", dg->model->GENmodName);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName);
else else
printf(" <???????>");
printf(" %*s", DEV_WIDTH, "<???????>");
} else } else
printf(" <error> ");
printf(" %*s", DEV_WIDTH, "<error>");
return 0; return 0;
} }
@ -278,9 +279,10 @@ param_forall(dgen *dg, int flags)
j = 0; j = 0;
do { do {
if (!j) if (!j)
printf("%10.10s", plist[i].keyword);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH,
plist[i].keyword);
else else
printf(" ");
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, printvals, k = dgen_for_n(dg, count, printvals,
(char *) (plist + i), j); (char *) (plist + i), j);
printf("\n"); printf("\n");
@ -323,9 +325,9 @@ listparam(wordlist *p, dgen *dg)
j = 0; j = 0;
do { do {
if (!j) if (!j)
printf("%10.10s", p->wl_word);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
else else
printf(" ");
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, printvals, plist + i, j); k = dgen_for_n(dg, count, printvals, plist + i, j);
printf("\n"); printf("\n");
j += 1; j += 1;
@ -334,9 +336,9 @@ listparam(wordlist *p, dgen *dg)
j = 0; j = 0;
do { do {
if (!j) if (!j)
printf("%10.10s", p->wl_word);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
else else
printf(" ");
printf("%*s", LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, bogus1, 0, j); k = dgen_for_n(dg, count, bogus1, 0, j);
printf("\n"); printf("\n");
j += 1; j += 1;
@ -346,9 +348,9 @@ listparam(wordlist *p, dgen *dg)
j = 0; j = 0;
do { do {
if (!j) if (!j)
printf("%10.10s", p->wl_word);
printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word);
else else
printf(" ");
printf("%*s", LEFT_WIDTH, " ");
k = dgen_for_n(dg, count, bogus2, 0, j); k = dgen_for_n(dg, count, bogus2, 0, j);
printf("\n"); printf("\n");
j += 1; j += 1;
@ -358,13 +360,13 @@ listparam(wordlist *p, dgen *dg)
int bogus1(dgen *dg) int bogus1(dgen *dg)
{ {
printf(" ---------");
printf(" %*s", DEV_WIDTH, "---------");
return 0; return 0;
} }
int bogus2(dgen *dg) int bogus2(dgen *dg)
{ {
printf(" ?????????");
printf(" %*s", DEV_WIDTH, "?????????");
return 0; return 0;
} }
@ -400,54 +402,54 @@ printvals(dgen *dg, IFparm *p, int i)
if (p->dataType & IF_VECTOR) { if (p->dataType & IF_VECTOR) {
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) { switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
case IF_FLAG: case IF_FLAG:
printf(" % 9d", val.v.vec.iVec[i]);
printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]);
break; break;
case IF_INTEGER: case IF_INTEGER:
printf(" % 9d", val.v.vec.iVec[i]);
printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]);
break; break;
case IF_REAL: case IF_REAL:
printf(" % 9.3g", val.v.vec.rVec[i]);
printf(" % *.6g", DEV_WIDTH, val.v.vec.rVec[i]);
break; break;
case IF_COMPLEX: case IF_COMPLEX:
if (!(i % 2)) 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 else
printf(" % 9.3g", val.v.vec.cVec[i / 2].imag);
printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].imag);
break; break;
case IF_STRING: case IF_STRING:
printf(" %9.9s", val.v.vec.sVec[i]);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]);
break; break;
case IF_INSTANCE: case IF_INSTANCE:
printf(" %9.9s", val.v.vec.uVec[i]);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]);
break; break;
default: default:
printf(" ******** ");
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
} }
} else { } else {
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) { switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
case IF_FLAG: case IF_FLAG:
printf(" % 9d", val.iValue);
printf(" % *d", DEV_WIDTH, val.iValue);
break; break;
case IF_INTEGER: case IF_INTEGER:
printf(" % 9d", val.iValue);
printf(" % *d", DEV_WIDTH, val.iValue);
break; break;
case IF_REAL: case IF_REAL:
printf(" % 9.3g", val.rValue);
printf(" % *.6g", DEV_WIDTH, val.rValue);
break; break;
case IF_COMPLEX: case IF_COMPLEX:
if (i % 2) if (i % 2)
printf(" % 9.3g", val.cValue.real);
printf(" % *.6g", DEV_WIDTH, val.cValue.real);
else else
printf(" % 9.3g", val.cValue.imag);
printf(" % *.6g", DEV_WIDTH, val.cValue.imag);
break; break;
case IF_STRING: case IF_STRING:
printf(" %9.9s", val.sValue);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.sValue);
break; break;
case IF_INSTANCE: case IF_INSTANCE:
printf(" %9.9s ", val.uValue);
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.uValue);
break; break;
default: default:
printf(" ******** ");
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
} }
} }

4
src/frontend/device.h

@ -1,11 +1,15 @@
/************* /*************
* Header file for device.c * Header file for device.c
* 1999 E. Rouat * 1999 E. Rouat
* Modified: 2000 AlansFixes
************/ ************/
#ifndef DEVICE_H_INCLUDED #ifndef DEVICE_H_INCLUDED
#define DEVICE_H_INCLUDED #define DEVICE_H_INCLUDED
#define LEFT_WIDTH 11
#define DEV_WIDTH 21
void com_showmod(wordlist *wl); void com_showmod(wordlist *wl);
void com_show(wordlist *wl); void com_show(wordlist *wl);
int printstr(dgen *dg, char *name); int printstr(dgen *dg, char *name);

30
src/frontend/dotcards.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/ **********/
/* /*
@ -154,19 +155,14 @@ ft_cktcoms(bool terse)
if (!ft_curckt) if (!ft_curckt)
return 1; return 1;
if (!ft_curckt->ci_commands)
if (!ft_curckt->ci_commands && !setcplot("op"))
goto nocmds; goto nocmds;
coms = ft_curckt->ci_commands; coms = ft_curckt->ci_commands;
cp_interactive = FALSE; cp_interactive = FALSE;
/* Circuit name */
fprintf(cp_out, "Circuit: %s\nDate: %s\n\n", ft_curckt->ci_name,
datestring());
fprintf(cp_out, "\n");
/* Listing */ /* Listing */
if (ft_listprint) { if (ft_listprint) {
if (terse)
if (FALSE)
fprintf(cp_err, ".options: no listing, rawfile was generated.\n"); fprintf(cp_err, ".options: no listing, rawfile was generated.\n");
else else
inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options, 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 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"); fprintf(cp_out, "OP information in rawfile.\n");
} else { } 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"); fprintf(cp_out, "\t----\t-------\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next) { for (v = plot_cur->pl_dvecs; v; v = v->v_next) {
if (!isreal(v)) { if (!isreal(v)) {
@ -188,17 +184,17 @@ ft_cktcoms(bool terse)
v->v_name); v->v_name);
continue; 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])); printnum(v->v_realdata[0]));
} }
fprintf(cp_out, "\n\tSource\tCurrent\n"); fprintf(cp_out, "\n\tSource\tCurrent\n");
fprintf(cp_out, "\t------\t-------\n\n"); fprintf(cp_out, "\t------\t-------\n\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next) for (v = plot_cur->pl_dvecs; v; v = v->v_next)
if (v->v_type == SV_CURRENT) 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) if (!ft_nomod)
com_showmod(&all); com_showmod(&all);
@ -320,7 +316,7 @@ nocmds:
/* The options */ /* The options */
if (ft_optsprint) { if (ft_optsprint) {
fprintf(cp_err, "Options:\n\n");
fprintf(cp_out, "Options:\n\n");
cp_vprint(); cp_vprint();
(void) putc('\n', cp_out); (void) putc('\n', cp_out);
} }

441
src/frontend/outitf.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/ **********/
/* /*
@ -20,10 +21,12 @@ Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ifsim.h" #include "ifsim.h"
#include "jobdefs.h" #include "jobdefs.h"
#include "iferrmsg.h" #include "iferrmsg.h"
#include "circuits.h" #include "circuits.h"
#include "outitf.h" #include "outitf.h"
#include "variable.h" #include "variable.h"
#include <fcntl.h>
#include <time.h>
#include "cktdefs.h"
extern void gr_end_iplot(void); extern void gr_end_iplot(void);
@ -56,11 +59,14 @@ static void freeRun(runDesc *run);
#define DOUBLE_PRECISION 15 #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 shouldstop = FALSE; /* Tell simulator to stop next time it asks. */
static bool printinfo = FALSE; /* Print informational "error messages". */ static bool printinfo = FALSE; /* Print informational "error messages". */
/* The two "begin plot" routines share all their internals... */ /* The two "begin plot" routines share all their internals... */
@ -110,7 +116,9 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
int numsaves; int numsaves;
int i, j, depind; int i, j, depind;
char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP]; char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP];
bool saveall = TRUE;
char *ch, tmpname[BSIZE_SP];
bool saveall = TRUE;
bool savealli = FALSE;
char *an_name; char *an_name;
/* Check to see if we want to print informational data. */ /* Check to see if we want to print informational data. */
@ -144,12 +152,18 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
savesused[i] = TRUE; savesused[i] = TRUE;
continue; continue;
} }
if (cieq(saves[i].name, "all")) {
if (cieq(saves[i].name, "all") || cieq(saves[i].name, "allv")) {
saveall = TRUE; saveall = TRUE;
savesused[i] = TRUE; savesused[i] = TRUE;
saves[i].used = 1; saves[i].used = 1;
continue; continue;
} }
if (cieq(saves[i].name, "alli")) {
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 { } else {
for (i = 0; i < numNames; i++) for (i = 0; i < numNames; i++)
if (!refName || !name_eq(dataNames[i], refName)) { if (!refName || !name_eq(dataNames[i], refName)) {
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. */ /* Pass 2. */
for (i = 0; i < numsaves; i++) { for (i = 0; i < numsaves; i++) {
if (savesused[i]) if (savesused[i])
@ -265,7 +342,9 @@ addDataDesc(runDesc *run, char *name, int type, int ind)
dataDesc *data; dataDesc *data;
if (!run->numData) if (!run->numData)
run->data = (dataDesc *) tmalloc(sizeof (dataDesc));
{run->data = (dataDesc *) tmalloc(32768);
run->data = (dataDesc *) trealloc(run->data, sizeof (dataDesc));
}
else else
run->data = (dataDesc *) trealloc((char *) run->data, run->data = (dataDesc *) trealloc((char *) run->data,
sizeof (dataDesc) * (run->numData + 1)); 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 */ char *unique; /* unique char * from back-end */
if (!run->numData) if (!run->numData)
run->data = (dataDesc *) tmalloc(sizeof (dataDesc));
{run->data = (dataDesc *) tmalloc(32768);
run->data = (dataDesc *) trealloc(run->data, sizeof (dataDesc));}
else else
run->data = (dataDesc *) trealloc((char *) run->data, run->data = (dataDesc *) trealloc((char *) run->data,
sizeof (dataDesc) * (run->numData + 1)); sizeof (dataDesc) * (run->numData + 1));
@ -344,12 +424,23 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
fileStartPoint(run->fp, run->binary, run->pointCount); fileStartPoint(run->fp, run->binary, run->pointCount);
if (run->refIndex != -1) { if (run->refIndex != -1) {
if (run->isComplex)
if (run->isComplex){
fileAddComplexValue(run->fp, run->binary, refValue->cValue); fileAddComplexValue(run->fp, run->binary, refValue->cValue);
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); 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++) { for (i = 0; i < run->numData; i++) {
/* we've already printed reference vec first */ /* we've already printed reference vec first */
if (run->data[i].outIndex == -1) continue; if (run->data[i].outIndex == -1) continue;
@ -368,7 +459,22 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
} else { } else {
/* should pre-check instance */ /* should pre-check instance */
if (!getSpecial(&run->data[i], run, &val)) if (!getSpecial(&run->data[i], run, &val))
{
if (run->pointCount==1)
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; continue;
};
if (run->data[i].type == IF_REAL) if (run->data[i].type == IF_REAL)
fileAddRealValue(run->fp, run->binary, fileAddRealValue(run->fp, run->binary,
val.rValue); val.rValue);
@ -380,6 +486,10 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
} }
} }
fileEndPoint(run->fp, run->binary); fileEndPoint(run->fp, run->binary);
if (ferror(run->fp)) {
fprintf(stderr, "Warning: rawfile write error !!\n");
shouldstop=true;
};
} else { } else {
for (i = 0; i < run->numData; i++) { for (i = 0; i < run->numData; i++) {
if (run->data[i].outIndex == -1) { if (run->data[i].outIndex == -1) {
@ -529,7 +639,12 @@ static void
fileInit(runDesc *run) fileInit(runDesc *run)
{ {
char buf[513]; char buf[513];
int i;
int i, tmp, sweep;
float ftmp;
time_t time_of_day;
CKTcircuit *ckt;
lastclock = clock();
/* This is a hack. */ /* This is a hack. */
run->isComplex = FALSE; run->isComplex = FALSE;
@ -538,34 +653,163 @@ fileInit(runDesc *run)
run->isComplex = TRUE; run->isComplex = TRUE;
i = 0; 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); sprintf(buf, "Title: %s\n", run->name);
i += strlen(buf); i += strlen(buf);
fputs(buf, run->fp); fputs(buf, run->fp);
sprintf(buf, "Date: %s\n", datestring());
i += strlen(buf);
fputs(buf, run->fp);
sprintf(buf, "Plotname: %s\n", run->type);
i += strlen(buf);
fputs(buf, run->fp);
sprintf(buf, "Flags: %s\n", run->isComplex ? "complex" : "real");
/* 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); i += strlen(buf);
fputs(buf, run->fp); fputs(buf, run->fp);
sprintf(buf, "No. Variables: %d\n", run->numData);
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); i += strlen(buf);
fputs(buf, run->fp); 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); i += strlen(buf);
fputs(buf, run->fp); 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. */ fflush(run->fp); /* Gotta do this for LATTICE. */
if (run->fp == stdout || (run->pointPos = ftell(run->fp)) <= 0) if (run->fp == stdout || (run->pointPos = ftell(run->fp)) <= 0)
run->pointPos = i; 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);
/* 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 */
fprintf(run->fp, "Command: version %s\n", ft_sim->version);
fprintf(run->fp, "Variables:\n");
tmp = 0;
fwrite((char *)&tmp,2,1,run->fp);
i += 2;
fflush(run->fp); /* Make sure this gets to disk */
return; return;
} }
static void static void
@ -573,34 +817,88 @@ fileInit_pass2(runDesc *run)
{ {
int i, type; int i, type;
char *name, buf[BSIZE_SP]; char *name, buf[BSIZE_SP];
char *ch, *end;
for (i = 0; i < run->numData; i++) { 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; type = SV_CURRENT;
}
else if (cieq(name, "time")) else if (cieq(name, "time"))
type = SV_TIME; type = SV_TIME;
else if (cieq(name, "frequency")) else if (cieq(name, "frequency"))
type = SV_FREQUENCY; type = SV_FREQUENCY;
else else
type = SV_VOLTAGE; type = SV_VOLTAGE;
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");
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);
};
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; return;
} }
static void static void
@ -608,6 +906,11 @@ fileStartPoint(FILE *fp, bool bin, int num)
{ {
if (!bin) if (!bin)
fprintf(fp, "%d\t", num - 1); fprintf(fp, "%d\t", num - 1);
/* reset set buffer pointer to zero */
column = 0;
return; return;
} }
@ -615,23 +918,53 @@ fileStartPoint(FILE *fp, bool bin, int num)
static void static void
fileAddRealValue(FILE *fp, bool bin, double value) 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 static void
fileAddComplexValue(FILE *fp, bool bin, IFcomplex value) 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); DOUBLE_PRECISION, value.imag);
} }
@ -641,6 +974,8 @@ fileAddComplexValue(FILE *fp, bool bin, IFcomplex value)
static void static void
fileEndPoint(FILE *fp, bool bin) fileEndPoint(FILE *fp, bool bin)
{ {
/* write row buffer to file */
fwrite((char *)rowbuf, rowbuflen, 1, fp);
return; return;
} }
@ -650,11 +985,15 @@ static void
fileEnd(runDesc *run) fileEnd(runDesc *run)
{ {
long place; long place;
int nrows;
if (run->fp != stdout) { if (run->fp != stdout) {
place = ftell(run->fp); place = ftell(run->fp);
fseek(run->fp, run->pointPos, 0); 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); fseek(run->fp, place, 0);
} else { } else {
/* Yet another hack-around */ /* Yet another hack-around */
@ -662,6 +1001,10 @@ fileEnd(runDesc *run)
} }
fflush(run->fp); fflush(run->fp);
/* deallocate row buffer */
tfree(rowbuf);
return; return;
} }

19
src/frontend/runcoms.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
Modified: 2000 AlansFixes
**********/ **********/
/* /*
@ -34,6 +35,8 @@ extern struct dbcomm *dbs;
FILE *rawfileFp; FILE *rawfileFp;
bool rawfileBinary; bool rawfileBinary;
#define RAWBUF_SIZE 32768
char rawfileBuf[RAWBUF_SIZE];
void void
com_scirc(wordlist *wl) com_scirc(wordlist *wl)
@ -212,6 +215,7 @@ dosim(char *what, wordlist *wl)
if (!*wl->wl_word) if (!*wl->wl_word)
rawfileFp = stdout; rawfileFp = stdout;
else if (!(rawfileFp = fopen(wl->wl_word, "w"))) { else if (!(rawfileFp = fopen(wl->wl_word, "w"))) {
setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE);
perror(wl->wl_word); perror(wl->wl_word);
ft_setflag = FALSE; ft_setflag = FALSE;
return 1; return 1;
@ -249,7 +253,12 @@ dosim(char *what, wordlist *wl)
ft_curckt->ci_inprogress = FALSE; ft_curckt->ci_inprogress = FALSE;
} }
if (rawfileFp) 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_curckt->ci_runonce = TRUE;
ft_setflag = FALSE; ft_setflag = FALSE;
return err; return err;
@ -284,6 +293,14 @@ bool
ft_getOutReq(FILE **fpp, struct plot **plotp, bool *binp, char *name, char *title) ft_getOutReq(FILE **fpp, struct plot **plotp, bool *binp, char *name, char *title)
{ {
/*struct plot *pl;*/ /*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) { if (rawfileFp) {
*fpp = rawfileFp; *fpp = rawfileFp;

10
src/frontend/spiceif.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group 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, INPpas2((void *) ckt, (card *) deck->li_next,
(INPtables *) *tab,ft_curckt->ci_defTask); (INPtables *) *tab,ft_curckt->ci_defTask);
INPkillMods(); 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); return (ckt);
} }

9
src/frontend/subckt.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group 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); 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); return (ll);
} }

9
src/include/cktdefs.h

@ -1,6 +1,7 @@
/* /*
* Copyright (c) 1985 Thomas L. Quarles * Copyright (c) 1985 Thomas L. Quarles
* Modified 1999 Paolo Nenzi - Removed non STDC definitions * Modified 1999 Paolo Nenzi - Removed non STDC definitions
* Modified 2000 AlansFixes
*/ */
#ifndef CKT #ifndef CKT
#define CKT "CKTdefs.h $Revision$ on $Date$ " #define CKT "CKTdefs.h $Revision$ on $Date$ "
@ -173,6 +174,7 @@ typedef struct {
double CKTlteAbstol; double CKTlteAbstol;
#endif /* NEWTRUNC */ #endif /* NEWTRUNC */
double CKTgmin; /* Parallel Conductance --- */ double CKTgmin; /* Parallel Conductance --- */
double CKTgshunt;
double CKTdelmin; /* ??? */ double CKTdelmin; /* ??? */
double CKTtrtol; /* ??? */ double CKTtrtol; /* ??? */
double CKTfinalTime; /* ??? */ double CKTfinalTime; /* ??? */
@ -184,7 +186,9 @@ typedef struct {
double CKTdiagGmin; /* ??? */ double CKTdiagGmin; /* ??? */
int CKTnumSrcSteps; /* ??? */ int CKTnumSrcSteps; /* ??? */
int CKTnumGminSteps; /* ??? */ int CKTnumGminSteps; /* ??? */
double CKTgminFactor;
int CKTnoncon; /* ??? */ int CKTnoncon; /* ??? */
double CKTdefaultMosM;
double CKTdefaultMosL; /* Default Channel Lenght of MOS devices */ double CKTdefaultMosL; /* Default Channel Lenght of MOS devices */
double CKTdefaultMosW; /* Default Channel Width of MOS devics */ double CKTdefaultMosW; /* Default Channel Width of MOS devics */
double CKTdefaultMosAD; /* Default Drain Area of MOS */ double CKTdefaultMosAD; /* Default Drain Area of MOS */
@ -211,6 +215,7 @@ typedef struct {
lines */ lines */
unsigned int CKTbadMos3:1; /* Use old, unfixed MOS3 equations */ unsigned int CKTbadMos3:1; /* Use old, unfixed MOS3 equations */
unsigned int CKTkeepOpInfo:1; /* flag for small signal analyses */ unsigned int CKTkeepOpInfo:1; /* flag for small signal analyses */
unsigned int CKTcopyNodesets:1; /* NodesetFIX */
int CKTtroubleNode; /* Non-convergent node number */ int CKTtroubleNode; /* Non-convergent node number */
GENinstance *CKTtroubleElt; /* Non-convergent device instance */ 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 CKTsetNodPm( void *, void *, int , IFvalue *, IFvalue *);
extern int CKTsetOpt( void *, void *, int , IFvalue *); extern int CKTsetOpt( void *, void *, int , IFvalue *);
extern int CKTsetup( CKTcircuit *); extern int CKTsetup( CKTcircuit *);
extern int CKTunsetup(CKTcircuit *ckt);
extern int CKTunsetup(CKTcircuit *);
extern int CKTtemp( CKTcircuit *); extern int CKTtemp( CKTcircuit *);
extern char *CKTtrouble(void *, char *); extern char *CKTtrouble(void *, char *);
extern void CKTterr( int , CKTcircuit *, double *); extern void CKTterr( int , CKTcircuit *, double *);
@ -333,6 +338,8 @@ extern int NIpzSym(PZtrial **, PZtrial *);
extern int NIpzSym2(PZtrial **, PZtrial *); extern int NIpzSym2(PZtrial **, PZtrial *);
extern int NIreinit( CKTcircuit *); extern int NIreinit( CKTcircuit *);
extern int NIsenReinit( CKTcircuit *); extern int NIsenReinit( CKTcircuit *);
extern int NIdIter (CKTcircuit *);
extern int NInzIter (CKTcircuit *, int, int );
extern IFfrontEnd *SPfrontEnd; extern IFfrontEnd *SPfrontEnd;
#endif /*CKT*/ #endif /*CKT*/

2
src/include/cpextern.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group 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(); extern void out_init();
#ifndef out_printf #ifndef out_printf
/* don't want to declare it if we have #define'ed it */ /* don't want to declare it if we have #define'ed it */
extern void out_printf(); extern void out_printf();
#endif #endif
extern void out_send(); extern void out_send();

2
src/include/devdefs.h

@ -86,7 +86,7 @@ typedef struct SPICEdev {
} SPICEdev; /* instance of structure for each possible type of device */ } 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 * IOPP( ) IO parameter which the principle value of a device (used
* for naming output variables in sensetivity) * for naming output variables in sensetivity)
* IOPA( ) IO parameter significant for time-varying (non-dc) analyses * IOPA( ) IO parameter significant for time-varying (non-dc) analyses

25
src/include/distodef.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury Author: 1988 Jaijeet S Roychowdhury
Modified: 2000 AlansFixes
**********/ **********/
#ifndef DISTODEF #ifndef DISTODEF
@ -198,18 +199,18 @@ extern double DFiF12(double, double, double, double,
extern double DFn2F12(DpassStr*); extern double DFn2F12(DpassStr*);
extern double DFi2F12(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 *);

29
src/include/fteext.h

@ -1,7 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group 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_delete();
extern void com_iplot(); extern void com_iplot();
extern void com_save(); extern void com_save();
extern void com_save2(wordlist *, char *); /* AlansFixes */
extern void com_step(); extern void com_step();
extern void com_stop(); extern void com_stop();
extern void com_sttus(); extern void com_sttus();
@ -56,6 +57,12 @@ extern void com_trce();
extern void ft_trquery(); extern void ft_trquery();
extern void dbfree( ); extern void dbfree( );
/* breakp2.c */
extern int ft_getSaves(struct save_info **); /* AlanFixes */
/* circuits.c */ /* circuits.c */
extern struct circ *ft_curckt; extern struct circ *ft_curckt;
@ -180,6 +187,10 @@ extern void fatal();
extern void fperror(); extern void fperror();
extern void ft_sperror(); extern void ft_sperror();
extern char ErrorMessage[]; extern char ErrorMessage[];
extern int internalerror(char *);
extern int externalerror(char *);
/* evaluate.c */ /* evaluate.c */
@ -309,6 +320,7 @@ extern void com_ghelp();
extern void com_help(); extern void com_help();
extern void com_quit(); extern void com_quit();
extern void com_version(); extern void com_version();
extern int hcomp();
extern void com_where(); extern void com_where();
/* numparse.c */ /* numparse.c */
@ -337,14 +349,14 @@ extern int cp_userset();
extern struct func ft_funcs[]; extern struct func ft_funcs[];
extern struct func func_not; extern struct func func_not;
extern struct func func_uminus; 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(); extern void free_pnode();
/* plotcurve.c */ /* 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 */ /* plotinterface.c */
@ -374,9 +386,8 @@ extern void com_setscale();
extern void com_transpose(); extern void com_transpose();
/* rawfile.c */ /* rawfile.c */
extern int raw_prec; 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(); extern struct plot *raw_read();
/* resource.c */ /* resource.c */
@ -402,6 +413,8 @@ extern void com_disto();
extern void com_noise(); extern void com_noise();
extern int ft_dorun(); extern int ft_dorun();
extern bool ft_getOutReq(FILE **, struct plot **, bool *, char *, char *);
/* spice.c & nutmeg.c */ /* spice.c & nutmeg.c */
extern bool ft_nutmeg; extern bool ft_nutmeg;

3
src/include/hlpdefs.h

@ -1,7 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group 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 topic *hlp_read(fplace *place);
extern void hlp_free(void); extern void hlp_free(void);
extern long findsubject(char *filename, char *subject); extern long findsubject(char *filename, char *subject);
extern bool hlp_approvedfile();
/* provide.c */ /* provide.c */

2
src/include/inpdefs.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#ifndef INP #ifndef INP
@ -103,6 +104,7 @@ int INPmakeMod(char*,int,card*);
char *INPmkTemp(char*); char *INPmkTemp(char*);
void INPpas1(void*,card*,INPtables*); void INPpas1(void*,card*,INPtables*);
void INPpas2(void*,card*,INPtables*,void *); void INPpas2(void*,card*,INPtables*,void *);
void INPpas3(void*,card*,INPtables*,void *);
int INPpName(char*,IFvalue*,void*,int,void*); int INPpName(char*,IFvalue*,void*,int,void*);
int INPtermInsert(void*,char**,INPtables*,void**); int INPtermInsert(void*,char**,INPtables*,void**);
int INPmkTerm(void*,char**,INPtables*,void**); int INPmkTerm(void*,char**,INPtables*,void**);

12
src/include/optdefs.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#ifndef OPT #ifndef OPT
@ -104,4 +105,15 @@ typedef struct {
#define OPT_TRANSYNC 59 #define OPT_TRANSYNC 59
#define OPT_ACSYNC 60 #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*/ #endif /*OPT*/

1
src/include/sensgen.h

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

2
src/include/smpdefs.h

@ -7,6 +7,7 @@ typedef struct MatrixElement *SMPelement;
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "complex.h" #include "complex.h"
@ -36,6 +37,7 @@ SMPelement * SMPfindElt( SMPmatrix *, int , int , int );
int SMPcZeroCol(SMPmatrix *eMatrix, int Col); int SMPcZeroCol(SMPmatrix *eMatrix, int Col);
int SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col); int SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col);
int SMPzeroRow(SMPmatrix *eMatrix, int Row); int SMPzeroRow(SMPmatrix *eMatrix, int Row);
void spConstMult(SMPmatrix*, double);
#ifdef PARALLEL_ARCH #ifdef PARALLEL_ARCH
void SMPcombine(SMPmatrix *Matrix, double RHS[], double Spare[]); void SMPcombine(SMPmatrix *Matrix, double RHS[], double Spare[]);
void SMPcCombine(SMPmatrix *Matrix, double RHS[], double Spare[], void SMPcCombine(SMPmatrix *Matrix, double RHS[], double Spare[],

8
src/include/tskdefs.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -45,8 +46,10 @@ typedef struct {
double TSKlteAbstol; double TSKlteAbstol;
#endif /* NEWTRUNC */ #endif /* NEWTRUNC */
double TSKgmin; double TSKgmin;
double TSKgshunt; /* shunt conductance (CKTdiagGmin) */
double TSKdelmin; double TSKdelmin;
double TSKtrtol; double TSKtrtol;
double TSKdefaultMosM;
double TSKdefaultMosL; double TSKdefaultMosL;
double TSKdefaultMosW; double TSKdefaultMosW;
double TSKdefaultMosAD; double TSKdefaultMosAD;
@ -56,6 +59,11 @@ typedef struct {
unsigned int TSKtryToCompact:1; /* flag for LTRA lines */ unsigned int TSKtryToCompact:1; /* flag for LTRA lines */
unsigned int TSKbadMos3:1; /* flag for MOS3 models */ unsigned int TSKbadMos3:1; /* flag for MOS3 models */
unsigned int TSKkeepOpInfo:1; /* flag for small signal analyses */ 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; }TSKtask;
#endif /*TSK*/ #endif /*TSK*/

3
src/misc/dup2.c

@ -1,3 +1,4 @@
/* Modified: 2000 AlansFixes */
#include <config.h> #include <config.h>
#include "ngspice.h" #include "ngspice.h"
#include "dup2.h" #include "dup2.h"
@ -16,5 +17,5 @@ dup2(int oldd, int newd)
return 0; return 0;
} }
#else #else
int Dummy_Symbol;
int Dummy_Symbol_2;
#endif #endif

8
src/spicelib/analysis/cktdojob.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -47,6 +48,7 @@ CKTdoJob(void *inCkt, int reset, void *inTask)
ckt->CKTtranMaxIter = task->TSKtranMaxIter; ckt->CKTtranMaxIter = task->TSKtranMaxIter;
ckt->CKTnumSrcSteps = task->TSKnumSrcSteps; ckt->CKTnumSrcSteps = task->TSKnumSrcSteps;
ckt->CKTnumGminSteps = task->TSKnumGminSteps; ckt->CKTnumGminSteps = task->TSKnumGminSteps;
ckt->CKTgminFactor = task->TSKgminFactor;
ckt->CKTminBreak = task->TSKminBreak; ckt->CKTminBreak = task->TSKminBreak;
ckt->CKTabstol = task->TSKabstol; ckt->CKTabstol = task->TSKabstol;
ckt->CKTpivotAbsTol = task->TSKpivotAbsTol; ckt->CKTpivotAbsTol = task->TSKpivotAbsTol;
@ -55,8 +57,10 @@ CKTdoJob(void *inCkt, int reset, void *inTask)
ckt->CKTchgtol = task->TSKchgtol; ckt->CKTchgtol = task->TSKchgtol;
ckt->CKTvoltTol = task->TSKvoltTol; ckt->CKTvoltTol = task->TSKvoltTol;
ckt->CKTgmin = task->TSKgmin; ckt->CKTgmin = task->TSKgmin;
ckt->CKTgshunt = task->TSKgshunt;
ckt->CKTdelmin = task->TSKdelmin; ckt->CKTdelmin = task->TSKdelmin;
ckt->CKTtrtol = task->TSKtrtol; ckt->CKTtrtol = task->TSKtrtol;
ckt->CKTdefaultMosM = task->TSKdefaultMosM;
ckt->CKTdefaultMosL = task->TSKdefaultMosL; ckt->CKTdefaultMosL = task->TSKdefaultMosL;
ckt->CKTdefaultMosW = task->TSKdefaultMosW; ckt->CKTdefaultMosW = task->TSKdefaultMosW;
ckt->CKTdefaultMosAD = task->TSKdefaultMosAD; ckt->CKTdefaultMosAD = task->TSKdefaultMosAD;
@ -66,6 +70,10 @@ CKTdoJob(void *inCkt, int reset, void *inTask)
ckt->CKTtryToCompact = task->TSKtryToCompact; ckt->CKTtryToCompact = task->TSKtryToCompact;
ckt->CKTbadMos3 = task->TSKbadMos3; ckt->CKTbadMos3 = task->TSKbadMos3;
ckt->CKTkeepOpInfo = task->TSKkeepOpInfo; ckt->CKTkeepOpInfo = task->TSKkeepOpInfo;
ckt->CKTcopyNodesets = task->TSKcopyNodesets;
ckt->CKTnodeDamping = task->TSKnodeDamping;
ckt->CKTabsDv = task->TSKabsDv;
ckt->CKTrelDv = task->TSKrelDv;
ckt->CKTtroubleNode = 0; ckt->CKTtroubleNode = 0;
ckt->CKTtroubleElt = NULL; ckt->CKTtroubleElt = NULL;
#ifdef NEWTRUNC #ifdef NEWTRUNC

18
src/spicelib/analysis/cktload.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFIxes
**********/ **********/
/* /*
*/ */
@ -76,10 +77,12 @@ CKTload(CKTcircuit *ckt)
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes, if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes,
node->number)) node->number))
{ {
*(ckt->CKTrhs+node->number) = 1.0e10 * node->nodeset;
*(ckt->CKTrhs+node->number) = 1.0e10 * node->nodeset *
ckt->CKTsrcFact;
*(node->ptr) = 1e10; *(node->ptr) = 1e10;
} else { } else {
*(ckt->CKTrhs+node->number) = node->nodeset;
*(ckt->CKTrhs+node->number) = node->nodeset *
ckt->CKTsrcFact;
*(node->ptr) = 1; *(node->ptr) = 1;
} }
/* DAG: Original CIDER fix. If above fix doesn't work, /* DAG: Original CIDER fix. If above fix doesn't work,
@ -98,10 +101,17 @@ CKTload(CKTcircuit *ckt)
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes, if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes,
node->number)) 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; *(node->ptr) += 1.0e10;
} else { } 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; *(node->ptr) = 1;
} }
/* DAG: Original CIDER fix. If above fix doesn't work, /* DAG: Original CIDER fix. If above fix doesn't work,

10
src/spicelib/analysis/cktntask.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -24,6 +25,7 @@ CKTnewTask(void *ckt, void **taskPtr, IFuid taskName)
tsk = *(TSKtask **)taskPtr; tsk = *(TSKtask **)taskPtr;
tsk->TSKname = taskName; tsk->TSKname = taskName;
tsk->TSKgmin = 1e-12; tsk->TSKgmin = 1e-12;
tsk->TSKgshunt = 0;
tsk->TSKabstol = 1e-12; tsk->TSKabstol = 1e-12;
tsk->TSKreltol = 1e-3; tsk->TSKreltol = 1e-3;
tsk->TSKchgtol = 1e-14; tsk->TSKchgtol = 1e-14;
@ -39,12 +41,16 @@ CKTnewTask(void *ckt, void **taskPtr, IFuid taskName)
tsk->TSKdcTrcvMaxIter = 50; tsk->TSKdcTrcvMaxIter = 50;
tsk->TSKintegrateMethod = TRAPEZOIDAL; tsk->TSKintegrateMethod = TRAPEZOIDAL;
tsk->TSKmaxOrder = 2; tsk->TSKmaxOrder = 2;
tsk->TSKnumSrcSteps = 1;
tsk->TSKnumGminSteps = 1;
tsk->TSKnumSrcSteps = 10; tsk->TSKnumSrcSteps = 10;
tsk->TSKnumGminSteps = 10; tsk->TSKnumGminSteps = 10;
tsk->TSKgminFactor = 10;
tsk->TSKpivotAbsTol = 1e-13; tsk->TSKpivotAbsTol = 1e-13;
tsk->TSKpivotRelTol = 1e-3; tsk->TSKpivotRelTol = 1e-3;
tsk->TSKtemp = 300.15; tsk->TSKtemp = 300.15;
tsk->TSKnomTemp = 300.15; tsk->TSKnomTemp = 300.15;
tsk->TSKdefaultMosM = 1;
tsk->TSKdefaultMosL = 1e-4; tsk->TSKdefaultMosL = 1e-4;
tsk->TSKdefaultMosW = 1e-4; tsk->TSKdefaultMosW = 1e-4;
tsk->TSKdefaultMosAD = 0; tsk->TSKdefaultMosAD = 0;
@ -53,5 +59,9 @@ CKTnewTask(void *ckt, void **taskPtr, IFuid taskName)
tsk->TSKtryToCompact=0; tsk->TSKtryToCompact=0;
tsk->TSKbadMos3=0; tsk->TSKbadMos3=0;
tsk->TSKkeepOpInfo=0; tsk->TSKkeepOpInfo=0;
tsk->TSKcopyNodesets=0;
tsk->TSKnodeDamping=0;
tsk->TSKabsDv=0.5;
tsk->TSKrelDv=2.0;
return(OK); return(OK);
} }

296
src/spicelib/analysis/cktop.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -15,7 +16,11 @@ CKTop(CKTcircuit *ckt, long int firstmode, long int continuemode, int iterlim)
{ {
int converged; int converged;
int i; int i;
CKTnode *n; /* AlansFixes */
double raise, ConvFact, NumNodes; /* AlansFixes */
double *OldRhsOld, *OldCKTstate0; /* AlansFixes */
int iters;
ckt->CKTmode = firstmode; ckt->CKTmode = firstmode;
if(!ckt->CKTnoOpIter) { if(!ckt->CKTnoOpIter) {
converged = NIiter(ckt,iterlim); 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 /* note that no path out of this code allows ckt->CKTdiagGmin to be
* anything but 0.000000000 * 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; ckt->CKTmode = firstmode;
(*(SPfrontEnd->IFerror))(ERR_INFO, (*(SPfrontEnd->IFerror))(ERR_INFO,
"starting Gmin stepping",(IFuid *)NULL); "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++) { for(i=0;i<ckt->CKTnumGminSteps;i++) {
ckt->CKTdiagGmin *= 10;
ckt->CKTdiagGmin *= ckt->CKTgminFactor;
} }
for(i=0;i<=ckt->CKTnumGminSteps;i++) { for(i=0;i<=ckt->CKTnumGminSteps;i++) {
fprintf(stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
ckt->CKTnoncon =1; ckt->CKTnoncon =1;
converged = NIiter(ckt,iterlim);
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
if(converged != 0) { if(converged != 0) {
ckt->CKTdiagGmin = 0;
ckt->CKTdiagGmin = ckt->CKTgshunt;
(*(SPfrontEnd->IFerror))(ERR_WARNING, (*(SPfrontEnd->IFerror))(ERR_WARNING,
"Gmin step failed",(IFuid *)NULL); "Gmin step failed",(IFuid *)NULL);
break; break;
} }
ckt->CKTdiagGmin /= 10;
ckt->CKTdiagGmin /= ckt->CKTgminFactor;
ckt->CKTmode=continuemode; ckt->CKTmode=continuemode;
(*(SPfrontEnd->IFerror))(ERR_INFO, (*(SPfrontEnd->IFerror))(ERR_INFO,
"One successful Gmin step",(IFuid *)NULL); "One successful Gmin step",(IFuid *)NULL);
} }
ckt->CKTdiagGmin = 0;
ckt->CKTdiagGmin = ckt->CKTgshunt;
converged = NIiter(ckt,iterlim); converged = NIiter(ckt,iterlim);
if(converged == 0) { if(converged == 0) {
(*(SPfrontEnd->IFerror))(ERR_INFO, (*(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 * note that no path out of this code allows ckt->CKTsrcFact to be
* anything but 1.000000000 * anything but 1.000000000
*/ */
if(ckt->CKTnumSrcSteps >1) {
if(ckt->CKTnumSrcSteps >=1) {
ckt->CKTmode = firstmode; ckt->CKTmode = firstmode;
(*(SPfrontEnd->IFerror))(ERR_INFO, (*(SPfrontEnd->IFerror))(ERR_INFO,
"starting source stepping",(IFuid *)NULL); "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) { 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, (*(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 { } else {
return(converged); return(converged);
} }

5
src/spicelib/analysis/cktsens.c

@ -1,5 +1,6 @@
/********** /**********
Copyright 1991 Regents of the University of California. All rights reserved. Copyright 1991 Regents of the University of California. All rights reserved.
Modified: 2000 AlanFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -549,7 +550,9 @@ int sens_sens(CKTcircuit *ckt, int restart)
nvalue.v.vec.cVec = output_cvalues; nvalue.v.vec.cVec = output_cvalues;
value.rValue = freq; value.rValue = freq;
OUTpData(sen_data, &value, &nvalue);
(*(SPfrontEnd->OUTpData))(sen_data, &value, &nvalue);
freq = inc_freq(freq, sen_info->step_type, step_size); freq = inc_freq(freq, sen_info->step_type, step_size);
} }

35
src/spicelib/analysis/cktsopt.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
@ -33,6 +34,9 @@ CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
case OPT_GMIN: case OPT_GMIN:
task->TSKgmin = val->rValue; task->TSKgmin = val->rValue;
break; break;
case OPT_GSHUNT:
task->TSKgshunt = val->rValue;
break;
case OPT_RELTOL: case OPT_RELTOL:
task->TSKreltol = val->rValue; task->TSKreltol = val->rValue;
break; break;
@ -79,6 +83,12 @@ CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
case OPT_GMINSTEPS: case OPT_GMINSTEPS:
task->TSKnumGminSteps = val->iValue; task->TSKnumGminSteps = val->iValue;
break; break;
case OPT_GMINFACT:
task->TSKgminFactor = val->rValue;
break;
case OPT_DEFM:
task->TSKdefaultMosM = val->rValue;
break;
case OPT_DEFL: case OPT_DEFL:
task->TSKdefaultMosL = val->rValue; task->TSKdefaultMosL = val->rValue;
break; break;
@ -119,6 +129,18 @@ CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
case OPT_KEEPOPINFO: case OPT_KEEPOPINFO:
task->TSKkeepOpInfo = val->iValue; task->TSKkeepOpInfo = val->iValue;
break; 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: default:
return(-1); return(-1);
} }
@ -127,6 +149,7 @@ CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
static IFparm OPTtbl[] = { static IFparm OPTtbl[] = {
{ "noopiter", OPT_NOOPITER,IF_SET|IF_FLAG,"Go directly to gmin stepping" }, { "noopiter", OPT_NOOPITER,IF_SET|IF_FLAG,"Go directly to gmin stepping" },
{ "gmin", OPT_GMIN,IF_SET|IF_REAL,"Minimum conductance" }, { "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"}, { "reltol", OPT_RELTOL,IF_SET|IF_REAL ,"Relative error tolerence"},
{ "abstol", OPT_ABSTOL,IF_SET|IF_REAL,"Absolute error tolerence" }, { "abstol", OPT_ABSTOL,IF_SET|IF_REAL,"Absolute error tolerence" },
{ "vntol", OPT_VNTOL,IF_SET|IF_REAL,"Voltage 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"}, { "itl6", OPT_SRCSTEPS, IF_SET|IF_INTEGER,"number of source steps"},
{ "srcsteps", 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"}, { "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"}, { "acct", 0, IF_FLAG ,"Print accounting"},
{ "list", 0, IF_FLAG, "Print a listing" }, { "list", 0, IF_FLAG, "Print a listing" },
{ "nomod", 0, IF_FLAG, "Don't print a model summary" }, { "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" }, { "lvltim", 0, IF_INTEGER,"Type of timestep control" },
{ "method", OPT_METHOD, IF_SET|IF_STRING,"Integration method" }, { "method", OPT_METHOD, IF_SET|IF_STRING,"Integration method" },
{ "maxord", OPT_MAXORD, IF_SET|IF_INTEGER,"Maximum integration order" }, { "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" }, { "defl", OPT_DEFL,IF_SET|IF_REAL,"Default MOSfet length" },
{ "defw", OPT_DEFW,IF_SET|IF_REAL,"Default MOSfet width" }, { "defw", OPT_DEFW,IF_SET|IF_REAL,"Default MOSfet width" },
{ "minbreak", OPT_MINBREAK,IF_SET|IF_REAL,"Minimum time between breakpoints" }, { "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, { "badmos3", OPT_BADMOS3, IF_SET|IF_FLAG,
"use old mos3 model (discontinuous with respect to kappa)" }, "use old mos3 model (discontinuous with respect to kappa)" },
{ "keepopinfo", OPT_KEEPOPINFO, IF_SET|IF_FLAG, { "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); int OPTcount = sizeof(OPTtbl)/sizeof(IFparm);

2
src/spicelib/analysis/ckttyplk.c

@ -4,7 +4,7 @@ Author: 1985 Thomas L. Quarles
**********/ **********/
/* look up the 'type' in the device description struct and return the /* 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" #include "ngspice.h"

44
src/spicelib/analysis/dcop.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -31,7 +32,42 @@ DCop(CKTcircuit *ckt)
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter); 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; ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
@ -57,7 +93,11 @@ DCop(CKTcircuit *ckt)
} }
#endif #endif
converged = CKTload(ckt); 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); (*(SPfrontEnd->OUTendPlot))(plot);
return(converged); return(converged);
} }

65
src/spicelib/analysis/dctran.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* subroutine to do DC TRANSIENT analysis /* subroutine to do DC TRANSIENT analysis
@ -44,12 +45,13 @@ DCtran(CKTcircuit *ckt,
double maxstepsize=0.0; double maxstepsize=0.0;
int ltra_num; int ltra_num;
CKTnode *node;
#ifdef PARALLEL_ARCH #ifdef PARALLEL_ARCH
long type = MT_TRANAN, length = 1; long type = MT_TRANAN, length = 1;
#endif /* PARALLEL_ARCH */ #endif /* PARALLEL_ARCH */
if(restart || ckt->CKTtime == 0) { 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 */ /* begin LTRA code addition */
if (ckt->CKTtimePoints != NULL) if (ckt->CKTtimePoints != NULL)
@ -96,6 +98,52 @@ DCtran(CKTcircuit *ckt,
(ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITJCT, (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITJCT,
(ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT, (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT,
ckt->CKTdcMaxIter); 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); if(converged != 0) return(converged);
ckt->CKTstat->STATtimePts ++; ckt->CKTstat->STATtimePts ++;
ckt->CKTorder=1; ckt->CKTorder=1;
@ -198,7 +246,8 @@ nextTime:
*/ */
#ifdef STEPDEBUG #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 */ #endif /* STEPDEBUG */
ckt->CKTstat->STATaccepted ++; ckt->CKTstat->STATaccepted ++;
ckt->CKTbreak=0; ckt->CKTbreak=0;
@ -317,7 +366,8 @@ resume:
ckt->CKTsaveDelta = ckt->CKTdelta; ckt->CKTsaveDelta = ckt->CKTdelta;
ckt->CKTdelta = *(ckt->CKTbreaks) - ckt->CKTtime; ckt->CKTdelta = *(ckt->CKTbreaks) - ckt->CKTtime;
#ifdef STEPDEBUG #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 #endif
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */ ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
} }
@ -363,7 +413,8 @@ resume:
ckt->CKTstat->STATrejected ++; ckt->CKTstat->STATrejected ++;
ckt->CKTdelta = ckt->CKTdelta/8; ckt->CKTdelta = ckt->CKTdelta/8;
#ifdef STEPDEBUG #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 #endif
if(firsttime) { if(firsttime) {
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN;
@ -437,8 +488,10 @@ resume:
/* time point OK - 630*/ /* time point OK - 630*/
ckt->CKTdelta = new; ckt->CKTdelta = new;
#ifdef STEPDEBUG #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 #endif
#ifdef WANT_SENSE2 #ifdef WANT_SENSE2
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){

5
src/spicelib/analysis/traninit.c

@ -1,5 +1,6 @@
/********** /**********
Copyright 1991 Regents of the University of California. All rights reserved. Copyright 1991 Regents of the University of California. All rights reserved.
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -39,12 +40,12 @@ int TRANinit(CKTcircuit *ckt, JOB *job)
#else #else
/* The original spice code */ /* The original spice code */
if(ckt->CKTmaxStep == 0) { if(ckt->CKTmaxStep == 0) {
ckt->CKTmaxStep = (ckt->CKTfinalTime-ckt->CKTinitTime)/50;
ckt->CKTmaxStep = (ckt->CKTfinalTime-ckt->CKTinitTime)/100;
} }
#endif #endif
ckt->CKTdelmin = 1e-9*ckt->CKTmaxStep; /* XXX */
ckt->CKTdelmin = 1e-11*ckt->CKTmaxStep; /* XXX */
ckt->CKTmode = ((TRANan*)job)->TRANmode; ckt->CKTmode = ((TRANan*)job)->TRANmode;
return OK; return OK;

3
src/spicelib/devices/bjt/bjtdisto.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury Author: 1988 Jaijeet S Roychowdhury
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -45,7 +46,7 @@ BJTdisto(int mode, GENmodel *genmodel, CKTcircuit *ckt)
#endif #endif
if (mode == D_SETUP) if (mode == D_SETUP)
return(BJTdSetup(model,ckt));
return(BJTdSetup((GENmodel *)model,ckt));
if ((mode == D_TWOF1) || (mode == D_THRF1) || if ((mode == D_TWOF1) || (mode == D_THRF1) ||
(mode == D_F1PF2) || (mode == D_F1MF2) || (mode == D_F1PF2) || (mode == D_F1MF2) ||

4
src/spicelib/devices/bjt/bjtext.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AnalsFixes
**********/ **********/
#ifdef __STDC__ #ifdef __STDC__
@ -27,6 +28,9 @@ extern int BJTtemp(GENmodel*,CKTcircuit*);
extern int BJTtrunc(GENmodel*,CKTcircuit*,double*); extern int BJTtrunc(GENmodel*,CKTcircuit*,double*);
extern int BJTdisto(int,GENmodel*,CKTcircuit*); extern int BJTdisto(int,GENmodel*,CKTcircuit*);
extern int BJTnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int BJTnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int BJTdSetup(GENmodel*, register CKTcircuit*);
#else /* stdc */ #else /* stdc */
extern int BJTacLoad(); extern int BJTacLoad();
extern int BJTask(); extern int BJTask();

71
src/spicelib/devices/bjt/bjtload.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
@ -369,43 +370,65 @@ BJTload(inModel,ckt)
* determine dc current and derivitives * determine dc current and derivitives
*/ */
next1: vtn=vt*model->BJTemissionCoeffF; next1: vtn=vt*model->BJTemissionCoeffF;
if(vbe > -5*vtn){
if(vbe >= -3*vtn){
evbe=exp(vbe/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); evben=exp(vbe/vte);
cben=c2*(evben-1); cben=c2*(evben-1);
gben=c2*evben/vte; gben=c2*evben/vte;
} else {
arg=3*vte/(vbe*CONSTe);
arg = arg * arg * arg;
cben = -c2*(1+arg);
gben = c2*3*arg/vbe;
} }
} else {
gbe = -csat/vbe+ckt->CKTgmin;
cbe=gbe*vbe;
gben = -c2/vbe;
cben=gben*vbe;
} }
gben+=ckt->CKTgmin;
cben+=ckt->CKTgmin*vbe;
vtn=vt*model->BJTemissionCoeffR; vtn=vt*model->BJTemissionCoeffR;
if(vbc > -5*vtn) {
if(vbc >= -3*vtn) {
evbc=exp(vbc/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 {
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); evbcn=exp(vbc/vtc);
cbcn=c4*(evbcn-1); cbcn=c4*(evbcn-1);
gbcn=c4*evbcn/vtc; 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 * determine base charge terms
*/ */

41
src/spicelib/devices/bjt/bjtsetup.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
@ -149,6 +150,9 @@ BJTsetup(matrix,inModel,ckt,states)
for (here = model->BJTinstances; here != NULL ; for (here = model->BJTinstances; here != NULL ;
here=here->BJTnextInstance) { here=here->BJTnextInstance) {
if (here->BJTowner != ARCHme) goto matrixpointers; if (here->BJTowner != ARCHme) goto matrixpointers;
CKTnode *tmpNode;
IFuid tmpName;
if(!here->BJTareaGiven) { if(!here->BJTareaGiven) {
here->BJTarea = 1; here->BJTarea = 1;
@ -166,6 +170,18 @@ matrixpointers:
error = CKTmkVolt(ckt,&tmp,here->BJTname,"collector"); error = CKTmkVolt(ckt,&tmp,here->BJTname,"collector");
if(error) return(error); if(error) return(error);
here->BJTcolPrimeNode = tmp->number; 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) { if(model->BJTbaseResist == 0) {
here->BJTbasePrimeNode = here->BJTbaseNode; here->BJTbasePrimeNode = here->BJTbaseNode;
@ -173,6 +189,18 @@ matrixpointers:
error = CKTmkVolt(ckt,&tmp,here->BJTname, "base"); error = CKTmkVolt(ckt,&tmp,here->BJTname, "base");
if(error) return(error); if(error) return(error);
here->BJTbasePrimeNode = tmp->number; 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) { if(model->BJTemitterResist == 0) {
here->BJTemitPrimeNode = here->BJTemitNode; here->BJTemitPrimeNode = here->BJTemitNode;
@ -180,6 +208,19 @@ matrixpointers:
error = CKTmkVolt(ckt,&tmp,here->BJTname, "emitter"); error = CKTmkVolt(ckt,&tmp,here->BJTname, "emitter");
if(error) return(error); if(error) return(error);
here->BJTemitPrimeNode = tmp->number; 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 */ /* macro to make elements with built in test for out of memory */

4
src/spicelib/devices/bjt/bjttemp.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -185,7 +186,8 @@ BJTtemp(inModel,ckt)
here->BJTtf5 = here->BJTtBCpot * (1 - exp((1 - here->BJTtf5 = here->BJTtBCpot * (1 - exp((1 -
model->BJTjunctionExpBC) * xfc)) / model->BJTjunctionExpBC) * xfc)) /
(1 - model->BJTjunctionExpBC); (1 - model->BJTjunctionExpBC);
here->BJTtVcrit = vt * log(vt / (CONSTroot2*model->BJTsatCur));
here->BJTtVcrit = vt *
log(vt / (CONSTroot2*here->BJTtSatCur*here->BJTarea));
} }
} }

3
src/spicelib/devices/bsim1/b1disto.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury Author: 1988 Jaijeet S Roychowdhury
Modified: AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -43,7 +44,7 @@ B1disto(mode,genmodel,ckt)
B1instance *here; B1instance *here;
if (mode == D_SETUP) if (mode == D_SETUP)
return(B1dSetup(model,ckt));
return(B1dSetup((GENmodel *)model,ckt));
if ((mode == D_TWOF1) || (mode == D_THRF1) || if ((mode == D_TWOF1) || (mode == D_THRF1) ||
(mode == D_F1PF2) || (mode == D_F1MF2) || (mode == D_F1PF2) || (mode == D_F1MF2) ||

19
src/spicelib/devices/bsim1/b1set.c

@ -271,6 +271,9 @@ B1setup(matrix,inModel,ckt,states)
for (here = model->B1instances; here != NULL ; for (here = model->B1instances; here != NULL ;
here=here->B1nextInstance) { here=here->B1nextInstance) {
CKTnode *tmpNode;
IFuid tmpName;
if (here->B1owner == ARCHme) { if (here->B1owner == ARCHme) {
/* allocate a chunk of the state vector */ /* allocate a chunk of the state vector */
here->B1states = *states; here->B1states = *states;
@ -325,6 +328,14 @@ B1setup(matrix,inModel,ckt,states)
error = CKTmkVolt(ckt,&tmp,here->B1name,"drain"); error = CKTmkVolt(ckt,&tmp,here->B1name,"drain");
if(error) return(error); if(error) return(error);
here->B1dNodePrime = tmp->number; 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 { } else {
here->B1dNodePrime = here->B1dNode; here->B1dNodePrime = here->B1dNode;
} }
@ -337,6 +348,14 @@ B1setup(matrix,inModel,ckt,states)
error = CKTmkVolt(ckt,&tmp,here->B1name,"source"); error = CKTmkVolt(ckt,&tmp,here->B1name,"source");
if(error) return(error); if(error) return(error);
here->B1sNodePrime = tmp->number; 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 { } else {
here->B1sNodePrime = here->B1sNode; here->B1sNodePrime = here->B1sNode;

2
src/spicelib/devices/bsim1/bsim1ext.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Hong June Park, Thomas L. Quarles Author: 1985 Hong June Park, Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#ifdef __STDC__ #ifdef __STDC__
@ -26,6 +27,7 @@ extern int B1unsetup(GENmodel*,CKTcircuit*);
extern int B1temp(GENmodel*,CKTcircuit*); extern int B1temp(GENmodel*,CKTcircuit*);
extern int B1trunc(GENmodel*,CKTcircuit*,double*); extern int B1trunc(GENmodel*,CKTcircuit*,double*);
extern int B1disto(int,GENmodel*,CKTcircuit*); extern int B1disto(int,GENmodel*,CKTcircuit*);
extern int B1dSetup(GENmodel*, register CKTcircuit*);
#else /* stdc */ #else /* stdc */
extern int B1acLoad(); extern int B1acLoad();
extern int B1ask(); extern int B1ask();

16
src/spicelib/devices/bsim2/b2set.c

@ -494,6 +494,14 @@ B2setup(matrix,inModel,ckt,states)
error = CKTmkVolt(ckt,&tmp,here->B2name,"drain"); error = CKTmkVolt(ckt,&tmp,here->B2name,"drain");
if(error) return(error); if(error) return(error);
here->B2dNodePrime = tmp->number; 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 { } else {
here->B2dNodePrime = here->B2dNode; here->B2dNodePrime = here->B2dNode;
} }
@ -506,6 +514,14 @@ B2setup(matrix,inModel,ckt,states)
error = CKTmkVolt(ckt,&tmp,here->B2name,"source"); error = CKTmkVolt(ckt,&tmp,here->B2name,"source");
if(error) return(error); if(error) return(error);
here->B2sNodePrime = tmp->number; 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 { } else {
here->B2sNodePrime = here->B2sNode; here->B2sNodePrime = here->B2sNode;

2
src/spicelib/devices/bsim3/b3.c

@ -2,6 +2,7 @@
Copyright 1999 Regents of the University of California. All rights reserved. Copyright 1999 Regents of the University of California. All rights reserved.
Author: 1995 Min-Chie Jeng and Mansun Chan. Author: 1995 Min-Chie Jeng and Mansun Chan.
Author: 1997-1999 Weidong Liu. Author: 1997-1999 Weidong Liu.
Modified: 2000 AlansFixes
File: b3.c File: b3.c
**********/ **********/
@ -14,6 +15,7 @@ File: b3.c
IFparm BSIM3pTable[] = { /* parameters */ IFparm BSIM3pTable[] = { /* parameters */
IOP( "l", BSIM3_L, IF_REAL , "Length"), IOP( "l", BSIM3_L, IF_REAL , "Length"),
IOP( "w", BSIM3_W, IF_REAL , "Width"), IOP( "w", BSIM3_W, IF_REAL , "Width"),
IOP( "m", BSIM3_M, IF_REAL , "Parallel multiplier"),
IOP( "ad", BSIM3_AD, IF_REAL , "Drain area"), IOP( "ad", BSIM3_AD, IF_REAL , "Drain area"),
IOP( "as", BSIM3_AS, IF_REAL , "Source area"), IOP( "as", BSIM3_AS, IF_REAL , "Source area"),
IOP( "pd", BSIM3_PD, IF_REAL , "Drain perimeter"), IOP( "pd", BSIM3_PD, IF_REAL , "Drain perimeter"),

132
src/spicelib/devices/bsim3/b3acld.c

@ -2,6 +2,7 @@
Copyright 1999 Regents of the University of California. All rights reserved. Copyright 1999 Regents of the University of California. All rights reserved.
Author: 1995 Min-Chie Jeng and Mansun Chan. Author: 1995 Min-Chie Jeng and Mansun Chan.
Author: 1997-1999 Weidong Liu. Author: 1997-1999 Weidong Liu.
Modified: 2000 AlansFixes
File: b3acld.c File: b3acld.c
**********/ **********/
@ -259,76 +260,79 @@ double ScalingFactor = 1.0e-9;
xcbdb = (cbdb - capbd ) * omega; xcbdb = (cbdb - capbd ) * omega;
xcbsb = (cbsb - capbs ) * omega; xcbsb = (cbsb - capbs ) * omega;
*(here->BSIM3GgPtr +1) += xcggb;
m = here->BSIM3m;
*(here->BSIM3GgPtr +1) += m * xcggb;
*(here->BSIM3BbPtr +1) -= xcbgb + xcbdb + xcbsb; *(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->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->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->BSIM3SPbPtr +1) -= xcsgb + xcsdb + xcssb;
*(here->BSIM3SPdpPtr +1) += 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->BSIM3DdpPtr) -= gdpr;
*(here->BSIM3SspPtr) -= gspr;
*(here->BSIM3BgPtr) -= here->BSIM3gbgs;
*(here->BSIM3BdpPtr) -= gbd - gbbdp;
*(here->BSIM3BspPtr) -= 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->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->BSIM3GgPtr) -= xgtg;
*(here->BSIM3GbPtr) -= xgtb;
*(here->BSIM3GdpPtr) -= xgtd;
*(here->BSIM3GspPtr) -= xgts;
*(here->BSIM3SPdpPtr +1) += m * xcsdb;
*(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) -= m * gdpr;
*(here->BSIM3SspPtr) -= m * gspr;
*(here->BSIM3BgPtr) -= m * here->BSIM3gbgs;
*(here->BSIM3BdpPtr) -= m * (gbd - gbbdp);
*(here->BSIM3BspPtr) -= m * (gbs - gbbsp);
*(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) -= 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) -= m * xgtg;
*(here->BSIM3GbPtr) -= m * xgtb;
*(here->BSIM3GdpPtr) -= m * xgtd;
*(here->BSIM3GspPtr) -= m * xgts;
if (here->BSIM3nqsMod) 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) += here->BSIM3gtau;
*(here->BSIM3DPqPtr) += dxpart * here->BSIM3gtau;
*(here->BSIM3SPqPtr) += sxpart * here->BSIM3gtau;
*(here->BSIM3GqPtr) -= here->BSIM3gtau;
*(here->BSIM3QgPtr) += xgtg;
*(here->BSIM3QdpPtr) += xgtd;
*(here->BSIM3QspPtr) += xgts;
*(here->BSIM3QbPtr) += xgtb;
{ *(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) += m * here->BSIM3gtau;
*(here->BSIM3DPqPtr) += m * (dxpart * here->BSIM3gtau);
*(here->BSIM3SPqPtr) += m * (sxpart * here->BSIM3gtau);
*(here->BSIM3GqPtr) -= m * here->BSIM3gtau;
*(here->BSIM3QgPtr) += m * xgtg;
*(here->BSIM3QdpPtr) += m * xgtd;
*(here->BSIM3QspPtr) += m * xgts;
*(here->BSIM3QbPtr) += m * xgtb;
} }
} }
} }

68
src/spicelib/devices/bsim3/b3ask.c

@ -32,6 +32,9 @@ BSIM3instance *here = (BSIM3instance*)inst;
case BSIM3_W: case BSIM3_W:
value->rValue = here->BSIM3w; value->rValue = here->BSIM3w;
return(OK); return(OK);
case BSIM3_M:
value->rValue = here->BSIM3m;
return(OK);
case BSIM3_AS: case BSIM3_AS:
value->rValue = here->BSIM3sourceArea; value->rValue = here->BSIM3sourceArea;
return(OK); return(OK);
@ -85,9 +88,11 @@ BSIM3instance *here = (BSIM3instance*)inst;
return(OK); return(OK);
case BSIM3_SOURCECONDUCT: case BSIM3_SOURCECONDUCT:
value->rValue = here->BSIM3sourceConductance; value->rValue = here->BSIM3sourceConductance;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_DRAINCONDUCT: case BSIM3_DRAINCONDUCT:
value->rValue = here->BSIM3drainConductance; value->rValue = here->BSIM3drainConductance;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_VBD: case BSIM3_VBD:
value->rValue = *(ckt->CKTstate0 + here->BSIM3vbd); value->rValue = *(ckt->CKTstate0 + here->BSIM3vbd);
@ -103,78 +108,103 @@ BSIM3instance *here = (BSIM3instance*)inst;
return(OK); return(OK);
case BSIM3_CD: case BSIM3_CD:
value->rValue = here->BSIM3cd; value->rValue = here->BSIM3cd;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CBS: case BSIM3_CBS:
value->rValue = here->BSIM3cbs;
value->rValue = here->BSIM3cbs;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CBD: case BSIM3_CBD:
value->rValue = here->BSIM3cbd;
value->rValue = here->BSIM3cbd;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_GM: case BSIM3_GM:
value->rValue = here->BSIM3gm;
value->rValue = here->BSIM3gm;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_GDS: case BSIM3_GDS:
value->rValue = here->BSIM3gds;
value->rValue = here->BSIM3gds;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_GMBS: case BSIM3_GMBS:
value->rValue = here->BSIM3gmbs; value->rValue = here->BSIM3gmbs;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_GBD: case BSIM3_GBD:
value->rValue = here->BSIM3gbd;
value->rValue = here->BSIM3gbd;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_GBS: case BSIM3_GBS:
value->rValue = here->BSIM3gbs;
value->rValue = here->BSIM3gbs;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_QB: case BSIM3_QB:
value->rValue = *(ckt->CKTstate0 + here->BSIM3qb);
value->rValue = *(ckt->CKTstate0 + here->BSIM3qb);
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CQB: case BSIM3_CQB:
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqb); value->rValue = *(ckt->CKTstate0 + here->BSIM3cqb);
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_QG: case BSIM3_QG:
value->rValue = *(ckt->CKTstate0 + here->BSIM3qg);
value->rValue = *(ckt->CKTstate0 + here->BSIM3qg);
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CQG: case BSIM3_CQG:
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqg);
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqg);
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_QD: case BSIM3_QD:
value->rValue = *(ckt->CKTstate0 + here->BSIM3qd);
value->rValue = *(ckt->CKTstate0 + here->BSIM3qd);
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CQD: case BSIM3_CQD:
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqd);
value->rValue = *(ckt->CKTstate0 + here->BSIM3cqd);
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CGG: case BSIM3_CGG:
value->rValue = here->BSIM3cggb;
value->rValue = here->BSIM3cggb;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CGD: case BSIM3_CGD:
value->rValue = here->BSIM3cgdb; value->rValue = here->BSIM3cgdb;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CGS: case BSIM3_CGS:
value->rValue = here->BSIM3cgsb; value->rValue = here->BSIM3cgsb;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CDG: case BSIM3_CDG:
value->rValue = here->BSIM3cdgb;
value->rValue = here->BSIM3cdgb;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CDD: case BSIM3_CDD:
value->rValue = here->BSIM3cddb;
value->rValue = here->BSIM3cddb;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CDS: case BSIM3_CDS:
value->rValue = here->BSIM3cdsb;
value->rValue = here->BSIM3cdsb;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CBG: case BSIM3_CBG:
value->rValue = here->BSIM3cbgb; value->rValue = here->BSIM3cbgb;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CBDB: case BSIM3_CBDB:
value->rValue = here->BSIM3cbdb; value->rValue = here->BSIM3cbdb;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CBSB: case BSIM3_CBSB:
value->rValue = here->BSIM3cbsb; value->rValue = here->BSIM3cbsb;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CAPBD: case BSIM3_CAPBD:
value->rValue = here->BSIM3capbd;
value->rValue = here->BSIM3capbd;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_CAPBS: case BSIM3_CAPBS:
value->rValue = here->BSIM3capbs; value->rValue = here->BSIM3capbs;
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_VON: case BSIM3_VON:
value->rValue = here->BSIM3von; value->rValue = here->BSIM3von;
@ -183,10 +213,12 @@ BSIM3instance *here = (BSIM3instance*)inst;
value->rValue = here->BSIM3vdsat; value->rValue = here->BSIM3vdsat;
return(OK); return(OK);
case BSIM3_QBS: case BSIM3_QBS:
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs);
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs);
value->rValue *= here->BSIM3m;
return(OK); return(OK);
case BSIM3_QBD: case BSIM3_QBD:
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd);
value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd);
value->rValue *= here->BSIM3m;
return(OK); return(OK);
default: default:
return(E_BADPARM); return(E_BADPARM);

125
src/spicelib/devices/bsim3/b3ld.c

@ -3,6 +3,7 @@ Copyright 1999 Regents of the University of California. All rights reserved.
Author: 1991 JianHui Huang and Min-Chie Jeng. Author: 1991 JianHui Huang and Min-Chie Jeng.
Modified by Mansun Chan (1995). Modified by Mansun Chan (1995).
Author: 1997-1999 Weidong Liu. Author: 1997-1999 Weidong Liu.
Modified: 2000 AlansFixes
File: b3ld.c File: b3ld.c
**********/ **********/
@ -118,6 +119,8 @@ double Cgg, Cgd, Cgb, Cdg, Cdd, Cds;
double Csg, Csd, Css, Csb, Cbg, Cbd, Cbb; double Csg, Csd, Css, Csb, Cbg, Cbd, Cbb;
double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0; double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0;
double dQac0_dVg, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; double dQac0_dVg, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb;
double m;
struct bsim3SizeDependParam *pParam; struct bsim3SizeDependParam *pParam;
int ByPass, Check, ChargeComputationNeeded, error; int ByPass, Check, ChargeComputationNeeded, error;
@ -318,6 +321,8 @@ for (; model != NULL; model = model->BSIM3nextModel)
vbd = vbs - vds; vbd = vbs - vds;
vgd = vgs - vds; vgd = vgs - vds;
vgb = vgs - vbs; vgb = vgs - vbs;
m=here->BSIM3m;
/* Source/drain junction diode DC model begins */ /* Source/drain junction diode DC model begins */
Nvtm = model->BSIM3vtm * model->BSIM3jctEmissionCoeff; Nvtm = model->BSIM3vtm * model->BSIM3jctEmissionCoeff;
@ -331,29 +336,29 @@ for (; model != NULL; model = model->BSIM3nextModel)
* model->BSIM3jctSidewallTempSatCurDensity; * model->BSIM3jctSidewallTempSatCurDensity;
} }
if (SourceSatCurrent <= 0.0) if (SourceSatCurrent <= 0.0)
{ here->BSIM3gbs = ckt->CKTgmin;
{ here->BSIM3gbs = ckt->CKTgmin/m;
here->BSIM3cbs = here->BSIM3gbs * vbs; here->BSIM3cbs = here->BSIM3gbs * vbs;
} }
else else
{ if (model->BSIM3ijth == 0.0) { if (model->BSIM3ijth == 0.0)
{ evbs = exp(vbs / Nvtm); { 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) here->BSIM3cbs = SourceSatCurrent * (evbs - 1.0)
+ ckt->CKTgmin * vbs;
+ (ckt->CKTgmin/m) * vbs;
} }
else else
{ if (vbs < here->BSIM3vjsm) { if (vbs < here->BSIM3vjsm)
{ evbs = exp(vbs / Nvtm); { 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) here->BSIM3cbs = SourceSatCurrent * (evbs - 1.0)
+ ckt->CKTgmin * vbs;
+ (ckt->CKTgmin/m) * vbs;
} }
else else
{ T0 = here->BSIM3IsEvjsm / Nvtm; { T0 = here->BSIM3IsEvjsm / Nvtm;
here->BSIM3gbs = T0 + ckt->CKTgmin;
here->BSIM3gbs = T0 + (ckt->CKTgmin/m);
here->BSIM3cbs = here->BSIM3IsEvjsm - SourceSatCurrent here->BSIM3cbs = here->BSIM3IsEvjsm - SourceSatCurrent
+ T0 * (vbs - here->BSIM3vjsm) + T0 * (vbs - here->BSIM3vjsm)
+ ckt->CKTgmin * vbs;
+ (ckt->CKTgmin/m) * vbs;
} }
} }
} }
@ -368,29 +373,29 @@ for (; model != NULL; model = model->BSIM3nextModel)
* model->BSIM3jctSidewallTempSatCurDensity; * model->BSIM3jctSidewallTempSatCurDensity;
} }
if (DrainSatCurrent <= 0.0) if (DrainSatCurrent <= 0.0)
{ here->BSIM3gbd = ckt->CKTgmin;
{ here->BSIM3gbd = (ckt->CKTgmin/m);
here->BSIM3cbd = here->BSIM3gbd * vbd; here->BSIM3cbd = here->BSIM3gbd * vbd;
} }
else else
{ if (model->BSIM3ijth == 0.0) { if (model->BSIM3ijth == 0.0)
{ evbd = exp(vbd / Nvtm); { 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) here->BSIM3cbd = DrainSatCurrent * (evbd - 1.0)
+ ckt->CKTgmin * vbd;
+ (ckt->CKTgmin/m) * vbd;
} }
else else
{ if (vbd < here->BSIM3vjdm) { if (vbd < here->BSIM3vjdm)
{ evbd = exp(vbd / Nvtm); { 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) here->BSIM3cbd = DrainSatCurrent * (evbd - 1.0)
+ ckt->CKTgmin * vbd;
+ (ckt->CKTgmin/m) * vbd;
} }
else else
{ T0 = here->BSIM3IsEvjdm / Nvtm; { T0 = here->BSIM3IsEvjdm / Nvtm;
here->BSIM3gbd = T0 + ckt->CKTgmin;
here->BSIM3gbd = T0 + (ckt->CKTgmin/m);
here->BSIM3cbd = here->BSIM3IsEvjdm - DrainSatCurrent here->BSIM3cbd = here->BSIM3IsEvjdm - DrainSatCurrent
+ T0 * (vbd - here->BSIM3vjdm) + T0 * (vbd - here->BSIM3vjdm)
+ ckt->CKTgmin * vbd;
+ (ckt->CKTgmin/m) * vbd;
} }
} }
} }
@ -2833,71 +2838,71 @@ line900:
cqdef = -cqdef; cqdef = -cqdef;
cqcheq = -cqcheq; 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)); + ceqqb + ceqqd));
if (here->BSIM3nqsMod) if (here->BSIM3nqsMod)
*(ckt->CKTrhs + here->BSIM3qNode) += (cqcheq - cqdef);
*(ckt->CKTrhs + here->BSIM3qNode) += m*(cqcheq - cqdef);
/* /*
* load y matrix * load y matrix
*/ */
T1 = qdef * here->BSIM3gtau; 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 + here->BSIM3gds + here->BSIM3gbd
+ RevSum + gcddb + dxpart * ggtd + 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 + here->BSIM3gds + here->BSIM3gbs
+ FwdSum + gcssb + sxpart * ggts + 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 + 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 + 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) 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: ; line1000: ;
} /* End of Mosfet Instance */ } /* End of Mosfet Instance */

5
src/spicelib/devices/bsim3/b3par.c

@ -2,6 +2,7 @@
Copyright 1999 Regents of the University of California. All rights reserved. Copyright 1999 Regents of the University of California. All rights reserved.
Author: 1995 Min-Chie Jeng and Mansun Chan. Author: 1995 Min-Chie Jeng and Mansun Chan.
Author: 1997-1999 Weidong Liu. Author: 1997-1999 Weidong Liu.
Modified: 2000 AlansFixes
File: b3par.c File: b3par.c
**********/ **********/
@ -29,6 +30,10 @@ IFvalue *select;
here->BSIM3l = value->rValue; here->BSIM3l = value->rValue;
here->BSIM3lGiven = TRUE; here->BSIM3lGiven = TRUE;
break; break;
case BSIM3_M:
here->BSIM3m = value->rValue;
here->BSIM3mGiven = TRUE;
break;
case BSIM3_AS: case BSIM3_AS:
here->BSIM3sourceArea = value->rValue; here->BSIM3sourceArea = value->rValue;
here->BSIM3sourceAreaGiven = TRUE; here->BSIM3sourceAreaGiven = TRUE;

27
src/spicelib/devices/bsim3/b3set.c

@ -2,6 +2,8 @@
Copyright 1999 Regents of the University of California. All rights reserved. Copyright 1999 Regents of the University of California. All rights reserved.
Author: 1995 Min-Chie Jeng and Mansun Chan. Author: 1995 Min-Chie Jeng and Mansun Chan.
Author: 1997-1999 Weidong Liu. Author: 1997-1999 Weidong Liu.
Modified: 2000 AlansFixes
File: b3set.c File: b3set.c
**********/ **********/
@ -848,6 +850,10 @@ CKTnode *tmp;
{ {
if (here->BSIM3owner == ARCHme) { if (here->BSIM3owner == ARCHme) {
/* allocate a chunk of the state vector */ /* allocate a chunk of the state vector */
CKTnode *tmpNode;
IFuid tmpName;
here->BSIM3states = *states; here->BSIM3states = *states;
*states += BSIM3numStates; *states += BSIM3numStates;
} }
@ -877,7 +883,10 @@ CKTnode *tmp;
here->BSIM3w = 5.0e-6; here->BSIM3w = 5.0e-6;
if (!here->BSIM3nqsModGiven) if (!here->BSIM3nqsModGiven)
here->BSIM3nqsMod = 0; here->BSIM3nqsMod = 0;
if (!here->BSIM3mGiven)
here->BSIM3m = 1;
/* process drain series resistance */ /* process drain series resistance */
if ((model->BSIM3sheetResistance > 0.0) && if ((model->BSIM3sheetResistance > 0.0) &&
(here->BSIM3drainSquares > 0.0 ) && (here->BSIM3drainSquares > 0.0 ) &&
@ -885,6 +894,14 @@ CKTnode *tmp;
{ error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain"); { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain");
if(error) return(error); if(error) return(error);
here->BSIM3dNodePrime = tmp->number; 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 else
{ here->BSIM3dNodePrime = here->BSIM3dNode; { here->BSIM3dNodePrime = here->BSIM3dNode;
@ -897,6 +914,14 @@ CKTnode *tmp;
{ error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source"); { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source");
if(error) return(error); if(error) return(error);
here->BSIM3sNodePrime = tmp->number; 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 else
{ here->BSIM3sNodePrime = here->BSIM3sNode; { here->BSIM3sNodePrime = here->BSIM3sNode;

5
src/spicelib/devices/bsim3/bsim3def.h

@ -2,6 +2,7 @@
Copyright 1999 Regents of the University of California. All rights reserved. Copyright 1999 Regents of the University of California. All rights reserved.
Author: 1995 Min-Chie Jeng and Mansun Chan. Author: 1995 Min-Chie Jeng and Mansun Chan.
Author: 1997-1999 Weidong Liu. Author: 1997-1999 Weidong Liu.
Modified: 2000 AlansFixes
File: bsim3def.h File: bsim3def.h
**********/ **********/
@ -106,6 +107,7 @@ typedef struct sBSIM3instance
unsigned BSIM3lGiven :1; unsigned BSIM3lGiven :1;
unsigned BSIM3wGiven :1; unsigned BSIM3wGiven :1;
unsigned BSIM3mGiven :1;
unsigned BSIM3drainAreaGiven :1; unsigned BSIM3drainAreaGiven :1;
unsigned BSIM3sourceAreaGiven :1; unsigned BSIM3sourceAreaGiven :1;
unsigned BSIM3drainSquaresGiven :1; unsigned BSIM3drainSquaresGiven :1;
@ -152,7 +154,7 @@ typedef struct sBSIM3instance
double *BSIM3SPqPtr; double *BSIM3SPqPtr;
double *BSIM3BqPtr; 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 BSIM3vbd BSIM3states+ 0
#define BSIM3vbs BSIM3states+ 1 #define BSIM3vbs BSIM3states+ 1
#define BSIM3vgs BSIM3states+ 2 #define BSIM3vgs BSIM3states+ 2
@ -1213,6 +1215,7 @@ typedef struct sBSIM3model
/* device parameters */ /* device parameters */
#define BSIM3_W 1 #define BSIM3_W 1
#define BSIM3_L 2 #define BSIM3_L 2
#define BSIM3_M 15
#define BSIM3_AS 3 #define BSIM3_AS 3
#define BSIM3_AD 4 #define BSIM3_AD 4
#define BSIM3_PS 5 #define BSIM3_PS 5

6
src/spicelib/devices/cap/capask.c

@ -56,7 +56,7 @@ CAPask(ckt,inst, which, value, select)
} else { } else {
value->rValue = *(ckt->CKTstate0 + here->CAPccap); value->rValue = *(ckt->CKTstate0 + here->CAPccap);
} }
}
} else value->rValue = *(ckt->CKTstate0 + here->CAPccap);
return(OK); return(OK);
case CAP_POWER: case CAP_POWER:
if (ckt->CKTcurrentAnalysis & DOING_AC) { if (ckt->CKTcurrentAnalysis & DOING_AC) {
@ -74,7 +74,9 @@ CAPask(ckt,inst, which, value, select)
(*(ckt->CKTrhsOld + here->CAPposNode) - (*(ckt->CKTrhsOld + here->CAPposNode) -
*(ckt->CKTrhsOld + here->CAPnegNode)); *(ckt->CKTrhsOld + here->CAPnegNode));
} }
}
} else value->rValue = *(ckt->CKTstate0 + here->CAPccap) *
(*(ckt->CKTrhsOld + here->CAPposNode) -
*(ckt->CKTrhsOld + here->CAPnegNode));
return(OK); return(OK);
case CAP_QUEST_SENS_DC: case CAP_QUEST_SENS_DC:
if(ckt->CKTsenInfo){ if(ckt->CKTsenInfo){

8
src/spicelib/devices/cktinit.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modifed: 2000 AlansFixes
**********/ **********/
#include <config.h> #include <config.h>
@ -30,12 +31,13 @@ CKTinit(void **ckt) /* new circuit to create */
sckt->CKTmatrix = NULL; sckt->CKTmatrix = NULL;
sckt->CKTgmin = 1e-12; sckt->CKTgmin = 1e-12;
sckt->CKTgshunt=0;
sckt->CKTabstol = 1e-12; sckt->CKTabstol = 1e-12;
sckt->CKTreltol = 1e-3; sckt->CKTreltol = 1e-3;
sckt->CKTchgtol = 1e-14; sckt->CKTchgtol = 1e-14;
sckt->CKTvoltTol = 1e-6; sckt->CKTvoltTol = 1e-6;
sckt->CKTtrtol = 7; sckt->CKTtrtol = 7;
sckt->CKTbypass = 1;
sckt->CKTbypass = 0;
sckt->CKTisSetup = 0; sckt->CKTisSetup = 0;
sckt->CKTtranMaxIter = 10; sckt->CKTtranMaxIter = 10;
sckt->CKTdcMaxIter = 100; sckt->CKTdcMaxIter = 100;
@ -47,6 +49,7 @@ CKTinit(void **ckt) /* new circuit to create */
sckt->CKTpivotRelTol = 1e-3; sckt->CKTpivotRelTol = 1e-3;
sckt->CKTtemp = 300.15; sckt->CKTtemp = 300.15;
sckt->CKTnomTemp = 300.15; sckt->CKTnomTemp = 300.15;
sckt->CKTdefaultMosM = 1;
sckt->CKTdefaultMosL = 1e-4; sckt->CKTdefaultMosL = 1e-4;
sckt->CKTdefaultMosW = 1e-4; sckt->CKTdefaultMosW = 1e-4;
sckt->CKTdefaultMosAD = 0; sckt->CKTdefaultMosAD = 0;
@ -59,6 +62,9 @@ CKTinit(void **ckt) /* new circuit to create */
sckt->CKTtimePoints = NULL; sckt->CKTtimePoints = NULL;
if (sckt->CKTstat == (STATistics *)NULL) if (sckt->CKTstat == (STATistics *)NULL)
return E_NOMEM; return E_NOMEM;
sckt->CKTnodeDamping = 0;
sckt->CKTabsDv = 0.5;
sckt->CKTrelDv = 2.0;
return OK; return OK;
} }

3
src/spicelib/devices/csw/Makefile.am

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

3
src/spicelib/devices/csw/cswdefs.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Gordon M. Jacobs Author: 1985 Gordon M. Jacobs
Modified: 2000 AlansFixes
**********/ **********/
#ifndef CSW #ifndef CSW
@ -54,7 +55,7 @@ typedef struct sCSWinstance {
#define CSW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */ #define CSW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */
#define CSW_OFF_CONDUCTANCE ckt->CKTgmin /* default off conductance */ #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 */ typedef struct sCSWmodel { /* model structure for a switch */
int CSWmodType; /* type index of this device type */ int CSWmodType; /* type index of this device type */

5
src/spicelib/devices/csw/cswext.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Gordon M. Jacobs Author: 1985 Gordon M. Jacobs
Modified: 2000 AlansFixes
**********/ **********/
#ifdef __STDC__ #ifdef __STDC__
@ -16,6 +17,9 @@ extern int CSWparam(int,IFvalue*,GENinstance*,IFvalue*);
extern int CSWpzLoad(GENmodel*,CKTcircuit*,SPcomplex*); extern int CSWpzLoad(GENmodel*,CKTcircuit*,SPcomplex*);
extern int CSWsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int CSWsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
extern int CSWnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int CSWnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int CSWtrunc(GENmodel*,CKTcircuit*,double*);
#else /* stdc */ #else /* stdc */
extern int CSWask(); extern int CSWask();
extern int CSWacLoad(); extern int CSWacLoad();
@ -29,5 +33,6 @@ extern int CSWparam();
extern int CSWpzLoad(); extern int CSWpzLoad();
extern int CSWsetup(); extern int CSWsetup();
extern int CSWnoise(); extern int CSWnoise();
extern int CSWtrunc();
#endif /* stdc */ #endif /* stdc */

4
src/spicelib/devices/csw/cswinit.c

@ -1,3 +1,5 @@
/* Modified: 2000 AlansFixes */
#include <config.h> #include <config.h>
#include <devdefs.h> #include <devdefs.h>
@ -31,7 +33,7 @@ SPICEdev CSWinfo = {
DEVunsetup : NULL, DEVunsetup : NULL,
DEVpzSetup : CSWsetup, DEVpzSetup : CSWsetup,
DEVtemperature: NULL, DEVtemperature: NULL,
DEVtrunc : NULL,
DEVtrunc :CSWtrunc,
DEVfindBranch : NULL, DEVfindBranch : NULL,
DEVacLoad : CSWacLoad, DEVacLoad : CSWacLoad,
DEVaccept : NULL, DEVaccept : NULL,

8
src/spicelib/devices/csw/cswload.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Gordon Jacobs Author: 1985 Gordon Jacobs
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -47,6 +48,9 @@ CSWload(inModel,ckt)
*(ckt->CKTstate0 + here->CSWstate) = 0.0; *(ckt->CKTstate0 + here->CSWstate) = 0.0;
current_state = 0.0; current_state = 0.0;
} }
*(ckt->CKTstate0 + (here->CSWstate+1)) = 0;
} else if (ckt->CKTmode & (MODEINITSMSIG)) { } else if (ckt->CKTmode & (MODEINITSMSIG)) {
previous_state = *(ckt->CKTstate0 + here->CSWstate); previous_state = *(ckt->CKTstate0 + here->CSWstate);
@ -70,6 +74,8 @@ CSWload(inModel,ckt)
current_state = previous_state; current_state = previous_state;
} }
*(ckt->CKTstate0 + (here->CSWstate+1)) = i_ctrl;
if(current_state != previous_state) { if(current_state != previous_state) {
ckt->CKTnoncon++; /* ensure one more iteration */ ckt->CKTnoncon++; /* ensure one more iteration */
ckt->CKTtroubleElt = (GENinstance *) here; ckt->CKTtroubleElt = (GENinstance *) here;
@ -96,6 +102,8 @@ CSWload(inModel,ckt)
*(ckt->CKTstate0 + here->CSWstate) = 1.0; *(ckt->CKTstate0 + here->CSWstate) = 1.0;
} }
*(ckt->CKTstate0 + (here->CSWstate+1)) = i_ctrl;
} }
g_now = current_state?(model->CSWonConduct):(model->CSWoffConduct); g_now = current_state?(model->CSWonConduct):(model->CSWoffConduct);

25
src/spicelib/devices/devsup.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* support routines for device models */ /* support routines for device models */
@ -47,18 +48,32 @@ DEVpnjlim(double vnew,
if((vnew > vcrit) && (fabs(vnew - vold) > (vt + vt))) { if((vnew > vcrit) && (fabs(vnew - vold) > (vt + vt))) {
if(vold > 0) { if(vold > 0) {
arg = 1 + (vnew - vold) / vt;
arg = (vnew - vold) / vt;
if(arg > 0) { if(arg > 0) {
vnew = vold + vt * log(arg);
vnew = vold + vt * (2+log(arg-2));
} else { } else {
vnew = vcrit;
vnew = vold - vt * (2+log(2-arg));
} }
} else { } else {
vnew = vt *log(vnew/vt); vnew = vt *log(vnew/vt);
} }
*icheck = 1; *icheck = 1;
} else { } 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); return(vnew);
} }
@ -76,7 +91,7 @@ DEVfetlim(double vnew,
double vtemp; double vtemp;
vtsthi = fabs(2*(vold-vto))+2; vtsthi = fabs(2*(vold-vto))+2;
vtstlo = vtsthi/2 +2;
vtstlo = fabs(vold-vto)*1;
vtox = vto + 3.5; vtox = vto + 3.5;
delv = vnew-vold; delv = vnew-vold;

4
src/spicelib/devices/dio/dioext.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#ifdef __STDC__ #ifdef __STDC__
@ -29,6 +30,9 @@ extern int DIOtrunc(GENmodel*,CKTcircuit*,double*);
extern int DIOdisto(int,GENmodel*,CKTcircuit*); extern int DIOdisto(int,GENmodel*,CKTcircuit*);
extern int DIOnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int DIOnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int DIOdSetup(DIOmodel*,CKTcircuit*);
#else /* stdc */ #else /* stdc */
extern int DIOacLoad(); extern int DIOacLoad();

13
src/spicelib/devices/dio/dioload.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -176,7 +177,7 @@ next1: if (vd >= -3*vte) {
evd = exp(vd/vte); evd = exp(vd/vte);
cd = csat*(evd-1)+ckt->CKTgmin*vd; cd = csat*(evd-1)+ckt->CKTgmin*vd;
gd = csat*evd/vte+ckt->CKTgmin; gd = csat*evd/vte+ckt->CKTgmin;
} else if((!(here->DIOtBrkdwnV))||
} else if((!(model->DIObreakdownVoltageGiven)) ||
vd >= -here->DIOtBrkdwnV) { vd >= -here->DIOtBrkdwnV) {
arg=3*vte/(vd*CONSTe); arg=3*vte/(vd*CONSTe);
arg = arg * arg * arg; arg = arg * arg * arg;
@ -194,10 +195,10 @@ next1: if (vd >= -3*vte) {
*/ */
czero=here->DIOtJctCap*here->DIOarea; czero=here->DIOtJctCap*here->DIOarea;
if (vd < here->DIOtDepCap){ if (vd < here->DIOtDepCap){
arg=1-vd/model->DIOjunctionPot;
arg=1-vd/here->DIOtJctPot;
sarg=exp(-model->DIOgradingCoeff*log(arg)); sarg=exp(-model->DIOgradingCoeff*log(arg));
*(ckt->CKTstate0 + here->DIOcapCharge) = *(ckt->CKTstate0 + here->DIOcapCharge) =
model->DIOtransitTime*cd+model->DIOjunctionPot*
model->DIOtransitTime*cd+here->DIOtJctPot*
czero* (1-arg*sarg)/(1-model->DIOgradingCoeff); czero* (1-arg*sarg)/(1-model->DIOgradingCoeff);
capd=model->DIOtransitTime*gd+czero*sarg; capd=model->DIOtransitTime*gd+czero*sarg;
} else { } else {
@ -205,11 +206,11 @@ next1: if (vd >= -3*vte) {
*(ckt->CKTstate0 + here->DIOcapCharge) = *(ckt->CKTstate0 + here->DIOcapCharge) =
model->DIOtransitTime*cd+czero*here->DIOtF1+czof2* model->DIOtransitTime*cd+czero*here->DIOtF1+czof2*
(model->DIOf3*(vd-here->DIOtDepCap)+ (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)); here->DIOtDepCap));
capd=model->DIOtransitTime*gd+czof2*(model->DIOf3+ capd=model->DIOtransitTime*gd+czof2*(model->DIOf3+
model->DIOgradingCoeff*vd/model->DIOjunctionPot);
model->DIOgradingCoeff*vd/here->DIOtJctPot);
} }
here->DIOcap = capd; here->DIOcap = capd;

13
src/spicelib/devices/dio/diosetup.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* load the diode structure with those pointers needed later /* load the diode structure with those pointers needed later
@ -86,9 +87,21 @@ matrixpointers:
if(model->DIOresist == 0) { if(model->DIOresist == 0) {
here->DIOposPrimeNode = here->DIOposNode; here->DIOposPrimeNode = here->DIOposNode;
} else if(here->DIOposPrimeNode == 0) { } else if(here->DIOposPrimeNode == 0) {
CKTnode *tmpNode;
IFuid tmpName;
error = CKTmkVolt(ckt,&tmp,here->DIOname,"internal"); error = CKTmkVolt(ckt,&tmp,here->DIOname,"internal");
if(error) return(error); if(error) return(error);
here->DIOposPrimeNode = tmp->number; 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 */ /* macro to make elements with built in test for out of memory */

10
src/spicelib/devices/dio/diotemp.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* perform the temperature update to the diode */ /* perform the temperature update to the diode */
@ -111,7 +112,10 @@ DIOtemp(inModel,ckt)
here->DIOtJctPot; here->DIOtJctPot;
/* and Vcrit */ /* and Vcrit */
vte=model->DIOemissionCoeff*vt; 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 /* and now to copute the breakdown voltage, again, using
* temperature adjusted basic parameters */ * temperature adjusted basic parameters */
if (model->DIObreakdownVoltageGiven){ if (model->DIObreakdownVoltageGiven){
@ -121,12 +125,12 @@ DIOtemp(inModel,ckt)
emsg = MALLOC(100); emsg = MALLOC(100);
if(emsg == (char *)NULL) return(E_NOMEM); if(emsg == (char *)NULL) return(E_NOMEM);
(void)sprintf(emsg, (void)sprintf(emsg,
"%%s: breakdown current increased to %g to resolve incompatability",
"%%s: breakdown current increased to %g to resolve",
cbv); cbv);
(*(SPfrontEnd->IFerror))(ERR_WARNING,emsg,&(here->DIOname)); (*(SPfrontEnd->IFerror))(ERR_WARNING,emsg,&(here->DIOname));
FREE(emsg); FREE(emsg);
(*(SPfrontEnd->IFerror))(ERR_WARNING, (*(SPfrontEnd->IFerror))(ERR_WARNING,
"with specified saturation current",(IFuid*)NULL);
"incompatibility with specified saturation current",(IFuid*)NULL);
xbv=model->DIObreakdownVoltage; xbv=model->DIObreakdownVoltage;
} else { } else {
tol=ckt->CKTreltol*cbv; tol=ckt->CKTreltol*cbv;

2
src/spicelib/devices/isrc/isrcload.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 Alansfixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -187,6 +188,7 @@ ISRCload(inModel,ckt)
} }
} }
loadDone: loadDone:
if (ckt->CKTmode & MODETRANOP) value *= ckt->CKTsrcFact;
*(ckt->CKTrhs + (here->ISRCposNode)) += value; *(ckt->CKTrhs + (here->ISRCposNode)) += value;
*(ckt->CKTrhs + (here->ISRCnegNode)) -= value; *(ckt->CKTrhs + (here->ISRCnegNode)) -= value;
} }

12
src/spicelib/devices/isrc/isrcpar.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -21,6 +22,8 @@ ISRCparam(param,value,inst,select)
GENinstance *inst; GENinstance *inst;
IFvalue *select; IFvalue *select;
{ {
int i;
ISRCinstance *here = (ISRCinstance*)inst; ISRCinstance *here = (ISRCinstance*)inst;
switch(param) { switch(param) {
case ISRC_DC: case ISRC_DC:
@ -83,6 +86,15 @@ ISRCparam(param,value,inst,select)
here->ISRCcoeffs = value->v.vec.rVec; here->ISRCcoeffs = value->v.vec.rVec;
here->ISRCfunctionOrder = value->v.numValue; here->ISRCfunctionOrder = value->v.numValue;
here->ISRCcoeffsGiven = TRUE; 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; break;
case ISRC_SFFM: case ISRC_SFFM:
if(value->v.numValue <2) return(E_BADPARM); if(value->v.numValue <2) return(E_BADPARM);

3
src/spicelib/devices/jfet/jfetext.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#ifdef __STDC__ #ifdef __STDC__
@ -22,6 +23,8 @@ extern int JFETtrunc(GENmodel*,CKTcircuit*,double*);
extern int JFETdisto(int,GENmodel*,CKTcircuit*); extern int JFETdisto(int,GENmodel*,CKTcircuit*);
extern int JFETnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int JFETnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int JFETdSetup(GENmodel*,CKTcircuit*);
#else /* stdc */ #else /* stdc */
extern int JFETacLoad(); extern int JFETacLoad();
extern int JFETask(); extern int JFETask();

31
src/spicelib/devices/jfet/jfetload.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
Sydney University mods Copyright(c) 1989 Anthony E. Parker, David J. Skellern Sydney University mods Copyright(c) 1989 Anthony E. Parker, David J. Skellern
Laboratory for Communication Science Engineering Laboratory for Communication Science Engineering
Sydney University Department of Electrical Engineering, Australia Sydney University Department of Electrical Engineering, Australia
@ -74,6 +75,8 @@ JFETload(inModel,ckt)
int icheck; int icheck;
int ichk1; int ichk1;
int error; int error;
double arg, vt_temp;
/* loop through all the models */ /* loop through all the models */
for( ; model != NULL; model = model->JFETnextModel ) { for( ; model != NULL; model = model->JFETnextModel ) {
@ -219,22 +222,30 @@ JFETload(inModel,ckt)
* determine dc current and derivatives * determine dc current and derivatives
*/ */
vds=vgs-vgd; 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 { } 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; 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 { } 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; cgd = csat*(evgd-1)+ckt->CKTgmin*vgd;
} }
cg = cg+cgd; cg = cg+cgd;
/* Modification for Sydney University JFET model */ /* Modification for Sydney University JFET model */

24
src/spicelib/devices/jfet/jfetset.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
Sydney University mods Copyright(c) 1989 Anthony E. Parker, David J. Skellern Sydney University mods Copyright(c) 1989 Anthony E. Parker, David J. Skellern
Laboratory for Communication Science Engineering Laboratory for Communication Science Engineering
Sydney University Department of Electrical Engineering, Australia Sydney University Department of Electrical Engineering, Australia
@ -95,6 +96,9 @@ JFETsetup(matrix,inModel,ckt,states)
here=here->JFETnextInstance) { here=here->JFETnextInstance) {
if (here->JFETowner != ARCHme) goto matrixpointers; if (here->JFETowner != ARCHme) goto matrixpointers;
CKTnode *tmpNode;
IFuid tmpName;
if(!here->JFETareaGiven) { if(!here->JFETareaGiven) {
here->JFETarea = 1; here->JFETarea = 1;
} }
@ -106,6 +110,16 @@ matrixpointers:
error = CKTmkVolt(ckt,&tmp,here->JFETname,"source"); error = CKTmkVolt(ckt,&tmp,here->JFETname,"source");
if(error) return(error); if(error) return(error);
here->JFETsourcePrimeNode = tmp->number; 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 { } else {
here->JFETsourcePrimeNode = here->JFETsourceNode; here->JFETsourcePrimeNode = here->JFETsourceNode;
} }
@ -113,6 +127,16 @@ matrixpointers:
error = CKTmkVolt(ckt,&tmp,here->JFETname,"drain"); error = CKTmkVolt(ckt,&tmp,here->JFETname,"drain");
if(error) return(error); if(error) return(error);
here->JFETdrainPrimeNode = tmp->number; 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 { } else {
here->JFETdrainPrimeNode = here->JFETdrainNode; here->JFETdrainPrimeNode = here->JFETdrainNode;
} }

3
src/spicelib/devices/ltra/ltraext.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1990 Jaijeet S. Roychowdhury Author: 1990 Jaijeet S. Roychowdhury
Modified: 2000 AlansFixes
**********/ **********/
#ifdef __STDC__ #ifdef __STDC__
@ -19,6 +20,8 @@ extern int LTRAunsetup(GENmodel*,CKTcircuit*);
extern int LTRAtemp(GENmodel*,CKTcircuit*); extern int LTRAtemp(GENmodel*,CKTcircuit*);
extern int LTRAtrunc(GENmodel*,CKTcircuit*,double*); 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 int LTRAquadInterp(double,double,double,double,double*,double*,double*);
/* /*
extern double LTRAcoeffSetup(double*,int,double,double,double*,double,double*,int,int*); extern double LTRAcoeffSetup(double*,int,double,double,double*,double,double*,int,int*);

3
src/spicelib/devices/mes/mesext.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 S. Hwang Author: 1985 S. Hwang
Modified: 2000 AlansFixes
**********/ **********/
#ifdef __STDC__ #ifdef __STDC__
@ -22,6 +23,8 @@ extern int MEStrunc(GENmodel*,CKTcircuit*,double*);
extern int MESdisto(int,GENmodel*,CKTcircuit*); extern int MESdisto(int,GENmodel*,CKTcircuit*);
extern int MESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int MESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int MESdSetup(GENmodel*,CKTcircuit*);
#else /* stdc */ #else /* stdc */
extern int MESacLoad(); extern int MESacLoad();
extern int MESask(); extern int MESask();

20
src/spicelib/devices/mes/mesload.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 S. Hwang Author: 1985 S. Hwang
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -80,6 +81,7 @@ MESload(inModel,ckt)
double vgst; double vgst;
double vto; double vto;
double xfact; double xfact;
double arg;
int icheck; int icheck;
int ichk1; int ichk1;
int error; int error;
@ -230,22 +232,28 @@ MESload(inModel,ckt)
* determine dc current and derivatives * determine dc current and derivatives
*/ */
vds = vgs-vgd; 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 { } else {
evgs = exp(vgs/CONSTvt0); evgs = exp(vgs/CONSTvt0);
ggs = csat*evgs/CONSTvt0+ckt->CKTgmin; ggs = csat*evgs/CONSTvt0+ckt->CKTgmin;
cg = csat*(evgs-1)+ckt->CKTgmin*vgs; 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 { } else {
evgd = exp(vgd/CONSTvt0); evgd = exp(vgd/CONSTvt0);
ggd = csat*evgd/CONSTvt0+ckt->CKTgmin; ggd = csat*evgd/CONSTvt0+ckt->CKTgmin;
cgd = csat*(evgd-1)+ckt->CKTgmin*vgd; cgd = csat*(evgd-1)+ckt->CKTgmin*vgd;
} }
cg = cg+cgd; cg = cg+cgd;
/* /*
* compute drain current and derivitives for normal mode * compute drain current and derivitives for normal mode

24
src/spicelib/devices/mes/messetup.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 S. Hwang Author: 1985 S. Hwang
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -81,6 +82,9 @@ MESsetup(matrix,inModel,ckt,states)
here=here->MESnextInstance) { here=here->MESnextInstance) {
if (here->MESowner != ARCHme) goto matrixpointers; if (here->MESowner != ARCHme) goto matrixpointers;
CKTnode *tmpNode;
IFuid tmpName;
if(!here->MESareaGiven) { if(!here->MESareaGiven) {
here->MESarea = 1; here->MESarea = 1;
} }
@ -92,6 +96,16 @@ matrixpointers:
error = CKTmkVolt(ckt,&tmp,here->MESname,"source"); error = CKTmkVolt(ckt,&tmp,here->MESname,"source");
if(error) return(error); if(error) return(error);
here->MESsourcePrimeNode = tmp->number; 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 { } else {
here->MESsourcePrimeNode = here->MESsourceNode; here->MESsourcePrimeNode = here->MESsourceNode;
} }
@ -99,6 +113,16 @@ matrixpointers:
error = CKTmkVolt(ckt,&tmp,here->MESname,"drain"); error = CKTmkVolt(ckt,&tmp,here->MESname,"drain");
if(error) return(error); if(error) return(error);
here->MESdrainPrimeNode = tmp->number; 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 { } else {
here->MESdrainPrimeNode = here->MESdrainNode; here->MESdrainPrimeNode = here->MESdrainNode;
} }

2
src/spicelib/devices/mos1/mos1.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Thomas L. Quarles Author: 1987 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -11,6 +12,7 @@ Author: 1987 Thomas L. Quarles
#include "suffix.h" #include "suffix.h"
IFparm MOS1pTable[] = { /* parameters */ IFparm MOS1pTable[] = { /* parameters */
IOPU("m", MOS1_M, IF_REAL , "Multiplier"),
IOPU("l", MOS1_L, IF_REAL , "Length"), IOPU("l", MOS1_L, IF_REAL , "Length"),
IOPU("w", MOS1_W, IF_REAL , "Width"), IOPU("w", MOS1_W, IF_REAL , "Width"),
IOPU("ad", MOS1_AD, IF_REAL , "Drain area"), IOPU("ad", MOS1_AD, IF_REAL , "Drain area"),

9
src/spicelib/devices/mos1/mos1acld.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -51,12 +52,14 @@ MOS1acLoad(inModel,ckt)
* meyer's model parameters * meyer's model parameters
*/ */
EffectiveLength=here->MOS1l - 2*model->MOS1latDiff; EffectiveLength=here->MOS1l - 2*model->MOS1latDiff;
GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor * GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor *
here->MOS1w;
here->MOS1m * here->MOS1w;
GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor *
here->MOS1w;
here->MOS1m * here->MOS1w;
GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor * GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor *
EffectiveLength;
here->MOS1m * EffectiveLength;
capgs = ( *(ckt->CKTstate0+here->MOS1capgs)+ capgs = ( *(ckt->CKTstate0+here->MOS1capgs)+
*(ckt->CKTstate0+here->MOS1capgs) + *(ckt->CKTstate0+here->MOS1capgs) +
GateSourceOverlapCap ); GateSourceOverlapCap );

29
src/spicelib/devices/mos1/mos1ask.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Thomas L. Quarles Author: 1987 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -34,11 +35,14 @@ MOS1ask(ckt,inst,which,value,select)
value->rValue = here->MOS1temp-CONSTCtoK; value->rValue = here->MOS1temp-CONSTCtoK;
return(OK); return(OK);
case MOS1_CGS: case MOS1_CGS:
value->rValue = *(ckt->CKTstate0 + here->MOS1capgs);
value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgs);
return(OK); return(OK);
case MOS1_CGD: 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: case MOS1_L:
value->rValue = here->MOS1l; value->rValue = here->MOS1l;
return(OK); return(OK);
@ -178,7 +182,11 @@ MOS1ask(ckt,inst,which,value,select)
value->rValue = *(ckt->CKTstate0 + here->MOS1vds); value->rValue = *(ckt->CKTstate0 + here->MOS1vds);
return(OK); return(OK);
case MOS1_CAPGS: 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); return(OK);
case MOS1_QGS: case MOS1_QGS:
value->rValue = *(ckt->CKTstate0 + here->MOS1qgs); value->rValue = *(ckt->CKTstate0 + here->MOS1qgs);
@ -187,7 +195,11 @@ MOS1ask(ckt,inst,which,value,select)
value->rValue = *(ckt->CKTstate0 + here->MOS1cqgs); value->rValue = *(ckt->CKTstate0 + here->MOS1cqgs);
return(OK); return(OK);
case MOS1_CAPGD: 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); return(OK);
case MOS1_QGD: case MOS1_QGD:
value->rValue = *(ckt->CKTstate0 + here->MOS1qgd); value->rValue = *(ckt->CKTstate0 + here->MOS1qgd);
@ -196,7 +208,12 @@ MOS1ask(ckt,inst,which,value,select)
value->rValue = *(ckt->CKTstate0 + here->MOS1cqgd); value->rValue = *(ckt->CKTstate0 + here->MOS1cqgd);
return(OK); return(OK);
case MOS1_CAPGB: 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); return(OK);
case MOS1_QGB: case MOS1_QGB:
value->rValue = *(ckt->CKTstate0 + here->MOS1qgb); value->rValue = *(ckt->CKTstate0 + here->MOS1qgb);

6
src/spicelib/devices/mos1/mos1defs.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#ifndef MOS1 #ifndef MOS1
@ -30,6 +31,8 @@ typedef struct sMOS1instance {
int MOS1bNode; /* number of the bulk node of the mosfet */ int MOS1bNode; /* number of the bulk node of the mosfet */
int MOS1dNodePrime; /* number of the internal drain 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 */ 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 MOS1l; /* the length of the channel region */
double MOS1w; /* the width 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 MOS1off:1; /* non-zero to indicate device is off for dc analysis*/
unsigned MOS1tempGiven :1; /* instance temperature specified */ unsigned MOS1tempGiven :1; /* instance temperature specified */
unsigned MOS1mGiven :1;
unsigned MOS1lGiven :1; unsigned MOS1lGiven :1;
unsigned MOS1wGiven :1; unsigned MOS1wGiven :1;
unsigned MOS1drainAreaGiven :1; unsigned MOS1drainAreaGiven :1;
@ -406,7 +410,7 @@ typedef struct sMOS1model { /* model structure for a resistor */
#define MOS1_CS 18 #define MOS1_CS 18
#define MOS1_POWER 19 #define MOS1_POWER 19
#define MOS1_TEMP 20 #define MOS1_TEMP 20
#define MOS1_M 21
/* model paramerers */ /* model paramerers */
#define MOS1_MOD_VTO 101 #define MOS1_MOD_VTO 101
#define MOS1_MOD_KP 102 #define MOS1_MOD_KP 102

22
src/spicelib/devices/mos1/mos1dset.c

@ -91,26 +91,28 @@ MOS1dSetup(inModel,ckt)
vt = CONSTKoverQ * here->MOS1temp; vt = CONSTKoverQ * here->MOS1temp;
EffectiveLength=here->MOS1l - 2*model->MOS1latDiff; EffectiveLength=here->MOS1l - 2*model->MOS1latDiff;
if( (here->MOS1tSatCurDens == 0) ||
if( (here->MOS1tSatCurDens == 0) ||
(here->MOS1drainArea == 0) || (here->MOS1drainArea == 0) ||
(here->MOS1sourceArea == 0)) { (here->MOS1sourceArea == 0)) {
DrainSatCur = here->MOS1tSatCur;
SourceSatCur = here->MOS1tSatCur;
DrainSatCur = here->MOS1m * here->MOS1tSatCur;
SourceSatCur = here->MOS1m * here->MOS1tSatCur;
} else { } else {
DrainSatCur = here->MOS1tSatCurDens * DrainSatCur = here->MOS1tSatCurDens *
here->MOS1drainArea;
here->MOS1m * here->MOS1drainArea;
SourceSatCur = here->MOS1tSatCurDens * SourceSatCur = here->MOS1tSatCurDens *
here->MOS1sourceArea;
here->MOS1m * here->MOS1sourceArea;
} }
GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor * GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor *
here->MOS1w;
here->MOS1m * here->MOS1w;
GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor *
here->MOS1w;
here->MOS1m * here->MOS1w;
GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor * 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 * OxideCap = model->MOS1oxideCapFactor * EffectiveLength *
here->MOS1w;
here->MOS1m * here->MOS1w;
vbs = model->MOS1type * ( vbs = model->MOS1type * (
*(ckt->CKTrhsOld+here->MOS1bNode) - *(ckt->CKTrhsOld+here->MOS1bNode) -

2
src/spicelib/devices/mos1/mos1ext.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#ifdef __STDC__ #ifdef __STDC__
@ -27,6 +28,7 @@ extern int MOS1trunc(GENmodel*,CKTcircuit*,double*);
extern int MOS1convTest(GENmodel*,CKTcircuit*); extern int MOS1convTest(GENmodel*,CKTcircuit*);
extern int MOS1disto(int,GENmodel*,CKTcircuit*); extern int MOS1disto(int,GENmodel*,CKTcircuit*);
extern int MOS1noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int MOS1noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int MOS1dSetup(GENmodel*,CKTcircuit*);
#else /* stdc */ #else /* stdc */
extern int MOS1acLoad(); extern int MOS1acLoad();

59
src/spicelib/devices/mos1/mos1load.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -111,26 +112,29 @@ MOS1load(inModel,ckt)
*/ */
EffectiveLength=here->MOS1l - 2*model->MOS1latDiff; 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;
(here->MOS1drainArea == 0) ||
(here->MOS1sourceArea == 0)) {
DrainSatCur = here->MOS1m * here->MOS1tSatCur;
SourceSatCur = here->MOS1m * here->MOS1tSatCur;
} else { } else {
DrainSatCur = here->MOS1tSatCurDens * DrainSatCur = here->MOS1tSatCurDens *
here->MOS1drainArea;
here->MOS1m * here->MOS1drainArea;
SourceSatCur = here->MOS1tSatCurDens * SourceSatCur = here->MOS1tSatCurDens *
here->MOS1sourceArea;
here->MOS1m * here->MOS1sourceArea;
} }
GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor * GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor *
here->MOS1w;
here->MOS1m * here->MOS1w;
GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor *
here->MOS1w;
here->MOS1m * here->MOS1w;
GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor * 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 * OxideCap = model->MOS1oxideCapFactor * EffectiveLength *
here->MOS1w;
here->MOS1m * here->MOS1w;
/* /*
* ok - now to do the start-up operations * 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 * here we just evaluate the ideal diode current and the
* corresponding derivative (conductance). * 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 { } else {
evbd = exp(MIN(MAX_EXP_ARG,vbd/vt)); 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 /* now to determine whether the user was able to correctly
* identify the source and drain of his device * identify the source and drain of his device
*/ */
@ -861,9 +862,9 @@ MOS1load(inModel,ckt)
* load current vector * load current vector
*/ */
ceqbs = model->MOS1type * ceqbs = model->MOS1type *
(here->MOS1cbs-(here->MOS1gbs-ckt->CKTgmin)*vbs);
(here->MOS1cbs-(here->MOS1gbs)*vbs);
ceqbd = model->MOS1type * ceqbd = model->MOS1type *
(here->MOS1cbd-(here->MOS1gbd-ckt->CKTgmin)*vbd);
(here->MOS1cbd-(here->MOS1gbd)*vbd);
if (here->MOS1mode >= 0) { if (here->MOS1mode >= 0) {
xnrm=1; xnrm=1;
xrev=0; xrev=0;

2
src/spicelib/devices/mos1/mos1noi.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Gary W. Ng Author: 1987 Gary W. Ng
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -145,6 +146,7 @@ if (!data->namelist) return(E_NOMEM);
exp(model->MOS1fNexp * exp(model->MOS1fNexp *
log(MAX(fabs(inst->MOS1cd),N_MINLOG))) / log(MAX(fabs(inst->MOS1cd),N_MINLOG))) /
(data->freq * inst->MOS1w * (data->freq * inst->MOS1w *
inst->MOS1m *
(inst->MOS1l - 2*model->MOS1latDiff) * coxSquared); (inst->MOS1l - 2*model->MOS1latDiff) * coxSquared);
lnNdens[MOS1FLNOIZ] = lnNdens[MOS1FLNOIZ] =
log(MAX(noizDens[MOS1FLNOIZ],N_MINLOG)); log(MAX(noizDens[MOS1FLNOIZ],N_MINLOG));

5
src/spicelib/devices/mos1/mos1par.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -28,6 +29,10 @@ MOS1param(param,value,inst,select)
here->MOS1temp = value->rValue+CONSTCtoK; here->MOS1temp = value->rValue+CONSTCtoK;
here->MOS1tempGiven = TRUE; here->MOS1tempGiven = TRUE;
break; break;
case MOS1_M:
here->MOS1m = value->rValue;
here->MOS1mGiven = TRUE;
break;
case MOS1_W: case MOS1_W:
here->MOS1w = value->rValue; here->MOS1w = value->rValue;
here->MOS1wGiven = TRUE; here->MOS1wGiven = TRUE;

9
src/spicelib/devices/mos1/mos1pzld.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -53,12 +54,14 @@ MOS1pzLoad(inModel,ckt,s)
* meyer's model parameters * meyer's model parameters
*/ */
EffectiveLength=here->MOS1l - 2*model->MOS1latDiff; EffectiveLength=here->MOS1l - 2*model->MOS1latDiff;
GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor * GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor *
here->MOS1w;
here->MOS1m * here->MOS1w;
GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor *
here->MOS1w;
here->MOS1m * here->MOS1w;
GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor * GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor *
EffectiveLength;
here->MOS1m * EffectiveLength;
capgs = ( 2* *(ckt->CKTstate0+here->MOS1capgs)+ capgs = ( 2* *(ckt->CKTstate0+here->MOS1capgs)+
GateSourceOverlapCap ); GateSourceOverlapCap );
capgd = ( 2* *(ckt->CKTstate0+here->MOS1capgd)+ capgd = ( 2* *(ckt->CKTstate0+here->MOS1capgd)+

24
src/spicelib/devices/mos1/mos1set.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* load the MOS1 device structure with those pointers needed later /* 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) { if(!here->MOS1drainPerimiterGiven) {
here->MOS1drainPerimiter = 0; here->MOS1drainPerimiter = 0;
} }
@ -139,6 +143,16 @@ MOS1setup(matrix,inModel,ckt,states)
error = CKTmkVolt(ckt,&tmp,here->MOS1name,"drain"); error = CKTmkVolt(ckt,&tmp,here->MOS1name,"drain");
if(error) return(error); if(error) return(error);
here->MOS1dNodePrime = tmp->number; 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 { } else {
here->MOS1dNodePrime = here->MOS1dNode; here->MOS1dNodePrime = here->MOS1dNode;
} }
@ -150,6 +164,16 @@ MOS1setup(matrix,inModel,ckt,states)
error = CKTmkVolt(ckt,&tmp,here->MOS1name,"source"); error = CKTmkVolt(ckt,&tmp,here->MOS1name,"source");
if(error) return(error); if(error) return(error);
here->MOS1sNodePrime = tmp->number; 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 { } else {
here->MOS1sNodePrime = here->MOS1sNode; here->MOS1sNodePrime = here->MOS1sNode;
} }

6
src/spicelib/devices/mos1/mos1sprt.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* Pretty print the sensitivity info for all /* Pretty print the sensitivity info for all
@ -41,7 +42,10 @@ CKTcircuit *ckt;
printf(" Drain, Gate , Source nodes: %s, %s ,%s\n", printf(" Drain, Gate , Source nodes: %s, %s ,%s\n",
CKTnodName(ckt,here->MOS1dNode),CKTnodName(ckt,here->MOS1gNode), CKTnodName(ckt,here->MOS1dNode),CKTnodName(ckt,here->MOS1gNode),
CKTnodName(ckt,here->MOS1sNode)); CKTnodName(ckt,here->MOS1sNode));
printf(" Multiplier: %g ",here->MOS1m);
printf(here->MOS1mGiven ? "(specified)\n" : "(default)\n");
printf(" Length: %g ",here->MOS1l); printf(" Length: %g ",here->MOS1l);
printf(here->MOS1lGiven ? "(specified)\n" : "(default)\n"); printf(here->MOS1lGiven ? "(specified)\n" : "(default)\n");
printf(" Width: %g ",here->MOS1w); printf(" Width: %g ",here->MOS1w);

40
src/spicelib/devices/mos1/mos1temp.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -137,6 +138,9 @@ MOS1temp(inModel,ckt)
if(!here->MOS1drainAreaGiven) { if(!here->MOS1drainAreaGiven) {
here->MOS1drainArea = ckt->CKTdefaultMosAD; here->MOS1drainArea = ckt->CKTdefaultMosAD;
} }
if(!here->MOS1mGiven) {
here->MOS1m = ckt->CKTdefaultMosM;
}
if(!here->MOS1lGiven) { if(!here->MOS1lGiven) {
here->MOS1l = ckt->CKTdefaultMosL; here->MOS1l = ckt->CKTdefaultMosL;
} }
@ -193,27 +197,30 @@ MOS1temp(inModel,ckt)
(here->MOS1drainArea == 0) || (here->MOS1drainArea == 0) ||
(here->MOS1sourceArea == 0) ) { (here->MOS1sourceArea == 0) ) {
here->MOS1sourceVcrit = here->MOS1drainVcrit = here->MOS1sourceVcrit = here->MOS1drainVcrit =
vt*log(vt/(CONSTroot2*here->MOS1tSatCur));
vt*log(vt/(CONSTroot2*here->MOS1m*here->MOS1tSatCur));
} else { } else {
here->MOS1drainVcrit = here->MOS1drainVcrit =
vt * log( vt / (CONSTroot2 * vt * log( vt / (CONSTroot2 *
here->MOS1m *
here->MOS1tSatCurDens * here->MOS1drainArea)); here->MOS1tSatCurDens * here->MOS1drainArea));
here->MOS1sourceVcrit = here->MOS1sourceVcrit =
vt * log( vt / (CONSTroot2 * vt * log( vt / (CONSTroot2 *
here->MOS1m *
here->MOS1tSatCurDens * here->MOS1sourceArea)); here->MOS1tSatCurDens * here->MOS1sourceArea));
} }
if(model->MOS1capBDGiven) { if(model->MOS1capBDGiven) {
czbd = here->MOS1tCbd;
czbd = here->MOS1tCbd * here->MOS1m;
} else { } else {
if(model->MOS1bulkCapFactorGiven) {
czbd=here->MOS1tCj*here->MOS1drainArea;
if(model->MOS1bulkCapFactorGiven) {
czbd=here->MOS1tCj*here->MOS1m*here->MOS1drainArea;
} else { } else {
czbd=0; czbd=0;
} }
} }
if(model->MOS1sideWallCapFactorGiven) { if(model->MOS1sideWallCapFactorGiven) {
czbdsw= here->MOS1tCjsw * here->MOS1drainPerimiter;
czbdsw= here->MOS1tCjsw * here->MOS1drainPerimiter *
here->MOS1m;
} else { } else {
czbdsw=0; czbdsw=0;
} }
@ -239,16 +246,17 @@ MOS1temp(inModel,ckt)
(here->MOS1tDepCap*here->MOS1tDepCap) (here->MOS1tDepCap*here->MOS1tDepCap)
-here->MOS1tDepCap * here->MOS1f2d; -here->MOS1tDepCap * here->MOS1f2d;
if(model->MOS1capBSGiven) { if(model->MOS1capBSGiven) {
czbs=here->MOS1tCbs;
czbs=here->MOS1tCbs * here->MOS1m;
} else { } else {
if(model->MOS1bulkCapFactorGiven) { if(model->MOS1bulkCapFactorGiven) {
czbs=here->MOS1tCj*here->MOS1sourceArea;
czbs=here->MOS1tCj*here->MOS1sourceArea * here->MOS1m;
} else { } else {
czbs=0; czbs=0;
} }
} }
if(model->MOS1sideWallCapFactorGiven) { if(model->MOS1sideWallCapFactorGiven) {
czbssw = here->MOS1tCjsw * here->MOS1sourcePerimiter;
czbssw = here->MOS1tCjsw * here->MOS1sourcePerimiter *
here->MOS1m;
} else { } else {
czbssw=0; czbssw=0;
} }
@ -277,14 +285,16 @@ MOS1temp(inModel,ckt)
if(model->MOS1drainResistanceGiven) { if(model->MOS1drainResistanceGiven) {
if(model->MOS1drainResistance != 0) { if(model->MOS1drainResistance != 0) {
here->MOS1drainConductance = 1/model->MOS1drainResistance;
here->MOS1drainConductance = here->MOS1m /
model->MOS1drainResistance;
} else { } else {
here->MOS1drainConductance = 0; here->MOS1drainConductance = 0;
} }
} else if (model->MOS1sheetResistanceGiven) { } else if (model->MOS1sheetResistanceGiven) {
if(model->MOS1sheetResistance != 0) { if(model->MOS1sheetResistance != 0) {
here->MOS1drainConductance = here->MOS1drainConductance =
1/(model->MOS1sheetResistance*here->MOS1drainSquares);
here->MOS1m /
(model->MOS1sheetResistance*here->MOS1drainSquares);
} else { } else {
here->MOS1drainConductance = 0; here->MOS1drainConductance = 0;
} }
@ -293,14 +303,18 @@ MOS1temp(inModel,ckt)
} }
if(model->MOS1sourceResistanceGiven) { if(model->MOS1sourceResistanceGiven) {
if(model->MOS1sourceResistance != 0) { if(model->MOS1sourceResistance != 0) {
here->MOS1sourceConductance = 1/model->MOS1sourceResistance;
here->MOS1sourceConductance = here->MOS1m /
model->MOS1sourceResistance;
} else { } else {
here->MOS1sourceConductance = 0; here->MOS1sourceConductance = 0;
} }
} else if (model->MOS1sheetResistanceGiven) { } else if (model->MOS1sheetResistanceGiven) {
if(model->MOS1sheetResistance != 0) {
if ((model->MOS1sheetResistance != 0) &&
(here->MOS1sourceSquares != 0)) {
#else
here->MOS1sourceConductance = here->MOS1sourceConductance =
1/(model->MOS1sheetResistance*here->MOS1sourceSquares);
here->MOS1m /
(model->MOS1sheetResistance*here->MOS1sourceSquares);
} else { } else {
here->MOS1sourceConductance = 0; here->MOS1sourceConductance = 0;
} }

2
src/spicelib/devices/mos2/mos2.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFIxes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -11,6 +12,7 @@ Author: 1985 Thomas L. Quarles
#include "suffix.h" #include "suffix.h"
IFparm MOS2pTable[] = { /* parameters */ IFparm MOS2pTable[] = { /* parameters */
IOPU("m", MOS2_M, IF_REAL , "Multiplier"),
IOPU("l", MOS2_L, IF_REAL , "Length"), IOPU("l", MOS2_L, IF_REAL , "Length"),
IOPU("w", MOS2_W, IF_REAL , "Width"), IOPU("w", MOS2_W, IF_REAL , "Width"),
IOPU("ad", MOS2_AD, IF_REAL , "Drain area"), IOPU("ad", MOS2_AD, IF_REAL , "Drain area"),

7
src/spicelib/devices/mos2/mos2acld.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -52,11 +53,11 @@ MOS2acLoad(inModel,ckt)
*/ */
EffectiveLength=here->MOS2l - 2*model->MOS2latDiff; EffectiveLength=here->MOS2l - 2*model->MOS2latDiff;
GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor * GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor *
here->MOS2w;
here->MOS2m * here->MOS2w;
GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor *
here->MOS2w;
here->MOS2m * here->MOS2w;
GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor * GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor *
EffectiveLength;
here->MOS2m * EffectiveLength;
capgs = ( *(ckt->CKTstate0+here->MOS2capgs)+ capgs = ( *(ckt->CKTstate0+here->MOS2capgs)+
*(ckt->CKTstate0+here->MOS2capgs) + *(ckt->CKTstate0+here->MOS2capgs) +
GateSourceOverlapCap ); GateSourceOverlapCap );

29
src/spicelib/devices/mos2/mos2ask.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Mathew Lew and Thomas L. Quarles Author: 1987 Mathew Lew and Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -34,14 +35,17 @@ MOS2ask(ckt,inst,which,value,select)
value->rValue = here->MOS2temp-CONSTCtoK; value->rValue = here->MOS2temp-CONSTCtoK;
return(OK); return(OK);
case MOS2_CGS: case MOS2_CGS:
value->rValue = *(ckt->CKTstate0 + here->MOS2capgs);
value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgs);
return(OK); return(OK);
case MOS2_CGD: 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); return(OK);
case MOS2_L: case MOS2_L:
value->rValue = here->MOS2l; value->rValue = here->MOS2l;
return(OK);
return(OK);
case MOS2_W: case MOS2_W:
value->rValue = here->MOS2w; value->rValue = here->MOS2w;
return(OK); return(OK);
@ -178,7 +182,11 @@ MOS2ask(ckt,inst,which,value,select)
value->rValue = *(ckt->CKTstate0 + here->MOS2vds); value->rValue = *(ckt->CKTstate0 + here->MOS2vds);
return(OK); return(OK);
case MOS2_CAPGS: 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); return(OK);
case MOS2_QGS: case MOS2_QGS:
value->rValue = *(ckt->CKTstate0 + here->MOS2qgs); value->rValue = *(ckt->CKTstate0 + here->MOS2qgs);
@ -187,7 +195,11 @@ MOS2ask(ckt,inst,which,value,select)
value->rValue = *(ckt->CKTstate0 + here->MOS2cqgs); value->rValue = *(ckt->CKTstate0 + here->MOS2cqgs);
return(OK); return(OK);
case MOS2_CAPGD: 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); return(OK);
case MOS2_QGD: case MOS2_QGD:
value->rValue = *(ckt->CKTstate0 + here->MOS2qgd); value->rValue = *(ckt->CKTstate0 + here->MOS2qgd);
@ -196,7 +208,12 @@ MOS2ask(ckt,inst,which,value,select)
value->rValue = *(ckt->CKTstate0 + here->MOS2cqgd); value->rValue = *(ckt->CKTstate0 + here->MOS2cqgd);
return(OK); return(OK);
case MOS2_CAPGB: 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); return(OK);
case MOS2_QGB: case MOS2_QGB:
value->rValue = *(ckt->CKTstate0 + here->MOS2qgb); value->rValue = *(ckt->CKTstate0 + here->MOS2qgb);

6
src/spicelib/devices/mos2/mos2defs.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFIxes
**********/ **********/
#ifndef MOS2 #ifndef MOS2
@ -33,6 +34,8 @@ typedef struct sMOS2instance {
int MOS2mode; /* device mode : 1 = normal, -1 = inverse */ 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 MOS2off :1;/* non-zero to indicate device is off for dc analysis*/
unsigned MOS2lGiven :1; unsigned MOS2lGiven :1;
unsigned MOS2wGiven :1; unsigned MOS2wGiven :1;
@ -151,6 +154,8 @@ typedef struct sMOS2instance {
/* the cureve matching Fc * Vj */ /* the cureve matching Fc * Vj */
double MOS2tVbi; /* temperature adjusted Vbi */ double MOS2tVbi; /* temperature adjusted Vbi */
double MOS2m; /* parallel device multiplier */
double MOS2l; /* the length of the channel region */ double MOS2l; /* the length of the channel region */
double MOS2w; /* the width of the channel region */ double MOS2w; /* the width of the channel region */
double MOS2drainArea; /* the area of the drain diffusion */ 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_TEMP 77
#define MOS2_SOURCERESIST 78 #define MOS2_SOURCERESIST 78
#define MOS2_DRAINRESIST 79 #define MOS2_DRAINRESIST 79
#define MOS2_M 80
/* model paramerers */ /* model paramerers */
#define MOS2_MOD_VTO 101 #define MOS2_MOD_VTO 101

25
src/spicelib/devices/mos2/mos2dset.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury Author: 1988 Jaijeet S Roychowdhury
Modified: 2000 AlansFixes
**********/ **********/
#include <stdio.h> #include <stdio.h>
@ -82,26 +83,28 @@ double gmbds;
vt = CONSTKoverQ * here->MOS2temp; vt = CONSTKoverQ * here->MOS2temp;
EffectiveLength=here->MOS2l - 2*model->MOS2latDiff; EffectiveLength=here->MOS2l - 2*model->MOS2latDiff;
if( (here->MOS2tSatCurDens == 0) ||
if( (here->MOS2tSatCurDens == 0) ||
(here->MOS2drainArea == 0) || (here->MOS2drainArea == 0) ||
(here->MOS2sourceArea == 0)) { (here->MOS2sourceArea == 0)) {
DrainSatCur = here->MOS2tSatCur;
SourceSatCur = here->MOS2tSatCur;
DrainSatCur = here->MOS2m * here->MOS2tSatCur;
SourceSatCur = here->MOS2m * here->MOS2tSatCur;
} else { } else {
DrainSatCur = here->MOS2tSatCurDens * DrainSatCur = here->MOS2tSatCurDens *
here->MOS2drainArea;
here->MOS2m * here->MOS2drainArea;
SourceSatCur = here->MOS2tSatCurDens * SourceSatCur = here->MOS2tSatCurDens *
here->MOS2sourceArea;
here->MOS2m * here->MOS2sourceArea;
} }
GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor * GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor *
here->MOS2w;
here->MOS2m * here->MOS2w;
GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor *
here->MOS2w;
here->MOS2m * here->MOS2w;
GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor * 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 * 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); PlusDeriv(&d_cdonco,&d_cdonco,&d_dummy);
TimesDeriv(&d_cdonco,&d_cdonco,-1.0); TimesDeriv(&d_cdonco,&d_cdonco,-1.0);
d_cdonco.value += factor; 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); EqualDeriv(&d_xn,&d_cdonco);
d_xn.value = xn; d_xn.value = xn;
tmp = vt*xn; tmp = vt*xn;

4
src/spicelib/devices/mos2/mos2ext.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#ifdef __STDC__ #ifdef __STDC__
@ -27,6 +28,9 @@ extern int MOS2temp(GENmodel*,CKTcircuit*);
extern int MOS2trunc(GENmodel*,CKTcircuit*,double*); extern int MOS2trunc(GENmodel*,CKTcircuit*,double*);
extern int MOS2disto(int,GENmodel*,CKTcircuit*); extern int MOS2disto(int,GENmodel*,CKTcircuit*);
extern int MOS2noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int MOS2noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int MOS2dSetup(GENmodel*,CKTcircuit*);
#else /* stdc */ #else /* stdc */
extern int MOS2acLoad(); extern int MOS2acLoad();
extern int MOS2ask(); extern int MOS2ask();

66
src/spicelib/devices/mos2/mos2load.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 alansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -108,26 +109,28 @@ MOS2load(inModel,ckt)
} }
EffectiveLength=here->MOS2l - 2*model->MOS2latDiff; EffectiveLength=here->MOS2l - 2*model->MOS2latDiff;
if( (here->MOS2tSatCurDens == 0) || if( (here->MOS2tSatCurDens == 0) ||
(here->MOS2drainArea == 0) || (here->MOS2drainArea == 0) ||
(here->MOS2sourceArea == 0)) { (here->MOS2sourceArea == 0)) {
DrainSatCur = here->MOS2tSatCur;
SourceSatCur = here->MOS2tSatCur;
DrainSatCur = here->MOS2m * here->MOS2tSatCur;
SourceSatCur = here->MOS2m * here->MOS2tSatCur;
} else { } else {
DrainSatCur = here->MOS2tSatCurDens *
DrainSatCur = here->MOS2m * here->MOS2tSatCurDens *
here->MOS2drainArea; here->MOS2drainArea;
SourceSatCur = here->MOS2tSatCurDens *
SourceSatCur = here->MOS2m * here->MOS2tSatCurDens *
here->MOS2sourceArea; here->MOS2sourceArea;
} }
GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor * GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor *
here->MOS2w;
here->MOS2m * here->MOS2w;
GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor *
here->MOS2w;
here->MOS2m * here->MOS2w;
GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor * 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 * OxideCap = model->MOS2oxideCapFactor * EffectiveLength *
here->MOS2w;
here->MOS2m * here->MOS2w;
if(SenCond){ if(SenCond){
@ -374,24 +377,23 @@ MOS2load(inModel,ckt)
* correspoinding derivative (conductance). * 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 { } else {
evbs = exp(vbs/vt);
evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));
here->MOS2gbs = SourceSatCur*evbs/vt + ckt->CKTgmin; 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 { } 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) { if(vds >= 0) {
/* normal mode */ /* normal mode */
here->MOS2mode = 1; here->MOS2mode = 1;
@ -561,7 +563,7 @@ next1: if(vbs <= 0) {
dsrgdb = -0.5*sarg*tmp; dsrgdb = -0.5*sarg*tmp;
d2sdb2 = -dsrgdb*tmp; d2sdb2 = -dsrgdb*tmp;
} }
if ((lvds-lvbs) >= 0) {
if ((lvbs-lvds) <= 0) {
barg = sqrt(phiMinVbs+lvds); barg = sqrt(phiMinVbs+lvds);
dbrgdb = -0.5/barg; dbrgdb = -0.5/barg;
d2bdb2 = 0.5*dbrgdb/(phiMinVbs+lvds); d2bdb2 = 0.5*dbrgdb/(phiMinVbs+lvds);
@ -642,14 +644,17 @@ next1: if(vbs <= 0) {
cfs = CHARGE*model->MOS2fastSurfaceStateDensity* cfs = CHARGE*model->MOS2fastSurfaceStateDensity*
1e4 /*(cm**2/m**2)*/; 1e4 /*(cm**2/m**2)*/;
cdonco = -(gamasd*dsrgdb+dgddvb*sarg)+factor; 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; tmp = vt*xn;
von = von+tmp; von = von+tmp;
argg = 1.0/tmp; argg = 1.0/tmp;
vgst = lvgs-von; vgst = lvgs-von;
} else { } else {
vgst = lvgs-von; vgst = lvgs-von;
if (lvgs <= von) {
if (lvgs <= vbin) {
/* /*
* cutoff region * cutoff region
*/ */
@ -899,6 +904,13 @@ line610:
goto line1050; 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; if (lvgs > von) goto line900;
/* /*
* subthreshold region * subthreshold region
@ -1285,9 +1297,9 @@ bypass:
* load current vector * load current vector
*/ */
ceqbs = model->MOS2type * ceqbs = model->MOS2type *
(here->MOS2cbs-(here->MOS2gbs-ckt->CKTgmin)*vbs);
(here->MOS2cbs-(here->MOS2gbs)*vbs);
ceqbd = model->MOS2type * ceqbd = model->MOS2type *
(here->MOS2cbd-(here->MOS2gbd-ckt->CKTgmin)*vbd);
(here->MOS2cbd-(here->MOS2gbd)*vbd);
if (here->MOS2mode >= 0) { if (here->MOS2mode >= 0) {
xnrm=1; xnrm=1;
xrev=0; xrev=0;

4
src/spicelib/devices/mos2/mos2noi.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Gary W. Ng Author: 1987 Gary W. Ng
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -134,7 +135,8 @@ if (!data->namelist) return(E_NOMEM);
noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef *
exp(model->MOS2fNexp * exp(model->MOS2fNexp *
log(MAX(fabs(inst->MOS2cd),N_MINLOG))) / log(MAX(fabs(inst->MOS2cd),N_MINLOG))) /
(data->freq * inst->MOS2w *
(data->freq * inst->MOS2w *
inst->MOS2m *
(inst->MOS2l - 2*model->MOS2latDiff) * (inst->MOS2l - 2*model->MOS2latDiff) *
model->MOS2oxideCapFactor * model->MOS2oxideCapFactor); model->MOS2oxideCapFactor * model->MOS2oxideCapFactor);
lnNdens[MOS2FLNOIZ] = lnNdens[MOS2FLNOIZ] =

5
src/spicelib/devices/mos2/mos2par.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -28,6 +29,10 @@ MOS2param(param,value,inst,select)
here->MOS2temp = value->rValue+CONSTCtoK; here->MOS2temp = value->rValue+CONSTCtoK;
here->MOS2tempGiven = TRUE; here->MOS2tempGiven = TRUE;
break; break;
case MOS2_M:
here->MOS2m = value->rValue;
here->MOS2mGiven = TRUE;
break;
case MOS2_W: case MOS2_W:
here->MOS2w = value->rValue; here->MOS2w = value->rValue;
here->MOS2wGiven = TRUE; here->MOS2wGiven = TRUE;

9
src/spicelib/devices/mos2/mos2pzld.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -53,12 +54,14 @@ MOS2pzLoad(inModel,ckt,s)
* meyer's model parameters * meyer's model parameters
*/ */
EffectiveLength=here->MOS2l - 2*model->MOS2latDiff; EffectiveLength=here->MOS2l - 2*model->MOS2latDiff;
GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor * GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor *
here->MOS2w;
here->MOS2m * here->MOS2w;
GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor *
here->MOS2w;
here->MOS2m * here->MOS2w;
GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor * GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor *
EffectiveLength;
here->MOS2m * EffectiveLength;
capgs = ( 2* *(ckt->CKTstate0+here->MOS2capgs)+ capgs = ( 2* *(ckt->CKTstate0+here->MOS2capgs)+
GateSourceOverlapCap ); GateSourceOverlapCap );
capgd = ( 2* *(ckt->CKTstate0+here->MOS2capgd)+ capgd = ( 2* *(ckt->CKTstate0+here->MOS2capgd)+

26
src/spicelib/devices/mos2/mos2set.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -124,7 +125,10 @@ MOS2setup(matrix,inModel,ckt,states)
/* loop through all the instances of the model */ /* loop through all the instances of the model */
for (here = model->MOS2instances; here != NULL ; for (here = model->MOS2instances; here != NULL ;
here=here->MOS2nextInstance) { here=here->MOS2nextInstance) {
CKTnode *tmpNode;
IFuid tmpName;
if (here->MOS2owner == ARCHme) { if (here->MOS2owner == ARCHme) {
/* allocate a chunk of the state vector */ /* allocate a chunk of the state vector */
here->MOS2states = *states; here->MOS2states = *states;
@ -165,6 +169,16 @@ MOS2setup(matrix,inModel,ckt,states)
error = CKTmkVolt(ckt,&tmp,here->MOS2name,"internal#drain"); error = CKTmkVolt(ckt,&tmp,here->MOS2name,"internal#drain");
if(error) return(error); if(error) return(error);
here->MOS2dNodePrime = tmp->number; 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 { } else {
here->MOS2dNodePrime = here->MOS2dNode; here->MOS2dNodePrime = here->MOS2dNode;
} }
@ -176,6 +190,16 @@ MOS2setup(matrix,inModel,ckt,states)
error = CKTmkVolt(ckt,&tmp,here->MOS2name,"internal#source"); error = CKTmkVolt(ckt,&tmp,here->MOS2name,"internal#source");
if(error) return(error); if(error) return(error);
here->MOS2sNodePrime = tmp->number; 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 { } else {
here->MOS2sNodePrime = here->MOS2sNode; here->MOS2sNodePrime = here->MOS2sNode;
} }

5
src/spicelib/devices/mos2/mos2sprt.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -22,7 +23,7 @@ MOS2sPrint(inModel,ckt)
MOS2model *model = (MOS2model *)inModel; MOS2model *model = (MOS2model *)inModel;
MOS2instance *here; MOS2instance *here;
printf("LEVEL 1 MOSFETS-----------------\n");
printf("LEVEL 2 MOSFETS-----------------\n");
/* loop through all the MOS2 models */ /* loop through all the MOS2 models */
for( ; model != NULL; model = model->MOS2nextModel ) { for( ; model != NULL; model = model->MOS2nextModel ) {
@ -38,6 +39,8 @@ MOS2sPrint(inModel,ckt)
CKTnodName(ckt,here->MOS2dNode),CKTnodName(ckt,here->MOS2gNode), CKTnodName(ckt,here->MOS2dNode),CKTnodName(ckt,here->MOS2gNode),
CKTnodName(ckt,here->MOS2sNode)); CKTnodName(ckt,here->MOS2sNode));
printf(" Multiplier: %g ",here->MOS2m);
printf(here->MOS2mGiven ? "(specified)\n" : "(default)\n");
printf(" Length: %g ",here->MOS2l); printf(" Length: %g ",here->MOS2l);
printf(here->MOS2lGiven ? "(specified)\n" : "(default)\n"); printf(here->MOS2lGiven ? "(specified)\n" : "(default)\n");
printf(" Width: %g ",here->MOS2w); printf(" Width: %g ",here->MOS2w);

40
src/spicelib/devices/mos2/mos2temp.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -147,6 +148,9 @@ MOS2temp(inModel,ckt)
if(!here->MOS2drainAreaGiven) { if(!here->MOS2drainAreaGiven) {
here->MOS2drainArea = ckt->CKTdefaultMosAD; here->MOS2drainArea = ckt->CKTdefaultMosAD;
}
if(!here->MOS2mGiven) {
here->MOS2m = ckt->CKTdefaultMosM;
} }
if(!here->MOS2lGiven) { if(!here->MOS2lGiven) {
here->MOS2l = ckt->CKTdefaultMosL; here->MOS2l = ckt->CKTdefaultMosL;
@ -159,14 +163,17 @@ MOS2temp(inModel,ckt)
} }
if(model->MOS2drainResistanceGiven) { if(model->MOS2drainResistanceGiven) {
if(model->MOS2drainResistance != 0) { if(model->MOS2drainResistance != 0) {
here->MOS2drainConductance = 1/model->MOS2drainResistance;
here->MOS2drainConductance = here->MOS2m /
model->MOS2drainResistance;
} else { } else {
here->MOS2drainConductance = 0; here->MOS2drainConductance = 0;
} }
} else if (model->MOS2sheetResistanceGiven) { } else if (model->MOS2sheetResistanceGiven) {
if(model->MOS2sheetResistance != 0) {
if((model->MOS2sheetResistance != 0) &&
(here->MOS2drainSquares != 0)) {
here->MOS2drainConductance = here->MOS2drainConductance =
1/(model->MOS2sheetResistance*here->MOS2drainSquares);
here->MOS2m /
(model->MOS2sheetResistance*here->MOS2drainSquares);
} else { } else {
here->MOS2drainConductance = 0; here->MOS2drainConductance = 0;
} }
@ -175,14 +182,17 @@ MOS2temp(inModel,ckt)
} }
if(model->MOS2sourceResistanceGiven) { if(model->MOS2sourceResistanceGiven) {
if(model->MOS2sourceResistance != 0) { if(model->MOS2sourceResistance != 0) {
here->MOS2sourceConductance = 1/model->MOS2sourceResistance;
here->MOS2sourceConductance = here->MOS2m /
model->MOS2sourceResistance;
} else { } else {
here->MOS2sourceConductance = 0; here->MOS2sourceConductance = 0;
} }
} else if (model->MOS2sheetResistanceGiven) { } else if (model->MOS2sheetResistanceGiven) {
if(model->MOS2sheetResistance != 0) {
if ((model->MOS2sheetResistance != 0) &&
(here->MOS2sourceSquares != 0)) {
here->MOS2sourceConductance = here->MOS2sourceConductance =
1/(model->MOS2sheetResistance*here->MOS2sourceSquares);
here->MOS2m /
(model->MOS2sheetResistance*here->MOS2sourceSquares);
} else { } else {
here->MOS2sourceConductance = 0; here->MOS2sourceConductance = 0;
} }
@ -238,26 +248,29 @@ MOS2temp(inModel,ckt)
(here->MOS2drainArea == 0) || (here->MOS2drainArea == 0) ||
(here->MOS2sourceArea == 0) ) { (here->MOS2sourceArea == 0) ) {
here->MOS2sourceVcrit = here->MOS2drainVcrit = here->MOS2sourceVcrit = here->MOS2drainVcrit =
vt*log(vt/(CONSTroot2*here->MOS2tSatCur));
vt*log(vt/(CONSTroot2*here->MOS2m*here->MOS2tSatCur));
} else { } else {
here->MOS2drainVcrit = here->MOS2drainVcrit =
vt * log( vt / (CONSTroot2 * vt * log( vt / (CONSTroot2 *
here->MOS2m *
here->MOS2tSatCurDens * here->MOS2drainArea)); here->MOS2tSatCurDens * here->MOS2drainArea));
here->MOS2sourceVcrit = here->MOS2sourceVcrit =
vt * log( vt / (CONSTroot2 * vt * log( vt / (CONSTroot2 *
here->MOS2m *
here->MOS2tSatCurDens * here->MOS2sourceArea)); here->MOS2tSatCurDens * here->MOS2sourceArea));
} }
if(model->MOS2capBDGiven) { if(model->MOS2capBDGiven) {
czbd = here->MOS2tCbd;
czbd = here->MOS2tCbd * here->MOS2m;
} else { } else {
if(model->MOS2bulkCapFactorGiven) { if(model->MOS2bulkCapFactorGiven) {
czbd=here->MOS2tCj*here->MOS2drainArea;
czbd=here->MOS2tCj*here->MOS2drainArea * here->MOS2m;
} else { } else {
czbd=0; czbd=0;
} }
} }
if(model->MOS2sideWallCapFactorGiven) { if(model->MOS2sideWallCapFactorGiven) {
czbdsw= here->MOS2tCjsw * here->MOS2drainPerimiter;
czbdsw= here->MOS2tCjsw * here->MOS2drainPerimiter *
here->MOS2m;;
} else { } else {
czbdsw=0; czbdsw=0;
} }
@ -283,16 +296,17 @@ MOS2temp(inModel,ckt)
(here->MOS2tDepCap*here->MOS2tDepCap) (here->MOS2tDepCap*here->MOS2tDepCap)
-here->MOS2tDepCap * here->MOS2f2d; -here->MOS2tDepCap * here->MOS2f2d;
if(model->MOS2capBSGiven) { if(model->MOS2capBSGiven) {
czbs=here->MOS2tCbs;
czbs=here->MOS2tCbs * here->MOS2m;
} else { } else {
if(model->MOS2bulkCapFactorGiven) { if(model->MOS2bulkCapFactorGiven) {
czbs=here->MOS2tCj*here->MOS2sourceArea;
czbs=here->MOS2tCj*here->MOS2sourceArea * here->MOS2m;
} else { } else {
czbs=0; czbs=0;
} }
} }
if(model->MOS2sideWallCapFactorGiven) { if(model->MOS2sideWallCapFactorGiven) {
czbssw = here->MOS2tCjsw * here->MOS2sourcePerimiter;
czbssw = here->MOS2tCjsw * here->MOS2sourcePerimiter *
here->MOS2m;
} else { } else {
czbssw=0; czbssw=0;
} }

7
src/spicelib/devices/mos3/mos3.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Thomas L. Quarles Author: 1987 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -11,6 +12,7 @@ Author: 1987 Thomas L. Quarles
#include "suffix.h" #include "suffix.h"
IFparm MOS3pTable[] = { /* parameters */ IFparm MOS3pTable[] = { /* parameters */
IOPU("m", MOS3_M, IF_REAL , "Multiplier"),
IOPU("l", MOS3_L, IF_REAL , "Length"), IOPU("l", MOS3_L, IF_REAL , "Length"),
IOPU("w", MOS3_W, IF_REAL , "Width"), IOPU("w", MOS3_W, IF_REAL , "Width"),
IOPU("ad", MOS3_AD, IF_REAL , "Drain area"), 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"), IOPU("js", MOS3_MOD_JS, IF_REAL ,"Bulk jct. sat. current density"),
IOP("tox", MOS3_MOD_TOX, IF_REAL ,"Oxide thickness"), IOP("tox", MOS3_MOD_TOX, IF_REAL ,"Oxide thickness"),
IOP("ld", MOS3_MOD_LD, IF_REAL ,"Lateral diffusion"), 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"), IOP("u0", MOS3_MOD_U0, IF_REAL ,"Surface mobility"),
IOPR("uo", 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."), IOP("fc", MOS3_MOD_FC, IF_REAL ,"Forward bias jct. fit parm."),

14
src/spicelib/devices/mos3/mos3acld.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -23,6 +24,7 @@ MOS3acLoad(inModel,ckt)
int xnrm; int xnrm;
int xrev; int xrev;
double EffectiveLength; double EffectiveLength;
double EffectiveWidth;
double xgs; double xgs;
double xgd; double xgd;
double xgb; double xgb;
@ -50,13 +52,17 @@ MOS3acLoad(inModel,ckt)
/* /*
* charge oriented model parameters * 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 * GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor *
here->MOS3w;
here->MOS3m * EffectiveWidth;
GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor *
here->MOS3w;
here->MOS3m * EffectiveWidth;
GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor * GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor *
EffectiveLength;
here->MOS3m * EffectiveLength;
/* /*
* meyer"s model parameters * meyer"s model parameters
*/ */

32
src/spicelib/devices/mos3/mos3ask.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Mathew Lew and Thomas L. Quarles Author: 1987 Mathew Lew and Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -34,10 +35,13 @@ MOS3ask(ckt,inst,which,value,select)
value->rValue = here->MOS3temp-CONSTCtoK; value->rValue = here->MOS3temp-CONSTCtoK;
return(OK); return(OK);
case MOS3_CGS: case MOS3_CGS:
value->rValue = *(ckt->CKTstate0 + here->MOS3capgs);
value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgs);
return(OK); return(OK);
case MOS3_CGD: 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); return(OK);
case MOS3_L: case MOS3_L:
value->rValue = here->MOS3l; value->rValue = here->MOS3l;
@ -178,7 +182,13 @@ MOS3ask(ckt,inst,which,value,select)
value->rValue = *(ckt->CKTstate0 + here->MOS3vds); value->rValue = *(ckt->CKTstate0 + here->MOS3vds);
return(OK); return(OK);
case MOS3_CAPGS: 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); return(OK);
case MOS3_QGS: case MOS3_QGS:
value->rValue = *(ckt->CKTstate0 + here->MOS3qgs); value->rValue = *(ckt->CKTstate0 + here->MOS3qgs);
@ -187,7 +197,13 @@ MOS3ask(ckt,inst,which,value,select)
value->rValue = *(ckt->CKTstate0 + here->MOS3cqgs); value->rValue = *(ckt->CKTstate0 + here->MOS3cqgs);
return(OK); return(OK);
case MOS3_CAPGD: 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); return(OK);
case MOS3_QGD: case MOS3_QGD:
value->rValue = *(ckt->CKTstate0 + here->MOS3qgd); value->rValue = *(ckt->CKTstate0 + here->MOS3qgd);
@ -196,7 +212,13 @@ MOS3ask(ckt,inst,which,value,select)
value->rValue = *(ckt->CKTstate0 + here->MOS3cqgd); value->rValue = *(ckt->CKTstate0 + here->MOS3cqgd);
return(OK); return(OK);
case MOS3_CAPGB: 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); return(OK);
case MOS3_QGB: case MOS3_QGB:
value->rValue = *(ckt->CKTstate0 + here->MOS3qgb); value->rValue = *(ckt->CKTstate0 + here->MOS3qgb);

17
src/spicelib/devices/mos3/mos3defs.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlanFixes
**********/ **********/
#ifndef MOS3 #ifndef MOS3
@ -30,6 +31,7 @@ typedef struct sMOS3instance {
int MOS3dNodePrime; /* number of the internal drain node of the mosfet */ int MOS3dNodePrime; /* number of the internal drain node of the mosfet */
int MOS3sNodePrime; /* number of the internal source 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 MOS3l; /* the length of the channel region */
double MOS3w; /* the width of the channel region */ double MOS3w; /* the width of the channel region */
double MOS3drainArea; /* the area of the drain diffusion */ 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 MOS3off :1;/* non-zero to indicate device is off for dc analysis*/
unsigned MOS3tempGiven :1; /* instance temperature specified */ unsigned MOS3tempGiven :1; /* instance temperature specified */
unsigned MOS3mGiven :1;
unsigned MOS3lGiven :1; unsigned MOS3lGiven :1;
unsigned MOS3wGiven :1; unsigned MOS3wGiven :1;
unsigned MOS3drainAreaGiven :1; unsigned MOS3drainAreaGiven :1;
@ -321,6 +324,10 @@ typedef struct sMOS3model { /* model structure for a resistor */
int MOS3type; /* device type : 1 = nmos, -1 = pmos */ int MOS3type; /* device type : 1 = nmos, -1 = pmos */
double MOS3tnom; /* temperature at which parameters measured */ double MOS3tnom; /* temperature at which parameters measured */
double MOS3latDiff; 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 MOS3jctSatCurDensity; /* input - use tSatCurDens*/
double MOS3jctSatCur; /* input - use tSatCur instead */ double MOS3jctSatCur; /* input - use tSatCur instead */
double MOS3drainResistance; double MOS3drainResistance;
@ -362,6 +369,10 @@ typedef struct sMOS3model { /* model structure for a resistor */
unsigned MOS3typeGiven :1; unsigned MOS3typeGiven :1;
unsigned MOS3latDiffGiven :1; unsigned MOS3latDiffGiven :1;
unsigned MOS3lengthAdjustGiven :1;
unsigned MOS3widthNarrowGiven :1;
unsigned MOS3widthAdjustGiven :1;
unsigned MOS3delvt0Given :1;
unsigned MOS3jctSatCurDensityGiven :1; unsigned MOS3jctSatCurDensityGiven :1;
unsigned MOS3jctSatCurGiven :1; unsigned MOS3jctSatCurGiven :1;
unsigned MOS3drainResistanceGiven :1; unsigned MOS3drainResistanceGiven :1;
@ -485,6 +496,7 @@ typedef struct sMOS3model { /* model structure for a resistor */
#define MOS3_TEMP 77 #define MOS3_TEMP 77
#define MOS3_SOURCERESIST 78 #define MOS3_SOURCERESIST 78
#define MOS3_DRAINRESIST 79 #define MOS3_DRAINRESIST 79
#define MOS3_M 80
/* model parameters */ /* model parameters */
#define MOS3_MOD_VTO 101 #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_AF 143
#define MOS3_MOD_TYPE 144 #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 */ /* device questions */

39
src/spicelib/devices/mos3/mos3dset.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury Author: 1988 Jaijeet S Roychowdhury
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -27,6 +28,7 @@ MOS3dSetup(inModel,ckt)
double Beta; double Beta;
double DrainSatCur; double DrainSatCur;
double EffectiveLength; double EffectiveLength;
double EffectiveWidth;
double GateBulkOverlapCap; double GateBulkOverlapCap;
double GateDrainOverlapCap; double GateDrainOverlapCap;
double GateSourceOverlapCap; double GateSourceOverlapCap;
@ -76,29 +78,32 @@ MOS3dSetup(inModel,ckt)
* here. They may be moved at the expense of instance size * 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) || if( (here->MOS3tSatCurDens == 0) ||
(here->MOS3drainArea == 0) || (here->MOS3drainArea == 0) ||
(here->MOS3sourceArea == 0)) { (here->MOS3sourceArea == 0)) {
DrainSatCur = here->MOS3tSatCur;
SourceSatCur = here->MOS3tSatCur;
DrainSatCur = here->MOS3m * here->MOS3tSatCur;
SourceSatCur = here->MOS3m * here->MOS3tSatCur;
} else { } else {
DrainSatCur = here->MOS3tSatCurDens * DrainSatCur = here->MOS3tSatCurDens *
here->MOS3drainArea;
here->MOS3m * here->MOS3drainArea;
SourceSatCur = here->MOS3tSatCurDens * SourceSatCur = here->MOS3tSatCurDens *
here->MOS3sourceArea;
here->MOS3m * here->MOS3sourceArea;
} }
GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor * GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor *
here->MOS3w;
here->MOS3m * EffectiveWidth;
GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor *
here->MOS3w;
here->MOS3m * EffectiveWidth;
GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor * GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor *
EffectiveLength;
Beta = here->MOS3tTransconductance * here->MOS3w/EffectiveLength;
here->MOS3m * EffectiveLength;
Beta = here->MOS3tTransconductance * here->MOS3m *
EffectiveWidth/EffectiveLength;
OxideCap = model->MOS3oxideCapFactor * EffectiveLength * OxideCap = model->MOS3oxideCapFactor * EffectiveLength *
here->MOS3w;
here->MOS3m * EffectiveWidth;
/* /*
* ok - now to do the start-up operations * ok - now to do the start-up operations
@ -381,7 +386,7 @@ d_p.d3_pqr = 0.0;
fbodys = 0.5*gammas/(sqphbs+sqphbs); fbodys = 0.5*gammas/(sqphbs+sqphbs);
DivDeriv(&d_fbodys,&d_gammas,&d_sqphbs); DivDeriv(&d_fbodys,&d_gammas,&d_sqphbs);
TimesDeriv(&d_fbodys,&d_fbodys,0.25); TimesDeriv(&d_fbodys,&d_fbodys,0.25);
fbody = fbodys+model->MOS3narrowFactor/here->MOS3w;
fbody = fbodys+model->MOS3narrowFactor/EffectiveWidth;
EqualDeriv(&d_fbody,&d_fbodys); EqualDeriv(&d_fbody,&d_fbodys);
d_fbody.value += fbody - fbodys; d_fbody.value += fbody - fbodys;
@ -389,9 +394,10 @@ d_p.d3_pqr = 0.0;
EqualDeriv(&d_onfbdy,&d_fbody); EqualDeriv(&d_onfbdy,&d_fbody);
d_onfbdy.value += 1.0; d_onfbdy.value += 1.0;
InvDeriv(&d_onfbdy,&d_onfbdy); 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); 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); MultDeriv(&d_qbonco,&d_gammas,&d_sqphbs);
PlusDeriv(&d_qbonco,&d_qbonco,&d_dummy); PlusDeriv(&d_qbonco,&d_qbonco,&d_dummy);
/* /*
@ -412,7 +418,8 @@ d_p.d3_pqr = 0.0;
EqualDeriv(&d_von,&d_vth); EqualDeriv(&d_von,&d_vth);
if ( model->MOS3fastSurfaceStateDensity != 0.0 ) { if ( model->MOS3fastSurfaceStateDensity != 0.0 ) {
csonco = CHARGE*model->MOS3fastSurfaceStateDensity * 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; cdonco = 0.5*qbonco/phibs;
DivDeriv(&d_cdonco,&d_qbonco,&d_phibs); DivDeriv(&d_cdonco,&d_qbonco,&d_phibs);
TimesDeriv(&d_cdonco,&d_cdonco,0.5); TimesDeriv(&d_cdonco,&d_cdonco,0.5);

2
src/spicelib/devices/mos3/mos3ext.h

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#ifdef __STDC__ #ifdef __STDC__
@ -27,6 +28,7 @@ extern int MOS3temp(GENmodel*,CKTcircuit*);
extern int MOS3trunc(GENmodel*,CKTcircuit*,double*); extern int MOS3trunc(GENmodel*,CKTcircuit*,double*);
extern int MOS3disto(int,GENmodel*,CKTcircuit*); extern int MOS3disto(int,GENmodel*,CKTcircuit*);
extern int MOS3noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int MOS3noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int MOS3dSetup(GENmodel*,CKTcircuit*);
#else /* stdc */ #else /* stdc */
extern int MOS3acLoad(); extern int MOS3acLoad();
extern int MOS3ask(); extern int MOS3ask();

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

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
#include "ngspice.h" #include "ngspice.h"
@ -26,6 +27,7 @@ MOS3load(inModel,ckt)
double Beta; double Beta;
double DrainSatCur; double DrainSatCur;
double EffectiveLength; double EffectiveLength;
double EffectiveWidth;
double GateBulkOverlapCap; double GateBulkOverlapCap;
double GateDrainOverlapCap; double GateDrainOverlapCap;
double GateSourceOverlapCap; double GateSourceOverlapCap;
@ -117,28 +119,33 @@ next:
* here. They may be moved at the expense of instance size * 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->MOS3drainArea == 0) ||
(here->MOS3sourceArea == 0)) { (here->MOS3sourceArea == 0)) {
DrainSatCur = here->MOS3tSatCur;
SourceSatCur = here->MOS3tSatCur;
DrainSatCur = here->MOS3m * here->MOS3tSatCur;
SourceSatCur = here->MOS3m * here->MOS3tSatCur;
} else { } else {
DrainSatCur = here->MOS3tSatCurDens *
DrainSatCur = here->MOS3m * here->MOS3tSatCurDens *
here->MOS3drainArea; here->MOS3drainArea;
SourceSatCur = here->MOS3tSatCurDens *
SourceSatCur = here->MOS3m * here->MOS3tSatCurDens *
here->MOS3sourceArea; here->MOS3sourceArea;
} }
GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor * GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor *
here->MOS3w;
here->MOS3m * EffectiveWidth;
GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor * GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor *
here->MOS3w;
here->MOS3m * EffectiveWidth;
GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor * GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor *
EffectiveLength;
Beta = here->MOS3tTransconductance * here->MOS3w/EffectiveLength;
here->MOS3m * EffectiveLength;
Beta = here->MOS3tTransconductance *
here->MOS3m * EffectiveWidth/EffectiveLength;
OxideCap = model->MOS3oxideCapFactor * EffectiveLength * OxideCap = model->MOS3oxideCapFactor * EffectiveLength *
here->MOS3w;
here->MOS3m * EffectiveWidth;
if(SenCond){ if(SenCond){
#ifdef SENSDEBUG #ifdef SENSDEBUG
printf("MOS3senPertFlag = ON \n"); printf("MOS3senPertFlag = ON \n");
@ -395,23 +402,26 @@ next:
* here we just evaluate the ideal diode current and the * here we just evaluate the ideal diode current and the
* corresponding derivative (conductance). * 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 { } else {
evbs = exp(MIN(MAX_EXP_ARG,vbs/vt)); evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));
here->MOS3gbs = SourceSatCur*evbs/vt + ckt->CKTgmin; 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 { } else {
evbd = exp(MIN(MAX_EXP_ARG,vbd/vt)); 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 /* now to determine whether the user was able to correctly
@ -600,12 +610,12 @@ next1: if(vbs <= 0) {
*/ */
gammas = model->MOS3gamma*fshort; gammas = model->MOS3gamma*fshort;
fbodys = 0.5*gammas/(sqphbs+sqphbs); fbodys = 0.5*gammas/(sqphbs+sqphbs);
fbody = fbodys+model->MOS3narrowFactor/here->MOS3w;
fbody = fbodys+model->MOS3narrowFactor/EffectiveWidth;
onfbdy = 1.0/(1.0+fbody); onfbdy = 1.0/(1.0+fbody);
dfbdvb = -fbodys*dsqdvb/sqphbs+fbodys*dfsdvb/fshort; 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- dqbdvb = gammas*dsqdvb+model->MOS3gamma*dfsdvb*sqphbs-
model->MOS3narrowFactor/here->MOS3w;
model->MOS3narrowFactor/EffectiveWidth;
/* /*
*.....static feedback effect *.....static feedback effect
*/ */
@ -622,7 +632,8 @@ next1: if(vbs <= 0) {
von = vth; von = vth;
if ( model->MOS3fastSurfaceStateDensity != 0.0 ) { if ( model->MOS3fastSurfaceStateDensity != 0.0 ) {
csonco = CHARGE*model->MOS3fastSurfaceStateDensity * 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); cdonco = qbonco/(phibs+phibs);
xn = 1.0+csonco+cdonco; xn = 1.0+csonco+cdonco;
von = vth+vt*xn; von = vth+vt*xn;
@ -685,7 +696,8 @@ next1: if(vbs <= 0) {
*/ */
cdnorm = cdo*vdsx; cdnorm = cdo*vdsx;
here->MOS3gm = 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; here->MOS3gmbs = dcodvb*vdsx;
/* /*
*.....drain current without velocity saturation effect *.....drain current without velocity saturation effect
@ -695,16 +707,17 @@ next1: if(vbs <= 0) {
cdrain = Beta*cdnorm; cdrain = Beta*cdnorm;
here->MOS3gm = Beta*here->MOS3gm+dfgdvg*cd1; here->MOS3gm = Beta*here->MOS3gm+dfgdvg*cd1;
here->MOS3gds = Beta*here->MOS3gds+dfgdvd*cd1; here->MOS3gds = Beta*here->MOS3gds+dfgdvd*cd1;
here->MOS3gmbs = Beta*here->MOS3gmbs;
here->MOS3gmbs = Beta*here->MOS3gmbs+dfgdvb*cd1;
/* /*
*.....velocity saturation factor *.....velocity saturation factor
*/ */
if ( model->MOS3maxDriftVel != 0.0 ) {
if ( model->MOS3maxDriftVel > 0.0 ) {
fdrain = 1.0/(1.0+vdsx*onvdsc); fdrain = 1.0/(1.0+vdsx*onvdsc);
fd2 = fdrain*fdrain; fd2 = fdrain*fdrain;
arga = fd2*vdsx*onvdsc*onfg; arga = fd2*vdsx*onvdsc*onfg;
dfddvg = -dfgdvg*arga; 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; dfddvb = -dfgdvb*arga;
/* /*
*.....drain current *.....drain current
@ -718,7 +731,24 @@ next1: if(vbs <= 0) {
/* /*
*.....channel length modulation *.....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->MOS3maxDriftVel <= 0.0 ) goto line510;
if (model->MOS3alpha == 0.0) goto line700; if (model->MOS3alpha == 0.0) goto line700;
cdsat = cdrain; cdsat = cdrain;
@ -757,9 +787,15 @@ next1: if(vbs <= 0) {
ddldvb = dldem*demdvb; ddldvb = dldem*demdvb;
goto line520; goto line520;
line510: 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; ddldvg = 0.0;
ddldvd = -dldvd; ddldvd = -dldvd;
ddldvb = 0.0; ddldvb = 0.0;
@ -782,14 +818,19 @@ line520:
*/ */
dlonxl = delxl*oneoverxl; dlonxl = delxl*oneoverxl;
xlfact = 1.0/(1.0-dlonxl); xlfact = 1.0/(1.0-dlonxl);
cd1 = cdrain;
cdrain = cdrain*xlfact; cdrain = cdrain*xlfact;
diddl = cdrain/(EffectiveLength-delxl); diddl = cdrain/(EffectiveLength-delxl);
here->MOS3gm = here->MOS3gm*xlfact+diddl*ddldvg; here->MOS3gm = here->MOS3gm*xlfact+diddl*ddldvg;
gds0 = here->MOS3gds*xlfact+diddl*ddldvd;
here->MOS3gmbs = here->MOS3gmbs*xlfact+diddl*ddldvb; here->MOS3gmbs = here->MOS3gmbs*xlfact+diddl*ddldvb;
gds0 = diddl*ddldvd;
here->MOS3gm = here->MOS3gm+gds0*dvsdvg; here->MOS3gm = here->MOS3gm+gds0*dvsdvg;
here->MOS3gmbs = here->MOS3gmbs+gds0*dvsdvb; 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 *.....finish strong inversion case
*/ */
@ -1162,9 +1203,9 @@ bypass:
* load current vector * load current vector
*/ */
ceqbs = model->MOS3type * ceqbs = model->MOS3type *
(here->MOS3cbs-(here->MOS3gbs-ckt->CKTgmin)*vbs);
(here->MOS3cbs-(here->MOS3gbs)*vbs);
ceqbd = model->MOS3type * ceqbd = model->MOS3type *
(here->MOS3cbd-(here->MOS3gbd-ckt->CKTgmin)*vbd);
(here->MOS3cbd-(here->MOS3gbd)*vbd);
if (here->MOS3mode >= 0) { if (here->MOS3mode >= 0) {
xnrm=1; xnrm=1;
xrev=0; xrev=0;

19
src/spicelib/devices/mos3/mos3mask.c

@ -1,6 +1,7 @@
/********** /**********
Copyright 1990 Regents of the University of California. All rights reserved. Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Thomas L. Quarles Author: 1987 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/ **********/
/* /*
*/ */
@ -89,6 +90,18 @@ MOS3mAsk(ckt,inst,which,value)
case MOS3_MOD_LD: case MOS3_MOD_LD:
value->rValue = here->MOS3latDiff; value->rValue = here->MOS3latDiff;
return(OK); 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: case MOS3_MOD_RSH:
value->rValue = here->MOS3sheetResistance; value->rValue = here->MOS3sheetResistance;
return(OK); return(OK);
@ -136,7 +149,13 @@ MOS3mAsk(ckt,inst,which,value)
return(OK); return(OK);
case MOS3_MOD_KAPPA: case MOS3_MOD_KAPPA:
value->rValue = here->MOS3kappa; value->rValue = here->MOS3kappa;
return(OK);
case MOS3_MOD_KF:
value->rValue = here->MOS3fNcoef;
return(OK); return(OK);
case MOS3_MOD_AF:
value->rValue = here->MOS3fNexp;
return(OK);
case MOS3_MOD_TYPE: case MOS3_MOD_TYPE:
if (here->MOS3type > 0) if (here->MOS3type > 0)
value->sValue = "nmos"; value->sValue = "nmos";

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save