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

📄 enhtrans.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 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 + -