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 e31d6a3c1c
commit 744eaece69
2 changed files with 183 additions and 160 deletions

View File

@ -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:

View File

@ -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);