Revert "Improve error messages when reading (and discarding) binned models,"

This reverts commit 33f18b485a.
This commit is contained in:
Holger Vogt 2025-05-23 14:23:48 +02:00
parent 72df67271c
commit 7a6a258465
2 changed files with 25 additions and 46 deletions

View File

@ -583,18 +583,11 @@ doit(struct card *deck, wordlist *modnames) {
scale = 1; scale = 1;
error = 0; error = 0;
/* Second pass: do the replacements. /* 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) */
do { /* while (!error && numpasses-- && gotone) */ do { /* while (!error && numpasses-- && gotone) */
struct card *c = deck; struct card *c = deck;
struct card *prev_of_c = NULL; struct card *prev_of_c = NULL;
bool foundmodel = FALSE;
gotone = FALSE; gotone = FALSE;
for (; c; prev_of_c = c, c = c->nextcard) { for (; c; prev_of_c = c, c = c->nextcard) {
if (ciprefix(invoke, c->line)) { /* found reference to .subckt (i.e. component with refdes X) */ 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; gotone = TRUE;
t = tofree = s = copy(c->line); /* s & t hold copy of component line */ 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); tofree2 = scname = gettok(&s);
/*scname += strlen(invoke); */
while ((*scname == ' ') || (*scname == '\t') || (*scname == ':')) while ((*scname == ' ') || (*scname == '\t') || (*scname == ':'))
scname++; scname++;
/* Now set s to point to last non-space chars in the x line (i.e. /* Now set s to point to last non-space chars in line (i.e.
* the name of the model invoked) * the name of the model invoked
*/ */
while (*s) while (*s)
s++; s++;
@ -621,47 +617,38 @@ doit(struct card *deck, wordlist *modnames) {
s--; s--;
s++; s++;
/* Iterate through .subckt list and look for .subckt name /* iterate through .subckt list and look for .subckt name invoked */
corresponding to the subckt name extracted from the x line */
for (sss = subs; sss; sss = sss->su_next) for (sss = subs; sss; sss = sss->su_next)
if (eq(sss->su_name, s)) if (eq(sss->su_name, s))
break; break;
/* At this point,
* c is the card with the x line. /* At this point, sss points to the .subckt invoked,
* scname points to the netname of the x line involved. * and scname points to the netnames
* s is the subckt name extracted from the x line. * involved.
* sss points to the subcircuit referenced by the x line
* sss->su_def is the contents of the subcircuit.
*/ */
/* If no .subckt is found, don't complain -- this might be an /* If no .subckt is found, don't complain -- this might be an
* instance of a subckt that is defined above at higher level. * instance of a subckt that is defined above at higher level.
*/ */
if (sss) { if (sss) {
// tprint(sss->su_def); // tprint(sss->su_def);
/* copy of the contents between .subckt and .ends */
struct card *su_deck = inp_deckcopy(sss->su_def); struct card *su_deck = inp_deckcopy(sss->su_def);
/* If we have modern PDKs, we have to reduce the amount of memory required. /* 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. We try to reduce the models to the one really used.
Otherwise su_deck is full of unused binning models. 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). */
if ((newcompat.hs || newcompat.spe) && c->w > 0 && c->l > 0) { if ((newcompat.hs || newcompat.spe) && c->w > 0 && c->l > 0) {
/* extract wmin, wmax, lmin, lmax */ /* extract wmin, wmax, lmin, lmax */
struct card* enter_su_deck = su_deck; struct card* new_deck = su_deck;
struct card* prev = NULL; struct card* prev = NULL;
while (su_deck) { while (su_deck) {
/* find a .model line */
if (!ciprefix(".model", su_deck->line)) { if (!ciprefix(".model", su_deck->line)) {
prev = su_deck; prev = su_deck;
su_deck = su_deck->nextcard; su_deck = su_deck->nextcard;
continue; 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; char* curr_line = su_deck->line;
float fwmin, fwmax, flmin, flmax; float fwmin, fwmax, flmin, flmax;
char *wmin = strstr(curr_line, " wmin="); char *wmin = strstr(curr_line, " wmin=");
@ -729,39 +716,32 @@ doit(struct card *deck, wordlist *modnames) {
su_deck = su_deck->nextcard; su_deck = su_deck->nextcard;
continue; continue;
} }
/* check if x line's w and l are withing the limites of wmin, wmax, lmin, lmax */
float csl = (float)scale * c->l; float csl = (float)scale * c->l;
/* scale by nf */ /* scale by nf */
float csw = (float)scale * c->w / c->nf; float csw = (float)scale * c->w / c->nf;
/*fprintf(stdout, "Debug: nf = %f\n", c->nf);*/ /*fprintf(stdout, "Debug: nf = %f\n", c->nf);*/
if (csl >= flmin && csl < flmax && csw >= fwmin && csw < fwmax) { 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; prev = su_deck;
su_deck = su_deck->nextcard; su_deck = su_deck->nextcard;
foundmodel = TRUE;
continue; continue;
} }
else { else {
/* if not within the limits,
delete the .model line not fitting the device */
struct card* tmpcard = su_deck->nextcard; struct card* tmpcard = su_deck->nextcard;
line_free_x(prev->nextcard, FALSE); line_free_x(prev->nextcard, FALSE);
su_deck = prev->nextcard = tmpcard; su_deck = prev->nextcard = tmpcard;
} }
} }
/* go back to the first card of su_deck */ su_deck = new_deck;
su_deck = enter_su_deck;
} }
if (!foundmodel && (newcompat.hs || newcompat.spe) && c->w > 0 && c->l > 0) { if (!su_deck) {
fprintf(stderr, "\nError: Could not find a model\n" fprintf(stderr, "\nError: Could not find a model for device %s in subcircuit %s\n",
" for device %s in transistor subcircuit %s\n", scname, sss->su_name); scname, sss->su_name);
fprintf(stderr, " with w = %.3g and l = %.3g\n\n", c->w, c->l);
controlled_exit(1); controlled_exit(1);
} }
foundmodel = FALSE;
struct card *rest_of_c = c->nextcard; struct card *rest_of_c = c->nextcard;
/* Now we have to replace this line with the /* Now we have to replace this line with the
@ -802,8 +782,8 @@ doit(struct card *deck, wordlist *modnames) {
tfree(tofree); tfree(tofree);
tfree(tofree2); tfree(tofree2);
} /* if (ciprefix(invoke, c->line)) */ }
} /* for (; c; prev_of_c = c, c = c->nextcard) */ }
} while (!error && numpasses-- && gotone); } while (!error && numpasses-- && gotone);

View File

@ -292,7 +292,6 @@ INPgetModBin(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab, char
for (modtmp = modtab; modtmp; modtmp = modtmp->INPnextModel) { for (modtmp = modtab; modtmp; modtmp = modtmp->INPnextModel) {
/* exact: 1, with binning extension .[0-9]: 2*/
if (model_name_match(name, modtmp->INPmodName) < 2) if (model_name_match(name, modtmp->INPmodName) < 2)
continue; continue;
@ -335,8 +334,8 @@ INPgetModBin(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab, char
*model = modtmp; *model = modtmp;
return NULL; return NULL;
} }
fprintf(stderr, "Warning: no model found for w=%.3e and l=%.3e\n", w, l);
} }
return NULL; return NULL;
} }