1 /**********
2 Copyright 1990 Regents of the University of California. All rights reserved.
3 Author: 1985 Thomas L. Quarles
4 Modified: 2000 AlansFixes
5 **********/
6
7 #include "ngspice/ngspice.h"
8 #include "ngspice/cktdefs.h"
9 #include "ngspice/sperror.h"
10 #include "ngspice/trandefs.h"
11 #include "ngspice/cpextern.h"
12 #include "ngspice/fteext.h"
13
14 #include "analysis.h"
15
16 #ifdef XSPICE
17 /* gtri - add - wbk - 11/26/90 - add include for MIF and EVT global data */
18 #include "ngspice/mif.h"
19 #include "ngspice/evtproto.h"
20 /* gtri - end - wbk - 11/26/90 */
21 /* gtri - add - 12/12/90 - wbk - include ipc stuff */
22 #include "ngspice/ipctiein.h"
23 /* gtri - end - 12/12/90 */
24 #endif
25
26 extern SPICEanalysis *analInfo[];
27
28 int
CKTdoJob(CKTcircuit * ckt,int reset,TSKtask * task)29 CKTdoJob(CKTcircuit *ckt, int reset, TSKtask *task)
30 {
31 JOB *job;
32 double startTime;
33 int error, i, error2;
34
35 int ANALmaxnum = spice_num_analysis();
36
37 #ifdef WANT_SENSE2
38 int senflag;
39 static int sens_num = -1;
40
41 /* Sensitivity is special */
42 if (sens_num < 0) {
43 for (i = 0; i < ANALmaxnum; i++)
44 if (!strcmp("SENS2", analInfo[i]->if_analysis.name))
45 break;
46 sens_num = i;
47 }
48 #endif
49
50 startTime = SPfrontEnd->IFseconds();
51
52 ckt->CKTtemp = task->TSKtemp;
53 ckt->CKTnomTemp = task->TSKnomTemp;
54 ckt->CKTmaxOrder = task->TSKmaxOrder;
55 ckt->CKTintegrateMethod = task->TSKintegrateMethod;
56 ckt->CKTindverbosity = task->TSKindverbosity;
57 ckt->CKTxmu = task->TSKxmu;
58 ckt->CKTbypass = task->TSKbypass;
59 ckt->CKTdcMaxIter = task->TSKdcMaxIter;
60 ckt->CKTdcTrcvMaxIter = task->TSKdcTrcvMaxIter;
61 ckt->CKTtranMaxIter = task->TSKtranMaxIter;
62 ckt->CKTnumSrcSteps = task->TSKnumSrcSteps;
63 ckt->CKTnumGminSteps = task->TSKnumGminSteps;
64 ckt->CKTgminFactor = task->TSKgminFactor;
65 ckt->CKTminBreak = task->TSKminBreak;
66 ckt->CKTabstol = task->TSKabstol;
67 ckt->CKTpivotAbsTol = task->TSKpivotAbsTol;
68 ckt->CKTpivotRelTol = task->TSKpivotRelTol;
69 ckt->CKTreltol = task->TSKreltol;
70 ckt->CKTchgtol = task->TSKchgtol;
71 ckt->CKTvoltTol = task->TSKvoltTol;
72 ckt->CKTgmin = task->TSKgmin;
73 ckt->CKTgshunt = task->TSKgshunt;
74 ckt->CKTcshunt = task->TSKcshunt;
75 ckt->CKTdelmin = task->TSKdelmin;
76 ckt->CKTtrtol = task->TSKtrtol;
77 #ifdef XSPICE
78 /* Lower value of trtol to give smaller stepsize and more accuracy,
79 but only if there are 'A' devices in the circuit,
80 may be overridden by 'set xtrtol=newval' */
81 if (ckt->CKTadevFlag && (ckt->CKTtrtol > 1)) {
82 int newtol;
83 if (cp_getvar("xtrtol", CP_NUM, &newtol, 0)) {
84 printf("Override trtol to %d for xspice 'A' devices\n", newtol);
85 ckt->CKTtrtol = newtol;
86 }
87 else {
88 printf("Reducing trtol to 1 for xspice 'A' devices\n");
89 ckt->CKTtrtol = 1;
90 }
91 }
92 #endif
93 ckt->CKTdefaultMosM = task->TSKdefaultMosM;
94 ckt->CKTdefaultMosL = task->TSKdefaultMosL;
95 ckt->CKTdefaultMosW = task->TSKdefaultMosW;
96 ckt->CKTdefaultMosAD = task->TSKdefaultMosAD;
97 ckt->CKTdefaultMosAS = task->TSKdefaultMosAS;
98 ckt->CKTfixLimit = task->TSKfixLimit;
99 ckt->CKTnoOpIter = task->TSKnoOpIter;
100 ckt->CKTtryToCompact = task->TSKtryToCompact;
101 ckt->CKTbadMos3 = task->TSKbadMos3;
102 ckt->CKTkeepOpInfo = task->TSKkeepOpInfo;
103 ckt->CKTcopyNodesets = task->TSKcopyNodesets;
104 ckt->CKTnodeDamping = task->TSKnodeDamping;
105 ckt->CKTabsDv = task->TSKabsDv;
106 ckt->CKTrelDv = task->TSKrelDv;
107 ckt->CKTtroubleNode = 0;
108 ckt->CKTtroubleElt = NULL;
109 ckt->CKTnoopac = task->TSKnoopac && ckt->CKTisLinear;
110 ckt->CKTepsmin = task->TSKepsmin;
111 #ifdef NEWTRUNC
112 ckt->CKTlteReltol = task->TSKlteReltol;
113 ckt->CKTlteAbstol = task->TSKlteAbstol;
114 #endif /* NEWTRUNC */
115
116 fprintf(stdout, "Doing analysis at TEMP = %f and TNOM = %f\n\n",
117 ckt->CKTtemp - CONSTCtoK, ckt->CKTnomTemp - CONSTCtoK);
118
119 /* call altermod and alter on device and model parameters assembled in
120 devtlist and modtlist (if using temper) because we have a new temperature */
121 inp_evaluate_temper(ft_curckt);
122
123 error = 0;
124
125 if (reset) {
126
127 ckt->CKTdelta = 0.0;
128 ckt->CKTtime = 0.0;
129 ckt->CKTcurrentAnalysis = 0;
130
131 #ifdef WANT_SENSE2
132 senflag = 0;
133 if (sens_num < ANALmaxnum)
134 for (job = task->jobs; !error && job; job = job->JOBnextJob) {
135 if (job->JOBtype == sens_num) {
136 senflag = 1;
137 ckt->CKTcurJob = job;
138 ckt->CKTsenInfo = (SENstruct *) job;
139 error = analInfo[sens_num]->an_func (ckt, reset);
140 }
141 }
142
143 if (ckt->CKTsenInfo && (!senflag || error))
144 FREE(ckt->CKTsenInfo);
145 #endif
146
147 /* make sure this is either up do date or NULL */
148 ckt->CKTcurJob = NULL;
149
150 /* normal reset */
151 if (!error)
152 error = CKTunsetup(ckt);
153
154 #ifdef XSPICE
155 /* gtri - add - 12/12/90 - wbk - set ipc syntax error flag */
156 if(error) g_ipc.syntax_error = IPC_TRUE;
157 /* gtri - end - 12/12/90 */
158 #endif
159
160 if (!error)
161 error = CKTsetup(ckt);
162
163 #ifdef XSPICE
164 /* gtri - add - 12/12/90 - wbk - set ipc syntax error flag */
165 if(error) g_ipc.syntax_error = IPC_TRUE;
166 /* gtri - end - 12/12/90 */
167 #endif
168
169 if (!error)
170 error = CKTtemp(ckt);
171
172 #ifdef XSPICE
173 /* gtri - add - 12/12/90 - wbk - set ipc syntax error flag */
174 if(error) g_ipc.syntax_error = IPC_TRUE;
175 /* gtri - end - 12/12/90 */
176 #endif
177
178 if (error) {
179
180 #ifdef XSPICE
181 /* gtri - add - 12/12/90 - wbk - return if syntax errors from parsing */
182 if(g_ipc.enabled) {
183 if(g_ipc.syntax_error)
184 ;
185 else {
186 /* else, send (GO) errchk status if we got this far */
187 /* Caller is responsible for sending NOGO status if we returned earlier */
188 ipc_send_errchk();
189 }
190 }
191 /* gtri - end - 12/12/90 */
192 #endif
193
194
195 return error;
196
197
198 }/* if error */
199 }
200
201 error2 = OK;
202
203 /* Analysis order is important */
204 for (i = 0; i < ANALmaxnum; i++) {
205
206 #ifdef WANT_SENSE2
207 if (i == sens_num)
208 continue;
209 #endif
210
211 for (job = task->jobs; job; job = job->JOBnextJob) {
212 if (job->JOBtype == i) {
213 ckt->CKTcurJob=job;
214 error = OK;
215 if (analInfo[i]->an_init)
216 error = analInfo[i]->an_init (ckt, job);
217 if (!error && analInfo[i]->do_ic)
218 error = CKTic(ckt);
219 if (!error){
220 #ifdef XSPICE
221 if(reset) {
222 /* gtri - begin - 6/10/91 - wbk - Setup event-driven data */
223 error = EVTsetup(ckt);
224 if(error) {
225 ckt->CKTstat->STATtotAnalTime +=
226 SPfrontEnd->IFseconds() - startTime;
227 return(error);
228 }
229 /* gtri - end - 6/10/91 - wbk - Setup event-driven data */
230 }
231 #endif
232 error = analInfo[i]->an_func (ckt, reset);
233 /* txl, cpl addition */
234 if (error == 1111) break;
235 }
236 if (error)
237 error2 = error;
238 }
239 }
240 }
241
242 ckt->CKTstat->STATtotAnalTime += SPfrontEnd->IFseconds() - startTime;
243
244 #ifdef WANT_SENSE2
245 if (ckt->CKTsenInfo)
246 SENdestroy(ckt->CKTsenInfo);
247 #endif
248
249 return(error2);
250 }
251
252