Unused binning models are removed.

Flag 'nf', when given on the x lines, is
recognized.
Tested with TSMC, Skywater, and X-Fab model
files.
This commit is contained in:
Holger Vogt 2021-01-10 12:49:00 +01:00
parent e601325149
commit 822a63974f
4 changed files with 81 additions and 13 deletions

View File

@ -2452,9 +2452,10 @@ static void rem_unused_mos_models(struct card* deck) {
}
for (tmpc = deck; tmpc; tmpc = tmpc->nextcard) {
char* curr_line = tmpc->line;
/* We only look for MOS devices and extract W and L */
/* We only look for MOS devices and extract W, L, nf, and wnflag */
if (*curr_line == 'm') {
float w = 0., l = 0.;
float w = 0., l = 0., nf = 1., wnf = 1.;
int wnflag = 0;
char* wstr = strstr(curr_line, " w=");
if (wstr) {
int err;
@ -2475,6 +2476,36 @@ static void rem_unused_mos_models(struct card* deck) {
continue;
}
}
char* nfstr = strstr(curr_line, " nf=");
if (nfstr) {
int err;
nfstr = nfstr + 4;
nfstr = skip_ws(nfstr);
nf = (float)INPevaluate(&nfstr, &err, 0);
if (err) {
continue;
}
}
char* wnstr = strstr(curr_line, " wnflag=");
if (wnstr) {
int err;
wnstr = wnstr + 8;
wnstr = skip_ws(wnstr);
wnf = (float)INPevaluate(&wnstr, &err, 0);
if (err) {
continue;
}
}
if (!cp_getvar("wnflag", CP_NUM, &wnflag, 0)) {
if (newcompat.spe || newcompat.hs)
wnflag = 1;
else
wnflag = 0;
}
nf = wnflag * wnf > 0.5f ? nf : 1.f;
w = w / nf;
/* what is the device's model name? */
char* mname = nexttok(curr_line);
int nonodes = 4; /* FIXME: this is a hack! How to really detect the number of nodes? */

View File

@ -617,13 +617,32 @@ static void print_compat_mode(void) {
}
/* We check x lines for w= and l= and fill in their values.
To be used when expanding subcircuits with binned model cards. */
/* We check x lines for nf=, w= and l= and fill in their values.
To be used when expanding subcircuits with binned model cards.
In subckt.c, function doit(), lines 621ff. the unsused models
are filtered out. 'nf' given on an x line (subcircuit invocation)
is aknowledged. The option 'wnflag', if set to 0 in .spiceinit,
will set 'nf' to 1 and thus suppress its usage.
In inp.c, function rem_unused_mos_models, another trial to removing
unused MOS models is given, this time on the expanded m lines and
its models.*/
void inp_get_w_l_x(struct card* card) {
int wnflag;
if (!cp_getvar("wnflag", CP_NUM, &wnflag, 0)) {
if (newcompat.spe || newcompat.hs)
wnflag = 1;
else
wnflag = 0;
}
for (; card; card = card->nextcard) {
char* curr_line = card->line;
int skip_control = 0;
char* w = NULL, * l = NULL;
char* w = NULL, * l = NULL, * nf = NULL;
card->w = card->l = 0;
card->nf = 1.;
/* exclude any command inside .control ... .endc */
if (ciprefix(".control", curr_line)) {
@ -639,7 +658,6 @@ void inp_get_w_l_x(struct card* card) {
}
/* only subcircuit invocations */
if (*curr_line != 'x' && !newcompat.hs && !newcompat.spe) {
card->w = card->l = 0;
continue;
}
@ -649,30 +667,43 @@ void inp_get_w_l_x(struct card* card) {
w = w + 3;
card->w = (float)INPevaluate(&w, &err, 0);
if(err) {
card->w = card->l = 0;
card->w = 0;
continue;
}
}
}
else {
card->w = card->l = 0;
continue;
}
l = strstr(curr_line, " l=");
if (l) {
int err;
l = l + 3;
card->l = (float)INPevaluate(&l, &err, 0);
if(err) {
card->w = card->l = 0;
card->l = 0;
continue;
}
}
}
else {
card->w = card->l = 0;
continue;
}
}
nf = strstr(curr_line, " nf=");
if (nf) {
int err;
nf = nf + 4;
card->nf = (float)INPevaluate(&nf, &err, 0);
if (err) {
card->w = card->l = 0;
card->nf = 1.;
continue;
}
}
else {
continue;
}
}
}

View File

@ -698,7 +698,9 @@ doit(struct card *deck, wordlist *modnames) {
}
float csl = (float)scale * c->l;
float csw = (float)scale * c->w;
/* 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) {
/* use the current .model card */
prev = su_deck;
@ -823,6 +825,7 @@ struct card * inp_deckcopy(struct card *deck) {
d->linenum = deck->linenum;
d->w = deck->w;
d->l = deck->l;
d->nf = deck->nf;
d->line = copy(deck->line);
if (deck->error)
d->error = copy(deck->error);
@ -867,6 +870,7 @@ struct card *inp_deckcopy_oc(struct card * deck)
}
d->w = deck->w;
d->l = deck->l;
d->nf = deck->nf;
d->linenum_orig = deck->linenum;
d->linenum = i++;
d->line = copy(deck->line);
@ -923,6 +927,7 @@ struct card* inp_deckcopy_ln(struct card* deck)
}
d->w = deck->w;
d->l = deck->l;
d->nf = deck->nf;
d->linenum_orig = deck->linenum_orig;
d->linenum = deck->linenum;
d->line = copy(deck->line);

View File

@ -84,6 +84,7 @@ struct card {
struct nscope *level;
float w;
float l;
float nf;
};
/* structure used to save models in after they are read during pass 1 */