Browse Source

Unused binning models are removed.

Flag 'nf', when given on the x lines, is
recognized.
Tested with TSMC, Skywater, and X-Fab model
files.
pre-master-46
Holger Vogt 5 years ago
parent
commit
822a63974f
  1. 35
      src/frontend/inp.c
  2. 45
      src/frontend/inpcom.c
  3. 7
      src/frontend/subckt.c
  4. 1
      src/include/ngspice/inpdefs.h

35
src/frontend/inp.c

@ -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? */

45
src/frontend/inpcom.c

@ -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,7 +667,7 @@ 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;
}
}
@ -658,14 +676,13 @@ void inp_get_w_l_x(struct card* card) {
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;
}
}
@ -673,6 +690,20 @@ void inp_get_w_l_x(struct card* card) {
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;
}
}
}

7
src/frontend/subckt.c

@ -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);

1
src/include/ngspice/inpdefs.h

@ -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 */

Loading…
Cancel
Save