From a2fd346b1a752ce18be3a06c2a45d3376fbf76b2 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Mon, 2 May 2022 11:41:25 -0700 Subject: [PATCH] Trial run at scanning cards for Pspice U* devices and models. #define INTEGRATE_UDEVICES to turn it on. No new cards are created yet, just lots of debugging info. --- src/frontend/inpcom.c | 115 +++++++++++++++++++++++++++++++++ src/frontend/udevices.c | 15 ++++- src/include/ngspice/udevices.h | 2 +- 3 files changed, 128 insertions(+), 4 deletions(-) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 1c5df41ed..4b8e9a87c 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -52,6 +52,11 @@ Author: 1985 Wayne A. Christopher /* gtri - end - 12/12/90 */ #endif +/* #define INTEGRATE_UDEVICES */ +#ifdef INTEGRATE_UDEVICES +#include "ngspice/udevices.h" +#endif + /* SJB - Uncomment this line for debug tracing */ /*#define TRACE*/ @@ -8281,6 +8286,109 @@ static void rem_double_braces(struct card* newcard) } } +#ifdef INTEGRATE_UDEVICES +static struct card *u_instances(struct card *startcard) +{ + struct card *card, *returncard = NULL, *subcktcard = NULL; + int level = 0; + int models_ok = 0, models_not_ok = 0; + int udev_ok = 0, udev_not_ok = 0; + BOOL create_called = FALSE, repeat_pass = FALSE; + BOOL skip_next = FALSE; + + card = startcard; + while (card) { + char *cut_line = card->line; + + skip_next = FALSE; + printf("line: %s\n", cut_line); + if (ciprefix(".subckt", cut_line)) { + models_ok = models_not_ok = 0; + udev_ok = udev_not_ok = 0; + level++; + if (level > 1) { + /* Bail out */ + printf("Too many nesting levels\n"); + break; + } + subcktcard = card; + printf("** subckt: %s\n", cut_line); + if (!repeat_pass) { + if (create_called) { + cleanup_model_xlator(); + } + create_model_xlator(); + create_called = TRUE; + printf("Doing first pass\n"); + } else { + printf("Doing second pass\n"); + } + } else if (ciprefix(".ends", cut_line)) { + level--; + printf("** ends: %s\n", cut_line); + if (repeat_pass) { + printf("Second pass "); + } else { + printf("First pass "); + } + printf("udev_ok=%d udev_not_ok=%d models_ok=%d models_not_ok=%d\n", + udev_ok, udev_not_ok, models_ok, models_not_ok); + if (models_not_ok > 0 || udev_not_ok > 0) { + repeat_pass = FALSE; + cleanup_model_xlator(); + create_called = FALSE; + } else if (udev_ok > 0) { + printf("Repeat subckt\n"); + repeat_pass = TRUE; + card = subcktcard; + skip_next = TRUE; + } else { + repeat_pass = FALSE; + cleanup_model_xlator(); + create_called = FALSE; + } + subcktcard = NULL; + } else if (ciprefix(".model", cut_line)) { + if (subcktcard && !repeat_pass) { + printf("** model: %s\n", cut_line); + if (!u_process_model_line(cut_line)) { + printf("Unable to convert model\n"); + models_not_ok++; + } else { + models_ok++; + } + } + } else if (ciprefix("u", cut_line)) { + if (subcktcard) { + printf("** instance: %s\n", cut_line); + if (repeat_pass) { + if (!u_process_instance(cut_line)) { + /* Bail out */ + printf("Unable to convert instance\n"); + break; + } + } else { + if (u_check_instance(cut_line)) { + printf("Instance can be converted\n"); + udev_ok++; + } else { + printf("Instance can NOT be converted\n"); + udev_not_ok++; + } + } + } + } + if (!skip_next) { + card = card->nextcard; + } + } + if (create_called) { + cleanup_model_xlator(); + } + return returncard; +} +#endif + /**** PSPICE to ngspice ************** * .model replacement in ako (a kind of) model descriptions * replace the E source TABLE function by a B source pwl @@ -8326,6 +8434,13 @@ static struct card *pspice_compat(struct card *oldcard) controlled_exit(1); } +#ifdef INTEGRATE_UDEVICES + { + struct card *ucard; + ucard = u_instances(oldcard); + } +#endif + /* Process .distribution cards. */ do_distribution(oldcard); diff --git a/src/frontend/udevices.c b/src/frontend/udevices.c index e16e8b976..3f3bcc7f5 100644 --- a/src/frontend/udevices.c +++ b/src/frontend/udevices.c @@ -50,7 +50,7 @@ TODO add support for compound gates, srff, pullup/down */ -/* #define TRACE */ +#define TRACE /* device types */ #define D_AND 0 @@ -203,8 +203,10 @@ static char *find_xspice_for_delay(char *itype) if (strcmp(itype, "and3") == 0) { return xspice_tab[D_AND]; } if (strcmp(itype, "and3a") == 0) { return xspice_tab[D_AND]; } +/* Not implemented if (strcmp(itype, "ao") == 0) { return xspice_tab[D_AO]; } if (strcmp(itype, "aoi") == 0) { return xspice_tab[D_AOI]; } +*/ break; } case 'b': { @@ -259,17 +261,23 @@ static char *find_xspice_for_delay(char *itype) if (strcmp(itype, "or3") == 0) { return xspice_tab[D_OR]; } if (strcmp(itype, "or3a") == 0) { return xspice_tab[D_OR]; } +/* Not implemented if (strcmp(itype, "oa") == 0) { return xspice_tab[D_OA]; } if (strcmp(itype, "oai") == 0) { return xspice_tab[D_OAI]; } +*/ break; } case 'p': { +/* Not implemented if (strcmp(itype, "pulldn") == 0) { return xspice_tab[D_DOWN]; } if (strcmp(itype, "pullup") == 0) { return xspice_tab[D_UP]; } +*/ break; } case 's': { +/* Not implemented if (strcmp(itype, "srff") == 0) { return xspice_tab[D_SRFF]; } +*/ break; } case 'x': { @@ -2474,15 +2482,16 @@ BOOL u_process_model_line(char *line) /* Translate a .model line to find the delays */ /* Return TRUE if ok */ char *newline; + BOOL retval; size_t n = strlen(line) - 1; if (n > 0 && line[n] == '\n') line[n] = '\0'; if (strncmp(line, ".model ", strlen(".model ")) == 0) { newline = TMALLOC(char, strlen(line) + 1); (void) memcpy(newline, line, strlen(line) + 1); - u_process_model(newline, line, "model_new_name", "d_xspice"); + retval = u_process_model(newline, line, "model_new_name", "d_xspice"); tfree(newline); - return TRUE; + return retval; } else { return FALSE; } diff --git a/src/include/ngspice/udevices.h b/src/include/ngspice/udevices.h index 5312189a7..116ef9fe9 100644 --- a/src/include/ngspice/udevices.h +++ b/src/include/ngspice/udevices.h @@ -3,7 +3,7 @@ BOOL u_process_instance(char *line); BOOL u_process_model_line(char *line); -BOOL u_check_instaance(char *line); +BOOL u_check_instance(char *line); void create_model_xlator(void); void cleanup_model_xlator(void);