Redo the transformation vswitch -> pswitch
Parsing takes default values into account, when parameter is missing. S vswitch --> pswitch code model S_ST vswitch (with hysreresis) --> SW switch S iswitch --> aswitch code model S_ST iswitch (with hysreresis) --> CSW switch Use string handling for replacements: allow parameter equations in .model lines.
This commit is contained in:
parent
a41cbad50e
commit
86201a85a2
|
|
@ -8077,62 +8077,6 @@ static struct card *ako_model(struct card *startcard)
|
||||||
return returncard;
|
return returncard;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* in out
|
|
||||||
von cntl_on
|
|
||||||
voff cntl_off
|
|
||||||
ron r_on
|
|
||||||
roff r_off
|
|
||||||
*/
|
|
||||||
static int rep_spar(char *inpar[4])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
char *t, *strend;
|
|
||||||
char *tok = inpar[i];
|
|
||||||
if ((t = strstr(tok, "von")) != NULL) {
|
|
||||||
strend = copy(t + 1);
|
|
||||||
tfree(inpar[i]);
|
|
||||||
inpar[i] = tprintf("cntl_%s", strend);
|
|
||||||
tfree(strend);
|
|
||||||
}
|
|
||||||
else if ((t = strstr(tok, "voff")) != NULL) {
|
|
||||||
strend = copy(t + 1);
|
|
||||||
tfree(inpar[i]);
|
|
||||||
inpar[i] = tprintf("cntl_%s", strend);
|
|
||||||
tfree(strend);
|
|
||||||
}
|
|
||||||
else if ((t = strstr(tok, "ion")) != NULL) {
|
|
||||||
strend = copy(t + 1);
|
|
||||||
tfree(inpar[i]);
|
|
||||||
inpar[i] = tprintf("cntl_%s", strend);
|
|
||||||
tfree(strend);
|
|
||||||
}
|
|
||||||
else if ((t = strstr(tok, "ioff")) != NULL) {
|
|
||||||
strend = copy(t + 1);
|
|
||||||
tfree(inpar[i]);
|
|
||||||
inpar[i] = tprintf("cntl_%s", strend);
|
|
||||||
tfree(strend);
|
|
||||||
}
|
|
||||||
else if ((t = strstr(tok, "ron")) != NULL) {
|
|
||||||
strend = copy(t + 1);
|
|
||||||
tfree(inpar[i]);
|
|
||||||
inpar[i] = tprintf("r_%s", strend);
|
|
||||||
tfree(strend);
|
|
||||||
}
|
|
||||||
else if ((t = strstr(tok, "roff")) != NULL) {
|
|
||||||
strend = copy(t + 1);
|
|
||||||
tfree(inpar[i]);
|
|
||||||
inpar[i] = tprintf("r_%s", strend);
|
|
||||||
tfree(strend);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "Bad vswitch parameter %s\n", tok);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vsmodels {
|
struct vsmodels {
|
||||||
char *modelname;
|
char *modelname;
|
||||||
char *subcktline;
|
char *subcktline;
|
||||||
|
|
@ -8752,9 +8696,8 @@ static struct card *pspice_compat(struct card *oldcard)
|
||||||
|
|
||||||
* simple hierachy, as nested subcircuits are not allowed in PSPICE */
|
* simple hierachy, as nested subcircuits are not allowed in PSPICE */
|
||||||
|
|
||||||
/* first scan: find the vswitch models, transform them and put them into a
|
/* first scan: find the vswitch models, transform them and put the S models
|
||||||
* list */
|
into a 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;
|
||||||
|
|
@ -8768,85 +8711,127 @@ 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];
|
|
||||||
char *modname;
|
char *modname;
|
||||||
int i;
|
|
||||||
|
|
||||||
card->line = str = inp_remove_ws(card->line);
|
str = card->line = inp_remove_ws(card->line);
|
||||||
str = nexttok(str); /* throw away '.model' */
|
str = nexttok(str); /* throw away '.model' */
|
||||||
INPgetNetTok(&str, &modname, 0); /* model name */
|
INPgetNetTok(&str, &modname, 0); /* model name */
|
||||||
if (!ciprefix("vswitch", str)) {
|
if (!ciprefix("vswitch", str)) {
|
||||||
tfree(modname);
|
tfree(modname);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* we have to find 4 parameters, identified by '=', separated by
|
str = nexttok_noparens(str); /* throw away 'vswitch' */
|
||||||
* spaces */
|
/* S_ST switch (parameters ron, roff, vt, vh)
|
||||||
char *equalptr[4];
|
* we have to find 0 to 4 parameters, identified by 'vh=' etc.
|
||||||
equalptr[0] = strstr(str, "=");
|
* Parameters not found have to be replaced by their default values. */
|
||||||
if (!equalptr[0]) {
|
if (strstr(str, "vt=") || strstr(str, "vh=")) {
|
||||||
fprintf(stderr,
|
char* newstr;
|
||||||
"Error: not enough parameters in vswitch model\n "
|
char* lstr = copy(str);
|
||||||
"%s\n",
|
char* partstr = strstr(lstr, "ron=");
|
||||||
card->line);
|
if (!partstr) {
|
||||||
controlled_exit(1);
|
newstr = tprintf("%s %s", "ron=1.0", lstr); //default value
|
||||||
}
|
tfree(lstr);
|
||||||
for (i = 1; i < 4; i++) {
|
lstr = newstr;
|
||||||
equalptr[i] = strstr(equalptr[i - 1] + 1, "=");
|
|
||||||
if (!equalptr[i]) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error: not enough parameters in vswitch model\n "
|
|
||||||
" %s\n",
|
|
||||||
card->line);
|
|
||||||
controlled_exit(1);
|
|
||||||
}
|
}
|
||||||
|
partstr = strstr(lstr, "roff=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "roff=1.0e12", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
partstr = strstr(lstr, "vt=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "vt=0", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
partstr = strstr(lstr, "vh=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "vh=0", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
tfree(card->line);
|
||||||
|
if (lstr[strlen(lstr) - 1] == ')')
|
||||||
|
card->line = tprintf(".model %s sw ( %s", modname, lstr);
|
||||||
|
else
|
||||||
|
card->line = tprintf(".model %s sw %s", modname, lstr);
|
||||||
|
tfree(lstr);
|
||||||
|
tfree(modname);
|
||||||
}
|
}
|
||||||
for (i = 0; i < 4; i++) {
|
/* S vswitch (parameters ron, roff, von, voff) */
|
||||||
equalptr[i] = skip_back_ws(equalptr[i], str);
|
/* We have to find 0 to 4 parameters, identified by 'von=' etc. and
|
||||||
while (*(equalptr[i]) != '(' && !isspace_c(*(equalptr[i])) &&
|
* replace them by the pswitch code model parameters
|
||||||
*(equalptr[i]) != ',')
|
* replace VON by cntl_on, VOFF by cntl_off, RON by r_on, and ROFF by r_off.
|
||||||
(equalptr[i])--;
|
* Parameters not found have to be replaced by their default values. */
|
||||||
(equalptr[i])++;
|
else if (strstr(str, "von=") || strstr(str, "voff=")) {
|
||||||
}
|
char* newstr, *begstr;
|
||||||
for (i = 0; i < 3; i++)
|
char* lstr = copy(str);
|
||||||
modpar[i] = copy_substring(equalptr[i], equalptr[i + 1] - 1);
|
/* ron */
|
||||||
if (strrchr(equalptr[3], ')'))
|
char* partstr = strstr(lstr, "ron=");
|
||||||
modpar[3] = copy_substring(
|
if (!partstr) {
|
||||||
equalptr[3], strrchr(equalptr[3], ')'));
|
newstr = tprintf("%s %s", "r_on=1.0", lstr); //default value
|
||||||
else
|
}
|
||||||
/* vswitch defined without parens */
|
else {
|
||||||
modpar[3] = copy(equalptr[3]);
|
begstr = copy_substring(lstr, partstr);
|
||||||
|
newstr = tprintf("%s r_on%s", begstr, partstr + 3);
|
||||||
/* check if we have parameters VT and VH */
|
}
|
||||||
for (i = 0; i < 4; i++) {
|
tfree(lstr);
|
||||||
if (ciprefix("vh", modpar[i]))
|
lstr = newstr;
|
||||||
have_vh = TRUE;
|
/* roff */
|
||||||
if (ciprefix("vt", modpar[i]))
|
partstr = strstr(lstr, "roff=");
|
||||||
have_vt = TRUE;
|
if (!partstr) {
|
||||||
}
|
newstr = tprintf("%s %s", "r_off=1.0e6", lstr); //default value
|
||||||
if (have_vh && have_vt) {
|
}
|
||||||
/* replace vswitch by sw */
|
else {
|
||||||
char *vs = strstr(card->line, "vswitch");
|
begstr = copy_substring(lstr, partstr);
|
||||||
memmove(vs, " sw", 7);
|
newstr = tprintf("%s r_off%s", begstr, partstr + 4);
|
||||||
|
}
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
/* von */
|
||||||
|
partstr = strstr(lstr, "von=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "cntl_on=1", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
begstr = copy_substring(lstr, partstr);
|
||||||
|
newstr = tprintf("%s cntl_on%s", begstr, partstr + 3);
|
||||||
|
}
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
/* voff */
|
||||||
|
partstr = strstr(lstr, "voff=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "cntl_off=0", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
begstr = copy_substring(lstr, partstr);
|
||||||
|
newstr = tprintf("%s cntl_off%s", begstr, partstr + 4);
|
||||||
|
}
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
tfree(card->line);
|
||||||
|
if (lstr[strlen(lstr) - 1] == ')')
|
||||||
|
card->line = tprintf(".model a%s pswitch( log=TRUE %s", modname, lstr);
|
||||||
|
else
|
||||||
|
card->line = tprintf(".model a%s pswitch(%s log=TRUE)", modname, lstr);
|
||||||
|
tfree(lstr);
|
||||||
|
/* add to list, to change vswitch instance to code model line */
|
||||||
|
if (nesting > 0)
|
||||||
|
modelsfound = insert_new_model(
|
||||||
|
modelsfound, modname, subcktline->line);
|
||||||
|
else
|
||||||
|
modelsfound = insert_new_model(modelsfound, modname, "top");
|
||||||
|
tfree(modname);
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -8854,10 +8839,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) {
|
||||||
|
|
@ -8939,7 +8920,6 @@ iswi:;
|
||||||
|
|
||||||
/* first scan: find the iswitch models, transform them and put them into a
|
/* first scan: find the iswitch models, transform them and put them into a
|
||||||
* list */
|
* list */
|
||||||
bool have_it = FALSE, have_ih = 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;
|
||||||
|
|
@ -8953,9 +8933,7 @@ iswi:;
|
||||||
nesting--;
|
nesting--;
|
||||||
|
|
||||||
if (ciprefix(".model", card->line) && strstr(card->line, "iswitch")) {
|
if (ciprefix(".model", card->line) && strstr(card->line, "iswitch")) {
|
||||||
char* modpar[4];
|
|
||||||
char* modname;
|
char* modname;
|
||||||
int i;
|
|
||||||
|
|
||||||
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' */
|
||||||
|
|
@ -8964,6 +8942,122 @@ iswi:;
|
||||||
tfree(modname);
|
tfree(modname);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
str = nexttok_noparens(str); /* throw away 'iswitch' */
|
||||||
|
/* S_ST switch (parameters ron, roff, it, ih)
|
||||||
|
* we have to find 0 to 4 parameters, identified by 'ih=' etc.
|
||||||
|
* Parameters not found have to be replaced by their default values. */
|
||||||
|
if (strstr(str, "it=") || strstr(str, "ih=")) {
|
||||||
|
char* newstr;
|
||||||
|
char* lstr = copy(str);
|
||||||
|
char* partstr = strstr(lstr, "ron=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "ron=1.0", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
partstr = strstr(lstr, "roff=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "roff=1.0e12", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
partstr = strstr(lstr, "it=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "it=0", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
partstr = strstr(lstr, "ih=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "ih=0", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
tfree(card->line);
|
||||||
|
if (lstr[strlen(lstr) - 1] == ')')
|
||||||
|
card->line = tprintf(".model %s csw ( %s", modname, lstr);
|
||||||
|
else
|
||||||
|
card->line = tprintf(".model %s csw %s", modname, lstr);
|
||||||
|
tfree(lstr);
|
||||||
|
tfree(modname);
|
||||||
|
}
|
||||||
|
/* S vswitch (parameters ron, roff, ion, ioff) */
|
||||||
|
/* We have to find 0 to 4 parameters, identified by 'ion=' etc. and
|
||||||
|
* replace them by the pswitch code model parameters
|
||||||
|
* replace VON by cntl_on, VOFF by cntl_off, RON by r_on, and ROFF by r_off.
|
||||||
|
* Parameters not found have to be replaced by their default values. */
|
||||||
|
else if (strstr(str, "ion=") || strstr(str, "ioff=")) {
|
||||||
|
char* newstr, * begstr;
|
||||||
|
char* lstr = copy(str);
|
||||||
|
/* ron */
|
||||||
|
char* partstr = strstr(lstr, "ron=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "r_on=1.0", lstr); //default value
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
begstr = copy_substring(lstr, partstr);
|
||||||
|
newstr = tprintf("%s r_on%s", begstr, partstr + 3);
|
||||||
|
}
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
/* roff */
|
||||||
|
partstr = strstr(lstr, "roff=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "r_off=1.0e6", lstr); //default value
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
begstr = copy_substring(lstr, partstr);
|
||||||
|
newstr = tprintf("%s r_off%s", begstr, partstr + 4);
|
||||||
|
}
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
/* von */
|
||||||
|
partstr = strstr(lstr, "ion=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "cntl_on=1", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
begstr = copy_substring(lstr, partstr);
|
||||||
|
newstr = tprintf("%s cntl_on%s", begstr, partstr + 3);
|
||||||
|
}
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
/* voff */
|
||||||
|
partstr = strstr(lstr, "ioff=");
|
||||||
|
if (!partstr) {
|
||||||
|
newstr = tprintf("%s %s", "cntl_off=0", lstr); //default value
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
begstr = copy_substring(lstr, partstr);
|
||||||
|
newstr = tprintf("%s cntl_off%s", begstr, partstr + 4);
|
||||||
|
}
|
||||||
|
tfree(lstr);
|
||||||
|
lstr = newstr;
|
||||||
|
tfree(card->line);
|
||||||
|
if (lstr[strlen(lstr) - 1] == ')')
|
||||||
|
card->line = tprintf(".model a%s aswitch( log=TRUE limit=TRUE %s", modname, lstr);
|
||||||
|
else
|
||||||
|
card->line = tprintf(".model a%s aswitch(%s log=TRUE limit=TRUE)", modname, lstr);
|
||||||
|
tfree(lstr);
|
||||||
|
/* add to list, to change vswitch instance to code model line */
|
||||||
|
if (nesting > 0)
|
||||||
|
modelsfound = insert_new_model(
|
||||||
|
modelsfound, modname, subcktline->line);
|
||||||
|
else
|
||||||
|
modelsfound = insert_new_model(modelsfound, modname, "top");
|
||||||
|
tfree(modname);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Error: Bad switch model in line %s\n", card->line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if(0)
|
||||||
/* we have to find 4 parameters, identified by '=', separated by
|
/* we have to find 4 parameters, identified by '=', separated by
|
||||||
* spaces */
|
* spaces */
|
||||||
char* equalptr[4];
|
char* equalptr[4];
|
||||||
|
|
@ -9033,15 +9127,11 @@ iswi:;
|
||||||
tfree(modname);
|
tfree(modname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* no need to continue if no iswitch is found */
|
/* no need to continue if no iswitch is found */
|
||||||
if (!modelsfound)
|
if (!modelsfound)
|
||||||
return newcard;
|
return newcard;
|
||||||
|
|
||||||
/* no need to change the switch instances if switch csw is used */
|
|
||||||
if (have_ih && have_it)
|
|
||||||
return newcard;
|
|
||||||
|
|
||||||
/* second scan: find the switch instances s calling an iswitch model and
|
/* second scan: find the switch instances s calling an iswitch model and
|
||||||
* transform them */
|
* transform them */
|
||||||
for (card = newcard; card; card = card->nextcard) {
|
for (card = newcard; card; card = card->nextcard) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue