📄 subckt.c
字号:
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 + -