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/numd2/Makefile
|
||||
src/spicelib/devices/numos/Makefile
|
||||
src/spicelib/devices/relmodel/Makefile
|
||||
src/spicelib/parser/Makefile
|
||||
src/ciderlib/Makefile
|
||||
src/ciderlib/input/Makefile
|
||||
|
|
|
|||
|
|
@ -137,6 +137,11 @@ ngspice_LDADD += \
|
|||
spicelib/devices/numos/libnumos.la
|
||||
endif
|
||||
|
||||
if RELAN_WANTED
|
||||
ngspice_LDADD += \
|
||||
spicelib/devices/relmodel/librelmodel.la
|
||||
endif
|
||||
|
||||
ngspice_LDADD += \
|
||||
spicelib/analysis/libckt.la \
|
||||
spicelib/devices/libdev.la
|
||||
|
|
@ -384,6 +389,11 @@ libspice_la_LIBADD += \
|
|||
spicelib/devices/numos/libnumos.la
|
||||
endif
|
||||
|
||||
if RELAN_WANTED
|
||||
libspice_la_LIBADD += \
|
||||
spicelib/devices/relmodel/librelmodel.la
|
||||
endif
|
||||
|
||||
libspice_la_LIBADD += \
|
||||
spicelib/analysis/libckt.la \
|
||||
spicelib/devices/libdev.la
|
||||
|
|
@ -503,6 +513,11 @@ libngspice_la_LIBADD += \
|
|||
spicelib/devices/numos/libnumos.la
|
||||
endif
|
||||
|
||||
if RELAN_WANTED
|
||||
libngspice_la_LIBADD += \
|
||||
spicelib/devices/relmodel/librelmodel.la
|
||||
endif
|
||||
|
||||
libngspice_la_LIBADD += \
|
||||
spicelib/analysis/libckt.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()*/
|
||||
if (cieq(model_type, "c") ||
|
||||
cieq(model_type, "l") ||
|
||||
|
||||
#ifdef RELAN
|
||||
cieq(model_type, "relmodel") ||
|
||||
#endif
|
||||
|
||||
cieq(model_type, "r"))
|
||||
{
|
||||
found_model = TRUE;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ struct GENmodel { /* model structure for a resistor */
|
|||
GENinstance *GENinstances; /* pointer to list of instances that have this
|
||||
* model */
|
||||
IFuid GENmodName; /* pointer to character string naming this model */
|
||||
|
||||
#ifdef RELAN
|
||||
GENmodel *GENrelmodelModel ; /* Relmodel Companion Model */
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -59,6 +59,10 @@ if NUMDEV_WANTED
|
|||
SUBDIRS += nbjt nbjt2 numd numd2 numos
|
||||
endif
|
||||
|
||||
if RELAN_WANTED
|
||||
SUBDIRS += relmodel
|
||||
endif
|
||||
|
||||
DIST_SUBDIRS = \
|
||||
@VLADEVDIR@ \
|
||||
asrc \
|
||||
|
|
@ -114,7 +118,8 @@ DIST_SUBDIRS = \
|
|||
nbjt2 \
|
||||
numd \
|
||||
numd2 \
|
||||
numos
|
||||
numos \
|
||||
relmodel
|
||||
|
||||
|
||||
noinst_LTLIBRARIES = libdev.la
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ Author: Francesco Lannutti - August 2014
|
|||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
#include "bsim4def.h"
|
||||
#include "../relmodel/relmodeldefs.h"
|
||||
#include "ngspice/sperror.h"
|
||||
|
||||
int
|
||||
|
|
@ -19,7 +20,10 @@ BSIM4agingAdd (GENmodel *inModel, int step)
|
|||
/* loop through all the instances of the model */
|
||||
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 ;
|
||||
BSIM4instance *here ;
|
||||
RELMODELmodel *relmodelModel ;
|
||||
unsigned int i ;
|
||||
double vges ;
|
||||
|
||||
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 E_01 = 0.335e9 ; // [V/m] //
|
||||
const double Ea = (0.04 * 0.1602136e-18) ; // [J] // Activation energy ---------------- Fittato 0.49-------------------->0.04
|
||||
const double X1 = 0.9 ; // [dimensionless] // Process parameter
|
||||
const double X2 = 0.5 ; // [dimensionless] // Process parameter
|
||||
// const double K1_2 = 81e53 ; // [C^(-1/2) * m^(-5/2)] //------------------fittato 8----->9 ->squared
|
||||
// const double T0 = 1e10 ; // [s/m^2] //------------fittato 1---->0.05
|
||||
// const double E_01 = 0.335e9 ; // [V/m] //
|
||||
// const double Ea = (0.13 * 0.1602136e-18) ; // [J] // Activation energy ---------------- Fittato 0.49-------------------->0.04
|
||||
// const double X1 = 1 ; // [dimensionless] // Process parameter
|
||||
// const double X2 = 0.5 ; // [dimensionless] // Process parameter
|
||||
|
||||
double T_clk = 10e-9 ; // [s] // Clock period (from netlist)
|
||||
double alfa = 0.5 ; // [dimensionless] // Duty cycle (from paper)
|
||||
// double T_clk = 1e-9 ; // [s] // Clock period (from netlist)
|
||||
// double alfa = 0.5 ; // [dimensionless] // Duty cycle (from paper)
|
||||
|
||||
double f = 0.333333333333333333333333333333333333333 ;
|
||||
|
||||
double vges ;
|
||||
double Kv ;
|
||||
double C ; // Temperature dependant constant
|
||||
double beta ; // Recovery factor
|
||||
|
|
@ -53,40 +58,47 @@ BSIM4agingSetup (GENmodel *inModel, CKTcircuit *ckt)
|
|||
|
||||
double r ;
|
||||
|
||||
C = 1 / T0 * exp (-Ea / (CONSTboltz * ckt->CKTtemp)) ;
|
||||
|
||||
ckt->CKTagingN = (int)((ckt->CKTagingTotalTime - ckt->CKTagingStartTime) / ckt->CKTagingStep) ;
|
||||
|
||||
/* loop through all the BSIM4 device models */
|
||||
for (; model != NULL ; model = model->BSIM4nextModel)
|
||||
{
|
||||
/* loop through all the instances of the model */
|
||||
for (here = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance)
|
||||
if (model->BSIM4type == PMOS)
|
||||
{
|
||||
here->BSIM4agingDelvto = TMALLOC (double, (size_t)ckt->CKTagingN) ;
|
||||
relmodelModel = (RELMODELmodel *)(model->BSIM4relmodelModel) ;
|
||||
|
||||
//vgs = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodePrime] - ckt->CKTrhsOld [here->BSIM4sNodePrime]) ;
|
||||
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) ;
|
||||
C = 1 / relmodelModel->RELMODELt0 * exp (-relmodelModel->RELMODELea * 0.1602136e-18 / (CONSTboltz * ckt->CKTtemp)) ;
|
||||
|
||||
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 aging steps */
|
||||
i = 0 ;
|
||||
for (r = ckt->CKTagingStartTime + ckt->CKTagingStep ; r <= ckt->CKTagingTotalTime ; r += ckt->CKTagingStep)
|
||||
/* loop through all the instances of the model */
|
||||
for (here = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance)
|
||||
{
|
||||
beta = 1 - (2 * X1 * model->BSIM4toxe + sqrt (X2 * C * (1 - alfa) * T_clk)) / (2 * model->BSIM4toxe + sqrt (C * r)) ;
|
||||
delta_Vth = pow ((sqrt ((pow (Kv, 2)) * alfa * T_clk) / (1 - pow (beta, 3))), f) ;
|
||||
here->BSIM4agingDelvto [i] = delta_Vth ;
|
||||
// double Vth ;
|
||||
// Vth = model->BSIM4type * here->BSIM4von - here->BSIM4agingDelvto [i] ;
|
||||
// printf ("Delta Vth equals to %-.9g for %.1f second(s)\t\t", here->BSIM4agingDelvto [i], r) ;
|
||||
// printf ("Vth equals to %-.9g for %.1f second(s)\n", Vth, r) ;
|
||||
i++ ;
|
||||
here->BSIM4agingDelvto = TMALLOC (double, (size_t)ckt->CKTagingN) ;
|
||||
|
||||
// vgs = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodePrime] - ckt->CKTrhsOld [here->BSIM4sNodePrime]) ;
|
||||
// vges = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodeExt] - ckt->CKTrhsOld [here->BSIM4sNodePrime]) ;
|
||||
vges = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodeExt] - ckt->CKTrhsOld [here->BSIM4sNode]) ;
|
||||
printf ("\n\nName: %s\nVth: %-.9g\nVges: %-.9g\nToxe: %-.9g\n", here->BSIM4name, here->BSIM4von, model->BSIM4type * vges, model->BSIM4toxe) ;
|
||||
|
||||
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) ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -826,6 +826,10 @@ typedef struct sBSIM4model
|
|||
BSIM4instance *BSIM4instances;
|
||||
IFuid BSIM4modName;
|
||||
|
||||
#ifdef RELAN
|
||||
struct sBSIM4model *BSIM4relmodelModel ;
|
||||
#endif
|
||||
|
||||
/* --- end of generic struct GENmodel --- */
|
||||
|
||||
int BSIM4type;
|
||||
|
|
|
|||
|
|
@ -137,6 +137,10 @@ int add_udn(int,Evt_Udn_Info_t **);
|
|||
#include "ndev/ndevitf.h"
|
||||
#endif
|
||||
|
||||
#ifdef RELAN
|
||||
#include "relmodel/relmodelitf.h"
|
||||
#endif
|
||||
|
||||
static SPICEdev *(*static_devices[])(void) = {
|
||||
/* URC device MUST precede both resistors and capacitors */
|
||||
get_urc_info,
|
||||
|
|
@ -209,6 +213,10 @@ static SPICEdev *(*static_devices[])(void) = {
|
|||
get_ndev_info,
|
||||
#endif
|
||||
|
||||
#ifdef RELAN
|
||||
get_relmodel_info
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
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
|
||||
* pass 1 */
|
||||
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) ||
|
||||
strcmp(token, ".print") == 0 || strcmp(token, ".plot") == 0) {
|
||||
/* obsolete - ignore */
|
||||
|
|
|
|||
|
|
@ -215,19 +215,40 @@ char *INPdomodel(CKTcircuit *ckt, card * image, INPtables * tab)
|
|||
/* -------- Check if model is a MOSFET --------- */
|
||||
else if ((strcmp(type_name, "nmos") == 0)
|
||||
|| (strcmp(type_name, "pmos") == 0)
|
||||
|
||||
#ifdef RELAN
|
||||
|| (strcmp(type_name, "relmodel") == 0)
|
||||
#endif
|
||||
|
||||
|| (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;
|
||||
|
||||
#ifdef RELAN
|
||||
if (!(strcmp(type_name, "relmodel")))
|
||||
{
|
||||
type = INPtypelook ("RELMODEL") ;
|
||||
if (type < 0)
|
||||
{
|
||||
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:
|
||||
type = INPtypelook("Mos2");
|
||||
if (type < 0) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,135 @@ Modified: AlansFixes
|
|||
|
||||
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
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RELAN
|
||||
else if (strcmp (token, ".appendmodel") == 0) {
|
||||
dot_appendmodel (ckt, tab, current) ;
|
||||
goto quit ;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
quit:
|
||||
FREE(token);
|
||||
|
|
|
|||
Loading…
Reference in New Issue