📄 mif_inp2a.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"#include <stdio.h>#include "util.h"#include "IFsim.h"#include "INPdefs.h"#include "DEVdefs.h"#include "INPmacs.h"#include "FTEextern.h"#include "MIFproto.h"#include "MIFparse.h"#include "MIFdefs.h"#include "MIFcmdat.h"#include "EVT.h"#include "EVTproto.h"#include "suffix.h"#define NUM_SPICE3_MODELS 23 /* Number of Berkeley models in DEVices array. */ /* See CKT/SPIinit.c */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( GENERIC *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( GENERIC *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.*/voidMIF_INP2A(ckt,tab,current)GENERIC *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; /* 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; /* 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 */ /* 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 and put it into "model" */ while(*line != '\0') model = MIFgettok(&line); 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) || (type < NUM_SPICE3_MODELS)) { 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, &fast, name)) /* initialize the code model specific elements of the inst struct */ MIFinit_inst(mdfast, fast); /* *********************** */ /* Process the connections */ /* *********************** */ /* get the line text from the card struct */ /* skipping over the name of the instance */ /* and reading the first token following */ line = current->line; MIFgettok(&line); next_token = MIFget_token(&line,&next_token_type); /* loop through the fixed number of connections expected */ for(i = 0; i < DEVices[type]->DEVpublic.num_conn; i++) { /* there better be at least one more token besides the model name */ if(*line == '\0') { LITERR("Missing connections on A device"); return; } /* prepare a pointer for fast access to info about this connection */ conn_info = &(DEVices[type]->DEVpublic.conn[i]); /* get the default port type for this connection */ def_port_type = conn_info->default_port_type; def_port_type_str = conn_info->default_type; /* set analog and event_driven flags on instance and model */ if((def_port_type == MIF_DIGITAL) || (def_port_type == MIF_USER_DEFINED)) { fast->event_driven = MIF_TRUE; mdfast->event_driven = MIF_TRUE; } else { fast->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"); return; } /* set the null flag to true */ fast->conn[i]->is_null = MIF_TRUE; fast->conn[i]->size = 0; /* eat the null token and continue to next connection */ next_token = MIFget_token(&line,&next_token_type); continue; } else { /* set the null flag to false */ fast->conn[i]->is_null = MIF_FALSE; } /* process connection as appropriate for scalar or array */ if(! conn_info->is_array) { /* a scalar connection - the simpler case */ /* do a couple of error checks */ if(next_token_type == MIF_LARRAY_TOK) { LITERR("ERROR - Scalar connection expected, [ found"); return; } if(next_token_type == MIF_RARRAY_TOK) { LITERR("ERROR - Unexpected ]"); return; } /* If all OK, get the port data into the instance struct */ /* allocating the port member of the instance struct as needed */ MIFget_port(ckt, tab, current, fast, &line, &next_token, &next_token_type, def_port_type, def_port_type_str, conn_info, i, /* connection index */ 0, /* port index for scalar connection */ &status); if(status == MIF_ERROR) return; fast->conn[i]->size = 1; } else { /* the connection is an array - much to be done ... */ /* get the leading port type for the array if any */ /* it will distribute across all ports inside the braces */ /* overriding the default type in the interface spec */ if(next_token_type == MIF_PERCENT_TOK) { /* get the port type identifier and check it for validity */ next_token = MIFget_token(&line,&next_token_type); 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; } /* check for required leading array delim character and eat it if found */ if(next_token_type != MIF_LARRAY_TOK) { LITERR("Missing [, an array connection was expected"); return; } else next_token = MIFget_token(&line,&next_token_type); /* get and process ports until ] is encountered */ for(j = 0; (next_token_type != MIF_RARRAY_TOK) && (*line != '\0'); j++) { /* First, do some error checks */ /* check for required leading array delim character */ if(next_token_type == MIF_LARRAY_TOK) { LITERR("ERROR - Unexpected [ - Arrays of arrays not allowed"); return; } /* If all OK, get the port nodes into the instance struct */ /* allocating the port member of the instance struct as needed */ MIFget_port(ckt, tab, current, fast, &line, &next_token, &next_token_type, def_port_type, def_port_type_str, conn_info, i, /* connection index */ j, /* port index */ &status); if(status == MIF_ERROR) return; } /* make sure we exited because the end of the array connection */ /* was reached. If so, eat the closing array delimiter */ if(*line == '\0') { LITERR("Missing ] in array connection"); return; } else next_token = MIFget_token(&line,&next_token_type); /* record the number of ports found for this connection */ if(j < 1) { LITERR("Array connection must have at least one port"); return; } fast->conn[i]->size = j; } /* array connection processing */ /* be careful about putting stuff here, there is a 'continue' used */ /* in the processing of NULL connections above */ } /* for number of connections */ /* *********************** */ /* Error Checks */ /* *********************** */ /* check for too many connections */ if(*line != '\0') { LITERR("Too many connections"); return; } /* check connection constraints */ for(i = 0; i < DEVices[type]->DEVpublic.num_conn; i++) { conn_info = &(DEVices[type]->DEVpublic.conn[i]); if( (fast->conn[i]->is_null) && (! conn_info->null_allowed) ) { LITERR("Null found for connection where not allowed"); return; } if(conn_info->has_lower_bound) { if(fast->conn[i]->size < conn_info->lower_bound) { LITERR("Too few ports in connection"); return; } } if(conn_info->has_upper_bound) { if(fast->conn[i]->size > conn_info->upper_bound) { LITERR("Too many ports in connection"); return; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -