Added '.model NAME relmodel level=1 PARAMETERS'

Added '.appendmodel NAME TO_DEVICE_MODEL'
This commit is contained in:
Francesco Lannutti 2014-09-03 23:21:58 +02:00
parent 07877577e7
commit cd9cab644b
20 changed files with 604 additions and 40 deletions

View File

@ -1133,6 +1133,7 @@ AC_CONFIG_FILES([Makefile
src/spicelib/devices/numd/Makefile src/spicelib/devices/numd/Makefile
src/spicelib/devices/numd2/Makefile src/spicelib/devices/numd2/Makefile
src/spicelib/devices/numos/Makefile src/spicelib/devices/numos/Makefile
src/spicelib/devices/relmodel/Makefile
src/spicelib/parser/Makefile src/spicelib/parser/Makefile
src/ciderlib/Makefile src/ciderlib/Makefile
src/ciderlib/input/Makefile src/ciderlib/input/Makefile

View File

@ -137,6 +137,11 @@ ngspice_LDADD += \
spicelib/devices/numos/libnumos.la spicelib/devices/numos/libnumos.la
endif endif
if RELAN_WANTED
ngspice_LDADD += \
spicelib/devices/relmodel/librelmodel.la
endif
ngspice_LDADD += \ ngspice_LDADD += \
spicelib/analysis/libckt.la \ spicelib/analysis/libckt.la \
spicelib/devices/libdev.la spicelib/devices/libdev.la
@ -384,6 +389,11 @@ libspice_la_LIBADD += \
spicelib/devices/numos/libnumos.la spicelib/devices/numos/libnumos.la
endif endif
if RELAN_WANTED
libspice_la_LIBADD += \
spicelib/devices/relmodel/librelmodel.la
endif
libspice_la_LIBADD += \ libspice_la_LIBADD += \
spicelib/analysis/libckt.la \ spicelib/analysis/libckt.la \
spicelib/devices/libdev.la spicelib/devices/libdev.la
@ -503,6 +513,11 @@ libngspice_la_LIBADD += \
spicelib/devices/numos/libnumos.la spicelib/devices/numos/libnumos.la
endif endif
if RELAN_WANTED
libngspice_la_LIBADD += \
spicelib/devices/relmodel/librelmodel.la
endif
libngspice_la_LIBADD += \ libngspice_la_LIBADD += \
spicelib/analysis/libckt.la \ spicelib/analysis/libckt.la \
spicelib/devices/libdev.la spicelib/devices/libdev.la

View File

@ -1846,6 +1846,11 @@ comment_out_unused_subckt_models(struct line *start_card, int no_of_lines)
and, if 5, will not be detected by get_subckt_model_name()*/ and, if 5, will not be detected by get_subckt_model_name()*/
if (cieq(model_type, "c") || if (cieq(model_type, "c") ||
cieq(model_type, "l") || cieq(model_type, "l") ||
#ifdef RELAN
cieq(model_type, "relmodel") ||
#endif
cieq(model_type, "r")) cieq(model_type, "r"))
{ {
found_model = TRUE; found_model = TRUE;

View File

@ -45,6 +45,11 @@ struct GENmodel { /* model structure for a resistor */
GENinstance *GENinstances; /* pointer to list of instances that have this GENinstance *GENinstances; /* pointer to list of instances that have this
* model */ * model */
IFuid GENmodName; /* pointer to character string naming this model */ IFuid GENmodName; /* pointer to character string naming this model */
#ifdef RELAN
GENmodel *GENrelmodelModel ; /* Relmodel Companion Model */
#endif
}; };
#endif #endif

View File

@ -59,6 +59,10 @@ if NUMDEV_WANTED
SUBDIRS += nbjt nbjt2 numd numd2 numos SUBDIRS += nbjt nbjt2 numd numd2 numos
endif endif
if RELAN_WANTED
SUBDIRS += relmodel
endif
DIST_SUBDIRS = \ DIST_SUBDIRS = \
@VLADEVDIR@ \ @VLADEVDIR@ \
asrc \ asrc \
@ -114,7 +118,8 @@ DIST_SUBDIRS = \
nbjt2 \ nbjt2 \
numd \ numd \
numd2 \ numd2 \
numos numos \
relmodel
noinst_LTLIBRARIES = libdev.la noinst_LTLIBRARIES = libdev.la

View File

@ -5,6 +5,7 @@ Author: Francesco Lannutti - August 2014
#include "ngspice/ngspice.h" #include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h" #include "ngspice/cktdefs.h"
#include "bsim4def.h" #include "bsim4def.h"
#include "../relmodel/relmodeldefs.h"
#include "ngspice/sperror.h" #include "ngspice/sperror.h"
int int
@ -19,7 +20,10 @@ BSIM4agingAdd (GENmodel *inModel, int step)
/* loop through all the instances of the model */ /* loop through all the instances of the model */
for (here = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance) for (here = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance)
{ {
here->BSIM4delvto = here->BSIM4agingDelvto [step] ; if (model->BSIM4type == PMOS)
{
here->BSIM4delvto = here->BSIM4agingDelvto [step] ;
}
} }
} }
@ -31,21 +35,22 @@ BSIM4agingSetup (GENmodel *inModel, CKTcircuit *ckt)
{ {
BSIM4model *model = (BSIM4model*)inModel ; BSIM4model *model = (BSIM4model*)inModel ;
BSIM4instance *here ; BSIM4instance *here ;
RELMODELmodel *relmodelModel ;
unsigned int i ; unsigned int i ;
double vges ;
const double K1_2 = 81e53 ; // [C^(-1/2) * m^(-5/2)] //------------------fittato 8----->9 ->squared // const double K1_2 = 81e53 ; // [C^(-1/2) * m^(-5/2)] //------------------fittato 8----->9 ->squared
const double T0 = 0.05e10 ; // [s/m^2] //------------fittato 1---->0.05 // const double T0 = 1e10 ; // [s/m^2] //------------fittato 1---->0.05
const double E_01 = 0.335e9 ; // [V/m] // // const double E_01 = 0.335e9 ; // [V/m] //
const double Ea = (0.04 * 0.1602136e-18) ; // [J] // Activation energy ---------------- Fittato 0.49-------------------->0.04 // const double Ea = (0.13 * 0.1602136e-18) ; // [J] // Activation energy ---------------- Fittato 0.49-------------------->0.04
const double X1 = 0.9 ; // [dimensionless] // Process parameter // const double X1 = 1 ; // [dimensionless] // Process parameter
const double X2 = 0.5 ; // [dimensionless] // Process parameter // const double X2 = 0.5 ; // [dimensionless] // Process parameter
double T_clk = 10e-9 ; // [s] // Clock period (from netlist) // double T_clk = 1e-9 ; // [s] // Clock period (from netlist)
double alfa = 0.5 ; // [dimensionless] // Duty cycle (from paper) // double alfa = 0.5 ; // [dimensionless] // Duty cycle (from paper)
double f = 0.333333333333333333333333333333333333333 ; double f = 0.333333333333333333333333333333333333333 ;
double vges ;
double Kv ; double Kv ;
double C ; // Temperature dependant constant double C ; // Temperature dependant constant
double beta ; // Recovery factor double beta ; // Recovery factor
@ -53,40 +58,47 @@ BSIM4agingSetup (GENmodel *inModel, CKTcircuit *ckt)
double r ; double r ;
C = 1 / T0 * exp (-Ea / (CONSTboltz * ckt->CKTtemp)) ;
ckt->CKTagingN = (int)((ckt->CKTagingTotalTime - ckt->CKTagingStartTime) / ckt->CKTagingStep) ; ckt->CKTagingN = (int)((ckt->CKTagingTotalTime - ckt->CKTagingStartTime) / ckt->CKTagingStep) ;
/* loop through all the BSIM4 device models */ /* loop through all the BSIM4 device models */
for (; model != NULL ; model = model->BSIM4nextModel) for (; model != NULL ; model = model->BSIM4nextModel)
{ {
/* loop through all the instances of the model */ if (model->BSIM4type == PMOS)
for (here = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance)
{ {
here->BSIM4agingDelvto = TMALLOC (double, (size_t)ckt->CKTagingN) ; relmodelModel = (RELMODELmodel *)(model->BSIM4relmodelModel) ;
//vgs = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodePrime] - ckt->CKTrhsOld [here->BSIM4sNodePrime]) ; C = 1 / relmodelModel->RELMODELt0 * exp (-relmodelModel->RELMODELea * 0.1602136e-18 / (CONSTboltz * ckt->CKTtemp)) ;
vges = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodeExt] - ckt->CKTrhsOld [here->BSIM4sNodePrime]) ;
// printf ("\n\nName: %s\nVth: %-.9g\nVges: %-.9g\nToxe: %-.9g\n", here->BSIM4name, model->BSIM4type * here->BSIM4von, model->BSIM4type * vges, model->BSIM4toxe) ;
Kv = (CHARGE * CHARGE * CHARGE * model->BSIM4toxe * model->BSIM4toxe) / (CONSTepsSiO2 * CONSTepsSiO2) * K1_2 * (model->BSIM4type * vges - model->BSIM4type * here->BSIM4von) * sqrt (C) * exp (2 * (model->BSIM4type * vges - model->BSIM4type * here->BSIM4von) / (model->BSIM4toxe * E_01)) ; /* loop through all the instances of the model */
for (here = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance)
/* loop through all the aging steps */
i = 0 ;
for (r = ckt->CKTagingStartTime + ckt->CKTagingStep ; r <= ckt->CKTagingTotalTime ; r += ckt->CKTagingStep)
{ {
beta = 1 - (2 * X1 * model->BSIM4toxe + sqrt (X2 * C * (1 - alfa) * T_clk)) / (2 * model->BSIM4toxe + sqrt (C * r)) ; here->BSIM4agingDelvto = TMALLOC (double, (size_t)ckt->CKTagingN) ;
delta_Vth = pow ((sqrt ((pow (Kv, 2)) * alfa * T_clk) / (1 - pow (beta, 3))), f) ;
here->BSIM4agingDelvto [i] = delta_Vth ; // vgs = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodePrime] - ckt->CKTrhsOld [here->BSIM4sNodePrime]) ;
// double Vth ; // vges = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodeExt] - ckt->CKTrhsOld [here->BSIM4sNodePrime]) ;
// Vth = model->BSIM4type * here->BSIM4von - here->BSIM4agingDelvto [i] ; vges = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodeExt] - ckt->CKTrhsOld [here->BSIM4sNode]) ;
// printf ("Delta Vth equals to %-.9g for %.1f second(s)\t\t", here->BSIM4agingDelvto [i], r) ; printf ("\n\nName: %s\nVth: %-.9g\nVges: %-.9g\nToxe: %-.9g\n", here->BSIM4name, here->BSIM4von, model->BSIM4type * vges, model->BSIM4toxe) ;
// printf ("Vth equals to %-.9g for %.1f second(s)\n", Vth, r) ;
i++ ; Kv = (CHARGE * CHARGE * CHARGE * model->BSIM4toxe * model->BSIM4toxe) / (CONSTepsSiO2 * CONSTepsSiO2) * relmodelModel->RELMODELk1_2 * (model->BSIM4type * vges - model->BSIM4type * here->BSIM4von) * sqrt (C) * exp (2 * (model->BSIM4type * vges - model->BSIM4type * here->BSIM4von) / (model->BSIM4toxe * relmodelModel->RELMODELe_01)) ;
/* loop through all the aging steps */
i = 0 ;
for (r = ckt->CKTagingStartTime + ckt->CKTagingStep ; r <= ckt->CKTagingTotalTime ; r += ckt->CKTagingStep)
{
beta = 1 - (2 * relmodelModel->RELMODELx1 * model->BSIM4toxe + sqrt (relmodelModel->RELMODELx2 * C * (1 - relmodelModel->RELMODELalfa) * relmodelModel->RELMODELt_clk)) / (2 * model->BSIM4toxe + sqrt (C * r)) ;
delta_Vth = pow ((sqrt (Kv * Kv * relmodelModel->RELMODELalfa * relmodelModel->RELMODELt_clk) / (1 - beta * beta * beta)), f) ;
here->BSIM4agingDelvto [i] = delta_Vth ;
double Vth ;
Vth = here->BSIM4von + here->BSIM4agingDelvto [i] ;
// printf ("Delta Vth equals to %-.9g for %.1f second(s)\t\t", here->BSIM4agingDelvto [i], r) ;
printf ("Vth = %-.9lf\t%.1f seconds\n", Vth, r) ;
printf ("delvto = %-.9lf\t%.1f seconds\n", here->BSIM4agingDelvto [i], r) ;
i++ ;
}
printf ("\n\n") ;
} }
} }
} }
printf ("\n\n") ;
return (OK) ; return (OK) ;
} }

View File

@ -826,6 +826,10 @@ typedef struct sBSIM4model
BSIM4instance *BSIM4instances; BSIM4instance *BSIM4instances;
IFuid BSIM4modName; IFuid BSIM4modName;
#ifdef RELAN
struct sBSIM4model *BSIM4relmodelModel ;
#endif
/* --- end of generic struct GENmodel --- */ /* --- end of generic struct GENmodel --- */
int BSIM4type; int BSIM4type;

View File

@ -137,6 +137,10 @@ int add_udn(int,Evt_Udn_Info_t **);
#include "ndev/ndevitf.h" #include "ndev/ndevitf.h"
#endif #endif
#ifdef RELAN
#include "relmodel/relmodelitf.h"
#endif
static SPICEdev *(*static_devices[])(void) = { static SPICEdev *(*static_devices[])(void) = {
/* URC device MUST precede both resistors and capacitors */ /* URC device MUST precede both resistors and capacitors */
get_urc_info, get_urc_info,
@ -209,6 +213,10 @@ static SPICEdev *(*static_devices[])(void) = {
get_ndev_info, get_ndev_info,
#endif #endif
#ifdef RELAN
get_relmodel_info
#endif
}; };
static int DEVNUM = NUMELEMS(static_devices); static int DEVNUM = NUMELEMS(static_devices);

View File

@ -0,0 +1,21 @@
## Process this file with automake to produce Makefile.in
noinst_LTLIBRARIES = librelmodel.la
if RELAN_WANTED
librelmodel_la_SOURCES = \
relmodel.c \
relmodelmask.c \
relmodelmpar.c \
relmodeldefs.h \
relmodelext.h \
relmodelinit.c \
relmodelinit.h \
relmodelitf.h
endif
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
AM_CFLAGS = $(STATIC)
MAINTAINERCLEANFILES = Makefile.in

View File

@ -0,0 +1,32 @@
/**********
Author: Francesco Lannutti - August 2014
**********/
#include "ngspice/ngspice.h"
#include "ngspice/devdefs.h"
#include "relmodeldefs.h"
#include "ngspice/suffix.h"
IFparm RELMODELpTable [] = { /* parameters */
} ;
IFparm RELMODELmPTable [] = { /* model parameters */
IOP ("t0", RELMODEL_MOD_T0, IF_REAL, "T0"),
IOP ("ea", RELMODEL_MOD_EA, IF_REAL, "Activation Energy [eV]"),
IOP ("k1_2", RELMODEL_MOD_K1_2, IF_REAL, "K1^2"),
IOP ("e_01", RELMODEL_MOD_E_01, IF_REAL, "E_01"),
IOP ("x1", RELMODEL_MOD_X1, IF_REAL, "X1"),
IOP ("x2", RELMODEL_MOD_X2, IF_REAL, "X2"),
IOP ("t_clk", RELMODEL_MOD_T_CLK, IF_REAL, "Period"),
IOP ("alfa", RELMODEL_MOD_ALFA, IF_REAL, "Switching Activity"),
IP ("relmodel", RELMODEL_MOD_RELMODEL, IF_FLAG, "Flag to indicate RELMODEL"),
} ;
char *RELMODELnames [] = {
} ;
int RELMODELnSize = NUMELEMS(RELMODELnames) ;
int RELMODELpTSize = NUMELEMS(RELMODELpTable) ;
int RELMODELmPTSize = NUMELEMS(RELMODELmPTable) ;
int RELMODELiSize = 0 ;
int RELMODELmSize = sizeof(RELMODELmodel) ;

View File

@ -0,0 +1,55 @@
/**********
Author: Francesco Lannutti - August 2014
**********/
#ifndef RELMODEL
#define RELMODEL
#include "ngspice/ifsim.h"
#include "ngspice/gendefs.h"
#include "ngspice/cktdefs.h"
#include "ngspice/complex.h"
#include "ngspice/noisedef.h"
typedef struct sRELMODELmodel
{
int RELMODELmodType ;
struct sRELMODELmodel *RELMODELnextModel ;
IFuid RELMODELmodName ;
double RELMODELt0 ;
double RELMODELea ;
double RELMODELk1_2 ;
double RELMODELe_01 ;
double RELMODELx1 ;
double RELMODELx2 ;
double RELMODELt_clk ;
double RELMODELalfa ;
int RELMODELrelmodel ;
unsigned RELMODELt0Given : 1 ;
unsigned RELMODELeaGiven : 1 ;
unsigned RELMODELk1_2Given : 1 ;
unsigned RELMODELe_01Given : 1 ;
unsigned RELMODELx1Given : 1 ;
unsigned RELMODELx2Given : 1 ;
unsigned RELMODELt_clkGiven : 1 ;
unsigned RELMODELalfaGiven : 1 ;
unsigned RELMODELrelmodelGiven : 1 ;
} RELMODELmodel ;
/* Global parameters */
#define RELMODEL_MOD_T0 1
#define RELMODEL_MOD_EA 2
#define RELMODEL_MOD_K1_2 3
#define RELMODEL_MOD_E_01 4
#define RELMODEL_MOD_X1 5
#define RELMODEL_MOD_X2 6
#define RELMODEL_MOD_T_CLK 7
#define RELMODEL_MOD_ALFA 8
#define RELMODEL_MOD_RELMODEL 9
#include "relmodelext.h"
#endif /* RELMODEL */

View File

@ -0,0 +1,7 @@
/**********
Author: Francesco Lannutti - August 2014
**********/
extern int RELMODELmAsk (CKTcircuit *, GENmodel *, int, IFvalue *) ;
extern int RELMODELmDelete (GENmodel **, IFuid, GENmodel *) ;
extern int RELMODELmParam (int, IFvalue *, GENmodel *) ;

View File

@ -0,0 +1,71 @@
/**********
Author: Francesco Lannutti - August 2014
**********/
#include "ngspice/config.h"
#include "ngspice/devdefs.h"
#include "relmodelitf.h"
#include "relmodelext.h"
#include "relmodelinit.h"
SPICEdev RELMODELinfo = {
{
"RELMODEL",
"MOSFET Reliability Analysis Addiction Model",
&RELMODELnSize,
&RELMODELnSize,
RELMODELnames,
&RELMODELpTSize,
RELMODELpTable,
&RELMODELmPTSize,
RELMODELmPTable,
DEV_DEFAULT
},
NULL, /* DEVparam */
RELMODELmParam, /* DEVmodParam */
NULL, /* DEVload */
NULL, /* DEVsetup */
NULL, /* DEVunsetup */
NULL, /* DEVpzSetup */
NULL, /* DEVtemperature */
NULL, /* DEVtrunc */
NULL, /* DEVfindBranch */
NULL, /* DEVacLoad */
NULL, /* DEVaccept */
NULL, /* DEVdestroy */
NULL, /* DEVmodDelete */
NULL, /* DEVdelete */
NULL, /* DEVsetic */
NULL, /* DEVask */
RELMODELmAsk, /* DEVmodAsk */
NULL, /* DEVpzLoad */
NULL, /* DEVconvTest */
NULL, /* DEVsenSetup */
NULL, /* DEVsenLoad */
NULL, /* DEVsenUpdate */
NULL, /* DEVsenAcLoad */
NULL, /* DEVsenPrint */
NULL, /* DEVsenTrunc */
NULL, /* DEVdisto */
NULL, /* DEVnoise */
NULL, /* DEVsoaCheck */
&RELMODELiSize, /* DEVinstSize */
&RELMODELmSize, /* DEVmodSize */
NULL, /* DEVagingAdd */
NULL /* DEVagingSetup */
} ;
SPICEdev *
get_relmodel_info (void)
{
return &RELMODELinfo ;
}

View File

@ -0,0 +1,17 @@
/**********
Author: Francesco Lannutti - August 2014
**********/
#ifndef _RELMODELINIT_H
#define _RELMODELINIT_H
extern IFparm RELMODELpTable [] ;
extern IFparm RELMODELmPTable [] ;
extern char *RELMODELnames [] ;
extern int RELMODELpTSize ;
extern int RELMODELmPTSize ;
extern int RELMODELnSize ;
extern int RELMODELiSize ;
extern int RELMODELmSize ;
#endif

View File

@ -0,0 +1,10 @@
/**********
Author: Francesco Lannutti - August 2014
**********/
#ifndef DEV_RELMODEL
#define DEV_RELMODEL
SPICEdev *get_relmodel_info (void) ;
#endif

View File

@ -0,0 +1,61 @@
/**********
Author: Francesco Lannutti - August 2014
**********/
#include "ngspice/ngspice.h"
#include "ngspice/ifsim.h"
#include "ngspice/cktdefs.h"
#include "ngspice/devdefs.h"
#include "relmodeldefs.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
RELMODELmAsk (CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
{
RELMODELmodel *model = (RELMODELmodel *)inst ;
NG_IGNORE (ckt) ;
switch (which)
{
case RELMODEL_MOD_T0:
value->rValue = model->RELMODELt0 ;
return (OK) ;
case RELMODEL_MOD_EA:
value->rValue = model->RELMODELea ;
return (OK) ;
case RELMODEL_MOD_K1_2:
value->rValue = model->RELMODELk1_2 ;
return (OK) ;
case RELMODEL_MOD_E_01:
value->rValue = model->RELMODELe_01 ;
return (OK) ;
case RELMODEL_MOD_X1:
value->rValue = model->RELMODELx1 ;
return (OK) ;
case RELMODEL_MOD_X2:
value->rValue = model->RELMODELx2 ;
return (OK) ;
case RELMODEL_MOD_T_CLK:
value->rValue = model->RELMODELt_clk ;
return (OK) ;
case RELMODEL_MOD_ALFA:
value->rValue = model->RELMODELalfa ;
return (OK) ;
case RELMODEL_MOD_RELMODEL:
value->iValue = model->RELMODELrelmodel ;
return (OK) ;
default:
return (E_BADPARM) ;
}
}

View File

@ -0,0 +1,69 @@
/**********
Author: Francesco Lannutti - August 2014
**********/
#include "ngspice/ngspice.h"
#include "relmodeldefs.h"
#include "ngspice/ifsim.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#include "ngspice/const.h"
int
RELMODELmParam (int param, IFvalue *value, GENmodel *inMod)
{
RELMODELmodel *model = (RELMODELmodel*)inMod ;
switch (param)
{
case RELMODEL_MOD_T0:
model->RELMODELt0 = value->rValue ;
model->RELMODELt0Given = TRUE ;
break ;
case RELMODEL_MOD_EA:
model->RELMODELea = value->rValue ;
model->RELMODELeaGiven = TRUE ;
break ;
case RELMODEL_MOD_K1_2:
model->RELMODELk1_2 = value->rValue ;
model->RELMODELk1_2Given = TRUE ;
break ;
case RELMODEL_MOD_E_01:
model->RELMODELe_01 = value->rValue ;
model->RELMODELe_01Given = TRUE ;
break ;
case RELMODEL_MOD_X1:
model->RELMODELx1 = value->rValue ;
model->RELMODELx1Given = TRUE ;
break ;
case RELMODEL_MOD_X2:
model->RELMODELx2 = value->rValue ;
model->RELMODELx2Given = TRUE ;
break ;
case RELMODEL_MOD_T_CLK:
model->RELMODELt_clk = value->rValue ;
model->RELMODELt_clkGiven = TRUE ;
break ;
case RELMODEL_MOD_ALFA:
model->RELMODELalfa = value->rValue ;
model->RELMODELalfaGiven = TRUE ;
break ;
case RELMODEL_MOD_RELMODEL:
model->RELMODELrelmodel = 1 ;
model->RELMODELrelmodelGiven = TRUE ;
break ;
default:
return (E_BADPARM) ;
}
return (OK) ;
}

View File

@ -698,6 +698,14 @@ INP2dot(CKTcircuit *ckt, INPtables *tab, card *current, TSKtask *task, CKTnode *
/* don't have to do anything, since models were all done in /* don't have to do anything, since models were all done in
* pass 1 */ * pass 1 */
goto quit; goto quit;
#ifdef RELAN
} else if (strcmp (token, ".appendmodel") == 0) {
/* don't have to do anything, since this command is handled in
* pass 3 */
goto quit ;
#endif
} else if ((strcmp(token, ".width") == 0) || } else if ((strcmp(token, ".width") == 0) ||
strcmp(token, ".print") == 0 || strcmp(token, ".plot") == 0) { strcmp(token, ".print") == 0 || strcmp(token, ".plot") == 0) {
/* obsolete - ignore */ /* obsolete - ignore */

View File

@ -215,19 +215,40 @@ char *INPdomodel(CKTcircuit *ckt, card * image, INPtables * tab)
/* -------- Check if model is a MOSFET --------- */ /* -------- Check if model is a MOSFET --------- */
else if ((strcmp(type_name, "nmos") == 0) else if ((strcmp(type_name, "nmos") == 0)
|| (strcmp(type_name, "pmos") == 0) || (strcmp(type_name, "pmos") == 0)
#ifdef RELAN
|| (strcmp(type_name, "relmodel") == 0)
#endif
|| (strcmp(type_name, "nsoi") == 0) || (strcmp(type_name, "nsoi") == 0)
|| (strcmp(type_name, "psoi") == 0)) { || (strcmp(type_name, "psoi") == 0)) {
err = INPfindLev(line, &lev); err = INPfindLev(line, &lev);
switch (lev) { switch (lev) {
case 0: case 0:
case 1: case 1:
type = INPtypelook("Mos1");
if (type < 0) { #ifdef RELAN
err = if (!(strcmp(type_name, "relmodel")))
INPmkTemp {
("Device type MOS1 not available in this binary\n"); type = INPtypelook ("RELMODEL") ;
} if (type < 0)
break; {
err = INPmkTemp ("Model type 'relmodel' not available in this binary\n") ;
}
} else {
#endif
type = INPtypelook ("Mos1") ;
if (type < 0)
{
err = INPmkTemp ("Device type MOS1 not available in this binary\n") ;
}
#ifdef RELAN
}
#endif
break ;
case 2: case 2:
type = INPtypelook("Mos2"); type = INPtypelook("Mos2");
if (type < 0) { if (type < 0) {

View File

@ -14,6 +14,135 @@ Modified: AlansFixes
extern IFsimulator *ft_sim; extern IFsimulator *ft_sim;
#ifdef RELAN
static void
dot_appendmodel (CKTcircuit *ckt, INPtables *tab, card *current)
{
/* .appendmodel from_model to_model */
int type; /* the type the model says it is */
char *line ; /* the part of the current line left to parse */
char *relmodel_name ; /* the relmodel name */
char *appendmodel_name ; /* the appendmodel name */
char *save ; /* saj - used to save the posn of the start of
the parameters if the model is a mosfet */
int error ; /* error code temporary */
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);
#endif
line = current->line ;
INPgetTok (&line, &relmodel_name, 1) ; /* throw away .appendmodel */
tfree (relmodel_name) ;
INPgetTok (&line, &relmodel_name, 1) ; /* get relmodel name */
save = line ; /* saj - save the posn for later if the default mosfet model is used */
thismodel = NULL ;
err_msg = INPgetMod (ckt, relmodel_name, &thismodel, tab) ;
tfree (err_msg) ;
/* check if using model binning -- pass in line since need 'l' and 'w' */
if (thismodel == NULL)
{
INPgetModBin (ckt, relmodel_name, &thismodel, tab, line) ;
}
model = relmodel_name ; /* mosfet */
line = save ; /* reset the posn to what it sould be */
INPinsert (&model, tab) ;
thismodel = NULL ;
#ifdef TRACE
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 ;
} else {
tfree (err_msg) ;
}
} else {
tfree (err_msg) ;
}
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 ("BSIM4v5")
&& thismodel->INPmodType != INPtypelook ("BSIM4v6")
&& thismodel->INPmodType != INPtypelook ("BSIM4v7")
&& thismodel->INPmodType != INPtypelook ("BSIM3v0")
&& thismodel->INPmodType != INPtypelook ("BSIM3v1")
&& thismodel->INPmodType != INPtypelook ("SOI3")
&& thismodel->INPmodType != INPtypelook ("HiSIM2")
&& thismodel->INPmodType != INPtypelook ("HiSIMHV")
&& thismodel->INPmodType != INPtypelook ("RELMODEL")
)
{
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 ;
}
INPgetTok (&line, &appendmodel_name, 1) ; /* get appendmodel name */
thismodel = NULL ;
err_msg = INPgetMod (ckt, appendmodel_name, &thismodel, tab) ;
tfree (err_msg) ;
if (thismodel == NULL)
{
INPgetModBin (ckt, relmodel_name, &thismodel, tab, line) ;
}
thismodel->INPmodfast->GENrelmodelModel = mdfast ; /* Attach 'relmodel' model to 'appendmodel' model */
return ;
}
#endif
/* pass 3 - Read all nodeset and IC lines. All circuit nodes will have /* pass 3 - Read all nodeset and IC lines. All circuit nodes will have
* been created by now, (except for internal device nodes), so any * been created by now, (except for internal device nodes), so any
@ -131,6 +260,14 @@ INPpas3(CKTcircuit *ckt, card *data, INPtables *tab, TSKtask *task,
break; break;
} }
} }
#ifdef RELAN
else if (strcmp (token, ".appendmodel") == 0) {
dot_appendmodel (ckt, tab, current) ;
goto quit ;
}
#endif
} }
quit: quit:
FREE(token); FREE(token);