You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

684 lines
18 KiB

/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice/ngspice.h"
#include "ngspice/iferrmsg.h"
#include "ngspice/inpdefs.h"
#include "inpxx.h"
/*--------------------------------------------------------------
* This fcn takes the model card & examines it. Depending upon
* model type, it parses the model line, and then calls
* INPmakeMod to stick the model name into the model list.
* Note that multi-line models are handled in the calling fcn
* (INPpas1).
*-------------------------------------------------------------*/
char *INPdomodel(CKTcircuit *ckt, struct card *image, INPtables * tab)
{
char *modname;
int type = -1;
int lev, error1=0;
char ver[100];
char *type_name;
char *err = NULL;
char *line;
char *val;
double rval=0, lval=0;
NG_IGNORE(ckt);
line = image->line;
#ifdef TRACE
printf("In INPdomodel, examining line %s . . . \n", line);
#endif
INPgetTok(&line, &modname, 1); /* throw away '.model' */
tfree(modname);
INPgetNetTok(&line, &modname, 1); /* get model name */
INPinsert(&modname, tab); /* stick model name into table */
INPgetTok(&line, &type_name, 1); /* get model type */
/* ----- Check if model is a BJT --------- */
if (strcmp(type_name, "npn") == 0 || strcmp(type_name, "pnp") == 0) {
err = INPfindLev(line,&lev);
switch(lev) {
case 0:
case 1:
case 2:
type = INPtypelook("BJT");
if (type < 0) {
err = INPmkTemp(
"Device type BJT not available in this binary\n");
}
break;
case 4:
case 9:
type = INPtypelook("VBIC");
if(type < 0) {
err = INPmkTemp(
"Device type VBIC not available in this binary\n");
}
break;
#ifdef ADMS
case 6:
type = INPtypelook("bjt504t");
if(type < 0) {
err = INPmkTemp(
"Device type MEXTRAM not available in this binary\n");
}
break;
case 7:
type = INPtypelook("hicum0");
if(type < 0) {
err = INPmkTemp(
"Device type HICUM0 not available in this binary\n");
}
break;
case 8:
type = INPtypelook("hicum2");
if(type < 0) {
err = INPmkTemp(
"Device type HICUM2 not available in this binary\n");
}
break;
#endif
default: /* placeholder; use level 4 for the next model */
#ifdef ADMS
err = INPmkTemp(
"Only BJT levels 1-2, 4,6-9 are supported in this binary\n");
#else
err = INPmkTemp(
"Only BJT levels 1-2, 4, 9 are supported in this binary\n");
#endif
break;
}
INPmakeMod(modname, type, image);
} /* end if ((strcmp(typename, "npn") == 0) || (strcmp(typename, "pnp") == 0)) */
/* -------- Check if model is a diode --------- */
else if (strcmp(type_name, "d") == 0) {
type = INPtypelook("Diode");
if (type < 0) {
err =
INPmkTemp
("Device type Diode not available in this binary\n");
}
INPmakeMod(modname, type, image);
} /* else if (strcmp(typename, "d") == 0) { */
/* -------- Check if model is a jfet --------- */
else if (strcmp(type_name, "njf") == 0 ||
strcmp(type_name, "pjf") == 0) {
err = INPfindLev(line, &lev);
switch (lev) {
case 0:
case 1:
type = INPtypelook("JFET");
if (type < 0) {
err =
INPmkTemp
("Device type JFET not available in this binary\n");
}
break;
case 2:
type = INPtypelook("JFET2");
if (type < 0) {
err =
INPmkTemp
("Device type JFET2 not available in this binary\n");
}
break;
default: /* placeholder; use level 3 for the next model */
err =
INPmkTemp
("Only JFET device levels 1-2 are supported in this binary\n");
break;
}
INPmakeMod(modname, type, image);
} /* end else if ((strcmp(typename, "njf") == 0) */
/* -------- Check if model is a MES or an HFET --------- */
else if (strcmp(type_name, "nmf") == 0 ||
strcmp(type_name, "pmf") == 0 ||
strcmp(type_name, "nhfet") == 0 ||
strcmp(type_name, "phfet") == 0) {
err = INPfindLev( line, &lev );
switch ( lev )
{
case 0:
case 1:
type = INPtypelook("MES");
if (type < 0)
{
err = INPmkTemp("Device type MES not available\n");
}
break;
case 2:
type = INPtypelook("MESA");
if (type < 0)
{
err = INPmkTemp("Device type MESA not availabe\n");
}
break;
case 3:
type = INPtypelook("MESA");
if (type < 0)
{
err = INPmkTemp("Device type MESA not availabe\n");
}
break;
case 4:
type = INPtypelook("MESA");
if ( type < 0)
{
err = INPmkTemp(" Device type MESA not available\n");
}
break;
case 5:
type = INPtypelook("HFET1");
if ( type < 0)
{
err = INPmkTemp(" Device type HFET1 not available\n");
}
break;
case 6:
type = INPtypelook("HFET2");
if ( type < 0)
{
err = INPmkTemp(" Device type HFET2 not available in this binary\n");
}
break;
default:
err = INPmkTemp("only mesfet device level 1-4 and hfet level 5-6 supported\n");
break;
}
INPmakeMod(modname, type, image);
}
/* -------- Check if model is a Uniform Distrib. RC line --------- */
else if (strcmp(type_name, "urc") == 0) {
type = INPtypelook("URC");
if (type < 0) {
err =
INPmkTemp
("Device type URC not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
/* ------ Check if model is a VDMOS FET ------- */
else if ((strcmp(type_name, "vdmos") == 0) ||
(strcmp(type_name, "vdmosn") == 0) ||
(strcmp(type_name, "vdmosp") == 0)) {
type = INPtypelook("VDMOS");
if (type < 0) {
err =
INPmkTemp
("Device type VDMOS not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
/* -------- Check if model is a MOSFET --------- */
else if ((strcmp(type_name, "nmos") == 0)
|| (strcmp(type_name, "pmos") == 0)
|| (strcmp(type_name, "nsoi") == 0)
|| (strcmp(type_name, "psoi") == 0)) {
err = INPfindLev(line, &lev);
switch (lev) {
case 0:
case 1:
type = INPtypelook("Mos1");
if (type < 0) {
err =
INPmkTemp
("Device type MOS1 not available in this binary\n");
}
break;
case 2:
type = INPtypelook("Mos2");
if (type < 0) {
err =
INPmkTemp
("Device type MOS2 not available in this binary\n");
}
break;
case 3:
type = INPtypelook("Mos3");
if (type < 0) {
err =
INPmkTemp
("Device type MOS3 not available in this binary\n");
}
break;
case 4:
type = INPtypelook("BSIM1");
if (type < 0) {
err =
INPmkTemp
("Device type BSIM1 not available in this binary\n");
}
break;
case 5:
type = INPtypelook("BSIM2");
if (type < 0) {
err =
INPmkTemp
("Device type BSIM2 not available in this binary\n");
}
break;
case 6:
type = INPtypelook("Mos6");
if (type < 0) {
err =
INPmkTemp
("Device type MOS6 not available in this binary\n");
}
break;
case 7:
type = INPtypelook("MOS7");
if (type < 0) {
err =
INPmkTemp
("Device type MOS7 not available in this binary\n");
}
break;
case 8: case 49:
err = INPfindVer(line, ver);
if ( strcmp(ver, "3.0") == 0 ) {
type = INPtypelook("BSIM3v0");
}
if ( strcmp(ver, "3.1") == 0 ) {
type = INPtypelook("BSIM3v1");
}
if ( prefix("3.2", ver)) { /* version string ver has to start with 3.2 */
type = INPtypelook("BSIM3v32");
}
if ( (strstr(ver, "default")) || (prefix("3.3", ver)) ) {
type = INPtypelook("BSIM3");
}
if (type < 0) {
err = tprintf("Device type BSIM3 version %s not available in this binary\n", ver);
}
break;
case 9:
type = INPtypelook("Mos9");
if(type < 0) {
err = INPmkTemp
("Device type MOS9 not available in this binary\n");
}
break;
case 14: case 54:
err = INPfindVer(line, ver); /* mapping of minor versions >= 4.2.1 are included */
if ((prefix("4.0", ver)) || (prefix("4.1", ver)) || (prefix("4.2", ver)) || (prefix("4.3", ver)) || (prefix("4.4", ver)) || (prefix("4.5", ver))) {
type = INPtypelook("BSIM4v5");
}
if (prefix("4.6", ver)) {
type = INPtypelook("BSIM4v6");
}
if (prefix("4.7", ver)) {
type = INPtypelook("BSIM4v7");
}
if ( (strstr(ver, "default")) || (prefix("4.8", ver)) ) {
type = INPtypelook("BSIM4");
}
if (type < 0) {
err = tprintf("Device type BSIM4 version %s not available in this binary\n", ver);
}
break;
case 15:
type = INPtypelook("BSIM5");
if (type < 0) {
err =
INPmkTemp
("Device type BSIM5 not available in this binary\n");
}
break;
case 16:
type = INPtypelook("BSIM6");
if (type < 0) {
err =
INPmkTemp
("Device type BSIM6 not available in this binary\n");}
break;
#ifdef ADMS
case 44:
type = INPtypelook("ekv");
if (type < 0) {
err =
INPmkTemp
("Device type EKV not available in this binary\n");
}
break;
case 45:
type = INPtypelook("psp102");
if (type < 0) {
err =
INPmkTemp
("Device type PSP102 not available in this binary\n");
}
break;
#endif
case 55:
type = INPtypelook("B3SOIFD");
if (type < 0) {
err =
INPmkTemp
("Placeholder: Device type B3SOIFD not available in this binary\n");
}
break;
case 56:
type = INPtypelook("B3SOIDD");
if (type < 0) {
err =
INPmkTemp
("Placeholder: Device type B3SOIDD not available in this binary\n");
}
break;
case 57:
type = INPtypelook("B3SOIPD");
if (type < 0) {
err =
INPmkTemp
("Placeholder: Device type B3SOIPD not available in this binary\n");
}
break;
case 10: case 58:
type = INPtypelook("B4SOI");
if (type < 0) {
err =
INPmkTemp
("Device type B4SOI V4.0 not available in this binary\n");
}
break;
case 60:
type = INPtypelook("SOI3");
if (type < 0) {
err =
INPmkTemp
("Device type SOI3 not available in this binary (STAG release)\n");
}
break;
case 68:
type = INPtypelook("HiSIM2");
if (type < 0) {
err =
INPmkTemp
("Placeholder: Device type HiSIM2 not available in this binary\n");
}
break;
case 73:
err = INPfindVer(line, ver); /* mapping of minor versions >= 1.1 are included */
if ((prefix("1.1", ver)) || (prefix("1.2", ver))) {
type = INPtypelook("HiSIMHV1");
}
if ( (strstr(ver, "default")) || (prefix("2.0", ver)) || (prefix("2.1", ver)) || (prefix("2.2", ver)) ) {
type = INPtypelook("HiSIMHV2");
}
if (type < 0) {
err = tprintf("Device type HiSIMHV version %s not available in this binary\n", ver);
}
break;
default: /* placeholder; use level xxx for the next model */
#ifdef ADMS
err = INPmkTemp
("Only MOS device levels 1-6,8-10,14,44,45,49,54-58,60,68,73 are supported in this binary\n");
#else
err = INPmkTemp
("Only MOS device levels 1-6,8-10,14,49,54-58,60,68,73 are supported in this binary\n");
#endif
break;
}
INPmakeMod(modname, type, image);
}
#ifdef NDEV
/* -------- Check if model is a numerical device --------- */
else if (strcmp(type_name, "ndev") == 0) {
type = INPtypelook("NDEV");
if (type < 0) {
err =
INPmkTemp
("Device type NDEV not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
#endif
/* -------- Check if model is a resistor --------- */
else if (strcmp(type_name, "r") == 0) {
type = INPtypelook("Resistor");
if (type < 0) {
err =
INPmkTemp
("Device type Resistor not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
/* -------- Check if model is a PSPICE resistor --------- */
else if (strcmp(type_name, "res") == 0) {
type = INPtypelook("Resistor");
if (type < 0) {
err =
INPmkTemp
("Device type Resistor not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
/* -------- Check if model is a transmission line of some sort --------- */
else if(strcmp(type_name,"txl") == 0) {
INPgetTok(&line,&val,1);
while (*line != '\0') {
if (*val == 'R' || *val == 'r') {
INPgetTok(&line,&val,1);
rval = INPevaluate(&val, &error1, 1);
}
if ((strcmp(val,"L") == 0) || (strcmp(val,"l") == 0)) {
INPgetTok(&line,&val,1);
lval = INPevaluate(&val, &error1, 1);
}
INPgetTok(&line,&val,1);
}
if(lval)
rval = rval/lval;
if (rval > 1.6e10) {
type = INPtypelook("TransLine");
INPmakeMod(modname,type,image);
}
if (rval > 1.6e9) {
type = INPtypelook("CplLines");
INPmakeMod(modname,type,image);
}
else {
type = INPtypelook("TransLine");
INPmakeMod(modname,type,image);
}
if(type < 0) {
err = INPmkTemp(
"Device type TransLine not available in this binary\n");
}
}
/* -------- Check if model is a coupled transmission line --------- */
else if(strcmp(type_name,"cpl") == 0) {
type = INPtypelook("CplLines");
if(type < 0) {
err = INPmkTemp(
"Device type CplLines not available in this binary\n");
}
INPmakeMod(modname,type,image);
}
/* -------- Check if model is a cap --------- */
else if (strcmp(type_name, "c") == 0) {
type = INPtypelook("Capacitor");
if (type < 0) {
err =
INPmkTemp
("Device type Capacitor not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
/* -------- Check if model is an ind --------- */
else if (strcmp(type_name, "l") == 0) {
type = INPtypelook("Inductor");
if (type < 0) {
err =
INPmkTemp
("Device type Inductor not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
/* -------- Check if model is a switch --------- */
else if (strcmp(type_name, "sw") == 0) {
type = INPtypelook("Switch");
if (type < 0) {
err =
INPmkTemp
("Device type Switch not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
/* -------- Check if model is a Current Controlled Switch --------- */
else if (strcmp(type_name, "csw") == 0) {
type = INPtypelook("CSwitch");
if (type < 0) {
err =
INPmkTemp
("Device type CSwitch not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
/* -------- Check if model is a Lossy TransLine --------- */
else if (strcmp(type_name, "ltra") == 0) {
type = INPtypelook("LTRA");
if (type < 0) {
err =
INPmkTemp
("Device type LTRA not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
#ifdef CIDER
else if(strcmp(type_name,"numd") == 0) {
err = INPfindLev(line,&lev);
switch( lev ) {
case 1:
default:
type = INPtypelook("NUMD");
if(type < 0) {
err =
INPmkTemp
("Device type NUMD not available in this binary\n");
}
break;
case 2:
type = INPtypelook("NUMD2");
if(type < 0) {
err =
INPmkTemp
("Device type NUMD2 not available in this binary\n");
}
break;
}
INPmakeMod(modname,type,image);
} else if(strcmp(type_name,"nbjt") == 0) {
err = INPfindLev(line,&lev);
switch( lev ) {
case 1:
default:
type = INPtypelook("NBJT");
if(type < 0) {
err =
INPmkTemp
("Device type NBJT not available in this binary\n");
}
break;
case 2:
type = INPtypelook("NBJT2");
if(type < 0) {
err =
INPmkTemp
("Device type NBJT2 not available in this binary\n");
}
break;
}
INPmakeMod(modname,type,image);
} else if(strcmp(type_name,"numos") == 0) {
type = INPtypelook("NUMOS");
if(type < 0) {
err =
INPmkTemp
("Device type NUMOS not available in this binary\n");
}
INPmakeMod(modname,type,image);
}
#endif /* CIDER */
/* type poly added by SDB . . . */
#ifdef XSPICE
/* -------- Check if model is a poly (specific to xspice) --------- */
else if ( strcmp(type_name, "poly") == 0 ||
strcmp(type_name, "POLY") == 0 ) {
type = INPtypelook("POLY");
if (type < 0) {
err =
INPmkTemp
("Device type POLY not available in this binary\n");
}
INPmakeMod(modname, type, image);
}
#endif
/* -------- Default action --------- */
else {
#ifndef XSPICE
type = -1;
err = tprintf("unknown model type %s - ignored\n", type_name);
#else
/* gtri - modify - wbk - 10/23/90 - modify to look for code models */
#ifdef TRACE
printf("In INPdomodel, found unknown model type, typename = %s . . .\n", type_name);
#endif
/* look for this model type and put it in the table of models */
type = INPtypelook(type_name);
if(type < 0) {
err = tprintf("Unknown model type %s - ignored\n", type_name);
#ifdef TRACE
printf("In INPdomodel, ignoring unknown model typ typename = %s . . .\n", type_name);
#endif
}
else {
#ifdef TRACE
printf("In INPdomodel, adding unknown model typename = %s to model list. . .\n", type_name);
#endif
INPmakeMod(modname,type,image);
}
/* gtri - end - wbk - 10/23/90 */
#endif
}
tfree(type_name);
return (err);
}