From 7a6a25846598c17d53f79d3548759f85e884500a Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 23 May 2025 14:23:48 +0200 Subject: [PATCH] Revert "Improve error messages when reading (and discarding) binned models," This reverts commit 33f18b485ad59f515ba94b73fafebbaba84f4def. --- src/frontend/subckt.c | 68 +++++++++++++---------------------- src/spicelib/parser/inpgmod.c | 3 +- 2 files changed, 25 insertions(+), 46 deletions(-) diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index d7ec7ce7c..4cb7be417 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -583,18 +583,11 @@ doit(struct card *deck, wordlist *modnames) { scale = 1; error = 0; - /* Second pass: do the replacements. - Check if binning is used for .model inside of the subcircuit. - Reduce .model lines to the one with appropriate w and l. - (Inspired by Skywater PDK with excessive use of binning (161 bins) - in the subcircuit referencing a MOS device) */ + /* Second pass: do the replacements. */ do { /* while (!error && numpasses-- && gotone) */ struct card *c = deck; struct card *prev_of_c = NULL; - bool foundmodel = FALSE; - gotone = FALSE; - for (; c; prev_of_c = c, c = c->nextcard) { if (ciprefix(invoke, c->line)) { /* found reference to .subckt (i.e. component with refdes X) */ @@ -604,13 +597,16 @@ doit(struct card *deck, wordlist *modnames) { gotone = TRUE; t = tofree = s = copy(c->line); /* s & t hold copy of component line */ - /* scname contains the refdes Xname */ + /* 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 the x line (i.e. - * the name of the model invoked) + /* Now set s to point to last non-space chars in line (i.e. + * the name of the model invoked */ while (*s) s++; @@ -621,47 +617,38 @@ doit(struct card *deck, wordlist *modnames) { s--; s++; - /* Iterate through .subckt list and look for .subckt name - corresponding to the subckt name extracted from the x line */ + /* 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, - * c is the card with the x line. - * scname points to the netname of the x line involved. - * s is the subckt name extracted from the x line. - * sss points to the subcircuit referenced by the x line - * sss->su_def is the contents of the subcircuit. + + /* 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) { // tprint(sss->su_def); - - /* copy of the contents between .subckt and .ends */ struct card *su_deck = inp_deckcopy(sss->su_def); /* If we have modern PDKs, we have to reduce the amount of memory required. We try to reduce the models to the one really used. - Otherwise su_deck is full of unused binning models. - c->w > 0 and c->l > 0 point to an x line with given w and l - (typically a call to a MOS device). */ + Otherwise su_deck is full of unused binning models.*/ if ((newcompat.hs || newcompat.spe) && c->w > 0 && c->l > 0) { /* extract wmin, wmax, lmin, lmax */ - struct card* enter_su_deck = su_deck; + struct card* new_deck = su_deck; struct card* prev = NULL; while (su_deck) { - /* find a .model line */ if (!ciprefix(".model", su_deck->line)) { prev = su_deck; su_deck = su_deck->nextcard; continue; } - /* check if line contains wmin, wmax, lmin, lmax - if available, extract its values, - if not, go to next line */ + char* curr_line = su_deck->line; float fwmin, fwmax, flmin, flmax; char *wmin = strstr(curr_line, " wmin="); @@ -729,39 +716,32 @@ doit(struct card *deck, wordlist *modnames) { su_deck = su_deck->nextcard; continue; } - /* check if x line's w and l are withing the limites of wmin, wmax, lmin, lmax */ + float csl = (float)scale * c->l; /* scale by nf */ float csw = (float)scale * c->w / c->nf; /*fprintf(stdout, "Debug: nf = %f\n", c->nf);*/ if (csl >= flmin && csl < flmax && csw >= fwmin && csw < fwmax) { - /* if within the limits, use the current .model card */ + /* use the current .model card */ prev = su_deck; su_deck = su_deck->nextcard; - foundmodel = TRUE; continue; } else { - /* if not within the limits, - delete the .model line not fitting the device */ struct card* tmpcard = su_deck->nextcard; line_free_x(prev->nextcard, FALSE); su_deck = prev->nextcard = tmpcard; } } - /* go back to the first card of su_deck */ - su_deck = enter_su_deck; + su_deck = new_deck; } - if (!foundmodel && (newcompat.hs || newcompat.spe) && c->w > 0 && c->l > 0) { - fprintf(stderr, "\nError: Could not find a model\n" - " for device %s in transistor subcircuit %s\n", scname, sss->su_name); - fprintf(stderr, " with w = %.3g and l = %.3g\n\n", c->w, c->l); + if (!su_deck) { + fprintf(stderr, "\nError: Could not find a model for device %s in subcircuit %s\n", + scname, sss->su_name); controlled_exit(1); } - foundmodel = FALSE; - struct card *rest_of_c = c->nextcard; /* Now we have to replace this line with the @@ -802,8 +782,8 @@ doit(struct card *deck, wordlist *modnames) { tfree(tofree); tfree(tofree2); - } /* if (ciprefix(invoke, c->line)) */ - } /* for (; c; prev_of_c = c, c = c->nextcard) */ + } + } } while (!error && numpasses-- && gotone); diff --git a/src/spicelib/parser/inpgmod.c b/src/spicelib/parser/inpgmod.c index ac7e88b09..64c402d7e 100644 --- a/src/spicelib/parser/inpgmod.c +++ b/src/spicelib/parser/inpgmod.c @@ -292,7 +292,6 @@ INPgetModBin(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab, char for (modtmp = modtab; modtmp; modtmp = modtmp->INPnextModel) { - /* exact: 1, with binning extension .[0-9]: 2*/ if (model_name_match(name, modtmp->INPmodName) < 2) continue; @@ -335,8 +334,8 @@ INPgetModBin(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab, char *model = modtmp; return NULL; } - fprintf(stderr, "Warning: no model found for w=%.3e and l=%.3e\n", w, l); } + return NULL; }