From aafd7bbb42076612e087664a3c5b95299b1bc81c Mon Sep 17 00:00:00 2001 From: dwarning Date: Sun, 21 Jan 2024 21:58:43 +0100 Subject: [PATCH 01/20] correct bartlett/triangle fft window formulae --- src/frontend/spec.c | 2 +- src/maths/fft/fftext.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/spec.c b/src/frontend/spec.c index 8e5d2c108..c6a6e33f0 100644 --- a/src/frontend/spec.c +++ b/src/frontend/spec.c @@ -122,7 +122,7 @@ com_spec(wordlist *wl) if (maxt-time[i] > span) { win[i] = 0; } else { - win[i] = 2 - fabs(2+4*(time[i]-maxt)/span); + win[i] = 1 - 2 * fabs((time[i]-maxt)-span/2) / span; } } else if (eq(window, "blackman")) { diff --git a/src/maths/fft/fftext.c b/src/maths/fft/fftext.c index 6dc6400e8..802cab8bd 100644 --- a/src/maths/fft/fftext.c +++ b/src/maths/fft/fftext.c @@ -115,7 +115,7 @@ fft_windows(char *window, double *win, double *time, int length, double maxt, do if (maxt-time[i] > span) win[i] = 0.0; else - win[i] = 2.0 - fabs(2+4*(time[i]-maxt)/span); + win[i] = 1.0 - 2.0 * fabs((time[i]-maxt)-span/2) / span; } else if (eq(window, "hann") || eq(window, "hanning") || eq(window, "cosine")) for (i = 0; i < length; i++) { From 9e41383dd9313806b7d9fb36816795551d72b7a0 Mon Sep 17 00:00:00 2001 From: dwarning Date: Mon, 22 Jan 2024 17:37:27 +0100 Subject: [PATCH 02/20] window weightings between 0 and 1 for fft vector function and command --- src/maths/fft/fftext.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/maths/fft/fftext.c b/src/maths/fft/fftext.c index 802cab8bd..b5695ce62 100644 --- a/src/maths/fft/fftext.c +++ b/src/maths/fft/fftext.c @@ -114,31 +114,33 @@ fft_windows(char *window, double *win, double *time, int length, double maxt, do for (i = 0; i < length; i++) { if (maxt-time[i] > span) win[i] = 0.0; + else if (maxt-time[i] < span/2) + win[i] = 2 * (maxt-time[i]) / span; else - win[i] = 1.0 - 2.0 * fabs((time[i]-maxt)-span/2) / span; + win[i] = 2.0 - 2 * (maxt-time[i]) / span; } else if (eq(window, "hann") || eq(window, "hanning") || eq(window, "cosine")) for (i = 0; i < length; i++) { if (maxt-time[i] > span) win[i] = 0.0; else - win[i] = 1.0 - cos(2*M_PI*(time[i]-maxt)/span); + win[i] = 0.5 - 0.5*cos(2*M_PI*(time[i]-maxt)/span); } else if (eq(window, "hamming")) for (i = 0; i < length; i++) { if (maxt-time[i] > span) win[i] = 0.0; else - win[i] = 1.0 - 0.46/0.54*cos(2*M_PI*(time[i]-maxt)/span); + win[i] = 0.54 - 0.46*cos(2*M_PI*(time[i]-maxt)/span); } else if (eq(window, "blackman")) for (i = 0; i < length; i++) { if (maxt-time[i] > span) { win[i] = 0; } else { - win[i] = 1.0; - win[i] -= 0.50/0.42*cos(2*M_PI*(time[i]-maxt)/span); - win[i] += 0.08/0.42*cos(4*M_PI*(time[i]-maxt)/span); + win[i] = 0.42; + win[i] -= 0.50*cos(2*M_PI*(time[i]-maxt)/span); + win[i] += 0.08*cos(4*M_PI*(time[i]-maxt)/span); } } else if (eq(window, "flattop")) @@ -146,16 +148,16 @@ fft_windows(char *window, double *win, double *time, int length, double maxt, do if (maxt-time[i] > span) { win[i] = 0; } else { - win[i] = 1.0; - win[i] -= 1.93*cos(2*M_PI*(time[i]-maxt)/span); - win[i] += 1.29*cos(4*M_PI*(time[i]-maxt)/span); - win[i] -= 0.388*cos(6*M_PI*(time[i]-maxt)/span); - win[i] += 0.032*cos(8*M_PI*(time[i]-maxt)/span); + win[i] = 0.21557895; + win[i] -= 0.41663158*cos(2*M_PI*(time[i]-maxt)/span); + win[i] += 0.277263158*cos(4*M_PI*(time[i]-maxt)/span); + win[i] -= 0.083578947*cos(6*M_PI*(time[i]-maxt)/span); + win[i] += 0.006947368*cos(8*M_PI*(time[i]-maxt)/span); } } else if (eq(window, "gaussian")) { sigma = 1.0/order; - scale = 0.83/sigma; + scale = 0.5/sigma; for (i = 0; i < length; i++) { if (maxt-time[i] > span) win[i] = 0; From d92569742f1efcd03bfcc15c753e66384006106c Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 24 Jan 2024 10:11:44 +0100 Subject: [PATCH 03/20] Add a transformer with parameters on the .subckt line --- examples/various/transformers1.cir | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/examples/various/transformers1.cir b/examples/various/transformers1.cir index 552be7550..cf26601b4 100644 --- a/examples/various/transformers1.cir +++ b/examples/various/transformers1.cir @@ -6,6 +6,8 @@ V1 1 0 dc 0 ac 1 sin (0 1 1k) Xtr1 1 0 2 0 tr1 +Xtr1a 1 0 32 0 tr1a psr=1m ssr=1m lp=1m ls=4m kt=0.98 + Xtr2 1 0 12 0 tr2 Xtr3 1 0 22 0 tr3 @@ -22,6 +24,16 @@ Xtr3 1 0 22 0 tr3 K1 L1 L2 0.98 ; coupling constant .ends +* transformer 1a +* ngspice manual 3.3.10, with parameters replacing fixed values +.subckt tr1a p1 p2 s1 s2 psr=1m ssr=1m lp=100u ls=100u kt=1 + Rp1 p1 pint1 {psr} ; primary series resistance + Rs1 s1 sint1 {ssr} ; secondary series resistance + L1 pint1 p2 {lp} ; primary inductance + L2 sint1 s2 {ls} ; secondary inductance + K1 L1 L2 {kt} ; coupling constant +.ends + * transformer 2 * ngspice manual 12.2.20 and 12.2.21 * px primary nodes, sx secondary nodes of electric circuit @@ -53,7 +65,7 @@ Xtr3 1 0 22 0 tr3 .control run set xbrushwidth=2 -plot V(1) v(2) V(1)+5 V(12)+5 V(1)+10 V(22)+10 +plot V(1) v(2) V(1)+5 V(12)+5 V(1)+10 V(22)+10 V(1)+15 V(32)+15 .endc .end From 8aa20cfc982d13d555e99c04d1ffc23cd2dfdd7b Mon Sep 17 00:00:00 2001 From: dwarning Date: Wed, 24 Jan 2024 23:16:44 +0100 Subject: [PATCH 04/20] fft window functions back to correct scaling - no need need for post scaling step --- src/maths/fft/fftext.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/maths/fft/fftext.c b/src/maths/fft/fftext.c index b5695ce62..fd0be8863 100644 --- a/src/maths/fft/fftext.c +++ b/src/maths/fft/fftext.c @@ -115,32 +115,43 @@ fft_windows(char *window, double *win, double *time, int length, double maxt, do if (maxt-time[i] > span) win[i] = 0.0; else if (maxt-time[i] < span/2) - win[i] = 2 * (maxt-time[i]) / span; + win[i] = 4.0 * (maxt-time[i]) / span; else - win[i] = 2.0 - 2 * (maxt-time[i]) / span; + win[i] = 4.0 - 4.0 * (maxt-time[i]) / span; } else if (eq(window, "hann") || eq(window, "hanning") || eq(window, "cosine")) for (i = 0; i < length; i++) { if (maxt-time[i] > span) win[i] = 0.0; else - win[i] = 0.5 - 0.5*cos(2*M_PI*(time[i]-maxt)/span); + win[i] = 1.0 - cos(2*M_PI*(time[i]-maxt)/span); } else if (eq(window, "hamming")) for (i = 0; i < length; i++) { if (maxt-time[i] > span) win[i] = 0.0; else - win[i] = 0.54 - 0.46*cos(2*M_PI*(time[i]-maxt)/span); + win[i] = 1.0 - 0.46/0.54*cos(2*M_PI*(time[i]-maxt)/span); } else if (eq(window, "blackman")) for (i = 0; i < length; i++) { if (maxt-time[i] > span) { win[i] = 0; } else { - win[i] = 0.42; - win[i] -= 0.50*cos(2*M_PI*(time[i]-maxt)/span); - win[i] += 0.08*cos(4*M_PI*(time[i]-maxt)/span); + win[i] = 1.0; + win[i] -= 0.50/0.42*cos(2*M_PI*(time[i]-maxt)/span); + win[i] += 0.08/0.42*cos(4*M_PI*(time[i]-maxt)/span); + } + } + else if (eq(window, "blackmanharris")) + for (i = 0; i < length; i++) { + if (maxt-time[i] > span) { + win[i] = 0; + } else { + win[i] = 1.0; + win[i] -= 0.48829/0.35875*cos(2*M_PI*(time[i]-maxt)/span); + win[i] += 0.14128/0.35875*cos(4*M_PI*(time[i]-maxt)/span); + win[i] -= 0.01168/0.35875*cos(6*M_PI*(time[i]-maxt)/span); } } else if (eq(window, "flattop")) @@ -148,16 +159,16 @@ fft_windows(char *window, double *win, double *time, int length, double maxt, do if (maxt-time[i] > span) { win[i] = 0; } else { - win[i] = 0.21557895; - win[i] -= 0.41663158*cos(2*M_PI*(time[i]-maxt)/span); - win[i] += 0.277263158*cos(4*M_PI*(time[i]-maxt)/span); - win[i] -= 0.083578947*cos(6*M_PI*(time[i]-maxt)/span); - win[i] += 0.006947368*cos(8*M_PI*(time[i]-maxt)/span); + win[i] = 1.0; + win[i] -= 1.93*cos(2*M_PI*(time[i]-maxt)/span); + win[i] += 1.29*cos(4*M_PI*(time[i]-maxt)/span); + win[i] -= 0.388*cos(6*M_PI*(time[i]-maxt)/span); + win[i] += 0.032*cos(8*M_PI*(time[i]-maxt)/span); } } else if (eq(window, "gaussian")) { sigma = 1.0/order; - scale = 0.5/sigma; + scale = 0.83/sigma; for (i = 0; i < length; i++) { if (maxt-time[i] > span) win[i] = 0; From e0c3206601767fde4350983620540497cbb71cca Mon Sep 17 00:00:00 2001 From: dwarning Date: Fri, 26 Jan 2024 07:45:27 +0100 Subject: [PATCH 05/20] partially revert commit aafd7bbb: spec triangular window --- src/frontend/spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/spec.c b/src/frontend/spec.c index c6a6e33f0..8e5d2c108 100644 --- a/src/frontend/spec.c +++ b/src/frontend/spec.c @@ -122,7 +122,7 @@ com_spec(wordlist *wl) if (maxt-time[i] > span) { win[i] = 0; } else { - win[i] = 1 - 2 * fabs((time[i]-maxt)-span/2) / span; + win[i] = 2 - fabs(2+4*(time[i]-maxt)/span); } } else if (eq(window, "blackman")) { From 1e8f9a411ac1b740289d46f580b8faa6ae5758da Mon Sep 17 00:00:00 2001 From: dwarning Date: Fri, 26 Jan 2024 08:32:18 +0100 Subject: [PATCH 06/20] rm obsolete order for spec blackman window --- src/frontend/spec.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/frontend/spec.c b/src/frontend/spec.c index 8e5d2c108..40625996d 100644 --- a/src/frontend/spec.c +++ b/src/frontend/spec.c @@ -126,11 +126,6 @@ com_spec(wordlist *wl) } } else if (eq(window, "blackman")) { - int order; - if (!cp_getvar("specwindoworder", CP_NUM, &order, 0)) - order = 2; - if (order < 2) /* only order 2 supported here */ - order = 2; for (i = 0; i < tlen; i++) { if (maxt-time[i] > span) { win[i] = 0; From c0b3511b206cedee77a5844314561bc4444a2ed7 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 2 Feb 2024 11:12:24 +0100 Subject: [PATCH 07/20] compile with gcc-14 fails due to `-Werror=incompatible-pointer-types` Patch provided by Mamoru Tasaka. --- src/tclspice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tclspice.c b/src/tclspice.c index 367eb334e..7e8e47b92 100644 --- a/src/tclspice.c +++ b/src/tclspice.c @@ -2433,7 +2433,7 @@ tmeasure TCL_CMDPROCARGS(clientData, interp, argc, argv) return TCL_ERROR; } - wl = wl_build((char **)argv); + wl = wl_build((const char * const *)argv); get_measure2(wl, &mvalue, NULL, FALSE); From 7d1ea80a2e2cee9fa28e42ab1ca7167b8c044a93 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 2 Feb 2024 11:15:14 +0100 Subject: [PATCH 08/20] F source fails when VNAM contains math symbols like '-'. Use INPgetNetTok for instance parameters like it has been done for nodes already. --- src/spicelib/parser/inpgval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spicelib/parser/inpgval.c b/src/spicelib/parser/inpgval.c index f9f84ad14..626681570 100644 --- a/src/spicelib/parser/inpgval.c +++ b/src/spicelib/parser/inpgval.c @@ -89,7 +89,7 @@ INPgetValue(CKTcircuit *ckt, char **line, int type, INPtables *tab) INPgetNetTok(line, &word, 1); INPtermInsert(ckt, &word, tab, &(temp.nValue)); } else if (type == IF_INSTANCE) { - INPgetTok(line, &word, 1); + INPgetNetTok(line, &word, 1); INPinsert(&word, tab); temp.uValue = word; } else if (type == IF_STRING) { From 2ec5944dd4b681ec790f523f3fddb4b0d5802ff8 Mon Sep 17 00:00:00 2001 From: Giles Atkinson <“gatk555@gmail.com”> Date: Tue, 30 Jan 2024 13:54:21 +0000 Subject: [PATCH 09/20] Use all available precision when creating a "plot" command for a zoomed window. That prevents an unexpected zoom-out in one dimension caused by a zero-height (or width) window being requested when zooming with already high magnification. --- src/frontend/plotting/x11.c | 19 ++++++++++++++----- src/frontend/wdisp/windisp.c | 10 ++++++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index fed83762c..ca468cd24 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -1085,14 +1085,23 @@ zoomin(GRAPH *graph) if ((t = strchr(buf2, ':')) != NULL) *t = '\0'; + /* Set the foreground and background colors to the + * "calling" window's colors using undocumented keyword, "sgraphid". + */ + if (!eq(plot_cur->pl_typename, buf2)) { + /* Switch plot before and after "plot" command. */ (void) sprintf(buf, - "setplot %s; %s xlimit %.20e %.20e ylimit %.20e %.20e sgraphid %d; setplot $curplot\n", - buf2, graph->commandline, fx0, fx1, fy0, fy1, graph->graphid); + "setplot %s; %s xlimit %.20e %.20e ylimit %.20e %.20e " + "sgraphid %d; setplot $curplot\n", + buf2, graph->commandline, fx0, fx1, fy0, fy1, + graph->graphid); } else { - /* set the foreground and background colors to the "calling" window's colors */ - (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e sgraphid %d\n", - graph->commandline, fx0, fx1, fy0, fy1, graph->graphid); + (void) sprintf(buf, + "%s xlimit %.20e %.20e ylimit %.20e %.20e " + "sgraphid %d\n", + graph->commandline, fx0, fx1, fy0, fy1, + graph->graphid); } /* don't use the following if using GNU Readline or BSD EditLine */ diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index 33a238fcd..ed8bc5a3c 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -630,11 +630,13 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, if (!eq(plot_cur->pl_typename, buf2)) { (void) sprintf(buf, -// "setplot %s; %s xlimit %e %e ylimit %e %e; setplot $curplot\n", - "setplot %s; %s xlimit %e %e ylimit %e %e sgraphid %d\n", - buf2, gr->commandline, fx0, fxe, fy0, fye, gr->graphid); + "setplot %s; %s xlimit %.20e %.20e ylimit %.20e " + "%.20e sgraphid %d ; setplot $curplot\n", + buf2, gr->commandline, fx0, fxe, fy0, fye, + gr->graphid); } else { - (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e sgraphid %d\n", + (void) sprintf(buf, "%s xlimit %.20e %.20e ylimit %.20e %.20e " + "sgraphid %d\n", gr->commandline, fx0, fxe, fy0, fye, gr->graphid); } From 1c9f8b6345569e8cabfe8eeeedb2dbcec2f8d207 Mon Sep 17 00:00:00 2001 From: dwarning Date: Mon, 12 Feb 2024 11:08:35 +0100 Subject: [PATCH 10/20] two corrections in Ycor and NF formulae --- src/spicelib/analysis/span.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/spicelib/analysis/span.c b/src/spicelib/analysis/span.c index 86e59daa0..f4bdcbefa 100644 --- a/src/spicelib/analysis/span.c +++ b/src/spicelib/analysis/span.c @@ -126,7 +126,7 @@ CKTspnoise(CKTcircuit* ckt, int mode, int operation, Ndata* data, NOISEAN* noise cplx Ycor = csubco(ckt->CKTYmat->d[0][0], cmultco( cdivco(tempCy->d[0][1], tempCy->d[1][1]), - tempCy->d[1][0] + ckt->CKTYmat->d[1][0] )); double Y11_Ycor = cmodsqr(csubco(ckt->CKTYmat->d[0][0], Ycor)); @@ -138,7 +138,7 @@ CKTspnoise(CKTcircuit* ckt, int mode, int operation, Ndata* data, NOISEAN* noise caddco(Y0, Ysopt)); Fmin = 1.0 + 2.0 * Rn * (Ycor.re + Ysopt.re); double Ysoptmod = cmodu(csubco(Y0, Ysopt)); - NF = Fmin + (Rn / Ysopt.re) * SQR(Ysoptmod); + NF = Fmin + (Rn / Y0.re) * SQR(Ysoptmod); Fmin = 10.0 * log10(Fmin); NF = 10.0 * log10(NF); } From 2a6db71726fb5575adf09b8fd48bfe51f6b71348 Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 23 Jan 2024 11:37:07 +0100 Subject: [PATCH 11/20] formatting mos1...3 noise code --- src/spicelib/devices/mos1/mos1noi.c | 264 ++++++++++++++-------------- src/spicelib/devices/mos2/mos2noi.c | 251 +++++++++++++------------- src/spicelib/devices/mos3/mos3noi.c | 254 +++++++++++++------------- 3 files changed, 395 insertions(+), 374 deletions(-) diff --git a/src/spicelib/devices/mos1/mos1noi.c b/src/spicelib/devices/mos1/mos1noi.c index 79d91442e..07fed16d3 100644 --- a/src/spicelib/devices/mos1/mos1noi.c +++ b/src/spicelib/devices/mos1/mos1noi.c @@ -20,16 +20,14 @@ Modified: 2000 AlansFixes * all of the MOSFET's is summed with the variable "OnDens". */ - int -MOS1noise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, - Ndata *data, double *OnDens) -{ - NOISEAN *job = (NOISEAN *) ckt->CKTcurJob; +MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, + Ndata * data, double * OnDens) { + NOISEAN * job = (NOISEAN * ) ckt -> CKTcurJob; - MOS1model *firstModel = (MOS1model *) genmodel; - MOS1model *model; - MOS1instance *inst; + MOS1model * firstModel = (MOS1model * ) genmodel; + MOS1model * model; + MOS1instance * inst; double coxSquared; double tempOnoise; double tempInoise; @@ -39,151 +37,161 @@ MOS1noise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, /* define the names of the noise sources */ - static char *MOS1nNames[MOS1NSRCS] = { /* Note that we have to keep the order */ - "_rd", /* noise due to rd */ /* consistent with thestrchr definitions */ - "_rs", /* noise due to rs */ /* in MOS1defs.h */ - "_id", /* noise due to id */ - "_1overf", /* flicker (1/f) noise */ - "" /* total transistor noise */ + static char * MOS1nNames[MOS1NSRCS] = { + /* Note that we have to keep the order */ + "_rd", + /* noise due to rd */ /* consistent with thestrchr definitions */ + "_rs", + /* noise due to rs */ /* in MOS1defs.h */ + "_id", + /* noise due to id */ + "_1overf", + /* flicker (1/f) noise */ + "" /* total transistor noise */ }; - for (model=firstModel; model != NULL; model=MOS1nextModel(model)) { + for (model = firstModel; model != NULL; model = MOS1nextModel(model)) { - /* Oxide capacitance can be zero in MOS level 1. Since this will give us problems in our 1/f */ - /* noise model, we ASSUME an actual "tox" of 1e-7 */ + /* Oxide capacitance can be zero in MOS level 1. Since this will give us problems in our 1/f */ + /* noise model, we ASSUME an actual "tox" of 1e-7 */ - if (model->MOS1oxideCapFactor == 0.0) { - coxSquared = 3.9 * 8.854214871e-12 / 1e-7; + if (model -> MOS1oxideCapFactor == 0.0) { + coxSquared = 3.9 * 8.854214871e-12 / 1e-7; } else { - coxSquared = model->MOS1oxideCapFactor; + coxSquared = model -> MOS1oxideCapFactor; } - coxSquared *= coxSquared; - for (inst=MOS1instances(model); inst != NULL; inst=MOS1nextInstance(inst)) { - - switch (operation) { + coxSquared *= coxSquared; + for (inst = MOS1instances(model); inst != NULL; inst = MOS1nextInstance(inst)) { - case N_OPEN: + switch (operation) { - /* see if we have to to produce a summary report */ - /* if so, name all the noise generators */ + case N_OPEN: - if (job->NStpsSm != 0) { - switch (mode) { + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ - case N_DENS: - for (i=0; i < MOS1NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->MOS1name, MOS1nNames[i]); - } - break; + if (job -> NStpsSm != 0) { + switch (mode) { - case INT_NOIZ: - for (i=0; i < MOS1NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->MOS1name, MOS1nNames[i]); - NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->MOS1name, MOS1nNames[i]); - } - break; - } - } - break; + case N_DENS: + for (i = 0; i < MOS1NSRCS; i++) { + NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst -> MOS1name, MOS1nNames[i]); + } + break; - case N_CALC: - switch (mode) { + case INT_NOIZ: + for (i = 0; i < MOS1NSRCS; i++) { + NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst -> MOS1name, MOS1nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst -> MOS1name, MOS1nNames[i]); + } + break; + } + } + break; - case N_DENS: - NevalSrc(&noizDens[MOS1RDNOIZ],&lnNdens[MOS1RDNOIZ], - ckt,THERMNOISE,inst->MOS1dNodePrime,inst->MOS1dNode, - inst->MOS1drainConductance); + case N_CALC: + switch (mode) { - NevalSrc(&noizDens[MOS1RSNOIZ],&lnNdens[MOS1RSNOIZ], - ckt,THERMNOISE,inst->MOS1sNodePrime,inst->MOS1sNode, - inst->MOS1sourceConductance); + case N_DENS: + NevalSrc( & noizDens[MOS1RDNOIZ], & lnNdens[MOS1RDNOIZ], + ckt, THERMNOISE, inst -> MOS1dNodePrime, inst -> MOS1dNode, + inst -> MOS1drainConductance); - NevalSrc(&noizDens[MOS1IDNOIZ],&lnNdens[MOS1IDNOIZ], - ckt,THERMNOISE,inst->MOS1dNodePrime,inst->MOS1sNodePrime, - (2.0/3.0 * fabs(inst->MOS1gm))); + NevalSrc( & noizDens[MOS1RSNOIZ], & lnNdens[MOS1RSNOIZ], + ckt, THERMNOISE, inst -> MOS1sNodePrime, inst -> MOS1sNode, + inst -> MOS1sourceConductance); - NevalSrc(&noizDens[MOS1FLNOIZ], NULL, ckt, - N_GAIN,inst->MOS1dNodePrime, inst->MOS1sNodePrime, - (double)0.0); - noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef * - exp(model->MOS1fNexp * - log(MAX(fabs(inst->MOS1cd),N_MINLOG))) / - (data->freq * inst->MOS1w * - (inst->MOS1l - 2*model->MOS1latDiff) * coxSquared); - lnNdens[MOS1FLNOIZ] = - log(MAX(noizDens[MOS1FLNOIZ],N_MINLOG)); + NevalSrc( & noizDens[MOS1IDNOIZ], & lnNdens[MOS1IDNOIZ], + ckt, THERMNOISE, inst -> MOS1dNodePrime, inst -> MOS1sNodePrime, + (2.0 / 3.0 * fabs(inst -> MOS1gm))); - noizDens[MOS1TOTNOIZ] = noizDens[MOS1RDNOIZ] + - noizDens[MOS1RSNOIZ] + - noizDens[MOS1IDNOIZ] + - noizDens[MOS1FLNOIZ]; - lnNdens[MOS1TOTNOIZ] = - log(MAX(noizDens[MOS1TOTNOIZ], N_MINLOG)); + NevalSrc( & noizDens[MOS1FLNOIZ], NULL, ckt, + N_GAIN, inst -> MOS1dNodePrime, inst -> MOS1sNodePrime, + (double) 0.0); + noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef * + exp(model -> MOS1fNexp * + log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) / + (data -> freq * + inst -> MOS1w * + (inst -> MOS1l - 2 * model -> MOS1latDiff) * + coxSquared); + lnNdens[MOS1FLNOIZ] = + log(MAX(noizDens[MOS1FLNOIZ], N_MINLOG)); - *OnDens += noizDens[MOS1TOTNOIZ]; + noizDens[MOS1TOTNOIZ] = noizDens[MOS1RDNOIZ] + + noizDens[MOS1RSNOIZ] + + noizDens[MOS1IDNOIZ] + + noizDens[MOS1FLNOIZ]; + lnNdens[MOS1TOTNOIZ] = + log(MAX(noizDens[MOS1TOTNOIZ], N_MINLOG)); - if (data->delFreq == 0.0) { + * OnDens += noizDens[MOS1TOTNOIZ]; - /* if we haven't done any previous integration, we need to */ - /* initialize our "history" variables */ + if (data -> delFreq == 0.0) { - for (i=0; i < MOS1NSRCS; i++) { - inst->MOS1nVar[LNLSTDENS][i] = lnNdens[i]; - } + /* if we haven't done any previous integration, we need to */ + /* initialize our "history" variables */ - /* clear out our integration variables if it's the first pass */ + for (i = 0; i < MOS1NSRCS; i++) { + inst -> MOS1nVar[LNLSTDENS][i] = lnNdens[i]; + } - if (data->freq == job->NstartFreq) { - for (i=0; i < MOS1NSRCS; i++) { - inst->MOS1nVar[OUTNOIZ][i] = 0.0; - inst->MOS1nVar[INNOIZ][i] = 0.0; - } - } - } else { /* data->delFreq != 0.0 (we have to integrate) */ - for (i=0; i < MOS1NSRCS; i++) { - if (i != MOS1TOTNOIZ) { - tempOnoise = Nintegrate(noizDens[i], lnNdens[i], - inst->MOS1nVar[LNLSTDENS][i], data); - tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , - lnNdens[i] + data->lnGainInv, - inst->MOS1nVar[LNLSTDENS][i] + data->lnGainInv, - data); - inst->MOS1nVar[LNLSTDENS][i] = lnNdens[i]; - data->outNoiz += tempOnoise; - data->inNoise += tempInoise; - if (job->NStpsSm != 0) { - inst->MOS1nVar[OUTNOIZ][i] += tempOnoise; - inst->MOS1nVar[OUTNOIZ][MOS1TOTNOIZ] += tempOnoise; - inst->MOS1nVar[INNOIZ][i] += tempInoise; - inst->MOS1nVar[INNOIZ][MOS1TOTNOIZ] += tempInoise; + /* clear out our integration variables if it's the first pass */ + + if (data -> freq == job -> NstartFreq) { + for (i = 0; i < MOS1NSRCS; i++) { + inst -> MOS1nVar[OUTNOIZ][i] = 0.0; + inst -> MOS1nVar[INNOIZ][i] = 0.0; + } + } + } else { + /* data->delFreq != 0.0 (we have to integrate) */ + for (i = 0; i < MOS1NSRCS; i++) { + if (i != MOS1TOTNOIZ) { + tempOnoise = Nintegrate(noizDens[i], lnNdens[i], + inst -> MOS1nVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data -> GainSqInv, + lnNdens[i] + data -> lnGainInv, + inst -> MOS1nVar[LNLSTDENS][i] + data -> lnGainInv, + data); + inst -> MOS1nVar[LNLSTDENS][i] = lnNdens[i]; + data -> outNoiz += tempOnoise; + data -> inNoise += tempInoise; + if (job -> NStpsSm != 0) { + inst -> MOS1nVar[OUTNOIZ][i] += tempOnoise; + inst -> MOS1nVar[OUTNOIZ][MOS1TOTNOIZ] += tempOnoise; + inst -> MOS1nVar[INNOIZ][i] += tempInoise; + inst -> MOS1nVar[INNOIZ][MOS1TOTNOIZ] += tempInoise; } - } - } - } - if (data->prtSummary) { - for (i=0; i < MOS1NSRCS; i++) { /* print a summary report */ - data->outpVector[data->outNumber++] = noizDens[i]; - } - } - break; + } + } + } + if (data -> prtSummary) { + for (i = 0; i < MOS1NSRCS; i++) { + /* print a summary report */ + data -> outpVector[data -> outNumber++] = noizDens[i]; + } + } + break; - case INT_NOIZ: /* already calculated, just output */ - if (job->NStpsSm != 0) { - for (i=0; i < MOS1NSRCS; i++) { - data->outpVector[data->outNumber++] = inst->MOS1nVar[OUTNOIZ][i]; - data->outpVector[data->outNumber++] = inst->MOS1nVar[INNOIZ][i]; - } - } /* if */ - break; - } /* switch (mode) */ - break; + case INT_NOIZ: + /* already calculated, just output */ + if (job -> NStpsSm != 0) { + for (i = 0; i < MOS1NSRCS; i++) { + data -> outpVector[data -> outNumber++] = inst -> MOS1nVar[OUTNOIZ][i]; + data -> outpVector[data -> outNumber++] = inst -> MOS1nVar[INNOIZ][i]; + } + } /* if */ + break; + } /* switch (mode) */ + break; - case N_CLOSE: - return (OK); /* do nothing, the main calling routine will close */ - break; /* the plots */ - } /* switch (operation) */ - } /* for inst */ - } /* for model */ + case N_CLOSE: + return (OK); /* do nothing, the main calling routine will close */ + break; /* the plots */ + } /* switch (operation) */ + } /* for inst */ + } /* for model */ -return(OK); + return (OK); } diff --git a/src/spicelib/devices/mos2/mos2noi.c b/src/spicelib/devices/mos2/mos2noi.c index f20c5f01c..1b47ab19c 100644 --- a/src/spicelib/devices/mos2/mos2noi.c +++ b/src/spicelib/devices/mos2/mos2noi.c @@ -20,16 +20,14 @@ Modified: 2000 AlansFixes * all of the MOSFET's is summed with the variable "OnDens". */ - int -MOS2noise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, - Ndata *data, double *OnDens) -{ - NOISEAN *job = (NOISEAN *) ckt->CKTcurJob; +MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, + Ndata * data, double * OnDens) { + NOISEAN * job = (NOISEAN * ) ckt -> CKTcurJob; - MOS2model *firstModel = (MOS2model *) genmodel; - MOS2model *model; - MOS2instance *inst; + MOS2model * firstModel = (MOS2model * ) genmodel; + MOS2model * model; + MOS2instance * inst; double tempOnoise; double tempInoise; double noizDens[MOS2NSRCS]; @@ -38,142 +36,151 @@ MOS2noise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, /* define the names of the noise sources */ - static char *MOS2nNames[MOS2NSRCS] = { /* Note that we have to keep the order */ - "_rd", /* noise due to rd */ /* consistent with thestrchr definitions */ - "_rs", /* noise due to rs */ /* in MOS2defs.h */ - "_id", /* noise due to id */ - "_1overf", /* flicker (1/f) noise */ - "" /* total transistor noise */ + static char * MOS2nNames[MOS2NSRCS] = { + /* Note that we have to keep the order */ + "_rd", + /* noise due to rd */ /* consistent with thestrchr definitions */ + "_rs", + /* noise due to rs */ /* in MOS2defs.h */ + "_id", + /* noise due to id */ + "_1overf", + /* flicker (1/f) noise */ + "" /* total transistor noise */ }; - for (model=firstModel; model != NULL; model=MOS2nextModel(model)) { - for (inst=MOS2instances(model); inst != NULL; inst=MOS2nextInstance(inst)) { + for (model = firstModel; model != NULL; model = MOS2nextModel(model)) { + for (inst = MOS2instances(model); inst != NULL; inst = MOS2nextInstance(inst)) { - switch (operation) { + switch (operation) { - case N_OPEN: + case N_OPEN: - /* see if we have to to produce a summary report */ - /* if so, name all the noise generators */ + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ - if (job->NStpsSm != 0) { - switch (mode) { + if (job -> NStpsSm != 0) { + switch (mode) { - case N_DENS: - for (i=0; i < MOS2NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->MOS2name, MOS2nNames[i]); - } - break; + case N_DENS: + for (i = 0; i < MOS2NSRCS; i++) { + NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst -> MOS2name, MOS2nNames[i]); + } + break; - case INT_NOIZ: - for (i=0; i < MOS2NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->MOS2name, MOS2nNames[i]); - NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->MOS2name, MOS2nNames[i]); - } - break; - } - } - break; + case INT_NOIZ: + for (i = 0; i < MOS2NSRCS; i++) { + NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst -> MOS2name, MOS2nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst -> MOS2name, MOS2nNames[i]); + } + break; + } + } + break; - case N_CALC: - switch (mode) { + case N_CALC: + switch (mode) { - case N_DENS: - NevalSrc(&noizDens[MOS2RDNOIZ],&lnNdens[MOS2RDNOIZ], - ckt,THERMNOISE,inst->MOS2dNodePrime,inst->MOS2dNode, - inst->MOS2drainConductance); + case N_DENS: + NevalSrc( & noizDens[MOS2RDNOIZ], & lnNdens[MOS2RDNOIZ], + ckt, THERMNOISE, inst -> MOS2dNodePrime, inst -> MOS2dNode, + inst -> MOS2drainConductance); - NevalSrc(&noizDens[MOS2RSNOIZ],&lnNdens[MOS2RSNOIZ], - ckt,THERMNOISE,inst->MOS2sNodePrime,inst->MOS2sNode, - inst->MOS2sourceConductance); + NevalSrc( & noizDens[MOS2RSNOIZ], & lnNdens[MOS2RSNOIZ], + ckt, THERMNOISE, inst -> MOS2sNodePrime, inst -> MOS2sNode, + inst -> MOS2sourceConductance); - NevalSrc(&noizDens[MOS2IDNOIZ],&lnNdens[MOS2IDNOIZ], - ckt,THERMNOISE,inst->MOS2dNodePrime,inst->MOS2sNodePrime, - (2.0/3.0 * fabs(inst->MOS2gm))); + NevalSrc( & noizDens[MOS2IDNOIZ], & lnNdens[MOS2IDNOIZ], + ckt, THERMNOISE, inst -> MOS2dNodePrime, inst -> MOS2sNodePrime, + (2.0 / 3.0 * fabs(inst -> MOS2gm))); - NevalSrc(&noizDens[MOS2FLNOIZ], NULL, ckt, - N_GAIN,inst->MOS2dNodePrime, inst->MOS2sNodePrime, - (double)0.0); - noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * - exp(model->MOS2fNexp * - log(MAX(fabs(inst->MOS2cd),N_MINLOG))) / - (data->freq * inst->MOS2w * - (inst->MOS2l - 2*model->MOS2latDiff) * - model->MOS2oxideCapFactor * model->MOS2oxideCapFactor); - lnNdens[MOS2FLNOIZ] = - log(MAX(noizDens[MOS2FLNOIZ],N_MINLOG)); + NevalSrc( & noizDens[MOS2FLNOIZ], NULL, ckt, + N_GAIN, inst -> MOS2dNodePrime, inst -> MOS2sNodePrime, + (double) 0.0); + noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef * + exp(model -> MOS2fNexp * + log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) / + (data -> freq * + inst -> MOS2w * + (inst -> MOS2l - 2 * model -> MOS2latDiff) * + model -> MOS2oxideCapFactor * model -> MOS2oxideCapFactor); + lnNdens[MOS2FLNOIZ] = + log(MAX(noizDens[MOS2FLNOIZ], N_MINLOG)); - noizDens[MOS2TOTNOIZ] = noizDens[MOS2RDNOIZ] + - noizDens[MOS2RSNOIZ] + - noizDens[MOS2IDNOIZ] + - noizDens[MOS2FLNOIZ]; - lnNdens[MOS2TOTNOIZ] = - log(MAX(noizDens[MOS2TOTNOIZ], N_MINLOG)); + noizDens[MOS2TOTNOIZ] = noizDens[MOS2RDNOIZ] + + noizDens[MOS2RSNOIZ] + + noizDens[MOS2IDNOIZ] + + noizDens[MOS2FLNOIZ]; + lnNdens[MOS2TOTNOIZ] = + log(MAX(noizDens[MOS2TOTNOIZ], N_MINLOG)); - *OnDens += noizDens[MOS2TOTNOIZ]; + * OnDens += noizDens[MOS2TOTNOIZ]; - if (data->delFreq == 0.0) { + if (data -> delFreq == 0.0) { - /* if we haven't done any previous integration, we need to */ - /* initialize our "history" variables */ + /* if we haven't done any previous integration, we need to */ + /* initialize our "history" variables */ - for (i=0; i < MOS2NSRCS; i++) { - inst->MOS2nVar[LNLSTDENS][i] = lnNdens[i]; - } + for (i = 0; i < MOS2NSRCS; i++) { + inst -> MOS2nVar[LNLSTDENS][i] = lnNdens[i]; + } - /* clear out our integration variables if it's the first pass */ + /* clear out our integration variables if it's the first pass */ - if (data->freq == job->NstartFreq) { - for (i=0; i < MOS2NSRCS; i++) { - inst->MOS2nVar[OUTNOIZ][i] = 0.0; - inst->MOS2nVar[INNOIZ][i] = 0.0; - } - } - } else { /* data->delFreq != 0.0 (we have to integrate) */ - for (i=0; i < MOS2NSRCS; i++) { - if (i != MOS2TOTNOIZ) { - tempOnoise = Nintegrate(noizDens[i], lnNdens[i], - inst->MOS2nVar[LNLSTDENS][i], data); - tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , - lnNdens[i] + data->lnGainInv, - inst->MOS2nVar[LNLSTDENS][i] + data->lnGainInv, - data); - inst->MOS2nVar[LNLSTDENS][i] = lnNdens[i]; - data->outNoiz += tempOnoise; - data->inNoise += tempInoise; - if (job->NStpsSm != 0) { - inst->MOS2nVar[OUTNOIZ][i] += tempOnoise; - inst->MOS2nVar[OUTNOIZ][MOS2TOTNOIZ] += tempOnoise; - inst->MOS2nVar[INNOIZ][i] += tempInoise; - inst->MOS2nVar[INNOIZ][MOS2TOTNOIZ] += tempInoise; + if (data -> freq == job -> NstartFreq) { + for (i = 0; i < MOS2NSRCS; i++) { + inst -> MOS2nVar[OUTNOIZ][i] = 0.0; + inst -> MOS2nVar[INNOIZ][i] = 0.0; + } + } + } else { + /* data->delFreq != 0.0 (we have to integrate) */ + for (i = 0; i < MOS2NSRCS; i++) { + if (i != MOS2TOTNOIZ) { + tempOnoise = Nintegrate(noizDens[i], lnNdens[i], + inst -> MOS2nVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data -> GainSqInv, + lnNdens[i] + data -> lnGainInv, + inst -> MOS2nVar[LNLSTDENS][i] + data -> lnGainInv, + data); + inst -> MOS2nVar[LNLSTDENS][i] = lnNdens[i]; + data -> outNoiz += tempOnoise; + data -> inNoise += tempInoise; + if (job -> NStpsSm != 0) { + inst -> MOS2nVar[OUTNOIZ][i] += tempOnoise; + inst -> MOS2nVar[OUTNOIZ][MOS2TOTNOIZ] += tempOnoise; + inst -> MOS2nVar[INNOIZ][i] += tempInoise; + inst -> MOS2nVar[INNOIZ][MOS2TOTNOIZ] += tempInoise; } - } - } - } - if (data->prtSummary) { - for (i=0; i < MOS2NSRCS; i++) { /* print a summary report */ - data->outpVector[data->outNumber++] = noizDens[i]; - } - } - break; + } + } + } + if (data -> prtSummary) { + for (i = 0; i < MOS2NSRCS; i++) { + /* print a summary report */ + data -> outpVector[data -> outNumber++] = noizDens[i]; + } + } + break; - case INT_NOIZ: /* already calculated, just output */ - if (job->NStpsSm != 0) { - for (i=0; i < MOS2NSRCS; i++) { - data->outpVector[data->outNumber++] = inst->MOS2nVar[OUTNOIZ][i]; - data->outpVector[data->outNumber++] = inst->MOS2nVar[INNOIZ][i]; - } - } /* if */ - break; - } /* switch (mode) */ - break; + case INT_NOIZ: + /* already calculated, just output */ + if (job -> NStpsSm != 0) { + for (i = 0; i < MOS2NSRCS; i++) { + data -> outpVector[data -> outNumber++] = inst -> MOS2nVar[OUTNOIZ][i]; + data -> outpVector[data -> outNumber++] = inst -> MOS2nVar[INNOIZ][i]; + } + } /* if */ + break; + } /* switch (mode) */ + break; - case N_CLOSE: - return (OK); /* do nothing, the main calling routine will close */ - break; /* the plots */ - } /* switch (operation) */ - } /* for inst */ - } /* for model */ + case N_CLOSE: + return (OK); /* do nothing, the main calling routine will close */ + break; /* the plots */ + } /* switch (operation) */ + } /* for inst */ + } /* for model */ -return(OK); + return (OK); } diff --git a/src/spicelib/devices/mos3/mos3noi.c b/src/spicelib/devices/mos3/mos3noi.c index 82008d9b5..6265dec93 100644 --- a/src/spicelib/devices/mos3/mos3noi.c +++ b/src/spicelib/devices/mos3/mos3noi.c @@ -20,16 +20,14 @@ Modified: 2000 AlansFixes * all of the MOSFET's is summed with the variable "OnDens". */ - int -MOS3noise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, - Ndata *data, double *OnDens) -{ - NOISEAN *job = (NOISEAN *) ckt->CKTcurJob; +MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, + Ndata * data, double * OnDens) { + NOISEAN * job = (NOISEAN * ) ckt -> CKTcurJob; - MOS3model *firstModel = (MOS3model *) genmodel; - MOS3model *model; - MOS3instance *inst; + MOS3model * firstModel = (MOS3model * ) genmodel; + MOS3model * model; + MOS3instance * inst; double tempOnoise; double tempInoise; double noizDens[MOS3NSRCS]; @@ -38,143 +36,151 @@ MOS3noise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, /* define the names of the noise sources */ - static char *MOS3nNames[MOS3NSRCS] = { /* Note that we have to keep the order */ - "_rd", /* noise due to rd */ /* consistent with thestrchr definitions */ - "_rs", /* noise due to rs */ /* in MOS3defs.h */ - "_id", /* noise due to id */ - "_1overf", /* flicker (1/f) noise */ - "" /* total transistor noise */ + static char * MOS3nNames[MOS3NSRCS] = { + /* Note that we have to keep the order */ + "_rd", + /* noise due to rd */ /* consistent with thestrchr definitions */ + "_rs", + /* noise due to rs */ /* in MOS3defs.h */ + "_id", + /* noise due to id */ + "_1overf", + /* flicker (1/f) noise */ + "" /* total transistor noise */ }; - for (model=firstModel; model != NULL; model=MOS3nextModel(model)) { - for (inst=MOS3instances(model); inst != NULL; inst=MOS3nextInstance(inst)) { - - switch (operation) { + for (model = firstModel; model != NULL; model = MOS3nextModel(model)) { + for (inst = MOS3instances(model); inst != NULL; inst = MOS3nextInstance(inst)) { - case N_OPEN: + switch (operation) { - /* see if we have to to produce a summary report */ - /* if so, name all the noise generators */ + case N_OPEN: - if (job->NStpsSm != 0) { - switch (mode) { + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ - case N_DENS: - for (i=0; i < MOS3NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->MOS3name, MOS3nNames[i]); - } - break; + if (job -> NStpsSm != 0) { + switch (mode) { - case INT_NOIZ: - for (i=0; i < MOS3NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->MOS3name, MOS3nNames[i]); - NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->MOS3name, MOS3nNames[i]); - } - break; - } - } - break; + case N_DENS: + for (i = 0; i < MOS3NSRCS; i++) { + NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst -> MOS3name, MOS3nNames[i]); + } + break; - case N_CALC: - switch (mode) { + case INT_NOIZ: + for (i = 0; i < MOS3NSRCS; i++) { + NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst -> MOS3name, MOS3nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst -> MOS3name, MOS3nNames[i]); + } + break; + } + } + break; - case N_DENS: - NevalSrc(&noizDens[MOS3RDNOIZ],&lnNdens[MOS3RDNOIZ], - ckt,THERMNOISE,inst->MOS3dNodePrime,inst->MOS3dNode, - inst->MOS3drainConductance); + case N_CALC: + switch (mode) { - NevalSrc(&noizDens[MOS3RSNOIZ],&lnNdens[MOS3RSNOIZ], - ckt,THERMNOISE,inst->MOS3sNodePrime,inst->MOS3sNode, - inst->MOS3sourceConductance); + case N_DENS: + NevalSrc( & noizDens[MOS3RDNOIZ], & lnNdens[MOS3RDNOIZ], + ckt, THERMNOISE, inst -> MOS3dNodePrime, inst -> MOS3dNode, + inst -> MOS3drainConductance); - NevalSrc(&noizDens[MOS3IDNOIZ],&lnNdens[MOS3IDNOIZ], - ckt,THERMNOISE,inst->MOS3dNodePrime,inst->MOS3sNodePrime, - (2.0/3.0 * fabs(inst->MOS3gm))); + NevalSrc( & noizDens[MOS3RSNOIZ], & lnNdens[MOS3RSNOIZ], + ckt, THERMNOISE, inst -> MOS3sNodePrime, inst -> MOS3sNode, + inst -> MOS3sourceConductance); - NevalSrc(&noizDens[MOS3FLNOIZ], NULL, ckt, - N_GAIN,inst->MOS3dNodePrime, inst->MOS3sNodePrime, - (double)0.0); - noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef * - exp(model->MOS3fNexp * - log(MAX(fabs(inst->MOS3cd),N_MINLOG))) / - (data->freq * - (inst->MOS3w - 2*model->MOS3widthNarrow) * - (inst->MOS3l - 2*model->MOS3latDiff) * - model->MOS3oxideCapFactor * model->MOS3oxideCapFactor); - lnNdens[MOS3FLNOIZ] = - log(MAX(noizDens[MOS3FLNOIZ],N_MINLOG)); + NevalSrc( & noizDens[MOS3IDNOIZ], & lnNdens[MOS3IDNOIZ], + ckt, THERMNOISE, inst -> MOS3dNodePrime, inst -> MOS3sNodePrime, + (2.0 / 3.0 * fabs(inst -> MOS3gm))); - noizDens[MOS3TOTNOIZ] = noizDens[MOS3RDNOIZ] + - noizDens[MOS3RSNOIZ] + - noizDens[MOS3IDNOIZ] + - noizDens[MOS3FLNOIZ]; - lnNdens[MOS3TOTNOIZ] = - log(MAX(noizDens[MOS3TOTNOIZ], N_MINLOG)); + NevalSrc( & noizDens[MOS3FLNOIZ], NULL, ckt, + N_GAIN, inst -> MOS3dNodePrime, inst -> MOS3sNodePrime, + (double) 0.0); + noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef * + exp(model -> MOS3fNexp * + log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) / + (data -> freq * + (inst -> MOS3w - 2 * model -> MOS3widthNarrow) * + (inst -> MOS3l - 2 * model -> MOS3latDiff) * + model -> MOS3oxideCapFactor * model -> MOS3oxideCapFactor); + lnNdens[MOS3FLNOIZ] = + log(MAX(noizDens[MOS3FLNOIZ], N_MINLOG)); - *OnDens += noizDens[MOS3TOTNOIZ]; + noizDens[MOS3TOTNOIZ] = noizDens[MOS3RDNOIZ] + + noizDens[MOS3RSNOIZ] + + noizDens[MOS3IDNOIZ] + + noizDens[MOS3FLNOIZ]; + lnNdens[MOS3TOTNOIZ] = + log(MAX(noizDens[MOS3TOTNOIZ], N_MINLOG)); - if (data->delFreq == 0.0) { + * OnDens += noizDens[MOS3TOTNOIZ]; - /* if we haven't done any previous integration, we need to */ - /* initialize our "history" variables */ + if (data -> delFreq == 0.0) { - for (i=0; i < MOS3NSRCS; i++) { - inst->MOS3nVar[LNLSTDENS][i] = lnNdens[i]; - } + /* if we haven't done any previous integration, we need to */ + /* initialize our "history" variables */ - /* clear out our integration variables if it's the first pass */ + for (i = 0; i < MOS3NSRCS; i++) { + inst -> MOS3nVar[LNLSTDENS][i] = lnNdens[i]; + } - if (data->freq == job->NstartFreq) { - for (i=0; i < MOS3NSRCS; i++) { - inst->MOS3nVar[OUTNOIZ][i] = 0.0; - inst->MOS3nVar[INNOIZ][i] = 0.0; - } - } - } else { /* data->delFreq != 0.0 (we have to integrate) */ - for (i=0; i < MOS3NSRCS; i++) { - if (i != MOS3TOTNOIZ) { - tempOnoise = Nintegrate(noizDens[i], lnNdens[i], - inst->MOS3nVar[LNLSTDENS][i], data); - tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , - lnNdens[i] + data->lnGainInv, - inst->MOS3nVar[LNLSTDENS][i] + data->lnGainInv, - data); - inst->MOS3nVar[LNLSTDENS][i] = lnNdens[i]; - data->outNoiz += tempOnoise; - data->inNoise += tempInoise; - if (job->NStpsSm != 0) { - inst->MOS3nVar[OUTNOIZ][i] += tempOnoise; - inst->MOS3nVar[OUTNOIZ][MOS3TOTNOIZ] += tempOnoise; - inst->MOS3nVar[INNOIZ][i] += tempInoise; - inst->MOS3nVar[INNOIZ][MOS3TOTNOIZ] += tempInoise; + /* clear out our integration variables if it's the first pass */ + + if (data -> freq == job -> NstartFreq) { + for (i = 0; i < MOS3NSRCS; i++) { + inst -> MOS3nVar[OUTNOIZ][i] = 0.0; + inst -> MOS3nVar[INNOIZ][i] = 0.0; + } + } + } else { + /* data->delFreq != 0.0 (we have to integrate) */ + for (i = 0; i < MOS3NSRCS; i++) { + if (i != MOS3TOTNOIZ) { + tempOnoise = Nintegrate(noizDens[i], lnNdens[i], + inst -> MOS3nVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data -> GainSqInv, + lnNdens[i] + data -> lnGainInv, + inst -> MOS3nVar[LNLSTDENS][i] + data -> lnGainInv, + data); + inst -> MOS3nVar[LNLSTDENS][i] = lnNdens[i]; + data -> outNoiz += tempOnoise; + data -> inNoise += tempInoise; + if (job -> NStpsSm != 0) { + inst -> MOS3nVar[OUTNOIZ][i] += tempOnoise; + inst -> MOS3nVar[OUTNOIZ][MOS3TOTNOIZ] += tempOnoise; + inst -> MOS3nVar[INNOIZ][i] += tempInoise; + inst -> MOS3nVar[INNOIZ][MOS3TOTNOIZ] += tempInoise; } - } - } - } - if (data->prtSummary) { - for (i=0; i < MOS3NSRCS; i++) { /* print a summary report */ - data->outpVector[data->outNumber++] = noizDens[i]; - } - } - break; + } + } + } + if (data -> prtSummary) { + for (i = 0; i < MOS3NSRCS; i++) { + /* print a summary report */ + data -> outpVector[data -> outNumber++] = noizDens[i]; + } + } + break; - case INT_NOIZ: /* already calculated, just output */ - if (job->NStpsSm != 0) { - for (i=0; i < MOS3NSRCS; i++) { - data->outpVector[data->outNumber++] = inst->MOS3nVar[OUTNOIZ][i]; - data->outpVector[data->outNumber++] = inst->MOS3nVar[INNOIZ][i]; - } - } /* if */ - break; - } /* switch (mode) */ - break; + case INT_NOIZ: + /* already calculated, just output */ + if (job -> NStpsSm != 0) { + for (i = 0; i < MOS3NSRCS; i++) { + data -> outpVector[data -> outNumber++] = inst -> MOS3nVar[OUTNOIZ][i]; + data -> outpVector[data -> outNumber++] = inst -> MOS3nVar[INNOIZ][i]; + } + } /* if */ + break; + } /* switch (mode) */ + break; - case N_CLOSE: - return (OK); /* do nothing, the main calling routine will close */ - break; /* the plots */ - } /* switch (operation) */ - } /* for inst */ - } /* for model */ + case N_CLOSE: + return (OK); /* do nothing, the main calling routine will close */ + break; /* the plots */ + } /* switch (operation) */ + } /* for inst */ + } /* for model */ -return(OK); + return (OK); } From 1381d71cb1debcf8ddd5d751354a650d64405eb6 Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 23 Jan 2024 14:55:08 +0100 Subject: [PATCH 12/20] selectable flicker noise models for mos1...3 --- src/spicelib/devices/mos1/mos1.c | 3 +- src/spicelib/devices/mos1/mos1defs.h | 3 ++ src/spicelib/devices/mos1/mos1mask.c | 3 ++ src/spicelib/devices/mos1/mos1mpar.c | 4 +++ src/spicelib/devices/mos1/mos1noi.c | 46 +++++++++++++++++++++++----- src/spicelib/devices/mos1/mos1set.c | 3 ++ src/spicelib/devices/mos2/mos2.c | 3 +- src/spicelib/devices/mos2/mos2defs.h | 3 ++ src/spicelib/devices/mos2/mos2mask.c | 3 ++ src/spicelib/devices/mos2/mos2mpar.c | 4 +++ src/spicelib/devices/mos2/mos2noi.c | 46 +++++++++++++++++++++++----- src/spicelib/devices/mos2/mos2set.c | 3 ++ src/spicelib/devices/mos3/mos3.c | 3 +- src/spicelib/devices/mos3/mos3defs.h | 3 ++ src/spicelib/devices/mos3/mos3mask.c | 3 ++ src/spicelib/devices/mos3/mos3mpar.c | 4 +++ src/spicelib/devices/mos3/mos3noi.c | 46 +++++++++++++++++++++++----- src/spicelib/devices/mos3/mos3set.c | 3 ++ 18 files changed, 162 insertions(+), 24 deletions(-) diff --git a/src/spicelib/devices/mos1/mos1.c b/src/spicelib/devices/mos1/mos1.c index 54bee5f79..f7931a530 100644 --- a/src/spicelib/devices/mos1/mos1.c +++ b/src/spicelib/devices/mos1/mos1.c @@ -148,7 +148,8 @@ IFparm MOS1mPTable[] = { /* model parameters */ IOP("nss", MOS1_MOD_NSS, IF_REAL ,"Surface state density"), IOP("tnom", MOS1_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"), IOP("kf", MOS1_MOD_KF, IF_REAL ,"Flicker noise coefficient"), - IOP("af", MOS1_MOD_AF, IF_REAL ,"Flicker noise exponent") + IOP("af", MOS1_MOD_AF, IF_REAL ,"Flicker noise exponent"), + IOP("nlev", MOS1_MOD_NLEV, IF_INTEGER ,"Noise model selection") }; char *MOS1names[] = { diff --git a/src/spicelib/devices/mos1/mos1defs.h b/src/spicelib/devices/mos1/mos1defs.h index b6fc299b3..231388ac0 100644 --- a/src/spicelib/devices/mos1/mos1defs.h +++ b/src/spicelib/devices/mos1/mos1defs.h @@ -383,6 +383,7 @@ typedef struct sMOS1model { /* model structure for a resistor */ double MOS1surfaceMobility; /* input - use tSurfMob */ double MOS1fNcoef; double MOS1fNexp; + int MOS1nlev; unsigned MOS1typeGiven :1; unsigned MOS1latDiffGiven :1; @@ -415,6 +416,7 @@ typedef struct sMOS1model { /* model structure for a resistor */ unsigned MOS1tnomGiven :1; unsigned MOS1fNcoefGiven :1; unsigned MOS1fNexpGiven :1; + unsigned MOS1nlevGiven :1; } MOS1model; @@ -483,6 +485,7 @@ enum { MOS1_MOD_TNOM, MOS1_MOD_KF, MOS1_MOD_AF, + MOS1_MOD_NLEV, MOS1_MOD_TYPE, }; diff --git a/src/spicelib/devices/mos1/mos1mask.c b/src/spicelib/devices/mos1/mos1mask.c index 494392609..c04522f71 100644 --- a/src/spicelib/devices/mos1/mos1mask.c +++ b/src/spicelib/devices/mos1/mos1mask.c @@ -105,6 +105,9 @@ MOS1mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) case MOS1_MOD_NSS: value->rValue = model->MOS1surfaceStateDensity; return(OK); + case MOS1_MOD_NLEV: + value->iValue = model->MOS1nlev; + return(OK); case MOS1_MOD_TYPE: if (model->MOS1type > 0) value->sValue = "nmos"; diff --git a/src/spicelib/devices/mos1/mos1mpar.c b/src/spicelib/devices/mos1/mos1mpar.c index 1986e1750..728fd06d0 100644 --- a/src/spicelib/devices/mos1/mos1mpar.c +++ b/src/spicelib/devices/mos1/mos1mpar.c @@ -147,6 +147,10 @@ MOS1mParam(int param, IFvalue *value, GENmodel *inModel) model->MOS1fNexp = value->rValue; model->MOS1fNexpGiven = TRUE; break; + case MOS1_MOD_NLEV: + model->MOS1nlev = value->iValue; + model->MOS1nlevGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos1/mos1noi.c b/src/spicelib/devices/mos1/mos1noi.c index 07fed16d3..93b93749c 100644 --- a/src/spicelib/devices/mos1/mos1noi.c +++ b/src/spicelib/devices/mos1/mos1noi.c @@ -10,6 +10,7 @@ Modified: 2000 AlansFixes #include "ngspice/iferrmsg.h" #include "ngspice/noisedef.h" #include "ngspice/suffix.h" +#include "ngspice/compatmode.h" /* * MOS1noise (mode, operation, firstModel, ckt, data, OnDens) @@ -108,13 +109,44 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, NevalSrc( & noizDens[MOS1FLNOIZ], NULL, ckt, N_GAIN, inst -> MOS1dNodePrime, inst -> MOS1sNodePrime, (double) 0.0); - noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef * - exp(model -> MOS1fNexp * - log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) / - (data -> freq * - inst -> MOS1w * - (inst -> MOS1l - 2 * model -> MOS1latDiff) * - coxSquared); + if (newcompat.s3) { + noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef * + exp(model -> MOS1fNexp * + log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) / + (data -> freq * + inst -> MOS1w * + (inst -> MOS1l - 2 * model -> MOS1latDiff) * + coxSquared); + } else { + switch (model -> MOS1nlev) { + case 0: + noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef * + exp(model -> MOS1fNexp * + log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) / + (data -> freq * + (inst -> MOS1l - 2 * model -> MOS1latDiff) * + (inst -> MOS1l - 2 * model -> MOS1latDiff) * + sqrt(coxSquared)); + break; + case 1: + noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef * + exp(model -> MOS1fNexp * + log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) / + (data -> freq * + inst -> MOS1w * + (inst -> MOS1l - 2 * model -> MOS1latDiff) * + sqrt(coxSquared)); + break; + case 2: case 3: + noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef * + inst -> MOS1gm * inst -> MOS1gm / + (pow(data -> freq, model -> MOS1fNexp) * + inst -> MOS1w * + (inst -> MOS1l - 2 * model -> MOS1latDiff) * + sqrt(coxSquared)); + break; + } + } lnNdens[MOS1FLNOIZ] = log(MAX(noizDens[MOS1FLNOIZ], N_MINLOG)); diff --git a/src/spicelib/devices/mos1/mos1set.c b/src/spicelib/devices/mos1/mos1set.c index 6912cbe71..65ba81311 100644 --- a/src/spicelib/devices/mos1/mos1set.c +++ b/src/spicelib/devices/mos1/mos1set.c @@ -87,6 +87,9 @@ MOS1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, if(!model->MOS1fNexpGiven) { model->MOS1fNexp = 1; } + if(!model->MOS1nlevGiven) { + model->MOS1nlev = 2; + } /* loop through all the instances of the model */ for (here = MOS1instances(model); here != NULL ; diff --git a/src/spicelib/devices/mos2/mos2.c b/src/spicelib/devices/mos2/mos2.c index d36a08147..040895297 100644 --- a/src/spicelib/devices/mos2/mos2.c +++ b/src/spicelib/devices/mos2/mos2.c @@ -156,7 +156,8 @@ IFparm MOS2mPTable[] = { /* model parameters */ IOP("nfs", MOS2_MOD_NFS, IF_REAL ,"Fast surface state density"), IOPU("tnom", MOS2_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"), IOP("kf", MOS2_MOD_KF, IF_REAL ,"Flicker noise coefficient"), - IOP("af", MOS2_MOD_AF, IF_REAL ,"Flicker noise exponent") + IOP("af", MOS2_MOD_AF, IF_REAL ,"Flicker noise exponent"), + IOP("nlev", MOS2_MOD_NLEV, IF_INTEGER ,"Noise model selection") }; char *MOS2names[] = { diff --git a/src/spicelib/devices/mos2/mos2defs.h b/src/spicelib/devices/mos2/mos2defs.h index bf59484d2..bcce92f49 100644 --- a/src/spicelib/devices/mos2/mos2defs.h +++ b/src/spicelib/devices/mos2/mos2defs.h @@ -390,6 +390,7 @@ typedef struct sMOS2model { /* model structure for a resistor */ double MOS2surfaceMobility; double MOS2fNcoef; double MOS2fNexp; + int MOS2nlev; double MOS2narrowFactor; /* delta */ double MOS2critFieldExp; /* uexp */ @@ -437,6 +438,7 @@ typedef struct sMOS2model { /* model structure for a resistor */ unsigned MOS2channelChargeGiven :1; /* neff */ unsigned MOS2fNcoefGiven :1; unsigned MOS2fNexpGiven :1; + unsigned MOS2nlevGiven :1; } MOS2model; @@ -574,6 +576,7 @@ enum { enum { MOS2_MOD_KF = 139, MOS2_MOD_AF, + MOS2_MOD_NLEV, MOS2_MOD_TYPE, }; diff --git a/src/spicelib/devices/mos2/mos2mask.c b/src/spicelib/devices/mos2/mos2mask.c index b3cfda751..9e149ea72 100644 --- a/src/spicelib/devices/mos2/mos2mask.c +++ b/src/spicelib/devices/mos2/mos2mask.c @@ -130,6 +130,9 @@ MOS2mAsk(CKTcircuit *ckt, GENmodel *inModel, int param, case MOS2_MOD_AF: value->rValue = model->MOS2fNexp; break; + case MOS2_MOD_NLEV: + value->iValue = model->MOS2nlev; + break; case MOS2_MOD_TYPE: if (model->MOS2type > 0) value->sValue = "nmos"; diff --git a/src/spicelib/devices/mos2/mos2mpar.c b/src/spicelib/devices/mos2/mos2mpar.c index 49967db0a..97fb101a0 100644 --- a/src/spicelib/devices/mos2/mos2mpar.c +++ b/src/spicelib/devices/mos2/mos2mpar.c @@ -178,6 +178,10 @@ MOS2mParam(int param, IFvalue *value, GENmodel *inModel) model->MOS2fNexp = value->rValue; model->MOS2fNexpGiven = TRUE; break; + case MOS2_MOD_NLEV: + model->MOS2nlev = value->iValue; + model->MOS2nlevGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos2/mos2noi.c b/src/spicelib/devices/mos2/mos2noi.c index 1b47ab19c..94dfbdf79 100644 --- a/src/spicelib/devices/mos2/mos2noi.c +++ b/src/spicelib/devices/mos2/mos2noi.c @@ -10,6 +10,7 @@ Modified: 2000 AlansFixes #include "ngspice/iferrmsg.h" #include "ngspice/noisedef.h" #include "ngspice/suffix.h" +#include "ngspice/compatmode.h" /* * MOS2noise (mode, operation, firstModel, ckt, data, OnDens) @@ -97,13 +98,44 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, NevalSrc( & noizDens[MOS2FLNOIZ], NULL, ckt, N_GAIN, inst -> MOS2dNodePrime, inst -> MOS2sNodePrime, (double) 0.0); - noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef * - exp(model -> MOS2fNexp * - log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) / - (data -> freq * - inst -> MOS2w * - (inst -> MOS2l - 2 * model -> MOS2latDiff) * - model -> MOS2oxideCapFactor * model -> MOS2oxideCapFactor); + if (newcompat.s3) { + noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef * + exp(model -> MOS2fNexp * + log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) / + (data -> freq * + inst -> MOS2w * + (inst -> MOS2l - 2 * model -> MOS2latDiff) * + model -> MOS2oxideCapFactor * model -> MOS2oxideCapFactor); + } else { + switch (model -> MOS2nlev) { + case 0: + noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef * + exp(model -> MOS2fNexp * + log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) / + (data -> freq * + (inst -> MOS2l - 2 * model -> MOS2latDiff) * + (inst -> MOS2l - 2 * model -> MOS2latDiff) * + model -> MOS2oxideCapFactor); + break; + case 1: + noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef * + exp(model -> MOS2fNexp * + log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) / + (data -> freq * + inst -> MOS2w * + (inst -> MOS2l - 2 * model -> MOS2latDiff) * + model -> MOS2oxideCapFactor); + break; + case 2: case 3: + noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef * + inst -> MOS2gm * inst -> MOS2gm / + (pow(data -> freq, model -> MOS2fNexp) * + inst -> MOS2w * + (inst -> MOS2l - 2 * model -> MOS2latDiff) * + model -> MOS2oxideCapFactor); + break; + } + } lnNdens[MOS2FLNOIZ] = log(MAX(noizDens[MOS2FLNOIZ], N_MINLOG)); diff --git a/src/spicelib/devices/mos2/mos2set.c b/src/spicelib/devices/mos2/mos2set.c index 3c3acfd4d..b23be6d1f 100644 --- a/src/spicelib/devices/mos2/mos2set.c +++ b/src/spicelib/devices/mos2/mos2set.c @@ -116,6 +116,9 @@ MOS2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!model->MOS2fNexpGiven) { model->MOS2fNexp = 1; } + if(!model->MOS2nlevGiven) { + model->MOS2nlev = 2; + } /* loop through all the instances of the model */ for (here = MOS2instances(model); here != NULL ; diff --git a/src/spicelib/devices/mos3/mos3.c b/src/spicelib/devices/mos3/mos3.c index 553840366..72d738eb2 100644 --- a/src/spicelib/devices/mos3/mos3.c +++ b/src/spicelib/devices/mos3/mos3.c @@ -156,7 +156,8 @@ IFparm MOS3mPTable[] = { /* model parameters */ IOP("kappa", MOS3_MOD_KAPPA, IF_REAL ,"Kappa"), IOPU("tnom", MOS3_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"), IOP("kf", MOS3_MOD_KF, IF_REAL ,"Flicker noise coefficient"), - IOP("af", MOS3_MOD_AF, IF_REAL ,"Flicker noise exponent") + IOP("af", MOS3_MOD_AF, IF_REAL ,"Flicker noise exponent"), + IOP("nlev", MOS3_MOD_NLEV, IF_INTEGER ,"Noise model selection") }; char *MOS3names[] = { diff --git a/src/spicelib/devices/mos3/mos3defs.h b/src/spicelib/devices/mos3/mos3defs.h index 7e4c9aba4..7ce5f4bfb 100644 --- a/src/spicelib/devices/mos3/mos3defs.h +++ b/src/spicelib/devices/mos3/mos3defs.h @@ -400,6 +400,7 @@ typedef struct sMOS3model { /* model structure for a resistor */ double MOS3kappa; /* kappa */ double MOS3fNcoef; double MOS3fNexp; + int MOS3nlev; unsigned MOS3typeGiven :1; unsigned MOS3latDiffGiven :1; @@ -442,6 +443,7 @@ typedef struct sMOS3model { /* model structure for a resistor */ unsigned MOS3tnomGiven :1; /* Tnom was given? */ unsigned MOS3fNcoefGiven :1; unsigned MOS3fNexpGiven :1; + unsigned MOS3nlevGiven :1; } MOS3model; @@ -580,6 +582,7 @@ enum { MOS3_MOD_TNOM, MOS3_MOD_KF, MOS3_MOD_AF, + MOS3_MOD_NLEV, MOS3_MOD_TYPE, MOS3_MOD_XL, MOS3_MOD_WD, diff --git a/src/spicelib/devices/mos3/mos3mask.c b/src/spicelib/devices/mos3/mos3mask.c index d66c89029..9f870ec9b 100644 --- a/src/spicelib/devices/mos3/mos3mask.c +++ b/src/spicelib/devices/mos3/mos3mask.c @@ -154,6 +154,9 @@ MOS3mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) case MOS3_MOD_AF: value->rValue = here->MOS3fNexp; return(OK); + case MOS3_MOD_NLEV: + value->iValue = here->MOS3nlev; + return(OK); case MOS3_MOD_TYPE: if (here->MOS3type > 0) value->sValue = "nmos"; diff --git a/src/spicelib/devices/mos3/mos3mpar.c b/src/spicelib/devices/mos3/mos3mpar.c index 8b4a57e87..1564410b0 100644 --- a/src/spicelib/devices/mos3/mos3mpar.c +++ b/src/spicelib/devices/mos3/mos3mpar.c @@ -191,6 +191,10 @@ MOS3mParam(int param, IFvalue *value, GENmodel *inModel) model->MOS3fNexp = value->rValue; model->MOS3fNexpGiven = TRUE; break; + case MOS3_MOD_NLEV: + model->MOS3nlev = value->iValue; + model->MOS3nlevGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos3/mos3noi.c b/src/spicelib/devices/mos3/mos3noi.c index 6265dec93..33d8bd344 100644 --- a/src/spicelib/devices/mos3/mos3noi.c +++ b/src/spicelib/devices/mos3/mos3noi.c @@ -10,6 +10,7 @@ Modified: 2000 AlansFixes #include "ngspice/iferrmsg.h" #include "ngspice/noisedef.h" #include "ngspice/suffix.h" +#include "ngspice/compatmode.h" /* * MOS3noise (mode, operation, firstModel, ckt, data, OnDens) @@ -97,13 +98,44 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, NevalSrc( & noizDens[MOS3FLNOIZ], NULL, ckt, N_GAIN, inst -> MOS3dNodePrime, inst -> MOS3sNodePrime, (double) 0.0); - noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef * - exp(model -> MOS3fNexp * - log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) / - (data -> freq * - (inst -> MOS3w - 2 * model -> MOS3widthNarrow) * - (inst -> MOS3l - 2 * model -> MOS3latDiff) * - model -> MOS3oxideCapFactor * model -> MOS3oxideCapFactor); + if (newcompat.s3) { + noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef * + exp(model -> MOS3fNexp * + log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) / + (data -> freq * + (inst -> MOS3w - 2 * model -> MOS3widthNarrow) * + (inst -> MOS3l - 2 * model -> MOS3latDiff) * + model -> MOS3oxideCapFactor * model -> MOS3oxideCapFactor); + } else { + switch (model -> MOS3nlev) { + case 0: + noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef * + exp(model -> MOS3fNexp * + log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) / + (data -> freq * + (inst -> MOS3l - 2 * model -> MOS3latDiff) * + (inst -> MOS3l - 2 * model -> MOS3latDiff) * + model -> MOS3oxideCapFactor); + break; + case 1: + noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef * + exp(model -> MOS3fNexp * + log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) / + (data -> freq * + (inst -> MOS3w - 2 * model -> MOS3widthNarrow) * + (inst -> MOS3l - 2 * model -> MOS3latDiff) * + model -> MOS3oxideCapFactor); + break; + case 2: case 3: + noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef * + inst -> MOS3gm * inst -> MOS3gm / + (pow(data -> freq, model -> MOS3fNexp) * + (inst -> MOS3w - 2 * model -> MOS3widthNarrow) * + (inst -> MOS3l - 2 * model -> MOS3latDiff) * + model -> MOS3oxideCapFactor); + break; + } + } lnNdens[MOS3FLNOIZ] = log(MAX(noizDens[MOS3FLNOIZ], N_MINLOG)); diff --git a/src/spicelib/devices/mos3/mos3set.c b/src/spicelib/devices/mos3/mos3set.c index 4432ba461..d494f8434 100644 --- a/src/spicelib/devices/mos3/mos3set.c +++ b/src/spicelib/devices/mos3/mos3set.c @@ -139,6 +139,9 @@ MOS3setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!model->MOS3fNexpGiven) { model->MOS3fNexp = 1; } + if(!model->MOS3nlevGiven) { + model->MOS3nlev = 2; + } /* loop through all the instances of the model */ for (here = MOS3instances(model); here != NULL ; From 89c7b83954998ea1296428541852104105f7b35d Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 23 Jan 2024 17:01:05 +0100 Subject: [PATCH 13/20] mos1...3: formatting and white spaces --- src/spicelib/devices/mos1/mos1mask.c | 8 +- src/spicelib/devices/mos1/mos1mpar.c | 24 +++--- src/spicelib/devices/mos1/mos1noi.c | 120 +++++++++++++------------- src/spicelib/devices/mos1/mos1set.c | 82 +++++++++--------- src/spicelib/devices/mos2/mos2mask.c | 30 +++---- src/spicelib/devices/mos2/mos2mpar.c | 24 +++--- src/spicelib/devices/mos2/mos2noi.c | 124 +++++++++++++-------------- src/spicelib/devices/mos2/mos2set.c | 84 +++++++++--------- src/spicelib/devices/mos3/mos3mask.c | 20 ++--- src/spicelib/devices/mos3/mos3mpar.c | 26 +++--- src/spicelib/devices/mos3/mos3noi.c | 124 +++++++++++++-------------- src/spicelib/devices/mos3/mos3set.c | 64 +++++++------- 12 files changed, 365 insertions(+), 365 deletions(-) diff --git a/src/spicelib/devices/mos1/mos1mask.c b/src/spicelib/devices/mos1/mos1mask.c index c04522f71..903983103 100644 --- a/src/spicelib/devices/mos1/mos1mask.c +++ b/src/spicelib/devices/mos1/mos1mask.c @@ -109,10 +109,10 @@ MOS1mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) value->iValue = model->MOS1nlev; return(OK); case MOS1_MOD_TYPE: - if (model->MOS1type > 0) - value->sValue = "nmos"; - else - value->sValue = "pmos"; + if (model->MOS1type > 0) + value->sValue = "nmos"; + else + value->sValue = "pmos"; return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/mos1/mos1mpar.c b/src/spicelib/devices/mos1/mos1mpar.c index 728fd06d0..82a5dc714 100644 --- a/src/spicelib/devices/mos1/mos1mpar.c +++ b/src/spicelib/devices/mos1/mos1mpar.c @@ -139,18 +139,18 @@ MOS1mParam(int param, IFvalue *value, GENmodel *inModel) model->MOS1typeGiven = TRUE; } break; - case MOS1_MOD_KF: - model->MOS1fNcoef = value->rValue; - model->MOS1fNcoefGiven = TRUE; - break; - case MOS1_MOD_AF: - model->MOS1fNexp = value->rValue; - model->MOS1fNexpGiven = TRUE; - break; - case MOS1_MOD_NLEV: - model->MOS1nlev = value->iValue; - model->MOS1nlevGiven = TRUE; - break; + case MOS1_MOD_KF: + model->MOS1fNcoef = value->rValue; + model->MOS1fNcoefGiven = TRUE; + break; + case MOS1_MOD_AF: + model->MOS1fNexp = value->rValue; + model->MOS1fNexpGiven = TRUE; + break; + case MOS1_MOD_NLEV: + model->MOS1nlev = value->iValue; + model->MOS1nlevGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos1/mos1noi.c b/src/spicelib/devices/mos1/mos1noi.c index 93b93749c..9d78dd47e 100644 --- a/src/spicelib/devices/mos1/mos1noi.c +++ b/src/spicelib/devices/mos1/mos1noi.c @@ -24,7 +24,7 @@ Modified: 2000 AlansFixes int MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, Ndata * data, double * OnDens) { - NOISEAN * job = (NOISEAN * ) ckt -> CKTcurJob; + NOISEAN * job = (NOISEAN * ) ckt->CKTcurJob; MOS1model * firstModel = (MOS1model * ) genmodel; MOS1model * model; @@ -56,10 +56,10 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, /* Oxide capacitance can be zero in MOS level 1. Since this will give us problems in our 1/f */ /* noise model, we ASSUME an actual "tox" of 1e-7 */ - if (model -> MOS1oxideCapFactor == 0.0) { + if (model->MOS1oxideCapFactor == 0.0) { coxSquared = 3.9 * 8.854214871e-12 / 1e-7; } else { - coxSquared = model -> MOS1oxideCapFactor; + coxSquared = model->MOS1oxideCapFactor; } coxSquared *= coxSquared; for (inst = MOS1instances(model); inst != NULL; inst = MOS1nextInstance(inst)) { @@ -71,19 +71,19 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, /* see if we have to to produce a summary report */ /* if so, name all the noise generators */ - if (job -> NStpsSm != 0) { + if (job->NStpsSm != 0) { switch (mode) { case N_DENS: for (i = 0; i < MOS1NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst -> MOS1name, MOS1nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->MOS1name, MOS1nNames[i]); } break; case INT_NOIZ: for (i = 0; i < MOS1NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst -> MOS1name, MOS1nNames[i]); - NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst -> MOS1name, MOS1nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->MOS1name, MOS1nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->MOS1name, MOS1nNames[i]); } break; } @@ -95,54 +95,54 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, case N_DENS: NevalSrc( & noizDens[MOS1RDNOIZ], & lnNdens[MOS1RDNOIZ], - ckt, THERMNOISE, inst -> MOS1dNodePrime, inst -> MOS1dNode, - inst -> MOS1drainConductance); + ckt, THERMNOISE, inst->MOS1dNodePrime, inst->MOS1dNode, + inst->MOS1drainConductance); NevalSrc( & noizDens[MOS1RSNOIZ], & lnNdens[MOS1RSNOIZ], - ckt, THERMNOISE, inst -> MOS1sNodePrime, inst -> MOS1sNode, - inst -> MOS1sourceConductance); + ckt, THERMNOISE, inst->MOS1sNodePrime, inst->MOS1sNode, + inst->MOS1sourceConductance); NevalSrc( & noizDens[MOS1IDNOIZ], & lnNdens[MOS1IDNOIZ], - ckt, THERMNOISE, inst -> MOS1dNodePrime, inst -> MOS1sNodePrime, - (2.0 / 3.0 * fabs(inst -> MOS1gm))); + ckt, THERMNOISE, inst->MOS1dNodePrime, inst->MOS1sNodePrime, + (2.0 / 3.0 * fabs(inst->MOS1gm))); NevalSrc( & noizDens[MOS1FLNOIZ], NULL, ckt, - N_GAIN, inst -> MOS1dNodePrime, inst -> MOS1sNodePrime, + N_GAIN, inst->MOS1dNodePrime, inst->MOS1sNodePrime, (double) 0.0); if (newcompat.s3) { - noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef * - exp(model -> MOS1fNexp * - log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) / - (data -> freq * - inst -> MOS1w * - (inst -> MOS1l - 2 * model -> MOS1latDiff) * + noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef * + exp(model->MOS1fNexp * + log(MAX(fabs(inst->MOS1cd), N_MINLOG))) / + (data->freq * + inst->MOS1w * + (inst->MOS1l - 2 * model->MOS1latDiff) * coxSquared); } else { - switch (model -> MOS1nlev) { + switch (model->MOS1nlev) { case 0: - noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef * - exp(model -> MOS1fNexp * - log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) / - (data -> freq * - (inst -> MOS1l - 2 * model -> MOS1latDiff) * - (inst -> MOS1l - 2 * model -> MOS1latDiff) * + noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef * + exp(model->MOS1fNexp * + log(MAX(fabs(inst->MOS1cd), N_MINLOG))) / + (data->freq * + (inst->MOS1l - 2 * model->MOS1latDiff) * + (inst->MOS1l - 2 * model->MOS1latDiff) * sqrt(coxSquared)); break; case 1: - noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef * - exp(model -> MOS1fNexp * - log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) / - (data -> freq * - inst -> MOS1w * - (inst -> MOS1l - 2 * model -> MOS1latDiff) * + noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef * + exp(model->MOS1fNexp * + log(MAX(fabs(inst->MOS1cd), N_MINLOG))) / + (data->freq * + inst->MOS1w * + (inst->MOS1l - 2 * model->MOS1latDiff) * sqrt(coxSquared)); break; case 2: case 3: - noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef * - inst -> MOS1gm * inst -> MOS1gm / - (pow(data -> freq, model -> MOS1fNexp) * - inst -> MOS1w * - (inst -> MOS1l - 2 * model -> MOS1latDiff) * + noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef * + inst->MOS1gm * inst->MOS1gm / + (pow(data->freq, model->MOS1fNexp) * + inst->MOS1w * + (inst->MOS1l - 2 * model->MOS1latDiff) * sqrt(coxSquared)); break; } @@ -159,21 +159,21 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, * OnDens += noizDens[MOS1TOTNOIZ]; - if (data -> delFreq == 0.0) { + if (data->delFreq == 0.0) { /* if we haven't done any previous integration, we need to */ /* initialize our "history" variables */ for (i = 0; i < MOS1NSRCS; i++) { - inst -> MOS1nVar[LNLSTDENS][i] = lnNdens[i]; + inst->MOS1nVar[LNLSTDENS][i] = lnNdens[i]; } /* clear out our integration variables if it's the first pass */ - if (data -> freq == job -> NstartFreq) { + if (data->freq == job->NstartFreq) { for (i = 0; i < MOS1NSRCS; i++) { - inst -> MOS1nVar[OUTNOIZ][i] = 0.0; - inst -> MOS1nVar[INNOIZ][i] = 0.0; + inst->MOS1nVar[OUTNOIZ][i] = 0.0; + inst->MOS1nVar[INNOIZ][i] = 0.0; } } } else { @@ -181,37 +181,37 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, for (i = 0; i < MOS1NSRCS; i++) { if (i != MOS1TOTNOIZ) { tempOnoise = Nintegrate(noizDens[i], lnNdens[i], - inst -> MOS1nVar[LNLSTDENS][i], data); - tempInoise = Nintegrate(noizDens[i] * data -> GainSqInv, - lnNdens[i] + data -> lnGainInv, - inst -> MOS1nVar[LNLSTDENS][i] + data -> lnGainInv, + inst->MOS1nVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data->GainSqInv, + lnNdens[i] + data->lnGainInv, + inst->MOS1nVar[LNLSTDENS][i] + data->lnGainInv, data); - inst -> MOS1nVar[LNLSTDENS][i] = lnNdens[i]; - data -> outNoiz += tempOnoise; - data -> inNoise += tempInoise; - if (job -> NStpsSm != 0) { - inst -> MOS1nVar[OUTNOIZ][i] += tempOnoise; - inst -> MOS1nVar[OUTNOIZ][MOS1TOTNOIZ] += tempOnoise; - inst -> MOS1nVar[INNOIZ][i] += tempInoise; - inst -> MOS1nVar[INNOIZ][MOS1TOTNOIZ] += tempInoise; + inst->MOS1nVar[LNLSTDENS][i] = lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (job->NStpsSm != 0) { + inst->MOS1nVar[OUTNOIZ][i] += tempOnoise; + inst->MOS1nVar[OUTNOIZ][MOS1TOTNOIZ] += tempOnoise; + inst->MOS1nVar[INNOIZ][i] += tempInoise; + inst->MOS1nVar[INNOIZ][MOS1TOTNOIZ] += tempInoise; } } } } - if (data -> prtSummary) { + if (data->prtSummary) { for (i = 0; i < MOS1NSRCS; i++) { /* print a summary report */ - data -> outpVector[data -> outNumber++] = noizDens[i]; + data->outpVector[data->outNumber++] = noizDens[i]; } } break; case INT_NOIZ: /* already calculated, just output */ - if (job -> NStpsSm != 0) { + if (job->NStpsSm != 0) { for (i = 0; i < MOS1NSRCS; i++) { - data -> outpVector[data -> outNumber++] = inst -> MOS1nVar[OUTNOIZ][i]; - data -> outpVector[data -> outNumber++] = inst -> MOS1nVar[INNOIZ][i]; + data->outpVector[data->outNumber++] = inst->MOS1nVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] = inst->MOS1nVar[INNOIZ][i]; } } /* if */ break; diff --git a/src/spicelib/devices/mos1/mos1set.c b/src/spicelib/devices/mos1/mos1set.c index 65ba81311..313926e55 100644 --- a/src/spicelib/devices/mos1/mos1set.c +++ b/src/spicelib/devices/mos1/mos1set.c @@ -4,8 +4,8 @@ Author: 1985 Thomas L. Quarles Modified: 2000 AlansFixes **********/ - /* load the MOS1 device structure with those pointers needed later - * for fast matrix loading + /* load the MOS1 device structure with those pointers needed later + * for fast matrix loading */ #include "ngspice/ngspice.h" @@ -81,15 +81,15 @@ MOS1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, if(!model->MOS1gammaGiven) { model->MOS1gamma = 0; } - if(!model->MOS1fNcoefGiven) { - model->MOS1fNcoef = 0; - } - if(!model->MOS1fNexpGiven) { - model->MOS1fNexp = 1; - } - if(!model->MOS1nlevGiven) { - model->MOS1nlev = 2; - } + if(!model->MOS1fNcoefGiven) { + model->MOS1fNcoef = 0; + } + if(!model->MOS1fNexpGiven) { + model->MOS1fNexp = 1; + } + if(!model->MOS1nlevGiven) { + model->MOS1nlev = 2; + } /* loop through all the instances of the model */ for (here = MOS1instances(model); here != NULL ; @@ -124,34 +124,34 @@ MOS1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, if(!here->MOS1vonGiven) { here->MOS1von = 0; } - if(!here->MOS1drainSquaresGiven) { - here->MOS1drainSquares=1; - } - if(!here->MOS1sourceSquaresGiven) { - here->MOS1sourceSquares=1; - } + if(!here->MOS1drainSquaresGiven) { + here->MOS1drainSquares=1; + } + if(!here->MOS1sourceSquaresGiven) { + here->MOS1sourceSquares=1; + } if ((model->MOS1drainResistance != 0 - || (model->MOS1sheetResistance != 0 + || (model->MOS1sheetResistance != 0 && here->MOS1drainSquares != 0) )) { if (here->MOS1dNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->MOS1name,"drain"); if(error) return(error); here->MOS1dNodePrime = tmp->number; - + if (ckt->CKTcopyNodesets) { - CKTnode *tmpNode; - IFuid tmpName; + CKTnode *tmpNode; + IFuid tmpName; if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; } } } } - + } else { here->MOS1dNodePrime = here->MOS1dNode; } @@ -163,19 +163,19 @@ MOS1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, error = CKTmkVolt(ckt,&tmp,here->MOS1name,"source"); if(error) return(error); here->MOS1sNodePrime = tmp->number; - + if (ckt->CKTcopyNodesets) { - CKTnode *tmpNode; - IFuid tmpName; + CKTnode *tmpNode; + IFuid tmpName; if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; } } } - + } } else { here->MOS1sNodePrime = here->MOS1sNode; @@ -221,21 +221,21 @@ MOS1unsetup(GENmodel *inModel, CKTcircuit *ckt) MOS1instance *here; for (model = (MOS1model *)inModel; model != NULL; - model = MOS1nextModel(model)) + model = MOS1nextModel(model)) { for (here = MOS1instances(model); here != NULL; here=MOS1nextInstance(here)) - { - if (here->MOS1sNodePrime > 0 - && here->MOS1sNodePrime != here->MOS1sNode) - CKTdltNNum(ckt, here->MOS1sNodePrime); - here->MOS1sNodePrime= 0; + { + if (here->MOS1sNodePrime > 0 + && here->MOS1sNodePrime != here->MOS1sNode) + CKTdltNNum(ckt, here->MOS1sNodePrime); + here->MOS1sNodePrime= 0; - if (here->MOS1dNodePrime > 0 - && here->MOS1dNodePrime != here->MOS1dNode) - CKTdltNNum(ckt, here->MOS1dNodePrime); - here->MOS1dNodePrime= 0; - } + if (here->MOS1dNodePrime > 0 + && here->MOS1dNodePrime != here->MOS1dNode) + CKTdltNNum(ckt, here->MOS1dNodePrime); + here->MOS1dNodePrime= 0; + } } return OK; } diff --git a/src/spicelib/devices/mos2/mos2mask.c b/src/spicelib/devices/mos2/mos2mask.c index 9e149ea72..7cc54359f 100644 --- a/src/spicelib/devices/mos2/mos2mask.c +++ b/src/spicelib/devices/mos2/mos2mask.c @@ -124,21 +124,21 @@ MOS2mAsk(CKTcircuit *ckt, GENmodel *inModel, int param, case MOS2_MOD_UCRIT: value->rValue = model->MOS2critField; break; - case MOS2_MOD_KF: - value->rValue = model->MOS2fNcoef; - break; - case MOS2_MOD_AF: - value->rValue = model->MOS2fNexp; - break; - case MOS2_MOD_NLEV: - value->iValue = model->MOS2nlev; - break; - case MOS2_MOD_TYPE: - if (model->MOS2type > 0) - value->sValue = "nmos"; - else - value->sValue = "pmos"; - break; + case MOS2_MOD_KF: + value->rValue = model->MOS2fNcoef; + break; + case MOS2_MOD_AF: + value->rValue = model->MOS2fNexp; + break; + case MOS2_MOD_NLEV: + value->iValue = model->MOS2nlev; + break; + case MOS2_MOD_TYPE: + if (model->MOS2type > 0) + value->sValue = "nmos"; + else + value->sValue = "pmos"; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos2/mos2mpar.c b/src/spicelib/devices/mos2/mos2mpar.c index 97fb101a0..175858cbb 100644 --- a/src/spicelib/devices/mos2/mos2mpar.c +++ b/src/spicelib/devices/mos2/mos2mpar.c @@ -170,18 +170,18 @@ MOS2mParam(int param, IFvalue *value, GENmodel *inModel) model->MOS2typeGiven = TRUE; } break; - case MOS2_MOD_KF: - model->MOS2fNcoef = value->rValue; - model->MOS2fNcoefGiven = TRUE; - break; - case MOS2_MOD_AF: - model->MOS2fNexp = value->rValue; - model->MOS2fNexpGiven = TRUE; - break; - case MOS2_MOD_NLEV: - model->MOS2nlev = value->iValue; - model->MOS2nlevGiven = TRUE; - break; + case MOS2_MOD_KF: + model->MOS2fNcoef = value->rValue; + model->MOS2fNcoefGiven = TRUE; + break; + case MOS2_MOD_AF: + model->MOS2fNexp = value->rValue; + model->MOS2fNexpGiven = TRUE; + break; + case MOS2_MOD_NLEV: + model->MOS2nlev = value->iValue; + model->MOS2nlevGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos2/mos2noi.c b/src/spicelib/devices/mos2/mos2noi.c index 94dfbdf79..90da7b2d1 100644 --- a/src/spicelib/devices/mos2/mos2noi.c +++ b/src/spicelib/devices/mos2/mos2noi.c @@ -24,7 +24,7 @@ Modified: 2000 AlansFixes int MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, Ndata * data, double * OnDens) { - NOISEAN * job = (NOISEAN * ) ckt -> CKTcurJob; + NOISEAN * job = (NOISEAN * ) ckt->CKTcurJob; MOS2model * firstModel = (MOS2model * ) genmodel; MOS2model * model; @@ -60,19 +60,19 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, /* see if we have to to produce a summary report */ /* if so, name all the noise generators */ - if (job -> NStpsSm != 0) { + if (job->NStpsSm != 0) { switch (mode) { case N_DENS: for (i = 0; i < MOS2NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst -> MOS2name, MOS2nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->MOS2name, MOS2nNames[i]); } break; case INT_NOIZ: for (i = 0; i < MOS2NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst -> MOS2name, MOS2nNames[i]); - NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst -> MOS2name, MOS2nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->MOS2name, MOS2nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->MOS2name, MOS2nNames[i]); } break; } @@ -84,55 +84,55 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, case N_DENS: NevalSrc( & noizDens[MOS2RDNOIZ], & lnNdens[MOS2RDNOIZ], - ckt, THERMNOISE, inst -> MOS2dNodePrime, inst -> MOS2dNode, - inst -> MOS2drainConductance); + ckt, THERMNOISE, inst->MOS2dNodePrime, inst->MOS2dNode, + inst->MOS2drainConductance); NevalSrc( & noizDens[MOS2RSNOIZ], & lnNdens[MOS2RSNOIZ], - ckt, THERMNOISE, inst -> MOS2sNodePrime, inst -> MOS2sNode, - inst -> MOS2sourceConductance); + ckt, THERMNOISE, inst->MOS2sNodePrime, inst->MOS2sNode, + inst->MOS2sourceConductance); NevalSrc( & noizDens[MOS2IDNOIZ], & lnNdens[MOS2IDNOIZ], - ckt, THERMNOISE, inst -> MOS2dNodePrime, inst -> MOS2sNodePrime, - (2.0 / 3.0 * fabs(inst -> MOS2gm))); + ckt, THERMNOISE, inst->MOS2dNodePrime, inst->MOS2sNodePrime, + (2.0 / 3.0 * fabs(inst->MOS2gm))); NevalSrc( & noizDens[MOS2FLNOIZ], NULL, ckt, - N_GAIN, inst -> MOS2dNodePrime, inst -> MOS2sNodePrime, + N_GAIN, inst->MOS2dNodePrime, inst->MOS2sNodePrime, (double) 0.0); if (newcompat.s3) { - noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef * - exp(model -> MOS2fNexp * - log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) / - (data -> freq * - inst -> MOS2w * - (inst -> MOS2l - 2 * model -> MOS2latDiff) * - model -> MOS2oxideCapFactor * model -> MOS2oxideCapFactor); + noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * + exp(model->MOS2fNexp * + log(MAX(fabs(inst->MOS2cd), N_MINLOG))) / + (data->freq * + inst->MOS2w * + (inst->MOS2l - 2 * model->MOS2latDiff) * + model->MOS2oxideCapFactor * model->MOS2oxideCapFactor); } else { - switch (model -> MOS2nlev) { + switch (model->MOS2nlev) { case 0: - noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef * - exp(model -> MOS2fNexp * - log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) / - (data -> freq * - (inst -> MOS2l - 2 * model -> MOS2latDiff) * - (inst -> MOS2l - 2 * model -> MOS2latDiff) * - model -> MOS2oxideCapFactor); + noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * + exp(model->MOS2fNexp * + log(MAX(fabs(inst->MOS2cd), N_MINLOG))) / + (data->freq * + (inst->MOS2l - 2 * model->MOS2latDiff) * + (inst->MOS2l - 2 * model->MOS2latDiff) * + model->MOS2oxideCapFactor); break; case 1: - noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef * - exp(model -> MOS2fNexp * - log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) / - (data -> freq * - inst -> MOS2w * - (inst -> MOS2l - 2 * model -> MOS2latDiff) * - model -> MOS2oxideCapFactor); + noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * + exp(model->MOS2fNexp * + log(MAX(fabs(inst->MOS2cd), N_MINLOG))) / + (data->freq * + inst->MOS2w * + (inst->MOS2l - 2 * model->MOS2latDiff) * + model->MOS2oxideCapFactor); break; case 2: case 3: - noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef * - inst -> MOS2gm * inst -> MOS2gm / - (pow(data -> freq, model -> MOS2fNexp) * - inst -> MOS2w * - (inst -> MOS2l - 2 * model -> MOS2latDiff) * - model -> MOS2oxideCapFactor); + noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * + inst->MOS2gm * inst->MOS2gm / + (pow(data->freq, model->MOS2fNexp) * + inst->MOS2w * + (inst->MOS2l - 2 * model->MOS2latDiff) * + model->MOS2oxideCapFactor); break; } } @@ -148,21 +148,21 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, * OnDens += noizDens[MOS2TOTNOIZ]; - if (data -> delFreq == 0.0) { + if (data->delFreq == 0.0) { /* if we haven't done any previous integration, we need to */ /* initialize our "history" variables */ for (i = 0; i < MOS2NSRCS; i++) { - inst -> MOS2nVar[LNLSTDENS][i] = lnNdens[i]; + inst->MOS2nVar[LNLSTDENS][i] = lnNdens[i]; } /* clear out our integration variables if it's the first pass */ - if (data -> freq == job -> NstartFreq) { + if (data->freq == job->NstartFreq) { for (i = 0; i < MOS2NSRCS; i++) { - inst -> MOS2nVar[OUTNOIZ][i] = 0.0; - inst -> MOS2nVar[INNOIZ][i] = 0.0; + inst->MOS2nVar[OUTNOIZ][i] = 0.0; + inst->MOS2nVar[INNOIZ][i] = 0.0; } } } else { @@ -170,37 +170,37 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, for (i = 0; i < MOS2NSRCS; i++) { if (i != MOS2TOTNOIZ) { tempOnoise = Nintegrate(noizDens[i], lnNdens[i], - inst -> MOS2nVar[LNLSTDENS][i], data); - tempInoise = Nintegrate(noizDens[i] * data -> GainSqInv, - lnNdens[i] + data -> lnGainInv, - inst -> MOS2nVar[LNLSTDENS][i] + data -> lnGainInv, + inst->MOS2nVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data->GainSqInv, + lnNdens[i] + data->lnGainInv, + inst->MOS2nVar[LNLSTDENS][i] + data->lnGainInv, data); - inst -> MOS2nVar[LNLSTDENS][i] = lnNdens[i]; - data -> outNoiz += tempOnoise; - data -> inNoise += tempInoise; - if (job -> NStpsSm != 0) { - inst -> MOS2nVar[OUTNOIZ][i] += tempOnoise; - inst -> MOS2nVar[OUTNOIZ][MOS2TOTNOIZ] += tempOnoise; - inst -> MOS2nVar[INNOIZ][i] += tempInoise; - inst -> MOS2nVar[INNOIZ][MOS2TOTNOIZ] += tempInoise; + inst->MOS2nVar[LNLSTDENS][i] = lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (job->NStpsSm != 0) { + inst->MOS2nVar[OUTNOIZ][i] += tempOnoise; + inst->MOS2nVar[OUTNOIZ][MOS2TOTNOIZ] += tempOnoise; + inst->MOS2nVar[INNOIZ][i] += tempInoise; + inst->MOS2nVar[INNOIZ][MOS2TOTNOIZ] += tempInoise; } } } } - if (data -> prtSummary) { + if (data->prtSummary) { for (i = 0; i < MOS2NSRCS; i++) { /* print a summary report */ - data -> outpVector[data -> outNumber++] = noizDens[i]; + data->outpVector[data->outNumber++] = noizDens[i]; } } break; case INT_NOIZ: /* already calculated, just output */ - if (job -> NStpsSm != 0) { + if (job->NStpsSm != 0) { for (i = 0; i < MOS2NSRCS; i++) { - data -> outpVector[data -> outNumber++] = inst -> MOS2nVar[OUTNOIZ][i]; - data -> outpVector[data -> outNumber++] = inst -> MOS2nVar[INNOIZ][i]; + data->outpVector[data->outNumber++] = inst->MOS2nVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] = inst->MOS2nVar[INNOIZ][i]; } } /* if */ break; diff --git a/src/spicelib/devices/mos2/mos2set.c b/src/spicelib/devices/mos2/mos2set.c index b23be6d1f..9f8e9eac6 100644 --- a/src/spicelib/devices/mos2/mos2set.c +++ b/src/spicelib/devices/mos2/mos2set.c @@ -14,8 +14,8 @@ Modified: 2000 AlansFixes int MOS2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) - /* load the MOS2 device structure with those pointers needed later - * for fast matrix loading + /* load the MOS2 device structure with those pointers needed later + * for fast matrix loading */ { MOS2model *model = (MOS2model *)inModel; @@ -110,23 +110,23 @@ MOS2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!model->MOS2fastSurfaceStateDensityGiven) { model->MOS2fastSurfaceStateDensity = 0; } - if(!model->MOS2fNcoefGiven) { - model->MOS2fNcoef = 0; - } - if(!model->MOS2fNexpGiven) { - model->MOS2fNexp = 1; - } - if(!model->MOS2nlevGiven) { - model->MOS2nlev = 2; - } + if(!model->MOS2fNcoefGiven) { + model->MOS2fNcoef = 0; + } + if(!model->MOS2fNexpGiven) { + model->MOS2fNexp = 1; + } + if(!model->MOS2nlevGiven) { + model->MOS2nlev = 2; + } /* loop through all the instances of the model */ for (here = MOS2instances(model); here != NULL ; here=MOS2nextInstance(here)) { - - CKTnode *tmpNode; - IFuid tmpName; - + + CKTnode *tmpNode; + IFuid tmpName; + /* allocate a chunk of the state vector */ here->MOS2states = *states; *states += MOS2numStates; @@ -153,52 +153,52 @@ MOS2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!here->MOS2vdsatGiven) { here->MOS2vdsat = 0; } - if (!here->MOS2drainSquaresGiven) { - here->MOS2drainSquares=1; - } - if (!here->MOS2sourceSquaresGiven) { - here->MOS2sourceSquares=1; - } + if (!here->MOS2drainSquaresGiven) { + here->MOS2drainSquares=1; + } + if (!here->MOS2sourceSquaresGiven) { + here->MOS2sourceSquares=1; + } if ((model->MOS2drainResistance != 0 || (here->MOS2drainSquares != 0 - && model->MOS2sheetResistance != 0))) { + && model->MOS2sheetResistance != 0))) { if (here->MOS2dNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->MOS2name,"internal#drain"); if(error) return(error); here->MOS2dNodePrime = tmp->number; - + if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; } } } } - + } else { here->MOS2dNodePrime = here->MOS2dNode; } - if( ( (model->MOS2sourceResistance != 0) || + if( ( (model->MOS2sourceResistance != 0) || ((here->MOS2sourceSquares != 0) && (model->MOS2sheetResistance != 0)) )) { if (here->MOS2sNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->MOS2name,"internal#source"); if(error) return(error); here->MOS2sNodePrime = tmp->number; - + if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; } } } } - + } else { here->MOS2sNodePrime = here->MOS2sNode; } @@ -244,21 +244,21 @@ MOS2unsetup(GENmodel *inModel, CKTcircuit *ckt) MOS2instance *here; for (model = (MOS2model *)inModel; model != NULL; - model = MOS2nextModel(model)) + model = MOS2nextModel(model)) { for (here = MOS2instances(model); here != NULL; here=MOS2nextInstance(here)) - { - if (here->MOS2sNodePrime > 0 - && here->MOS2sNodePrime != here->MOS2sNode) - CKTdltNNum(ckt, here->MOS2sNodePrime); - here->MOS2sNodePrime = 0; + { + if (here->MOS2sNodePrime > 0 + && here->MOS2sNodePrime != here->MOS2sNode) + CKTdltNNum(ckt, here->MOS2sNodePrime); + here->MOS2sNodePrime = 0; - if (here->MOS2dNodePrime > 0 - && here->MOS2dNodePrime != here->MOS2dNode) - CKTdltNNum(ckt, here->MOS2dNodePrime); - here->MOS2dNodePrime = 0; - } + if (here->MOS2dNodePrime > 0 + && here->MOS2dNodePrime != here->MOS2dNode) + CKTdltNNum(ckt, here->MOS2dNodePrime); + here->MOS2dNodePrime = 0; + } } return OK; } diff --git a/src/spicelib/devices/mos3/mos3mask.c b/src/spicelib/devices/mos3/mos3mask.c index 9f870ec9b..f3a07716d 100644 --- a/src/spicelib/devices/mos3/mos3mask.c +++ b/src/spicelib/devices/mos3/mos3mask.c @@ -99,7 +99,7 @@ MOS3mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) return(OK); case MOS3_MOD_DELVTO: value->rValue = here->MOS3delvt0; - return(OK); + return(OK); case MOS3_MOD_RSH: value->rValue = here->MOS3sheetResistance; return(OK); @@ -147,22 +147,22 @@ MOS3mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) return(OK); case MOS3_MOD_KAPPA: value->rValue = here->MOS3kappa; - return(OK); + return(OK); case MOS3_MOD_KF: value->rValue = here->MOS3fNcoef; return(OK); case MOS3_MOD_AF: value->rValue = here->MOS3fNexp; - return(OK); + return(OK); case MOS3_MOD_NLEV: value->iValue = here->MOS3nlev; - return(OK); - case MOS3_MOD_TYPE: - if (here->MOS3type > 0) - value->sValue = "nmos"; - else - value->sValue = "pmos"; - return(OK); + return(OK); + case MOS3_MOD_TYPE: + if (here->MOS3type > 0) + value->sValue = "nmos"; + else + value->sValue = "pmos"; + return(OK); default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos3/mos3mpar.c b/src/spicelib/devices/mos3/mos3mpar.c index 1564410b0..890d0b4bb 100644 --- a/src/spicelib/devices/mos3/mos3mpar.c +++ b/src/spicelib/devices/mos3/mos3mpar.c @@ -118,7 +118,7 @@ MOS3mParam(int param, IFvalue *value, GENmodel *inModel) case MOS3_MOD_DELVTO: model->MOS3delvt0 = value->rValue; model->MOS3delvt0Given = TRUE; - break; + break; case MOS3_MOD_U0: model->MOS3surfaceMobility = value->rValue; model->MOS3surfaceMobilityGiven = TRUE; @@ -183,18 +183,18 @@ MOS3mParam(int param, IFvalue *value, GENmodel *inModel) model->MOS3tnom = value->rValue+CONSTCtoK; model->MOS3tnomGiven = TRUE; break; - case MOS3_MOD_KF: - model->MOS3fNcoef = value->rValue; - model->MOS3fNcoefGiven = TRUE; - break; - case MOS3_MOD_AF: - model->MOS3fNexp = value->rValue; - model->MOS3fNexpGiven = TRUE; - break; - case MOS3_MOD_NLEV: - model->MOS3nlev = value->iValue; - model->MOS3nlevGiven = TRUE; - break; + case MOS3_MOD_KF: + model->MOS3fNcoef = value->rValue; + model->MOS3fNcoefGiven = TRUE; + break; + case MOS3_MOD_AF: + model->MOS3fNexp = value->rValue; + model->MOS3fNexpGiven = TRUE; + break; + case MOS3_MOD_NLEV: + model->MOS3nlev = value->iValue; + model->MOS3nlevGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos3/mos3noi.c b/src/spicelib/devices/mos3/mos3noi.c index 33d8bd344..b6e79bba7 100644 --- a/src/spicelib/devices/mos3/mos3noi.c +++ b/src/spicelib/devices/mos3/mos3noi.c @@ -24,7 +24,7 @@ Modified: 2000 AlansFixes int MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, Ndata * data, double * OnDens) { - NOISEAN * job = (NOISEAN * ) ckt -> CKTcurJob; + NOISEAN * job = (NOISEAN * ) ckt->CKTcurJob; MOS3model * firstModel = (MOS3model * ) genmodel; MOS3model * model; @@ -60,19 +60,19 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, /* see if we have to to produce a summary report */ /* if so, name all the noise generators */ - if (job -> NStpsSm != 0) { + if (job->NStpsSm != 0) { switch (mode) { case N_DENS: for (i = 0; i < MOS3NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst -> MOS3name, MOS3nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->MOS3name, MOS3nNames[i]); } break; case INT_NOIZ: for (i = 0; i < MOS3NSRCS; i++) { - NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst -> MOS3name, MOS3nNames[i]); - NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst -> MOS3name, MOS3nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->MOS3name, MOS3nNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->MOS3name, MOS3nNames[i]); } break; } @@ -84,55 +84,55 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, case N_DENS: NevalSrc( & noizDens[MOS3RDNOIZ], & lnNdens[MOS3RDNOIZ], - ckt, THERMNOISE, inst -> MOS3dNodePrime, inst -> MOS3dNode, - inst -> MOS3drainConductance); + ckt, THERMNOISE, inst->MOS3dNodePrime, inst->MOS3dNode, + inst->MOS3drainConductance); NevalSrc( & noizDens[MOS3RSNOIZ], & lnNdens[MOS3RSNOIZ], - ckt, THERMNOISE, inst -> MOS3sNodePrime, inst -> MOS3sNode, - inst -> MOS3sourceConductance); + ckt, THERMNOISE, inst->MOS3sNodePrime, inst->MOS3sNode, + inst->MOS3sourceConductance); NevalSrc( & noizDens[MOS3IDNOIZ], & lnNdens[MOS3IDNOIZ], - ckt, THERMNOISE, inst -> MOS3dNodePrime, inst -> MOS3sNodePrime, - (2.0 / 3.0 * fabs(inst -> MOS3gm))); + ckt, THERMNOISE, inst->MOS3dNodePrime, inst->MOS3sNodePrime, + (2.0 / 3.0 * fabs(inst->MOS3gm))); NevalSrc( & noizDens[MOS3FLNOIZ], NULL, ckt, - N_GAIN, inst -> MOS3dNodePrime, inst -> MOS3sNodePrime, + N_GAIN, inst->MOS3dNodePrime, inst->MOS3sNodePrime, (double) 0.0); if (newcompat.s3) { - noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef * - exp(model -> MOS3fNexp * - log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) / - (data -> freq * - (inst -> MOS3w - 2 * model -> MOS3widthNarrow) * - (inst -> MOS3l - 2 * model -> MOS3latDiff) * - model -> MOS3oxideCapFactor * model -> MOS3oxideCapFactor); + noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef * + exp(model->MOS3fNexp * + log(MAX(fabs(inst->MOS3cd), N_MINLOG))) / + (data->freq * + (inst->MOS3w - 2 * model->MOS3widthNarrow) * + (inst->MOS3l - 2 * model->MOS3latDiff) * + model->MOS3oxideCapFactor * model->MOS3oxideCapFactor); } else { - switch (model -> MOS3nlev) { + switch (model->MOS3nlev) { case 0: - noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef * - exp(model -> MOS3fNexp * - log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) / - (data -> freq * - (inst -> MOS3l - 2 * model -> MOS3latDiff) * - (inst -> MOS3l - 2 * model -> MOS3latDiff) * - model -> MOS3oxideCapFactor); + noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef * + exp(model->MOS3fNexp * + log(MAX(fabs(inst->MOS3cd), N_MINLOG))) / + (data->freq * + (inst->MOS3l - 2 * model->MOS3latDiff) * + (inst->MOS3l - 2 * model->MOS3latDiff) * + model->MOS3oxideCapFactor); break; case 1: - noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef * - exp(model -> MOS3fNexp * - log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) / - (data -> freq * - (inst -> MOS3w - 2 * model -> MOS3widthNarrow) * - (inst -> MOS3l - 2 * model -> MOS3latDiff) * - model -> MOS3oxideCapFactor); + noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef * + exp(model->MOS3fNexp * + log(MAX(fabs(inst->MOS3cd), N_MINLOG))) / + (data->freq * + (inst->MOS3w - 2 * model->MOS3widthNarrow) * + (inst->MOS3l - 2 * model->MOS3latDiff) * + model->MOS3oxideCapFactor); break; case 2: case 3: - noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef * - inst -> MOS3gm * inst -> MOS3gm / - (pow(data -> freq, model -> MOS3fNexp) * - (inst -> MOS3w - 2 * model -> MOS3widthNarrow) * - (inst -> MOS3l - 2 * model -> MOS3latDiff) * - model -> MOS3oxideCapFactor); + noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef * + inst->MOS3gm * inst->MOS3gm / + (pow(data->freq, model->MOS3fNexp) * + (inst->MOS3w - 2 * model->MOS3widthNarrow) * + (inst->MOS3l - 2 * model->MOS3latDiff) * + model->MOS3oxideCapFactor); break; } } @@ -148,21 +148,21 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, * OnDens += noizDens[MOS3TOTNOIZ]; - if (data -> delFreq == 0.0) { + if (data->delFreq == 0.0) { /* if we haven't done any previous integration, we need to */ /* initialize our "history" variables */ for (i = 0; i < MOS3NSRCS; i++) { - inst -> MOS3nVar[LNLSTDENS][i] = lnNdens[i]; + inst->MOS3nVar[LNLSTDENS][i] = lnNdens[i]; } /* clear out our integration variables if it's the first pass */ - if (data -> freq == job -> NstartFreq) { + if (data->freq == job->NstartFreq) { for (i = 0; i < MOS3NSRCS; i++) { - inst -> MOS3nVar[OUTNOIZ][i] = 0.0; - inst -> MOS3nVar[INNOIZ][i] = 0.0; + inst->MOS3nVar[OUTNOIZ][i] = 0.0; + inst->MOS3nVar[INNOIZ][i] = 0.0; } } } else { @@ -170,37 +170,37 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, for (i = 0; i < MOS3NSRCS; i++) { if (i != MOS3TOTNOIZ) { tempOnoise = Nintegrate(noizDens[i], lnNdens[i], - inst -> MOS3nVar[LNLSTDENS][i], data); - tempInoise = Nintegrate(noizDens[i] * data -> GainSqInv, - lnNdens[i] + data -> lnGainInv, - inst -> MOS3nVar[LNLSTDENS][i] + data -> lnGainInv, + inst->MOS3nVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data->GainSqInv, + lnNdens[i] + data->lnGainInv, + inst->MOS3nVar[LNLSTDENS][i] + data->lnGainInv, data); - inst -> MOS3nVar[LNLSTDENS][i] = lnNdens[i]; - data -> outNoiz += tempOnoise; - data -> inNoise += tempInoise; - if (job -> NStpsSm != 0) { - inst -> MOS3nVar[OUTNOIZ][i] += tempOnoise; - inst -> MOS3nVar[OUTNOIZ][MOS3TOTNOIZ] += tempOnoise; - inst -> MOS3nVar[INNOIZ][i] += tempInoise; - inst -> MOS3nVar[INNOIZ][MOS3TOTNOIZ] += tempInoise; + inst->MOS3nVar[LNLSTDENS][i] = lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (job->NStpsSm != 0) { + inst->MOS3nVar[OUTNOIZ][i] += tempOnoise; + inst->MOS3nVar[OUTNOIZ][MOS3TOTNOIZ] += tempOnoise; + inst->MOS3nVar[INNOIZ][i] += tempInoise; + inst->MOS3nVar[INNOIZ][MOS3TOTNOIZ] += tempInoise; } } } } - if (data -> prtSummary) { + if (data->prtSummary) { for (i = 0; i < MOS3NSRCS; i++) { /* print a summary report */ - data -> outpVector[data -> outNumber++] = noizDens[i]; + data->outpVector[data->outNumber++] = noizDens[i]; } } break; case INT_NOIZ: /* already calculated, just output */ - if (job -> NStpsSm != 0) { + if (job->NStpsSm != 0) { for (i = 0; i < MOS3NSRCS; i++) { - data -> outpVector[data -> outNumber++] = inst -> MOS3nVar[OUTNOIZ][i]; - data -> outpVector[data -> outNumber++] = inst -> MOS3nVar[INNOIZ][i]; + data->outpVector[data->outNumber++] = inst->MOS3nVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] = inst->MOS3nVar[INNOIZ][i]; } } /* if */ break; diff --git a/src/spicelib/devices/mos3/mos3set.c b/src/spicelib/devices/mos3/mos3set.c index d494f8434..8fc6a2de1 100644 --- a/src/spicelib/devices/mos3/mos3set.c +++ b/src/spicelib/devices/mos3/mos3set.c @@ -17,8 +17,8 @@ Modified: 2000 AlansFixes int MOS3setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) - /* load the MOS3 device structure with those pointers needed later - * for fast matrix loading + /* load the MOS3 device structure with those pointers needed later + * for fast matrix loading */ { @@ -48,7 +48,7 @@ MOS3setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) } if(!model->MOS3delvt0Given) { model->MOS3delvt0 = 0; - } + } if(!model->MOS3jctSatCurDensityGiven) { model->MOS3jctSatCurDensity = 0; } @@ -132,24 +132,24 @@ MOS3setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) } if(!model->MOS3oxideThicknessGiven) { model->MOS3oxideThickness = 1e-7; - } - if(!model->MOS3fNcoefGiven) { - model->MOS3fNcoef = 0; - } - if(!model->MOS3fNexpGiven) { - model->MOS3fNexp = 1; - } - if(!model->MOS3nlevGiven) { - model->MOS3nlev = 2; - } + } + if(!model->MOS3fNcoefGiven) { + model->MOS3fNcoef = 0; + } + if(!model->MOS3fNexpGiven) { + model->MOS3fNexp = 1; + } + if(!model->MOS3nlevGiven) { + model->MOS3nlev = 2; + } /* loop through all the instances of the model */ for (here = MOS3instances(model); here != NULL ; here=MOS3nextInstance(here)) { - CKTnode *tmpNode; - IFuid tmpName; - + CKTnode *tmpNode; + IFuid tmpName; + /* allocate a chunk of the state vector */ here->MOS3states = *states; *states += MOS3NUMSTATES; @@ -198,8 +198,8 @@ MOS3setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; } } } @@ -209,7 +209,7 @@ MOS3setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) } if((model->MOS3sourceResistance != 0 || - (model->MOS3sheetResistance != 0 && + (model->MOS3sheetResistance != 0 && here->MOS3sourceSquares != 0 ) )) { if (here->MOS3sNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->MOS3name,"internal#source"); @@ -218,8 +218,8 @@ MOS3setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; } } } @@ -269,21 +269,21 @@ MOS3unsetup(GENmodel *inModel, CKTcircuit *ckt) MOS3instance *here; for (model = (MOS3model *)inModel; model != NULL; - model = MOS3nextModel(model)) + model = MOS3nextModel(model)) { for (here = MOS3instances(model); here != NULL; here=MOS3nextInstance(here)) - { - if (here->MOS3sNodePrime > 0 - && here->MOS3sNodePrime != here->MOS3sNode) - CKTdltNNum(ckt, here->MOS3sNodePrime); - here->MOS3sNodePrime= 0; + { + if (here->MOS3sNodePrime > 0 + && here->MOS3sNodePrime != here->MOS3sNode) + CKTdltNNum(ckt, here->MOS3sNodePrime); + here->MOS3sNodePrime= 0; - if (here->MOS3dNodePrime > 0 - && here->MOS3dNodePrime != here->MOS3dNode) - CKTdltNNum(ckt, here->MOS3dNodePrime); - here->MOS3dNodePrime= 0; - } + if (here->MOS3dNodePrime > 0 + && here->MOS3dNodePrime != here->MOS3dNode) + CKTdltNNum(ckt, here->MOS3dNodePrime); + here->MOS3dNodePrime= 0; + } } return OK; } From c2f0b1468c673d3b213408bf2c9c4cc14f1dda05 Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 23 Jan 2024 17:08:40 +0100 Subject: [PATCH 14/20] mos3mask: change unusual structure name --- src/spicelib/devices/mos3/mos3mask.c | 94 ++++++++++++++-------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/spicelib/devices/mos3/mos3mask.c b/src/spicelib/devices/mos3/mos3mask.c index f3a07716d..1dac927d4 100644 --- a/src/spicelib/devices/mos3/mos3mask.c +++ b/src/spicelib/devices/mos3/mos3mask.c @@ -18,147 +18,147 @@ Modified: 2000 AlansFixes /*ARGSUSED*/ int -MOS3mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) +MOS3mAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) { - MOS3model *here = (MOS3model *)inst; + MOS3model *model = (MOS3model *)inModel; NG_IGNORE(ckt); switch(which) { case MOS3_MOD_TNOM: - value->rValue = here->MOS3tnom-CONSTCtoK; + value->rValue = model->MOS3tnom-CONSTCtoK; return(OK); case MOS3_MOD_VTO: - value->rValue = here->MOS3vt0; + value->rValue = model->MOS3vt0; return(OK); case MOS3_MOD_KP: - value->rValue = here->MOS3transconductance; + value->rValue = model->MOS3transconductance; return(OK); case MOS3_MOD_GAMMA: - value->rValue = here->MOS3gamma; + value->rValue = model->MOS3gamma; return(OK); case MOS3_MOD_PHI: - value->rValue = here->MOS3phi; + value->rValue = model->MOS3phi; return(OK); case MOS3_MOD_RD: - value->rValue = here->MOS3drainResistance; + value->rValue = model->MOS3drainResistance; return(OK); case MOS3_MOD_RS: - value->rValue = here->MOS3sourceResistance; + value->rValue = model->MOS3sourceResistance; return(OK); case MOS3_MOD_CBD: - value->rValue = here->MOS3capBD; + value->rValue = model->MOS3capBD; return(OK); case MOS3_MOD_CBS: - value->rValue = here->MOS3capBS; + value->rValue = model->MOS3capBS; return(OK); case MOS3_MOD_IS: - value->rValue = here->MOS3jctSatCur; + value->rValue = model->MOS3jctSatCur; return(OK); case MOS3_MOD_PB: - value->rValue = here->MOS3bulkJctPotential; + value->rValue = model->MOS3bulkJctPotential; return(OK); case MOS3_MOD_CGSO: - value->rValue = here->MOS3gateSourceOverlapCapFactor; + value->rValue = model->MOS3gateSourceOverlapCapFactor; return(OK); case MOS3_MOD_CGDO: - value->rValue = here->MOS3gateDrainOverlapCapFactor; + value->rValue = model->MOS3gateDrainOverlapCapFactor; return(OK); case MOS3_MOD_CGBO: - value->rValue = here->MOS3gateBulkOverlapCapFactor; + value->rValue = model->MOS3gateBulkOverlapCapFactor; return(OK); case MOS3_MOD_CJ: - value->rValue = here->MOS3bulkCapFactor; + value->rValue = model->MOS3bulkCapFactor; return(OK); case MOS3_MOD_MJ: - value->rValue = here->MOS3bulkJctBotGradingCoeff; + value->rValue = model->MOS3bulkJctBotGradingCoeff; return(OK); case MOS3_MOD_CJSW: - value->rValue = here->MOS3sideWallCapFactor; + value->rValue = model->MOS3sideWallCapFactor; return(OK); case MOS3_MOD_MJSW: - value->rValue = here->MOS3bulkJctSideGradingCoeff; + value->rValue = model->MOS3bulkJctSideGradingCoeff; return(OK); case MOS3_MOD_JS: - value->rValue = here->MOS3jctSatCurDensity; + value->rValue = model->MOS3jctSatCurDensity; return(OK); case MOS3_MOD_TOX: - value->rValue = here->MOS3oxideThickness; + value->rValue = model->MOS3oxideThickness; return(OK); case MOS3_MOD_LD: - value->rValue = here->MOS3latDiff; + value->rValue = model->MOS3latDiff; return(OK); case MOS3_MOD_XL: - value->rValue = here->MOS3lengthAdjust; + value->rValue = model->MOS3lengthAdjust; return(OK); case MOS3_MOD_WD: - value->rValue = here->MOS3widthNarrow; + value->rValue = model->MOS3widthNarrow; return(OK); case MOS3_MOD_XW: - value->rValue = here->MOS3widthAdjust; + value->rValue = model->MOS3widthAdjust; return(OK); case MOS3_MOD_DELVTO: - value->rValue = here->MOS3delvt0; + value->rValue = model->MOS3delvt0; return(OK); case MOS3_MOD_RSH: - value->rValue = here->MOS3sheetResistance; + value->rValue = model->MOS3sheetResistance; return(OK); case MOS3_MOD_U0: - value->rValue = here->MOS3surfaceMobility; + value->rValue = model->MOS3surfaceMobility; return(OK); case MOS3_MOD_FC: - value->rValue = here->MOS3fwdCapDepCoeff; + value->rValue = model->MOS3fwdCapDepCoeff; return(OK); case MOS3_MOD_NSUB: - value->rValue = here->MOS3substrateDoping; + value->rValue = model->MOS3substrateDoping; return(OK); case MOS3_MOD_TPG: - value->iValue = here->MOS3gateType; + value->iValue = model->MOS3gateType; return(OK); case MOS3_MOD_NSS: - value->rValue = here->MOS3surfaceStateDensity; + value->rValue = model->MOS3surfaceStateDensity; return(OK); case MOS3_MOD_NFS: - value->rValue = here->MOS3fastSurfaceStateDensity; + value->rValue = model->MOS3fastSurfaceStateDensity; return(OK); case MOS3_MOD_DELTA: - value->rValue = here->MOS3narrowFactor; + value->rValue = model->MOS3narrowFactor; return(OK); case MOS3_MOD_VMAX: - value->rValue = here->MOS3maxDriftVel; + value->rValue = model->MOS3maxDriftVel; return(OK); case MOS3_MOD_XJ: - value->rValue = here->MOS3junctionDepth; + value->rValue = model->MOS3junctionDepth; return(OK); case MOS3_MOD_ETA: - value->rValue = here->MOS3eta; + value->rValue = model->MOS3eta; return(OK); case MOS3_MOD_XD: - value->rValue = here->MOS3coeffDepLayWidth; + value->rValue = model->MOS3coeffDepLayWidth; return(OK); case MOS3_DELTA: - value->rValue = here->MOS3delta; + value->rValue = model->MOS3delta; return(OK); case MOS3_MOD_THETA: - value->rValue = here->MOS3theta; + value->rValue = model->MOS3theta; return(OK); case MOS3_MOD_ALPHA: - value->rValue = here->MOS3alpha; + value->rValue = model->MOS3alpha; return(OK); case MOS3_MOD_KAPPA: - value->rValue = here->MOS3kappa; + value->rValue = model->MOS3kappa; return(OK); case MOS3_MOD_KF: - value->rValue = here->MOS3fNcoef; + value->rValue = model->MOS3fNcoef; return(OK); case MOS3_MOD_AF: - value->rValue = here->MOS3fNexp; + value->rValue = model->MOS3fNexp; return(OK); case MOS3_MOD_NLEV: - value->iValue = here->MOS3nlev; + value->iValue = model->MOS3nlev; return(OK); case MOS3_MOD_TYPE: - if (here->MOS3type > 0) + if (model->MOS3type > 0) value->sValue = "nmos"; else value->sValue = "pmos"; From 6359b7b41f8f4008f732be3086716a786bc3bc7f Mon Sep 17 00:00:00 2001 From: dwarning Date: Sun, 28 Jan 2024 10:08:29 +0100 Subject: [PATCH 15/20] mos1...3: add nlev=3 mode channel thermal noise --- src/spicelib/devices/mos1/mos1.c | 3 ++- src/spicelib/devices/mos1/mos1defs.h | 3 +++ src/spicelib/devices/mos1/mos1mask.c | 3 +++ src/spicelib/devices/mos1/mos1mpar.c | 4 ++++ src/spicelib/devices/mos1/mos1noi.c | 28 +++++++++++++++++++++++++++- src/spicelib/devices/mos1/mos1set.c | 3 +++ src/spicelib/devices/mos2/mos2.c | 3 ++- src/spicelib/devices/mos2/mos2defs.h | 3 +++ src/spicelib/devices/mos2/mos2mask.c | 3 +++ src/spicelib/devices/mos2/mos2mpar.c | 4 ++++ src/spicelib/devices/mos2/mos2noi.c | 28 +++++++++++++++++++++++++++- src/spicelib/devices/mos2/mos2set.c | 3 +++ src/spicelib/devices/mos3/mos3.c | 3 ++- src/spicelib/devices/mos3/mos3defs.h | 3 +++ src/spicelib/devices/mos3/mos3mask.c | 3 +++ src/spicelib/devices/mos3/mos3mpar.c | 4 ++++ src/spicelib/devices/mos3/mos3noi.c | 28 +++++++++++++++++++++++++++- src/spicelib/devices/mos3/mos3set.c | 3 +++ 18 files changed, 126 insertions(+), 6 deletions(-) diff --git a/src/spicelib/devices/mos1/mos1.c b/src/spicelib/devices/mos1/mos1.c index f7931a530..beaa11bc0 100644 --- a/src/spicelib/devices/mos1/mos1.c +++ b/src/spicelib/devices/mos1/mos1.c @@ -149,7 +149,8 @@ IFparm MOS1mPTable[] = { /* model parameters */ IOP("tnom", MOS1_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"), IOP("kf", MOS1_MOD_KF, IF_REAL ,"Flicker noise coefficient"), IOP("af", MOS1_MOD_AF, IF_REAL ,"Flicker noise exponent"), - IOP("nlev", MOS1_MOD_NLEV, IF_INTEGER ,"Noise model selection") + IOP("nlev", MOS1_MOD_NLEV, IF_INTEGER ,"Noise model selection"), + IOP("gdsnoi", MOS1_MOD_GDSNOI, IF_REAL ,"Channel shot noise coefficient") }; char *MOS1names[] = { diff --git a/src/spicelib/devices/mos1/mos1defs.h b/src/spicelib/devices/mos1/mos1defs.h index 231388ac0..6103b23ba 100644 --- a/src/spicelib/devices/mos1/mos1defs.h +++ b/src/spicelib/devices/mos1/mos1defs.h @@ -384,6 +384,7 @@ typedef struct sMOS1model { /* model structure for a resistor */ double MOS1fNcoef; double MOS1fNexp; int MOS1nlev; + double MOS1gdsnoi; unsigned MOS1typeGiven :1; unsigned MOS1latDiffGiven :1; @@ -417,6 +418,7 @@ typedef struct sMOS1model { /* model structure for a resistor */ unsigned MOS1fNcoefGiven :1; unsigned MOS1fNexpGiven :1; unsigned MOS1nlevGiven :1; + unsigned MOS1gdsnoiGiven :1; } MOS1model; @@ -486,6 +488,7 @@ enum { MOS1_MOD_KF, MOS1_MOD_AF, MOS1_MOD_NLEV, + MOS1_MOD_GDSNOI, MOS1_MOD_TYPE, }; diff --git a/src/spicelib/devices/mos1/mos1mask.c b/src/spicelib/devices/mos1/mos1mask.c index 903983103..e0c610c56 100644 --- a/src/spicelib/devices/mos1/mos1mask.c +++ b/src/spicelib/devices/mos1/mos1mask.c @@ -108,6 +108,9 @@ MOS1mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) case MOS1_MOD_NLEV: value->iValue = model->MOS1nlev; return(OK); + case MOS1_MOD_GDSNOI: + value->rValue = model->MOS1gdsnoi; + return(OK); case MOS1_MOD_TYPE: if (model->MOS1type > 0) value->sValue = "nmos"; diff --git a/src/spicelib/devices/mos1/mos1mpar.c b/src/spicelib/devices/mos1/mos1mpar.c index 82a5dc714..d849626ff 100644 --- a/src/spicelib/devices/mos1/mos1mpar.c +++ b/src/spicelib/devices/mos1/mos1mpar.c @@ -151,6 +151,10 @@ MOS1mParam(int param, IFvalue *value, GENmodel *inModel) model->MOS1nlev = value->iValue; model->MOS1nlevGiven = TRUE; break; + case MOS1_MOD_GDSNOI: + model->MOS1gdsnoi = value->rValue; + model->MOS1gdsnoiGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos1/mos1noi.c b/src/spicelib/devices/mos1/mos1noi.c index 9d78dd47e..ec7801963 100644 --- a/src/spicelib/devices/mos1/mos1noi.c +++ b/src/spicelib/devices/mos1/mos1noi.c @@ -35,6 +35,7 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, double noizDens[MOS1NSRCS]; double lnNdens[MOS1NSRCS]; int i; + double vgs, vds, vgd, vgst, alpha, beta, Sid; /* define the names of the noise sources */ @@ -102,9 +103,34 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, ckt, THERMNOISE, inst->MOS1sNodePrime, inst->MOS1sNode, inst->MOS1sourceConductance); + if (model->MOS1nlev < 3) { + + Sid = 2.0 / 3.0 * fabs(inst->MOS1gm); + + } else { + vds = *(ckt->CKTstate0 + inst->MOS1vds); + vgs = *(ckt->CKTstate0 + inst->MOS1vgs); + vgd = vgs - vds; + beta = inst->MOS1tTransconductance * inst->MOS1m * + inst->MOS1w/(inst->MOS1l - 2 * model->MOS1latDiff); + + vgst=(inst->MOS1mode==1?vgs:vgd) - model->MOS1type*inst->MOS1von; + if (vgst > 0) { + if (vgst <= (vds*inst->MOS1mode)) { + /* saturation region */ + alpha = 0.0; + } else { + /* linear region */ + alpha = 1.0 - (vds*inst->MOS1mode/(model->MOS1type*inst->MOS1vdsat)); + } + } + double betap = beta*(1.0+model->MOS1lambda*(vds*inst->MOS1mode)); + Sid = 2.0 / 3.0 * betap * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS1gdsnoi; + } + NevalSrc( & noizDens[MOS1IDNOIZ], & lnNdens[MOS1IDNOIZ], ckt, THERMNOISE, inst->MOS1dNodePrime, inst->MOS1sNodePrime, - (2.0 / 3.0 * fabs(inst->MOS1gm))); + Sid); NevalSrc( & noizDens[MOS1FLNOIZ], NULL, ckt, N_GAIN, inst->MOS1dNodePrime, inst->MOS1sNodePrime, diff --git a/src/spicelib/devices/mos1/mos1set.c b/src/spicelib/devices/mos1/mos1set.c index 313926e55..912e029a9 100644 --- a/src/spicelib/devices/mos1/mos1set.c +++ b/src/spicelib/devices/mos1/mos1set.c @@ -90,6 +90,9 @@ MOS1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, if(!model->MOS1nlevGiven) { model->MOS1nlev = 2; } + if(!model->MOS1gdsnoiGiven) { + model->MOS1gdsnoi = 1; + } /* loop through all the instances of the model */ for (here = MOS1instances(model); here != NULL ; diff --git a/src/spicelib/devices/mos2/mos2.c b/src/spicelib/devices/mos2/mos2.c index 040895297..bc577da61 100644 --- a/src/spicelib/devices/mos2/mos2.c +++ b/src/spicelib/devices/mos2/mos2.c @@ -157,7 +157,8 @@ IFparm MOS2mPTable[] = { /* model parameters */ IOPU("tnom", MOS2_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"), IOP("kf", MOS2_MOD_KF, IF_REAL ,"Flicker noise coefficient"), IOP("af", MOS2_MOD_AF, IF_REAL ,"Flicker noise exponent"), - IOP("nlev", MOS2_MOD_NLEV, IF_INTEGER ,"Noise model selection") + IOP("nlev", MOS2_MOD_NLEV, IF_INTEGER ,"Noise model selection"), + IOP("gdsnoi", MOS2_MOD_GDSNOI, IF_REAL ,"Channel shot noise coefficient") }; char *MOS2names[] = { diff --git a/src/spicelib/devices/mos2/mos2defs.h b/src/spicelib/devices/mos2/mos2defs.h index bcce92f49..8a1fc8ce1 100644 --- a/src/spicelib/devices/mos2/mos2defs.h +++ b/src/spicelib/devices/mos2/mos2defs.h @@ -391,6 +391,7 @@ typedef struct sMOS2model { /* model structure for a resistor */ double MOS2fNcoef; double MOS2fNexp; int MOS2nlev; + double MOS2gdsnoi; double MOS2narrowFactor; /* delta */ double MOS2critFieldExp; /* uexp */ @@ -439,6 +440,7 @@ typedef struct sMOS2model { /* model structure for a resistor */ unsigned MOS2fNcoefGiven :1; unsigned MOS2fNexpGiven :1; unsigned MOS2nlevGiven :1; + unsigned MOS2gdsnoiGiven :1; } MOS2model; @@ -577,6 +579,7 @@ enum { MOS2_MOD_KF = 139, MOS2_MOD_AF, MOS2_MOD_NLEV, + MOS2_MOD_GDSNOI, MOS2_MOD_TYPE, }; diff --git a/src/spicelib/devices/mos2/mos2mask.c b/src/spicelib/devices/mos2/mos2mask.c index 7cc54359f..ff125669e 100644 --- a/src/spicelib/devices/mos2/mos2mask.c +++ b/src/spicelib/devices/mos2/mos2mask.c @@ -133,6 +133,9 @@ MOS2mAsk(CKTcircuit *ckt, GENmodel *inModel, int param, case MOS2_MOD_NLEV: value->iValue = model->MOS2nlev; break; + case MOS2_MOD_GDSNOI: + value->rValue = model->MOS2gdsnoi; + return(OK); case MOS2_MOD_TYPE: if (model->MOS2type > 0) value->sValue = "nmos"; diff --git a/src/spicelib/devices/mos2/mos2mpar.c b/src/spicelib/devices/mos2/mos2mpar.c index 175858cbb..7c8f3dc15 100644 --- a/src/spicelib/devices/mos2/mos2mpar.c +++ b/src/spicelib/devices/mos2/mos2mpar.c @@ -182,6 +182,10 @@ MOS2mParam(int param, IFvalue *value, GENmodel *inModel) model->MOS2nlev = value->iValue; model->MOS2nlevGiven = TRUE; break; + case MOS2_MOD_GDSNOI: + model->MOS2gdsnoi = value->rValue; + model->MOS2gdsnoiGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos2/mos2noi.c b/src/spicelib/devices/mos2/mos2noi.c index 90da7b2d1..fdbcc3dbc 100644 --- a/src/spicelib/devices/mos2/mos2noi.c +++ b/src/spicelib/devices/mos2/mos2noi.c @@ -34,6 +34,7 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, double noizDens[MOS2NSRCS]; double lnNdens[MOS2NSRCS]; int i; + double vgs, vds, vgd, vgst, alpha, beta, Sid; /* define the names of the noise sources */ @@ -91,9 +92,34 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, ckt, THERMNOISE, inst->MOS2sNodePrime, inst->MOS2sNode, inst->MOS2sourceConductance); + if (model->MOS2nlev < 3) { + + Sid = 2.0 / 3.0 * fabs(inst->MOS2gm); + + } else { + vds = *(ckt->CKTstate0 + inst->MOS2vds); + vgs = *(ckt->CKTstate0 + inst->MOS2vgs); + vgd = vgs - vds; + beta = inst->MOS2tTransconductance * inst->MOS2m * + inst->MOS2w/(inst->MOS2l - 2 * model->MOS2latDiff); + + vgst=(inst->MOS2mode==1?vgs:vgd) - model->MOS2type*inst->MOS2von; + if (vgst > 0) { + if (vgst <= (vds*inst->MOS2mode)) { + /* saturation region */ + alpha = 0.0; + } else { + /* linear region */ + alpha = 1.0 - (vds*inst->MOS2mode/(model->MOS2type*inst->MOS2vdsat)); + } + } + double betap = beta*(1.0+model->MOS2lambda*(vds*inst->MOS2mode)); + Sid = 2.0 / 3.0 * betap * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS2gdsnoi; + } + NevalSrc( & noizDens[MOS2IDNOIZ], & lnNdens[MOS2IDNOIZ], ckt, THERMNOISE, inst->MOS2dNodePrime, inst->MOS2sNodePrime, - (2.0 / 3.0 * fabs(inst->MOS2gm))); + Sid); NevalSrc( & noizDens[MOS2FLNOIZ], NULL, ckt, N_GAIN, inst->MOS2dNodePrime, inst->MOS2sNodePrime, diff --git a/src/spicelib/devices/mos2/mos2set.c b/src/spicelib/devices/mos2/mos2set.c index 9f8e9eac6..34e58bef5 100644 --- a/src/spicelib/devices/mos2/mos2set.c +++ b/src/spicelib/devices/mos2/mos2set.c @@ -119,6 +119,9 @@ MOS2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!model->MOS2nlevGiven) { model->MOS2nlev = 2; } + if(!model->MOS2gdsnoiGiven) { + model->MOS2gdsnoi = 1; + } /* loop through all the instances of the model */ for (here = MOS2instances(model); here != NULL ; diff --git a/src/spicelib/devices/mos3/mos3.c b/src/spicelib/devices/mos3/mos3.c index 72d738eb2..a7f2cdf81 100644 --- a/src/spicelib/devices/mos3/mos3.c +++ b/src/spicelib/devices/mos3/mos3.c @@ -157,7 +157,8 @@ IFparm MOS3mPTable[] = { /* model parameters */ IOPU("tnom", MOS3_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"), IOP("kf", MOS3_MOD_KF, IF_REAL ,"Flicker noise coefficient"), IOP("af", MOS3_MOD_AF, IF_REAL ,"Flicker noise exponent"), - IOP("nlev", MOS3_MOD_NLEV, IF_INTEGER ,"Noise model selection") + IOP("nlev", MOS3_MOD_NLEV, IF_INTEGER ,"Noise model selection"), + IOP("gdsnoi", MOS3_MOD_GDSNOI, IF_REAL ,"Channel shot noise coefficient") }; char *MOS3names[] = { diff --git a/src/spicelib/devices/mos3/mos3defs.h b/src/spicelib/devices/mos3/mos3defs.h index 7ce5f4bfb..42b79faa4 100644 --- a/src/spicelib/devices/mos3/mos3defs.h +++ b/src/spicelib/devices/mos3/mos3defs.h @@ -401,6 +401,7 @@ typedef struct sMOS3model { /* model structure for a resistor */ double MOS3fNcoef; double MOS3fNexp; int MOS3nlev; + double MOS3gdsnoi; unsigned MOS3typeGiven :1; unsigned MOS3latDiffGiven :1; @@ -444,6 +445,7 @@ typedef struct sMOS3model { /* model structure for a resistor */ unsigned MOS3fNcoefGiven :1; unsigned MOS3fNexpGiven :1; unsigned MOS3nlevGiven :1; + unsigned MOS3gdsnoiGiven :1; } MOS3model; @@ -583,6 +585,7 @@ enum { MOS3_MOD_KF, MOS3_MOD_AF, MOS3_MOD_NLEV, + MOS3_MOD_GDSNOI, MOS3_MOD_TYPE, MOS3_MOD_XL, MOS3_MOD_WD, diff --git a/src/spicelib/devices/mos3/mos3mask.c b/src/spicelib/devices/mos3/mos3mask.c index 1dac927d4..355362111 100644 --- a/src/spicelib/devices/mos3/mos3mask.c +++ b/src/spicelib/devices/mos3/mos3mask.c @@ -157,6 +157,9 @@ MOS3mAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) case MOS3_MOD_NLEV: value->iValue = model->MOS3nlev; return(OK); + case MOS3_MOD_GDSNOI: + value->rValue = model->MOS3gdsnoi; + return(OK); case MOS3_MOD_TYPE: if (model->MOS3type > 0) value->sValue = "nmos"; diff --git a/src/spicelib/devices/mos3/mos3mpar.c b/src/spicelib/devices/mos3/mos3mpar.c index 890d0b4bb..aa6f678c3 100644 --- a/src/spicelib/devices/mos3/mos3mpar.c +++ b/src/spicelib/devices/mos3/mos3mpar.c @@ -195,6 +195,10 @@ MOS3mParam(int param, IFvalue *value, GENmodel *inModel) model->MOS3nlev = value->iValue; model->MOS3nlevGiven = TRUE; break; + case MOS3_MOD_GDSNOI: + model->MOS3gdsnoi = value->rValue; + model->MOS3gdsnoiGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/mos3/mos3noi.c b/src/spicelib/devices/mos3/mos3noi.c index b6e79bba7..7caa11e47 100644 --- a/src/spicelib/devices/mos3/mos3noi.c +++ b/src/spicelib/devices/mos3/mos3noi.c @@ -34,6 +34,7 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, double noizDens[MOS3NSRCS]; double lnNdens[MOS3NSRCS]; int i; + double vgs, vds, vgd, vgst, alpha, beta, Sid; /* define the names of the noise sources */ @@ -91,9 +92,34 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, ckt, THERMNOISE, inst->MOS3sNodePrime, inst->MOS3sNode, inst->MOS3sourceConductance); + if (model->MOS3nlev < 3) { + + Sid = 2.0 / 3.0 * fabs(inst->MOS3gm); + + } else { + vds = *(ckt->CKTstate0 + inst->MOS3vds); + vgs = *(ckt->CKTstate0 + inst->MOS3vgs); + vgd = vgs - vds; + beta = inst->MOS3tTransconductance * inst->MOS3m * + inst->MOS3w/(inst->MOS3l - 2 * model->MOS3latDiff); + + vgst=(inst->MOS3mode==1?vgs:vgd) - model->MOS3type*inst->MOS3von; + if (vgst > 0) { + if (vgst <= (vds*inst->MOS3mode)) { + /* saturation region */ + alpha = 0.0; + } else { + /* linear region */ + alpha = 1.0 - (vds*inst->MOS3mode/(model->MOS3type*inst->MOS3vdsat)); + } + } + double betap = beta; + Sid = 2.0 / 3.0 * betap * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS3gdsnoi; + } + NevalSrc( & noizDens[MOS3IDNOIZ], & lnNdens[MOS3IDNOIZ], ckt, THERMNOISE, inst->MOS3dNodePrime, inst->MOS3sNodePrime, - (2.0 / 3.0 * fabs(inst->MOS3gm))); + Sid); NevalSrc( & noizDens[MOS3FLNOIZ], NULL, ckt, N_GAIN, inst->MOS3dNodePrime, inst->MOS3sNodePrime, diff --git a/src/spicelib/devices/mos3/mos3set.c b/src/spicelib/devices/mos3/mos3set.c index 8fc6a2de1..5a947de33 100644 --- a/src/spicelib/devices/mos3/mos3set.c +++ b/src/spicelib/devices/mos3/mos3set.c @@ -142,6 +142,9 @@ MOS3setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!model->MOS3nlevGiven) { model->MOS3nlev = 2; } + if(!model->MOS3gdsnoiGiven) { + model->MOS3gdsnoi = 1; + } /* loop through all the instances of the model */ for (here = MOS3instances(model); here != NULL ; From 9ed7a24a0e3926e191176585d48da177ad2af670 Mon Sep 17 00:00:00 2001 From: dwarning Date: Sun, 28 Jan 2024 20:11:52 +0100 Subject: [PATCH 16/20] mos1...3: Beta in noise w/o channel length modulation --- src/spicelib/devices/mos1/mos1noi.c | 7 +++---- src/spicelib/devices/mos2/mos2noi.c | 7 +++---- src/spicelib/devices/mos3/mos3noi.c | 7 +++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/spicelib/devices/mos1/mos1noi.c b/src/spicelib/devices/mos1/mos1noi.c index ec7801963..2c853c9a9 100644 --- a/src/spicelib/devices/mos1/mos1noi.c +++ b/src/spicelib/devices/mos1/mos1noi.c @@ -111,8 +111,6 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, vds = *(ckt->CKTstate0 + inst->MOS1vds); vgs = *(ckt->CKTstate0 + inst->MOS1vgs); vgd = vgs - vds; - beta = inst->MOS1tTransconductance * inst->MOS1m * - inst->MOS1w/(inst->MOS1l - 2 * model->MOS1latDiff); vgst=(inst->MOS1mode==1?vgs:vgd) - model->MOS1type*inst->MOS1von; if (vgst > 0) { @@ -124,8 +122,9 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, alpha = 1.0 - (vds*inst->MOS1mode/(model->MOS1type*inst->MOS1vdsat)); } } - double betap = beta*(1.0+model->MOS1lambda*(vds*inst->MOS1mode)); - Sid = 2.0 / 3.0 * betap * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS1gdsnoi; + beta = inst->MOS1tTransconductance * inst->MOS1m * + inst->MOS1w/(inst->MOS1l - 2 * model->MOS1latDiff); + Sid = 2.0 / 3.0 * beta * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS1gdsnoi; } NevalSrc( & noizDens[MOS1IDNOIZ], & lnNdens[MOS1IDNOIZ], diff --git a/src/spicelib/devices/mos2/mos2noi.c b/src/spicelib/devices/mos2/mos2noi.c index fdbcc3dbc..c3e942adf 100644 --- a/src/spicelib/devices/mos2/mos2noi.c +++ b/src/spicelib/devices/mos2/mos2noi.c @@ -100,8 +100,6 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, vds = *(ckt->CKTstate0 + inst->MOS2vds); vgs = *(ckt->CKTstate0 + inst->MOS2vgs); vgd = vgs - vds; - beta = inst->MOS2tTransconductance * inst->MOS2m * - inst->MOS2w/(inst->MOS2l - 2 * model->MOS2latDiff); vgst=(inst->MOS2mode==1?vgs:vgd) - model->MOS2type*inst->MOS2von; if (vgst > 0) { @@ -113,8 +111,9 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, alpha = 1.0 - (vds*inst->MOS2mode/(model->MOS2type*inst->MOS2vdsat)); } } - double betap = beta*(1.0+model->MOS2lambda*(vds*inst->MOS2mode)); - Sid = 2.0 / 3.0 * betap * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS2gdsnoi; + beta = inst->MOS2tTransconductance * inst->MOS2m * + inst->MOS2w/(inst->MOS2l - 2 * model->MOS2latDiff); + Sid = 2.0 / 3.0 * beta * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS2gdsnoi; } NevalSrc( & noizDens[MOS2IDNOIZ], & lnNdens[MOS2IDNOIZ], diff --git a/src/spicelib/devices/mos3/mos3noi.c b/src/spicelib/devices/mos3/mos3noi.c index 7caa11e47..3d7551184 100644 --- a/src/spicelib/devices/mos3/mos3noi.c +++ b/src/spicelib/devices/mos3/mos3noi.c @@ -100,8 +100,6 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, vds = *(ckt->CKTstate0 + inst->MOS3vds); vgs = *(ckt->CKTstate0 + inst->MOS3vgs); vgd = vgs - vds; - beta = inst->MOS3tTransconductance * inst->MOS3m * - inst->MOS3w/(inst->MOS3l - 2 * model->MOS3latDiff); vgst=(inst->MOS3mode==1?vgs:vgd) - model->MOS3type*inst->MOS3von; if (vgst > 0) { @@ -113,8 +111,9 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, alpha = 1.0 - (vds*inst->MOS3mode/(model->MOS3type*inst->MOS3vdsat)); } } - double betap = beta; - Sid = 2.0 / 3.0 * betap * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS3gdsnoi; + beta = inst->MOS3tTransconductance * inst->MOS3m * + inst->MOS3w/(inst->MOS3l - 2 * model->MOS3latDiff); + Sid = 2.0 / 3.0 * beta * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS3gdsnoi; } NevalSrc( & noizDens[MOS3IDNOIZ], & lnNdens[MOS3IDNOIZ], From bd0f7257769f554a3c1a2ec99886aecde9ec162f Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Thu, 18 Jan 2024 13:11:56 -0800 Subject: [PATCH 17/20] There are approx. 47 out of 1455 subckts in PSPICE 9.1 libraries which contain X* subckt calls together with zero or more U* instances. Now this type of subckt can be translated to XSPICE. --- src/frontend/inpcompat.c | 3 ++- src/frontend/udevices.c | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/frontend/inpcompat.c b/src/frontend/inpcompat.c index b0dfd43c4..8e2ade0cb 100644 --- a/src/frontend/inpcompat.c +++ b/src/frontend/inpcompat.c @@ -576,7 +576,8 @@ static struct card *u_instances(struct card *startcard) models_ok++; } } - } else if (ciprefix("u", cut_line)) { + } else if (ciprefix("u", cut_line) || ciprefix("x", cut_line)) { + /* U* device instance or X* instance of a subckt */ if (subcktcard) { if (repeat_pass) { if (!u_process_instance(cut_line)) { diff --git a/src/frontend/udevices.c b/src/frontend/udevices.c index cfe25c88d..dcbe5d054 100644 --- a/src/frontend/udevices.c +++ b/src/frontend/udevices.c @@ -4239,11 +4239,16 @@ BOOL u_check_instance(char *line) { /* Check to see if the U* instance is a type which can be translated. + An X* instance of a subckt is allowed. Return TRUE if it can be translated */ char *xspice, *itype; - struct instance_hdr *hdr = create_instance_header(line); + struct instance_hdr *hdr = NULL; + if (ciprefix("x", line)) { + return TRUE; + } + hdr = create_instance_header(line); if (!hdr) { return FALSE; } @@ -4284,10 +4289,24 @@ BOOL u_process_instance(char *nline) { /* Return TRUE if ok */ char *p1, *itype, *xspice; - struct instance_hdr *hdr = create_instance_header(nline); + struct instance_hdr *hdr = NULL; Xlatorp xp = NULL; BOOL behav_ret = TRUE; + + if (ciprefix("x", nline)) { + /* An X* instance of a subckt is translated unchanged */ + Xlate_datap xdp = create_xlate_translated(nline); + Xlatorp xlp = create_xlator(); + (void) add_xlator(xlp, xdp); + append_xlator(translated_p, xlp); + if (ps_ports_and_pins & 4) { + printf("TRANS_IN %s\n", nline); + } + delete_xlator(xlp); + return TRUE; + } + hdr = create_instance_header(nline); if (!hdr) { return FALSE; } From e01290c9a2af36b62c4cd4a0c5b0c8f8e0a1b867 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Mon, 12 Feb 2024 16:04:00 -0800 Subject: [PATCH 18/20] Replace the logicexp parser with infix to postfix translation followed by evaluating the postfix. logicexp.c is now shorter and easier to understand and maintain. Also, operator precedence expression parsing conforms to the PSPICE rules. Thus, a & b | c is understood to mean (a & b) | c, for example. --- src/frontend/logicexp.c | 1521 ++++++++++++++------------------------- 1 file changed, 549 insertions(+), 972 deletions(-) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index 95f495c37..18ea46c9d 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "ngspice/memory.h" #include "ngspice/macros.h" @@ -22,10 +23,10 @@ #include "ngspice/logicexp.h" #include "ngspice/udevices.h" -/* Turn off/on debug tracing */ -#define PRINT_ALL FALSE -//#define PRINT_ALL TRUE static char *get_pindly_instance_name(void); +static char *get_inst_name(void); +static char *get_logicexp_tmodel_delays( + char *out_name, int gate_op, BOOL isnot, DSTRING *mname); /* Start of btree symbol table */ #define SYM_INPUT 1 @@ -40,7 +41,6 @@ static char *get_pindly_instance_name(void); typedef struct sym_entry *SYM_TAB; struct sym_entry { char *name; - char *alias; int attribute; int ref_count; // for inverters SYM_TAB left; @@ -55,7 +55,6 @@ static SYM_TAB new_sym_entry(char *name, int attr) newp->right = NULL; newp->name = TMALLOC(char, strlen(name) + 1); strcpy(newp->name, name); - newp->alias = NULL; newp->attribute = attr; newp->ref_count = 0; return newp; @@ -106,15 +105,6 @@ static SYM_TAB add_sym_tab_entry(char *name, int attr, SYM_TAB *stab) return entry; } -static void alias_sym_tab(char *alias, SYM_TAB t) -{ - if (t == NULL) { return; } - if (t->alias) - tfree(t->alias); - t->alias = TMALLOC(char, strlen(alias) + 1); - strcpy(t->alias, alias); -} - static void delete_sym_tab(SYM_TAB t) { if (t == NULL) { return; } @@ -122,23 +112,8 @@ static void delete_sym_tab(SYM_TAB t) delete_sym_tab(t->right); if (t->name) tfree(t->name); - if (t->alias) - tfree(t->alias); tfree(t); } - -static void print_sym_tab(SYM_TAB t, BOOL with_addr) -{ - if (t == NULL) { return; } - print_sym_tab(t->left, with_addr); - if (with_addr) - printf("%p --> \n", (void *)t); - printf("\"%s\" %d ref_count=%d", t->name, t->attribute, t->ref_count); - if (t->alias) - printf(" alias = \"%s\"", t->alias); - printf("\n"); - print_sym_tab(t->right, with_addr); -} /* End of btree symbol table */ /* Start of lexical scanner */ @@ -152,6 +127,7 @@ struct lexer { char *lexer_buf; char *lexer_line; int lexer_pos; + int lexer_last_pos; int lexer_back; SYM_TAB lexer_sym_tab; size_t lexer_blen; @@ -165,7 +141,7 @@ static LEXER new_lexer(char *line) lx = TMALLOC(struct lexer, 1); lx->lexer_line = TMALLOC(char, (strlen(line) + 1)); strcpy(lx->lexer_line, line); - lx->lexer_pos = lx->lexer_back = 0; + lx->lexer_pos = lx->lexer_last_pos = lx->lexer_back = 0; lx->lexer_blen = LEX_INIT_SZ; lx->lexer_buf = TMALLOC(char, lx->lexer_blen); (void) memset(lx->lexer_buf, 0, lx->lexer_blen); @@ -201,6 +177,7 @@ static int lexer_set_start(char *s, LEXER lx) if (!pos) return -1; lx->lexer_pos = (int) (pos - &lx->lexer_line[0]); + lx->lexer_last_pos = lx->lexer_pos; lx->lexer_back = lx->lexer_pos; return lx->lexer_pos; } @@ -354,9 +331,15 @@ static int lex_ident(int c) return 0; } +static void lexer_back_one(LEXER lx) +{ + lx->lexer_pos = lx->lexer_last_pos; +} + static int lexer_scan(LEXER lx) { int c; + lx->lexer_last_pos = lx->lexer_pos; while (1) { lx->lexer_buf[0] = '\0'; c = lexer_getchar(lx); @@ -420,6 +403,478 @@ static BOOL lex_all_digits(char *str) } /* End of lexical scanner */ +/* Start of name entries */ +typedef struct name_entry *NAME_ENTRY; +struct name_entry { + char *name; + NAME_ENTRY next; +}; + +static NAME_ENTRY new_name_entry(char *name) +{ + NAME_ENTRY newp; + newp = TMALLOC(struct name_entry, 1); + newp->next = NULL; + newp->name = TMALLOC(char, strlen(name) + 1); + strcpy(newp->name, name); + return newp; +} + +static NAME_ENTRY add_name_entry(char *name, NAME_ENTRY nelist) +{ + NAME_ENTRY newlist = NULL, x = NULL, last = NULL; + + if (nelist == NULL) { + newlist = new_name_entry(name); + return newlist; + } + for (x = nelist; x; x = x->next) { + /* No duplicates */ + if (eq(x->name, name)) { + //printf("\tFound entry %s\n", x->name); + return x; + } + last = x; + } + x = new_name_entry(name); + last->next = x; + //printf("\tAdd entry %s\n", x->name); + return x; +} + +static void delete_name_entry(NAME_ENTRY entry) +{ + if (!entry) return; + if (entry->name) tfree(entry->name); + tfree(entry); +} + +static void clear_name_list(NAME_ENTRY nelist) +{ + NAME_ENTRY x = NULL, next = NULL; + if (!nelist) { return; } + for (x = nelist; x; x = next) { + next = x->next; + delete_name_entry(x); + } +} +/* End of name entries */ + +/* Start of infix to posfix */ +#define STACK_SIZE 100 +#define PUSH_ERROR 1 +#define POP_ERROR 2 +#define TMP_PREFIX "tmp__" +#define TMP_LEN (strlen(TMP_PREFIX)) + +struct Stack { + int top; + char *array[STACK_SIZE]; +}; + +struct gate_data { + int type; + BOOL finished; + BOOL is_not; + BOOL is_possible; + char *outp; + NAME_ENTRY ins; + NAME_ENTRY last_input; + struct gate_data *nxt; + struct gate_data *prev; +}; + +static struct gate_data *first_gate = NULL; +static struct gate_data *last_gate = NULL; + +static struct gate_data *new_gate(int c, char *out, char *i1, char *i2) +{ + NAME_ENTRY np; + struct gate_data *gdp = TMALLOC(struct gate_data, 1); + gdp->type = c; + gdp->finished = gdp->is_possible = FALSE; + if (c == '~') { + gdp->is_not = TRUE; + } else { + gdp->is_not = FALSE; + } + gdp->nxt = gdp->prev = NULL; + if (out) { + gdp->outp = TMALLOC(char, strlen(out) + 1); + strcpy(gdp->outp, out); + } else { + gdp->outp = NULL; + } + if (i1) { // Only have second input if there is a first + np = new_name_entry(i1); + gdp->ins = np; + if (i2) { + assert(c != '~'); // inverters have only one input + np = new_name_entry(i2); + gdp->ins->next = np; + if (strncmp(i1, TMP_PREFIX, TMP_LEN) == 0 + && strncmp(i2, TMP_PREFIX, TMP_LEN) != 0) { + gdp->is_possible = TRUE; + } + } + gdp->last_input = np; + } else { + gdp->ins = NULL; + gdp->last_input = NULL; + } + return gdp; +} + +static struct gate_data *insert_gate(struct gate_data *gp) +{ + if (!first_gate) { + first_gate = last_gate = gp; + gp->nxt = gp->prev = NULL; + } else { + last_gate->nxt = gp; + gp->nxt = NULL; + gp->prev = last_gate; + last_gate = gp; + } + return last_gate; +} + +static char *tilde_tail(char *s, DSTRING *ds) +{ + ds_clear(ds); + if (strncmp(s, "tilde_", 6) == 0) { + ds_cat_printf(ds, "~%s", s + 6); + return ds_get_buf(ds); + } else { + return s; + } +} + +static void move_inputs(struct gate_data *curr, struct gate_data *prev) +{ + if (curr == NULL || prev == NULL) return; + if (prev->finished) return; + delete_name_entry(curr->ins); + curr->ins = prev->ins; + prev->last_input->next = curr->last_input; + prev->ins = prev->last_input = NULL; + prev->finished = TRUE; +} + +static void scan_gates(DSTRING *lhs) +{ + struct gate_data *current = NULL, *previous = NULL, *last_curr = NULL; + struct gate_data *prev = NULL; + + current = first_gate; + while (current) { + int is_gate = (current->type == '&' + || current->type == '^' + || current->type == '|'); + previous = current->prev; + if (is_gate && current->is_possible) { + if (previous && previous->type == current->type) { + if (eq(current->ins->name, previous->outp)) { + move_inputs(current, previous); + } + } + } else if (current->type == '~') { + if (previous + && (previous->type == '&' || previous->type == '|' + || previous->type == '^')) { + + if (strncmp(current->ins->name, TMP_PREFIX, TMP_LEN) == 0 + && strncmp(previous->outp, TMP_PREFIX, TMP_LEN) == 0) { + if (eq(current->ins->name, previous->outp)) { + tfree(previous->outp); + previous->outp = TMALLOC(char, strlen(current->outp) + 1); + strcpy(previous->outp, current->outp); + previous->is_not = TRUE; + current->finished = TRUE; + } + } + } + } else if (is_gate) { + if (current->finished == FALSE + && strncmp(current->ins->name, TMP_PREFIX, TMP_LEN) == 0) { + prev = current->prev; + while (prev) { + if (prev->type == current->type + && prev->finished == FALSE + && strncmp(prev->outp, TMP_PREFIX, TMP_LEN) == 0 + && eq(current->ins->name, prev->outp)) { + move_inputs(current, prev); + break; + } + prev = prev->prev; + } + } + } + last_curr = current; + current = current->nxt; + } + if (ds_get_length(lhs) > 0 && last_curr) { + previous = last_curr; + while (previous && previous->finished) { + previous = previous->prev; + } + if (previous) { + assert(previous->outp != NULL); + assert(previous->finished == FALSE); + tfree(previous->outp); + previous->outp = TMALLOC(char, ds_get_length(lhs) + 1); + strcpy(previous->outp, ds_get_buf(lhs)); + } + } +} + +static void gen_scanned_gates(struct gate_data *gp) +{ + DS_CREATE(instance, 64); + DS_CREATE(ds, 32); + DS_CREATE(mname, 32); + NAME_ENTRY nm = NULL; + if (!gp) return; + while (gp) { + if (gp->finished) { + gp = gp->nxt; + continue; + } + ds_clear(&instance); + ds_cat_printf(&instance, "%s ", get_inst_name()); + (void) get_logicexp_tmodel_delays(gp->outp, gp->type, gp->is_not, &mname); + if (gp->type == '&' || gp->type == '^' || gp->type == '|') { + nm = gp->ins; + ds_cat_str(&instance, "["); + while (nm) { + ds_cat_printf(&instance, " %s", tilde_tail(nm->name, &ds)); + nm = nm->next; + } + ds_cat_printf(&instance, " ] %s %s", gp->outp, ds_get_buf(&mname)); + } else if (gp->type == '~') { + ds_cat_printf(&instance, "%s %s %s", tilde_tail(gp->ins->name, &ds), + gp->outp, ds_get_buf(&mname)); + } + + u_add_instance(ds_get_buf(&instance)); + gp = gp->nxt; + } + ds_free(&instance); + ds_free(&mname); +} + +static void delete_gates(void) +{ + struct gate_data *g1, *g2; + NAME_ENTRY n1, n2; + g1 = first_gate; + while (g1) { + g2 = g1; + if (g1->outp) tfree(g1->outp); + n1 = g1->ins; + while (n1) { + n2 = n1; + n1 = n1->next; + delete_name_entry(n2); + } + g1 = g1->nxt; + tfree(g2); + } + first_gate = last_gate = NULL; +} + +static int get_precedence(char * s) { + switch (s[0]) { + case '~': + return 4; + case '&': + return 3; + case '^': + return 2; + case '|': + return 1; + default: + return 0; + } +} + +static int push(struct Stack* stack, char * item) +{ + if (stack->top == STACK_SIZE - 1) { + fprintf(stderr, "ERROR Postfix stack Overflow\n"); + return PUSH_ERROR; + } + stack->array[++stack->top] = item; + return 0; +} + +static char * pop(struct Stack* stack, int *status) +{ + if (stack->top == -1) { + fprintf(stderr, "ERROR Postfix stack Underflow\n"); + *status = POP_ERROR; + return ""; + } + *status = 0; + return stack->array[stack->top--]; +} + +static char *makestr(int c) +{ + static char buf[32]; + sprintf(buf, "%c", c); + return buf; +} + +static int infix_to_postfix(char* infix, DSTRING * postfix_p) +{ + struct Stack stack; + int ltok; + LEXER lx; + NAME_ENTRY nlist = NULL, entry = NULL; + int status = 0; + + lx = new_lexer(infix); + stack.top = -1; + nlist = add_name_entry("first", NULL); + ds_clear(postfix_p); + while ( ( ltok = lexer_scan(lx) ) != 0 ) { // start while ltok loop + if (ltok == LEX_ID) { + ds_cat_printf(postfix_p, " %s", lx->lexer_buf); + } else if (ltok == '(') { + entry = add_name_entry(makestr(ltok), nlist); + if (push(&stack, entry->name)) goto err_return; + } else if (ltok == ')') { + while ( stack.top != -1 && !eq(stack.array[stack.top], "(") ) { + ds_cat_printf(postfix_p, " %s", pop(&stack, &status)); + if (status) goto err_return; + } + pop(&stack, &status); + if (status) goto err_return; + } else if (lex_gate_op(ltok) || ltok == '~') { + char *tokstr = makestr(ltok); + if (ltok == '~') { // change ~ id --> tilde_id and continue + int next_tok; + next_tok = lexer_scan(lx); + if (next_tok == LEX_ID) { + ds_cat_printf(postfix_p, " tilde_%s", lx->lexer_buf); + continue; // while ltok loop + } else { + lexer_back_one(lx); + } + } + while ( stack.top != -1 && !eq(stack.array[stack.top], "(") && get_precedence(stack.array[stack.top]) >= get_precedence(tokstr) ) { + ds_cat_printf(postfix_p, " %s", pop(&stack, &status)); + if (status) goto err_return; + } + entry = add_name_entry(tokstr, nlist); + if (push(&stack, entry->name)) goto err_return; + } + } // end while ltok loop + while (stack.top != -1) { + ds_cat_printf(postfix_p, " %s", pop(&stack, &status)); + if (status) goto err_return; + } +err_return: + delete_lexer(lx); + clear_name_list(nlist); + return status; +} + +static int evaluate_postfix(char* postfix) +{ + static int count = 1; + struct Stack stack; + stack.top = -1; + char *operand1, *operand2; + char tmp[32]; + int ltok, prevtok = 0; + LEXER lx; + NAME_ENTRY nlist = NULL, entry = NULL; + struct gate_data *gp = NULL; + int status = 0; + int skip = 1; + +#ifdef PFX_USE_INVERTERS + if (getenv("PFX_USE_INVERTERS")) { + skip = 0; + } else { + skip = 1; + } +#endif + + lx = new_lexer(postfix); + nlist = add_name_entry("first", NULL); + tmp[0] = '\0'; + + while ( ( ltok = lexer_scan(lx) ) != 0 ) { // while ltok loop + if (ltok == LEX_ID) { + entry = add_name_entry(lx->lexer_buf, nlist); + if (push(&stack, entry->name)) goto err_return; + } else if (ltok == '~') { + operand1 = pop(&stack, &status); + if (status) goto err_return; + sprintf(tmp, "%s%d", TMP_PREFIX, count); + count++; + gp = new_gate('~', tmp, operand1, NULL); + gp = insert_gate(gp); + entry = add_name_entry(tmp, nlist); + if (push(&stack, entry->name)) goto err_return; + } else { + operand2 = pop(&stack, &status); + if (status) goto err_return; + operand1 = pop(&stack, &status); + if (status) goto err_return; + if (ltok == '|') { + sprintf(tmp, "%s%d", TMP_PREFIX, count); + count++; + gp = new_gate('|', tmp, operand1, operand2); + gp = insert_gate(gp); + entry = add_name_entry(tmp, nlist); + if (push(&stack, entry->name)) goto err_return; + } else if (ltok == '^') { + sprintf(tmp, "%s%d", TMP_PREFIX, count); + count++; + gp = new_gate('^', tmp, operand1, operand2); + gp = insert_gate(gp); + entry = add_name_entry(tmp, nlist); + if (push(&stack, entry->name)) goto err_return; + } else if (ltok == '&') { + sprintf(tmp, "%s%d", TMP_PREFIX, count); + count++; + gp = new_gate('&', tmp, operand1, operand2); + gp = insert_gate(gp); + entry = add_name_entry(tmp, nlist); + if (push(&stack, entry->name)) goto err_return; + } + } + prevtok = ltok; + } // end while ltok loop + if (prevtok == LEX_ID) { + char *n1 = NULL; + DS_CREATE(ds1, 32); + count++; + sprintf(tmp, "%s%d", TMP_PREFIX, count); + n1 = tilde_tail(pop(&stack, &status), &ds1); + if (status) goto err_return; + if (!skip && n1[0] == '~') { + gp = new_gate('~', tmp, n1 + 1, NULL); + gp->is_not = TRUE; + } else { + gp = new_gate('~', tmp, n1, NULL); + gp->is_not = FALSE; + } + gp = insert_gate(gp); + ds_free(&ds1); + } +err_return: + delete_lexer(lx); + clear_name_list(nlist); + return status; +} + +/* End of infix to posfix */ + /* Start parse table */ typedef struct table_line *TLINE; struct table_line { @@ -436,7 +891,6 @@ struct parse_table { }; static PTABLE parse_tab = NULL; -static PTABLE gen_tab = NULL; static PTABLE new_parse_table(void) { @@ -462,170 +916,24 @@ static void delete_parse_table(PTABLE pt) tfree(pt); } -static void delete_parse_gen_tables(void) +static void delete_parse_tables(void) { delete_parse_table(parse_tab); - delete_parse_table(gen_tab); - parse_tab = gen_tab = NULL; + parse_tab = NULL; } static void init_parse_tables(void) { parse_tab = new_parse_table(); - gen_tab = new_parse_table(); -} - -static TLINE ptab_new_line(char *line) -{ - TLINE t = NULL; - t = TMALLOC(struct table_line, 1); - t->next = NULL; - t->line = TMALLOC(char, (strlen(line) + 1)); - strcpy(t->line, line); - t->depth = 0; - return t; -} - -static TLINE add_common(char *line, BOOL ignore_blank) -{ - if (!line) - return NULL; - if (ignore_blank) { - if (line[0] == '\0') { - return NULL; - } else if (line[0] == '\n' && strlen(line) < 2) { - return NULL; - } - } - return ptab_new_line(line); -} - -static TLINE add_to_parse_table(PTABLE pt, char *line, BOOL ignore_blank) -{ - TLINE t; - if (!pt) - return NULL; - t = add_common(line, ignore_blank); - if (!t) - return NULL; - t->next = NULL; - if (!pt->first) { - pt->first = pt->last = t; - } else { - pt->last->next = t; - pt->last = t; - } - pt->entry_count++; - return t; -} - -static TLINE ptab_add_line(char *line, BOOL ignore_blank, int depth) -{ - TLINE t; - t = add_to_parse_table(parse_tab, line, ignore_blank); - if (t) - t->depth = depth; - return t; -} - -static TLINE gen_tab_add_line(char *line, BOOL ignore_blank) -{ - TLINE t; - t = add_to_parse_table(gen_tab, line, ignore_blank); - return t; -} - -static char *get_temp_from_line(char *line, BOOL begin, DSTRING *pds) -{ - /* First occurrence of "tmpx.." on the line, x is a digit */ - /* If begin is TRUE then "tmpx.." must be at the start of line */ - char *p, *q; - int j = 0; - p = strstr(line, "tmp"); - if (!p) - return NULL; - if (begin && p != line) - return NULL; - ds_clear(pds); - p += 3; - if (!isdigit(p[0])) - return NULL; - ds_cat_str(pds, "tmp"); - for (q = p, j = 0; isdigit(q[j]) || q[j] == '_'; j++) { - ds_cat_char(pds, q[j]); - } - ds_cat_char(pds, '\0'); - return ds_get_buf(pds); -} - -static char *find_temp_begin(char *line, DSTRING *pds) -{ - return get_temp_from_line(line, TRUE, pds); -} - -static char *find_temp_anywhere(char *line, DSTRING *pds) -{ - return get_temp_from_line(line, FALSE, pds); -} - -static TLINE tab_find(PTABLE pt, char *str, BOOL start_of_line) -{ - TLINE t; - size_t len; - - if (!pt) - return NULL; - t = pt->first; - len = strlen(str); - while (t) { - if (start_of_line) { - if (strncmp(t->line, str, len) == 0) - return t; - } else { - if (strstr(t->line, str)) - return t; - } - t = t->next; - } - return NULL; -} - -static void ptable_print(PTABLE pt) -{ - TLINE t; - if (!pt) - return; - t = pt->first; - printf("entry_count %u\n", pt->entry_count); - while (t) { - if (t->depth > 1) { - int i; - for (i = 1; i < t->depth; i++) { - printf(" "); - } - } - printf("%s", t->line); - if (t->depth > 0) - printf(" ...[%d]", t->depth); - printf("\n"); - t = t->next; - } } /* End parse table */ /* Start of logicexp parser */ -static char *get_inst_name(void); -static char *get_temp_name(void); static void aerror(char *s); static BOOL amatch(int t); -static BOOL bexpr(void); -static BOOL bfactor(void); static BOOL bparse(char *line, BOOL new_lexer); static int lookahead = 0; -static int adepth = 0; -static int max_adepth = 0; -static DSTRING d_curr_line; static int number_of_instances = 0; static BOOL use_tmodel_delays = FALSE; @@ -633,7 +941,7 @@ static void cleanup_parser(void) { delete_lexer(parse_lexer); parse_lexer = NULL; - delete_parse_gen_tables(); + delete_parse_tables(); } static char *get_inst_name(void) @@ -646,33 +954,6 @@ static char *get_inst_name(void) return name; } -static char *get_inverter_output_name(char *input, DSTRING *pds) -{ - LEXER lx = parse_lexer; - // FIX ME keep this name in the symbol table to ensure uniqueness - ds_clear(pds); - ds_cat_printf(pds, "inv_out__%s", input); - if (member_sym_tab(ds_get_buf(pds), lx->lexer_sym_tab)) - fprintf(stderr, "ERROR %s is already in use\n", ds_get_buf(pds)); - return ds_get_buf(pds); -} - -static char *get_inv_tail(char *str, DSTRING *pds) -{ - char *p = NULL, *q = NULL; - int j = 0; - size_t slen = strlen("inv_out__"); - p = strstr(str, "inv_out__"); - if (!p) - return NULL; - ds_clear(pds); - for (q = p + slen, j = 0; q[j] != '\0' && !isspace(q[j]); j++) { - ds_cat_char(pds, q[j]); - } - ds_cat_char(pds, '\0'); - return ds_get_buf(pds); -} - static void gen_models(void) { DS_CREATE(model, 64); @@ -733,15 +1014,6 @@ static void aerror(char *s) cleanup_parser(); } -char *get_temp_name(void) -{ - static char name[64]; - static int number = 0; - number++; - (void) sprintf(name, "tmp%d", number); - return name; -} - static BOOL amatch(int t) { if (lookahead == t) { @@ -755,688 +1027,88 @@ static BOOL amatch(int t) return TRUE; } -#define AMATCH_BFACTOR(n) \ -{ \ - if (!amatch((n))) { \ - return FALSE; \ - } \ -} - -static BOOL bfactor(void) -{ - /* factor is : ['~'] rest - where rest is: input_name_id | '(' expr ')' | error - [] means optional - */ - BOOL is_not = FALSE; - SYM_TAB entry = NULL; - LEXER lx = parse_lexer; - - adepth++; - - if (lookahead == '~') { - is_not = TRUE; - lookahead = lex_scan(); - } - - if (lookahead == LEX_ID) { - entry = add_sym_tab_entry(lx->lexer_buf, SYM_ID, &lx->lexer_sym_tab); - if (is_not) { - DS_CREATE(dstr, 128); - ds_clear(&dstr); - ds_cat_printf(&d_curr_line, "%s ", - get_inverter_output_name(lx->lexer_buf, &dstr)); - ds_free(&dstr); - entry->attribute |= SYM_INVERTER; - entry->ref_count++; - } else { - ds_cat_printf(&d_curr_line, "%s ", lx->lexer_buf); - } - - lookahead = lex_scan(); - - } else if (lookahead == '(') { - DS_CREATE(tmpnam, 64); - - ds_clear(&tmpnam); - if (adepth > max_adepth) - max_adepth = adepth; - - ds_cat_str(&tmpnam, get_temp_name()); - (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE, adepth); - ds_clear(&d_curr_line); - ds_cat_printf(&d_curr_line, "%s__%d <- ", ds_get_buf(&tmpnam), adepth); - - if (is_not) { - ds_cat_printf(&d_curr_line, "~ %c", lookahead); - } else { - ds_cat_printf(&d_curr_line, "%c", lookahead); - } - (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE, adepth); - ds_clear(&d_curr_line); - - lookahead = lex_scan(); - if (!bexpr()) { - cleanup_parser(); - return FALSE; - } - - (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE, adepth); - ds_clear(&d_curr_line); - - ds_cat_printf(&d_curr_line, "%c -> %s__%d", lookahead, - ds_get_buf(&tmpnam), adepth); - (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE, adepth); - ds_clear(&d_curr_line); - - ds_free(&tmpnam); - AMATCH_BFACTOR(')'); - - } else { - aerror("bfactor: syntax error"); - return FALSE; - } - adepth--; - return TRUE; -} - -static BOOL bexpr(void) -{ - /* expr is: factor { gate_op factor }+ - where {}+ means 0 or more times. - */ - if (!bfactor()) { - cleanup_parser(); - return FALSE; - } - - while (lex_gate_op(lookahead)) { - ds_cat_printf(&d_curr_line, "%c ", lookahead); - - lookahead = lex_scan(); - if (!bfactor()) { - cleanup_parser(); - return FALSE; - } - } - return TRUE; -} - -#define AMATCH_BSTMT(n) \ -{ \ - if (!amatch((n))) { \ - ds_free(&tname); ds_free(&assign); \ - return FALSE; \ - } \ -} - -static BOOL bstmt(void) +static BOOL bstmt_postfix(void) { /* A stmt is: output_name_id = '{' expr '}' */ - BOOL verbose = PRINT_ALL; - int end_pos = 0, start_pos = 0; - SYM_TAB entry = NULL; - DS_CREATE(tname, 64); - DS_CREATE(assign, LEX_BUF_SZ); + DS_CREATE(lhs, 32); + DS_CREATE(postfix, 1024); + DS_CREATE(infix, 1024); + char *right_bracket = NULL, *rest = NULL; + BOOL retval = TRUE; if (lookahead == LEX_ID) { - entry = add_sym_tab_entry(parse_lexer->lexer_buf, SYM_ID, - &parse_lexer->lexer_sym_tab); + ds_clear(&lhs); + ds_cat_str(&lhs, parse_lexer->lexer_buf); + lookahead = lex_scan(); } else { - aerror("bstmt: syntax error"); - return FALSE; + aerror("bstmt_postfix: syntax error"); + retval = FALSE; + goto bail_out; + } + if (!amatch(('='))) { + retval = FALSE; + goto bail_out; } - adepth++; - if (adepth > max_adepth) - max_adepth = adepth; - - if (verbose) { - start_pos = parse_lexer->lexer_pos; - printf("* %s", parse_lexer->lexer_buf); + rest = parse_lexer->lexer_line + parse_lexer->lexer_pos; + right_bracket = strstr(rest, "}"); + ds_clear(&infix); + ds_cat_mem(&infix, rest, right_bracket - rest); + if (infix_to_postfix(ds_get_buf(&infix), &postfix)) { + retval = FALSE; + goto bail_out; } - - AMATCH_BSTMT(LEX_ID); - AMATCH_BSTMT('='); - - ds_clear(&assign); - ds_cat_printf(&assign, "%s =", entry->name); - (void) ptab_add_line(ds_get_buf(&assign), TRUE, adepth); - - AMATCH_BSTMT('{'); - - ds_clear(&tname); - ds_cat_str(&tname, get_temp_name()); - ds_cat_printf(&d_curr_line, "%s__%d <- (", ds_get_buf(&tname), adepth); - (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE, adepth); - ds_clear(&d_curr_line); - - if (!bexpr()) { - cleanup_parser(); - ds_free(&assign); - ds_free(&tname); - return FALSE; + if (evaluate_postfix(ds_get_buf(&postfix))) { + retval = FALSE; + goto bail_out; } - - if (ds_get_length(&d_curr_line) > 0) { - (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE, adepth); + scan_gates(&lhs); + gen_scanned_gates(first_gate); + lookahead = lex_scan(); + while (lookahead != '}') { + lookahead = lex_scan(); } - ds_clear(&d_curr_line); - ds_cat_printf(&d_curr_line, ") -> %s__%d", ds_get_buf(&tname), adepth); - (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE, adepth); - ds_clear(&d_curr_line); + lookahead = lex_scan(); - if (verbose) { - DS_CREATE(stmt_str, 128); - end_pos = parse_lexer->lexer_pos; - ds_cat_mem(&stmt_str, &parse_lexer->lexer_line[start_pos], - (size_t) (end_pos - start_pos)); - printf("%s\n", ds_get_buf(&stmt_str)); - ds_free(&stmt_str); - } - - AMATCH_BSTMT('}'); - - ds_free(&assign); - ds_free(&tname); - adepth--; - return TRUE; +bail_out: + delete_gates(); + ds_free(&lhs); + ds_free(&postfix); + ds_free(&infix); + return retval; } -static PTABLE optimize_gen_tab(PTABLE pt) +static char *get_logicexp_tmodel_delays( + char *out_name, int gate_op, BOOL isnot, DSTRING *mname) { - /* This function compacts the gen_tab, returning a new PTABLE. - Aliases are transformed and removed as described below. - Usually, optimize_gen_tab is called a second time on the - PTABLE created by the first call. The algorithm here will - only transform one level of aliases. - */ - TLINE t = NULL; - LEXER lxr = NULL; - int val, idnum = 0, tok_count = 0; - SYM_TAB entry = NULL, alias_tab = NULL; - BOOL found_tilde = FALSE, starts_with_temp = FALSE; - BOOL prit = PRINT_ALL; - PTABLE new_gen = NULL; - DS_CREATE(scratch, LEX_BUF_SZ); - DS_CREATE(alias, 64); - DS_CREATE(non_tmp_name, 64); - DS_CREATE(tmp_name, 64); - DS_CREATE(find_str, 128); - - if (!pt || !pt->first) { - ds_free(&scratch); - ds_free(&alias); - ds_free(&non_tmp_name); - ds_free(&tmp_name); - ds_free(&find_str); - return NULL; - } - t = pt->first; - lxr = new_lexer(t->line); - /* Look for tmp... = another_name - t1 = name1 (alias for t1) - t2 = name2 (alias for t2) - t3 = t1 op t2 - during second pass transform - ignore t1, t2 - t3 = name1 op name2 - */ - while (t) { - idnum = 0; - val = lexer_scan(lxr); - ds_clear(&alias); - entry = NULL; - found_tilde = FALSE; - if (find_temp_begin(t->line, &find_str)) - starts_with_temp = TRUE; - else - starts_with_temp = FALSE; - tok_count = 0; - while (val != '\0') { - tok_count++; - if (val == LEX_ID) { - idnum++; - if (idnum == 1) { - entry = add_sym_tab_entry(lxr->lexer_buf, SYM_ID, - &alias_tab); - } else if (idnum == 2) { - ds_cat_str(&alias, lxr->lexer_buf); - } - } else if (val == '~') { - found_tilde = TRUE; - if (tok_count != 3) { - goto quick_return; - } - } else if (val == '=') { - if (tok_count != 2) { - goto quick_return; - } + ds_clear(mname); + if (use_tmodel_delays) { + /* This is the case when logicexp has a UGATE + timing model (not d0_gate) and no pindly. + */ + SYM_TAB entry = NULL; + char *nm1 = 0; + entry = member_sym_tab(out_name, parse_lexer->lexer_sym_tab); + if (entry && (entry->attribute & SYM_OUTPUT)) { + nm1 = tmodel_gate_name(gate_op, isnot); + if (nm1) { + ds_cat_str(mname, nm1); } - val = lexer_scan(lxr); } - if (starts_with_temp && !found_tilde && idnum == 2) - alias_sym_tab(ds_get_buf(&alias), entry); - t = t->next; - if (t) { - delete_lexer(lxr); - lxr = new_lexer(t->line); + if (!nm1) { + nm1 = lex_gate_name(gate_op, isnot); + ds_cat_str(mname, nm1); } - } - if (prit) { - printf("alias_tab:\n"); - print_sym_tab(alias_tab, FALSE); - } - delete_lexer(lxr); - - - /* Second pass, replace names by their aliases. - Perform transformation as mentioned above. - Transform: - t1 = t2 op t3 {op t4 ...} (t* can also be name*, not just tmps) - lhs = t1 (lhs of original x = { expr } statement) - into: - ignore lhs = t1 - lhs = t2 op t3 {op t4...} - NOTE that lhs_= t1 should be the last entry in gen_tab. - lhs = t1 (from stmt lhs = { expr }) is the top-most level - in the parse tree, and is encountered last in the evaluation order. - */ - new_gen = new_parse_table(); - ds_clear(&scratch); - t = pt->first; - lxr = new_lexer(t->line); - while (t) { // while (t) second pass - BOOL skip = FALSE; - - val = lexer_scan(lxr); - idnum = 0; - entry = NULL; - if (find_temp_begin(t->line, &find_str)) - starts_with_temp = TRUE; - else - starts_with_temp = FALSE; - tok_count = 0; - ds_clear(&scratch); - ds_clear(&non_tmp_name); - ds_clear(&tmp_name); - while (val != '\0' && !skip) { - tok_count++; - if (val == LEX_ID) { - idnum++; - entry = member_sym_tab(lxr->lexer_buf, alias_tab); - if (entry && entry->alias) { - if (idnum > 1) { - ds_cat_printf(&scratch, "%s ", entry->alias); - } else if (idnum == 1) { - if (starts_with_temp) { - skip = TRUE; - } - } - } else { - ds_cat_printf(&scratch, "%s ", lxr->lexer_buf); - if (tok_count == 1) { - ds_clear(&non_tmp_name); - if (!find_temp_begin(lxr->lexer_buf, &find_str)) - ds_cat_str(&non_tmp_name, lxr->lexer_buf); - } else if (tok_count == 3) { - if (ds_get_length(&non_tmp_name) > 0) { - char *str1 = NULL; - str1 = find_temp_begin(lxr->lexer_buf, &find_str); - if (str1) { - ds_clear(&tmp_name); - ds_cat_str(&tmp_name, lxr->lexer_buf); - } - } - } - } - - if (idnum > 2) { - ds_clear(&non_tmp_name); - ds_clear(&tmp_name); - } - } else { - if (val == LEX_OTHER) { - delete_parse_table(new_gen); - new_gen = NULL; - goto quick_return; - } - ds_cat_printf(&scratch, "%c ", val); - } - val = lexer_scan(lxr); - } - t = t->next; - if (t) { - delete_lexer(lxr); - lxr = new_lexer(t->line); - } - if (!skip) { - TLINE tnamel = NULL; - char *p = NULL; - DS_CREATE(d_buf, 128); - BOOL ignore_lhs = FALSE; - - ds_clear(&d_buf); - if (ds_get_length(&tmp_name) > 0) - tnamel = tab_find(new_gen, ds_get_buf(&tmp_name), TRUE); - if (ds_get_length(&non_tmp_name) > 0 && tnamel) { - ignore_lhs = TRUE; - - ds_clear(&d_buf); - p = strstr(tnamel->line, " = "); - if (p) { - ds_cat_str(&d_buf, ds_get_buf(&non_tmp_name)); - ds_cat_str(&d_buf, p); - tfree(tnamel->line); - tnamel->line = TMALLOC(char, ds_get_length(&d_buf) + 1); - strcpy(tnamel->line, ds_get_buf(&d_buf)); - } - } - if (!ignore_lhs) { - (void) add_to_parse_table(new_gen, - ds_get_buf(&scratch), TRUE); - } - ds_free(&d_buf); - } - } // end of while (t) second pass - -quick_return: - if (new_gen && new_gen->entry_count == 0) { - delete_parse_table(new_gen); - new_gen = NULL; - } - ds_free(&alias); - ds_free(&scratch); - ds_free(&non_tmp_name); - ds_free(&tmp_name); - ds_free(&find_str); - delete_lexer(lxr); - delete_sym_tab(alias_tab); - - return new_gen; -} - -static BOOL gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) -{ - /* gen_gates is called with PTABLE gate_tab being the final - PTABLE produced by optimize_gen_tab(,..) calls. - If gate tab is the orignal uncompacted gen_tab, then extra - redundant intermediate gates will be created. - */ - TLINE t; - LEXER lxr = NULL; - int val, tok_count = 0, gate_op = 0, idnum = 0, in_count = 0; - BOOL found_tilde = FALSE; - BOOL prit = PRINT_ALL; - DS_CREATE(out_name, 64); - DS_CREATE(in_names, 64); - DS_CREATE(gate_name, 64); - DS_CREATE(instance, 128); - - if (!gate_tab || !gate_tab->first) { - ds_free(&out_name); - ds_free(&in_names); - ds_free(&gate_name); - ds_free(&instance); - return FALSE; - } - t = gate_tab->first; - lxr = new_lexer(t->line); - while (t) { // while t loop - ds_clear(&out_name); - ds_clear(&in_names); - ds_clear(&gate_name); - ds_clear(&instance); - idnum = 0; - val = lexer_scan(lxr); - found_tilde = FALSE; - tok_count = 0; - gate_op = 0; - in_count = 0; - while (val != '\0') { // while val loop - tok_count++; - if (val == LEX_ID) { - idnum++; - if (idnum == 1) { //output name - ds_cat_str(&out_name, lxr->lexer_buf); - } else { // input name - char *tail = NULL; - DS_CREATE(dstr, 64); - in_count++; - tail = get_inv_tail(lxr->lexer_buf, &dstr); - if (tail && strlen(tail) > 0) { - ds_cat_printf(&in_names, " ~%s", tail); - if (prit) { - printf( - "change input name \"%s\" tail \"~%s\"\n", - lxr->lexer_buf, tail); - } - } else { - ds_cat_printf(&in_names, " %s", lxr->lexer_buf); - } - ds_free(&dstr); - } - } else if (val == '~') { - found_tilde = TRUE; - if (tok_count != 3) goto gen_error; - } else if (val == '=') { - if (tok_count != 2) goto gen_error; - } else if (lex_gate_op(val)) { - if (gate_op != 0) { - if (val != gate_op) { - fprintf(stderr, - "\nERROR operator precedence parsing is not implemented\n" - " at expression %s\n" - " Please modify the LOGICEXP by inserting parentheses.\n" - " For example change a & b | c & d & e | f\n" - " to (a & b) | (c & d & e) | f\n" - " to get the desired PSPice precedence rules\n", - t->line - ); - goto gen_error; - } - } - gate_op = val; - } else { - goto gen_error; - } - val = lexer_scan(lxr); - } // end while val loop - - if (in_count == 1) { // buffer or inverter - if (gate_op != 0) goto gen_error; - gate_op = '~'; // found_tilde specifies inverter or buffer - } else if (in_count >= 2) { // AND, OR. XOR and inverses - if (gate_op == 0) goto gen_error; - } else { - goto gen_error; - } - - if (use_tmodel_delays) { - /* This is the case when logicexp has a UGATE - timing model (not d0_gate) and no pindly. - */ - SYM_TAB entry = NULL; - char *nm1 = 0; - entry = member_sym_tab(ds_get_buf(&out_name), parser_symbols); - if (entry && (entry->attribute & SYM_OUTPUT)) { - nm1 = tmodel_gate_name(gate_op, found_tilde); - if (nm1) { - ds_cat_str(&gate_name, nm1); - } - } - if (!nm1) { - nm1 = lex_gate_name(gate_op, found_tilde); - ds_cat_str(&gate_name, nm1); - } - } else { - ds_cat_str(&gate_name, lex_gate_name(gate_op, found_tilde)); - } - - ds_cat_printf(&instance, "%s ", get_inst_name()); - if (in_count == 1) { - ds_cat_printf(&instance, "%s %s ", ds_get_buf(&in_names), - ds_get_buf(&out_name)); - } else { - ds_cat_printf(&instance, "[%s ] %s ", ds_get_buf(&in_names), - ds_get_buf(&out_name)); - } - ds_cat_printf(&instance, "%s", ds_get_buf(&gate_name)); - t = t->next; - if (t) { - delete_lexer(lxr); - lxr = new_lexer(t->line); - } - if (ds_get_length(&instance) > 0) { - u_add_instance(ds_get_buf(&instance)); - } - } // end while t loop - - delete_lexer(lxr); - ds_free(&out_name); - ds_free(&in_names); - ds_free(&gate_name); - ds_free(&instance); - return TRUE; - -gen_error: - delete_lexer(lxr); - ds_free(&out_name); - ds_free(&in_names); - ds_free(&gate_name); - ds_free(&instance); - return FALSE; -} - -/* - gen_tab lines format: - name1 = [~] name2 [op name3 {op namei}+] - [] means optional, {}+ means zero or more times. - op is gate type (&, |, ^), ~ means invert output. - name1 is the gate output, and name2,... are inputs. - & is AND, | is OR, ^ is XOR. - ~ & is NAND, ~ | is NOR, ~ ^ is XNOR. - In any given line, all the op values are the same, and don't change. - AND and OR can have >= 2 inputs, XOR can have only 2 inputs. - If there is only a single input, then the gate is BUF or INV(~). -*/ -static void bevaluate(TLINE t, int deep) -{ - /* TLINE t is the entry in the parse_tab and deep is the call depth - where the parse_tab is transformed into the gen_tab. The deeper - calls are evaluated first, bottom-up, as determined by beval_order. - The tokens in the parse_tab are reassembled into gen_tab lines - as described above. - */ - char *s; - int down = 0; - DS_CREATE(this, 64); - DS_CREATE(other, 64); - DS_CREATE(new_line, LEX_BUF_SZ); - DS_CREATE(find_str, 128); - - s = find_temp_begin(t->line, &find_str); - if (!s) { - ds_free(&find_str); - return; - } - ds_clear(&other); - ds_clear(&new_line); - ds_clear(&this); - ds_cat_str(&this, s); - if (strstr(t->line + ds_get_length(&this), " ~ ")) { - ds_cat_printf(&new_line, "%s = ~ ", ds_get_buf(&this)); } else { - if (deep == 1) { - ds_cat_printf(&new_line, "%s ", parse_tab->first->line); - } else { - ds_cat_printf(&new_line, "%s = ", ds_get_buf(&this)); - } + ds_cat_str(mname, lex_gate_name(gate_op, isnot)); } - t = t->next; - while (t) { - s = find_temp_anywhere(t->line, &find_str); - if (s) { - if (eq(ds_get_buf(&this), s)) { - break; - } else { - if (down == 0) { - s = find_temp_begin(t->line, &find_str); - ds_clear(&other); - ds_cat_str(&other, s); - down = 1; - ds_cat_printf(&new_line, " %s", ds_get_buf(&other)); - } else if (down == 1) { - s = find_temp_anywhere(t->line, &find_str); - if (eq(ds_get_buf(&other), s)) { - down = 0; - ds_clear(&other); - } - } - } - } else if (down == 0) { - s = find_temp_anywhere(t->line, &find_str); - if (!s) { - ds_cat_printf(&new_line, " %s", t->line); - } - } - t = t->next; - } - (void) gen_tab_add_line(ds_get_buf(&new_line), TRUE); - ds_free(&this); - ds_free(&other); - ds_free(&new_line); - ds_free(&find_str); - return; -} - -static void beval_order(void) -{ - /* The parser is top-down recursive descent. The depth is used - so that the parsed data is evaluated bottom-up. Then the - tmp.. regions can be evaluated before they are referenced. - */ - int i, depth; - TLINE t; - size_t slen; - - if (!parse_tab || !parse_tab->first) - return; - slen = strlen("tmp"); - for (i = max_adepth; i > 0; i--) { - t = parse_tab->first; - while (t) { - char *q; - int cmp = 0; - cmp = strncmp(t->line, "tmp", slen); - if (cmp == 0 && ((q = strstr(t->line, " <- ")) != NULL)) { - depth = t->depth; - if (depth > 0) { - if (i == depth) { - bevaluate(t, i); - } - } - } - t = t->next; - } - } - return; + return ds_get_buf(mname); } static BOOL bparse(char *line, BOOL new_lexer) { - int stmt_num = 0; - BOOL ret_val = TRUE, prit = PRINT_ALL; - PTABLE opt_tab1 = NULL, opt_tab2 = NULL; + BOOL ret_val = TRUE; DS_CREATE(stmt, LEX_BUF_SZ); - char *seed_buf; - - seed_buf = TMALLOC(char, LEX_BUF_SZ); - (void) memcpy(seed_buf, "seed", strlen("seed")); - - ds_init(&d_curr_line, seed_buf, strlen("seed"), - LEX_BUF_SZ, ds_buf_type_heap); - ds_clear(&d_curr_line); if (new_lexer) lex_init(line); @@ -1445,83 +1117,17 @@ static BOOL bparse(char *line, BOOL new_lexer) lookahead = lex_scan(); // "logic" lookahead = lex_scan(); // ':' lookahead = lex_scan(); - while (lookahead != '\0') { // while lookahead loop - unsigned int last_count = 0, curr_count = 0; + while (lookahead != '\0') { init_parse_tables(); - adepth = max_adepth = 0; - stmt_num++; ds_clear(&stmt); ds_cat_str(&stmt, parse_lexer->lexer_buf); - if (!bstmt()) { + if (!bstmt_postfix()) { cleanup_parser(); ret_val= FALSE; break; } + } - if (prit) { - printf("START parse_tab\n"); - ptable_print(parse_tab); - printf("END parse_tab\n"); - } - - beval_order(); - - /* generate gates only when optimizations are successful */ - if (prit) { - printf("gen_tab "); - ptable_print(gen_tab); - } - last_count = gen_tab->entry_count; - if (last_count == 1) { - ret_val = gen_gates(gen_tab, parse_lexer->lexer_sym_tab); - if (!ret_val) { - fprintf(stderr, "ERROR generating gates for logicexp\n"); - } - } else if (last_count > 1) { - opt_tab1 = optimize_gen_tab(gen_tab); - if (prit) { - printf("opt_tab1 "); - ptable_print(opt_tab1); - } - if (opt_tab1) { - curr_count = opt_tab1->entry_count; - opt_tab2 = opt_tab1; - while (curr_count > 1 && curr_count < last_count) { - last_count = curr_count; - opt_tab2 = optimize_gen_tab(opt_tab1); - if (prit) { - printf("opt_tab2 "); - ptable_print(opt_tab2); - } - delete_parse_table(opt_tab1); - if (!opt_tab2) { - ret_val = FALSE; - break; - } - opt_tab1 = opt_tab2; - curr_count = opt_tab2->entry_count; - } - if (opt_tab2) { - ret_val = gen_gates(opt_tab2, parse_lexer->lexer_sym_tab); - if (!ret_val) { - fprintf(stderr, - "ERROR generating gates for logicexp\n"); - } - delete_parse_table(opt_tab2); - } - } else { - ret_val = FALSE; - } - } else { - ret_val = FALSE; - } - delete_parse_gen_tables(); - if (!ret_val) { - break; - } - } // end while lookahead loop - - ds_free(&d_curr_line); if (ret_val) gen_models(); ds_free(&stmt); @@ -1796,23 +1402,6 @@ static void delete_pindly_table(PINTABLE pint) tfree(pint); } -static void print_pindly_table(PINTABLE pint) -{ - PLINE p, next; - if (!pint) - return; - printf("num_entries %d\n", pint->num_entries); - next = pint->first; - while (next) { - p = next; - printf("in_name \"%s\"", p->in_name); - printf(" out_name \"%s\"", p->out_name); - printf(" ena_name \"%s\"", p->ena_name); - printf(" delays \"%s\"\n", p->delays); - next = p->next; - } -} - static PLINE nth_pindly_entry(PINTABLE pint, int n) { /* Entries are from 0 to num_entries - 1 */ @@ -1860,9 +1449,7 @@ static void gen_pindly_buffers(void) { DS_CREATE(dbuf, 128); PLINE pline = NULL; - BOOL prit = PRINT_ALL; - if (prit) { print_pindly_table(pindly_tab); } pline = pindly_tab->first; while (pline) { char *iname = NULL; @@ -2037,7 +1624,6 @@ static BOOL extract_delay( */ BOOL in_delay = FALSE, ret_val = TRUE; int i; - BOOL prit = PRINT_ALL; BOOL shorter = FALSE, update_val = FALSE; struct udevices_info info = u_get_udevices_info(); float del_max_val = 0.0, del_val = 0.0, del_min_val = FLT_MAX; @@ -2085,10 +1671,6 @@ static BOOL extract_delay( ds_clear(&tmp_ds); break; } - if (prit) { - printf("%s\n", ds_get_buf(&dly)); - printf("estimate \"%s\"\n", tmps); - } del_val = strtof(tmps, &units); update_val = FALSE; if (shorter) { @@ -2150,7 +1732,6 @@ static BOOL new_gen_output_models(LEXER lx) { int val, arrlen = 0, idx = 0, i; BOOL in_pindly = FALSE, in_tristate = FALSE; - BOOL prit = PRINT_ALL; DS_CREATE(enable_name, 64); DS_CREATE(last_enable, 64); PLINE pline = NULL; @@ -2192,7 +1773,6 @@ static BOOL new_gen_output_models(LEXER lx) } if (in_pindly && val == LEX_ID) { // start in_pindly and LEX_ID while (val == LEX_ID) { - if (prit) { printf("pindly out \"%s\"\n", lx->lexer_buf); } pline = find_pindly_out_name(pindly_tab, lx->lexer_buf); if (pline) { pline_arr[idx++] = pline; @@ -2218,7 +1798,6 @@ static BOOL new_gen_output_models(LEXER lx) BOOL invert = FALSE; if (eq(lx->lexer_buf, "lo")) invert = TRUE; - if (prit) { printf("tristate enable %s ", lx->lexer_buf); } val = lexer_scan(lx); if (val != '=') { // if there is no '=' it must be an enable id @@ -2231,7 +1810,6 @@ static BOOL new_gen_output_models(LEXER lx) goto err_return; } } - if (prit) { printf("ena \"%s\"\n", lx->lexer_buf); } ds_clear(&enable_name); if (invert) ds_cat_char(&enable_name, '~'); @@ -2252,7 +1830,6 @@ static BOOL new_gen_output_models(LEXER lx) goto err_return; } while (val == LEX_ID) { - if (prit) { printf("tristate out \"%s\"\n", lx->lexer_buf); } pline = find_pindly_out_name(pindly_tab, lx->lexer_buf); if (pline) { pline_arr[idx++] = pline; From b9c1f68ee034253c582c30a9089c90bb1af98894 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 13 Feb 2024 14:04:58 +0100 Subject: [PATCH 19/20] Preliminary fix to bug report 660 Final setting will be decided before next release. --- configure.ac | 2 +- src/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 48b776c4c..5c4a567e4 100644 --- a/configure.ac +++ b/configure.ac @@ -116,7 +116,7 @@ LT_INIT([shared static]) # # --> Set 'LT_NGSPICE_AGE' to 0. -LT_NGSPICE_CURRENT=0 +LT_NGSPICE_CURRENT=2 LT_NGSPICE_REVISION=9 LT_NGSPICE_AGE=2 LIBNGSPICE_SO_VERSION=$LT_NGSPICE_CURRENT.$LT_NGSPICE_REVISION.$LT_NGSPICE_AGE diff --git a/src/Makefile.am b/src/Makefile.am index 62a3536a2..aa2a49183 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -649,7 +649,7 @@ endif ## if !SHWIN ## if !SHCYG -libngspice_la_LDFLAGS += -version-info $(LT_NGSPICE_CURRENT):$(LT_NGSPICE_REVISION):$(LT_LIBNGSPICE_AGE) +libngspice_la_LDFLAGS += -version-info $(LT_NGSPICE_CURRENT):$(LT_NGSPICE_REVISION):$(LT_NGSPICE_AGE) ## endif ## endif From bfb2a5fd9c9ce361d6af40d5994ccc59225ed989 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 13 Feb 2024 14:59:49 +0100 Subject: [PATCH 20/20] As preliminary, better not change CURRENT --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 5c4a567e4..a19e417e8 100644 --- a/configure.ac +++ b/configure.ac @@ -116,9 +116,9 @@ LT_INIT([shared static]) # # --> Set 'LT_NGSPICE_AGE' to 0. -LT_NGSPICE_CURRENT=2 +LT_NGSPICE_CURRENT=0 LT_NGSPICE_REVISION=9 -LT_NGSPICE_AGE=2 +LT_NGSPICE_AGE=0 LIBNGSPICE_SO_VERSION=$LT_NGSPICE_CURRENT.$LT_NGSPICE_REVISION.$LT_NGSPICE_AGE # Announce the libtool version