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

📄 subckt.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 5 页
字号:
	for(c=deck;c; c=c->li_next)	    printf("   %s\n",c->li_line);#endif    /* First pass: xtract all the .subckts and stick pointers to them into sss.  */    for (last = deck, lc = NULL;  last;  ) {        if (ciprefix(sbend, last->li_line)) {         /* if line == .ends  */            fprintf(cp_err, "Error: misplaced %s line: %s\n", sbend,                    last->li_line);            return (NULL);        } 	else if (ciprefix(start, last->li_line)) {    /* if line == .subckt  */	    if (last->li_next == NULL) {            /* first check that next line is non null */                fprintf(cp_err, "Error: no %s line.\n", sbend);                return (NULL);            }            lcc = NULL;                                       wl_free(submod);            submod = NULL;            gotone = FALSE;	    /* Here we loop through the deck looking for .subckt and .ends cards.	     * At the end of this section, last will point to the location of the	     * .subckt card, and lcc will point to the location of the .ends card.	     */            for (nest = 0, c = last->li_next;  c;  c = c->li_next) {	       if (ciprefix(sbend, c->li_line)) { /* found a .ends */                     if (!nest)		        break;   /* nest = 0 means we have balanced .subckt and .ends  */                    else {		        nest--;    /* decrement nesting, and assign lcc to the current card */			lcc = c;   /* (lcc points to the position of the .ends)             */                        continue;  /* then continue looping                                 */                    }	        } else if (ciprefix(start, c->li_line))  /* if .subckt, increment nesting */                    nest++;	        lcc = c;     /* lcc points to current pos of c  */            } /* for (nest = 0 . . . */	    /* Check to see if we have looped through remainder of deck without finding .ends */            if (!c) {                       fprintf(cp_err, "Error: no %s line.\n", sbend);                return (NULL);              }            sss = alloc(struct subs);	    if (!lcc)               /* if lcc is null, then no .ends was found.  */		lcc = last;#ifdef NUMPARAMS            if ( use_numparams==FALSE )#endif	/* NUMPARAMS */     		            lcc->li_next = NULL;    /* shouldn't we free some memory here????? */	    /* At this point, last points to the .subckt card, and lcc points to the .ends card */	    /*  what does this do!??!?!  */            if (lc)                lc->li_next = c->li_next;            else                deck = c->li_next;	    /*  Now put the .subckt definition found into sss  */            sss->su_def = last->li_next;              s = last->li_line;                txfree(gettok(&s));            sss->su_name = gettok(&s);            sss->su_args = copy(s);	    /* count the number of args in the .subckt line */            for (sss->su_numargs = 0, i = 0; s[i]; ) {                while (isspace(s[i]))                    i++;                if (s[i]) {                    sss->su_numargs++;                    while (s[i] && !isspace(s[i]))                        i++;                }            }            sss->su_next = subs;               subs = sss;            /* Now that sss is built, assign it to subs */            last = c->li_next;            lcc = subs->su_def;	    #ifdef NUMPARAMS/*gp */     c->li_next = NULL;  /* Numparam needs line c */             c->li_line[0] = '*'; /* comment it out */#endif /* NUMPARAMS */     	} 	else {  /*  line is neither .ends nor .subckt.  */	  /* make lc point to this card, and advance last to next card. */            lc = last;                last = last->li_next;        }    } /* for (last = deck . . . .  */    /* At this point, sss holds the .subckt definition found, subs holds     * all .subckt defs found, including this one,     * last points to the NULL at the end of the deck,     * lc points to the last non-.subckt or .ends card,      * and lcc points to the .ends card      */    if (!sss)            /* if sss == FALSE, we have found no subckts.  Just return.  */        return (deck);    /* Otherwise, expand sub-subcircuits recursively. */    for (ks = sss = subs; sss; sss = sss->su_next)  /* iterate through the list of subcircuits */        if (!(sss->su_def = doit(sss->su_def)))            return (NULL);    subs = ks;  /* ks has held pointer to start of subcircuits list. */    #ifdef TRACE	/* SDB debug statement */	printf("In doit, about to start second pass through deck.\n");    for(c=deck;c; c=c->li_next)    printf("   %s\n",c->li_line);#endif    error = 0;    /* Second pass: do the replacements. */    do {                    /*  while (!error && numpasses-- && gotone)  */        gotone = FALSE;        for (c = deck, lc = NULL; c; ) {	   if (ciprefix(invoke, c->li_line)) {  /* found reference to .subckt (i.e. component with refdes X)  */		char *tofree, *tofree2;	        gotone = TRUE;                t = tofree = s = copy(c->li_line);       /*  s & t hold copy of component line  */		/*  make scname point to first non-whitepace chars after refdes invocation		 * e.g. if invocation is Xreference, *scname = reference		 */                tofree2 = scname = gettok(&s);                            scname += strlen(invoke);                   while ((*scname == ' ') || (*scname == '\t') ||                        (*scname == ':'))                    scname++;		/*  Now set s to point to last non-space chars in line (i.e.		 *   the name of the model invoked  		 */                while(*s)                    s++;                s--;                while ((*s == ' ') || (*s == '\t'))                    *s-- = '\0';                while ((*s != ' ') && (*s != '\t'))                    s--;                s++;		/* iterate through .subckt list and look for .subckt name invoked */                for (sss = subs; sss; sss = sss->su_next)                      if (eq(sss->su_name, s))                        break;		/* At this point, sss points to the .subckt invoked, 		 * and scname points to the netnames		 * involved.		 */                /* If no .subckt is found, don't complain -- this might be an                 * instance of a subckt that is defined above at higher level.                 */                if (!sss) {                    lc = c;                    c = c->li_next;                    continue;                }                /* Now we have to replace this line with the                 * macro definition.                 */                subname = copy(sss->su_name);  		/*  make lcc point to a copy of the .subckt definition  */                lcc = inp_deckcopy(sss->su_def);                  /* Change the names of .models found in .subckts . . .  */                if (modtranslate(lcc, scname))    /* this translates the model name in the .model line */                    devmodtranslate(lcc, scname); /* This translates the model name on all components in the deck */                s = sss->su_args;                txfree(gettok(&t));  /* Throw out the subcircuit refdes */		/* now invoke translate, which handles the remainder of the		 * translation.		 */                if (!translate(lcc, s, t, scname, subname))		    error = 1;		tfree(subname);                /* Now splice the decks together. */#ifdef NUMPARAMS		savenext =  c->li_next;                if ( use_numparams==FALSE ) {           	    /* old style: c will drop a dangling pointer: memory leak  */		    if (lc)            		lc->li_next = lcc;                    else                    	deck = lcc;                } else {                  /* ifdef NUMPARAMS, keep the invoke line as a comment  */    		  c->li_next = lcc;		  c->li_line[0] = '*'; /* comment it out */		}#else                if (lc)                    lc->li_next = lcc;                else                    deck = lcc;#endif /* NUMPARAMS */                while (lcc->li_next != NULL)                    lcc = lcc->li_next;                lcc->li_next = c->li_next;#ifdef NUMPARAMS                lcc->li_next = savenext;#endif /* NUMPARAMS */			                c = lcc->li_next;                lc = lcc;		tfree(tofree);		tfree(tofree2);            } 	  /* if (ciprefix(invoke, c->li_line)) . . . */	   else {                lc = c;                c = c->li_next;            }        }    } while (!error && numpasses-- && gotone);    if (!numpasses) {        fprintf(cp_err, "Error: infinite subckt recursion\n");        return (NULL);    }#ifdef TRACE    /* Added by H.Tanaka to display converted deck */    printf("Converted deck\n");    for (c = deck; c; c = c->li_next){	    printf( "%s\n",c->li_line);    }    {	wordlist * w;	printf("Models:\n");	for(w = modnames; w; w = w->wl_next)	    printf("%s\n",w->wl_word);    }#endif     if (error)	return NULL;	/* error message already reported; should free( ) */    subs = ts;    modnames = tmodnames;    submod = tsubmod;    return (deck);}/*-------------------------------------------------------------------*//* Copy a deck, including the actual lines.                          *//*-------------------------------------------------------------------*/struct line *inp_deckcopy(struct line *deck){    struct line *d = NULL, *nd = NULL;    while (deck) {        if (nd) {            d->li_next = alloc(struct line);            d = d->li_next;        } else            nd = d = alloc(struct line);        d->li_linenum = deck->li_linenum;        d->li_line = copy(deck->li_line);        if (deck->li_error)            d->li_error = copy(deck->li_error);        d->li_actual = inp_deckcopy(deck->li_actual);        deck = deck->li_next;    }    return (nd);}/*------------------------------------------------------------------------------------------* * Translate all of the device names and node names in the .subckt deck. They are * pre-pended with subname:, unless they are in the formal list, in which case * they are replaced with the corresponding entry in the actual list. * The one special case is node 0 -- this is always ground and we don't * touch it. * * Variable name meanings: * *deck = pointer to subcircuit definition (lcc) (struct line) * formal = copy of the .subckt definition line (e.g. ".subckt subcircuitname 1 2 3") (string) * actual = copy of the .subcircuit invocation line (e.g. "Xexample 4 5 6 subcircuitname") (string) * scname = refdes (- first letter) used at invocation (e.g. "example") (string) * subname = copy of the subcircuit name  *-------------------------------------------------------------------------------------------*/static inttranslate(struct line *deck, char *formal, char *actual, char *scname, char *subname){    struct line *c;    char *buffer, *next_name, dev_type, *name, *s, *t, ch, *nametofree;    int nnodes, i, dim, blen;    int rtn=0;        /* settrans builds the table holding the translated netnames.  */    i = settrans(formal, actual, subname);    if (i < 0) {	fprintf(stderr,	"Too few parameters for subcircuit type \"%s\" (instance: x%s)\n",		subname, scname);	goto quit;    } else if (i > 0) {	fprintf(stderr,	"Too many parameters for subcircuit type \"%s\" (instance: x%s)\n",		subname, scname);	goto quit;    }    /* now iterate through the .subckt deck and translate the cards. */    for (c = deck; c; c = c->li_next) {  #ifdef TRACE      /* SDB debug statement */      printf("\nIn translate, examining line %s \n", c->li_line);#endif            dev_type = *(c->li_line);         /* Rename the device. */        switch (dev_type) {        case '\0':        case '*':        case '.':            /* Just a pointer to the line into s and then break */	  buffer = tmalloc(2000+strlen(c->li_line));    /* DW,VA */	  s = c->li_line;	  break;#ifdef XSPICE/*===================  case A  ====================*//* gtri - add - wbk - 10/23/90 - process A devices specially *//* since they have a more involved and variable length node syntax */	            case 'a':        case 'A':	              /* translate the instance name according to normal rules */            s = c->li_line;            name = MIFgettok(&s);	    /* maschmann             sprintf(buffer, "%s:%s ", name, scname);   */            buffer = (char *)tmalloc((strlen(scname)+strlen(name)+5)*sizeof(char));            sprintf(buffer, "a:%s:%s ", scname, name+1 );                                 /* Now translate the nodes, looking ahead one token to recognize */            /* when we reach the model name which should not be translated   */            /* here.                                                         */            next_name = MIFgettok(&s);            while(1) {                /* rotate the tokens and get the the next one */                name = next_name;                next_name = MIFgettok(&s);                /* if next token is NULL, name holds the model name, so exit */                if(next_name == NULL)                    break;

⌨️ 快捷键说明

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