Patch to avoid false reads and writes due to inconsitent

structs SPAN and NOISEAN.
Prevent using non-initialized variables.
This commit is contained in:
Holger Vogt 2022-04-04 17:41:28 +02:00
parent 8a6231a813
commit 321d53a4e9
2 changed files with 183 additions and 160 deletions

View File

@ -28,16 +28,13 @@ Outside RFSPICE declaration, code is legacy NGSPICE code.
#include "ngspice/noisedef.h" #include "ngspice/noisedef.h"
#ifdef RFSPICE #ifdef RFSPICE
#include "../maths/dense/dense.h"
#include "../maths/dense/denseinlines.h"
extern CMat* eyem; extern CMat* eyem;
extern CMat* zref; extern CMat* zref;
extern CMat* gn; extern CMat* gn;
extern CMat* gninv; extern CMat* gninv;
extern CMat* vNoise; extern CMat* vNoise;
extern CMat* iNoise; extern CMat* iNoise;
#include "../../maths/dense/denseinlines.h"
#endif #endif
void void
@ -52,14 +49,20 @@ NevalSrc (double *noise, double *lnNoise, CKTcircuit *ckt, int type, int node1,
case SHOTNOISE: 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; break;
case THERMNOISE: 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; break;
case N_GAIN: case N_GAIN:
inoise = 0.0; inoise = 0.0;
*noise = cmodu(csubco(ckt->CKTadjointRHS->d[0][node1], ckt->CKTadjointRHS->d[0][node2]));
break; break;
} }
@ -171,14 +174,20 @@ double phi21) /* Phase of signal 2 relative to signal 1 */
case SHOTNOISE: case SHOTNOISE:
knoise = 2 * CHARGE; /* param is the dc current in a semiconductor */ knoise = 2 * CHARGE; /* param is the dc current in a semiconductor */
*noise = knoise;
*lnNoise = log(MAX(*noise, N_MINLOG));
break; break;
case THERMNOISE: case THERMNOISE:
knoise = 4 * CONSTboltz * ckt->CKTtemp; /* param is the conductance of a resistor */ 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; break;
case N_GAIN: case N_GAIN:
knoise = 0.0; knoise = 0.0;
*noise = cmodu(csubco(ckt->CKTadjointRHS->d[0][node1], ckt->CKTadjointRHS->d[0][node2]));
break; break;
} }
@ -263,6 +272,8 @@ NevalSrcInstanceTemp (double *noise, double *lnNoise, CKTcircuit *ckt, int type,
#ifdef RFSPICE #ifdef RFSPICE
// For this simulation we are not collecting any statistics on output nodes. Force noise to 0
if (ckt->CKTcurrentAnalysis & DOING_SP) if (ckt->CKTcurrentAnalysis & DOING_SP)
{ {
double inoise = 0.0; double inoise = 0.0;
@ -271,14 +282,21 @@ NevalSrcInstanceTemp (double *noise, double *lnNoise, CKTcircuit *ckt, int type,
case SHOTNOISE: 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 */
// 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; break;
case THERMNOISE: 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; break;
case N_GAIN: case N_GAIN:
inoise = 0.0; inoise = 0.0;
*noise = cmodu(csubco(ckt->CKTadjointRHS->d[0][node1], ckt->CKTadjointRHS->d[0][node2]));
return; return;
} }

View File

@ -30,6 +30,7 @@
#define INIT_STATS() \ #define INIT_STATS() \
do { \ do { \
startTime = SPfrontEnd->IFseconds(); \ startTime = SPfrontEnd->IFseconds(); \
@ -68,19 +69,17 @@ double Fmin = 0;
double refPortY0; double refPortY0;
int 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; double outNdens;
int i; int i;
#ifdef LEGACY
IFvalue outData; /* output variable (points to list of outputs)*/
IFvalue refVal; /* reference variable (always 0)*/
#endif
int error; int error;
outNdens = 0.0; outNdens = 0.0;
job->NStpsSm = 1;
/* let each device decide how many and what type of noise sources it has */ /* 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; if (a == 0) a = 2;
error = DEVices[i]->DEVnoise(mode, operation, ckt->CKThead[i], error = DEVices[i]->DEVnoise(mode, operation, ckt->CKThead[i],
ckt, data, &outNdens); ckt, data, &outNdens);
if (error) return (error); if (error)
{
ckt->CKTcurJob = (JOB*)oldJob;
return (error);
}
} }
} }
@ -141,45 +144,6 @@ CKTspnoise(CKTcircuit * ckt, int mode, int operation, Ndata * data)
freecmat(tempCy); 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: case N_CLOSE:
@ -194,8 +158,10 @@ CKTspnoise(CKTcircuit * ckt, int mode, int operation, Ndata * data)
break; break;
default: default:
ckt->CKTcurJob = (JOB*)oldJob;
return (E_INTERN); return (E_INTERN);
} }
ckt->CKTcurJob = (JOB*)oldJob;
return (OK); return (OK);
} }
@ -337,6 +303,26 @@ void deleteSPmatrix(CKTcircuit* ckt)
ckt->CKTadjointRHS = NULL; 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 int
SPan(CKTcircuit* ckt, int restart) SPan(CKTcircuit* ckt, int restart)
{ {
@ -362,6 +348,11 @@ SPan(CKTcircuit *ckt, int restart)
double* rhswoPorts = NULL; double* rhswoPorts = NULL;
double* irhswoPorts = 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), /* variable must be static, for continuation of interrupted (Ctrl-C),
longer lasting noise anlysis */ longer lasting noise anlysis */
static Ndata* data = NULL; static Ndata* data = NULL;
@ -436,7 +427,7 @@ SPan(CKTcircuit *ckt, int restart)
if (job->SPdoNoise) if (job->SPdoNoise)
{ {
data->lstFreq = job->SPstartFreq - 1; data->lstFreq = job->SPstartFreq - 1;
data->delFreq = 1.0; data->delFreq = 0.0;
} }
#ifdef XSPICE #ifdef XSPICE
@ -606,7 +597,8 @@ SPan(CKTcircuit *ckt, int restart)
} }
freq = job->SPstartFreq; freq = job->SPstartFreq;
} else { /* continue previous analysis */ }
else { /* continue previous analysis */
freq = job->SPsaveFreq; freq = job->SPsaveFreq;
job->SPsaveFreq = 0; /* clear the 'old' frequency */ job->SPsaveFreq = 0; /* clear the 'old' frequency */
/* fix resume? saj, indeed !*/ /* fix resume? saj, indeed !*/
@ -651,13 +643,22 @@ SPan(CKTcircuit *ckt, int restart)
return (E_NOMEM); return (E_NOMEM);
// Create Noise UID, if needed // Create Noise UID, if needed
if (job->SPdoNoise) if (job->SPdoNoise)
{ {
internalNoiseAN = SPcreateNoiseAnalysys(ckt);
if (internalNoiseAN == NULL)
return (E_NOMEM);
data->numPlots = 0; /* we don't have any plots yet */ data->numPlots = 0; /* we don't have any plots yet */
error = CKTspnoise(ckt, N_DENS, N_OPEN, data); data->freq = freq;
if (error) return(error);
error = CKTspnoise(ckt, N_DENS, N_OPEN, data, internalNoiseAN);
if (error) {
tfree(internalNoiseAN);
return(error);
}
} }
ckt->CKTactivePort = 0; ckt->CKTactivePort = 0;
@ -836,7 +837,7 @@ SPan(CKTcircuit *ckt, int restart)
if (job->SPdoNoise) if (job->SPdoNoise)
{ {
data->delFreq = freq - data->lstFreq;
data->freq = freq; data->freq = freq;
@ -866,9 +867,10 @@ SPan(CKTcircuit *ckt, int restart)
noise sourches noise sourches
*/ */
error = CKTspnoise(ckt, N_DENS, N_CALC, data); error = CKTspnoise(ckt, N_DENS, N_CALC, data, internalNoiseAN);
if (error) if (error)
{ {
tfree(internalNoiseAN);
tfree(data); tfree(data);
tfree(rhswoPorts); tfree(rhswoPorts);
tfree(irhswoPorts); tfree(irhswoPorts);
@ -896,6 +898,7 @@ SPan(CKTcircuit *ckt, int restart)
#endif #endif
if (error) { if (error) {
UPDATE_STATS(DOING_AC); UPDATE_STATS(DOING_AC);
tfree(internalNoiseAN);
tfree(rhswoPorts); tfree(rhswoPorts);
tfree(irhswoPorts); tfree(irhswoPorts);
tfree(data); tfree(data);
@ -940,6 +943,7 @@ SPan(CKTcircuit *ckt, int restart)
if (job->SPfreqDelta == 0) goto endsweep; if (job->SPfreqDelta == 0) goto endsweep;
break; break;
default: default:
tfree(internalNoiseAN);
tfree(rhswoPorts); tfree(rhswoPorts);
tfree(irhswoPorts); tfree(irhswoPorts);
tfree(data); tfree(data);
@ -952,6 +956,7 @@ endsweep:
SPfrontEnd->OUTendPlot(spPlot); SPfrontEnd->OUTendPlot(spPlot);
spPlot = NULL; spPlot = NULL;
UPDATE_STATS(0); UPDATE_STATS(0);
tfree(internalNoiseAN);
tfree(rhswoPorts); tfree(rhswoPorts);
tfree(irhswoPorts); tfree(irhswoPorts);
deleteSPmatrix(ckt); deleteSPmatrix(ckt);