static int dot_ac(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, TSKtask *task, CKTnode *gnode, JOB *foo) { int error; /* error code temporary */ IFvalue ptemp; /* a value structure to package resistance into */ IFvalue *parm; /* a pointer to a value struct for function returns */ int which; /* which analysis we are performing */ char *steptype; /* ac analysis, type of stepping function */ NG_IGNORE(gnode); /* .ac {DEC OCT LIN} NP FSTART FSTOP */ which = ft_find_analysis("AC"); if (which == -1) { LITERR("AC small signal analysis unsupported.\n"); return (0); } IFC(newAnalysis, (ckt, which, "AC Analysis", &foo, task)); INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */ ptemp.iValue = 1; GCA(INPapName, (ckt, which, foo, steptype, &ptemp)); tfree(steptype); parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* number of points */ GCA(INPapName, (ckt, which, foo, "numsteps", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */ GCA(INPapName, (ckt, which, foo, "start", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstop */ GCA(INPapName, (ckt, which, foo, "stop", parm)); return (0); }
static int dot_pz(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, TSKtask *task, CKTnode *gnode, JOB *foo) { int error; /* error code temporary */ IFvalue ptemp; /* a value structure to package resistance into */ IFvalue *parm; /* a pointer to a value struct for function returns */ int which; /* which analysis we are performing */ char *steptype; /* ac analysis, type of stepping function */ NG_IGNORE(gnode); /* .pz nodeI nodeG nodeJ nodeK {V I} {POL ZER PZ} */ which = ft_find_analysis("PZ"); if (which == -1) { LITERR("Pole-zero analysis unsupported.\n"); return (0); } IFC(newAnalysis, (ckt, which, "Pole-Zero Analysis", &foo, task)); parm = INPgetValue(ckt, &line, IF_NODE, tab); GCA(INPapName, (ckt, which, foo, "nodei", parm)); parm = INPgetValue(ckt, &line, IF_NODE, tab); GCA(INPapName, (ckt, which, foo, "nodeg", parm)); parm = INPgetValue(ckt, &line, IF_NODE, tab); GCA(INPapName, (ckt, which, foo, "nodej", parm)); parm = INPgetValue(ckt, &line, IF_NODE, tab); GCA(INPapName, (ckt, which, foo, "nodek", parm)); INPgetTok(&line, &steptype, 1); /* get V or I */ ptemp.iValue = 1; GCA(INPapName, (ckt, which, foo, steptype, &ptemp)); INPgetTok(&line, &steptype, 1); /* get POL, ZER, or PZ */ ptemp.iValue = 1; GCA(INPapName, (ckt, which, foo, steptype, &ptemp)); return (0); }
static int dot_tran(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, TSKtask *task, CKTnode *gnode, JOB *foo) { int error; /* error code temporary */ IFvalue ptemp; /* a value structure to package resistance into */ IFvalue *parm; /* a pointer to a value struct for function returns */ int which; /* which analysis we are performing */ double dtemp; /* random double precision temporary */ char *word; /* something to stick a word of input into */ NG_IGNORE(gnode); /* .tran Tstep Tstop <Tstart <Tmax> > <UIC> */ which = ft_find_analysis("TRAN"); if (which == -1) { LITERR("Transient analysis unsupported.\n"); return (0); } IFC(newAnalysis, (ckt, which, "Transient Analysis", &foo, task)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Tstep */ GCA(INPapName, (ckt, which, foo, "tstep", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Tstop */ GCA(INPapName, (ckt, which, foo, "tstop", parm)); if (*line) { dtemp = INPevaluate(&line, &error, 1); /* tstart? */ if (error == 0) { ptemp.rValue = dtemp; GCA(INPapName, (ckt, which, foo, "tstart", &ptemp)); dtemp = INPevaluate(&line, &error, 1); /* tmax? */ if (error == 0) { ptemp.rValue = dtemp; GCA(INPapName, (ckt, which, foo, "tmax", &ptemp)); } } } if (*line) { INPgetTok(&line, &word, 1); /* uic? */ if (strcmp(word, "uic") == 0) { ptemp.iValue = 1; GCA(INPapName, (ckt, which, foo, "uic", &ptemp)); } else { LITERR(" Error: unknown parameter on .tran - ignored\n"); } tfree(word); } return (0); }
/*SP: Steady State Analyis */ static int dot_pss(char *line, void *ckt, INPtables *tab, struct card *current, void *task, void *gnode, JOB *foo) { int error; /* error code temporary */ IFvalue ptemp; /* a value structure to package resistance into */ IFvalue *parm; /* a pointer to a value struct for function returns */ char *nname; /* the oscNode name */ CKTnode *nnode; /* the oscNode node */ int which; /* which analysis we are performing */ char *word; /* something to stick a word of input into */ NG_IGNORE(gnode); /* .pss Fguess StabTime OscNode <UIC>*/ which = ft_find_analysis("PSS"); if (which == -1) { LITERR("Periodic steady state analysis unsupported.\n"); return (0); } IFC(newAnalysis, (ckt, which, "Periodic Steady State Analysis", &foo, task)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Fguess */ GCA(INPapName, (ckt, which, foo, "fguess", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* StabTime */ GCA(INPapName, (ckt, which, foo, "stabtime", parm)); INPgetNetTok(&line, &nname, 0); INPtermInsert(ckt, &nname, tab, &nnode); ptemp.nValue = nnode; GCA(INPapName, (ckt, which, foo, "oscnode", &ptemp)); /* OscNode given as string */ parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* PSS points */ GCA(INPapName, (ckt, which, foo, "points", parm)); parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* PSS harmonics */ GCA(INPapName, (ckt, which, foo, "harmonics", parm)); parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* SC iterations */ GCA(INPapName, (ckt, which, foo, "sc_iter", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Steady coefficient */ GCA(INPapName, (ckt, which, foo, "steady_coeff", parm)); if (*line) { INPgetTok(&line, &word, 1); /* uic? */ if (strcmp(word, "uic") == 0) { ptemp.iValue = 1; GCA(INPapName, (ckt, which, foo, "uic", &ptemp)); } else { fprintf(stderr,"Error: unknown parameter %s on .pss - ignored\n", word); } } return (0); }
static int dot_dc(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, TSKtask *task, CKTnode *gnode, JOB *foo) { char *name; /* the resistor's name */ int error; /* error code temporary */ IFvalue ptemp; /* a value structure to package resistance into */ IFvalue *parm; /* a pointer to a value struct for function returns */ int which; /* which analysis we are performing */ NG_IGNORE(gnode); /* .dc SRC1NAME Vstart1 Vstop1 Vinc1 [SRC2NAME Vstart2 */ /* Vstop2 Vinc2 */ which = ft_find_analysis("DC"); if (which == -1) { LITERR("DC transfer curve analysis unsupported\n"); return (0); } IFC(newAnalysis, (ckt, which, "DC transfer characteristic", &foo, task)); INPgetTok(&line, &name, 1); INPinsert(&name, tab); ptemp.uValue = name; GCA(INPapName, (ckt, which, foo, "name1", &ptemp)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstart1 */ GCA(INPapName, (ckt, which, foo, "start1", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstop1 */ GCA(INPapName, (ckt, which, foo, "stop1", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vinc1 */ GCA(INPapName, (ckt, which, foo, "step1", parm)); if (*line) { INPgetTok(&line, &name, 1); INPinsert(&name, tab); ptemp.uValue = name; GCA(INPapName, (ckt, which, foo, "name2", &ptemp)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstart2 */ GCA(INPapName, (ckt, which, foo, "start2", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstop2 */ GCA(INPapName, (ckt, which, foo, "stop2", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vinc2 */ GCA(INPapName, (ckt, which, foo, "step2", parm)); } return 0; }
static int dot_sens2(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, TSKtask *task, CKTnode *gnode, JOB *foo) { int error; /* error code temporary */ IFvalue ptemp; /* a value structure to package resistance into */ IFvalue *parm; /* a pointer to a value struct for function returns */ int which; /* which analysis we are performing */ char *token; /* a token from the line */ NG_IGNORE(gnode); /* .sens {AC} {DC} {TRAN} [dev=nnn parm=nnn]* */ which = ft_find_analysis("SENS2"); if (which == -1) { LITERR("Sensitivity-2 analysis unsupported\n"); return (0); } IFC(newAnalysis, (ckt, which, "Sensitivity-2 Analysis", &foo, task)); while (*line) { IFparm *if_parm; /* read the entire line */ INPgetTok(&line, &token, 1); if_parm = ft_find_analysis_parm(which, token); if (!if_parm) { /* didn't find it! */ LITERR(" Error: unknown parameter on .sens-ignored \n"); continue; } /* found it, analysis which, parameter i */ if (if_parm->dataType & IF_FLAG) { /* one of the keywords! */ ptemp.iValue = 1; error = ft_sim->setAnalysisParm (ckt, foo, if_parm->id, &ptemp, NULL); if (error) current->error = INPerrCat(current->error, INPerror(error)); } else { parm = INPgetValue(ckt, &line, if_parm->dataType, tab); error = ft_sim->setAnalysisParm (ckt, foo, if_parm->id, parm, NULL); if (error) current->error = INPerrCat(current->error, INPerror(error)); } } return (0); }
static int dot_sens(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, TSKtask *task, CKTnode *gnode, JOB *foo) { char *name; /* the resistor's name */ int error; /* error code temporary */ IFvalue ptemp; /* a value structure to package resistance into */ IFvalue *parm; /* a pointer to a value struct for function returns */ int which; /* which analysis we are performing */ char *nname1; /* the first node's name */ char *nname2; /* the second node's name */ CKTnode *node1; /* the first node's node pointer */ CKTnode *node2; /* the second node's node pointer */ char *steptype; /* ac analysis, type of stepping function */ which = ft_find_analysis("SENS"); if (which == -1) { LITERR("Sensitivity unsupported.\n"); return (0); } IFC(newAnalysis, (ckt, which, "Sensitivity Analysis", &foo, task)); /* Format is: * .sens <output> * + [ac [dec|lin|oct] <pts> <low freq> <high freq> | dc ] */ /* Get the output voltage or current */ INPgetTok(&line, &name, 0); /* name is now either V or I or a serious error */ if (*name == 'v' && strlen(name) == 1) { if (*line != '(') { LITERR("Syntax error: '(' expected after 'v'\n"); return 0; } INPgetNetTok(&line, &nname1, 0); INPtermInsert(ckt, &nname1, tab, &node1); ptemp.nValue = node1; GCA(INPapName, (ckt, which, foo, "outpos", &ptemp)); if (*line != ')') { INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); ptemp.nValue = node2; GCA(INPapName, (ckt, which, foo, "outneg", &ptemp)); ptemp.sValue = tprintf("V(%s,%s)", nname1, nname2); GCA(INPapName, (ckt, which, foo, "outname", &ptemp)); } else { ptemp.nValue = gnode; GCA(INPapName, (ckt, which, foo, "outneg", &ptemp)); ptemp.sValue = tprintf("V(%s)", nname1); GCA(INPapName, (ckt, which, foo, "outname", &ptemp)); } } else if (*name == 'i' && strlen(name) == 1) { INPgetTok(&line, &name, 1); INPinsert(&name, tab); ptemp.uValue = name; GCA(INPapName, (ckt, which, foo, "outsrc", &ptemp)); } else { LITERR("Syntax error: voltage or current expected.\n"); return 0; } INPgetTok(&line, &name, 1); if (name && !strcmp(name, "pct")) { ptemp.iValue = 1; GCA(INPapName, (ckt, which, foo, "pct", &ptemp)); INPgetTok(&line, &name, 1); } if (name && !strcmp(name, "ac")) { INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */ ptemp.iValue = 1; GCA(INPapName, (ckt, which, foo, steptype, &ptemp)); parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* number of points */ GCA(INPapName, (ckt, which, foo, "numsteps", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */ GCA(INPapName, (ckt, which, foo, "start", parm)); parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstop */ GCA(INPapName, (ckt, which, foo, "stop", parm)); return (0); } else if (name && *name && strcmp(name, "dc")) { /* Bad flag */ LITERR("Syntax error: 'ac' or 'dc' expected.\n"); return 0; } return (0); }
static int dot_noise(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, TSKtask *task, CKTnode *gnode, JOB *foo) { int which; /* which analysis we are performing */ int error; /* error code temporary */ char *name; /* the resistor's name */ char *nname1; /* the first node's name */ char *nname2; /* the second node's name */ CKTnode *node1; /* the first node's node pointer */ CKTnode *node2; /* the second node's node pointer */ IFvalue ptemp; /* a value structure to package resistance into */ IFvalue *parm; /* a pointer to a value struct for function returns */ char *steptype; /* ac analysis, type of stepping function */ int found; char *point; /* .noise V(OUTPUT,REF) SRC {DEC OCT LIN} NP FSTART FSTOP <PTSPRSUM> */ which = ft_find_analysis("NOISE"); if (which == -1) { LITERR("Noise analysis unsupported.\n"); return (0); } IFC(newAnalysis, (ckt, which, "Noise Analysis", &foo, task)); INPgetTok(&line, &name, 1); /* Make sure the ".noise" command is followed by V(xxxx). If it is, extract 'xxxx'. If not, report an error. */ if (name != NULL) { if ((*name == 'V' || *name == 'v') && !name[1]) { INPgetNetTok(&line, &nname1, 0); INPtermInsert(ckt, &nname1, tab, &node1); ptemp.nValue = node1; GCA(INPapName, (ckt, which, foo, "output", &ptemp)); if (*line != ')') { INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); ptemp.nValue = node2; } else { ptemp.nValue = gnode; } GCA(INPapName, (ckt, which, foo, "outputref", &ptemp)); tfree(name); INPgetTok(&line, &name, 1); INPinsert(&name, tab); ptemp.uValue = name; GCA(INPapName, (ckt, which, foo, "input", &ptemp)); INPgetTok(&line, &steptype, 1); ptemp.iValue = 1; error = INPapName(ckt, which, foo, steptype, &ptemp); tfree(steptype); if (error) current->error = INPerrCat(current->error, INPerror(error)); parm = INPgetValue(ckt, &line, IF_INTEGER, tab); error = INPapName(ckt, which, foo, "numsteps", parm); if (error) current->error = INPerrCat(current->error, INPerror(error)); parm = INPgetValue(ckt, &line, IF_REAL, tab); error = INPapName(ckt, which, foo, "start", parm); if (error) current->error = INPerrCat(current->error, INPerror(error)); parm = INPgetValue(ckt, &line, IF_REAL, tab); error = INPapName(ckt, which, foo, "stop", parm); if (error) current->error = INPerrCat(current->error, INPerror(error)); /* now see if "ptspersum" has been specified by the user */ for (found = 0, point = line; (!found) && (*point != '\0'); found = ((*point != ' ') && (*(point++) != '\t'))) ; if (found) { parm = INPgetValue(ckt, &line, IF_INTEGER, tab); error = INPapName(ckt, which, foo, "ptspersum", parm); if (error) current->error = INPerrCat(current->error, INPerror(error)); } else { ptemp.iValue = 0; error = INPapName(ckt, which, foo, "ptspersum", &ptemp); if (error) current->error = INPerrCat(current->error, INPerror(error)); } } else LITERR("bad syntax " "[.noise v(OUT) SRC {DEC OCT LIN} " "NP FSTART FSTOP <PTSPRSUM>]\n"); } else { LITERR("bad syntax " "[.noise v(OUT) SRC {DEC OCT LIN} " "NP FSTART FSTOP <PTSPRSUM>]\n"); } return 0; }
static int dot_noise(char *line, void *ckt, INPtables *tab, card *current, void *task, void *gnode, void *foo) { int which; /* which analysis we are performing */ int i; /* generic loop variable */ int error; /* error code temporary */ char *name; /* the resistor's name */ char *nname1; /* the first node's name */ char *nname2; /* the second node's name */ void *node1; /* the first node's node pointer */ void *node2; /* the second node's node pointer */ IFvalue ptemp; /* a value structure to package resistance into */ IFvalue *parm; /* a pointer to a value struct for function returns */ char *steptype; /* ac analysis, type of stepping function */ int found; char *point; /* .noise V(OUTPUT,REF) SRC {DEC OCT LIN} NP FSTART FSTOP <PTSPRSUM> */ which = -1; for (i = 0; i < ft_sim->numAnalyses; i++) { if (strcmp(ft_sim->analyses[i]->name, "NOISE") == 0) { which = i; break; } } if (which == -1) { LITERR("Noise analysis unsupported.\n"); return (0); } IFC(newAnalysis, (ckt, which, "Noise Analysis", &foo, task)); INPgetTok(&line, &name, 1); /* Make sure the ".noise" command is followed by V(xxxx). If it is, extract 'xxxx'. If not, report an error. */ if (name != NULL) { int length; length = strlen(name); if (((*name == 'V') || (*name == 'v')) && (length == 1)) { INPgetNetTok(&line, &nname1, 0); INPtermInsert(ckt, &nname1, tab, &node1); ptemp.nValue = (IFnode) node1; GCA(INPapName, (ckt, which, foo, "output", &ptemp)) if (*line != ')') { INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); ptemp.nValue = (IFnode) node2; } else { ptemp.nValue = (IFnode) gnode; } GCA(INPapName, (ckt, which, foo, "outputref", &ptemp)) INPgetTok(&line, &name, 1); INPinsert(&name, tab); ptemp.uValue = name; GCA(INPapName, (ckt, which, foo, "input", &ptemp)) INPgetTok(&line, &steptype, 1); ptemp.iValue = 1; error = INPapName(ckt, which, foo, steptype, &ptemp); if (error) current->error = INPerrCat(current->error, INPerror(error)); parm = INPgetValue(ckt, &line, IF_INTEGER, tab); error = INPapName(ckt, which, foo, "numsteps", parm); if (error) current->error = INPerrCat(current->error, INPerror(error)); parm = INPgetValue(ckt, &line, IF_REAL, tab); error = INPapName(ckt, which, foo, "start", parm); if (error) current->error = INPerrCat(current->error, INPerror(error)); parm = INPgetValue(ckt, &line, IF_REAL, tab); error = INPapName(ckt, which, foo, "stop", parm); if (error) current->error = INPerrCat(current->error, INPerror(error)); /* now see if "ptspersum" has been specified by the user */ for (found = 0, point = line; (!found) && (*point != '\0'); found = ((*point != ' ') && (*(point++) != '\t'))); if (found) { parm = INPgetValue(ckt, &line, IF_INTEGER, tab); error = INPapName(ckt, which, foo, "ptspersum", parm); if (error) current->error = INPerrCat(current->error, INPerror(error)); } else { ptemp.iValue = 0; error = INPapName(ckt, which, foo, "ptspersum", &ptemp); if (error) current->error = INPerrCat(current->error, INPerror(error)); } } else
///<param name = "*ckt"> ircuit being parsed </param> ///<param name = "*anal"> The options analysis to add to </param> ///<param name = "*optCard"> The card image to get data from </param> ///<param name = "*tab"> The parse tables for this circuit </param> void INPdoOpts(GENERIC *ckt, GENERIC *anal, card *optCard, INPtables *tab) { char *line; char *token; char *errmsg; IFvalue *val = NULL; int error; int i; int which; IFanalysis *prm = NULL; which = -1; i = 0; for (i = 0; i < ft_sim->numAnalyses; i++) { prm = ft_sim->analyses[i]; if (strcmp(prm->name, "options") == 0) { which = i; break; } i++; } if (which == -1) { optCard->error = INPerrCat(optCard->error, INPmkTemp("errr: analysis options table not found\n")); return; } line = optCard->line; INPgetTok(&line, &token, 1); /* throw away '.option' */ while (*line) { INPgetTok(&line, &token, 1); for (i = 0; i < prm->numParms; i++) { if (strcmp(token, prm->analysisParms[i].keyword) == 0) { if (!(prm->analysisParms[i].dataType & IF_UNIMP_MASK)) { errmsg = (char *)MALLOC((45 + strlen(token)) * sizeof(char)); (void)sprintf(errmsg, " Warning: %s not yet implemented - ignored \n", token); optCard->error = INPerrCat(optCard->error, errmsg); val = INPgetValue(ckt, &line, prm->analysisParms[i].dataType, tab); break; } if (prm->analysisParms[i].dataType & IF_SET) { val = INPgetValue(ckt, &line, prm->analysisParms[i].dataType&IF_VARTYPES, tab); error = (*(ft_sim->setAnalysisParm))(ckt, anal, prm->analysisParms[i].id, val, (IFvalue*)NULL); if (error) { errmsg = (char *)MALLOC((35 + strlen(token))*sizeof(char)); (void)sprintf(errmsg, "Warning: can't set optione %s\n", token); optCard->error = INPerrCat(optCard->error, errmsg); } break; } } } if (i == prm->numParms) { errmsg = (char *)MALLOC(100 * sizeof(char)); (void)strcpy(errmsg, " Error: unknown option - ignored\n"); optCard->error = INPerrCat(optCard->error, errmsg); } } }
void INP2W(CKTcircuit *ckt, INPtables * tab, card * current) { /* Wname <node> <node> <vctrl> [<modname>] [IC] */ /* CURRENT CONTROLLED SWITCH */ int mytype; /* the type we determine resistors are */ int type; /* the type the model says it is */ char *line; /* the part of the current line left to parse */ char *name; /* the resistor's name */ char *model; /* the name of the resistor's model */ char *nname1; /* the first node's name */ char *nname2; /* the second node's name */ CKTnode *node1; /* the first node's node pointer */ CKTnode *node2; /* the second node's node pointer */ int error; /* error code temporary */ INPmodel *thismodel; /* pointer to model structure describing our model */ GENmodel *mdfast; /* pointer to the actual model */ GENinstance *fast; /* pointer to the actual instance */ IFvalue ptemp; /* a value structure to package resistance into */ IFvalue *parm; /* pointer to a value structure for functions to return */ int waslead; /* flag to indicate that funny unlabeled number was found */ double leadval; /* actual value of unlabeled number */ IFuid uid; /* uid for default model */ mytype = INPtypelook("CSwitch"); if (mytype < 0) { LITERR("Device type CSwitch not supported by this binary\n"); return; } line = current->line; INPgetTok(&line, &name, 1); INPinsert(&name, tab); INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); parm = INPgetValue(ckt, &line, IF_INSTANCE, tab); ptemp.uValue = parm->uValue; INPgetTok(&line, &model, 1); INPinsert(&model, tab); current->error = INPgetMod(ckt, model, &thismodel, tab); if (thismodel != NULL) { if (mytype != thismodel->INPmodType) { LITERR("incorrect model type"); return; } type = mytype; mdfast = (thismodel->INPmodfast); } else { type = mytype; if (!tab->defWmod) { /* create deafult W model */ IFnewUid(ckt, &uid, NULL, "W", UID_MODEL, NULL); IFC(newModel, (ckt, type, &(tab->defWmod), uid)); } mdfast = tab->defWmod; } IFC(newInstance, (ckt, mdfast, &fast, name)); GCA(INPpName, ("control", &ptemp, ckt, type, fast)); IFC(bindNode, (ckt, fast, 1, node1)); IFC(bindNode, (ckt, fast, 2, node2)); PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); if (waslead) { /* ignore a number */ } }
///<param name = "*ckt"> THe current circuit </param> ///<param name = "*name"> The name of the model </param> ///<param name = "**model"> The parse model structure </param> ///<param name = "*tab"> The current symbol table </param> char *INPgetMod(GENERIC * ckt, char *name, INPmodel **model, INPtables *tab) { INPmodel *modtmp; IFvalue * val; register int j; char * line; char *parm; char *err = NULL; char *temp; int error; for (modtmp = modtab; modtmp != (INPmodel *)NULL; modtmp = ((modtmp)->INPnextModel)) { if (strcmp((modtmp)->INPmodName, name) == 0) { /* found the model in question - now instantiate if necessary */ /* and return an appropriate pointer to it */ if (modtmp->INPmodType < 0) { /* illegal device type, so can't handle */ *model = (INPmodel *)NULL; err = (char *)MALLOC((35 + strlen(name)) * sizeof(char)); (void)sprintf(err, "Unknown device type for model %s \n", name); return(err); } if (!((modtmp)->INPmodUsed)) { /* not already defined, so create & give parameters */ error = (*(ft_sim->newModel))(ckt, (modtmp)->INPmodType, &((modtmp)->INPmodfast), (modtmp)->INPmodName); if (error) return(INPerror(error)); /* parameter isolation, identification, binding */ line = ((modtmp)->INPmodLine)->line; INPgetTok(&line, &parm, 1); /* throw away '.model' */ INPgetTok(&line, &parm, 1); /* throw away 'modname' */ while (*line != 0) { INPgetTok(&line, &parm, 1); if (!*parm) continue; for (j = 0; j < (*(*(ft_sim->devices)[(modtmp)->INPmodType]).numModelParms); j++) { if (strcmp(parm, ((*(ft_sim->devices)[(modtmp)->INPmodType]).modelParms[j].keyword)) == 0) { val = INPgetValue(ckt, &line, ((*(ft_sim->devices)[(modtmp)->INPmodType]).modelParms[j].dataType), tab); error = (*(ft_sim->setModelParm))(ckt, ((modtmp)->INPmodfast), (*(ft_sim->devices)[(modtmp)->INPmodType]).modelParms[j].id, val, (IFvalue*)NULL); if (error) return(INPerror(error)); break; } } if (strcmp(parm, "level") == 0) { /* just grab the level number and throw away */ /* since we already have that info from pass1 */ val = INPgetValue(ckt, &line, IF_REAL, tab); } else if (j >= (*(*(ft_sim->devices)[(modtmp)->INPmodType]).numModelParms)) { temp = (char *)MALLOC((40 + strlen(parm)) * sizeof(char)); (void)sprintf(temp, "unrecognized parameter (%s) - ignored\n", parm); err = INPerrCat(err, temp); } FREE(parm); } (modtmp)->INPmodUsed = 1; (modtmp)->INPmodLine->error = err; } *model = modtmp; return((char *)NULL); } } /* didn't find model - ERROR - return model */ *model = (INPmodel *)NULL; err = (char *)MALLOC((60 + strlen(name)) * sizeof(char)); (void)sprintf(err, " unable to find definition of model %s - default assumed \n", name); return(err); }