Merge branch 'pre-master' into bt_dev
This commit is contained in:
commit
fb4e1d9f2a
|
|
@ -0,0 +1,25 @@
|
||||||
|
baker-252 enhanced
|
||||||
|
* simple noiseless opamp with RC feedback
|
||||||
|
* compare E source and code model gain stage
|
||||||
|
* ngspice-40+ required
|
||||||
|
|
||||||
|
.control
|
||||||
|
set sqrnoise
|
||||||
|
noise V(vout) Vplus dec 100 1 1000G
|
||||||
|
print all
|
||||||
|
noise V(vouta) Vplusa dec 100 1 1000G
|
||||||
|
print all
|
||||||
|
.endc
|
||||||
|
|
||||||
|
Vplus Vplus 0 dc 0 ac 1
|
||||||
|
Rf vout vminus 100k
|
||||||
|
Cf vout vminus 1000p
|
||||||
|
Eopamp vout 0 vplus vminus 100Meg
|
||||||
|
|
||||||
|
Vplusa Vplusa 0 dc 0 ac 1
|
||||||
|
Rfa vouta vminusa 100k
|
||||||
|
Cfa vouta vminusa 1000p
|
||||||
|
a1 %vd(vplusa, vminusa) vouta amp
|
||||||
|
.model amp gain(gain=1e8)
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
* noise of a resistive divider
|
||||||
|
* noise of a resistive divider, lower resistor noiseless
|
||||||
|
* noise of a resistive divider with filter
|
||||||
|
* 'set behavior = lta' is required
|
||||||
|
|
||||||
|
V1 1 0 dc 0 ac 1
|
||||||
|
R1 1 2 10k
|
||||||
|
R2 2 0 10k
|
||||||
|
|
||||||
|
V11 11 0 dc 0 ac 1
|
||||||
|
R11 11 12 10k
|
||||||
|
R12 12 0 10k noiseless
|
||||||
|
|
||||||
|
V21 21 0 dc 0 ac 1
|
||||||
|
R21 21 22 10k
|
||||||
|
R22 22 0 10k
|
||||||
|
C22 22 0 1u
|
||||||
|
|
||||||
|
.control
|
||||||
|
noise v(2) V1 dec 10 1 100k
|
||||||
|
echo **resistive divider**
|
||||||
|
print onoise_total inoise_total
|
||||||
|
setplot noise1
|
||||||
|
print onoise_spectrum[0] inoise_spectrum[0]
|
||||||
|
noise v(12) V11 dec 10 1 100k
|
||||||
|
echo **resistive divider, lower resistor noiseless**
|
||||||
|
print onoise_total inoise_total
|
||||||
|
setplot noise3
|
||||||
|
print onoise_spectrum[0] inoise_spectrum[0]
|
||||||
|
noise v(22) V21 dec 10 1 100k
|
||||||
|
echo **resistive divider with filter**
|
||||||
|
print onoise_total inoise_total
|
||||||
|
setplot noise5
|
||||||
|
print onoise_spectrum[0] inoise_spectrum[0]
|
||||||
|
set xbrushwidth=2
|
||||||
|
plot onoise_spectrum inoise_spectrum xlimit 1 1e5
|
||||||
|
.endc
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
*noise of a resistive divider
|
||||||
|
*noise of a resistive divider with filter
|
||||||
|
*noise as above after a noiseless amplifier with gain 5
|
||||||
|
|
||||||
|
V1 1 0 dc 0 ac 1
|
||||||
|
R1 1 2 10k
|
||||||
|
R2 2 0 10k
|
||||||
|
|
||||||
|
V21 21 0 dc 0 ac 1
|
||||||
|
R21 21 22 10k
|
||||||
|
R22 22 0 10k
|
||||||
|
C22 22 0 1u
|
||||||
|
|
||||||
|
a1 2 3 amp
|
||||||
|
.model amp gain(in_offset = 0 gain = 5.0
|
||||||
|
+ out_offset = 0)
|
||||||
|
|
||||||
|
a2 22 23 amp
|
||||||
|
|
||||||
|
.control
|
||||||
|
|
||||||
|
noise v(2) V1 dec 10 1 100k
|
||||||
|
print onoise_total inoise_total
|
||||||
|
setplot noise1
|
||||||
|
print onoise_spectrum[0] inoise_spectrum[0]
|
||||||
|
|
||||||
|
noise v(3) V1 dec 10 1 100k
|
||||||
|
print onoise_total inoise_total
|
||||||
|
setplot noise3
|
||||||
|
print onoise_spectrum[0] inoise_spectrum[0]
|
||||||
|
|
||||||
|
noise v(22) V21 dec 10 1 100k
|
||||||
|
print onoise_total inoise_total
|
||||||
|
setplot noise5
|
||||||
|
print onoise_spectrum[0] inoise_spectrum[0]
|
||||||
|
|
||||||
|
noise v(23) V21 dec 10 1 100k
|
||||||
|
print onoise_total inoise_total
|
||||||
|
setplot noise7
|
||||||
|
print onoise_spectrum[0] inoise_spectrum[0]
|
||||||
|
set xbrushwidth = 2
|
||||||
|
plot onoise_spectrum noise5.onoise_spectrum inoise_spectrum xlimit 1 1e5
|
||||||
|
|
||||||
|
.endc
|
||||||
|
|
||||||
|
.end
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -113,8 +113,9 @@ typedef enum {
|
||||||
IPC_ANAL_AC,
|
IPC_ANAL_AC,
|
||||||
IPC_ANAL_TRAN,
|
IPC_ANAL_TRAN,
|
||||||
#ifdef RFSPICE
|
#ifdef RFSPICE
|
||||||
IPC_ANAL_SP
|
IPC_ANAL_SP,
|
||||||
#endif
|
#endif
|
||||||
|
IPC_ANAL_NOI
|
||||||
} Ipc_Anal_t;
|
} Ipc_Anal_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ typedef enum {
|
||||||
MIF_DC, /* A DC or DCOP analysis */
|
MIF_DC, /* A DC or DCOP analysis */
|
||||||
MIF_AC, /* A swept AC analysis */
|
MIF_AC, /* A swept AC analysis */
|
||||||
MIF_TRAN, /* A transient analysis */
|
MIF_TRAN, /* A transient analysis */
|
||||||
|
MIF_NOI, /* A noise analysis */
|
||||||
} Mif_Analysis_t;
|
} Mif_Analysis_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@ do { \
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ACan(CKTcircuit *ckt, int restart)
|
ACan(CKTcircuit* ckt, int restart)
|
||||||
{
|
{
|
||||||
ACAN *job = (ACAN *) ckt->CKTcurJob;
|
ACAN* job = (ACAN*)ckt->CKTcurJob;
|
||||||
|
|
||||||
double freq;
|
double freq;
|
||||||
double freqTol; /* tolerence parameter for finding final frequency */
|
double freqTol; /* tolerence parameter for finding final frequency */
|
||||||
|
|
@ -55,23 +55,23 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
double startTime;
|
double startTime;
|
||||||
int error;
|
int error;
|
||||||
int numNames;
|
int numNames;
|
||||||
IFuid *nameList; /* va: tmalloc'ed list of names */
|
IFuid* nameList; /* va: tmalloc'ed list of names */
|
||||||
IFuid freqUid;
|
IFuid freqUid;
|
||||||
static runDesc *acPlot = NULL;
|
static runDesc* acPlot = NULL;
|
||||||
runDesc *plot = NULL;
|
runDesc* plot = NULL;
|
||||||
|
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */
|
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */
|
||||||
|
|
||||||
/* Tell the beginPlot routine what mode we're in */
|
/* Tell the beginPlot routine what mode we're in */
|
||||||
g_ipc.anal_type = IPC_ANAL_AC;
|
g_ipc.anal_type = IPC_ANAL_AC;
|
||||||
|
|
||||||
/* Tell the code models what mode we're in */
|
/* Tell the code models what mode we're in */
|
||||||
g_mif_info.circuit.anal_type = MIF_DC;
|
g_mif_info.circuit.anal_type = MIF_DC;
|
||||||
g_mif_info.circuit.anal_init = MIF_TRUE;
|
g_mif_info.circuit.anal_init = MIF_TRUE;
|
||||||
|
|
||||||
/* gtri - end - wbk */
|
/* gtri - end - wbk */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* start at beginning */
|
/* start at beginning */
|
||||||
|
|
@ -86,8 +86,8 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
fprintf(stderr, "ERROR: AC startfreq <= 0\n");
|
fprintf(stderr, "ERROR: AC startfreq <= 0\n");
|
||||||
return E_PARMVAL;
|
return E_PARMVAL;
|
||||||
}
|
}
|
||||||
double num_steps = floor(fabs(log10(job->ACstopFreq/job->ACstartFreq))*job->ACnumberSteps);
|
double num_steps = floor(fabs(log10(job->ACstopFreq / job->ACstartFreq)) * job->ACnumberSteps);
|
||||||
job->ACfreqDelta = exp((log(job->ACstopFreq/job->ACstartFreq))/ num_steps);
|
job->ACfreqDelta = exp((log(job->ACstopFreq / job->ACstartFreq)) / num_steps);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case OCTAVE:
|
case OCTAVE:
|
||||||
|
|
@ -96,131 +96,132 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
return E_PARMVAL;
|
return E_PARMVAL;
|
||||||
}
|
}
|
||||||
job->ACfreqDelta =
|
job->ACfreqDelta =
|
||||||
exp(log(2.0)/job->ACnumberSteps);
|
exp(log(2.0) / job->ACnumberSteps);
|
||||||
break;
|
break;
|
||||||
case LINEAR:
|
case LINEAR:
|
||||||
if (job->ACnumberSteps-1 > 1)
|
if (job->ACnumberSteps - 1 > 1)
|
||||||
job->ACfreqDelta =
|
job->ACfreqDelta =
|
||||||
(job->ACstopFreq -
|
(job->ACstopFreq -
|
||||||
job->ACstartFreq) /
|
job->ACstartFreq) /
|
||||||
(job->ACnumberSteps - 1);
|
(job->ACnumberSteps - 1);
|
||||||
else
|
else
|
||||||
/* Patch from: Richard McRoberts
|
/* Patch from: Richard McRoberts
|
||||||
* This patch is for a rather pathological case:
|
* This patch is for a rather pathological case:
|
||||||
* a linear step with only one point */
|
* a linear step with only one point */
|
||||||
job->ACfreqDelta = 0;
|
job->ACfreqDelta = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return(E_BADPARM);
|
return(E_BADPARM);
|
||||||
}
|
|
||||||
#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,"\nAC operating point failed -\n");
|
|
||||||
CKTncDump(ckt);
|
|
||||||
return(error);
|
|
||||||
}
|
}
|
||||||
}
|
#ifdef XSPICE
|
||||||
else
|
/* gtri - begin - wbk - Call EVTop if event-driven instances exist */
|
||||||
fprintf(stdout,"\n Linear circuit, option noopac given: no OP analysis\n");
|
|
||||||
|
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, "\nAC operating point failed -\n");
|
||||||
|
CKTncDump(ckt);
|
||||||
|
return(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf(stdout, "\n Linear circuit, option noopac given: no OP analysis\n");
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
|
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
|
||||||
|
|
||||||
/* Send the operating point results for Mspice compatibility */
|
/* Send the operating point results for Mspice compatibility */
|
||||||
if(g_ipc.enabled)
|
if (g_ipc.enabled)
|
||||||
{
|
{
|
||||||
/* Call CKTnames to get names of nodes/branches used by
|
/* Call CKTnames to get names of nodes/branches used by
|
||||||
BeginPlot */
|
BeginPlot */
|
||||||
/* Probably should free nameList after this block since
|
/* Probably should free nameList after this block since
|
||||||
called again... */
|
called again... */
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt, &numNames, &nameList);
|
||||||
if(error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
/* We have to do a beginPlot here since the data to return is
|
/* We have to do a beginPlot here since the data to return is
|
||||||
* different for the DCOP than it is for the AC analysis.
|
* different for the DCOP than it is for the AC analysis.
|
||||||
* Moreover the begin plot has not even been done yet at this
|
* Moreover the begin plot has not even been done yet at this
|
||||||
* point...
|
* point...
|
||||||
*/
|
*/
|
||||||
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
SPfrontEnd->OUTpBeginPlot(ckt, ckt->CKTcurJob,
|
||||||
ckt->CKTcurJob->JOBname,
|
ckt->CKTcurJob->JOBname,
|
||||||
NULL, IF_REAL,
|
NULL, IF_REAL,
|
||||||
numNames, nameList, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
&acPlot);
|
&acPlot);
|
||||||
txfree(nameList);
|
txfree(nameList);
|
||||||
|
|
||||||
ipc_send_dcop_prefix();
|
ipc_send_dcop_prefix();
|
||||||
CKTdump(ckt, 0.0, acPlot);
|
CKTdump(ckt, 0.0, acPlot);
|
||||||
ipc_send_dcop_suffix();
|
ipc_send_dcop_suffix();
|
||||||
|
|
||||||
SPfrontEnd->OUTendPlot (acPlot);
|
SPfrontEnd->OUTendPlot(acPlot);
|
||||||
}
|
}
|
||||||
/* gtri - end - wbk */
|
/* gtri - end - wbk */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
||||||
error = CKTload(ckt);
|
error = CKTload(ckt);
|
||||||
if(error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
error = CKTnames(ckt,&numNames,&nameList);
|
error = CKTnames(ckt, &numNames, &nameList);
|
||||||
if(error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
if (ckt->CKTkeepOpInfo) {
|
if (ckt->CKTkeepOpInfo) {
|
||||||
/* Dump operating point. */
|
/* Dump operating point. */
|
||||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
error = SPfrontEnd->OUTpBeginPlot(ckt, ckt->CKTcurJob,
|
||||||
"AC Operating Point",
|
"AC Operating Point",
|
||||||
NULL, IF_REAL,
|
NULL, IF_REAL,
|
||||||
numNames, nameList, IF_REAL,
|
numNames, nameList, IF_REAL,
|
||||||
&plot);
|
&plot);
|
||||||
if(error) return(error);
|
if (error) return(error);
|
||||||
CKTdump(ckt, 0.0, plot);
|
CKTdump(ckt, 0.0, plot);
|
||||||
SPfrontEnd->OUTendPlot (plot);
|
SPfrontEnd->OUTendPlot(plot);
|
||||||
plot = NULL;
|
plot = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
SPfrontEnd->IFnewUid(ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
error = SPfrontEnd->OUTpBeginPlot(ckt, ckt->CKTcurJob,
|
||||||
ckt->CKTcurJob->JOBname,
|
ckt->CKTcurJob->JOBname,
|
||||||
freqUid, IF_REAL,
|
freqUid, IF_REAL,
|
||||||
numNames, nameList, IF_COMPLEX,
|
numNames, nameList, IF_COMPLEX,
|
||||||
&acPlot);
|
&acPlot);
|
||||||
tfree(nameList);
|
tfree(nameList);
|
||||||
if(error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
if (job->ACstepType != LINEAR) {
|
if (job->ACstepType != LINEAR) {
|
||||||
SPfrontEnd->OUTattributes (acPlot, NULL, OUT_SCALE_LOG, NULL);
|
SPfrontEnd->OUTattributes(acPlot, NULL, OUT_SCALE_LOG, NULL);
|
||||||
}
|
}
|
||||||
freq = job->ACstartFreq;
|
freq = job->ACstartFreq;
|
||||||
|
|
||||||
} else { /* continue previous analysis */
|
}
|
||||||
|
else { /* continue previous analysis */
|
||||||
freq = job->ACsaveFreq;
|
freq = job->ACsaveFreq;
|
||||||
job->ACsaveFreq = 0; /* clear the 'old' frequency */
|
job->ACsaveFreq = 0; /* clear the 'old' frequency */
|
||||||
/* fix resume? saj, indeed !*/
|
/* fix resume? saj, indeed !*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
error = SPfrontEnd->OUTpBeginPlot(NULL, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
666, NULL, 666,
|
666, NULL, 666,
|
||||||
&acPlot);
|
&acPlot);
|
||||||
/* saj*/
|
/* saj*/
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (job->ACstepType) {
|
switch (job->ACstepType) {
|
||||||
|
|
@ -238,14 +239,14 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */
|
/* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */
|
||||||
|
|
||||||
g_mif_info.circuit.anal_init = MIF_TRUE;
|
g_mif_info.circuit.anal_init = MIF_TRUE;
|
||||||
|
|
||||||
/* Tell the code models what mode we're in */
|
/* Tell the code models what mode we're in */
|
||||||
g_mif_info.circuit.anal_type = MIF_AC;
|
g_mif_info.circuit.anal_type = MIF_AC;
|
||||||
|
|
||||||
/* gtri - end - wbk */
|
/* gtri - end - wbk */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
INIT_STATS();
|
INIT_STATS();
|
||||||
|
|
@ -254,19 +255,19 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
/* main loop through all scheduled frequencies */
|
/* main loop through all scheduled frequencies */
|
||||||
while (freq <= job->ACstopFreq + freqTol) {
|
while (freq <= job->ACstopFreq + freqTol) {
|
||||||
if(SPfrontEnd->IFpauseTest()) {
|
if (SPfrontEnd->IFpauseTest()) {
|
||||||
/* user asked us to pause via an interrupt */
|
/* user asked us to pause via an interrupt */
|
||||||
job->ACsaveFreq = freq;
|
job->ACsaveFreq = freq;
|
||||||
return(E_PAUSE);
|
return(E_PAUSE);
|
||||||
}
|
}
|
||||||
ckt->CKTomega = 2.0 * M_PI *freq;
|
ckt->CKTomega = 2.0 * M_PI * freq;
|
||||||
|
|
||||||
/* Update opertating point, if variable 'hertz' is given */
|
/* Update opertating point, if variable 'hertz' is given */
|
||||||
if (ckt->CKTvarHertz) {
|
if (ckt->CKTvarHertz) {
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* Call EVTop if event-driven instances exist */
|
/* Call EVTop if event-driven instances exist */
|
||||||
|
|
||||||
if(ckt->evt->counts.num_insts != 0) {
|
if (ckt->evt->counts.num_insts != 0) {
|
||||||
error = EVTop(ckt,
|
error = EVTop(ckt,
|
||||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||||
|
|
@ -277,23 +278,23 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
// If no event-driven instances, do what SPICE normally does
|
// If no event-driven instances, do what SPICE normally does
|
||||||
error = CKTop(ckt,
|
error = CKTop(ckt,
|
||||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
||||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
||||||
ckt->CKTdcMaxIter);
|
ckt->CKTdcMaxIter);
|
||||||
|
|
||||||
if(error){
|
if (error) {
|
||||||
fprintf(stdout,"\nAC operating point failed -\n");
|
fprintf(stdout, "\nAC operating point failed -\n");
|
||||||
CKTncDump(ckt);
|
CKTncDump(ckt);
|
||||||
return(error);
|
return(error);
|
||||||
}
|
}
|
||||||
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
||||||
error = CKTload(ckt);
|
error = CKTload(ckt);
|
||||||
if(error) return(error);
|
if (error) return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEAC;
|
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEAC;
|
||||||
error = NIacIter(ckt);
|
error = NIacIter(ckt);
|
||||||
if (error) {
|
if (error) {
|
||||||
UPDATE_STATS(DOING_AC);
|
UPDATE_STATS(DOING_AC);
|
||||||
|
|
@ -301,18 +302,18 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WANT_SENSE2
|
#ifdef WANT_SENSE2
|
||||||
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&ACSEN) ){
|
if (ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & ACSEN)) {
|
||||||
long save;
|
long save;
|
||||||
int save1;
|
int save1;
|
||||||
|
|
||||||
save = ckt->CKTmode;
|
save = ckt->CKTmode;
|
||||||
ckt->CKTmode=(ckt->CKTmode&MODEUIC)|MODEDCOP|MODEINITSMSIG;
|
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
||||||
save1 = ckt->CKTsenInfo->SENmode;
|
save1 = ckt->CKTsenInfo->SENmode;
|
||||||
ckt->CKTsenInfo->SENmode = ACSEN;
|
ckt->CKTsenInfo->SENmode = ACSEN;
|
||||||
if (freq == job->ACstartFreq) {
|
if (freq == job->ACstartFreq) {
|
||||||
ckt->CKTsenInfo->SENacpertflag = 1;
|
ckt->CKTsenInfo->SENacpertflag = 1;
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
ckt->CKTsenInfo->SENacpertflag = 0;
|
ckt->CKTsenInfo->SENacpertflag = 0;
|
||||||
}
|
}
|
||||||
error = CKTsenAC(ckt);
|
error = CKTsenAC(ckt);
|
||||||
|
|
@ -324,24 +325,24 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
|
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
|
||||||
|
|
||||||
if(g_ipc.enabled)
|
if (g_ipc.enabled)
|
||||||
ipc_send_data_prefix(freq);
|
ipc_send_data_prefix(freq);
|
||||||
|
|
||||||
error = CKTacDump(ckt,freq,acPlot);
|
error = CKTacDump(ckt, freq, acPlot);
|
||||||
|
|
||||||
if(g_ipc.enabled)
|
if (g_ipc.enabled)
|
||||||
ipc_send_data_suffix();
|
ipc_send_data_suffix();
|
||||||
|
|
||||||
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
|
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
|
||||||
#else
|
#else
|
||||||
error = CKTacDump(ckt,freq,acPlot);
|
error = CKTacDump(ckt, freq, acPlot);
|
||||||
#endif
|
#endif
|
||||||
if (error) {
|
if (error) {
|
||||||
UPDATE_STATS(DOING_AC);
|
UPDATE_STATS(DOING_AC);
|
||||||
return(error);
|
return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* increment frequency */
|
/* increment frequency */
|
||||||
|
|
||||||
|
|
@ -349,37 +350,37 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
case DECADE:
|
case DECADE:
|
||||||
case OCTAVE:
|
case OCTAVE:
|
||||||
|
|
||||||
/* inserted again 14.12.2001 */
|
/* inserted again 14.12.2001 */
|
||||||
#ifdef HAS_PROGREP
|
#ifdef HAS_PROGREP
|
||||||
{
|
{
|
||||||
double endfreq = job->ACstopFreq;
|
double endfreq = job->ACstopFreq;
|
||||||
double startfreq = job->ACstartFreq;
|
double startfreq = job->ACstartFreq;
|
||||||
endfreq = log(endfreq);
|
endfreq = log(endfreq);
|
||||||
if (startfreq == 0.0)
|
if (startfreq == 0.0)
|
||||||
startfreq = 1e-12;
|
startfreq = 1e-12;
|
||||||
startfreq = log(startfreq);
|
startfreq = log(startfreq);
|
||||||
|
|
||||||
if (freq > 0.0)
|
if (freq > 0.0)
|
||||||
SetAnalyse( "ac", (int)((log(freq)-startfreq) * 1000.0 / (endfreq-startfreq)));
|
SetAnalyse("ac", (int)((log(freq) - startfreq) * 1000.0 / (endfreq - startfreq)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
freq *= job->ACfreqDelta;
|
freq *= job->ACfreqDelta;
|
||||||
if (job->ACfreqDelta == 1) goto endsweep;
|
if (job->ACfreqDelta == 1) goto endsweep;
|
||||||
break;
|
break;
|
||||||
case LINEAR:
|
case LINEAR:
|
||||||
|
|
||||||
#ifdef HAS_PROGREP
|
#ifdef HAS_PROGREP
|
||||||
{
|
{
|
||||||
double endfreq = job->ACstopFreq;
|
double endfreq = job->ACstopFreq;
|
||||||
double startfreq = job->ACstartFreq;
|
double startfreq = job->ACstartFreq;
|
||||||
SetAnalyse( "ac", (int)((freq - startfreq)* 1000.0 / (endfreq-startfreq)));
|
SetAnalyse("ac", (int)((freq - startfreq) * 1000.0 / (endfreq - startfreq)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
freq += job->ACfreqDelta;
|
freq += job->ACfreqDelta;
|
||||||
if (job->ACfreqDelta == 0) goto endsweep;
|
if (job->ACfreqDelta == 0) goto endsweep;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return(E_INTERN);
|
return(E_INTERN);
|
||||||
|
|
||||||
|
|
@ -387,52 +388,52 @@ ACan(CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
}
|
}
|
||||||
endsweep:
|
endsweep:
|
||||||
SPfrontEnd->OUTendPlot (acPlot);
|
SPfrontEnd->OUTendPlot(acPlot);
|
||||||
acPlot = NULL;
|
acPlot = NULL;
|
||||||
UPDATE_STATS(0);
|
UPDATE_STATS(0);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* CKTacLoad(ckt)
|
/* CKTacLoad(ckt)
|
||||||
* this is a driver program to iterate through all the various
|
* this is a driver program to iterate through all the various
|
||||||
* ac load functions provided for the circuit elements in the
|
* ac load functions provided for the circuit elements in the
|
||||||
* given circuit
|
* given circuit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
CKTacLoad(CKTcircuit *ckt)
|
CKTacLoad(CKTcircuit* ckt)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int size;
|
int size;
|
||||||
int error;
|
int error;
|
||||||
double startTime;
|
double startTime;
|
||||||
|
|
||||||
startTime = SPfrontEnd->IFseconds();
|
startTime = SPfrontEnd->IFseconds();
|
||||||
size = SMPmatSize(ckt->CKTmatrix);
|
size = SMPmatSize(ckt->CKTmatrix);
|
||||||
for (i=0;i<=size;i++) {
|
for (i = 0; i <= size; i++) {
|
||||||
ckt->CKTrhs[i]=0;
|
ckt->CKTrhs[i] = 0;
|
||||||
ckt->CKTirhs[i]=0;
|
ckt->CKTirhs[i] = 0;
|
||||||
}
|
}
|
||||||
SMPcClear(ckt->CKTmatrix);
|
SMPcClear(ckt->CKTmatrix);
|
||||||
|
|
||||||
for (i=0;i<DEVmaxnum;i++) {
|
for (i = 0; i < DEVmaxnum; i++) {
|
||||||
if ( DEVices[i] && DEVices[i]->DEVacLoad && ckt->CKThead[i] ) {
|
if (DEVices[i] && DEVices[i]->DEVacLoad && ckt->CKThead[i]) {
|
||||||
error = DEVices[i]->DEVacLoad (ckt->CKThead[i], ckt);
|
error = DEVices[i]->DEVacLoad(ckt->CKThead[i], ckt);
|
||||||
if(error) return(error);
|
if (error) return(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
/* gtri - begin - Put resistors to ground at all nodes. */
|
/* gtri - begin - Put resistors to ground at all nodes. */
|
||||||
/* Value of resistor is set by new "rshunt" option. */
|
/* Value of resistor is set by new "rshunt" option. */
|
||||||
|
|
||||||
if(ckt->enh->rshunt_data.enabled) {
|
if (ckt->enh->rshunt_data.enabled) {
|
||||||
for(i = 0; i < ckt->enh->rshunt_data.num_nodes; i++) {
|
for (i = 0; i < ckt->enh->rshunt_data.num_nodes; i++) {
|
||||||
*(ckt->enh->rshunt_data.diag[i]) +=
|
*(ckt->enh->rshunt_data.diag[i]) +=
|
||||||
ckt->enh->rshunt_data.gshunt;
|
ckt->enh->rshunt_data.gshunt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gtri - end - Put resistors to ground at all nodes */
|
/* gtri - end - Put resistors to ground at all nodes */
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,28 @@ Modified: 2001 AlansFixes
|
||||||
#include "vsrc/vsrcdefs.h"
|
#include "vsrc/vsrcdefs.h"
|
||||||
#include "isrc/isrcdefs.h"
|
#include "isrc/isrcdefs.h"
|
||||||
|
|
||||||
// fixme
|
#ifdef XSPICE
|
||||||
// ugly hack to work around missing api to specify the "type" of signals
|
#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;
|
extern int fixme_onoise_type;
|
||||||
extern int fixme_inoise_type;
|
extern int fixme_inoise_type;
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
NOISEan (CKTcircuit *ckt, int restart)
|
NOISEan(CKTcircuit* ckt, int restart)
|
||||||
{
|
{
|
||||||
/* variable must be static, for continuation of interrupted (Ctrl-C),
|
/* variable must be static, for continuation of interrupted (Ctrl-C),
|
||||||
longer lasting noise anlysis */
|
longer lasting noise anlysis */
|
||||||
static Ndata *data;
|
static Ndata* data;
|
||||||
|
|
||||||
double realVal;
|
double realVal;
|
||||||
double imagVal;
|
double imagVal;
|
||||||
|
|
@ -44,32 +54,52 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
double freqTol; /* tolerence parameter for finding final frequency; hack */
|
double freqTol; /* tolerence parameter for finding final frequency; hack */
|
||||||
int i, src_type;
|
int i, src_type;
|
||||||
|
|
||||||
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;
|
int numNames;
|
||||||
GENinstance *inst = CKTfndDev(ckt, job->input);
|
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);
|
bool frequequal = AlmostEqualUlps(job->NstartFreq, job->NstopFreq, 3);
|
||||||
|
|
||||||
posOutNode = (job->output) -> number;
|
posOutNode = (job->output)->number;
|
||||||
negOutNode = (job->outputRef) -> number;
|
negOutNode = (job->outputRef)->number;
|
||||||
|
|
||||||
if (job->NnumSteps < 1) {
|
if (job->NnumSteps < 1) {
|
||||||
SPfrontEnd->IFerrorf(ERR_WARNING,
|
SPfrontEnd->IFerrorf(ERR_WARNING,
|
||||||
"Number of steps for noise measurement has to be larger than 0,\n but currently is %d\n",
|
"Number of steps for noise measurement has to be larger than 0,\n but currently is %d\n",
|
||||||
job->NnumSteps);
|
job->NnumSteps);
|
||||||
return(E_PARMVAL);
|
return(E_PARMVAL);
|
||||||
} else if ((job->NnumSteps == 1) && (job->NstpType == LINEAR)) {
|
}
|
||||||
|
else if ((job->NnumSteps == 1) && (job->NstpType == LINEAR)) {
|
||||||
if (!frequequal) {
|
if (!frequequal) {
|
||||||
job->NstopFreq = job->NstartFreq;
|
job->NstopFreq = job->NstartFreq;
|
||||||
SPfrontEnd->IFerrorf(ERR_WARNING,
|
SPfrontEnd->IFerrorf(ERR_WARNING,
|
||||||
"Noise measurement at a single frequency %g only!\n",
|
"Noise measurement at a single frequency %g only!\n",
|
||||||
job->NstartFreq);
|
job->NstartFreq);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (frequequal) {
|
if (frequequal) {
|
||||||
job->NstopFreq = job->NstartFreq;
|
job->NstopFreq = job->NstartFreq;
|
||||||
job->NnumSteps = 1;
|
job->NnumSteps = 1;
|
||||||
SPfrontEnd->IFerrorf(ERR_WARNING,
|
SPfrontEnd->IFerrorf(ERR_WARNING,
|
||||||
"Noise measurement at a single frequency %g only!\n",
|
"Noise measurement at a single frequency %g only!\n",
|
||||||
job->NstartFreq);
|
job->NstartFreq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* see if the source specified is AC */
|
/* see if the source specified is AC */
|
||||||
|
|
@ -77,45 +107,47 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
bool ac_given = FALSE;
|
bool ac_given = FALSE;
|
||||||
|
|
||||||
if (!inst || inst->GENmodPtr->GENmodType < 0) {
|
if (!inst || inst->GENmodPtr->GENmodType < 0) {
|
||||||
SPfrontEnd->IFerrorf (ERR_WARNING,
|
SPfrontEnd->IFerrorf(ERR_WARNING,
|
||||||
"Noise input source %s not in circuit",
|
"Noise input source %s not in circuit",
|
||||||
job->input);
|
job->input);
|
||||||
return E_NOTFOUND;
|
return E_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst->GENmodPtr->GENmodType == CKTtypelook("Vsource")) {
|
if (inst->GENmodPtr->GENmodType == CKTtypelook("Vsource")) {
|
||||||
ac_given = ((VSRCinstance *)inst) -> VSRCacGiven;
|
ac_given = ((VSRCinstance*)inst)->VSRCacGiven;
|
||||||
src_type = SV_VOLTAGE;
|
src_type = SV_VOLTAGE;
|
||||||
} else if(inst->GENmodPtr->GENmodType == CKTtypelook("Isource")) {
|
}
|
||||||
ac_given = ((ISRCinstance *)inst) -> ISRCacGiven;
|
else if (inst->GENmodPtr->GENmodType == CKTtypelook("Isource")) {
|
||||||
|
ac_given = ((ISRCinstance*)inst)->ISRCacGiven;
|
||||||
src_type = SV_CURRENT;
|
src_type = SV_CURRENT;
|
||||||
} else {
|
}
|
||||||
SPfrontEnd->IFerrorf (ERR_WARNING,
|
else {
|
||||||
"Noise input source %s is not of proper type",
|
SPfrontEnd->IFerrorf(ERR_WARNING,
|
||||||
job->input);
|
"Noise input source %s is not of proper type",
|
||||||
|
job->input);
|
||||||
return E_NOTFOUND;
|
return E_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ac_given) {
|
if (!ac_given) {
|
||||||
SPfrontEnd->IFerrorf (ERR_WARNING,
|
SPfrontEnd->IFerrorf(ERR_WARNING,
|
||||||
"Noise input source %s has no AC value",
|
"Noise input source %s has no AC value",
|
||||||
job->input);
|
job->input);
|
||||||
return E_NOACINPUT;
|
return E_NOACINPUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (job->NsavFstp == 0.0) || restart) { /* va, NsavFstp is double */
|
if ((job->NsavFstp == 0.0) || restart) { /* va, NsavFstp is double */
|
||||||
switch (job->NstpType) {
|
switch (job->NstpType) {
|
||||||
|
|
||||||
|
|
||||||
case DECADE:
|
case DECADE:
|
||||||
job->NfreqDelta = exp(log(10.0)/
|
job->NfreqDelta = exp(log(10.0) /
|
||||||
job->NnumSteps);
|
job->NnumSteps);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OCTAVE:
|
case OCTAVE:
|
||||||
job->NfreqDelta = exp(log(2.0)/
|
job->NfreqDelta = exp(log(2.0) /
|
||||||
job->NnumSteps);
|
job->NnumSteps);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LINEAR:
|
case LINEAR:
|
||||||
|
|
@ -123,24 +155,98 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
job->NfreqDelta = 0;
|
job->NfreqDelta = 0;
|
||||||
else
|
else
|
||||||
job->NfreqDelta = (job->NstopFreq -
|
job->NfreqDelta = (job->NstopFreq -
|
||||||
job->NstartFreq) / (job->NnumSteps - 1);
|
job->NstartFreq) / (job->NnumSteps - 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return(E_BADPARM);
|
return(E_BADPARM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error = DCop(ckt); */
|
#ifdef XSPICE
|
||||||
error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
|
/* gtri - begin - wbk - Call EVTop if event-driven instances exist */
|
||||||
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
|
|
||||||
ckt->CKTdcMaxIter);
|
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. */
|
/* Patch to noisean.c by Richard D. McRoberts. */
|
||||||
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
|
||||||
error = CKTload(ckt);
|
error = CKTload(ckt);
|
||||||
if(error) return(error);
|
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);
|
data = TMALLOC(Ndata, 1);
|
||||||
step = 0;
|
step = 0;
|
||||||
|
|
@ -152,10 +258,10 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
/* the current front-end needs the namelist to be fully
|
/* the current front-end needs the namelist to be fully
|
||||||
declared before an OUTpBeginplot */
|
declared before an OUTpBeginplot */
|
||||||
|
|
||||||
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
SPfrontEnd->IFnewUid(ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
|
||||||
|
|
||||||
data->numPlots = 0; /* we don't have any plots yet */
|
data->numPlots = 0; /* we don't have any plots yet */
|
||||||
error = CKTnoise(ckt,N_DENS,N_OPEN,data);
|
error = CKTnoise(ckt, N_DENS, N_OPEN, data);
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -165,10 +271,10 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
if (src_type == SV_VOLTAGE)
|
if (src_type == SV_VOLTAGE)
|
||||||
fixme_inoise_type =
|
fixme_inoise_type =
|
||||||
data->squared ? SV_SQR_VOLTAGE_DENSITY : SV_VOLTAGE_DENSITY;
|
data->squared ? SV_SQR_VOLTAGE_DENSITY : SV_VOLTAGE_DENSITY;
|
||||||
else
|
else
|
||||||
fixme_inoise_type =
|
fixme_inoise_type =
|
||||||
data->squared ? SV_SQR_CURRENT_DENSITY : SV_CURRENT_DENSITY;
|
data->squared ? SV_SQR_CURRENT_DENSITY : SV_CURRENT_DENSITY;
|
||||||
|
|
||||||
fixme_onoise_type =
|
fixme_onoise_type =
|
||||||
data->squared ? SV_SQR_VOLTAGE_DENSITY : SV_VOLTAGE_DENSITY;
|
data->squared ? SV_SQR_VOLTAGE_DENSITY : SV_VOLTAGE_DENSITY;
|
||||||
|
|
@ -176,36 +282,37 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
if (!data->squared)
|
if (!data->squared)
|
||||||
for (i = 0; i < data->numPlots; i++)
|
for (i = 0; i < data->numPlots; i++)
|
||||||
data->squared_value[i] =
|
data->squared_value[i] =
|
||||||
ciprefix("inoise", data->namelist[i]) ||
|
ciprefix("inoise", data->namelist[i]) ||
|
||||||
ciprefix("onoise", data->namelist[i]);
|
ciprefix("onoise", data->namelist[i]);
|
||||||
|
|
||||||
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
error = SPfrontEnd->OUTpBeginPlot(ckt, ckt->CKTcurJob,
|
||||||
data->squared
|
data->squared
|
||||||
? "Noise Spectral Density Curves - (V^2 or A^2)/Hz"
|
? "Noise Spectral Density Curves - (V^2 or A^2)/Hz"
|
||||||
|
|
||||||
: "Noise Spectral Density Curves",
|
: "Noise Spectral Density Curves",
|
||||||
freqUid, IF_REAL,
|
freqUid, IF_REAL,
|
||||||
data->numPlots, data->namelist, IF_REAL,
|
data->numPlots, data->namelist, IF_REAL,
|
||||||
&(data->NplotPtr));
|
&(data->NplotPtr));
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
if (job->NstpType != LINEAR) {
|
if (job->NstpType != LINEAR) {
|
||||||
SPfrontEnd->OUTattributes (data->NplotPtr, NULL, OUT_SCALE_LOG, NULL);
|
SPfrontEnd->OUTattributes(data->NplotPtr, NULL, OUT_SCALE_LOG, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { /* we must have paused before. pick up where we left off */
|
}
|
||||||
|
else { /* we must have paused before. pick up where we left off */
|
||||||
step = (int)(job->NsavFstp);
|
step = (int)(job->NsavFstp);
|
||||||
switch (job->NstpType) {
|
switch (job->NstpType) {
|
||||||
|
|
||||||
case DECADE:
|
case DECADE:
|
||||||
case OCTAVE:
|
case OCTAVE:
|
||||||
data->freq = job->NstartFreq * exp (step *
|
data->freq = job->NstartFreq * exp(step *
|
||||||
log (job->NfreqDelta));
|
log(job->NfreqDelta));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LINEAR:
|
case LINEAR:
|
||||||
data->freq = job->NstartFreq + step *
|
data->freq = job->NstartFreq + step *
|
||||||
job->NfreqDelta;
|
job->NfreqDelta;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -216,11 +323,11 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
data->outNoiz = job->NsavOnoise;
|
data->outNoiz = job->NsavOnoise;
|
||||||
data->inNoise = job->NsavInoise;
|
data->inNoise = job->NsavInoise;
|
||||||
/* saj resume rawfile fix*/
|
/* saj resume rawfile fix*/
|
||||||
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
|
error = SPfrontEnd->OUTpBeginPlot(NULL, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
666, NULL, 666,
|
666, NULL, 666,
|
||||||
&(data->NplotPtr));
|
&(data->NplotPtr));
|
||||||
/*saj*/
|
/*saj*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,10 +345,22 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
|
|
||||||
data->lstFreq = data->freq;
|
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 */
|
/* do the noise analysis over all frequencies */
|
||||||
|
|
||||||
while (data->freq <= job->NstopFreq + freqTol) {
|
while (data->freq <= job->NstopFreq + freqTol) {
|
||||||
if(SPfrontEnd->IFpauseTest()) {
|
if (SPfrontEnd->IFpauseTest()) {
|
||||||
job->NsavFstp = step; /* save our results */
|
job->NsavFstp = step; /* save our results */
|
||||||
job->NsavOnoise = data->outNoiz; /* up until now */
|
job->NsavOnoise = data->outNoiz; /* up until now */
|
||||||
job->NsavInoise = data->inNoise;
|
job->NsavInoise = data->inNoise;
|
||||||
|
|
@ -257,12 +376,12 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NIacIter(ckt);
|
NIacIter(ckt);
|
||||||
realVal = ckt->CKTrhsOld [posOutNode]
|
realVal = ckt->CKTrhsOld[posOutNode]
|
||||||
- ckt->CKTrhsOld [negOutNode];
|
- ckt->CKTrhsOld[negOutNode];
|
||||||
imagVal = ckt->CKTirhsOld [posOutNode]
|
imagVal = ckt->CKTirhsOld[posOutNode]
|
||||||
- ckt->CKTirhsOld [negOutNode];
|
- ckt->CKTirhsOld[negOutNode];
|
||||||
data->GainSqInv = 1.0 / MAX(((realVal*realVal)
|
data->GainSqInv = 1.0 / MAX(((realVal * realVal)
|
||||||
+ (imagVal*imagVal)),N_MINGAIN);
|
+ (imagVal * imagVal)), N_MINGAIN);
|
||||||
data->lnGainInv = log(data->GainSqInv);
|
data->lnGainInv = log(data->GainSqInv);
|
||||||
|
|
||||||
/* set up a block of "common" data so we don't have to
|
/* set up a block of "common" data so we don't have to
|
||||||
|
|
@ -270,13 +389,14 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
data->delFreq = data->freq - data->lstFreq;
|
data->delFreq = data->freq - data->lstFreq;
|
||||||
data->lnFreq = log(MAX(data->freq,N_MINLOG));
|
data->lnFreq = log(MAX(data->freq, N_MINLOG));
|
||||||
data->lnLastFreq = log(MAX(data->lstFreq,N_MINLOG));
|
data->lnLastFreq = log(MAX(data->lstFreq, N_MINLOG));
|
||||||
data->delLnFreq = data->lnFreq - data->lnLastFreq;
|
data->delLnFreq = data->lnFreq - data->lnLastFreq;
|
||||||
|
|
||||||
if ((job->NStpsSm != 0) && ((step % (job->NStpsSm)) == 0)) {
|
if ((job->NStpsSm != 0) && ((step % (job->NStpsSm)) == 0)) {
|
||||||
data->prtSummary = TRUE;
|
data->prtSummary = TRUE;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
data->prtSummary = FALSE;
|
data->prtSummary = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,13 +409,13 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
* it will be given in refVal.rValue (see later)
|
* it will be given in refVal.rValue (see later)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NInzIter(ckt,posOutNode,negOutNode); /* solve the adjoint system */
|
NInzIter(ckt, posOutNode, negOutNode); /* solve the adjoint system */
|
||||||
|
|
||||||
/* now we use the adjoint system to calculate the noise
|
/* now we use the adjoint system to calculate the noise
|
||||||
* contributions of each generator in the circuit
|
* contributions of each generator in the circuit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
error = CKTnoise(ckt,N_DENS,N_CALC,data);
|
error = CKTnoise(ckt, N_DENS, N_CALC, data);
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
data->lstFreq = data->freq;
|
data->lstFreq = data->freq;
|
||||||
|
|
||||||
|
|
@ -321,23 +441,23 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = CKTnoise(ckt,N_DENS,N_CLOSE,data);
|
error = CKTnoise(ckt, N_DENS, N_CLOSE, data);
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
data->numPlots = 0;
|
data->numPlots = 0;
|
||||||
data->outNumber = 0;
|
data->outNumber = 0;
|
||||||
|
|
||||||
if (job->NstartFreq != job->NstopFreq) {
|
if (job->NstartFreq != job->NstopFreq) {
|
||||||
error = CKTnoise(ckt,INT_NOIZ,N_OPEN,data);
|
error = CKTnoise(ckt, INT_NOIZ, N_OPEN, data);
|
||||||
|
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
if (src_type == SV_VOLTAGE)
|
if (src_type == SV_VOLTAGE)
|
||||||
fixme_inoise_type =
|
fixme_inoise_type =
|
||||||
data->squared ? SV_SQR_VOLTAGE : SV_VOLTAGE;
|
data->squared ? SV_SQR_VOLTAGE : SV_VOLTAGE;
|
||||||
else
|
else
|
||||||
fixme_inoise_type =
|
fixme_inoise_type =
|
||||||
data->squared ? SV_SQR_CURRENT : SV_CURRENT;
|
data->squared ? SV_SQR_CURRENT : SV_CURRENT;
|
||||||
|
|
||||||
fixme_onoise_type =
|
fixme_onoise_type =
|
||||||
data->squared ? SV_SQR_VOLTAGE : SV_VOLTAGE;
|
data->squared ? SV_SQR_VOLTAGE : SV_VOLTAGE;
|
||||||
|
|
@ -345,21 +465,21 @@ NOISEan (CKTcircuit *ckt, int restart)
|
||||||
if (!data->squared)
|
if (!data->squared)
|
||||||
for (i = 0; i < data->numPlots; i++)
|
for (i = 0; i < data->numPlots; i++)
|
||||||
data->squared_value[i] =
|
data->squared_value[i] =
|
||||||
ciprefix("inoise", data->namelist[i]) ||
|
ciprefix("inoise", data->namelist[i]) ||
|
||||||
ciprefix("onoise", data->namelist[i]);
|
ciprefix("onoise", data->namelist[i]);
|
||||||
|
|
||||||
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
|
SPfrontEnd->OUTpBeginPlot(ckt, ckt->CKTcurJob,
|
||||||
data->squared
|
data->squared
|
||||||
? "Integrated Noise - V^2 or A^2"
|
? "Integrated Noise - V^2 or A^2"
|
||||||
: "Integrated Noise",
|
: "Integrated Noise",
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
data->numPlots, data->namelist, IF_REAL,
|
data->numPlots, data->namelist, IF_REAL,
|
||||||
&(data->NplotPtr));
|
&(data->NplotPtr));
|
||||||
|
|
||||||
error = CKTnoise(ckt,INT_NOIZ,N_CALC,data);
|
error = CKTnoise(ckt, INT_NOIZ, N_CALC, data);
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
|
|
||||||
error = CKTnoise(ckt,INT_NOIZ,N_CLOSE,data);
|
error = CKTnoise(ckt, INT_NOIZ, N_CLOSE, data);
|
||||||
if (error) return(error);
|
if (error) return(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -487,11 +487,16 @@ VBICsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((model->VBICthermalResistGiven) && (model->VBICthermalResist > 0.0)
|
if(model->VBICselftGiven)
|
||||||
&& model->VBICselftGiven && model->VBICselft == 1)
|
if(model->VBICselft == 1)
|
||||||
here->VBIC_selfheat = 1;
|
here->VBIC_selfheat = 1;
|
||||||
|
else
|
||||||
|
here->VBIC_selfheat = 0;
|
||||||
else
|
else
|
||||||
here->VBIC_selfheat = 0;
|
if((model->VBICthermalResistGiven) && (model->VBICthermalResist > 0.0))
|
||||||
|
here->VBIC_selfheat = 1;
|
||||||
|
else
|
||||||
|
here->VBIC_selfheat = 0;
|
||||||
|
|
||||||
if((model->VBICthermalResistGiven) && (model->VBICthermalCapacitance < 1e-12))
|
if((model->VBICthermalResistGiven) && (model->VBICthermalCapacitance < 1e-12))
|
||||||
model->VBICthermalCapacitance = 1e-12;
|
model->VBICthermalCapacitance = 1e-12;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ VBICsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
|
||||||
if (vsub > model->VBICvsubMax)
|
if (vsub > model->VBICvsubMax)
|
||||||
if (warns_vsub < maxwarns) {
|
if (warns_vsub < maxwarns) {
|
||||||
soa_printf(ckt, (GENinstance*)here,
|
soa_printf(ckt, (GENinstance*)here,
|
||||||
"|Vce|=%g has exceeded Vce_max=%g\n",
|
"|Vcs|=%g has exceeded Vcs_max=%g\n",
|
||||||
vsub, model->VBICvsubMax);
|
vsub, model->VBICvsubMax);
|
||||||
warns_vsub++;
|
warns_vsub++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue