diff --git a/src/frontend/inpdeg.c b/src/frontend/inpdeg.c index 871fa972b..d33ff436b 100644 --- a/src/frontend/inpdeg.c +++ b/src/frontend/inpdeg.c @@ -21,7 +21,7 @@ License: Modified BSD #define DEGMODMAX 64 /* global pointer: results from first tran run */ -NGHASHPTR degdatahash; +NGHASHPTR degdatahash = NULL; struct agemod { char* devmodel; @@ -192,8 +192,8 @@ int adddegmonitors(struct card* deck) { */ char* aline = tprintf("adegmon%d_%s %%v([%s]) mon%d degmon%d\n", degmonno, instname, fournodes, degmonno, degmonno); - char* mline = tprintf(".model degmon%d degmon (tfuture=%e %s devmod=\"%s\"\n", - degmonno, tfuture, clength, modname); + char* mline = tprintf(".model degmon%d degmon (tfuture=%e %s devmod=\"%s\" instname=\"%s\"\n", + degmonno, tfuture, clength, modname, instname); tfree(clength); insert_new_line(deck, aline, 0, deck->linenum_orig, deck->linesource); insert_new_line(deck, mline, 0, deck->linenum_orig, deck->linesource); @@ -212,7 +212,7 @@ int adddegmonitors(struct card* deck) { } } /* initialze the result data storage */ - degdatahash = nghash_init(degmonno); + degdatahash = nghash_init(64); return degmonno; } diff --git a/src/include/ngspice/mifcmdat.h b/src/include/ngspice/mifcmdat.h index 77427af83..1360cc7e1 100644 --- a/src/include/ngspice/mifcmdat.h +++ b/src/include/ngspice/mifcmdat.h @@ -47,6 +47,7 @@ NON-STANDARD FEATURES #include "ngspice/typedefs.h" #include "ngspice/miftypes.h" +#include "ngspice/hash.h" #ifdef KLU #include "ngspice/smpdefs.h" @@ -335,6 +336,7 @@ typedef struct Mif_Circ_Data_s { double t[8]; /* History of last 8 analysis times t[0]=time */ double tstep; /* tran simulation tstep */ double tstop; /* tran simulation tstop */ + NGHASHPTR deghash; /* result data degradation monitor */ } Mif_Circ_Data_t; diff --git a/src/xspice/icm/xtradev/degmonitor/cfunc.mod b/src/xspice/icm/xtradev/degmonitor/cfunc.mod index e5ad01806..dc0dbd11c 100644 --- a/src/xspice/icm/xtradev/degmonitor/cfunc.mod +++ b/src/xspice/icm/xtradev/degmonitor/cfunc.mod @@ -75,7 +75,7 @@ struct agemod { double paramvals[DEGPARAMAX]; bool paramread[DEGPARAMAX]; NGHASHPTR paramhash; -} *agemodptr; +}; /* This struct is model-specific: We need three data sets for dlt_vth [0], d_idlin [1], and d_idsat [2] */ @@ -83,7 +83,7 @@ typedef struct { double constfac[3]; /* intermediate factor */ double sintegral[3]; /* intermediate intgral */ double prevtime[3]; /* previous time */ - int devtype; /* device type 1: nms, -1: pmos */ + int devtype; /* device type 1: nmos, -1: pmos */ double VGS0; /* degradation model parameter */ double A[3]; /* degradation model parameter */ double Ea[3]; /* degradation model parameter */ @@ -92,6 +92,8 @@ typedef struct { double L2[3]; /* degradation model parameter */ double n[3]; /* degradation model parameter */ double c[3]; /* degradation model parameter */ + double result[3]; /* degradation simulation result */ + char *parentname; /* name of parent device for degmon */ } degLocal_Data_t; @@ -299,6 +301,10 @@ void cm_degmon(ARGS) /* structure holding parms, degLocal_Data_t *loc; /* Pointer to local static data, not to be included in the state vector */ + /* Pointer to global hash table, saving the + degradation sim results of the first tran sim. */ + NGHASHPTR glohash = mif_private->circuit.deghash; + if (ANALYSIS == MIF_AC) { return; } @@ -311,7 +317,7 @@ void cm_degmon(ARGS) /* structure holding parms, tsim = TSTOP; if (INIT==1) { - + char inam[1024]; double Temp = TEMPERATURE + 273.15; int err = -1, ii; struct agemod *agemods = cm_get_deg_params(); @@ -361,7 +367,26 @@ void cm_degmon(ARGS) /* structure holding parms, cm_message_send("Error: could not extract device type from model name\n"); cm_cexit(1); } + /* retrieve the parent instance name, e.g. + a.xtop.xcolumnblock.xcolumn@0@.xperiph2.xclkwe.xwenand.adegmon63_xi1_pmos + --> + n.xtop.xcolumnblock.xcolumn@0@.xperiph2.xclkwe.xwenand.xi1_pmos.nsg13_lv_pmos + */ + char *ipath = strdup(INSTMODNAME); + char *colon = strchr(ipath, ':'); + if (!colon) { + cm_message_printf("Error: no colon, incompatible model name %s\n", ipath); + cm_cexit(1); + } + *colon = '\0'; + char *xinstname = PARAM(instname); + snprintf(inam, 1024, "n.%s.%s.n%s", ipath, xinstname, devmod); + loc->parentname = strdup(inam); + tfree(ipath); + /* + cm_message_send(loc->parentname); + cm_message_send(devmod); cm_message_send(INSTNAME); cm_message_send(INSTMODNAME); */ @@ -424,15 +449,23 @@ void cm_degmon(ARGS) /* structure holding parms, OUTPUT(mon) = sintegral; if (T(0) > 0.99999 * tsim) { + /** debugging **/ + char *thisinstance = INSTNAME; +// cm_message_printf("%s\n", thisinstance); /**** model equations 2 ****/ sintegral = sintegral * tfut / tsim; deg = 1. / (c * (pow(sintegral, -1.* n))); /***************************/ - cm_message_printf("no. %d, Degradation deg = %e\n", ii, deg); +// cm_message_printf("no. %d, Degradation deg = %e\n", ii, deg); sintegral = 1e99; // flag final time step + loc->result[ii] = deg; } loc->sintegral[ii] = sintegral; loc->prevtime[ii] = prevtime; } + /* save the degradation data for this instance */ + if (T(0) > 0.99999 * tsim) { + nghash_insert(glohash, loc->parentname, loc->result); + } } } diff --git a/src/xspice/icm/xtradev/degmonitor/ifspec.ifs b/src/xspice/icm/xtradev/degmonitor/ifspec.ifs index 4b0953600..fab3030bb 100644 --- a/src/xspice/icm/xtradev/degmonitor/ifspec.ifs +++ b/src/xspice/icm/xtradev/degmonitor/ifspec.ifs @@ -53,14 +53,14 @@ Null_Allowed: yes yes PARAMETER_TABLE: -Parameter_Name: tfuture -Description: "future time" -Data_Type: real -Default_Value: 315336e4 -Limits: - -Vector: no -Vector_Bounds: - -Null_Allowed: yes +Parameter_Name: tfuture instname +Description: "future time" "parent instance" +Data_Type: real string +Default_Value: 315336e4 - +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes no STATIC_VAR_TABLE: diff --git a/src/xspice/mif/mifload.c b/src/xspice/mif/mifload.c index 1f1c579aa..68874dbb8 100644 --- a/src/xspice/mif/mifload.c +++ b/src/xspice/mif/mifload.c @@ -50,6 +50,7 @@ NON-STANDARD FEATURES #include "ngspice/cktdefs.h" #include "ngspice/devdefs.h" #include "ngspice/sperror.h" +#include "ngspice/hash.h" #include "ngspice/evt.h" @@ -73,8 +74,7 @@ static void MIFauto_partial( ); - - +extern NGHASHPTR degdatahash; /* @@ -214,6 +214,7 @@ MIFload( cm_data.circuit.call_type = MIF_ANALOG; cm_data.circuit.temperature = ckt->CKTtemp - 273.15; + cm_data.circuit.deghash = degdatahash; g_mif_info.circuit.call_type = MIF_ANALOG; g_mif_info.ckt = ckt;