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