Added '.model NAME relmodel level=1 PARAMETERS'
Added '.appendmodel NAME TO_DEVICE_MODEL'
This commit is contained in:
parent
07877577e7
commit
cd9cab644b
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) ;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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) ;
|
||||||
|
|
@ -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 */
|
||||||
|
|
@ -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 *) ;
|
||||||
|
|
@ -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 ;
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
/**********
|
||||||
|
Author: Francesco Lannutti - August 2014
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#ifndef DEV_RELMODEL
|
||||||
|
#define DEV_RELMODEL
|
||||||
|
|
||||||
|
SPICEdev *get_relmodel_info (void) ;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -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) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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) ;
|
||||||
|
}
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue