Jspice3
noian.c File Reference
#include "spice.h"
#include <stdio.h>
#include <math.h>
#include "srcdefs.h"
#include "fteconst.h"
#include "iferrmsg.h"
#include "sperror.h"
#include "util.h"
#include "outdata.h"
#include "noisedef.h"
#include "cktext.h"
#include "niext.h"
Include dependency graph for noian.c:

Go to the source code of this file.

Macros

#define ANAL_EXT
 

Functions

static int noi_operation ()
 
static int noi_dcoperation ()
 
int NOISEan (GENERIC *cktp, int restart)
 
static int noi_dcoperation (CKTcircuit *ckt, struct sOUTdata *outd, int restart)
 
static int noi_operation (CKTcircuit *ckt, struct sOUTdata *outd, int restart)
 
int CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
 

Macro Definition Documentation

#define ANAL_EXT

Definition at line 8 of file noian.c.

Function Documentation

int CKTnoise ( CKTcircuit ckt,
int  mode,
int  operation,
Ndata data 
)

Definition at line 326 of file noian.c.

332 {
333  double outNdens;
334  extern SPICEdev *DEVices[];
335  IFvalue outData; /* output variable (points to list of outputs) */
336  IFvalue refVal; /* reference variable (always 0) */
337  int error;
338  struct sCKTmodHead *mh;
339  int (*func)();
340 
341  outNdens = 0.0;
342 
343  /* let each device decide how many and what type of noise sources
344  * it has
345  */
346  for (mh = ckt->CKTheadList; mh != NULL; mh = mh->next) {
347  if ((func = DEVices[mh->type]->DEVnoise) != NULL) {
348  error = (*func)(mode,operation,mh->head,ckt,data,&outNdens);
349  if (error)
350  return (error);
351  }
352  }
353 
354  if (operation == N_OPEN) {
355 
356  /* take care of the noise for the circuit as a whole */
357 
358  if (mode == N_DENS) {
359 
360  data->namelist = (IFuid *)trealloc((char *)data->namelist,
361  (data->numPlots + 1)*sizeof(IFuid));
362 
363  (*(SPfrontEnd->IFnewUid))(ckt,&(data->namelist[data->numPlots++]),
364  (IFuid)NULL,"onoise_spectrum",UID_OTHER,(GENERIC **)NULL);
365 
366  data->namelist = (IFuid *)trealloc((char *)data->namelist,
367  (data->numPlots + 1)*sizeof(IFuid));
368 
369  (*(SPfrontEnd->IFnewUid))(ckt,&(data->namelist[data->numPlots++]),
370  (IFuid)NULL,"inoise_spectrum",UID_OTHER,(GENERIC **)NULL);
371 
372  /* we've added two more plots */
373 
374  data->outpVector =
375  (double *)MALLOC(data->numPlots * sizeof(double));
376 
377  return (OK);
378  }
379 
380  if (mode == INT_NOIZ) {
381 
382  data->namelist = (IFuid *)trealloc((char *)data->namelist,
383  (data->numPlots + 1)*sizeof(IFuid));
384 
385  (*(SPfrontEnd->IFnewUid))(ckt,&(data->namelist[data->numPlots++]),
386  (IFuid)NULL,"onoise_total",UID_OTHER,(GENERIC **)NULL);
387 
388  data->namelist = (IFuid *)trealloc((char *)data->namelist,
389  (data->numPlots + 1)*sizeof(IFuid));
390 
391  (*(SPfrontEnd->IFnewUid))(ckt,&(data->namelist[data->numPlots++]),
392  (IFuid)NULL,"inoise_total",UID_OTHER,(GENERIC **)NULL);
393 
394  /* we've added two more plots */
395 
396  data->outpVector =
397  (double *) MALLOC(data->numPlots * sizeof(double));
398 
399  return (OK);
400  }
401 
402  return (E_INTERN);
403  }
404 
405  if (operation == N_CALC) {
406 
407  if (mode == N_DENS) {
408 
409  if ((((NOISEAN*)ckt->CKTcurJob)->NStpsSm == 0)
410  || data->prtSummary) {
411  data->outpVector[data->outNumber++] = outNdens;
412  data->outpVector[data->outNumber++] =
413  (outNdens * data->GainSqInv);
414 
415  refVal.rValue = data->freq; /* the reference is the freq */
416  outData.v.numValue = data->outNumber; /* vector number */
417  outData.v.vec.rVec = data->outpVector; /* vector of outputs */
418  (*(SPfrontEnd->OUTdata))(data->NplotPtr,&refVal,&outData);
419  }
420  return (OK);
421  }
422 
423  if (mode == INT_NOIZ) {
424 
425  data->outpVector[data->outNumber++] = data->outNoiz;
426  data->outpVector[data->outNumber++] = data->inNoise;
427  outData.v.vec.rVec = data->outpVector; /* vector of outputs */
428  outData.v.numValue = data->outNumber; /* vector number */
429  (*(SPfrontEnd->OUTdata))(data->NplotPtr,&refVal,&outData);
430  return (OK);
431  }
432 
433  return (E_INTERN);
434  }
435 
436  if (operation == N_CLOSE) {
437 
438  (*(SPfrontEnd->OUTendPlot))(data->NplotPtr);
439  FREE(data->namelist);
440  FREE(data->outpVector);
441  return (OK);
442  }
443 
444  return (E_INTERN);
445 }
#define E_INTERN
Definition: sperror.h:15
int numValue
Definition: ifsim.h:240
#define N_OPEN
Definition: noisedef.h:85
struct sCKTmodHead * next
Definition: cktdefs.h:58
int IFnewUid()
union uIFvalue::@13::@14 vec
if(TDesc==NULL)
Definition: cd.c:1326
SPICEdev * DEVices[]
Definition: sconfig.c:109
#define N_CLOSE
Definition: noisedef.h:87
IFfrontEnd * SPfrontEnd
Definition: main.c:917
#define FREE(ptr)
Definition: spdefs.h:436
double rValue
Definition: ifsim.h:233
#define OK
Definition: iferrmsg.h:17
GENERIC * IFuid
Definition: ifsim.h:72
struct sCKTmodHead * CKTheadList
Definition: cktdefs.h:63
#define MALLOC(x)
Definition: util.h:9
#define NULL
Definition: spdefs.h:121
#define INT_NOIZ
Definition: noisedef.h:84
#define N_DENS
Definition: noisedef.h:83
int(* DEVnoise)()
Definition: devdefs.h:109
Definition: fteparse.h:37
int type
Definition: cktdefs.h:56
return(True)
#define UID_OTHER
Definition: ifsim.h:85
GENmodel * head
Definition: cktdefs.h:57
struct uIFvalue::@13 v
#define N_CALC
Definition: noisedef.h:86
char * trealloc()
char GENERIC
Definition: ifsim.h:27
static int noi_dcoperation ( )
static
static int noi_dcoperation ( CKTcircuit ckt,
struct sOUTdata outd,
int  restart 
)
static

Definition at line 209 of file noian.c.

214 {
215  NOISEAN *job = (NOISEAN*) ckt->CKTcurJob;
216  Ndata *data = job->NdataPtr;
217  int error;
218 
219  if (restart) {
220  data->freq = job->AC.fstart;
221  data->lstFreq = data->freq;
222  data->outNoiz = 0.0;
223  data->inNoise = 0.0;
224  job->Nstep = 0;
225  }
226  else {
227  /* we must have paused before. pick up where we left off */
228  data->outNoiz = job->NsavOnoise;
229  data->inNoise = job->NsavInoise;
230  }
231 
232  error = CKTic(ckt);
233  if (error)
234  return (error);
235 
236  error = CKTop(ckt,
239  ckt->CKTdcMaxIter);
240 
241  if (error)
242  return (error);
243 
244  error = ACloop(noi_operation,ckt,restart,&job->AC,outd);
245  if (error == E_PAUSE) {
246  job->NsavOnoise = data->outNoiz; /* up until now */
247  job->NsavInoise = data->inNoise;
248  return (error);
249  }
250  return (OK);
251 }
#define E_PAUSE
Definition: iferrmsg.h:15
if(TDesc==NULL)
Definition: cd.c:1326
#define MODEINITFLOAT
Definition: cktdefs.h:156
int ACloop(int(*func)(), CKTcircuit *ckt, int restart, struct sACprms *ac, struct sOUTdata *outd)
Definition: acan.c:177
static int noi_operation()
#define OK
Definition: iferrmsg.h:17
int Nstep
Definition: noisedef.h:54
int CKTic()
struct sACprms AC
Definition: noisedef.h:55
int CKTop()
double NsavOnoise
Definition: noisedef.h:48
double fstart
Definition: analysis.h:60
#define MODEDCOP
Definition: cktdefs.h:150
double NsavInoise
Definition: noisedef.h:49
JOB * CKTcurJob
Definition: cktdefs.h:216
#define MODEINITJCT
Definition: cktdefs.h:157
int CKTdcMaxIter
Definition: cktdefs.h:171
Ndata * NdataPtr
Definition: noisedef.h:51
Definition: noisedef.h:18
static int noi_operation ( )
static
static int noi_operation ( CKTcircuit ckt,
struct sOUTdata outd,
int  restart 
)
static

Definition at line 255 of file noian.c.

260 {
261  NOISEAN *job = (NOISEAN*) ckt->CKTcurJob;
262  Ndata *data = job->NdataPtr;
263  double realVal, imagVal;
264  int error;
265 
266  data->freq = ckt->CKTomega/(2*M_PI);
267  realVal = *((ckt->CKTrhsOld) + job->NposOutNode) -
268  *((ckt->CKTrhsOld) + job->NnegOutNode);
269  imagVal = *((ckt->CKTirhsOld) + job->NposOutNode) -
270  *((ckt->CKTirhsOld) + job->NnegOutNode);
271  data->GainSqInv = 1.0 / MAX(((realVal*realVal)
272  + (imagVal*imagVal)),N_MINGAIN);
273  data->lnGainInv = log(data->GainSqInv);
274 
275  /* set up a block of "common" data so we don't have to
276  * recalculate it for every device
277  */
278 
279  data->delFreq = data->freq - data->lstFreq;
280  data->lnFreq = log(MAX(data->freq,N_MINLOG));
281  data->lnLastFreq = log(MAX(data->lstFreq,N_MINLOG));
282  data->delLnFreq = data->lnFreq - data->lnLastFreq;
283 
284  if ((job->NStpsSm != 0) && ((job->Nstep % (job->NStpsSm)) == 0)) {
285  data->prtSummary = TRUE;
286  }
287  else {
288  data->prtSummary = FALSE;
289  }
290 
291  data->outNumber = 0;
292  /* the frequency will NOT be stored in array[0] as before; instead,
293  * it will be given in refVal.rValue (see later)
294  */
295 
296  /* solve the adjoint system */
297  NInzIter(ckt,job->NposOutNode,job->NnegOutNode);
298 
299  /* now we use the adjoint system to calculate the noise
300  * contributions of each generator in the circuit
301  */
302 
303  error = CKTnoise(ckt,N_DENS,N_CALC,data);
304  if (error)
305  return (error);
306  outd->count++;
307 
308  data->lstFreq = data->freq;
309  job->Nstep++;
310 
311  return (OK);
312 }
#define FALSE
Definition: mfb.h:23
#define N_MINGAIN
Definition: noisedef.h:99
#define MAX(a, b)
Definition: spdefs.h:135
void NInzIter()
int NnegOutNode
Definition: noisedef.h:53
#define M_PI
Definition: spice.h:132
#define TRUE
Definition: util.h:27
#define N_MINLOG
Definition: noisedef.h:95
#define OK
Definition: iferrmsg.h:17
double * CKTrhsOld
Definition: cktdefs.h:98
int Nstep
Definition: noisedef.h:54
#define N_DENS
Definition: noisedef.h:83
double CKTomega
Definition: cktdefs.h:198
int CKTnoise(CKTcircuit *ckt, int mode, int operation, Ndata *data)
Definition: noian.c:326
double * CKTirhsOld
Definition: cktdefs.h:101
int count
Definition: outdata.h:23
int NposOutNode
Definition: noisedef.h:52
int NStpsSm
Definition: noisedef.h:50
double freq
Definition: noisedef.h:19
#define N_CALC
Definition: noisedef.h:86
JOB * CKTcurJob
Definition: cktdefs.h:216
Ndata * NdataPtr
Definition: noisedef.h:51
Definition: noisedef.h:18
int NOISEan ( GENERIC cktp,
int  restart 
)

Definition at line 33 of file noian.c.

37 {
38  CKTcircuit *ckt = (CKTcircuit *)cktp;
39  Ndata *data;
40  struct sOUTdata outd;
41  int error, error1;
42  int i, code;
43  CKTnode *node;
44  NOISEAN *job = (NOISEAN*) (ckt->CKTcurJob);
45  static char *nodundef = "noise output node %s is not defined";
46  static char *noacinput = "no AC input source %s for noise analysis";
47  SRCinstance *here;
48 
49  if (ckt->CKTjjPresent) {
50  (*(SPfrontEnd->IFerror))(ERR_FATAL,
51  "Noise analysis not possible with Josephson junctions", NULL);
52  return (OK);
53  }
54  /* make sure all the nodes/sources referenced are actually
55  * in the circuit
56  */
57  if (restart) {
58  job->NposOutNode = -1;
59  if (job->Noutput) {
60  for (node = ckt->CKTnodes; node; node = node->next) {
61  if (strcmp(node->name, job->Noutput) == 0) {
62  job->NposOutNode = node->number;
63  break;
64  }
65  }
66  }
67  if (job->NposOutNode == -1) {
68  (*(SPfrontEnd->IFerror))(ERR_FATAL,nodundef,
69  (IFuid)&(job->Noutput));
70  return (E_NODUNDEF);
71  }
72  if (job->NoutputRef) { /* was an output reference specified? */
73  job->NnegOutNode = -1;
74  for (node = ckt->CKTnodes; node; node = node->next) {
75  if (strcmp(node->name, job->NoutputRef) == 0) {
76  job->NnegOutNode = node->number;
77  break;
78  }
79  }
80  if (job->NnegOutNode == -1) {
81  (*(SPfrontEnd->IFerror))(ERR_FATAL,nodundef,
82  (IFuid)&(job->NoutputRef));
83  return (E_NODUNDEF);
84  }
85  }
86  else {
87  job->NnegOutNode = 0;
88  /* if no output reference node was specified, we assume ground */
89  }
90 
91  /* see if the source specified is AC */
92 
93  code = CKTtypelook("Source");
94  here = (SRCinstance *)NULL;
95  error = CKTfndDev((GENERIC*)ckt,&code,(GENERIC**)&here,
96  job->Ninput, (GENERIC *)NULL,(IFuid)NULL);
97 
98  if (error) {
99  (*(SPfrontEnd->IFerror))(ERR_FATAL,noacinput,
100  (IFuid)&(job->Ninput));
101  return (E_NOACINPUT);
102  }
103 
104  if (job->DC.eltName[0] != NULL) {
105  /* DC source was given */
106 
107  for (i = 0; i <= job->DC.nestLevel; i++) {
108 
109  here = (SRCinstance *)NULL;
110  error = CKTfndDev((GENERIC*)ckt,&code,(GENERIC**)&here,
111  job->DC.eltName[i], (GENERIC *)NULL,(IFuid)NULL);
112 
113  if (error) {
114  (*(SPfrontEnd->IFerror))(ERR_FATAL,
115  "DCtrCurv: source %s not in circuit",
116  &(job->DC.eltName[i]));
117  return (E_NOTFOUND);
118  }
119  job->DC.elt[i] = (GENinstance*)here;
120  job->DC.vsave[i] = here->SRCdcValue;
121  }
122  }
123 
124  data = (Ndata*)MALLOC(sizeof(Ndata));
125  job->NdataPtr = data;
126 
127  /* the current front-end needs the namelist to be fully
128  * declared before an OUTbeginplot
129  */
130 
131  (*(SPfrontEnd->IFnewUid))((GENERIC *)ckt,&outd.refName,(IFuid)NULL,
132  "frequency", UID_OTHER,(GENERIC **)NULL);
133 
134  data->numPlots = 0; /* we don't have any plots yet */
135  error = CKTnoise(ckt,N_DENS,N_OPEN,data);
136  if (error)
137  return(error);
138 
139  /*
140  * all names in the namelist have been declared. now start the
141  * plot
142  */
143 
144  outd.circuitPtr = (GENERIC *)ckt;
145  outd.analysisPtr = (GENERIC*)ckt->CKTcurJob;
146  outd.analName = "Noise Spectral Density Curves - (V^2 or A^2)/Hz";
147  outd.refType = IF_REAL;
148  outd.numNames = data->numPlots;
149  outd.dataNames = data->namelist;
150  outd.dataType = IF_REAL;
151  outd.plotPtr = &(data->NplotPtr);
152  outd.numPts = 1;
153  outd.initValue = 0;
154  outd.finalValue = 0;
155  outd.step = 0;
156  outd.count = 0;
157  (*(SPfrontEnd->OUTbeginPlot))((GENERIC*)&outd);
158 
159  }
160 
161  /* do the noise analysis over all frequencies */
162  error = DCTloop(noi_dcoperation,ckt,restart,&job->DC,&outd);
163  if (error == E_PAUSE)
164  return (error);
165  error1 = CKTnoise(ckt,N_DENS,N_CLOSE,data);
166  if (error)
167  return (error);
168  if (error1)
169  return (error1);
170 
171  data->numPlots = 0;
172  data->outNumber = 0;
173 
174  if (job->AC.fstart != job->AC.fstop) {
175  error = CKTnoise(ckt,INT_NOIZ,N_OPEN,data);
176  if (error)
177  return(error);
178 
179  outd.circuitPtr = (GENERIC *)ckt;
180  outd.analysisPtr = (GENERIC*)ckt->CKTcurJob;
181  outd.analName = "Integrated Noise - V^2 or A^2";
182  outd.refName = (IFuid)NULL;
183  outd.refType = (int)0;
184  outd.numNames = data->numPlots;
185  outd.dataNames = data->namelist;
186  outd.dataType = IF_REAL;
187  outd.plotPtr = &(data->NplotPtr);
188  outd.numPts = 1;
189  outd.initValue = 0;
190  outd.finalValue = 0;
191  outd.step = 0;
192  outd.count = 0;
193  (*(SPfrontEnd->OUTbeginPlot))((GENERIC*)&outd);
194 
195  error = CKTnoise(ckt,INT_NOIZ,N_CALC,data);
196  if (error)
197  return(error);
198 
199  error = CKTnoise(ckt,INT_NOIZ,N_CLOSE,data);
200  if (error)
201  return(error);
202  }
203 
204  FREE (data);
205  return (OK);
206 }
#define E_PAUSE
Definition: iferrmsg.h:15
#define N_OPEN
Definition: noisedef.h:85
IFuid name
Definition: cktdefs.h:31
char * Ninput
Definition: noisedef.h:47
int NnegOutNode
Definition: noisedef.h:53
#define ERR_FATAL
Definition: ifsim.h:518
IFuid * namelist
Definition: noisedef.h:35
#define N_CLOSE
Definition: noisedef.h:87
#define E_NOTFOUND
Definition: iferrmsg.h:35
int DCTloop(int(*func)(), CKTcircuit *ckt, int restart, struct sDCTprms *dc, struct sOUTdata *outd)
Definition: dctan.c:177
IFfrontEnd * SPfrontEnd
Definition: main.c:917
double SRCdcValue
Definition: srcdefs.h:77
int CKTtypelook()
#define FREE(ptr)
Definition: spdefs.h:436
IFuid eltName[DCTNESTLEVEL]
Definition: analysis.h:34
#define OK
Definition: iferrmsg.h:17
GENERIC * IFuid
Definition: ifsim.h:72
#define MALLOC(x)
Definition: util.h:9
GENERIC * NplotPtr
Definition: noisedef.h:34
char * NoutputRef
Definition: noisedef.h:46
#define NULL
Definition: spdefs.h:121
#define INT_NOIZ
Definition: noisedef.h:84
#define N_DENS
Definition: noisedef.h:83
struct sCKTnode * next
Definition: cktdefs.h:43
int number
Definition: cktdefs.h:39
CKTnode * CKTnodes
Definition: cktdefs.h:135
int CKTjjPresent
Definition: cktdefs.h:168
#define E_NOACINPUT
Definition: sperror.h:29
double vsave[DCTNESTLEVEL]
Definition: analysis.h:30
int CKTnoise(CKTcircuit *ckt, int mode, int operation, Ndata *data)
Definition: noian.c:326
#define IF_REAL
Definition: ifsim.h:108
struct sACprms AC
Definition: noisedef.h:55
double fstop
Definition: analysis.h:61
int outNumber
Definition: noisedef.h:29
int NposOutNode
Definition: noisedef.h:52
#define UID_OTHER
Definition: ifsim.h:85
int numPlots
Definition: noisedef.h:30
int CKTfndDev()
#define E_NODUNDEF
Definition: sperror.h:28
struct sDCTprms DC
Definition: noisedef.h:56
double fstart
Definition: analysis.h:60
#define N_CALC
Definition: noisedef.h:86
JOB * CKTcurJob
Definition: cktdefs.h:216
static int noi_dcoperation()
char * Noutput
Definition: noisedef.h:45
Ndata * NdataPtr
Definition: noisedef.h:51
int nestLevel
Definition: analysis.h:35
GENinstance * elt[DCTNESTLEVEL]
Definition: analysis.h:33
char GENERIC
Definition: ifsim.h:27
Definition: noisedef.h:18