From 744eaece691e6ba317b87d4cad0f6b2ed5a5e642 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 4 Apr 2022 17:41:28 +0200 Subject: [PATCH] Patch to avoid false reads and writes due to inconsitent structs SPAN and NOISEAN. Prevent using non-initialized variables. --- src/spicelib/analysis/nevalsrc.c | 122 +++++++++-------- src/spicelib/analysis/span.c | 221 ++++++++++++++++--------------- 2 files changed, 183 insertions(+), 160 deletions(-) diff --git a/src/spicelib/analysis/nevalsrc.c b/src/spicelib/analysis/nevalsrc.c index 9bde00ae2..c8f6b7dd4 100644 --- a/src/spicelib/analysis/nevalsrc.c +++ b/src/spicelib/analysis/nevalsrc.c @@ -15,12 +15,12 @@ Author: 1987 Gary W. Ng */ -/* -Modified by Alessio Cacciatori: S-Params noise is calculated as noise current -correlation matrix. Per each noise source, the noise voltage at RF ports is converted -as an input noise current source by using (already availalble) Y matrix. -Outside RFSPICE declaration, code is legacy NGSPICE code. -*/ + /* + Modified by Alessio Cacciatori: S-Params noise is calculated as noise current + correlation matrix. Per each noise source, the noise voltage at RF ports is converted + as an input noise current source by using (already availalble) Y matrix. + Outside RFSPICE declaration, code is legacy NGSPICE code. + */ #include "ngspice/ngspice.h" #include "ngspice/cktdefs.h" @@ -28,20 +28,17 @@ Outside RFSPICE declaration, code is legacy NGSPICE code. #include "ngspice/noisedef.h" #ifdef RFSPICE -#include "../maths/dense/dense.h" -#include "../maths/dense/denseinlines.h" - extern CMat* eyem; extern CMat* zref; extern CMat* gn; extern CMat* gninv; extern CMat* vNoise; extern CMat* iNoise; - +#include "../../maths/dense/denseinlines.h" #endif void -NevalSrc (double *noise, double *lnNoise, CKTcircuit *ckt, int type, int node1, int node2, double param) +NevalSrc(double* noise, double* lnNoise, CKTcircuit* ckt, int type, int node1, int node2, double param) { #ifdef RFSPICE if (ckt->CKTcurrentAnalysis & DOING_SP) @@ -51,15 +48,21 @@ NevalSrc (double *noise, double *lnNoise, CKTcircuit *ckt, int type, int node1, switch (type) { case SHOTNOISE: - inoise = 2 * CHARGE * fabs(param); /* param is the dc current in a semiconductor */ + inoise = 2 * CHARGE * fabs(param); /* param is the dc current in a semiconductor */ + *noise = inoise; + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case THERMNOISE: - inoise = 4 * CONSTboltz * ckt->CKTtemp * param; /* param is the conductance of a resistor */ + inoise = 4 * CONSTboltz * ckt->CKTtemp * param; /* param is the conductance of a resistor */ + *noise = inoise; + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case N_GAIN: inoise = 0.0; + *noise = cmodu(csubco(ckt->CKTadjointRHS->d[0][node1], ckt->CKTadjointRHS->d[0][node2])); + break; } @@ -95,19 +98,19 @@ NevalSrc (double *noise, double *lnNoise, CKTcircuit *ckt, int type, int node1, double imagVal; double gain; - realVal = ckt->CKTrhs [node1] - ckt->CKTrhs [node2]; - imagVal = ckt->CKTirhs [node1] - ckt->CKTirhs [node2]; - gain = (realVal*realVal) + (imagVal*imagVal); + realVal = ckt->CKTrhs[node1] - ckt->CKTrhs[node2]; + imagVal = ckt->CKTirhs[node1] - ckt->CKTirhs[node2]; + gain = (realVal * realVal) + (imagVal * imagVal); switch (type) { case SHOTNOISE: *noise = gain * 2 * CHARGE * fabs(param); /* param is the dc current in a semiconductor */ - *lnNoise = log( MAX(*noise,N_MINLOG) ); + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case THERMNOISE: *noise = gain * 4 * CONSTboltz * ckt->CKTtemp * param; /* param is the conductance of a resistor */ - *lnNoise = log( MAX(*noise,N_MINLOG) ); + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case N_GAIN: @@ -131,22 +134,22 @@ NevalSrc (double *noise, double *lnNoise, CKTcircuit *ckt, int type, int node1, * "case by case" basis. What we CAN provide, though, is the noise * gain associated with the 1/f source. */ -/* Modified by Darsen Lu for BSIM4 tnoiMod=2 10/10/2010 -*/ + /* Modified by Darsen Lu for BSIM4 tnoiMod=2 10/10/2010 + */ void -NevalSrc2 ( -double *noise, -double *lnNoise, -CKTcircuit *ckt, -int type, -int node1, -int node2, -double param1, -int node3, -int node4, -double param2, -double phi21) /* Phase of signal 2 relative to signal 1 */ +NevalSrc2( + double* noise, + double* lnNoise, + CKTcircuit* ckt, + int type, + int node1, + int node2, + double param1, + int node3, + int node4, + double param2, + double phi21) /* Phase of signal 2 relative to signal 1 */ { double realVal1, imagVal1; @@ -159,10 +162,10 @@ double phi21) /* Phase of signal 2 relative to signal 1 */ { double knoise = 0.0; - + T0 = sqrt(param1); T1 = sqrt(param2); - cplx cfact; + cplx cfact; cfact.re = cos(phi21); cfact.im = sin(phi21); @@ -171,14 +174,20 @@ double phi21) /* Phase of signal 2 relative to signal 1 */ case SHOTNOISE: knoise = 2 * CHARGE; /* param is the dc current in a semiconductor */ + *noise = knoise; + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case THERMNOISE: knoise = 4 * CONSTboltz * ckt->CKTtemp; /* param is the conductance of a resistor */ + // For this simulation we are not collecting any statistics on output nodes. Force noise to 0 + *noise = knoise; + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case N_GAIN: knoise = 0.0; + *noise = cmodu(csubco(ckt->CKTadjointRHS->d[0][node1], ckt->CKTadjointRHS->d[0][node2])); break; } @@ -187,7 +196,7 @@ double phi21) /* Phase of signal 2 relative to signal 1 */ // Calculate input equivalent noise current source (we have port impedance attached) for (unsigned int s = 0; s < ckt->CKTportCount; s++) { - cplx vNoiseA = cmultdo(csubco(ckt->CKTadjointRHS->d[s][node1], ckt->CKTadjointRHS->d[s][node2]), knoise * sqrt(param1) ); + cplx vNoiseA = cmultdo(csubco(ckt->CKTadjointRHS->d[s][node1], ckt->CKTadjointRHS->d[s][node2]), knoise * sqrt(param1)); cplx vNoiseB = cmultco(cmultdo(csubco(ckt->CKTadjointRHS->d[s][node3], ckt->CKTadjointRHS->d[s][node4]), knoise * sqrt(param1)), cfact); vNoise->d[0][s] = caddco(vNoiseA, vNoiseB); @@ -217,27 +226,27 @@ double phi21) /* Phase of signal 2 relative to signal 1 */ #endif - realVal1 = ckt->CKTrhs [node1] - ckt->CKTrhs [node2]; - imagVal1 = ckt->CKTirhs [node1] - ckt->CKTirhs [node2]; - realVal2 = ckt->CKTrhs [node3] - ckt->CKTrhs [node4]; - imagVal2 = ckt->CKTirhs [node3] - ckt->CKTirhs [node4]; + realVal1 = ckt->CKTrhs[node1] - ckt->CKTrhs[node2]; + imagVal1 = ckt->CKTirhs[node1] - ckt->CKTirhs[node2]; + realVal2 = ckt->CKTrhs[node3] - ckt->CKTrhs[node4]; + imagVal2 = ckt->CKTirhs[node3] - ckt->CKTirhs[node4]; T0 = sqrt(param1); T1 = sqrt(param2); T2 = T1 * cos(phi21); T3 = T1 * sin(phi21); realOut = T0 * realVal1 + T2 * realVal2 - T3 * imagVal2; imagOut = T0 * imagVal1 + T2 * imagVal2 + T3 * realVal2; - param_gain = (realOut*realOut) + (imagOut*imagOut); + param_gain = (realOut * realOut) + (imagOut * imagOut); switch (type) { case SHOTNOISE: *noise = 2.0 * CHARGE * fabs(param_gain); /* param is the dc current in a semiconductor */ - *lnNoise = log( MAX(*noise,N_MINLOG) ); + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case THERMNOISE: *noise = 4.0 * CONSTboltz * ckt->CKTtemp * param_gain; /* param is the conductance of a resistor */ - *lnNoise = log( MAX(*noise,N_MINLOG) ); + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case N_GAIN: @@ -257,12 +266,14 @@ will implement dtemp feature. */ void -NevalSrcInstanceTemp (double *noise, double *lnNoise, CKTcircuit *ckt, int type, - int node1, int node2, double param, double param2) +NevalSrcInstanceTemp(double* noise, double* lnNoise, CKTcircuit* ckt, int type, + int node1, int node2, double param, double param2) { #ifdef RFSPICE + // For this simulation we are not collecting any statistics on output nodes. Force noise to 0 + if (ckt->CKTcurrentAnalysis & DOING_SP) { double inoise = 0.0; @@ -271,14 +282,21 @@ NevalSrcInstanceTemp (double *noise, double *lnNoise, CKTcircuit *ckt, int type, case SHOTNOISE: inoise = 2 * CHARGE * fabs(param); /* param is the dc current in a semiconductor */ + // For this simulation we are not collecting any statistics on output nodes. Force noise to 0 + *noise = inoise; + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case THERMNOISE: - inoise = 4.0 *CONSTboltz* (ckt->CKTtemp + param2)* param; /* param is the conductance of a resistor */ + inoise = 4.0 * CONSTboltz * (ckt->CKTtemp + param2) * param; /* param is the conductance of a resistor */ + // For this simulation we are not collecting any statistics on output nodes. Force noise to 0 + *noise = inoise; + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case N_GAIN: inoise = 0.0; + *noise = cmodu(csubco(ckt->CKTadjointRHS->d[0][node1], ckt->CKTadjointRHS->d[0][node2])); return; } @@ -286,7 +304,7 @@ NevalSrcInstanceTemp (double *noise, double *lnNoise, CKTcircuit *ckt, int type, inoise = sqrt(inoise); // Calculate input equivalent noise current source (we have port impedance attached) for (unsigned int s = 0; s < ckt->CKTportCount; s++) - vNoise->d[0][s] = cmultdo(csubco(ckt->CKTadjointRHS->d[s][node1], ckt->CKTadjointRHS->d[s][node2]),inoise); + vNoise->d[0][s] = cmultdo(csubco(ckt->CKTadjointRHS->d[s][node1], ckt->CKTadjointRHS->d[s][node2]), inoise); for (unsigned int d = 0; d < ckt->CKTportCount; d++) { @@ -313,20 +331,20 @@ NevalSrcInstanceTemp (double *noise, double *lnNoise, CKTcircuit *ckt, int type, double realVal; double imagVal; double gain; - realVal = ckt->CKTrhs [node1] - ckt->CKTrhs [node2]; - imagVal = ckt->CKTirhs [node1] - ckt->CKTirhs [node2]; - gain = (realVal*realVal) + (imagVal*imagVal); + realVal = ckt->CKTrhs[node1] - ckt->CKTrhs[node2]; + imagVal = ckt->CKTirhs[node1] - ckt->CKTirhs[node2]; + gain = (realVal * realVal) + (imagVal * imagVal); switch (type) { case SHOTNOISE: *noise = gain * 2 * CHARGE * fabs(param); /* param is the dc current in a semiconductor */ - *lnNoise = log( MAX(*noise,N_MINLOG) ); + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case THERMNOISE: *noise = gain * 4 * CONSTboltz * (ckt->CKTtemp + param2) /* param2 is the instance temperature difference */ - * param; /* param is the conductance of a resistor */ - *lnNoise = log( MAX(*noise,N_MINLOG) ); + * param; /* param is the conductance of a resistor */ + *lnNoise = log(MAX(*noise, N_MINLOG)); break; case N_GAIN: diff --git a/src/spicelib/analysis/span.c b/src/spicelib/analysis/span.c index a53c871dd..caceb95e5 100644 --- a/src/spicelib/analysis/span.c +++ b/src/spicelib/analysis/span.c @@ -1,5 +1,5 @@ /* -**** +**** * Alessio Cacciatori 2021 **** */ @@ -12,7 +12,7 @@ #ifdef XSPICE #include "ngspice/evt.h" #include "ngspice/enh.h" -/* gtri - add - wbk - 12/19/90 - Add headers */ +/* gtri - add - wbk - 12/19/90 - Add headers */ #include "ngspice/mif.h" #include "ngspice/evtproto.h" #include "ngspice/ipctiein.h" @@ -30,6 +30,7 @@ + #define INIT_STATS() \ do { \ startTime = SPfrontEnd->IFseconds(); \ @@ -68,19 +69,17 @@ double Fmin = 0; double refPortY0; int -CKTspnoise(CKTcircuit * ckt, int mode, int operation, Ndata * data) +CKTspnoise(CKTcircuit* ckt, int mode, int operation, Ndata* data, NOISEAN* noisean) { - NOISEAN* job = (NOISEAN*)ckt->CKTcurJob; + // Temporarily assign current job as a (dummy) NOISEAN analysis + // This is needed to avoid + SPAN* oldJob = (SPAN*)ckt->CKTcurJob; + ckt->CKTcurJob = (JOB*)noisean; double outNdens; int i; -#ifdef LEGACY - IFvalue outData; /* output variable (points to list of outputs)*/ - IFvalue refVal; /* reference variable (always 0)*/ -#endif int error; outNdens = 0.0; - job->NStpsSm = 1; /* let each device decide how many and what type of noise sources it has */ @@ -91,7 +90,11 @@ CKTspnoise(CKTcircuit * ckt, int mode, int operation, Ndata * data) if (a == 0) a = 2; error = DEVices[i]->DEVnoise(mode, operation, ckt->CKThead[i], ckt, data, &outNdens); - if (error) return (error); + if (error) + { + ckt->CKTcurJob = (JOB*)oldJob; + return (error); + } } } @@ -107,17 +110,17 @@ CKTspnoise(CKTcircuit * ckt, int mode, int operation, Ndata * data) { // We have the Cy noise matrix, - + // Equations from Stephen Maas 'Noise' double knorm = 4.0 * CONSTboltz * (ckt->CKTtemp); - CMat* tempCy = cscalarmultiply(ckt->CKTNoiseCYmat, 1.0/knorm); // cmultiply(, YConj); + CMat* tempCy = cscalarmultiply(ckt->CKTNoiseCYmat, 1.0 / knorm); // cmultiply(, YConj); if (ckt->CKTportCount == 2) { - + double Y21mod = cmodsqr(ckt->CKTYmat->d[1][0]); - Rn = (tempCy->d[1][1].re / Y21mod) ; + Rn = (tempCy->d[1][1].re / Y21mod); cplx Ycor = csubco(ckt->CKTYmat->d[0][0], cmultco( cdivco(tempCy->d[0][1], tempCy->d[1][1]), @@ -137,50 +140,11 @@ CKTspnoise(CKTcircuit * ckt, int mode, int operation, Ndata * data) Fmin = 10.0 * log10(Fmin); NF = 10.0 * log10(NF); } - + freecmat(tempCy); - } + } - -#ifdef LEGACY - switch (mode) { - - case N_DENS: - if ((job->NStpsSm == 0) - || data->prtSummary) - { - data->outpVector[data->outNumber++] = outNdens; - data->outpVector[data->outNumber++] = - (outNdens * data->GainSqInv); - - refVal.rValue = data->freq; /* the reference is the freq */ - if (!data->squared) - for (i = 0; i < data->outNumber; i++) - if (data->squared_value[i]) - data->outpVector[i] = sqrt(data->outpVector[i]); - outData.v.numValue = data->outNumber; /* vector number */ - outData.v.vec.rVec = data->outpVector; /* vector of outputs */ - SPfrontEnd->OUTpData(data->NplotPtr, &refVal, &outData); - } - break; - - case INT_NOIZ: - data->outpVector[data->outNumber++] = data->outNoiz; - data->outpVector[data->outNumber++] = data->inNoise; - if (!data->squared) - for (i = 0; i < data->outNumber; i++) - if (data->squared_value[i]) - data->outpVector[i] = sqrt(data->outpVector[i]); - outData.v.vec.rVec = data->outpVector; /* vector of outputs */ - outData.v.numValue = data->outNumber; /* vector number */ - SPfrontEnd->OUTpData(data->NplotPtr, &refVal, &outData); - break; - - default: - return (E_INTERN); - } -#endif - break; + break; case N_CLOSE: SPfrontEnd->OUTendPlot(data->NplotPtr); @@ -194,14 +158,16 @@ CKTspnoise(CKTcircuit * ckt, int mode, int operation, Ndata * data) break; default: + ckt->CKTcurJob = (JOB*)oldJob; return (E_INTERN); } + ckt->CKTcurJob = (JOB*)oldJob; return (OK); } int -NInspIter(CKTcircuit * ckt, VSRCinstance* port) +NInspIter(CKTcircuit* ckt, VSRCinstance* port) { int i; @@ -273,7 +239,7 @@ int initSPmatrix(CKTcircuit* ckt, int doNoise) return (E_NOMEM); // Now that we have found the model, we may init the Zref and Gn ports - if (ckt->CKTVSRCid>=0) + if (ckt->CKTVSRCid >= 0) VSRCspinit(ckt->CKThead[ckt->CKTVSRCid], ckt, zref, gn, gninv); if (doNoise) @@ -284,7 +250,7 @@ int initSPmatrix(CKTcircuit* ckt, int doNoise) ckt->CKTNoiseCYmat = newcmatnoinit(ckt->CKTportCount, ckt->CKTportCount); if (ckt->CKTNoiseCYmat == NULL) return (E_NOMEM); - // Use CKTadjointRHS as a convenience storage for all solutions (each solution per each + // Use CKTadjointRHS as a convenience storage for all solutions (each solution per each // port excitation) if (ckt->CKTadjointRHS != NULL) freecmat(ckt->CKTadjointRHS); ckt->CKTadjointRHS = newcmatnoinit(ckt->CKTportCount, ckt->CKTmaxEqNum); @@ -337,12 +303,32 @@ void deleteSPmatrix(CKTcircuit* ckt) ckt->CKTadjointRHS = NULL; } + +NOISEAN* SPcreateNoiseAnalysys(CKTcircuit* ckt) +{ + NOISEAN* internalNoiseAN = TMALLOC(NOISEAN, 1); + if (internalNoiseAN==NULL) return NULL; + SPAN* span = (SPAN*)ckt->CKTcurJob; + + internalNoiseAN->NstartFreq = span->SPstartFreq; + internalNoiseAN->NstopFreq = span->SPstopFreq; + internalNoiseAN->NStpsSm = 1; // Force to output noise at every freq step + internalNoiseAN->JOBnextJob = NULL; + internalNoiseAN->JOBtype = span->JOBtype; + internalNoiseAN->JOBname = NULL; + internalNoiseAN->NfreqDelta = span->SPfreqDelta; + internalNoiseAN->NstpType = span->SPstepType; + internalNoiseAN->NnumSteps = span->SPnumberSteps; + return internalNoiseAN; +} + + int -SPan(CKTcircuit *ckt, int restart) +SPan(CKTcircuit* ckt, int restart) { - SPAN *job = (SPAN *) ckt->CKTcurJob; + SPAN* job = (SPAN*)ckt->CKTcurJob; double freq; double freqTol; /* tolerence parameter for finding final frequency */ @@ -354,17 +340,22 @@ SPan(CKTcircuit *ckt, int restart) int error; int numNames; int i; - IFuid *nameList; /* va: tmalloc'ed list of names */ + IFuid* nameList; /* va: tmalloc'ed list of names */ IFuid freqUid; - static runDesc *spPlot = NULL; - runDesc *plot = NULL; + static runDesc* spPlot = NULL; + runDesc* plot = NULL; double* rhswoPorts = NULL; double* irhswoPorts = NULL; + NOISEAN* internalNoiseAN = NULL; + // Noise analysis is performed at each freq of the SP Analysis + // A temporary dummy job is therefore created + + /* variable must be static, for continuation of interrupted (Ctrl-C), longer lasting noise anlysis */ - static Ndata* data=NULL; + static Ndata* data = NULL; if (job->SPdoNoise) { data = TMALLOC(Ndata, 1); @@ -380,18 +371,18 @@ SPan(CKTcircuit *ckt, int restart) #ifdef XSPICE -/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */ + /* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */ - /* Tell the beginPlot routine what mode we're in */ + /* Tell the beginPlot routine what mode we're in */ - // For now, let's keep this as IPC_ANAL_AC (TBD) + // For now, let's keep this as IPC_ANAL_AC (TBD) g_ipc.anal_type = IPC_ANAL_AC; /* Tell the code models what mode we're in */ g_mif_info.circuit.anal_type = MIF_DC; g_mif_info.circuit.anal_init = MIF_TRUE; -/* gtri - end - wbk */ + /* gtri - end - wbk */ #endif /* start at beginning */ @@ -436,7 +427,7 @@ SPan(CKTcircuit *ckt, int restart) if (job->SPdoNoise) { data->lstFreq = job->SPstartFreq - 1; - data->delFreq = 1.0; + data->delFreq = 0.0; } #ifdef XSPICE @@ -452,7 +443,7 @@ SPan(CKTcircuit *ckt, int restart) EVTop_save(ckt, MIF_TRUE, 0.0); } else -#endif +#endif /* If no event-driven instances, do what SPICE normally does */ if (!ckt->CKTnoopac) { /* skip OP if option NOOPAC is set and circuit is linear */ error = CKTop(ckt, @@ -598,26 +589,27 @@ SPan(CKTcircuit *ckt, int restart) - tfree(nameList); - if(error) return(error); + tfree(nameList); + if (error) return(error); if (job->SPstepType != LINEAR) { - SPfrontEnd->OUTattributes (spPlot, NULL, OUT_SCALE_LOG, NULL); - } + SPfrontEnd->OUTattributes(spPlot, NULL, OUT_SCALE_LOG, NULL); + } freq = job->SPstartFreq; - } else { /* continue previous analysis */ + } + else { /* continue previous analysis */ freq = job->SPsaveFreq; job->SPsaveFreq = 0; /* clear the 'old' frequency */ - /* fix resume? saj, indeed !*/ - error = SPfrontEnd->OUTpBeginPlot (NULL, NULL, - NULL, - NULL, 0, - 666, NULL, 666, - &spPlot); - /* saj*/ + /* fix resume? saj, indeed !*/ + error = SPfrontEnd->OUTpBeginPlot(NULL, NULL, + NULL, + NULL, 0, + 666, NULL, 666, + &spPlot); + /* saj*/ } - + switch (job->SPstepType) { case DECADE: case OCTAVE: @@ -633,14 +625,14 @@ SPan(CKTcircuit *ckt, int restart) #ifdef XSPICE -/* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */ + /* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */ g_mif_info.circuit.anal_init = MIF_TRUE; /* Tell the code models what mode we're in */ g_mif_info.circuit.anal_type = MIF_AC; -/* gtri - end - wbk */ + /* gtri - end - wbk */ #endif INIT_STATS(); @@ -651,13 +643,22 @@ SPan(CKTcircuit *ckt, int restart) return (E_NOMEM); // Create Noise UID, if needed - if (job->SPdoNoise) { + internalNoiseAN = SPcreateNoiseAnalysys(ckt); + if (internalNoiseAN == NULL) + return (E_NOMEM); data->numPlots = 0; /* we don't have any plots yet */ - error = CKTspnoise(ckt, N_DENS, N_OPEN, data); - if (error) return(error); + data->freq = freq; + + + error = CKTspnoise(ckt, N_DENS, N_OPEN, data, internalNoiseAN); + + if (error) { + tfree(internalNoiseAN); + return(error); + } } ckt->CKTactivePort = 0; @@ -688,7 +689,7 @@ SPan(CKTcircuit *ckt, int restart) EVTop_save(ckt, MIF_TRUE, 0.0); } else -#endif +#endif // If no event-driven instances, do what SPICE normally does error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, @@ -707,7 +708,7 @@ SPan(CKTcircuit *ckt, int restart) } } - // Store previous rhs + // Store previous rhs if (rhswoPorts == NULL) rhswoPorts = (double*)TMALLOC(double, ckt->CKTmaxEqNum); else @@ -735,7 +736,7 @@ SPan(CKTcircuit *ckt, int restart) int vsrcLookupType = CKTtypelook("Vsource"); int vsrcRoot = -1; - + // Get VSRCs root model if (ckt->CKTVSRCid == -1) { @@ -761,12 +762,12 @@ SPan(CKTcircuit *ckt, int restart) // Pre-load everything but RF Ports (these will be updated in the next cycle). error = NIspPreload(ckt); if (error) return (error); - -// error = VSRCsaveNPData(ckt->CKThead[vsrcRoot]); -// if (error) return (error); - //Keep a backup copy - memcpy(rhswoPorts, ckt->CKTrhs, ckt->CKTmaxEqNum * sizeof(double)); + // error = VSRCsaveNPData(ckt->CKThead[vsrcRoot]); + // if (error) return (error); + + //Keep a backup copy + memcpy(rhswoPorts, ckt->CKTrhs, ckt->CKTmaxEqNum * sizeof(double)); memcpy(rhswoPorts, ckt->CKTirhs, ckt->CKTmaxEqNum * sizeof(double)); for (activePort = 1; activePort <= ckt->CKTportCount; activePort++) @@ -836,7 +837,7 @@ SPan(CKTcircuit *ckt, int restart) if (job->SPdoNoise) { - data->delFreq = freq - data->lstFreq; + data->freq = freq; @@ -847,7 +848,7 @@ SPan(CKTcircuit *ckt, int restart) /* the frequency will NOT be stored in array[0] as before; instead, * it will be given in refVal.rValue (see later) */ - ckt->CKTactivePort = activePort+1; + ckt->CKTactivePort = activePort + 1; NInspIter(ckt, (VSRCinstance*)(ckt->CKTrfPorts[activePort])); /* solve the adjoint system */ /* put the solution of the current adjoint system into the storage matrix*/ @@ -861,15 +862,16 @@ SPan(CKTcircuit *ckt, int restart) ckt->CKTadjointRHS->d[activePort][j] = temp; } } - /* - now we have all the solutions of the adjoint system, we may look into actual - noise sourches - */ + /* + now we have all the solutions of the adjoint system, we may look into actual + noise sourches + */ - error = CKTspnoise(ckt, N_DENS, N_CALC, data); + error = CKTspnoise(ckt, N_DENS, N_CALC, data, internalNoiseAN); if (error) { - tfree(data); + tfree(internalNoiseAN); + tfree(data); tfree(rhswoPorts); tfree(irhswoPorts); deleteSPmatrix(ckt); @@ -878,7 +880,7 @@ SPan(CKTcircuit *ckt, int restart) data->lstFreq = freq; } - + #ifdef XSPICE /* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ @@ -893,9 +895,10 @@ SPan(CKTcircuit *ckt, int restart) /* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ #else error = CKTspDump(ckt, freq, acPlot, job->SPdoNoise)); -#endif +#endif if (error) { UPDATE_STATS(DOING_AC); + tfree(internalNoiseAN); tfree(rhswoPorts); tfree(irhswoPorts); tfree(data); @@ -940,6 +943,7 @@ SPan(CKTcircuit *ckt, int restart) if (job->SPfreqDelta == 0) goto endsweep; break; default: + tfree(internalNoiseAN); tfree(rhswoPorts); tfree(irhswoPorts); tfree(data); @@ -949,9 +953,10 @@ SPan(CKTcircuit *ckt, int restart) } } endsweep: - SPfrontEnd->OUTendPlot (spPlot); + SPfrontEnd->OUTendPlot(spPlot); spPlot = NULL; UPDATE_STATS(0); + tfree(internalNoiseAN); tfree(rhswoPorts); tfree(irhswoPorts); deleteSPmatrix(ckt);