Patch to avoid false reads and writes due to inconsitent
structs SPAN and NOISEAN. Prevent using non-initialized variables.
This commit is contained in:
parent
8a6231a813
commit
321d53a4e9
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue