Redo the transformation vswitch -> pswitch

Parsing takes defaults into account
S switch --> pswitch code model
S_ST switch (with hysreresis) --> SW switch

iswitch not yet done
This commit is contained in:
Holger Vogt 2021-10-06 23:58:03 +02:00
parent e5ca96b039
commit b78bb48ead
1 changed files with 70 additions and 73 deletions

View File

@ -8754,12 +8754,12 @@ static struct card *pspice_compat(struct card *oldcard)
/* first scan: find the vswitch models, transform them and put them into a /* first scan: find the vswitch models, transform them and put them into a
* list */ * list */
bool have_vt = FALSE, have_vh = FALSE;
for (card = newcard; card; card = card->nextcard) { for (card = newcard; card; card = card->nextcard) {
char *str; char* str;
static struct card *subcktline = NULL; static struct card* subcktline = NULL;
static int nesting = 0; static int nesting = 0;
char *cut_line = card->line; char* cut_line = card->line;
if (ciprefix(".subckt", cut_line)) { if (ciprefix(".subckt", cut_line)) {
subcktline = card; subcktline = card;
nesting++; nesting++;
@ -8768,9 +8768,11 @@ static struct card *pspice_compat(struct card *oldcard)
nesting--; nesting--;
if (ciprefix(".model", card->line) && strstr(card->line, "vswitch")) { if (ciprefix(".model", card->line) && strstr(card->line, "vswitch")) {
char *modpar[4]; /* roff ron voff von */
char *modname; double s_values[4] = { 1e6, 1., 0., 1. }; /* default values */
int i; /* roff ron vt vh */
double s_st_values[4] = { 1e12, 1., 0., 0. }; /* default values */
char* modname;
card->line = str = inp_remove_ws(card->line); card->line = str = inp_remove_ws(card->line);
str = nexttok(str); /* throw away '.model' */ str = nexttok(str); /* throw away '.model' */
@ -8779,73 +8781,72 @@ static struct card *pspice_compat(struct card *oldcard)
tfree(modname); tfree(modname);
continue; continue;
} }
/* we have to find 4 parameters, identified by '=', separated by str = nexttok_noparens(str); /* throw away 'vswitch' */
* spaces */ /* the S_ST switch */
char *equalptr[4]; if (strstr(str, "vt=") || strstr(str, "vh=")) {
equalptr[0] = strstr(str, "="); int error;
if (!equalptr[0]) { while (str) {
fprintf(stderr, char* token = gettok_noparens(&str);
"Error: not enough parameters in vswitch model\n " if (!token)
"%s\n", break;
card->line); char* ntoken = strchr(token, '=');
controlled_exit(1); if (!ntoken)
} break;
for (i = 1; i < 4; i++) { ntoken++;
equalptr[i] = strstr(equalptr[i - 1] + 1, "="); double val = INPevaluate(&ntoken, &error, 0);
if (!equalptr[i]) { if (ciprefix("roff=", token))
fprintf(stderr, s_st_values[0] = val;
"Error: not enough parameters in vswitch model\n " else if (ciprefix("ron=", token))
" %s\n", s_st_values[1] = val;
card->line); else if (ciprefix("vt=", token))
controlled_exit(1); s_st_values[2] = val;
else if (ciprefix("vh=", token))
s_st_values[3] = val;
tfree(token);
} }
char* newline = tprintf(".model %s sw (roff=%g ron=%g vt=%g vh=%g)", modname,
s_st_values[0], s_st_values[1], s_st_values[2], s_st_values[3]);
tfree(card->line);
card->line = newline;
} }
for (i = 0; i < 4; i++) { /* the S switch */
equalptr[i] = skip_back_ws(equalptr[i], str); else if (strstr(str, "von=") || strstr(str, "voff=")) {
while (*(equalptr[i]) != '(' && !isspace_c(*(equalptr[i])) && int error;
*(equalptr[i]) != ',') while (str) {
(equalptr[i])--; char* token = gettok_noparens(&str);
(equalptr[i])++; if (!token)
} break;
for (i = 0; i < 3; i++) char* ntoken = strchr(token, '=');
modpar[i] = copy_substring(equalptr[i], equalptr[i + 1] - 1); if (!ntoken)
if (strrchr(equalptr[3], ')')) break;
modpar[3] = copy_substring( ntoken++;
equalptr[3], strrchr(equalptr[3], ')')); double val = INPevaluate(&ntoken, &error, 0);
else if (ciprefix("roff=", token))
/* vswitch defined without parens */ s_values[0] = val;
modpar[3] = copy(equalptr[3]); else if (ciprefix("ron=", token))
s_values[1] = val;
/* check if we have parameters VT and VH */ else if (ciprefix("voff=", token))
for (i = 0; i < 4; i++) { s_values[2] = val;
if (ciprefix("vh", modpar[i])) else if (ciprefix("von=", token))
have_vh = TRUE; s_values[3] = val;
if (ciprefix("vt", modpar[i])) tfree(token);
have_vt = TRUE; }
} /* replace VON by cntl_on, VOFF by cntl_off, RON by r_on, and ROFF by r_off */
if (have_vh && have_vt) { char* newline = tprintf(".model a%s pswitch (r_off=%g r_on=%g cntl_off=%g cntl_on=%g log=TRUE)", modname,
/* replace vswitch by sw */ s_values[0], s_values[1], s_values[2], s_values[3]);
char *vs = strstr(card->line, "vswitch"); tfree(card->line);
memmove(vs, " sw", 7); card->line = newline;
/* enter models into list only for code models */
if (nesting > 0)
modelsfound = insert_new_model(
modelsfound, modname, subcktline->line);
else
modelsfound = insert_new_model(modelsfound, modname, "top");
} }
else { else {
/* replace VON by cntl_on, VOFF by cntl_off, RON by r_on, and fprintf(stderr, "Error: Bad switch model in line %s\n", card->line);
* ROFF by r_off */
tfree(card->line);
rep_spar(modpar);
card->line = tprintf(
// ".model a%s aswitch(%s %s %s %s log=TRUE limit=TRUE)", modname,
// modpar[0], modpar[1], modpar[2], modpar[3]);
".model a%s pswitch(%s %s %s %s log=TRUE)", modname,
modpar[0], modpar[1], modpar[2], modpar[3]);
} }
for (i = 0; i < 4; i++)
tfree(modpar[i]);
if (nesting > 0)
modelsfound = insert_new_model(
modelsfound, modname, subcktline->line);
else
modelsfound = insert_new_model(modelsfound, modname, "top");
tfree(modname); tfree(modname);
} }
} }
@ -8854,10 +8855,6 @@ static struct card *pspice_compat(struct card *oldcard)
if (!modelsfound) if (!modelsfound)
goto iswi; goto iswi;
/* no need to change the switch instances if switch sw is used */
if (have_vh && have_vt)
goto iswi;
/* second scan: find the switch instances s calling a vswitch model and /* second scan: find the switch instances s calling a vswitch model and
* transform them */ * transform them */
for (card = newcard; card; card = card->nextcard) { for (card = newcard; card; card = card->nextcard) {