From 8d6726f0f4b46dbafeb61a9676cb73c92e563074 Mon Sep 17 00:00:00 2001 From: rlar Date: Sun, 22 Mar 2015 21:44:50 +0100 Subject: [PATCH] noisean, deliver results in V/sqrt(Hz) and A/sqrt(Hz) --- src/frontend/outitf.c | 23 ++++++++++++++-------- src/frontend/typesdef.c | 6 ++---- src/include/ngspice/noisedef.h | 1 + src/include/ngspice/sim.h | 6 ++---- src/spicelib/analysis/cktnoise.c | 11 +++++++++++ src/spicelib/analysis/noisean.c | 33 ++++++++++++++++++++++++++++++-- 6 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/frontend/outitf.c b/src/frontend/outitf.c index 52116e034..eb13a93c9 100644 --- a/src/frontend/outitf.c +++ b/src/frontend/outitf.c @@ -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")) diff --git a/src/frontend/typesdef.c b/src/frontend/typesdef.c index dea2acdd8..401556d5a 100644 --- a/src/frontend/typesdef.c +++ b/src/frontend/typesdef.c @@ -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 } , diff --git a/src/include/ngspice/noisedef.h b/src/include/ngspice/noisedef.h index effde5bfa..61ffbbbe9 100644 --- a/src/include/ngspice/noisedef.h +++ b/src/include/ngspice/noisedef.h @@ -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; diff --git a/src/include/ngspice/sim.h b/src/include/ngspice/sim.h index 38a3ba3c6..3f65f76d0 100644 --- a/src/include/ngspice/sim.h +++ b/src/include/ngspice/sim.h @@ -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, diff --git a/src/spicelib/analysis/cktnoise.c b/src/spicelib/analysis/cktnoise.c index d088c8bb5..ff161af34 100644 --- a/src/spicelib/analysis/cktnoise.c +++ b/src/spicelib/analysis/cktnoise.c @@ -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: diff --git a/src/spicelib/analysis/noisean.c b/src/spicelib/analysis/noisean.c index 340184b02..2be3f2467 100644 --- a/src/spicelib/analysis/noisean.c +++ b/src/spicelib/analysis/noisean.c @@ -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));