|
|
|
@ -16,300 +16,282 @@ void |
|
|
|
INP2M (CKTcircuit *ckt, INPtables * tab, card * current) |
|
|
|
{ |
|
|
|
|
|
|
|
/* Mname <node> <node> <node> <node> <model> [L=<val>] |
|
|
|
* [W=<val>] [AD=<val>] [AS=<val>] [PD=<val>] |
|
|
|
* [PS=<val>] [NRD=<val>] [NRS=<val>] [OFF] |
|
|
|
* [IC=<val>,<val>,<val>] |
|
|
|
*/ |
|
|
|
/* Mname <node> <node> <node> <node> <model> [L=<val>] |
|
|
|
* [W=<val>] [AD=<val>] [AS=<val>] [PD=<val>] |
|
|
|
* [PS=<val>] [NRD=<val>] [NRS=<val>] [OFF] |
|
|
|
* [IC=<val>,<val>,<val>] |
|
|
|
*/ |
|
|
|
|
|
|
|
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 *nname1; /* the first node's name */ |
|
|
|
char *nname2; /* the second node's name */ |
|
|
|
char *nname3; /* the third node's name */ |
|
|
|
char *nname4; /* the fourth node's name */ |
|
|
|
char *nname5; /* the fifth node's name */ |
|
|
|
char *nname6; /* the sixt node's name */ |
|
|
|
char *nname7; /* the seventh node's name */ |
|
|
|
char *save; /* saj - used to save the posn of the start of |
|
|
|
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 *nname1; /* the first node's name */ |
|
|
|
char *nname2; /* the second node's name */ |
|
|
|
char *nname3; /* the third node's name */ |
|
|
|
char *nname4; /* the fourth node's name */ |
|
|
|
char *nname5; /* the fifth node's name */ |
|
|
|
char *nname6; /* the sixt node's name */ |
|
|
|
char *nname7; /* the seventh node's name */ |
|
|
|
char *save; /* saj - used to save the posn of the start of |
|
|
|
the parameters if the model is a mosfet*/ |
|
|
|
CKTnode *node1; /* the first node's node pointer */ |
|
|
|
CKTnode *node2; /* the second node's node pointer */ |
|
|
|
CKTnode *node3; /* the third node's node pointer */ |
|
|
|
CKTnode *node4; /* the fourth node's node pointer */ |
|
|
|
CKTnode *node5; /* the fifth node's node pointer */ |
|
|
|
CKTnode *node6; /* the sixth node's node pointer */ |
|
|
|
CKTnode *node7; /* the seventh node's node pointer */ |
|
|
|
int error; /* error code temporary */ |
|
|
|
int nodeflag; /* flag indicating 4 or 5 (or 6 or 7) nodes */ |
|
|
|
GENinstance *fast; /* pointer to the actual instance */ |
|
|
|
int waslead; /* flag to indicate that funny unlabeled number was found */ |
|
|
|
double leadval; /* actual value of unlabeled number */ |
|
|
|
char *model; /* the name of the model */ |
|
|
|
INPmodel *thismodel; /* pointer to model description for user's model */ |
|
|
|
GENmodel *mdfast; /* pointer to the actual model */ |
|
|
|
IFuid uid; /* uid for default model */ |
|
|
|
char* err_msg; |
|
|
|
CKTnode *node1; /* the first node's node pointer */ |
|
|
|
CKTnode *node2; /* the second node's node pointer */ |
|
|
|
CKTnode *node3; /* the third node's node pointer */ |
|
|
|
CKTnode *node4; /* the fourth node's node pointer */ |
|
|
|
CKTnode *node5; /* the fifth node's node pointer */ |
|
|
|
CKTnode *node6; /* the sixth node's node pointer */ |
|
|
|
CKTnode *node7; /* the seventh node's node pointer */ |
|
|
|
int error; /* error code temporary */ |
|
|
|
int nodeflag; /* flag indicating 4 or 5 (or 6 or 7) nodes */ |
|
|
|
GENinstance *fast; /* pointer to the actual instance */ |
|
|
|
int waslead; /* flag to indicate that funny unlabeled number was found */ |
|
|
|
double leadval; /* actual value of unlabeled number */ |
|
|
|
char *model; /* the name of the model */ |
|
|
|
INPmodel *thismodel; /* pointer to model description for user's model */ |
|
|
|
GENmodel *mdfast; /* pointer to the actual model */ |
|
|
|
IFuid uid; /* uid for default model */ |
|
|
|
char* err_msg; |
|
|
|
|
|
|
|
#ifdef TRACE |
|
|
|
printf("INP2M: Parsing '%s'\n",current->line); |
|
|
|
printf("INP2M: Parsing '%s'\n",current->line); |
|
|
|
#endif |
|
|
|
|
|
|
|
nodeflag = 0; /* initially specify a 4 terminal device */ |
|
|
|
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); |
|
|
|
INPgetNetTok (&line, &nname3, 1); |
|
|
|
INPtermInsert (ckt, &nname3, tab, &node3); |
|
|
|
INPgetNetTok (&line, &nname4, 1); |
|
|
|
INPtermInsert (ckt, &nname4, tab, &node4); |
|
|
|
nodeflag = 0; /* initially specify a 4 terminal device */ |
|
|
|
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); |
|
|
|
INPgetNetTok (&line, &nname3, 1); |
|
|
|
INPtermInsert (ckt, &nname3, tab, &node3); |
|
|
|
INPgetNetTok (&line, &nname4, 1); |
|
|
|
INPtermInsert (ckt, &nname4, tab, &node4); |
|
|
|
|
|
|
|
node5 = NULL; |
|
|
|
node6 = NULL; |
|
|
|
node7 = NULL; |
|
|
|
node5 = NULL; |
|
|
|
node6 = NULL; |
|
|
|
node7 = NULL; |
|
|
|
|
|
|
|
/* See if 5th token after device specification is a model name */ |
|
|
|
/* See if 5th token after device specification is a model name */ |
|
|
|
|
|
|
|
INPgetNetTok (&line, &nname5, 1); /* get 5th token */ |
|
|
|
save = line; /* saj - save the posn for later if |
|
|
|
INPgetNetTok (&line, &nname5, 1); /* get 5th token */ |
|
|
|
save = line; /* saj - save the posn for later if |
|
|
|
the default mosfet model is used */ |
|
|
|
thismodel = NULL; |
|
|
|
thismodel = NULL; |
|
|
|
#ifdef TRACE |
|
|
|
printf("INP2M: checking for 4 node device\n"); |
|
|
|
printf("INP2M: checking for 4 node device\n"); |
|
|
|
#endif |
|
|
|
err_msg = INPgetMod (ckt, nname5, &thismodel, tab); |
|
|
|
tfree(err_msg); |
|
|
|
/* check if using model binning -- pass in line since need 'l' and 'w' */ |
|
|
|
if ( thismodel == NULL ) { |
|
|
|
INPgetModBin( ckt, nname5, &thismodel, tab, line ); |
|
|
|
} |
|
|
|
err_msg = INPgetMod (ckt, nname5, &thismodel, tab); |
|
|
|
tfree(err_msg); |
|
|
|
/* 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 */ |
|
|
|
INPgetNetTok (&line, &nname6, 1); /* get next token */ |
|
|
|
thismodel = NULL; |
|
|
|
#ifdef TRACE |
|
|
|
printf("INP2M: checking for 5 node device\n"); |
|
|
|
#endif |
|
|
|
err_msg = INPgetMod (ckt, nname6, &thismodel, tab); |
|
|
|
tfree(err_msg); |
|
|
|
if (thismodel == NULL) |
|
|
|
{ /* 6th token is not a model in the table */ |
|
|
|
nodeflag = 2; /* now specify a 6 node device */ |
|
|
|
INPgetNetTok (&line, &nname7, 1); /* get next token */ |
|
|
|
if (thismodel == NULL) { |
|
|
|
/* 5th token is not a model in the table */ |
|
|
|
nodeflag = 1; /* now specify a 5 node device */ |
|
|
|
INPgetNetTok (&line, &nname6, 1); /* get next token */ |
|
|
|
thismodel = NULL; |
|
|
|
#ifdef TRACE |
|
|
|
printf("INP2M: checking for 6 node device\n"); |
|
|
|
printf("INP2M: checking for 5 node device\n"); |
|
|
|
#endif |
|
|
|
err_msg = INPgetMod (ckt, nname7, &thismodel, tab); |
|
|
|
err_msg = INPgetMod (ckt, nname6, &thismodel, tab); |
|
|
|
tfree(err_msg); |
|
|
|
if (thismodel == NULL) |
|
|
|
{ /* 7th token is not a model in the table */ |
|
|
|
nodeflag = 3; /* now specify a 7 node device */ |
|
|
|
INPgetTok (&line, &model, 1); /* get model name */ |
|
|
|
if (thismodel == NULL) { |
|
|
|
/* 6th token is not a model in the table */ |
|
|
|
nodeflag = 2; /* now specify a 6 node device */ |
|
|
|
INPgetNetTok (&line, &nname7, 1); /* get next token */ |
|
|
|
thismodel = NULL; |
|
|
|
#ifdef TRACE |
|
|
|
printf("INP2M: checking for 7 node device\n"); |
|
|
|
printf("INP2M: checking for 6 node device\n"); |
|
|
|
#endif |
|
|
|
err_msg = INPgetMod (ckt, model, &thismodel, tab); /* get pointer to the model */ |
|
|
|
err_msg = INPgetMod (ckt, nname7, &thismodel, tab); |
|
|
|
tfree(err_msg); |
|
|
|
if (thismodel != NULL) |
|
|
|
{ |
|
|
|
if ((thismodel->INPmodType != INPtypelook ("B4SOI")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIDD")) |
|
|
|
) |
|
|
|
{ |
|
|
|
/* if model is not variable node B3SOIPD/FD/DD model, error! */ |
|
|
|
LITERR ("only level 55-58: B3SOI(PD|FD|DD) and B4SOI can have 7 nodes"); |
|
|
|
return; |
|
|
|
} |
|
|
|
else |
|
|
|
{ /* if looking at B3SOIPD/FD/DD or B4SOI model, allocate the 7th node */ |
|
|
|
INPtermInsert (ckt, &nname5, tab, &node5); |
|
|
|
INPtermInsert (ckt, &nname6, tab, &node6); |
|
|
|
INPtermInsert (ckt, &nname7, tab, &node7); |
|
|
|
if (thismodel == NULL) { |
|
|
|
/* 7th token is not a model in the table */ |
|
|
|
nodeflag = 3; /* now specify a 7 node device */ |
|
|
|
INPgetTok (&line, &model, 1); /* get model name */ |
|
|
|
#ifdef TRACE |
|
|
|
printf("INP2M: checking for 7 node device\n"); |
|
|
|
#endif |
|
|
|
err_msg = INPgetMod (ckt, model, &thismodel, tab); /* get pointer to the model */ |
|
|
|
tfree(err_msg); |
|
|
|
if (thismodel != NULL) { |
|
|
|
if ((thismodel->INPmodType != INPtypelook ("B4SOI")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIDD")) |
|
|
|
) { |
|
|
|
/* if model is not variable node B3SOIPD/FD/DD model, error! */ |
|
|
|
LITERR ("only level 55-58: B3SOI(PD|FD|DD) and B4SOI can have 7 nodes"); |
|
|
|
return; |
|
|
|
} else { |
|
|
|
/* if looking at B3SOIPD/FD/DD or B4SOI model, allocate the 7th node */ |
|
|
|
INPtermInsert (ckt, &nname5, tab, &node5); |
|
|
|
INPtermInsert (ckt, &nname6, tab, &node6); |
|
|
|
INPtermInsert (ckt, &nname7, tab, &node7); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
/* saj - unbreak the default model creation*/ |
|
|
|
else{ |
|
|
|
/* saj - unbreak the default model creation*/ |
|
|
|
else { |
|
|
|
#ifdef TRACE |
|
|
|
printf("INP2M: couldn't workout number of nodes, assuming 4\n"); |
|
|
|
printf("INP2M: couldn't workout number of nodes, assuming 4\n"); |
|
|
|
#endif |
|
|
|
nodeflag = 0; /* now reset to a 4 node device */ |
|
|
|
model = nname5;/* mosfet*/ |
|
|
|
line = save; /* reset the posn to what it sould be */ |
|
|
|
} |
|
|
|
/*saj*/ |
|
|
|
} |
|
|
|
else |
|
|
|
{ /* 7th token is a model - only have 6 terminal device */ |
|
|
|
nodeflag = 0; /* now reset to a 4 node device */ |
|
|
|
model = nname5;/* mosfet*/ |
|
|
|
line = save; /* reset the posn to what it sould be */ |
|
|
|
} |
|
|
|
/*saj*/ |
|
|
|
} else { |
|
|
|
/* 7th token is a model - only have 6 terminal device */ |
|
|
|
if ((thismodel->INPmodType != INPtypelook ("B4SOI")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIDD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("HiSIMHV")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("SOI3")) |
|
|
|
) { |
|
|
|
/* if model is not variable node B3SOIPD/FD/DD or STAG model, error! */ |
|
|
|
LITERR ("only level 55-58,61,62: B3SOI(PD|FD|DD), B4SOI, STAG (SOI3) and HiSIMHV can have 6 nodes"); |
|
|
|
return; |
|
|
|
} else { |
|
|
|
/* if looking at B3SOIPD/FD/DD, B4SOI, STAG (SOI3) or HiSIMHV model, allocate the 6th node */ |
|
|
|
INPtermInsert (ckt, &nname5, tab, &node5); |
|
|
|
INPtermInsert (ckt, &nname6, tab, &node6); |
|
|
|
model = nname7; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
/* 6th token is a model - only have 5 terminal device */ |
|
|
|
if ((thismodel->INPmodType != INPtypelook ("B4SOI")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIDD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("HiSIMHV")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("SOI3")) |
|
|
|
) |
|
|
|
{ |
|
|
|
/* if model is not variable node B3SOIPD/FD/DD or STAG model, error! */ |
|
|
|
LITERR ("only level 55-58,61,62: B3SOI(PD|FD|DD), B4SOI, STAG (SOI3) and HiSIMHV can have 6 nodes"); |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIDD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("HiSIMHV")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("SOI3")) |
|
|
|
) { |
|
|
|
/* if model is not variable node B3SOIPD/FD/DD model, error! */ |
|
|
|
LITERR ("only level 55-58,61,62: B3SOI(PD|FD|DD), B4SOI, STAG (SOI3) and HiSIMHV can have 5 nodes"); |
|
|
|
return; |
|
|
|
} else { |
|
|
|
/* if looking at B3SOIPD/FD/DD, B4SOI, STAG (SOI3) or HiSIMHV model, allocate the 5th node */ |
|
|
|
INPtermInsert (ckt, &nname5, tab, &node5); |
|
|
|
model = nname6; /* make model point to the correct token */ |
|
|
|
} |
|
|
|
else |
|
|
|
{ /* if looking at B3SOIPD/FD/DD, B4SOI, STAG (SOI3) or HiSIMHV model, allocate the 6th node */ |
|
|
|
INPtermInsert (ckt, &nname5, tab, &node5); |
|
|
|
INPtermInsert (ckt, &nname6, tab, &node6); |
|
|
|
model = nname7; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ /* 6th token is a model - only have 5 terminal device */ |
|
|
|
if ((thismodel->INPmodType != INPtypelook ("B4SOI")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("B3SOIDD")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("HiSIMHV")) && |
|
|
|
(thismodel->INPmodType != INPtypelook ("SOI3")) |
|
|
|
) |
|
|
|
{ |
|
|
|
/* if model is not variable node B3SOIPD/FD/DD model, error! */ |
|
|
|
LITERR ("only level 55-58,61,62: B3SOI(PD|FD|DD), B4SOI, STAG (SOI3) and HiSIMHV can have 5 nodes"); |
|
|
|
return; |
|
|
|
} |
|
|
|
else |
|
|
|
{ /* if looking at B3SOIPD/FD/DD, B4SOI, STAG (SOI3) or HiSIMHV model, allocate the 5th node */ |
|
|
|
INPtermInsert (ckt, &nname5, tab, &node5); |
|
|
|
model = nname6; /* make model point to the correct token */ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
{ /* 5th token is a model - only have 4 terminal device */ |
|
|
|
model = nname5; /* make model point to the correct token */ |
|
|
|
else { |
|
|
|
/* 5th token is a model - only have 4 terminal device */ |
|
|
|
model = nname5; /* make model point to the correct token */ |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
INPinsert (&model, tab); |
|
|
|
thismodel = NULL; |
|
|
|
INPinsert (&model, tab); |
|
|
|
thismodel = NULL; |
|
|
|
#ifdef TRACE |
|
|
|
printf("INP2M: Looking up model\n"); |
|
|
|
printf("INP2M: Looking up model\n"); |
|
|
|
#endif |
|
|
|
|
|
|
|
err_msg = INPgetMod (ckt, model, &thismodel, tab); |
|
|
|
if ( thismodel == NULL ) { |
|
|
|
INPgetModBin( ckt, model, &thismodel, tab, save ); |
|
|
|
if ( thismodel == NULL ) current->error = err_msg; |
|
|
|
} |
|
|
|
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 != NULL) { |
|
|
|
if (thismodel->INPmodType != INPtypelook ("Mos1") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos2") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos3") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos5") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos6") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos8") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos9") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM1") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM2") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM3") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM3v32") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("B4SOI") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("B3SOIPD") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("B3SOIFD") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("B3SOIDD") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM4") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM4v4") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM4v5") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM4v6") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM3v0") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM3v1") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("SOI3") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos2") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos3") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos5") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos6") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos8") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("Mos9") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM1") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM2") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM3") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM3v32") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("B4SOI") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("B3SOIPD") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("B3SOIFD") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("B3SOIDD") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM4") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM4v4") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM4v5") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM4v6") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM3v0") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("BSIM3v1") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("SOI3") |
|
|
|
#ifdef CIDER |
|
|
|
&& thismodel->INPmodType != INPtypelook ("NUMOS") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("NUMOS") |
|
|
|
#endif |
|
|
|
#ifdef ADMS |
|
|
|
&& thismodel->INPmodType != INPtypelook ("ekv") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("psp102") |
|
|
|
#endif |
|
|
|
&& thismodel->INPmodType != INPtypelook ("HiSIM2") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("HiSIMHV") |
|
|
|
) |
|
|
|
{ |
|
|
|
LITERR ("incorrect model type"); |
|
|
|
return; |
|
|
|
} |
|
|
|
type = thismodel->INPmodType; |
|
|
|
mdfast = (thismodel->INPmodfast); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
type = INPtypelook ("Mos1"); |
|
|
|
if (type < 0) |
|
|
|
{ |
|
|
|
LITERR ("Device type MOS1 not supported by this binary\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (!tab->defMmod) |
|
|
|
{ |
|
|
|
/* create default M model */ |
|
|
|
IFnewUid (ckt, &uid, NULL, "M", UID_MODEL, NULL); |
|
|
|
IFC (newModel, (ckt, type, &(tab->defMmod), uid)); |
|
|
|
} |
|
|
|
mdfast = tab->defMmod; |
|
|
|
&& thismodel->INPmodType != INPtypelook ("ekv") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("psp102") |
|
|
|
#endif |
|
|
|
&& thismodel->INPmodType != INPtypelook ("HiSIM2") |
|
|
|
&& thismodel->INPmodType != INPtypelook ("HiSIMHV") |
|
|
|
) { |
|
|
|
LITERR ("incorrect model type"); |
|
|
|
return; |
|
|
|
} |
|
|
|
type = thismodel->INPmodType; |
|
|
|
mdfast = (thismodel->INPmodfast); |
|
|
|
} else { |
|
|
|
type = INPtypelook ("Mos1"); |
|
|
|
if (type < 0) { |
|
|
|
LITERR ("Device type MOS1 not supported by this binary\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (!tab->defMmod) { |
|
|
|
/* create default M model */ |
|
|
|
IFnewUid (ckt, &uid, NULL, "M", UID_MODEL, NULL); |
|
|
|
IFC (newModel, (ckt, type, &(tab->defMmod), uid)); |
|
|
|
} |
|
|
|
mdfast = tab->defMmod; |
|
|
|
} |
|
|
|
IFC (newInstance, (ckt, mdfast, &fast, name)); |
|
|
|
IFC (bindNode, (ckt, fast, 1, node1)); |
|
|
|
IFC (bindNode, (ckt, fast, 2, node2)); |
|
|
|
IFC (bindNode, (ckt, fast, 3, node3)); |
|
|
|
IFC (bindNode, (ckt, fast, 4, node4)); |
|
|
|
/* use type - not thismodel->INPmodType as it might not exist! */ |
|
|
|
if ((type == INPtypelook ("B4SOI")) || |
|
|
|
(type == INPtypelook ("B3SOIPD")) || |
|
|
|
(type == INPtypelook ("B3SOIFD")) || |
|
|
|
(type == INPtypelook ("B3SOIDD")) || |
|
|
|
(type == INPtypelook ("HiSIMHV")) || |
|
|
|
(type == INPtypelook ("SOI3"))) |
|
|
|
{ |
|
|
|
switch (nodeflag) |
|
|
|
{ |
|
|
|
case 0: |
|
|
|
fast->GENnode5 = -1; |
|
|
|
fast->GENnode6 = -1; |
|
|
|
fast->GENnode7 = -1; |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
IFC (bindNode, (ckt, fast, 5, node5)); |
|
|
|
fast->GENnode6 = -1; |
|
|
|
fast->GENnode7 = -1; |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
IFC (bindNode, (ckt, fast, 5, node5)); |
|
|
|
IFC (bindNode, (ckt, fast, 6, node6)); |
|
|
|
fast->GENnode7 = -1; |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
IFC (bindNode, (ckt, fast, 5, node5)); |
|
|
|
IFC (bindNode, (ckt, fast, 6, node6)); |
|
|
|
IFC (bindNode, (ckt, fast, 7, node7)); |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
IFC (newInstance, (ckt, mdfast, &fast, name)); |
|
|
|
IFC (bindNode, (ckt, fast, 1, node1)); |
|
|
|
IFC (bindNode, (ckt, fast, 2, node2)); |
|
|
|
IFC (bindNode, (ckt, fast, 3, node3)); |
|
|
|
IFC (bindNode, (ckt, fast, 4, node4)); |
|
|
|
/* use type - not thismodel->INPmodType as it might not exist! */ |
|
|
|
if ((type == INPtypelook ("B4SOI")) || |
|
|
|
(type == INPtypelook ("B3SOIPD")) || |
|
|
|
(type == INPtypelook ("B3SOIFD")) || |
|
|
|
(type == INPtypelook ("B3SOIDD")) || |
|
|
|
(type == INPtypelook ("HiSIMHV")) || |
|
|
|
(type == INPtypelook ("SOI3"))) { |
|
|
|
switch (nodeflag) { |
|
|
|
case 0: |
|
|
|
fast->GENnode5 = -1; |
|
|
|
fast->GENnode6 = -1; |
|
|
|
fast->GENnode7 = -1; |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
IFC (bindNode, (ckt, fast, 5, node5)); |
|
|
|
fast->GENnode6 = -1; |
|
|
|
fast->GENnode7 = -1; |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
IFC (bindNode, (ckt, fast, 5, node5)); |
|
|
|
IFC (bindNode, (ckt, fast, 6, node6)); |
|
|
|
fast->GENnode7 = -1; |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
IFC (bindNode, (ckt, fast, 5, node5)); |
|
|
|
IFC (bindNode, (ckt, fast, 6, node6)); |
|
|
|
IFC (bindNode, (ckt, fast, 7, node7)); |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
PARSECALL ((&line, ckt, type, fast, &leadval, &waslead, tab)); |
|
|
|
if (waslead) |
|
|
|
{ |
|
|
|
LITERR (" error: no unlabeled parameter permitted on mosfet\n"); |
|
|
|
PARSECALL ((&line, ckt, type, fast, &leadval, &waslead, tab)); |
|
|
|
if (waslead) { |
|
|
|
LITERR (" error: no unlabeled parameter permitted on mosfet\n"); |
|
|
|
} |
|
|
|
} |