From 10c69b8d05635a38453955a5fa54a7b8aaa2d3c9 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 18 May 2018 15:25:19 +0200 Subject: [PATCH] replace S1 D S DG GND SWN by a1 %v(DG) %gd(D S) swa --- src/frontend/inpcom.c | 208 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 31bafe459..404d02fa1 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -6337,6 +6337,50 @@ inp_meas_current(struct card *deck) } } +/* in out + von cntl_on + voff cntl_off + ron r_on + roff r_off +*/ +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, "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; +} static struct card * pspice_compat(struct card *oldcard) @@ -6521,5 +6565,169 @@ pspice_compat(struct card *oldcard) } } } + +/* replace +* S1 D S DG GND SWN +* .MODEL SWN VSWITCH ( VON = {0.55} VOFF = {0.49} RON={1/(2*M*(W/LE)*(KPN/2)*10)} ROFF={1G} ) +* by +* a1 %v(DG) %gd(D S) swa +* .MODEL SWA aswitch(cntl_off=0.49 cntl_on=0.55 r_off=1G r_on={1/(2*M*(W/LE)*(KPN/2)*10)} log=TRUE) */ + for (card = newcard; card; card = card->nextcard) { + static struct card *subcktline = NULL; + static int nesting = 0; + char *cut_line = card->line; + if (*cut_line == '*') + continue; + // exclude any command inside .control ... .endc + if (ciprefix(".control", cut_line)) { + skip_control++; + continue; + } + else if (ciprefix(".endc", cut_line)) { + skip_control--; + continue; + } + else if (skip_control > 0) { + continue; + } + if (ciprefix(".subckt", cut_line)) { + subcktline = card; + nesting++; + } + if (ciprefix(".ends", cut_line)) + nesting--; + + if (ciprefix("s", cut_line)) { + /* check for the model name */ + int i; + struct card *modcard; + char *stoks[6]; + for (i = 0; i < 6; i++) + stoks[i] = gettok(&cut_line); + /* rewrite s line */ + tfree(card->line); + card->line = tprintf("a%s %%vd(%s %s) %%gd(%s %s) a%s", + stoks[0], stoks[3], stoks[4], stoks[1], stoks[2], stoks[5]); + /* find the corresponding model */ + if(nesting > 0) + /* inside of subckt, only same level */ + for (modcard = subcktline; ; modcard = modcard->nextcard) { + char *str; + if (ciprefix(".ends", modcard->line)) + break; + if (ciprefix(".model", modcard->line) && strstr(modcard->line, stoks[5]) && strstr(modcard->line, "vswitch")) { + char *modpar[4]; + modcard->line = str = inp_remove_ws(modcard->line); + str = nexttok(str); /* throw away '.model' */ + str = nexttok(str); /* throw away 'modname' */ + if (!ciprefix("vswitch", str)) + goto next_loop; +#ifndef XSPICE + else { + fprintf(stderr, "Error: vswitch device requires XSPICE \n"); + controlled_exit(1); + } +#endif + /* we have to find 4 parameters, identified by '=', separated by spaces */ + char *equalptr[4]; + equalptr[0] = strstr(str, "="); + if (!equalptr[0]) { + fprintf(stderr, "Error: not enough parameters in vswitch model\n %s\n", modcard->line); + controlled_exit(1); + } + for (i = 1; i < 4; i++) { + equalptr[i] = strstr(equalptr[i - 1] + 1, "="); + if (!equalptr[i]) { + fprintf(stderr, "Error: not enough parameters in vswitch model\n %s\n", modcard->line); + controlled_exit(1); + } + } + for (i = 0; i < 4; i++) { + equalptr[i] = skip_back_ws(equalptr[i], str); + equalptr[i] = skip_back_non_ws(equalptr[i], str); + } + for (i = 0; i < 3; i++) + modpar[i] = copy_substring(equalptr[i], equalptr[i + 1] - 1); + if (strrchr(equalptr[3], ')')) + modpar[3] = copy_substring(equalptr[3], strrchr(equalptr[3], ')')); + else + /* vswitch defined without parens */ + modpar[3] = copy(equalptr[3]); + tfree(modcard->line); + /* .model is now in modcard, tokens in modpar, call to s in card, tokens in stoks */ + /* rewrite .model line (modcard->li_line already freed in inp_remove_ws()) + Replace VON by cntl_on, VOFF by cntl_off, RON by r_on, and ROFF by r_off */ + rep_spar(modpar); + modcard->line = tprintf(".model a%s aswitch(%s %s %s %s log=TRUE)", + stoks[5], modpar[0], modpar[1], modpar[2], modpar[3]); + for (i = 0; i < 4; i++) + tfree(modpar[i]); + break; + } + } + else + /* at top level only or if no model is found at sub-level */ + for (modcard = newcard; modcard; modcard = modcard->nextcard) { + static int inesting = 0; + char *str; + if (ciprefix(".subckt", modcard->line)) { + inesting++; + } + if (ciprefix(".ends", modcard->line)) + inesting--; + if ((inesting == 0) && ciprefix(".model", modcard->line) && strstr(modcard->line, stoks[5]) && strstr(modcard->line, "vswitch")) { + char *delstr; + char *modpar[4]; + delstr = str = inp_remove_ws(modcard->line); + str = nexttok(str); /* throw away '.model' */ + str = nexttok(str); /* throw away 'modname' */ + if (!ciprefix("vswitch", str)) + goto next_loop; +#ifndef XSPICE + else { + fprintf(stderr, "Error: vswitch device requires XSPICE \n"); + controlled_exit(1); + } +#endif + /* we have to find 4 parameters, identified by '=', separated by spaces */ + char *equalptr[4]; + equalptr[0] = strstr(str, "="); + if (!equalptr[0]) { + fprintf(stderr, "Error: not enough parameters in vswitch model\n %s\n", modcard->line); + controlled_exit(1); + } + for (i = 1; i < 4; i++) { + equalptr[i] = strstr(equalptr[i - 1] + 1, "="); + if (!equalptr[i]) { + fprintf(stderr, "Error: not enough parameters in vswitch model\n %s\n", modcard->line); + controlled_exit(1); + } + } + for (i = 0; i < 4; i++) { + equalptr[i] = skip_back_ws(equalptr[i], str); + equalptr[i] = skip_back_non_ws(equalptr[i], str); + } + for (i = 0; i < 3; i++) + modpar[i] = copy_substring(equalptr[i], equalptr[i + 1] - 1); + modpar[3] = copy_substring(equalptr[3], strrchr(equalptr[3], ')')); + + tfree(modcard->line); + /* .model is now in modcard, tokens in modpar, call to s in card, tokens in stoks */ + /* rewrite .model line (already freed in inp_remove_ws()) + Replace VON by cntl_on, VOFF by cntl_off, RON by r_on, and ROFF by r_off */ + rep_spar(modpar); + modcard->line = tprintf(".model a%s aswitch ( %s %s %s %s log=TRUE )", + stoks[5], modpar[0], modpar[1], modpar[2], modpar[3]); + for (i = 0; i < 4; i++) + tfree(modpar[i]); + } + } + for (i = 0; i < 6; i++) + tfree(stoks[i]); + } + next_loop: + continue; + } + return newcard; }