From 6f3f1951588754ef7d302635a9c0c1d5e2cbd9ab Mon Sep 17 00:00:00 2001 From: pnenzi Date: Tue, 9 Oct 2007 07:19:45 +0000 Subject: [PATCH] Additions from Phil Barker (subckt nodeset and ic, simvars, mosfet binning, various fixes) --- ChangeLog | 24 ++++++++++++----- src/frontend/outitf.c | 4 +-- src/frontend/runcoms2.c | 3 +++ src/frontend/subckt.c | 33 +++++++++++++++++++++-- src/frontend/variable.c | 46 +++++++++++++++++++++++++++----- src/include/cpextern.h | 7 +++++ src/spicelib/analysis/cktdojob.c | 4 +-- src/spicelib/parser/Makefile.am | 1 + src/spicelib/parser/inp2m.c | 15 ++++++++++- 9 files changed, 118 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8ca40e6b..a72de3b3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,16 @@ -2007-10-8 Paolo Nenzi +2007-10-09 Paolo Nenzi + * src/frontend/cktdojob.c: Chenged of reporting analysis temperature + from Kelvins to Celsius (as suggested from Phil Barker). + * src/spicelib/parser/inp2m.c: Added model binning code left out in the + previous commit. + * src/frontend/variable.c: Added SIMVARS from Phil Barker. + * src/frontend/{outitf.c,runcoms2.c}, src/include/cpextern.h: Patch from + Phil Barker. + * src/frontend/subckt.c: allow for .ic, .nodeset names to be embedded + in a subckt;enhanced subckt.c to created appropriate node names for + flattened simulation netlist (Phil Barker). + +2007-10-08 Paolo Nenzi * src/main.c, src/frontend/{spiceif.c, spiceif.h, subckt.c}, src/include/{fteext.h, inpdefs.h}, src/spicelib/parser/{inp.h, inp2dot.c, inpdomod.c, inpfindv.c, @@ -8,7 +20,7 @@ - enhanced the interactive command 'alter' to allow for changing the model of a device -2007-10-8 Paolo Nenzi +2007-10-08 Paolo Nenzi * src/frontend/{inp.c, inpcom.c, inpcom.h, measure.c, nutimp.c, runcoms.c subckt.c, ftedefs.c, fteext.c, dctran.c, inp2dot.c, inppas2.c}: added several improvements mad by Phil Barker: @@ -25,21 +37,21 @@ - changed the flattened netlist names created in 'subckt.c' to match other spice simulators -2007-10-8 Paolo Nenzi +2007-10-08 Paolo Nenzi * src/frontend/{rawfile.c, outitf.c, runcoms.c}, src/include/ftedefs.h: modified current vectors output amd added struct elements for holding the name of the last analysis run (all from Phil Barker patch). -2007-10-8 Paolo Nenzi +2007-10-08 Paolo Nenzi *src/frontend/{device.c, device.h}: modified 'show' command to match SmartSpice syntax from Phil Barker patch. -2007-10-8 Paolo Nenzi +2007-10-08 Paolo Nenzi * src/frontend/plotting/plotit.c, src/frontend/{nutimp.c, parse.c}, src/maths/ni/{niconv.c, niiter.c}, src/spicelib/analysis/dctran.c: Applied patch from Phil barker, iproved error/warning reporting. -2007-10-8 Paolo Nenzi +2007-10-08 Paolo Nenzi * src/frontend/numparam/{general.h, mystring.c, numpaif.h, numparam.h, nupatest.c, spicenum.c, washprog.c, xpressn.c}: Applied patch from Phil Barker that improves the capabilites of numparam library. Now numparam diff --git a/src/frontend/outitf.c b/src/frontend/outitf.c index cc8c5e678..e85053c8b 100644 --- a/src/frontend/outitf.c +++ b/src/frontend/outitf.c @@ -534,10 +534,10 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) #ifndef HAS_WINDOWS if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) { if (run->isComplex) { - fprintf(stderr, " Reference value : % 12.5e\n", + fprintf(stderr, " Reference value : % 12.5e\r", refValue->cValue.real); } else { - fprintf(stderr, " Reference value : % 12.5e\n", + fprintf(stderr, " Reference value : % 12.5e\r", refValue->rValue); } lastclock = currclock; diff --git a/src/frontend/runcoms2.c b/src/frontend/runcoms2.c index c204f1208..84b186726 100644 --- a/src/frontend/runcoms2.c +++ b/src/frontend/runcoms2.c @@ -22,6 +22,7 @@ $Id$ #include "breakp2.h" #include "plotting/graf.h" +#include "inpdefs.h" #define RAWBUF_SIZE 32768 char rawfileBuf[RAWBUF_SIZE]; @@ -159,6 +160,8 @@ com_rset(wordlist *wl) return; } + INPkillMods(); + if_cktfree(ft_curckt->ci_ckt, ft_curckt->ci_symtab); for (v = ft_curckt->ci_vars; v; v = next) { next = v->va_next; diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index ab3967a69..0a4c1973b 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -731,8 +731,37 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub printf("\nIn translate, examining line (dev_type: %c, subname: %s, instance: %s) %s \n", dev_type, subname, scname, c->li_line ); #endif - - dev_type = *(c->li_line); + if ( ciprefix( ".ic", c->li_line ) || ciprefix( ".nodeset", c->li_line ) ) { + paren_ptr = s = c->li_line; + while ( ( paren_ptr = strstr( paren_ptr, "(" ) ) ) { + *paren_ptr = '\0'; + paren_ptr++; + name = paren_ptr; + + if ( !( paren_ptr = strstr( paren_ptr, ")" ) ) ) { + *(name-1) = '('; + fprintf(cp_err, "Error: missing closing ')' for .ic|.nodeset statement %s\n", c->li_line); + goto quit; + } + *paren_ptr = '\0'; + t = gettrans(name); + + if (t) { + new_str = tmalloc( strlen(s) + strlen(t) + strlen(paren_ptr+1) + 3 ); + sprintf( new_str, "%s(%s)%s", s, t, paren_ptr+1 ); + } else { + new_str = tmalloc( strlen(s) + strlen(scname) + strlen(name) + strlen(paren_ptr+1) + 4 ); + sprintf( new_str, "%s(%s.%s)%s", s, scname, name, paren_ptr+1 ); + } + + paren_ptr = new_str + strlen(s) + 1; + + tfree(s); + s = new_str; + } + c->li_line = s; + continue; + } /* Rename the device. */ switch (dev_type) { diff --git a/src/frontend/variable.c b/src/frontend/variable.c index ea7a813e8..50cda0e96 100644 --- a/src/frontend/variable.c +++ b/src/frontend/variable.c @@ -385,13 +385,35 @@ void cp_remvar(char *varname) { struct variable *v, *u, *lv = NULL; + struct variable *uv1, *uv2; bool found = TRUE; - int i; + int i, var_index = 0; + + cp_usrvars(&uv1, &uv2); for (v = variables; v; v = v->va_next) { + var_index = 0; if (eq(v->va_name, varname)) - break; + break; + lv = v; + } + if (v == NULL) { + var_index = 1; + lv = NULL; + for (v = uv1; v; v = v->va_next) { + if (eq(v->va_name, varname)) + break; + lv = v; + } + } + if (v == NULL) { + var_index = 2; + lv = NULL; + for (v = uv2; v; v = v->va_next) { + if (eq(v->va_name, varname)) + break; lv = v; + } } if (!v) { /* Gotta make up a var struct for cp_usrset()... */ @@ -432,7 +454,14 @@ cp_remvar(char *varname) if (lv) lv->va_next = v->va_next; else + if ( var_index == 0 ) { variables = v->va_next; + } else if ( var_index == 1 ) { + uv1 = v->va_next; + } else { + ft_curckt->ci_vars = v->va_next; + } + } break; @@ -450,6 +479,7 @@ cp_remvar(char *varname) break; case US_SIMVAR: + fprintf(stderr,"it's a US_SIMVAR!\n"); lv = NULL; if (ft_curckt) { for (u = ft_curckt->ci_vars; u; u = u->va_next) { @@ -484,15 +514,19 @@ bool cp_getvar(char *name, int type, void *retval) { struct variable *v; + struct variable *uv1, *uv2; + + cp_usrvars(&uv1, &uv2); #ifdef TRACE /* SDB debug statement */ - printf("in cp_getvar, trying to get value of variable %s.\n", name); + fprintf(stderr,"in cp_getvar, trying to get value of variable %s.\n", name); #endif - for (v = variables; v; v = v->va_next) - if (eq(name, v->va_name)) - break; + for (v = variables; v && !eq(name, v->va_name); v = v->va_next); + if (v == NULL) for (v = uv1; v && !eq(name, v->va_name); v = v->va_next); + if (v == NULL) for (v = uv2; v && !eq(name, v->va_name); v = v->va_next); + if (v == NULL) { if (type == VT_BOOL) * (bool *) retval = FALSE; diff --git a/src/include/cpextern.h b/src/include/cpextern.h index 35a77e4d0..4ba30d849 100644 --- a/src/include/cpextern.h +++ b/src/include/cpextern.h @@ -167,6 +167,13 @@ extern void cp_vset(char *varname, char type, char *value); extern struct variable *cp_setparse(wordlist *wl); /* var2.c */ +enum cp_types { + CP_BOOL, + CP_NUM, + CP_REAL, + CP_STRING, + CP_LIST +}; extern void cp_vprint(void); extern void com_set(wordlist *wl); extern void com_option(wordlist *wl); diff --git a/src/spicelib/analysis/cktdojob.c b/src/spicelib/analysis/cktdojob.c index d039f4b3d..c150bdab7 100644 --- a/src/spicelib/analysis/cktdojob.c +++ b/src/spicelib/analysis/cktdojob.c @@ -93,8 +93,8 @@ CKTdoJob(void *inCkt, int reset, void *inTask) ckt->CKTlteAbstol = task->TSKlteAbstol; #endif /* NEWTRUNC */ -printf("Doing analysis at TEMP = %f and TNOM = %f\n", - ckt->CKTtemp, ckt->CKTnomTemp); +printf("Doing analysis at TEMP = %f and TNOM = %f\n\n", + ckt->CKTtemp - CONSTCtoK, ckt->CKTnomTemp - CONSTCtoK); error = 0; if (reset) { diff --git a/src/spicelib/parser/Makefile.am b/src/spicelib/parser/Makefile.am index 0b7133d3d..5c7662e8c 100644 --- a/src/spicelib/parser/Makefile.am +++ b/src/spicelib/parser/Makefile.am @@ -40,6 +40,7 @@ libinp_a_SOURCES = \ inperror.c \ inpeval.c \ inpfindl.c \ + inpfindv.c \ inpgmod.c \ inpgstr.c \ inpgtitl.c \ diff --git a/src/spicelib/parser/inp2m.c b/src/spicelib/parser/inp2m.c index f5aa6aee5..abdac3962 100644 --- a/src/spicelib/parser/inp2m.c +++ b/src/spicelib/parser/inp2m.c @@ -50,6 +50,7 @@ INP2M (void *ckt, INPtables * tab, card * current) INPmodel *thismodel; /* pointer to model description for user's model */ void *mdfast; /* pointer to the actual model */ IFuid uid; /* uid for default model */ + char* err_msg; #ifdef TRACE printf("INP2M: Parsing '%s'\n",current->line); @@ -78,6 +79,12 @@ INP2M (void *ckt, INPtables * tab, card * current) printf("INP2M: checking for 4 node device\n"); #endif INPgetMod (ckt, nname5, &thismodel, tab); + + /* check if using model binning -- pass in line since need 'l' and 'w' */ + if ( thismodel == NULL ) { + INPgetModBin( ckt, nname5, &thismodel, tab, line ); + } + if (thismodel == NULL) { /* 5th token is not a model in the table */ nodeflag = 1; /* now specify a 5 node device */ @@ -184,7 +191,13 @@ INP2M (void *ckt, INPtables * tab, card * current) #ifdef TRACE printf("INP2M: Looking up model\n"); #endif - current->error = INPgetMod (ckt, model, &thismodel, tab); + + err_msg = INPgetMod (ckt, model, &thismodel, tab); + if ( thismodel == NULL ) { + INPgetModBin( ckt, model, &thismodel, tab, save ); + if ( thismodel == NULL ) current->error = err_msg; + } + if (thismodel != NULL) { if (thismodel->INPmodType != INPtypelook ("Mos1")