diff --git a/src/frontend/device.c b/src/frontend/device.c index d31e094b3..5342122d7 100644 --- a/src/frontend/device.c +++ b/src/frontend/device.c @@ -27,6 +27,7 @@ static wordlist *devexpand(char *name); static void all_show(wordlist *wl, int mode); static void all_show_old(wordlist *wl, int mode); static void com_alter_mod(wordlist *wl); +static void if_set_binned_model(CKTcircuit *, char *, char *, struct dvec *); /* * devhelp: lists available devices and information on parameters @@ -1079,6 +1080,40 @@ com_altermod(wordlist *wl) com_alter_common(wl, 1); } +static void +if_set_binned_model(CKTcircuit *ckt, char *devname, char *param, struct dvec *val) +{ + char *width_length; + double w=0.0, l=0.0; + struct variable *v; + + v = if_getparam(ckt, &devname, "w", 0, 0); + if (!v) { + fprintf(cp_err, "Error: Can't access width instance parameter.\n"); + return; + } + w = v->va_V.vV_real; + + v = if_getparam(ckt, &devname, "l", 0, 0); + if (!v) { + fprintf(cp_err, "Error: Can't access length instance parameter.\n"); + return; + } + l = v->va_V.vV_real; + + if (param[0] == 'w') { + w = *val->v_realdata; /* overwrite the width with the alter param */ + } else { + l = *val->v_realdata; /* overwrite the length with the alter param */ + } + width_length = TMALLOC(char, 36); + (void) sprintf(width_length,"w=%15.7e l=%15.7e", w, l); + + if_setparam_model(ft_curckt->ci_ckt, &devname, width_length); + FREE(width_length); + +} + static void com_alter_common(wordlist *wl, int do_model) { @@ -1328,6 +1363,12 @@ com_alter_common(wordlist *wl, int do_model) return; } + /* If we want alter the geometry of a MOS device + we have to ensure that we are in the valid model bin. */ + if ( (dev[0] == 'm') && ((param[0] == 'w') || (param[0] == 'l')) ) { + if_set_binned_model(ft_curckt->ci_ckt, dev, param, dv); + } + if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model); /* va: garbage collection for dv, if pnode names is no simple value */ diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index 3cb4ec8ad..f8cd4ad90 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -160,7 +160,9 @@ if_inpdeck(struct line *deck, INPtables **tab) INPpas1( ckt, (card *) deck->li_next, *tab); INPpas2( ckt, (card *) deck->li_next, *tab, ft_curckt->ci_defTask); - INPkillMods(); +/* INPkillMods(); FIXME: modtab should removed later - + because needed for alter geometry of binned MOS models, + see below if_setparam_model */ /* INPpas2 has been modified to ignore .NODESET and .IC * cards. These are left till INPpas3 so that we can check for @@ -820,7 +822,7 @@ spif_getparam(CKTcircuit *ckt, char **name, char *param, int ind, int do_model) /* 9/26/03 PJB : function to allow setting model of device */ void -if_setparam_model(CKTcircuit *ckt, char **name, char *val ) +if_setparam_model(CKTcircuit *ckt, char **name, char *val) { GENinstance *dev = NULL; GENinstance *prevDev = NULL; @@ -830,21 +832,29 @@ if_setparam_model(CKTcircuit *ckt, char **name, char *val ) GENinstance *iter; GENmodel *mods, *prevMod; int typecode; + char *modname; /* retrieve device name from symbol table */ INPretrieve(name, ft_curckt->ci_symtab); /* find the specified device */ typecode = finddev(ckt, *name, &dev, &curMod); if (typecode == -1) { - fprintf(cp_err, "Error: no such device or model name %s\n", *name); + fprintf(cp_err, "Error: no such device name %s\n", *name); return; } curMod = dev->GENmodPtr; + modname = copy(dev->GENmodPtr->GENmodName); + modname = strtok(modname, "."); /* want only have the parent model name */ /* retrieve the model from the global model table; also add the model to 'ckt' and indicate model is being used */ - INPgetMod( ckt, val, &inpmod, ft_curckt->ci_symtab ); + INPgetMod( ckt, modname, &inpmod, ft_curckt->ci_symtab ); + /* check if using model binning -- pass in line since need 'l' and 'w' */ + if ( inpmod == NULL ) { + INPgetModBin( ckt, modname, &inpmod, ft_curckt->ci_symtab, val ); + } + tfree(modname); if ( inpmod == NULL ) { fprintf(cp_err, "Error: no such model %s.\n", val); return; @@ -852,9 +862,8 @@ if_setparam_model(CKTcircuit *ckt, char **name, char *val ) newMod = inpmod->INPmodfast; /* see if new model name same as current model name */ - if ( newMod->GENmodName == curMod->GENmodName ) { - fprintf(cp_err, "Warning: new model same as current model; nothing changed.\n"); - return; + if ( newMod->GENmodName != curMod->GENmodName ) { + printf("Notice: model has changed from %s to %s.\n", curMod->GENmodName, newMod->GENmodName); } if ( newMod->GENmodType != curMod->GENmodType ) { fprintf(cp_err, "Error: new model %s must be same type as current model.\n", val);