⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inpgmod.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Thomas L. Quarles, 1991 David A. Gates**********/#include "spice.h"#include <stdio.h>#include "inpdefs.h"#include "util.h"#include "ifsim.h"#include "cpstd.h"#include "fteext.h"#include "numcards.h"#include "carddefs.h"#include "numgen.h"#include "suffix.h"extern INPmodel *modtab;extern IFcardInfo *INPcardTab[];extern int INPnumCards;#define E_MISSING	-1#define E_AMBIGUOUS	-2char *INPgetMod(ckt,name,model,tab)    GENERIC * ckt;    char *name;    INPmodel **model;    INPtables *tab;{    INPmodel *modtmp;    IFvalue * val;    register int j;    char * line;    char *parm;    char *err = NULL;    char *temp;    int error;    for (modtmp = modtab;modtmp != (INPmodel *)NULL;modtmp =            ((modtmp)->INPnextModel)) {        if (strcmp((modtmp)->INPmodName,name) == 0) {            /* found the model in question - now instantiate if necessary */            /* and return an appropriate pointer to it */            if(modtmp->INPmodType<0) {                /* illegal device type, so can't handle */                *model = (INPmodel *)NULL;                err = (char *)MALLOC((35+strlen(name)) * sizeof(char));                (void) sprintf(err,                        "Unknown device type for model %s \n",name);                return(err);            }            if(! ((modtmp)->INPmodUsed )) {                /* not already defined, so create & give parameters */                error = (*(ft_sim->newModel))( ckt,(modtmp)->INPmodType,                         &((modtmp)->INPmodfast), (modtmp)->INPmodName);                if(error) return(INPerror(error));                /* parameter isolation, identification, binding */		/* Handle Numerical Models Differently */		if ( ((modtmp)->INPmodType == INPtypelook("NUMD")) ||		     ((modtmp)->INPmodType == INPtypelook("NBJT")) ||		     ((modtmp)->INPmodType == INPtypelook("NUMD2")) ||		     ((modtmp)->INPmodType == INPtypelook("NBJT2")) ||		     ((modtmp)->INPmodType == INPtypelook("NUMOS")) ) {		    error = INPparseNumMod( ckt, modtmp, tab, &err );		    if (error) return(INPerror(error));		} else {     		/* It's an analytical model */                line = ((modtmp)->INPmodLine)->line;                INPgetTok(&line,&parm,1);     /* throw away '.model' */                INPgetTok(&line,&parm,1);     /* throw away 'modname' */                while(*line != 0) {                    INPgetTok(&line,&parm,1);		    if (!*parm)			continue;                    for(j=0;j<(*(*(ft_sim->devices)[(modtmp)->INPmodType]).                            numModelParms); j++) {                        if (strcmp(parm,((*(ft_sim->devices) [ (modtmp)->                                INPmodType ]).modelParms[j].keyword)) == 0) {                            val = INPgetValue(ckt,&line,                                    ((*(ft_sim->devices)[(modtmp)->                                    INPmodType ]).modelParms[j].                                    dataType),tab);                            error = (*(ft_sim->setModelParm))(ckt,                                     ((modtmp)->INPmodfast),                                    (*(ft_sim->devices)[(modtmp)->INPmodType ]).                                    modelParms[j].id,val,(IFvalue*)NULL);                            if(error) return(INPerror(error));                            break;                        }                     }                    if (strcmp(parm,"level")==0) {                        /* just grab the level number and throw away */                        /* since we already have that info from pass1 */                        val = INPgetValue(ckt,&line,IF_REAL,tab);                    } else if(j >=                             (*(*(ft_sim->devices)[(modtmp)->INPmodType]).                                    numModelParms)) {                        temp = (char *)MALLOC((40+strlen(parm)) * sizeof(char));                        (void)sprintf(temp,                            "unrecognized parameter (%s) - ignored", parm);                        err = INPerrCat(err,temp);                    }                    FREE(parm);                }		} /* analytical vs. numerical model parsing */                (modtmp)->INPmodUsed=1;                (modtmp)->INPmodLine->error = err;            }            *model = modtmp;            return((char *)NULL);        }    }    /* didn't find model - ERROR  - return model */    *model = (INPmodel *)NULL;    err = (char *)MALLOC((60+strlen(name)) * sizeof(char));    (void) sprintf(err,            " unable to find definition of model %s - default assumed \n",name);    return(err);}/* * Parse a numerical model by running through the list of original * input cards which make up the model * Given: * 1. First card looks like: .model modname modtype <level=val> * 2. Other cards look like: +<whitespace>? where ? tells us what * to do with the next card: *    '#$*' = comment card *    '+'   = continue previous card *    other = new card */intINPparseNumMod( ckt, model, tab, errMessage )    GENERIC * ckt;    INPmodel *model;    INPtables *tab;    char **errMessage;{    card *txtCard;	/* Text description of a card */    GENcard *tmpCard;	/* Processed description of a card */    IFcardInfo *info;	/* Info about the type of card located */    char *line;    char *cardName = NULL;	/* name of a card */    char *parm;		/* name of a parameter */    int cardType;	/* type/index for the current card */    int cardNum = 0;	/* number of this card in the overall line */    int lastType = E_MISSING;	/* type of previous card */    char *err = NULL, *tmp;    /* Strings for error messages */    IFvalue *value;    int error, idx, invert;    /* Chase down to the top of the list of actual cards */    txtCard = model->INPmodLine->actualLine;    /* Skip the first card if it exists since there's nothing interesting */    /* txtCard will be empty if the numerical model is empty */    if (txtCard) txtCard = txtCard->nextcard;    /* Now parse each remaining card */    while (txtCard) {	line = txtCard->line;	cardType = E_MISSING;	cardNum++;	/* Skip the initial '+' and any whitespace. */	line++;	while (*line == ' ' || *line == '\t')	    line++;	switch (*line) {	case '*':	case '$':	case '#':	case '\0':	case '\n':	    /* comment or empty cards */	    lastType = E_MISSING;	    break;        case '+':	    /* continuation card */	    if (lastType >= 0) {	        cardType = lastType;                while (*line == '+') line++;	/* Skip leading '+'s */	    } else {	        tmp = (char *)MALLOC((55)*sizeof(char));		(void) sprintf(tmp,		    "Error on card %d : illegal continuation \'+\' - ignored",		    cardNum);		err = INPerrCat(err,tmp);		lastType = E_MISSING;	        break;	    }	    /* FALL THRU when continuing a card */        default:	    if (cardType == E_MISSING) {	        /* new command card */		if (cardName) FREE(cardName);	/* get rid of old card name */	        INPgetTok(&line,&cardName,1);	/* get new card name */		if (*cardName) { 		/* Found a name? */		    cardType = INPfindCard(cardName,INPcardTab,INPnumCards);		    if (cardType >= 0) {		        /* Add card structure to model */			info = INPcardTab[cardType];			error = (*(info->newCard))( (GENERIC *)&tmpCard,			        model->INPmodfast );			if (error) return(error);		    /* Handle parameter-less cards */		    } else if (cinprefix( cardName, "title", 3 ) ) {		        /* Do nothing */		    } else if (cinprefix( cardName, "comment", 3 ) ) {		        /* Do nothing */		    } else if (cinprefix( cardName, "end", 3 ) ) {			/* Terminate parsing */			txtCard = ((card *) 0);			cardType = E_MISSING;		    } else {		        /* Error */		        tmp =(char *)MALLOC((55+strlen(cardName))*sizeof(char));			(void) sprintf(tmp,			    "Error on card %d : unrecognized name (%s) - ignored",			    cardNum, cardName );			err = INPerrCat(err,tmp);		    }		}	    }	    if (cardType >= 0) { /* parse the rest of this line */		while (*line) {		    /* Strip leading carat from booleans */		    if (*line == '^') {		      invert = true;		      *line++;	/* Skip the '^' */		    } else {		      invert = false;		    }		    INPgetTok(&line,&parm,1);		    if (!*parm)		      break;		    idx = INPfindParm(parm, info->cardParms, info->numParms);		    if (idx == E_MISSING) {			/* parm not found */                        tmp = (char *)MALLOC((60+strlen(parm)) * sizeof(char));                        (void)sprintf(tmp,                            "Error on card %d : unrecognized parameter (%s) - ignored",			    cardNum, parm);                        err = INPerrCat(err, tmp);		    } else if (idx == E_AMBIGUOUS) {			/* parm ambiguous */                        tmp = (char *)MALLOC((58+strlen(parm)) * sizeof(char));                        (void)sprintf(tmp,                            "Error on card %d : ambiguous parameter (%s) - ignored",			    cardNum, parm);                        err = INPerrCat(err, tmp);		    } else {		        value = INPgetValue( ckt, &line,			    ((info->cardParms)[idx]).dataType, tab );			if (invert) { /* invert if it's a boolean entry */			  if (((((info->cardParms)[idx]).dataType)&IF_VARTYPES)			      == IF_FLAG) {			    value->iValue = 0;			  } else {                            tmp =(char *)MALLOC((63+strlen(parm))*sizeof(char));                            (void)sprintf(tmp,                              "Error on card %d : non-boolean parameter (%s) - \'^\' ignored",			      cardNum, parm);                            err = INPerrCat(err, tmp);			  }			}                        error = (*(info->setCardParm))(			    ((info->cardParms)[idx]).id, value, tmpCard );			if (error) return(error);		    }		    FREE(parm);		}	    }	    lastType = cardType;	    break;	}	if (txtCard) txtCard = txtCard->nextcard;    }    *errMessage = err;    return( 0 );}/* * Locate the best match to a card name in an IFcardInfo table */intINPfindCard( name, table, numCards )    char *name;    IFcardInfo *table[];    int numCards;{    register int test;    int match, bestMatch;    int best;    int length;    length = strlen(name);    /* compare all the names in the card table to this name */    best = E_MISSING;    bestMatch = 0;    for ( test = 0; test < numCards; test++ ) {        match = cimatch( name, table[test]->name );        if ((match == bestMatch ) && (match > 0)){	    best = E_AMBIGUOUS;        } else if ((match > bestMatch) && (match == length)) {	    best = test;	    bestMatch = match;        }    }    return(best);}/* * Locate the best match to a parameter name in an IFparm table */intINPfindParm( name, table, numParms )    char *name;    IFparm *table;    int numParms;{    register int test, best;    int match, bestMatch;    int id, bestId;    int length;    length = strlen(name);    /* compare all the names in the parameter table to this name */    best = E_MISSING;    bestId = -1;    bestMatch = 0;    for ( test = 0; test < numParms; test++ ) {        match = cimatch( name, table[test].keyword );	if ( (match == length) && (match == strlen(table[test].keyword)) ) {	    /* exact match */	    best = test;	    /* all done */	    break;	}	id = table[test].id;        if ((match == bestMatch) && (match > 0) && (id != bestId)) {	    best = E_AMBIGUOUS;        } else if ((match > bestMatch) && (match == length)) {	    bestMatch = match;	    bestId = id;	    best = test;        }    }    return(best);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -