Revert "Improve error messages when reading (and discarding) binned models,"
This reverts commit 33f18b485a.
This commit is contained in:
parent
72df67271c
commit
7a6a258465
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue