diff --git a/configure.ac b/configure.ac index dfd680523..d7c5b3151 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index c64cc8b84..f18006039 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index fff371366..f5dae6960 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -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; diff --git a/src/include/ngspice/gendefs.h b/src/include/ngspice/gendefs.h index f3eab5dd2..678c22457 100644 --- a/src/include/ngspice/gendefs.h +++ b/src/include/ngspice/gendefs.h @@ -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 diff --git a/src/spicelib/devices/Makefile.am b/src/spicelib/devices/Makefile.am index 4a3caa7a0..2a4f78760 100644 --- a/src/spicelib/devices/Makefile.am +++ b/src/spicelib/devices/Makefile.am @@ -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 diff --git a/src/spicelib/devices/bsim4/b4reliability.c b/src/spicelib/devices/bsim4/b4reliability.c index 33f5eabc7..3b2fba8bf 100644 --- a/src/spicelib/devices/bsim4/b4reliability.c +++ b/src/spicelib/devices/bsim4/b4reliability.c @@ -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) ; } diff --git a/src/spicelib/devices/bsim4/bsim4def.h b/src/spicelib/devices/bsim4/bsim4def.h index b34710e1c..8fc12555e 100644 --- a/src/spicelib/devices/bsim4/bsim4def.h +++ b/src/spicelib/devices/bsim4/bsim4def.h @@ -826,6 +826,10 @@ typedef struct sBSIM4model BSIM4instance *BSIM4instances; IFuid BSIM4modName; +#ifdef RELAN + struct sBSIM4model *BSIM4relmodelModel ; +#endif + /* --- end of generic struct GENmodel --- */ int BSIM4type; diff --git a/src/spicelib/devices/dev.c b/src/spicelib/devices/dev.c index acdb09f2b..a4e30f69e 100644 --- a/src/spicelib/devices/dev.c +++ b/src/spicelib/devices/dev.c @@ -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); diff --git a/src/spicelib/devices/relmodel/Makefile.am b/src/spicelib/devices/relmodel/Makefile.am new file mode 100644 index 000000000..f6f0fe682 --- /dev/null +++ b/src/spicelib/devices/relmodel/Makefile.am @@ -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 diff --git a/src/spicelib/devices/relmodel/relmodel.c b/src/spicelib/devices/relmodel/relmodel.c new file mode 100644 index 000000000..e97b4386c --- /dev/null +++ b/src/spicelib/devices/relmodel/relmodel.c @@ -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) ; diff --git a/src/spicelib/devices/relmodel/relmodeldefs.h b/src/spicelib/devices/relmodel/relmodeldefs.h new file mode 100644 index 000000000..da64b599d --- /dev/null +++ b/src/spicelib/devices/relmodel/relmodeldefs.h @@ -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 */ diff --git a/src/spicelib/devices/relmodel/relmodelext.h b/src/spicelib/devices/relmodel/relmodelext.h new file mode 100644 index 000000000..f5a02499d --- /dev/null +++ b/src/spicelib/devices/relmodel/relmodelext.h @@ -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 *) ; diff --git a/src/spicelib/devices/relmodel/relmodelinit.c b/src/spicelib/devices/relmodel/relmodelinit.c new file mode 100644 index 000000000..79ecd113e --- /dev/null +++ b/src/spicelib/devices/relmodel/relmodelinit.c @@ -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 ; +} diff --git a/src/spicelib/devices/relmodel/relmodelinit.h b/src/spicelib/devices/relmodel/relmodelinit.h new file mode 100644 index 000000000..4535a5fe5 --- /dev/null +++ b/src/spicelib/devices/relmodel/relmodelinit.h @@ -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 diff --git a/src/spicelib/devices/relmodel/relmodelitf.h b/src/spicelib/devices/relmodel/relmodelitf.h new file mode 100644 index 000000000..10495917c --- /dev/null +++ b/src/spicelib/devices/relmodel/relmodelitf.h @@ -0,0 +1,10 @@ +/********** +Author: Francesco Lannutti - August 2014 +**********/ + +#ifndef DEV_RELMODEL +#define DEV_RELMODEL + +SPICEdev *get_relmodel_info (void) ; + +#endif diff --git a/src/spicelib/devices/relmodel/relmodelmask.c b/src/spicelib/devices/relmodel/relmodelmask.c new file mode 100644 index 000000000..077395c39 --- /dev/null +++ b/src/spicelib/devices/relmodel/relmodelmask.c @@ -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) ; + } +} diff --git a/src/spicelib/devices/relmodel/relmodelmpar.c b/src/spicelib/devices/relmodel/relmodelmpar.c new file mode 100644 index 000000000..3a5551f9f --- /dev/null +++ b/src/spicelib/devices/relmodel/relmodelmpar.c @@ -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) ; +} diff --git a/src/spicelib/parser/inp2dot.c b/src/spicelib/parser/inp2dot.c index 9363ebd31..90a11e7a5 100644 --- a/src/spicelib/parser/inp2dot.c +++ b/src/spicelib/parser/inp2dot.c @@ -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 */ diff --git a/src/spicelib/parser/inpdomod.c b/src/spicelib/parser/inpdomod.c index da3a49b42..df780d641 100644 --- a/src/spicelib/parser/inpdomod.c +++ b/src/spicelib/parser/inpdomod.c @@ -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) { diff --git a/src/spicelib/parser/inppas3.c b/src/spicelib/parser/inppas3.c index 7f57918c4..b8b9a184f 100644 --- a/src/spicelib/parser/inppas3.c +++ b/src/spicelib/parser/inppas3.c @@ -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);