📄 enhtrans.c
字号:
/* ===========================================================================FILE ENHtranslate_poly.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 functions used by the simulator in calling the internal "poly" code model to substitute for SPICE 2G6 style poly sources found in the input deck.INTERFACES ENHtranslate_poly()REFERENCED FILES None.NON-STANDARD FEATURES None.=========================================================================== *//*=== FUNCTION PROTOTYPES ===*///void free(void *); //ka removed compiler error/* int atoi(char *); *//*=== INCLUDE FILES ===*//* #include "prefix.h" */#include "ngspice.h"//#include "misc.h"#include "fteinp.h"#include "enh.h"#include "cpdefs.h"#include "ftedefs.h"#include "mifproto.h"/* #include "suffix.h" *//*=== FUNCTION PROTOTYPES ===*/static int needs_translating(char *card);static int count_tokens(char *card);static char *two2three_translate(char *orig_card, char **inst_card, char **mod_card);static int get_poly_dimension(char *card);/*ENHtranslate_poly()Translate all 2G6 style polynomial controlled sources in the deckto new polynomial controlled source code model syntax.*//*---------------------------------------------------------------------*//* ENHtranslate_poly takes (a pointer to) the SPICE deck as argument. *//* It loops through the deck, and translates all POLY statements *//* in dependent sources into a .model conformant with the needs of *//* XSPICE. It splices the new statements in the deck, and comments *//* out the old dependent source. *//* It returns (a pointer to) the processed deck. *//*---------------------------------------------------------------------*/struct line * ENHtranslate_poly( struct line *deck) /* Linked list of lines in input deck */{ struct line *d; struct line *l1; struct line *l2; char *card; /* Iterate through each card in the deck and translate as needed */ for(d = deck; d; d = d->li_next) {#ifdef TRACE /* SDB debug statement */ printf("In ENHtranslate_poly, now examining card %s . . . \n", d->li_line);#endif /* If doesn't need to be translated, continue to next card */ if(! needs_translating(d->li_line)) {#ifdef TRACE /* SDB debug statement */ /* printf("Card doesn't need translating. Continuing . . . .\n"); */#endif continue; }#ifdef TRACE /* SDB debug statement */ printf("Found a card to translate . . . .\n");#endif/* Create two new line structs and splice into deck *//* l1 = alloc(line); */ /* jgroves *//* l2 = alloc(line); */ /* jgroves */ l1 = alloc(struct line); l2 = alloc(struct line); l2->li_next = d->li_next; l1->li_next = l2; d->li_next = l1; /* PN 2004: Add original linenumber to ease the debug process * for malfromned netlist */ l1->li_linenum = d->li_linenum; l2->li_linenum = d->li_linenum; /* Create the translated cards */ d->li_error = two2three_translate(d->li_line, &(l1->li_line), &(l2->li_line)); /* Comment out the original line */ card = (void *) MALLOC(strlen(d->li_line) + 2); strcpy(card,"*"); strcat(card, d->li_line); d->li_line = card;#ifdef TRACE /* SDB debug statement */ printf("In ENHtranslate_poly, translated card = %s . . . \n", card);#endif /* Advance deck pointer to last line added */ d = l2; } /* Return head of deck */ return(deck);} /* ENHtranslate_poly *//*---------------------------------------------------------------------*//*needs_translating()Test to see if card needs translating. Return true if card definesan e,f,g, or h controlled source and has too many tokens to bea simple linear dependent source. Otherwise return false.*/static int needs_translating( char *card) /* the card text to check */{#ifdef TRACE /* SDB debug statement */ /* printf("In needs_translating, examining card %s . . . \n", card); */#endif switch(*card) { case 'e': case 'E': case 'g': case 'G': if(count_tokens(card) <=6) return(0); else return(1); case 'f': case 'F': case 'h': case 'H': if(count_tokens(card) <= 5) return(0); else return(1); default: return(0); }} /* needs_translating *//*---------------------------------------------------------------------*//*count_tokens()Count and return the number of tokens on the card.*/static int count_tokens( char *card) /* the card text on which to count tokens */{ int i; /* Get and count tokens until end of line reached */ for(i = 0; *card != '\0'; i++) txfree(MIFgettok(&card)); return(i);} /* count_tokens *//********************************************************************//*====================================================================two2three_translate()Do the syntax translation of the 2G6 source to the new code model syntax. The translation proceeds according to the template below.--------------------------------------------VCVS:ename N+ N- POLY(dim) NC+ NC- P0 P1 P2 . . .N+ N- = outputsNC+ NC- = inputsaname %vd[NC+ NC-] %vd[N+ N-] pname.model pname spice2poly(coef=P0 P1 P2 . . . )%vd[NC+ NC-] = inputs%vd[N+ N-] = outputs--------------------------------------------CCCSfname N+ N- POLY(dim) Vname P0 P1 P2 . . .N+ N- = outputsVname = input voltage source (measures current)aname %vnam[Vname] %id[N+ N-] pname.model pname spice2poly(coef=P0 P1 P2 . . . )%vnam[Vname] = input%id[N+ N-] = output--------------------------------------------VCCSgname N+ N- POLY(dim) NC+ NC- P0 P1 P2 , , ,N+ N- = outputsNC+ NC- = inputsaname %vd[NC+ NC-] %id[N+ N-] pname.model pname spice2poly(coef=P0 P1 P2 . . . )%vd[NC+ NC-] = inputs%id[N+ N-] = outputs--------------------------------------------CCVShname N+ N- POLY(dim) Vname P0 P1 P2 . . .N+ N- = outputsVname = input voltage source (measures current)aname %vnam[Vname] %vd[N+ N-] pname.model pname spice2poly(coef=P0 P1 P2 . . . )%vnam[Vname] = input%vd[N+ N-] = output====================================================================*//********************************************************************/static char *two2three_translate( char *orig_card, /* the original untranslated card */ char **inst_card, /* the instance card created by the translation */ char **mod_card) /* the model card created by the translation */{ int dim; int num_tokens; int num_conns; int num_coefs; int inst_card_len; int mod_card_len; int i; char type; char *tok; char *name; char **out_conn; char **in_conn; char **coef; char *card;#ifdef TRACE /* SDB debug statement */ printf("In two2three_translate, card to translate = %s . . .\n", orig_card);#endif /* Put the first character into local storage for checking type */ type = *orig_card; /* Count the number of tokens for use in parsing */ num_tokens = count_tokens(orig_card); /* Determine the dimension of the poly source */ /* Note that get_poly_dimension returns 0 for "no poly", -1 for invalid dimensiion, otherwise returns numeric value of POLY */ dim = get_poly_dimension(orig_card); if(dim == -1) { char *errmsg; printf("ERROR in two2three_translate -- Argument to poly() is not an integer\n"); printf("ERROR while parsing: %s\n", orig_card); errmsg = copy("ERROR in two2three_translate -- Argument to poly() is not an integer\n"); *inst_card = (void *)copy(" * ERROR Argument to poly() is not an integer"); *mod_card = (void *)copy(" * ERROR Argument to poly() is not an integer"); return errmsg; } /* Compute number of output connections based on type and dimension */ switch(type) { case 'E': case 'e': case 'G': case 'g': num_conns = 2 * dim; break; default: num_conns = dim; } /* Compute number of coefficients. Return error if less than one. */ if(dim == 0) num_coefs = num_tokens - num_conns - 3; /* no POLY token */ else num_coefs = num_tokens - num_conns - 5; /* POLY token present */#ifdef TRACE /* SDB debug statement */ printf("In two2three_translate, num_tokens=%d, num_conns=%d, num_coefs=%d . . .\n", num_tokens, num_conns, num_coefs);#endif if(num_coefs < 1){ char *errmsg; printf("ERROR - Number of connections differs from poly dimension\n"); printf("ERROR while parsing: %s\n", orig_card); errmsg = copy("ERROR in two2three_translate -- Argument to poly() is not an integer\n"); *inst_card = (void *)copy("* ERROR - Number of connections differs from poly dimension\n"); *mod_card = (void *)copy(" * ERROR - Number of connections differs from poly dimension\n"); return(errmsg);} /* Split card into name, output connections, input connections, */ /* and coefficients */ card = orig_card; name = MIFgettok(&card); /* Get output connections (2 netnames) */ out_conn = (void *) MALLOC(2 * sizeof(char *)); for(i = 0; i < 2; i++) out_conn[i] = MIFgettok(&card); /* check for POLY, and ignore it if present */ if (dim > 0) { #ifdef TRACE /* SDB debug statement */ printf("In two2three_translate, found poly!!! dim = %d \n", dim);#endif tok = MIFgettok(&card); /* read and discard POLY */ tok = MIFgettok(&card); /* read and discard dimension */ } /* Get input connections (2 netnames per dimension) */ in_conn = (void *) MALLOC(num_conns * sizeof(char *)); for(i = 0; i < num_conns; i++) in_conn[i] = MIFgettok(&card); /* The remainder of the line are the poly coeffs. */ coef = (void *) MALLOC(num_coefs * sizeof(char *)); for(i = 0; i < num_coefs; i++) coef[i] = MIFgettok(&card); /* Compute the size needed for the new cards to be created */ /* Allow a fair amount of extra space for connection types, etc. */ /* to be safe... */ inst_card_len = 70; inst_card_len += 2 * (strlen(name) + 1); for(i = 0; i < 2; i++) inst_card_len += strlen(out_conn[i]) + 1; for(i = 0; i < num_conns; i++) inst_card_len += strlen(in_conn[i]) + 1; mod_card_len = 70; mod_card_len += strlen(name) + 1; for(i = 0; i < num_coefs; i++) mod_card_len += strlen(coef[i]) + 1; /* Allocate space for the cards and write them into the strings */ *inst_card = (void *) MALLOC(inst_card_len); *mod_card = (void *) MALLOC(mod_card_len); strcpy(*inst_card, "a$poly$"); sprintf(*inst_card + strlen(*inst_card), "%s ", name); /* Write input nets/sources */ if((type == 'e') || (type == 'g') || (type == 'E') || (type == 'G')) { /* These input port types are vector & need a [. */ if (dim > 1) { sprintf(*inst_card + strlen(*inst_card), "%%vd [ "); } else { sprintf(*inst_card + strlen(*inst_card), "%%vd [ "); /* need something different? */ } } else /* This input port type is scalar */ sprintf(*inst_card + strlen(*inst_card), "%%vnam [ "); for(i = 0; i < num_conns; i++) sprintf(*inst_card + strlen(*inst_card), "%s ", in_conn[i]); if (dim > 1) { sprintf(*inst_card + strlen(*inst_card), "] "); } else { sprintf(*inst_card + strlen(*inst_card), "] "); /* need something different? */ } /* Write output nets */ if((type == 'e') || (type == 'h') || (type == 'E') || (type == 'H')) sprintf(*inst_card + strlen(*inst_card), "%%vd ( "); else sprintf(*inst_card + strlen(*inst_card), "%%id ( "); for(i = 0; i < 2; i++) sprintf(*inst_card + strlen(*inst_card), "%s ", out_conn[i]); sprintf(*inst_card + strlen(*inst_card), ") "); /* Write model name */ sprintf(*inst_card + strlen(*inst_card), "a$poly$%s", name); /* Now create model card */ sprintf(*mod_card, ".model a$poly$%s spice2poly coef = [ ", name); for(i = 0; i < num_coefs; i++) sprintf(*mod_card + strlen(*mod_card), "%s ", coef[i]); sprintf(*mod_card + strlen(*mod_card), "]");#ifdef TRACE /* SDB debug statement */ printf("In two2three_translate, translated statements:\n%s \n%s \n", *inst_card, *mod_card);#endif /* Free the temporary space */ FREE(name); name = NULL; for(i = 0; i < 2; i++) { FREE(out_conn[i]); out_conn[i] = NULL; } FREE(out_conn); out_conn = NULL; for(i = 0; i < num_conns; i++) { FREE(in_conn[i]); in_conn[i] = NULL; } FREE(in_conn); in_conn = NULL; for(i = 0; i < num_coefs; i++) { FREE(coef[i]); coef[i] = NULL; } FREE(coef); coef = NULL; /* Return NULL to indicate no error */ return(NULL);} /* two2three_translate *//*--------------------------------------------------------------------*//*get_poly_dimension()Get the poly source dimension from the token immediately followingthe 'poly' if any. Return values changed by SDB on 5.23.2003 to be:If "poly" is not present, return 0.If the dimension token following "poly" is invalid, return -1.Otherwise, return the integer dimension.*/static int get_poly_dimension( char *card) /* the card text */{ int i; int dim; char *local_tok; /* Skip over name and output connections */ for(i = 0; i < 3; i++) txfree(MIFgettok(&card)); /* Check the next token to see if it is "poly" */ /* If not, return 0 */ local_tok = MIFgettok(&card); if( strcmp(local_tok, "poly") && strcmp(local_tok, "POLY") ) /* check that local_tok is *not* poly */ { FREE(local_tok); local_tok = NULL; return(0); } FREE(local_tok); /* Must have been "poly", so next line must be a number */ /* Try to convert it. If successful, return the number */ /* else, return -1 to indicate an error... */ local_tok = MIFgettok(&card); dim = atoi(local_tok); FREE(local_tok); if (dim > 0) { return(dim); } else { return(-1); }} /* get_poly_dimension */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -