📄 spiceif.c
字号:
else goto badtype; break; case IF_FLAG: /* Do nothing. */ pval.iValue = *((int *) value); break; default: fprintf(cp_err, "if_option: Internal Error: bad option type %d.\n", ft_sim->analyses[which]->analysisParms[i].dataType); } if (!ckt) { /* XXX No circuit loaded */ fprintf(cp_err, "Simulation parameter \"%s\" can't be set until\n", name); fprintf(cp_err, "a circuit has been loaded.\n"); return 1; }#if (0) if ((err = (*(ft_sim->setAnalysisParm))(cc, (void *)ft_curckt->ci_curOpt, ft_sim->analyses[which]->analysisParms[i].id, &pval, (IFvalue *)NULL)) != OK) ft_sperror(err, "setAnalysisParm(options) ci_curOpt");#else /*CDHW*/ if ((err = (*(ft_sim->setAnalysisParm))(cc, (void *)ft_curckt->ci_defOpt, ft_sim->analyses[which]->analysisParms[i].id, &pval, (IFvalue *)NULL)) != OK) ft_sperror(err, "setAnalysisParm(options) ci_curOpt"); return 1;#endifbadtype: fprintf(cp_err, "Error: bad type given for option %s --\n", name); fprintf(cp_err, "\ttype given was "); switch (type) { case VT_BOOL: fputs("boolean", cp_err); break; case VT_NUM: fputs("integer", cp_err); break; case VT_REAL: fputs("real", cp_err); break; case VT_STRING: fputs("string", cp_err); break; case VT_LIST: fputs("list", cp_err); break; default: fputs("something strange", cp_err); break; } fprintf(cp_err, ", type expected was "); switch(ft_sim->analyses[which]->analysisParms[i].dataType & IF_VARTYPES) { case IF_REAL: fputs("real.\n", cp_err); break; case IF_INTEGER:fputs("integer.\n", cp_err); break; case IF_STRING: fputs("string.\n", cp_err); break; case IF_FLAG: fputs("flag.\n", cp_err); break; default: fputs("something strange.\n", cp_err); break; } if (type == VT_BOOL)fputs("\t(Note that you must use an = to separate option name and value.)\n", cp_err); return 0;}voidif_dump(void *ckt, FILE *file){ /*void *cc = (void *) ckt;*/ fprintf(file,"diagnostic output dump unavailable."); return;}voidif_cktfree(void *ckt, char *tab){ void *cc = (void *) ckt; (*(ft_sim->deleteCircuit))(cc); INPtabEnd((INPtables *) tab); return;}/* Return a string describing an error code. *//* BLOW THIS AWAY.... */char *if_errstring(int code){ return (INPerror(code));}/* Get a parameter value from the circuit. If name is left unspecified, * we want a circuit parameter. */struct variable *spif_getparam(void *ckt, char **name, char *param, int ind, int do_model){ struct variable *vv = NULL, *tv; IFvalue *pv; IFparm *opt; int typecode, i; GENinstance *dev=(GENinstance *)NULL; GENmodel *mod=(GENmodel *)NULL; IFdevice *device; /* fprintf(cp_err, "Calling if_getparam(%s, %s)\n", *name, param); */ if (param && eq(param, "all")) { /* MW. My "special routine here" */ INPretrieve(name,(INPtables *)ft_curckt->ci_symtab); typecode = finddev(ckt, *name,(void**) &dev,(void **) &mod); if (typecode == -1) { fprintf(cp_err, "Error: no such device or model name %s\n", *name); return (NULL); } device = ft_sim->devices[typecode]; for (i = 0; i < *(device->numInstanceParms); i++) { opt = &device->instanceParms[i]; if(opt->dataType & IF_REDUNDANT || !opt->description) continue; if(!(opt->dataType & IF_ASK)) continue; pv = doask(ckt, typecode, dev, mod, opt, ind); if (pv) { tv = parmtovar(pv, opt); if (vv) tv->va_next = vv; vv = tv; } else fprintf(cp_err, "Internal Error: no parameter '%s' on device '%s'\n", device->instanceParms[i].keyword, device->name); } return (vv); } else if (param) { /* MW. */ INPretrieve(name,(INPtables *)ft_curckt->ci_symtab); typecode = finddev(ckt, *name, (void**)&dev, (void **)&mod); if (typecode == -1) { fprintf(cp_err, "Error: no such device or model name %s\n", *name); return (NULL); } device = ft_sim->devices[typecode]; opt = parmlookup(device, &dev, param, do_model, 0); if (!opt) { fprintf(cp_err, "Error: no such parameter %s.\n", param); return (NULL); } pv = doask(ckt, typecode, dev, mod, opt, ind); if (pv) vv = parmtovar(pv, opt); return (vv); } else return (if_getstat(ckt, *name));}voidif_setparam(void *ckt, char **name, char *param, struct dvec *val, int do_model){ IFparm *opt; IFdevice *device; GENmodel *mod=(GENmodel *)NULL; GENinstance *dev=(GENinstance *)NULL; int typecode; /* PN */ INPretrieve(name,(INPtables *)ft_curckt->ci_symtab); typecode = finddev(ckt, *name, (void**)&dev, (void **)&mod); if (typecode == -1) { fprintf(cp_err, "Error: no such device or model name %s\n", *name); return; } device = ft_sim->devices[typecode]; opt = parmlookup(device, &dev, param, do_model, 1); if (!opt) { if (param) fprintf(cp_err, "Error: no such parameter %s.\n", param); else fprintf(cp_err, "Error: no default parameter.\n"); return; } if (do_model && !mod) { mod = dev->GENmodPtr; dev = (GENinstance *)NULL; } doset(ckt, typecode, dev, mod, opt, val);}static struct variable *parmtovar(IFvalue *pv, IFparm *opt){ struct variable *vv = alloc(struct variable); struct variable *nv; int i = 0; switch (opt->dataType & IF_VARTYPES) { case IF_INTEGER: vv->va_type = VT_NUM; vv->va_num = pv->iValue; break; case IF_REAL: case IF_COMPLEX: vv->va_type = VT_REAL; vv->va_real = pv->rValue; break; case IF_STRING: vv->va_type = VT_STRING; vv->va_string = pv->sValue; break; case IF_FLAG: vv->va_type = VT_BOOL; vv->va_bool = pv->iValue ? TRUE : FALSE; break; case IF_REALVEC: vv->va_type = VT_LIST; for (i = 0; i < pv->v.numValue; i++) { nv = alloc(struct variable); nv->va_next = vv->va_vlist; vv->va_vlist = nv; nv->va_type = VT_REAL; nv->va_real = pv->v.vec.rVec[i]; } break; default: fprintf(cp_err, "parmtovar: Internal Error: bad PARM type %d.\n", opt->dataType); return (NULL); } /* It's not clear whether we want the keyword or the desc here... */ vv->va_name = copy(opt->description); vv->va_next = NULL; return (vv);}/* Extract the parameter (IFparm structure) from the device or device's model. * If do_mode is TRUE then look in the device's parameters * If do_mode is FALSE then look in the device model's parameters * If inout equals 1 then look only for parameters with the IF_SET type flag * if inout equals 0 then look only for parameters with the IF_ASK type flag */static IFparm *parmlookup(IFdevice *dev, GENinstance **inptr, char *param, int do_model, int inout){ int i; /* First try the device questions... */ if (!do_model && dev->numInstanceParms) { for (i = 0; i < *(dev->numInstanceParms); i++) { if (!param && (dev->instanceParms[i].dataType & IF_PRINCIPAL)) return (&dev->instanceParms[i]); else if (!param) continue; else if ((((dev->instanceParms[i].dataType & IF_SET) && inout == 1) || ((dev->instanceParms[i].dataType & IF_ASK) && inout == 0)) && cieq(dev->instanceParms[i].keyword, param)) { if (dev->instanceParms[i].dataType & IF_REDUNDANT) i -= 1; return (&dev->instanceParms[i]); } } return NULL; } if (dev->numModelParms) { for (i = 0; i < *(dev->numModelParms); i++) if ((((dev->modelParms[i].dataType & IF_SET) && inout == 1) || ((dev->modelParms[i].dataType & IF_ASK) && inout == 0)) && eq(dev->modelParms[i].keyword, param)) { if (dev->modelParms[i].dataType & IF_REDUNDANT) i -= 1; return (&dev->modelParms[i]); } } return (NULL);}/* Perform the CKTask call. We have both 'fast' and 'modfast', so the other * parameters aren't necessary. */static IFvalue *doask(void *ckt, int typecode, GENinstance *dev, GENmodel *mod, IFparm *opt, int ind){ static IFvalue pv; int err; pv.iValue = ind; /* Sometimes this will be junk and ignored... */ /* fprintf(cp_err, "Calling doask(%d, %x, %x, %x)\n", typecode, dev, mod, opt); */ if (dev) err = (*(ft_sim->askInstanceQuest))((void *)ckt, (void *)dev, opt->id, &pv, (IFvalue *)NULL); else err = (*(ft_sim->askModelQuest))((void*)ckt, (void *) mod, opt->id, &pv, (IFvalue *)NULL); if (err != OK) { ft_sperror(err, "if_getparam"); return (NULL); } return (&pv);}/* Perform the CKTset call. We have both 'fast' and 'modfast', so the other * parameters aren't necessary. */static intdoset(void *ckt, int typecode, GENinstance *dev, GENmodel *mod, IFparm *opt, struct dvec *val){ IFvalue nval; int err; int n; int *iptr; double *dptr; int i; /* Count items */ if (opt->dataType & IF_VECTOR) { n = nval.v.numValue = val->v_length; dptr = val->v_realdata; /* XXXX compdata!!! */ switch (opt->dataType & (IF_VARTYPES & ~IF_VECTOR)) { case IF_FLAG: case IF_INTEGER: iptr = nval.v.vec.iVec = NEWN(int, n); for (i = 0; i < n; i++) *iptr++ = *dptr++; break; case IF_REAL: nval.v.vec.rVec = val->v_realdata; break; default: fprintf(cp_err, "Can't assign value to \"%s\" (unsupported vector type)\n", opt->keyword); return E_UNSUPP; } } else { switch (opt->dataType & IF_VARTYPES) { case IF_FLAG: case IF_INTEGER: nval.iValue = *val->v_realdata; break; case IF_REAL:/*kensmith don't blow up with NULL dereference*/ if (!val->v_realdata) { fprintf(cp_err,"Unable to determine the value\n"); return E_UNSUPP; } nval.rValue = *val->v_realdata; break; default: fprintf(cp_err, "Can't assign value to \"%s\" (unsupported type)\n", opt->keyword); return E_UNSUPP; } } /* fprintf(cp_err, "Calling doask(%d, %x, %x, %x)\n", typecode, dev, mod, opt); */ if (dev) err = (*(ft_sim->setInstanceParm))((void *)ckt, (void *)dev, opt->id, &nval, (IFvalue *)NULL); else err = (*(ft_sim->setModelParm))((void*)ckt, (void *) mod, opt->id, &nval, (IFvalue *)NULL); return err;}/* Get pointers to a device, its model, and its type number given the name. If * there is no such device, try to find a model with that name. */static intfinddev(void *ck, char *name, void **devptr, void **modptr){ int err; int type = -1; err = (*(ft_sim->findInstance))((void *)ck,&type,devptr,name,NULL,NULL); if(err == OK) return(type); type = -1; *devptr = (void *)NULL; err = (*(ft_sim->findModel))((void *)ck,&type,modptr,name); if(err == OK) return(type); *modptr = (void *)NULL; return(-1);}/* get an analysis parameter by name instead of id */int if_analQbyName(void *ckt, int which, void *anal, char *name, IFvalue *parm){ int i; for(i=0;i<ft_sim->analyses[which]->numParms;i++) { if(strcmp(ft_sim->analyses[which]->analysisParms[i].keyword,name)==0) { return( (*(ft_sim->askAnalysisQuest))(ckt,anal, ft_sim->analyses[which]->analysisParms[i].id,parm, (IFvalue *)NULL) ); } } return(E_BADPARM);}/* Get the parameters tstart, tstop, and tstep from the CKT struct. *//* BLOW THIS AWAY TOO */boolif_tranparams(struct circ *ci, double *start, double *stop, double *step){ IFvalue tmp; int err; int which = -1; int i; void *anal; IFuid tranUid; if(!ci->ci_curTask) return(FALSE); for(i=0;i<ft_sim->numAnalyses;i++) { if(strcmp(ft_sim->analyses[i]->name,"TRAN")==0){ which = i; break; } } if(which == -1) return(FALSE); err = IFnewUid(ci->ci_ckt,&tranUid,(IFuid)NULL,"Transient Analysis",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -