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) {
|
||||
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? */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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…
Reference in New Issue