📄 mif_inp2.c
字号:
/*============================================================================FILE MIF_INP2A.cMEMBER OF process XSPICECopyright 1991Georgia Tech Research CorporationAtlanta, Georgia 30332All Rights ReservedPROJECT A-8503AUTHORS 9/12/91 Bill KuhnMODIFICATIONS <date> <person name> <nature of modifications>SUMMARY This file contains the main routine for parsing code model lines in the SPICE circuit description input deck.INTERFACES MIF_INP2A()REFERENCED FILES None.NON-STANDARD FEATURES None.============================================================================*//* #include "prefix.h" */ /* jgroves */#include "ngspice.h"#include <stdio.h>//#include "util.h"#include "ifsim.h"#include "inpdefs.h"#include "devdefs.h"#include "inpmacs.h"#include "fteext.h"#include "mifproto.h"#include "mifparse.h"#include "mifdefs.h"#include "mifcmdat.h"#include "evt.h"#include "evtproto.h"/* #include "suffix.h" */ /* jgroves *//*#define NUM_SPICE3_MODELS 40 (was 23 - jgroves Number of Berkeley models in DEVices array. */ /* See CKT/SPIinit.c */extern int *DEVicesfl; /*flags for the devices */extern SPICEdev **DEVices; /* info about all device types */extern int DEVmaxnum; /* size of DEVices array */static void MIFinit_inst(MIFmodel *mdfast, MIFinstance *fast);static void MIFget_port_type( void *ckt, /* circuit structure to put mod/inst structs in */ INPtables *tab, /* symbol table for node names, etc. */ card *current, /* MUST be named 'current' for spice macros */ char **line, char **next_token, Mif_Token_Type_t *next_token_type, Mif_Port_Type_t *port_type, char **port_type_str, Mif_Conn_Info_t *conn_info, /* for faster access to conn info struct */ Mif_Status_t *status);static void MIFget_port( void *ckt, /* circuit structure to put mod/inst structs in */ INPtables *tab, /* symbol table for node names, etc. */ card *current, /* MUST be named 'current' for spice macros */ MIFinstance *fast, /* pointer to instance struct */ char **line, char **next_token, Mif_Token_Type_t *next_token_type, Mif_Port_Type_t def_port_type, char *def_port_type_str, Mif_Conn_Info_t *conn_inf, /* for faster access to conn info struct */ int conn_num, int port_num, Mif_Status_t *status);/* ********************************************************************* *//*MIF_INP2AThis function is called by INPpas2() in SPICE to parse the new``a'' type element cards and build the required circuit structuresfor the associated code model device and instance. It firstchecks the model name at the end of the element card to be surethe model was found in pass 1 of the parser. If so, MIFgetMod iscalled to process the .model card, creating the necessaryinternal model structure and filling in the parameter valueinformation. Next, the instance structure is allocated.Finally, the connections on the element card are scanned and theconnection information is filled-in on the instance structure,and error checks are performed.*//*--------------- Quick summary of algorithm -----------------------1. Get the spice card. Place card string into variable 'line'.2. Get the name of the instance and add it to the symbol table3. Locate the last token on the line and assign it to variable 'model' 4. Locate the model from pass 1. If it hasn't been processed yet, allocate structure in ckt for it, process the parameters, and return a pointer to its structure in 'thismodel'5. Get model type.6. Create a new instance structure in ckt for this instance.------ Process the connections: here's where it gets interesting. -----7. Reset 'line'. Then read instance name again to go over it.8. Read initial token.9 Start loop through port tokens:10. If token is a %, then read next token to get port type and save this port type. Otherwise, use default port type.11. Check if connection is null. If so, iterate to next conn.12. Get next token. Depending upon token type (scalar or array) do the following: -- Scalar: Process it, then continue loop. -- Array: Loop through all tokens until ] is found & process tokens. Then continue outer loop over port tokens.13. After looping through connection tokens, do error checks. At this point, nothing should be left in 'line'-------------------------------------------------------------------------*/voidMIF_INP2A(ckt,tab,current)void *ckt; /* circuit structure to put mod/inst structs in */INPtables *tab; /* symbol table for node names, etc. */card *current; /* the card we are to parse */ /* Must be called "current" for compatibility */ /* with macros */{/* parse a code model instance card *//* Aname <connection list> <mname> */ char *line; /* the text line for this card */ char *name; /* the name of the instance */ char *model=NULL; /* the name of the model */ char *def_port_type_str; /* The default port type in string form */ char *next_token; /* a token string */ int i; /* a loop counter */ int j; /* a loop counter */ int type; /* the type of the model for this instance */ /* int num_conn; number of connections for this model */ int error; /* for the IFC macro */ MIFmodel *mdfast; /* pointer to model struct */ MIFinstance *fast[1]; /* pointer to instance struct */ INPmodel *thismodel; /* pointer to model struct */ Mif_Conn_Info_t *conn_info; /* for faster access to conn info struct */ Mif_Param_Info_t *param_info; /* for faster access to param info struct */ Mif_Port_Type_t def_port_type; /* the default port type */ Mif_Status_t status; /* return status */ Mif_Token_Type_t next_token_type; /* the type of the next token */#ifdef TRACE /* SDB debug statement */ printf("In MIF_INP2A, line to process = %s . . . \n", current->line);#endif /* get the line text from the card struct */ line = current->line; /* get the name of the instance and add it to the symbol table */ name = MIFgettok(&line); INPinsert(&name, tab); /* locate the last token on the line (i.e. model name) and put it into "model" */ while(*line != '\0') model = MIFgettok(&line); /* make sure the model name was there. */ if(model == NULL) { LITERR("Missing model on A type device"); return; } /* Locate model from pass 1. If it hasn't been processed yet, */ /* allocate a structure in ckt for it, process its parameters */ /* and return a pointer to its structure in 'thismodel' */ current->error = MIFgetMod(ckt, model, &thismodel, tab); if(current->error) { return; } /* get the integer index into the DEVices data array for this */ /* model */ type = thismodel->INPmodType; if((type >= DEVmaxnum) || DEVicesfl[type] == 0) { LITERR("Invalid model type for A type device"); return; } /* create a new structure for this instance in ckt */ mdfast = thismodel->INPmodfast; IFC(newInstance, (ckt, mdfast,(void **)fast, name)) /* initialize the code model specific elements of the inst struct */ MIFinit_inst(mdfast, fast[0]); /* *********************** */ /* Process the connections */ /* *********************** */ /* reset 'line', and then read instance name again. */ line = current->line; MIFgettok(&line); /* read instance name again . . . .*/ /* OK -- now &line points to the first token after the instance name and we are ready to process the connections (netnames) */ /* now get next token. It should be either a % token, a [, or a connection (netname) which might be 'null'. */ next_token = MIFget_token(&line,&next_token_type); /* When we enter the loop, next_token holds the first thing *after* the instance name. Upon each iteration, we start the iteration with next_token holding the next *unprocessed* token. The loop proceeds through the fixed number of connections expected, as defined in the DEVices struct. */ for(i = 0; i < DEVices[type]->DEVpublic.num_conn; i++) { /* Check that the line is not finished yet. */ if(*line == '\0') { LITERR("Encountered end of line before all connections were found in model."); return; } /* At this point, we have one of three possibilities: 1. next_token holds a %, and &line points to either the port type identifier (id, vd, etc) 2. next_token holds a netname and &line points to the thing *after* the first netname. 3. next_token holds a [ indicating the start of an array of ports. */ /* prepare a pointer for fast access to info about this connection */ conn_info = &(DEVices[type]->DEVpublic.conn[i]); /* Now if we had a % token, get actual info about connection type. Otherwise use default info */ if(next_token_type == MIF_PERCENT_TOK) { /* we found a % */ /* get the port type identifier and check it for validity */ next_token = MIFget_token(&line,&next_token_type); /* Note that MIFget_port_type eats the next token and advances the token pointer in line */ MIFget_port_type(ckt, tab, current, &line, &next_token, &next_token_type, &def_port_type, &def_port_type_str, conn_info, &status); if(status == MIF_ERROR) return; } else { /* use the default port type for this connection */ def_port_type = conn_info->default_port_type; def_port_type_str = conn_info->default_type; } /* At this point, next_token should be either a [ char, or should hold the the first connection (netname) */ /* set analog and event_driven flags on instance and model */ if((def_port_type == MIF_DIGITAL) || (def_port_type == MIF_USER_DEFINED)) { fast[0]->event_driven = MIF_TRUE; mdfast->event_driven = MIF_TRUE; } else { fast[0]->analog = MIF_TRUE; mdfast->analog = MIF_TRUE; } /* check for a null connection and continue to next connection if found */ if(next_token_type == MIF_NULL_TOK) { /* make sure null is allowed */ if(! conn_info->null_allowed) { LITERR("NULL connection found where not allowed");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -