|
|
|
@ -13,7 +13,7 @@ Modified 2001: AlansFixes |
|
|
|
#ifdef XSPICE |
|
|
|
#include "ngspice/evt.h" |
|
|
|
#include "ngspice/enh.h" |
|
|
|
/* gtri - add - wbk - 12/19/90 - Add headers */ |
|
|
|
/* gtri - add - wbk - 12/19/90 - Add headers */ |
|
|
|
#include "ngspice/mif.h" |
|
|
|
#include "ngspice/evtproto.h" |
|
|
|
#include "ngspice/ipctiein.h" |
|
|
|
@ -42,9 +42,9 @@ do { \ |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
ACan(CKTcircuit *ckt, int restart) |
|
|
|
ACan(CKTcircuit* ckt, int restart) |
|
|
|
{ |
|
|
|
ACAN *job = (ACAN *) ckt->CKTcurJob; |
|
|
|
ACAN* job = (ACAN*)ckt->CKTcurJob; |
|
|
|
|
|
|
|
double freq; |
|
|
|
double freqTol; /* tolerence parameter for finding final frequency */ |
|
|
|
@ -55,23 +55,23 @@ ACan(CKTcircuit *ckt, int restart) |
|
|
|
double startTime; |
|
|
|
int error; |
|
|
|
int numNames; |
|
|
|
IFuid *nameList; /* va: tmalloc'ed list of names */ |
|
|
|
IFuid* nameList; /* va: tmalloc'ed list of names */ |
|
|
|
IFuid freqUid; |
|
|
|
static runDesc *acPlot = NULL; |
|
|
|
runDesc *plot = NULL; |
|
|
|
static runDesc* acPlot = NULL; |
|
|
|
runDesc* plot = NULL; |
|
|
|
|
|
|
|
|
|
|
|
#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; |
|
|
|
|
|
|
|
/* 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 */ |
|
|
|
/* gtri - end - wbk */ |
|
|
|
#endif |
|
|
|
|
|
|
|
/* start at beginning */ |
|
|
|
@ -86,8 +86,8 @@ ACan(CKTcircuit *ckt, int restart) |
|
|
|
fprintf(stderr, "ERROR: AC startfreq <= 0\n"); |
|
|
|
return E_PARMVAL; |
|
|
|
} |
|
|
|
double num_steps = floor(fabs(log10(job->ACstopFreq/job->ACstartFreq))*job->ACnumberSteps); |
|
|
|
job->ACfreqDelta = exp((log(job->ACstopFreq/job->ACstartFreq))/ num_steps); |
|
|
|
double num_steps = floor(fabs(log10(job->ACstopFreq / job->ACstartFreq)) * job->ACnumberSteps); |
|
|
|
job->ACfreqDelta = exp((log(job->ACstopFreq / job->ACstartFreq)) / num_steps); |
|
|
|
|
|
|
|
break; |
|
|
|
case OCTAVE: |
|
|
|
@ -96,133 +96,134 @@ ACan(CKTcircuit *ckt, int restart) |
|
|
|
return E_PARMVAL; |
|
|
|
} |
|
|
|
job->ACfreqDelta = |
|
|
|
exp(log(2.0)/job->ACnumberSteps); |
|
|
|
exp(log(2.0) / job->ACnumberSteps); |
|
|
|
break; |
|
|
|
case LINEAR: |
|
|
|
if (job->ACnumberSteps-1 > 1) |
|
|
|
if (job->ACnumberSteps - 1 > 1) |
|
|
|
job->ACfreqDelta = |
|
|
|
(job->ACstopFreq - |
|
|
|
job->ACstartFreq) / |
|
|
|
(job->ACnumberSteps - 1); |
|
|
|
(job->ACstopFreq - |
|
|
|
job->ACstartFreq) / |
|
|
|
(job->ACnumberSteps - 1); |
|
|
|
else |
|
|
|
/* Patch from: Richard McRoberts |
|
|
|
* This patch is for a rather pathological case: |
|
|
|
* a linear step with only one point */ |
|
|
|
/* Patch from: Richard McRoberts |
|
|
|
* This patch is for a rather pathological case: |
|
|
|
* a linear step with only one point */ |
|
|
|
job->ACfreqDelta = 0; |
|
|
|
break; |
|
|
|
default: |
|
|
|
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); |
|
|
|
/* 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 |
|
|
|
fprintf(stdout,"\n Linear circuit, option noopac given: no OP analysis\n"); |
|
|
|
|
|
|
|
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 |
|
|
|
/* 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, |
|
|
|
&acPlot); |
|
|
|
txfree(nameList); |
|
|
|
|
|
|
|
ipc_send_dcop_prefix(); |
|
|
|
CKTdump(ckt, 0.0, acPlot); |
|
|
|
ipc_send_dcop_suffix(); |
|
|
|
|
|
|
|
SPfrontEnd->OUTendPlot (acPlot); |
|
|
|
} |
|
|
|
/* gtri - end - wbk */ |
|
|
|
/* 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, |
|
|
|
&acPlot); |
|
|
|
txfree(nameList); |
|
|
|
|
|
|
|
ipc_send_dcop_prefix(); |
|
|
|
CKTdump(ckt, 0.0, acPlot); |
|
|
|
ipc_send_dcop_suffix(); |
|
|
|
|
|
|
|
SPfrontEnd->OUTendPlot(acPlot); |
|
|
|
} |
|
|
|
/* gtri - end - wbk */ |
|
|
|
#endif |
|
|
|
|
|
|
|
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, |
|
|
|
"AC Operating Point", |
|
|
|
NULL, IF_REAL, |
|
|
|
numNames, nameList, IF_REAL, |
|
|
|
&plot); |
|
|
|
if(error) return(error); |
|
|
|
CKTdump(ckt, 0.0, plot); |
|
|
|
SPfrontEnd->OUTendPlot (plot); |
|
|
|
plot = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL); |
|
|
|
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob, |
|
|
|
ckt->CKTcurJob->JOBname, |
|
|
|
freqUid, IF_REAL, |
|
|
|
numNames, nameList, IF_COMPLEX, |
|
|
|
&acPlot); |
|
|
|
tfree(nameList); |
|
|
|
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, |
|
|
|
"AC Operating Point", |
|
|
|
NULL, IF_REAL, |
|
|
|
numNames, nameList, IF_REAL, |
|
|
|
&plot); |
|
|
|
if (error) return(error); |
|
|
|
CKTdump(ckt, 0.0, plot); |
|
|
|
SPfrontEnd->OUTendPlot(plot); |
|
|
|
plot = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
SPfrontEnd->IFnewUid(ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL); |
|
|
|
error = SPfrontEnd->OUTpBeginPlot(ckt, ckt->CKTcurJob, |
|
|
|
ckt->CKTcurJob->JOBname, |
|
|
|
freqUid, IF_REAL, |
|
|
|
numNames, nameList, IF_COMPLEX, |
|
|
|
&acPlot); |
|
|
|
tfree(nameList); |
|
|
|
if (error) return(error); |
|
|
|
|
|
|
|
if (job->ACstepType != LINEAR) { |
|
|
|
SPfrontEnd->OUTattributes (acPlot, NULL, OUT_SCALE_LOG, NULL); |
|
|
|
} |
|
|
|
SPfrontEnd->OUTattributes(acPlot, NULL, OUT_SCALE_LOG, NULL); |
|
|
|
} |
|
|
|
freq = job->ACstartFreq; |
|
|
|
|
|
|
|
} else { /* continue previous analysis */ |
|
|
|
} |
|
|
|
else { /* continue previous analysis */ |
|
|
|
freq = job->ACsaveFreq; |
|
|
|
job->ACsaveFreq = 0; /* clear the 'old' frequency */ |
|
|
|
/* fix resume? saj, indeed !*/ |
|
|
|
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL, |
|
|
|
NULL, |
|
|
|
NULL, 0, |
|
|
|
666, NULL, 666, |
|
|
|
&acPlot); |
|
|
|
/* saj*/ |
|
|
|
/* fix resume? saj, indeed !*/ |
|
|
|
error = SPfrontEnd->OUTpBeginPlot(NULL, NULL, |
|
|
|
NULL, |
|
|
|
NULL, 0, |
|
|
|
666, NULL, 666, |
|
|
|
&acPlot); |
|
|
|
/* saj*/ |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
switch (job->ACstepType) { |
|
|
|
case DECADE: |
|
|
|
case OCTAVE: |
|
|
|
@ -238,14 +239,14 @@ ACan(CKTcircuit *ckt, int restart) |
|
|
|
|
|
|
|
|
|
|
|
#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; |
|
|
|
|
|
|
|
/* Tell the code models what mode we're in */ |
|
|
|
g_mif_info.circuit.anal_type = MIF_AC; |
|
|
|
|
|
|
|
/* gtri - end - wbk */ |
|
|
|
/* gtri - end - wbk */ |
|
|
|
#endif |
|
|
|
|
|
|
|
INIT_STATS(); |
|
|
|
@ -254,19 +255,19 @@ ACan(CKTcircuit *ckt, int restart) |
|
|
|
|
|
|
|
/* main loop through all scheduled frequencies */ |
|
|
|
while (freq <= job->ACstopFreq + freqTol) { |
|
|
|
if(SPfrontEnd->IFpauseTest()) { |
|
|
|
if (SPfrontEnd->IFpauseTest()) { |
|
|
|
/* user asked us to pause via an interrupt */ |
|
|
|
job->ACsaveFreq = freq; |
|
|
|
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 */ |
|
|
|
if (ckt->CKTvarHertz) { |
|
|
|
#ifdef XSPICE |
|
|
|
/* Call EVTop if event-driven instances exist */ |
|
|
|
|
|
|
|
if(ckt->evt->counts.num_insts != 0) { |
|
|
|
if (ckt->evt->counts.num_insts != 0) { |
|
|
|
error = EVTop(ckt, |
|
|
|
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, |
|
|
|
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, |
|
|
|
@ -275,25 +276,25 @@ ACan(CKTcircuit *ckt, int restart) |
|
|
|
EVTdump(ckt, IPC_ANAL_DCOP, 0.0); |
|
|
|
EVTop_save(ckt, MIF_TRUE, 0.0); |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
#endif |
|
|
|
// If no event-driven instances, do what SPICE normally does |
|
|
|
// If no event-driven instances, do what SPICE normally does |
|
|
|
error = CKTop(ckt, |
|
|
|
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, |
|
|
|
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, |
|
|
|
ckt->CKTdcMaxIter); |
|
|
|
|
|
|
|
if(error){ |
|
|
|
fprintf(stdout,"\nAC operating point failed -\n"); |
|
|
|
if (error) { |
|
|
|
fprintf(stdout, "\nAC operating point failed -\n"); |
|
|
|
CKTncDump(ckt); |
|
|
|
return(error); |
|
|
|
} |
|
|
|
} |
|
|
|
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; |
|
|
|
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); |
|
|
|
if (error) { |
|
|
|
UPDATE_STATS(DOING_AC); |
|
|
|
@ -301,18 +302,18 @@ ACan(CKTcircuit *ckt, int restart) |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef WANT_SENSE2 |
|
|
|
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&ACSEN) ){ |
|
|
|
if (ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & ACSEN)) { |
|
|
|
long save; |
|
|
|
int save1; |
|
|
|
|
|
|
|
save = ckt->CKTmode; |
|
|
|
ckt->CKTmode=(ckt->CKTmode&MODEUIC)|MODEDCOP|MODEINITSMSIG; |
|
|
|
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; |
|
|
|
save1 = ckt->CKTsenInfo->SENmode; |
|
|
|
ckt->CKTsenInfo->SENmode = ACSEN; |
|
|
|
if (freq == job->ACstartFreq) { |
|
|
|
ckt->CKTsenInfo->SENacpertflag = 1; |
|
|
|
} |
|
|
|
else{ |
|
|
|
else { |
|
|
|
ckt->CKTsenInfo->SENacpertflag = 0; |
|
|
|
} |
|
|
|
error = CKTsenAC(ckt); |
|
|
|
@ -324,24 +325,24 @@ ACan(CKTcircuit *ckt, int restart) |
|
|
|
#endif |
|
|
|
|
|
|
|
#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); |
|
|
|
|
|
|
|
error = CKTacDump(ckt,freq,acPlot); |
|
|
|
error = CKTacDump(ckt, freq, acPlot); |
|
|
|
|
|
|
|
if(g_ipc.enabled) |
|
|
|
if (g_ipc.enabled) |
|
|
|
ipc_send_data_suffix(); |
|
|
|
|
|
|
|
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ |
|
|
|
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ |
|
|
|
#else |
|
|
|
error = CKTacDump(ckt,freq,acPlot); |
|
|
|
error = CKTacDump(ckt, freq, acPlot); |
|
|
|
#endif |
|
|
|
if (error) { |
|
|
|
UPDATE_STATS(DOING_AC); |
|
|
|
return(error); |
|
|
|
} |
|
|
|
UPDATE_STATS(DOING_AC); |
|
|
|
return(error); |
|
|
|
} |
|
|
|
|
|
|
|
/* increment frequency */ |
|
|
|
|
|
|
|
@ -349,90 +350,90 @@ ACan(CKTcircuit *ckt, int restart) |
|
|
|
case DECADE: |
|
|
|
case OCTAVE: |
|
|
|
|
|
|
|
/* inserted again 14.12.2001 */ |
|
|
|
/* inserted again 14.12.2001 */ |
|
|
|
#ifdef HAS_PROGREP |
|
|
|
{ |
|
|
|
double endfreq = job->ACstopFreq; |
|
|
|
double startfreq = job->ACstartFreq; |
|
|
|
endfreq = log(endfreq); |
|
|
|
if (startfreq == 0.0) |
|
|
|
startfreq = 1e-12; |
|
|
|
startfreq = log(startfreq); |
|
|
|
|
|
|
|
if (freq > 0.0) |
|
|
|
SetAnalyse( "ac", (int)((log(freq)-startfreq) * 1000.0 / (endfreq-startfreq))); |
|
|
|
} |
|
|
|
{ |
|
|
|
double endfreq = job->ACstopFreq; |
|
|
|
double startfreq = job->ACstartFreq; |
|
|
|
endfreq = log(endfreq); |
|
|
|
if (startfreq == 0.0) |
|
|
|
startfreq = 1e-12; |
|
|
|
startfreq = log(startfreq); |
|
|
|
|
|
|
|
if (freq > 0.0) |
|
|
|
SetAnalyse("ac", (int)((log(freq) - startfreq) * 1000.0 / (endfreq - startfreq))); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
freq *= job->ACfreqDelta; |
|
|
|
if (job->ACfreqDelta == 1) goto endsweep; |
|
|
|
freq *= job->ACfreqDelta; |
|
|
|
if (job->ACfreqDelta == 1) goto endsweep; |
|
|
|
break; |
|
|
|
case LINEAR: |
|
|
|
|
|
|
|
#ifdef HAS_PROGREP |
|
|
|
{ |
|
|
|
double endfreq = job->ACstopFreq; |
|
|
|
double startfreq = job->ACstartFreq; |
|
|
|
SetAnalyse( "ac", (int)((freq - startfreq)* 1000.0 / (endfreq-startfreq))); |
|
|
|
} |
|
|
|
{ |
|
|
|
double endfreq = job->ACstopFreq; |
|
|
|
double startfreq = job->ACstartFreq; |
|
|
|
SetAnalyse("ac", (int)((freq - startfreq) * 1000.0 / (endfreq - startfreq))); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
freq += job->ACfreqDelta; |
|
|
|
if (job->ACfreqDelta == 0) goto endsweep; |
|
|
|
break; |
|
|
|
freq += job->ACfreqDelta; |
|
|
|
if (job->ACfreqDelta == 0) goto endsweep; |
|
|
|
break; |
|
|
|
default: |
|
|
|
return(E_INTERN); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
endsweep: |
|
|
|
SPfrontEnd->OUTendPlot (acPlot); |
|
|
|
SPfrontEnd->OUTendPlot(acPlot); |
|
|
|
acPlot = NULL; |
|
|
|
UPDATE_STATS(0); |
|
|
|
return(0); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* CKTacLoad(ckt) |
|
|
|
* this is a driver program to iterate through all the various |
|
|
|
* ac load functions provided for the circuit elements in the |
|
|
|
* given circuit |
|
|
|
*/ |
|
|
|
/* CKTacLoad(ckt) |
|
|
|
* this is a driver program to iterate through all the various |
|
|
|
* ac load functions provided for the circuit elements in the |
|
|
|
* given circuit |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
CKTacLoad(CKTcircuit *ckt) |
|
|
|
CKTacLoad(CKTcircuit* ckt) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int size; |
|
|
|
int error; |
|
|
|
double startTime; |
|
|
|
|
|
|
|
startTime = SPfrontEnd->IFseconds(); |
|
|
|
startTime = SPfrontEnd->IFseconds(); |
|
|
|
size = SMPmatSize(ckt->CKTmatrix); |
|
|
|
for (i=0;i<=size;i++) { |
|
|
|
ckt->CKTrhs[i]=0; |
|
|
|
ckt->CKTirhs[i]=0; |
|
|
|
for (i = 0; i <= size; i++) { |
|
|
|
ckt->CKTrhs[i] = 0; |
|
|
|
ckt->CKTirhs[i] = 0; |
|
|
|
} |
|
|
|
SMPcClear(ckt->CKTmatrix); |
|
|
|
|
|
|
|
for (i=0;i<DEVmaxnum;i++) { |
|
|
|
if ( DEVices[i] && DEVices[i]->DEVacLoad && ckt->CKThead[i] ) { |
|
|
|
error = DEVices[i]->DEVacLoad (ckt->CKThead[i], ckt); |
|
|
|
if(error) return(error); |
|
|
|
for (i = 0; i < DEVmaxnum; i++) { |
|
|
|
if (DEVices[i] && DEVices[i]->DEVacLoad && ckt->CKThead[i]) { |
|
|
|
error = DEVices[i]->DEVacLoad(ckt->CKThead[i], ckt); |
|
|
|
if (error) return(error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifdef XSPICE |
|
|
|
/* gtri - begin - Put resistors to ground at all nodes. */ |
|
|
|
/* Value of resistor is set by new "rshunt" option. */ |
|
|
|
|
|
|
|
if(ckt->enh->rshunt_data.enabled) { |
|
|
|
for(i = 0; i < ckt->enh->rshunt_data.num_nodes; i++) { |
|
|
|
*(ckt->enh->rshunt_data.diag[i]) += |
|
|
|
ckt->enh->rshunt_data.gshunt; |
|
|
|
} |
|
|
|
/* gtri - begin - Put resistors to ground at all nodes. */ |
|
|
|
/* Value of resistor is set by new "rshunt" option. */ |
|
|
|
|
|
|
|
if (ckt->enh->rshunt_data.enabled) { |
|
|
|
for (i = 0; i < ckt->enh->rshunt_data.num_nodes; i++) { |
|
|
|
*(ckt->enh->rshunt_data.diag[i]) += |
|
|
|
ckt->enh->rshunt_data.gshunt; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* gtri - end - Put resistors to ground at all nodes */ |
|
|
|
@ -451,7 +452,7 @@ CKTacLoad(CKTcircuit *ckt) |
|
|
|
/* gtri - end - wbk - 11/26/90 */ |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime; |
|
|
|
return(OK); |
|
|
|
} |