Adding degradation monitors
This commit is contained in:
parent
e2046ae7c9
commit
21fbffbccf
|
|
@ -963,6 +963,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
|||
/* Translate all SPICE 2G6 polynomial type sources */
|
||||
deck->nextcard = ENHtranslate_poly(deck->nextcard);
|
||||
#endif
|
||||
/* quote nodes of degmons, is required for parsing the a device node,
|
||||
when [x] is part of a node nname. */
|
||||
int err = 0;
|
||||
err = quote_degmons(deck->nextcard);
|
||||
|
||||
line_free(deck->actualLine, FALSE);
|
||||
deck->actualLine = realdeck;
|
||||
|
|
|
|||
|
|
@ -1100,6 +1100,9 @@ struct card *inp_readall(FILE *fp, const char *dir_name, const char* file_name,
|
|||
/* collect .agemodel data */
|
||||
readdegparams(working);
|
||||
|
||||
/* Add degradation monitors to devices in X lines */
|
||||
adddegmonitors(working);
|
||||
|
||||
if (newcompat.lt && newcompat.a)
|
||||
ltspice_compat_a(working);
|
||||
if (newcompat.ps && newcompat.a)
|
||||
|
|
|
|||
|
|
@ -14,5 +14,7 @@ extern char* inp_remove_ws(char* s);
|
|||
extern char* search_plain_identifier(char* str, const char* identifier);
|
||||
|
||||
extern int readdegparams(struct card* deck);
|
||||
extern int adddegmonitors(struct card* deck);
|
||||
extern int quote_degmons(struct card* deck);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@ int readdegparams (struct card *deck) {
|
|||
ftok = dftok = gettok(&cut_line);
|
||||
/* parameter name */
|
||||
f1 = gettok_char(&ftok, '=', FALSE, FALSE);
|
||||
if (!f1) {
|
||||
fprintf(stderr, "Error: bad.agemodel syntax in line\n % s", card->line);
|
||||
controlled_exit(1);
|
||||
}
|
||||
/* parameter value */
|
||||
f2 = copy(ftok + 1);
|
||||
agemods[ageindex].paramnames[parno] = f1;
|
||||
|
|
@ -116,4 +120,148 @@ int readdegparams (struct card *deck) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Look for an X line.
|
||||
Check if the model in the x line is found in the model list agemodds.
|
||||
Create a degradation monitor for each x line if model found.
|
||||
Add the x instance name to the degmod name.
|
||||
Add degmon line and its model line to the netlist.*/
|
||||
int adddegmonitors(struct card* deck) {
|
||||
static int degmonno;
|
||||
double tfuture = 315336e4;
|
||||
int nodes = 4;
|
||||
if (agemods[0].paramhash == NULL)
|
||||
return 1;
|
||||
for (; deck; deck = deck->nextcard) {
|
||||
int skip_control = 0;
|
||||
|
||||
char* line = deck->line;
|
||||
|
||||
if (*line == '*') {
|
||||
continue;
|
||||
}
|
||||
/* there is no e source inside .control ... .endc */
|
||||
if (ciprefix(".control", line)) {
|
||||
skip_control++;
|
||||
continue;
|
||||
}
|
||||
else if (ciprefix(".endc", line)) {
|
||||
skip_control--;
|
||||
continue;
|
||||
}
|
||||
else if (skip_control > 0) {
|
||||
continue;
|
||||
}
|
||||
if (*line == 'x') {
|
||||
char *modname, *fournodes, *instname;
|
||||
int ii;
|
||||
// fprintf(stdout, "%.80s\n", line);
|
||||
/* x instance model in subcircuit */
|
||||
/* get instance name */
|
||||
instname = gettok_instance(&line);
|
||||
fournodes = line;
|
||||
/* and 4 nodes */
|
||||
for (ii = 0; ii < nodes; ii++)
|
||||
line = nexttok(line);
|
||||
if (!line) {
|
||||
/* Must be something else, not a 4-node MOS */
|
||||
continue;
|
||||
}
|
||||
fournodes = copy_substring(fournodes, line);
|
||||
modname = gettok(&line);
|
||||
|
||||
/*check if model is available in agemods */
|
||||
for (ii = 0; ii < DEGMODMAX; ii++) {
|
||||
if (agemods[ii].devmodel) {
|
||||
if (cieq(modname, agemods[ii].devmodel)) {
|
||||
// fprintf(stdout, "device model %s found as no. %d\n\n", modname, ii);
|
||||
/* get the channel length */
|
||||
char* lpos = strstr(line, "l=");
|
||||
if (!lpos) {
|
||||
fprintf(stderr, "Error, l not found in device %s \n\n", deck->line);
|
||||
return 1;
|
||||
}
|
||||
char* clength = gettok(&lpos);
|
||||
/* Now add a degradation monitor like
|
||||
adegmon1 %v([z a vss vss]) mon degmon1
|
||||
.model degmon1 degmon (tfuture=3153360000 l=0.15e-6 devmod="sg13_lv_nmos")
|
||||
*/
|
||||
char* aline = tprintf("adegmon%d_%s %%v([%s]) mon%d degmon%d\n",
|
||||
degmonno, instname, fournodes, degmonno, degmonno);
|
||||
char* mline = tprintf(".model degmon%d degmon (tfuture=%e %s devmod=\"%s\"\n",
|
||||
degmonno, tfuture, clength, modname);
|
||||
tfree(clength);
|
||||
insert_new_line(deck, aline, 0, deck->linenum_orig, deck->linesource);
|
||||
insert_new_line(deck, mline, 0, deck->linenum_orig, deck->linesource);
|
||||
degmonno++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// fprintf(stderr, "No model found for device %.80s \n\n", deck->line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
tfree(fournodes);
|
||||
tfree(modname);
|
||||
tfree(instname);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int quote_degmons(struct card* deck) {
|
||||
for (; deck; deck = deck->nextcard) {
|
||||
int skip_control = 0;
|
||||
|
||||
char* line = deck->line;
|
||||
|
||||
if (*line == '*') {
|
||||
continue;
|
||||
}
|
||||
/* there is no e source inside .control ... .endc */
|
||||
if (ciprefix(".control", line)) {
|
||||
skip_control++;
|
||||
continue;
|
||||
}
|
||||
else if (ciprefix(".endc", line)) {
|
||||
skip_control--;
|
||||
continue;
|
||||
}
|
||||
else if (skip_control > 0) {
|
||||
continue;
|
||||
}
|
||||
if (*line == 'a' && strstr(line, "adegmon")) {
|
||||
char allnodes[1024];
|
||||
allnodes[0] = '\0';
|
||||
int ii, nodes = 4;
|
||||
char* newnodes, *instname;
|
||||
instname = gettok_instance(&line);
|
||||
/* skip %v */
|
||||
line = nexttok(line);
|
||||
char* deltoken;
|
||||
char* nodetoken = deltoken = gettok_char(&line, ']', false, true);
|
||||
if (!nodetoken)
|
||||
break;
|
||||
/* go beyond '[' */
|
||||
nodetoken++;
|
||||
for (ii = 0; ii < nodes; ii++) {
|
||||
char* nexttoken = gettok(&nodetoken);
|
||||
sprintf(allnodes, "%s \"%s\"", allnodes, nexttoken);
|
||||
if (!nexttoken)
|
||||
break;
|
||||
tfree(nexttoken);
|
||||
}
|
||||
if (!line || eq(line, "")) {
|
||||
/* Must be something else, not a 4-node MOS */
|
||||
continue;
|
||||
}
|
||||
newnodes = tprintf("%s %%v [ %s %s", instname, allnodes, line);
|
||||
|
||||
tfree(deltoken);
|
||||
tfree(instname);
|
||||
tfree(deck->line);
|
||||
deck->line = newnodes;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue