You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.5 KiB
133 lines
3.5 KiB
/**********
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
Author: 1987 Gary W. Ng
|
|
**********/
|
|
|
|
/*
|
|
* CKTnoise (ckt, mode, operation, data)
|
|
*
|
|
* This routine is responsible for naming and evaluating all of the
|
|
* noise sources in the circuit. It uses a series of subroutines to
|
|
* name and evaluate the sources associated with each model, and then
|
|
* it evaluates the noise for the entire circuit.
|
|
*/
|
|
|
|
#include "ngspice.h"
|
|
#include "cktdefs.h"
|
|
#include "devdefs.h"
|
|
#include "iferrmsg.h"
|
|
#include "noisedef.h"
|
|
#include "sperror.h"
|
|
|
|
|
|
int
|
|
CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
|
|
{
|
|
double outNdens;
|
|
int i;
|
|
IFvalue outData; /* output variable (points to list of outputs)*/
|
|
IFvalue refVal; /* reference variable (always 0)*/
|
|
int error;
|
|
|
|
outNdens = 0.0;
|
|
|
|
/* let each device decide how many and what type of noise sources it has */
|
|
|
|
for (i=0; i < DEVmaxnum; i++) {
|
|
if ( DEVices[i] && DEVices[i]->DEVnoise && ckt->CKThead[i] ) {
|
|
error = DEVices[i]->DEVnoise (mode, operation, ckt->CKThead[i],
|
|
ckt,data, &outNdens);
|
|
if (error) return (error);
|
|
}
|
|
}
|
|
|
|
switch (operation) {
|
|
|
|
case N_OPEN:
|
|
|
|
/* take care of the noise for the circuit as a whole */
|
|
|
|
switch (mode) {
|
|
|
|
case N_DENS:
|
|
|
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
|
|
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
|
(IFuid)NULL, "onoise_spectrum", UID_OTHER, NULL);
|
|
|
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
|
|
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
|
(IFuid)NULL, "inoise_spectrum", UID_OTHER, NULL);
|
|
|
|
/* we've added two more plots */
|
|
|
|
data->outpVector =
|
|
TMALLOC(double, data->numPlots);
|
|
break;
|
|
|
|
case INT_NOIZ:
|
|
|
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
|
(IFuid)NULL, "onoise_total", UID_OTHER, NULL);
|
|
|
|
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
|
|
SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
|
|
(IFuid)NULL, "inoise_total", UID_OTHER, NULL);
|
|
/* we've added two more plots */
|
|
|
|
data->outpVector =
|
|
TMALLOC(double, data->numPlots);
|
|
break;
|
|
|
|
default:
|
|
return (E_INTERN);
|
|
}
|
|
|
|
break;
|
|
|
|
case N_CALC:
|
|
|
|
switch (mode) {
|
|
|
|
case N_DENS:
|
|
if ((((NOISEAN*)ckt->CKTcurJob)->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 */
|
|
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;
|
|
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);
|
|
}
|
|
break;
|
|
|
|
case N_CLOSE:
|
|
SPfrontEnd->OUTendPlot (data->NplotPtr);
|
|
FREE(data->namelist);
|
|
FREE(data->outpVector);
|
|
break;
|
|
|
|
default:
|
|
return (E_INTERN);
|
|
}
|
|
return (OK);
|
|
}
|