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:
parent
e601325149
commit
822a63974f
|
|
@ -2452,9 +2452,10 @@ static void rem_unused_mos_models(struct card* deck) {
|
||||||
}
|
}
|
||||||
for (tmpc = deck; tmpc; tmpc = tmpc->nextcard) {
|
for (tmpc = deck; tmpc; tmpc = tmpc->nextcard) {
|
||||||
char* curr_line = tmpc->line;
|
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') {
|
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=");
|
char* wstr = strstr(curr_line, " w=");
|
||||||
if (wstr) {
|
if (wstr) {
|
||||||
int err;
|
int err;
|
||||||
|
|
@ -2475,6 +2476,36 @@ static void rem_unused_mos_models(struct card* deck) {
|
||||||
continue;
|
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? */
|
/* what is the device's model name? */
|
||||||
char* mname = nexttok(curr_line);
|
char* mname = nexttok(curr_line);
|
||||||
int nonodes = 4; /* FIXME: this is a hack! How to really detect the number of nodes? */
|
int nonodes = 4; /* FIXME: this is a hack! How to really detect the number of nodes? */
|
||||||
|
|
|
||||||
|
|
@ -617,13 +617,32 @@ static void print_compat_mode(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We check x lines for w= and l= and fill in their values.
|
/* We check x lines for nf=, w= and l= and fill in their values.
|
||||||
To be used when expanding subcircuits with binned model cards. */
|
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) {
|
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) {
|
for (; card; card = card->nextcard) {
|
||||||
char* curr_line = card->line;
|
char* curr_line = card->line;
|
||||||
int skip_control = 0;
|
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 */
|
/* exclude any command inside .control ... .endc */
|
||||||
if (ciprefix(".control", curr_line)) {
|
if (ciprefix(".control", curr_line)) {
|
||||||
|
|
@ -639,7 +658,6 @@ void inp_get_w_l_x(struct card* card) {
|
||||||
}
|
}
|
||||||
/* only subcircuit invocations */
|
/* only subcircuit invocations */
|
||||||
if (*curr_line != 'x' && !newcompat.hs && !newcompat.spe) {
|
if (*curr_line != 'x' && !newcompat.hs && !newcompat.spe) {
|
||||||
card->w = card->l = 0;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -649,7 +667,7 @@ void inp_get_w_l_x(struct card* card) {
|
||||||
w = w + 3;
|
w = w + 3;
|
||||||
card->w = (float)INPevaluate(&w, &err, 0);
|
card->w = (float)INPevaluate(&w, &err, 0);
|
||||||
if(err) {
|
if(err) {
|
||||||
card->w = card->l = 0;
|
card->w = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -658,14 +676,13 @@ void inp_get_w_l_x(struct card* card) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
l = strstr(curr_line, " l=");
|
l = strstr(curr_line, " l=");
|
||||||
if (l) {
|
if (l) {
|
||||||
int err;
|
int err;
|
||||||
l = l + 3;
|
l = l + 3;
|
||||||
card->l = (float)INPevaluate(&l, &err, 0);
|
card->l = (float)INPevaluate(&l, &err, 0);
|
||||||
if(err) {
|
if(err) {
|
||||||
card->w = card->l = 0;
|
card->l = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -673,6 +690,20 @@ void inp_get_w_l_x(struct card* card) {
|
||||||
card->w = card->l = 0;
|
card->w = card->l = 0;
|
||||||
continue;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -698,7 +698,9 @@ doit(struct card *deck, wordlist *modnames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float csl = (float)scale * c->l;
|
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) {
|
if (csl >= flmin && csl < flmax && csw >= fwmin && csw < fwmax) {
|
||||||
/* use the current .model card */
|
/* use the current .model card */
|
||||||
prev = su_deck;
|
prev = su_deck;
|
||||||
|
|
@ -823,6 +825,7 @@ struct card * inp_deckcopy(struct card *deck) {
|
||||||
d->linenum = deck->linenum;
|
d->linenum = deck->linenum;
|
||||||
d->w = deck->w;
|
d->w = deck->w;
|
||||||
d->l = deck->l;
|
d->l = deck->l;
|
||||||
|
d->nf = deck->nf;
|
||||||
d->line = copy(deck->line);
|
d->line = copy(deck->line);
|
||||||
if (deck->error)
|
if (deck->error)
|
||||||
d->error = copy(deck->error);
|
d->error = copy(deck->error);
|
||||||
|
|
@ -867,6 +870,7 @@ struct card *inp_deckcopy_oc(struct card * deck)
|
||||||
}
|
}
|
||||||
d->w = deck->w;
|
d->w = deck->w;
|
||||||
d->l = deck->l;
|
d->l = deck->l;
|
||||||
|
d->nf = deck->nf;
|
||||||
d->linenum_orig = deck->linenum;
|
d->linenum_orig = deck->linenum;
|
||||||
d->linenum = i++;
|
d->linenum = i++;
|
||||||
d->line = copy(deck->line);
|
d->line = copy(deck->line);
|
||||||
|
|
@ -923,6 +927,7 @@ struct card* inp_deckcopy_ln(struct card* deck)
|
||||||
}
|
}
|
||||||
d->w = deck->w;
|
d->w = deck->w;
|
||||||
d->l = deck->l;
|
d->l = deck->l;
|
||||||
|
d->nf = deck->nf;
|
||||||
d->linenum_orig = deck->linenum_orig;
|
d->linenum_orig = deck->linenum_orig;
|
||||||
d->linenum = deck->linenum;
|
d->linenum = deck->linenum;
|
||||||
d->line = copy(deck->line);
|
d->line = copy(deck->line);
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ struct card {
|
||||||
struct nscope *level;
|
struct nscope *level;
|
||||||
float w;
|
float w;
|
||||||
float l;
|
float l;
|
||||||
|
float nf;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* structure used to save models in after they are read during pass 1 */
|
/* structure used to save models in after they are read during pass 1 */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue