noisean, deliver results in V/sqrt(Hz) and A/sqrt(Hz)

This commit is contained in:
rlar 2015-03-22 21:44:50 +01:00
parent e755b45281
commit 8d6726f0f4
6 changed files with 62 additions and 18 deletions

View File

@ -72,6 +72,11 @@ extern void sh_vecinit(runDesc *run);
extern bool orflag;
#endif
// fixme
// ugly hack to work around missing api to specify the "type" of signals
int fixme_onoise_type = SV_NOTYPE;
int fixme_inoise_type = SV_NOTYPE;
#define DOUBLE_PRECISION 15
@ -137,6 +142,12 @@ beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analNam
/*to resume a run saj
*All it does is reassign the file pointer and return (requires *runp to be NULL if this is not needed)
*/
if (strcmp("NOISE", spice_analysis_get_name(analysisPtr->JOBtype))) {
fixme_onoise_type = SV_NOTYPE;
fixme_inoise_type = SV_NOTYPE;
}
if (dataType == 666 && numNames == 666) {
run = *runp;
run->writeOut = ft_getOutReq(&run->fp, &run->runPlot, &run->binary,
@ -850,14 +861,10 @@ guess_type(char *name)
type = SV_TIME;
else if (cieq(name, "frequency"))
type = SV_FREQUENCY;
else if (cieq(name, "onoise_spectrum"))
type = SV_OUTPUT_N_DENS;
else if (cieq(name, "onoise_integrated"))
type = SV_OUTPUT_NOISE;
else if (cieq(name, "inoise_spectrum"))
type = SV_INPUT_N_DENS;
else if (cieq(name, "inoise_integrated"))
type = SV_INPUT_NOISE;
else if (ciprefix("inoise", name))
type = fixme_inoise_type;
else if (ciprefix("onoise", name))
type = fixme_onoise_type;
else if (cieq(name, "temp-sweep"))
type = SV_TEMP;
else if (cieq(name, "res-sweep"))

View File

@ -37,10 +37,8 @@ static struct type types[NUMTYPES] = {
{ "frequency", "Hz" } ,
{ "voltage", "V" } ,
{ "current", "A" } ,
{ "onoise-spectrum", "(V or A)^2/Hz" } ,
{ "onoise-integrated", "V or A" } ,
{ "inoise-spectrum", "(V or A)^2/Hz" } ,
{ "inoise-integrated", "V or A" } ,
{ "voltage-density", "V/sqrt(Hz)" } ,
{ "current-density", "A/sqrt(Hz)" } ,
{ "pole", NULL } ,
{ "zero", NULL } ,
{ "s-param", NULL } ,

View File

@ -49,6 +49,7 @@ typedef struct {
/* a do loop. */
unsigned int prtSummary;
double *outpVector; /* pointer to our array of noise outputs */
char *squared_value;
runDesc *NplotPtr; /* the plot pointer */
IFuid *namelist; /* list of plot names */
} Ndata;

View File

@ -7,10 +7,8 @@ enum simulation_types {
SV_FREQUENCY,
SV_VOLTAGE,
SV_CURRENT,
SV_OUTPUT_N_DENS,
SV_OUTPUT_NOISE,
SV_INPUT_N_DENS,
SV_INPUT_NOISE,
SV_VOLTAGE_DENSITY,
SV_CURRENT_DENSITY,
SV_POLE,
SV_ZERO,
SV_SPARAM,

View File

@ -67,6 +67,8 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
data->outpVector =
TMALLOC(double, data->numPlots);
data->squared_value =
TMALLOC(char, data->numPlots);
break;
case INT_NOIZ:
@ -82,6 +84,8 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
data->outpVector =
TMALLOC(double, data->numPlots);
data->squared_value =
TMALLOC(char, data->numPlots);
break;
default:
@ -103,6 +107,9 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
(outNdens * data->GainSqInv);
refVal.rValue = data->freq; /* the reference is the freq */
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);
@ -112,6 +119,9 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
case INT_NOIZ:
data->outpVector[data->outNumber++] = data->outNoiz;
data->outpVector[data->outNumber++] = data->inNoise;
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);
@ -126,6 +136,7 @@ CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
SPfrontEnd->OUTendPlot (data->NplotPtr);
FREE(data->namelist);
FREE(data->outpVector);
FREE(data->squared_value);
break;
default:

View File

@ -16,9 +16,15 @@ Modified: 2001 AlansFixes
#include "ngspice/iferrmsg.h"
#include "ngspice/noisedef.h"
#include "ngspice/sperror.h"
#include "ngspice/sim.h"
#include "vsrc/vsrcdefs.h"
#include "isrc/isrcdefs.h"
// fixme
// ugly hack to work around missing api to specify the "type" of signals
extern int fixme_onoise_type;
extern int fixme_inoise_type;
int
NOISEan (CKTcircuit *ckt, int restart)
@ -35,6 +41,7 @@ NOISEan (CKTcircuit *ckt, int restart)
int step;
IFuid freqUid;
double freqTol; /* tolerence parameter for finding final frequency; hack */
int i, src_type;
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;
GENinstance *inst = CKTfndDev(ckt, job->input);
@ -55,8 +62,10 @@ NOISEan (CKTcircuit *ckt, int restart)
if (inst->GENmodPtr->GENmodType == CKTtypelook("Vsource")) {
ac_given = ((VSRCinstance *)inst) -> VSRCacGiven;
src_type = SV_VOLTAGE;
} else if(inst->GENmodPtr->GENmodType == CKTtypelook("Isource")) {
ac_given = ((ISRCinstance *)inst) -> ISRCacGiven;
src_type = SV_CURRENT;
} else {
SPfrontEnd->IFerrorf (ERR_WARNING,
"Noise input source %s is not of proper type",
@ -128,8 +137,20 @@ NOISEan (CKTcircuit *ckt, int restart)
* plot
*/
if (src_type == SV_VOLTAGE)
fixme_inoise_type = SV_VOLTAGE_DENSITY;
else
fixme_inoise_type = SV_CURRENT_DENSITY;
fixme_onoise_type = SV_VOLTAGE_DENSITY;
for (i = 0; i < data->numPlots; i++)
data->squared_value[i] =
ciprefix("inoise", data->namelist[i]) ||
ciprefix("onoise", data->namelist[i]);
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
"Noise Spectral Density Curves - (V^2 or A^2)/Hz",
"Noise Spectral Density Curves",
freqUid, IF_REAL,
data->numPlots, data->namelist, IF_REAL,
&(data->NplotPtr));
@ -275,8 +296,16 @@ NOISEan (CKTcircuit *ckt, int restart)
if (error) return(error);
fixme_inoise_type = src_type;
fixme_onoise_type = SV_VOLTAGE;
for (i = 0; i < data->numPlots; i++)
data->squared_value[i] =
ciprefix("inoise", data->namelist[i]) ||
ciprefix("onoise", data->namelist[i]);
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
"Integrated Noise - V^2 or A^2",
"Integrated Noise",
NULL, 0,
data->numPlots, data->namelist, IF_REAL,
&(data->NplotPtr));