Browse Source

Add noise capability to XSPICE code models

Coded according to acan., AC analysis

MIF_NOI is not yet supported by any code model, so
MIF_AC is used (code models behave like in ac mode,
they are noiseless.
pre-master-46
Holger Vogt 3 years ago
parent
commit
d53acbed8e
  1. 3
      src/include/ngspice/ipc.h
  2. 1
      src/include/ngspice/miftypes.h
  3. 124
      src/spicelib/analysis/noisean.c

3
src/include/ngspice/ipc.h

@ -113,8 +113,9 @@ typedef enum {
IPC_ANAL_AC,
IPC_ANAL_TRAN,
#ifdef RFSPICE
IPC_ANAL_SP
IPC_ANAL_SP,
#endif
IPC_ANAL_NOI
} Ipc_Anal_t;

1
src/include/ngspice/miftypes.h

@ -87,6 +87,7 @@ typedef enum {
MIF_DC, /* A DC or DCOP analysis */
MIF_AC, /* A swept AC analysis */
MIF_TRAN, /* A transient analysis */
MIF_NOI, /* A noise analysis */
} Mif_Analysis_t;

124
src/spicelib/analysis/noisean.c

@ -21,6 +21,16 @@ Modified: 2001 AlansFixes
#include "vsrc/vsrcdefs.h"
#include "isrc/isrcdefs.h"
#ifdef XSPICE
#include "ngspice/evt.h"
#include "ngspice/enh.h"
/* gtri - add - wbk - 12/19/90 - Add headers */
#include "ngspice/mif.h"
#include "ngspice/evtproto.h"
#include "ngspice/ipctiein.h"
/* gtri - end - wbk */
#endif
// fixme
// ugly hack to work around missing api to specify the "type" of signals
extern int fixme_onoise_type;
@ -44,6 +54,24 @@ NOISEan(CKTcircuit* ckt, int restart)
double freqTol; /* tolerence parameter for finding final frequency; hack */
int i, src_type;
int numNames;
IFuid* nameList; /* va: tmalloc'ed list of names */
static runDesc* noiPlot = NULL;
runDesc* plot = NULL;
#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */
/* Tell the beginPlot routine what mode we're in */
g_ipc.anal_type = IPC_ANAL_NOI;
/* 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 */
#endif
NOISEAN* job = (NOISEAN*)ckt->CKTcurJob;
GENinstance* inst = CKTfndDev(ckt, job->input);
bool frequequal = AlmostEqualUlps(job->NstartFreq, job->NstopFreq, 3);
@ -134,18 +162,92 @@ NOISEan(CKTcircuit* ckt, int restart)
return(E_BADPARM);
}
/* error = DCop(ckt); */
error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
#ifdef XSPICE
/* gtri - begin - wbk - Call EVTop if event-driven instances exist */
if (ckt->evt->counts.num_insts != 0) {
error = EVTop(ckt,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter,
MIF_TRUE);
EVTdump(ckt, IPC_ANAL_DCOP, 0.0);
EVTop_save(ckt, MIF_TRUE, 0.0);
}
else
#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,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
if (error) {
fprintf(stdout, "\nNOISE operating point failed -\n");
CKTncDump(ckt);
return(error);
}
}
else
fprintf(stdout, "\n Linear circuit, option noopac given: no OP analysis\n");
#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
/* Send the operating point results for Mspice compatibility */
if (g_ipc.enabled)
{
/* Call CKTnames to get names of nodes/branches used by
BeginPlot */
/* Probably should free nameList after this block since
called again... */
error = CKTnames(ckt, &numNames, &nameList);
if (error) return(error);
/* We have to do a beginPlot here since the data to return is
* different for the DCOP than it is for the AC analysis.
* Moreover the begin plot has not even been done yet at this
* point...
*/
SPfrontEnd->OUTpBeginPlot(ckt, ckt->CKTcurJob,
ckt->CKTcurJob->JOBname,
NULL, IF_REAL,
numNames, nameList, IF_REAL,
&noiPlot);
txfree(nameList);
ipc_send_dcop_prefix();
CKTdump(ckt, 0.0, noiPlot);
ipc_send_dcop_suffix();
SPfrontEnd->OUTendPlot(noiPlot);
}
/* gtri - end - wbk */
#endif
if (error) return(error);
/* Patch to noisean.c by Richard D. McRoberts. */
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
error = CKTload(ckt);
if (error) return(error);
error = CKTnames(ckt, &numNames, &nameList);
if (error) return(error);
if (ckt->CKTkeepOpInfo) {
/* Dump operating point. */
error = SPfrontEnd->OUTpBeginPlot(ckt, ckt->CKTcurJob,
"NOISE Operating Point",
NULL, IF_REAL,
numNames, nameList, IF_REAL,
&plot);
if (error) return(error);
CKTdump(ckt, 0.0, plot);
SPfrontEnd->OUTendPlot(plot);
plot = NULL;
}
data = TMALLOC(Ndata, 1);
step = 0;
data->freq = job->NstartFreq;
@ -243,6 +345,18 @@ NOISEan(CKTcircuit* ckt, int restart)
data->lstFreq = data->freq;
#ifdef XSPICE
/* 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 */
/* MIF_NOI is not yet supported by code models, so use their AC capabilities */
g_mif_info.circuit.anal_type = MIF_AC;
/* gtri - end - wbk */
#endif
/* do the noise analysis over all frequencies */
while (data->freq <= job->NstopFreq + freqTol) {

Loading…
Cancel
Save