1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California.  All rights reserved.
4 Authors: 1985 Thomas L. Quarles
5          1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 #ifndef IFSIMULATOR
9 #define IFSIMULATOR
10 
11 /*
12  * We don't always have access to an ANSI C compiler yet, so we
13  * make the following convenient definition
14  */
15 
16 #ifdef __STDC__
17 
18     /* using an ansi C compiler, so we have the void* construct */
19 
20 typedef void GENERIC;
21 
22 #else
23 
24     /* not using an ansi C compiler, so we have to use char* as the */
25     /* most generic pointer type */
26 
27 typedef char GENERIC;
28 
29 #endif
30 /*
31  * structure:   IFparm
32  *
33  *
34  * The structure used to describe all values passed
35  * between the front end and the simulator when there is any
36  * possibility one argument of the function could have more
37  * than one type.
38  *
39  * keyword is provided for the front end and is the token
40  *    the user is expected to label the data with.
41  *
42  * id is an integer intended to uniquely identify the parameter
43  *    to the simulator
44  *
45  * dataType is an integer which indicates the type of argument
46  *    that must be passed for this parameter
47  *
48  * description is a longer description intended for help menus
49  *    the description should all fit on one line, but should
50  *    give a knowledgable user a good idea what the parameter is
51  *    used for.
52  */
53 
54 typedef struct sIFparm {
55     char *keyword;
56     int id;
57     int dataType;
58     char *description;
59 } IFparm;
60 
61 /*
62  *
63  * datatype: IFuid
64  *
65  * unique identifier for all name-type data in the simulator.
66  * this permits the front end to use something other than
67  * a unique, fully qualified character string to identify
68  * an object.
69  *
70  */
71 
72 typedef GENERIC *IFuid;
73 
74 /*
75  *
76  * types for IFnewUid
77  *
78  */
79 
80 #define UID_ANALYSIS 0x1
81 #define UID_TASK 0x2
82 #define UID_INSTANCE 0x4
83 #define UID_MODEL 0x8
84 #define UID_SIGNAL 0x10
85 #define UID_OTHER 0x20
86 
87 
88 /*
89  * dataType values:
90  *
91  * Note:  These structures are put together by ORing together the
92  *    appropriate bits from the fields below as is shown for the vector
93  *    types.
94  * IF_REQUIRED indicates that the parameter must be specified.
95  *    The front end does not NEED to check for this, but can to save time,
96  *    since failure to do so will cause the simulator to fail.
97  * IF_SET indicates that the specified item is an input parameter.
98  * IF_ASK indicates that the specified item is something the simulator
99  *    can provide information about.
100  * IF_SET and IF_ASK are NOT mutually exclusive.
101  * if IF_SET and IF_ASK are both zero, it indicates a parameter that
102  *    the simulator recoginizes are being a reasonable paremeter, but
103  *    which this simulator does not implement.
104  */
105 
106 #define IF_FLAG 0x1
107 #define IF_INTEGER 0x2
108 #define IF_REAL 0x4
109 #define IF_COMPLEX 0x8
110 #define IF_NODE 0x10
111 #define IF_STRING 0x20
112 #define IF_INSTANCE 0x40
113 #define IF_PARSETREE 0x80
114 
115 /* indicates that for a query the integer field will have a selector
116  * in it to pick a sub-field */
117 #define IF_SELECT 0x800
118 #define IF_VSELECT 0x400
119 
120 /* indicates a vector of the specified type */
121 #define IF_VECTOR 0x8000
122 
123 #define IF_FLAGVEC     (IF_FLAG|IF_VECTOR)
124 #define IF_INTVEC      (IF_INTEGER|IF_VECTOR)
125 #define IF_REALVEC     (IF_REAL|IF_VECTOR)
126 #define IF_CPLXVEC     (IF_COMPLEX|IF_VECTOR)
127 #define IF_NODEVEC     (IF_NODE|IF_VECTOR)
128 #define IF_STRINGVEC   (IF_STRING|IF_VECTOR)
129 #define IF_INSTVEC     (IF_INSTANCE|IF_VECTOR)
130 
131 #define IF_REQUIRED 0x4000
132 
133 #define IF_VARTYPES 0x80ff
134 
135 #define IF_SET 0x2000
136 #define IF_ASK 0x1000
137 
138 /* If you AND with IF_UNIMP_MASK and get 0, it is recognized, but not
139  * implemented
140  */
141 #define IF_UNIMP_MASK 0x3000
142 
143 
144 /* Structure:   IFparseTree
145  *
146  * This structure is returned by the parser for a IF_PARSETREE valued
147  * parameter and describes the information that the simulator needs
148  * to know about the parse tree in order to use it.
149  * It is expected that the front end will have a more extensive
150  * structure which this structure will be a prefix of.
151  *
152  * Note that the function pointers are provided as hooks for
153  * versions which may want to compile code for the parse trees
154  * if they are used heavily.
155  *
156  */
157 
158 typedef struct sIFparseTree {
159     int numVars;            /* number of variables used */
160     int *varTypes;          /* array of types of variables */
161     char *line;             /* the parsed function string */
162     union uIFvalue * vars;  /* array of structures describing values */
163 #ifdef __STDC__
164     int ((*IFinit)(struct sIFparseTree*,double,double));
165     int ((*IFeval)(struct sIFparseTree*,double,double*,double*,
166         double*,double*));
167     void ((*IFfree)(struct sIFparseTree*));
168 #else
169     int ((*IFinit)());      /* function to call to init for run */
170     int ((*IFeval)());      /* function to call to get evaluated */
171     void ((*IFfree)());     /* function to destroy parse tree */
172 #endif /* STDC */
173 } IFparseTree;
174 
175 
176 /*
177  * Structure:    IFvalue
178  *
179  * structure used to pass the values corresponding to the above
180  * dataType.  All types are passed in one of these structures, with
181  * relatively simple rules concerning the handling of the structure.
182  *
183  * whoever makes the subroutine call allocates a single instance of the
184  * structure.  The basic data structure belongs to you, and you
185  * should arrange to free it when appropriate.
186  *
187  * The responsibilities of the data supplier are:
188  * Any vectors referenced by the structure are to be malloc()'d
189  * and are assumed to have been turned over to the recipient and
190  * thus should not be re-used or free()'d.
191  *
192  * The responsibilities of the data recipient are:
193  * scalar valued data is to be copied by the recipient
194  * vector valued data is now the property of the recipient,
195  * and must be free()'d when no longer needed.
196  *
197  * Character strings are a special case:  Since it is assumed
198  * that all character strings are directly descended from input
199  * tokens, it is assumed that they are static, thus nobody
200  * frees them until the circuit is deleted, when the front end
201  * may do so.
202  *
203  * EVERYBODY's responsibility is to be SURE that the right data
204  * is filled in and read out of the structure as per the IFparm
205  * structure describing the parameter being passed.  Programs
206  * neglecting this rule are fated to die of data corruption
207  *
208  */
209 
210 /*
211  * Some preliminary definitions:
212  *
213  * IFnode's are returned by the simulator, thus we don't really
214  * know what they look like, just that we get to carry pointers
215  * to them around all the time, and will need to save them occasionally
216  *
217  */
218 
219 
220 typedef GENERIC * IFnode;
221 
222 /*
223  * and of course, the standard complex data type
224  */
225 typedef struct sIFcomplex {
226     double real;
227     double imag;
228 } IFcomplex;
229 
230 
231 typedef union uIFvalue {
232     int iValue;             /* integer or flag valued data */
233     double rValue;          /* real valued data */
234     IFcomplex cValue;       /* complex valued data */
235     char *sValue;           /* string valued data */
236     IFuid uValue;           /* UID valued data */
237     IFnode nValue;          /* node valued data */
238     IFparseTree *tValue;    /* parse tree */
239     struct {
240         int numValue;       /* length of vector */
241         union {
242             int *iVec;      /* pointer to integer vector */
243             double *rVec;   /* pointer to real vector */
244             IFcomplex *cVec;/* pointer to complex vector */
245             char **sVec;    /* pointer to string vector */
246             IFuid *uVec;    /* pointer to UID vector */
247             IFnode *nVec;   /* pointer to node vector */
248         }vec;
249     }v;
250 } IFvalue;
251 
252 
253 /*
254  * sructure:  IFkeys
255  *
256  * This structure is used in the IFdevice structure below.  Each device
257  * can have multiple implementations, listed in the IFkeys structure.
258  * Each implementation is keyed by the 'key' character in the input
259  * line.  numTerms is the number of nodes in the implementation,
260  * and termNames is a list of terminal names.  numDevs is the number
261  * of controlling devices (as for a current controlled source).  soft
262  * evaluates true if the number of terms is not fixed (in which case
263  * numTerms is the maximum).
264  *
265  */
266 
267 typedef struct sIFkeys {
268     char key;           /* keying character in input */
269     int numTerms;       /* number of terminals in this type of instance */
270     char **termNames;   /* pointer to array of pointers to names */
271     int soft;           /* nonzero if number of terms not fixed */
272     int numDevs;        /* number of controlling devices */
273 } IFkeys;
274 
275 /*
276  * structure:  IFdevice
277  *
278  * This structure contains all the information available to the
279  * front end about a particular device.  The simulator will
280  * present the front end with an array of pointers to these structures
281  * which it will use to determine legal device types and parameters.
282  *
283  * Note to simulators:  you are passing an array of pointers to
284  * these structures, so you may in fact make this the first component
285  * in a larger, more complex structure which includes other data
286  * which you need, but which is not needed in the common
287  * front end interface.
288  *
289  */
290 
291 
292 typedef struct sIFdevice {
293     char *name;                 /* name of this type of device */
294     char *description;          /* description of this type of device */
295 
296     int *numKeys;               /* number of implementations */
297     IFkeys *keys;               /* list of device implementations */
298 /*
299  * levelMask is a bit field which determines the model levels (1-32)
300  * supported by this device, LSB 1 => level 1, etc.  modelKeys is a list
301  * of strings which name the model for this device.  parse is the function
302  * which actually parses the input line for this device (old INP2? routine).
303  */
304     unsigned levelMask;         /* model level mask, LSB => 1 */
305     char **modelKeys;           /* list of model names */
306 #ifdef __STDC__                 /* input parser function */
307     void (*parse)(int,GENERIC*,GENERIC*,GENERIC*);
308 #else
309     void (*parse)();
310 #endif
311 
312     int *numInstanceParms;      /* number of instance parameter descriptors */
313     IFparm *instanceParms;      /* array  of instance parameter descriptors */
314 
315     int *numModelParms;         /* number of model parameter descriptors */
316     IFparm *modelParms;         /* array  of model parameter descriptors */
317 
318 } IFdevice;
319 
320 
321 /*
322  * Structure: IFanalysis
323  *
324  * This structure contains all the information available to the
325  * front end about a particular analysis type.  The simulator will
326  * present the front end with an array of pointers to these structures
327  * which it will use to determine legal analysis types and parameters.
328  *
329  * Note to simulators:  As for IFdevice above, you pass an array of pointers
330  * to these, so you can make this structure a prefix to a larger structure
331  * which you use internally.
332  *
333  */
334 
335 typedef struct sIFanalysis {
336     char *name;                 /* name of this analysis type */
337     char *description;          /* description of this type of analysis */
338 
339     int numParms;               /* number of analysis parameter descriptors */
340     IFparm *analysisParms;      /* array  of analysis parameter descriptors */
341 
342 } IFanalysis;
343 
344 
345 /*
346  * Structure: IFsimulator
347  *
348  * This is what we have been leading up to all along.
349  * This structure describes a simulator to the front end, and is
350  * returned from the SIMinit command to the front end.
351  * This is where all those neat structures we described in the first
352  * few hundred lines of this file come from.
353  *
354  */
355 
356 typedef struct sIFsimulator {
357     char *simulator;            /* the simulator's name */
358     char *description;          /* description of this simulator */
359     char *version;              /* version or revision level of simulator */
360 
361 #ifdef __STDC__
362     int ((*newCircuit)(GENERIC **));
363                                     /* create new circuit */
364     int ((*deleteCircuit)(GENERIC *));
365                                     /* destroy old circuit's data structures*/
366 
367     int ((*newNode)(GENERIC *,GENERIC**,IFuid));
368                                     /* create new node */
369     int ((*groundNode)(GENERIC*,GENERIC**,IFuid));
370                                     /* create ground node */
371     int ((*bindNode)(GENERIC *,GENERIC*,int,GENERIC*));
372                                     /* bind a node to a terminal */
373     int ((*findNode)(GENERIC *,GENERIC**,IFuid));
374                                     /* find a node by name */
375     int ((*instToNode)(GENERIC *,GENERIC *,int,GENERIC **,IFuid *));
376                                     /* find the node attached to a terminal */
377     int ((*setNodeParm)(GENERIC*,GENERIC*,int,IFvalue*,IFvalue*));
378                                     /* set a parameter on a node */
379     int ((*askNodeQuest)(GENERIC*,GENERIC*,int,IFvalue*,IFvalue*));
380                                     /* ask a question about a node */
381     int ((*deleteNode)(GENERIC*,GENERIC*));
382                                     /* delete a node from the circuit */
383 
384     int ((*newInstance)(GENERIC*,GENERIC*,GENERIC**,IFuid));
385                                     /* create new instance */
386     int ((*setInstanceParm)(GENERIC*,GENERIC*,int,IFvalue*,IFvalue*));
387                                     /* set a parameter on an instance */
388     int ((*askInstanceQuest)(GENERIC*,GENERIC*,int,IFvalue*,IFvalue*));
389                                     /* ask a question about an instance */
390     int ((*findInstance)(GENERIC*,int*,GENERIC**,IFuid,GENERIC*,IFuid));
391                                     /* find a specific instance */
392     int ((*deleteInstance)(GENERIC*,GENERIC*));
393                                     /* delete an instance from the circuit */
394 
395     int ((*newModel)(GENERIC*,int,GENERIC**,IFuid));
396                                     /* create new model */
397     int ((*setModelParm)(GENERIC*,GENERIC*,int,IFvalue*,IFvalue*));
398                                     /* set a parameter on a model */
399     int ((*askModelQuest)(GENERIC*,GENERIC*,int,IFvalue*,IFvalue*));
400                                     /* ask a questions about a model */
401     int ((*findModel)(GENERIC*,int*,GENERIC**,IFuid));
402                                     /* find a specific model */
403     int ((*deleteModel)(GENERIC*,GENERIC*));
404                                     /* delete a model from the circuit*/
405 
406     int ((*newTask)(GENERIC*,GENERIC**,IFuid));
407                                     /* create a new task */
408     int ((*newAnalysis)(GENERIC*,int,IFuid,GENERIC**,GENERIC*));
409                                     /* create new analysis within a task */
410     int ((*setAnalysisParm)(GENERIC*,GENERIC*,int,IFvalue*,IFvalue*));
411                                     /* set a parameter on an analysis  */
412     int ((*askAnalysisQuest)(GENERIC*,GENERIC*,int,IFvalue*,IFvalue*));
413                                     /* ask a question about an analysis */
414     int ((*findAnalysis)(GENERIC*,int*,GENERIC**,IFuid,GENERIC*,IFuid));
415                                     /* find a specific analysis */
416     int ((*findTask)(GENERIC*,GENERIC**,IFuid));
417                                     /* find a specific task */
418     int ((*deleteTask)(GENERIC*,GENERIC*));
419                                     /* delete a task */
420 
421     int ((*doAnalyses)(GENERIC*,int,GENERIC*));
422     char *((*nonconvErr)(GENERIC*,char *)); /* return nonconvergence error */
423 #else
424     int ((*newCircuit)());          /* create new circuit */
425     int ((*deleteCircuit)());       /* destroy old ckt's data structures */
426 
427     int ((*newNode)());             /* create new node */
428     int ((*groundNode)());          /* create ground node */
429     int ((*bindNode)());            /* bind a node to a terminal */
430     int ((*findNode)());            /* find a node by name */
431     int ((*instToNode)());          /* find the node attached to a terminal */
432     int ((*setNodeParm)());         /* set a parameter on a node */
433     int ((*askNodeQuest)());        /* ask a question about a node */
434     int ((*deleteNode)());          /* delete a node from the circuit */
435 
436     int ((*newInstance)());         /* create new instance */
437     int ((*setInstanceParm)());     /* set a parameter on an instance */
438     int ((*askInstanceQuest)());    /* ask a question about an instance */
439     int ((*findInstance)());        /* find a specific instance */
440     int ((*deleteInstance)());      /* delete an instance from the circuit */
441 
442     int ((*newModel)());            /* create new model */
443     int ((*setModelParm)());        /* set a parameter on a model */
444     int ((*askModelQuest)());       /* ask a questions about a model */
445     int ((*findModel)());           /* find a specific model */
446     int ((*deleteModel)());         /* delete a model from the circuit*/
447 
448     int ((*newTask)());             /* create a new task */
449     int ((*newAnalysis)());         /* create new analysis within a task */
450     int ((*setAnalysisParm)());     /* set a parameter on an analysis  */
451     int ((*askAnalysisQuest)());    /* ask a question about an analysis */
452     int ((*findAnalysis)());        /* find a specific analysis */
453     int ((*findTask)());            /* find a specific task */
454     int ((*deleteTask)());          /* delete a task */
455 
456     int ((*doAnalyses)());          /* run a specified task */
457     char *((*nonconvErr)());        /* return nonconvergence error */
458 #endif /* STDC */
459 
460     int numDevices;                 /* number of device types supported */
461     IFdevice **devices;             /* array of device type descriptors */
462 
463     int numAnalyses;                /* number of analysis types supported */
464     IFanalysis **analyses;          /* array of analysis type descriptors */
465 
466     int numNodeParms;               /* number of node parameters supported */
467     IFparm *nodeParms;              /* array of node parameter descriptors */
468 
469     int numSpecSigs;     /* number of special signals legal in parse trees */
470     char **specSigs;     /* names of special signals legal in parse trees */
471     char *ptXalias;      /* alias for 'x' in parse tree */
472 
473 } IFsimulator;
474 
475 /*
476  * Structure: IFfrontEnd
477  *
478  * This structure provides the simulator with all the information
479  * it needs about the front end.  This is the entire set of
480  * front end and back end related routines the simulator
481  * should know about.
482  *
483  */
484 
485 typedef struct sIFfrontEnd {
486 #ifdef __STDC__
487     int ((*IFnewUid)(GENERIC*,IFuid*,IFuid,char*,int,GENERIC**));
488                             /* create a new UID in the circuit */
489     int ((*IFpauseTest)(void));
490                             /* should we stop now? */
491     double ((*IFseconds)(void));
492                             /* what time is it? */
493     int ((*IFerror)(int,char*,IFuid*));
494                             /* output an error or warning message */
495     int ((*OUTbeginPlot)(GENERIC*));
496                             /* start pointwise output plot */
497     int ((*OUTdata)(GENERIC*,IFvalue*,IFvalue*));
498                             /* data for pointwise plot */
499     int ((*OUTsetDims)(GENERIC*,int*,int));
500                             /* modify the plot dimensionality */
501     int ((*OUTendPlot)(GENERIC*));
502                             /* end of plot */
503 #else /* not STDC */
504     int ((*IFnewUid)());        /* create a new UID in the circuit */
505     int ((*IFpauseTest)());     /* should we stop now? */
506     double ((*IFseconds)());    /* what time is it? */
507     int ((*IFerror)());         /* output an error or warning message */
508     int ((*OUTbeginPlot)());    /* start pointwise output plot */
509     int ((*OUTdata)());         /* data for pointwise plot */
510     int ((*OUTsetDims)());      /* modify the plot dimensionality */
511     int ((*OUTendPlot)());      /* end of plot */
512 #endif /* STDC */
513     int *OUTendit;  /* if nonzero, quit the current analysis as if finished */
514 } IFfrontEnd;
515 
516 /* flags for the first argument to IFerror */
517 #define ERR_WARNING 0x1
518 #define ERR_FATAL 0x2
519 #define ERR_PANIC 0x4
520 #define ERR_INFO 0x8
521 
522     /* valid values for the second argument to doAnalyses */
523 
524     /* continue the analysis from where we left off */
525 #define RESUME 0
526     /* start everything over from the beginning of this task*/
527 #define RESTART 1
528     /* abandon the current analysis and go on the the next in the task*/
529 #define SKIPTONEXT 2
530 
531 #endif /*IFSIMULATOR*/
532