From e4a33e2601dd24746a4fbfb1a7bb7fa2f23415b3 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 17 Feb 2026 15:47:07 +0100 Subject: [PATCH] Add parameter 'type' to .agemodel data to determine if NMOS or PMOS. Still the model name is scanned for _pmos or _nmos, but as this is IHP specific, type will be available as well. --- examples/degradation/aging_par_ng.scs | 8 ++--- src/frontend/inpdeg.c | 38 +++++++++++++++++--- src/xspice/icm/xtradev/degmonitor/cfunc.mod | 12 ++++--- src/xspice/icm/xtradev/degmonitor/ifspec.ifs | 11 ++++++ 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/examples/degradation/aging_par_ng.scs b/examples/degradation/aging_par_ng.scs index 91894e646..cfb3aba1e 100644 --- a/examples/degradation/aging_par_ng.scs +++ b/examples/degradation/aging_par_ng.scs @@ -1,6 +1,6 @@ ** Aging model parameters for IHP SG13 as provided in report dated Aug. 04, 2020 *HCI for sg13_lv_nmos -.agemodel devmodel=sg13_lv_nmos simmodel=HCI1 +.agemodel devmodel=sg13_lv_nmos simmodel=HCI1 type=1 +VGS0=0 +A_dlt_vth=1.04278251474614 Ea_dlt_vth=-0.106083869027519 B_dlt_vth=-22.6581135967351 C_dlt_vth=1.62904374968154 n_dlt_vth=0.455945007437156 L1_dlt_vth=-323.358569130193 L2_dlt_vth=3.72613938696378 +A_d_idlin=-0.00139040789976234 Ea_d_idlin=-0.0118584793500301 B_d_idlin=-14.749789118097 C_d_idlin=-1.10802575535176 n_d_idlin=0.367853872165032 L1_d_idlin=0.37197482405651 L2_d_idlin=4.01997218084279 @@ -8,7 +8,7 @@ *HCI for sg13_lv_pmos -.agemodel devmodel=sg13_lv_pmos simmodel=HCI1 +.agemodel devmodel=sg13_lv_pmos simmodel=HCI1 type=-1 +VGS0=0 +A_dlt_vth=0.00371919889013014 Ea_dlt_vth=0.0021868213151032 B_dlt_vth=-34.5701694063 C_dlt_vth=2.11300276582398 n_dlt_vth=0.517202717847316 L1_dlt_vth=0.124381468968081 L2_dlt_vth=5.29860115672568 +A_d_idlin=-23.2508460441183 Ea_d_idlin=0.050154358160735 B_d_idlin=-32.1899206187362 C_d_idlin=-2.6194728247694 n_d_idlin=0.459948322974844 L1_d_idlin=-3.20085456216052 L2_d_idlin=0.717423141530388 @@ -16,7 +16,7 @@ *HCI for sg13_hv_nmos -.agemodel devmodel=sg13_hv_nmos simmodel=HCI1 +.agemodel devmodel=sg13_hv_nmos simmodel=HCI1 type=1 +VGS0=0 +A_dlt_vth=0.129461187724162 Ea_dlt_vth=0.0768 B_dlt_vth=-80.5496572326613 C_dlt_vth=1.14512726882936 n_dlt_vth=0.942191388231725 L1_dlt_vth=0.27849616001817 L2_dlt_vth=7.01110937618489 +A_d_idlin=-0.0184166382885276 Ea_d_idlin=0.0608801118771257 B_d_idlin=-23.5218152275618 C_d_idlin=-1.46990061848068 n_d_idlin=0.338761307697283 L1_d_idlin=1.08047302826256 L2_d_idlin=2.63342269179693 @@ -24,7 +24,7 @@ *HCI for sg13_hv_nmos -.agemodel devmodel=sg13_hv_pmos simmodel=HCI1 +.agemodel devmodel=sg13_hv_pmos simmodel=HCI1 type=-1 +VGS0=0 +A_dlt_vth=5.4910035879995e-05 Ea_dlt_vth=-0.0785946157729455 B_dlt_vth=-31.5544195032415 C_dlt_vth=2.51004514070583 n_dlt_vth=0.90250786255508 L1_dlt_vth=1.2053957395248 L2_dlt_vth=6.96962623027008 +A_d_idlin=-0.00118398358812099 Ea_d_idlin=0.100805262655776 B_d_idlin=-52.9721879702169 C_d_idlin=-6.84704084895915 n_d_idlin=0.742086799634025 L1_d_idlin=2.30578560187629 L2_d_idlin=4.01890651865737 diff --git a/src/frontend/inpdeg.c b/src/frontend/inpdeg.c index 6c78b27d2..76e6675cb 100644 --- a/src/frontend/inpdeg.c +++ b/src/frontend/inpdeg.c @@ -32,6 +32,7 @@ NGHASHPTR degdatahash = NULL; struct agemod { char* devmodel; char* simmodel; + int type; int numparams; char *paramnames[DEGPARAMAX]; char *paramvalstr[DEGPARAMAX]; @@ -86,6 +87,16 @@ int readdegparams (struct card *deck) { } tfree(dftok); tfree(f1); + ftok = dftok = gettok(&cut_line); + f1 = gettok_char(&ftok, '=', TRUE, FALSE); + if (f1 && ciprefix("type=", f1)) + agemods[ageindex].type = atoi(ftok); + else { + fprintf(stderr, "Error: bad .agemodel syntax in line\n %s", card->line); + continue; + } + tfree(dftok); + tfree(f1); /* now read all other parameters */ while (cut_line && *cut_line) { @@ -427,6 +438,10 @@ static int add_degmodel(struct card* deck, double* result) { fprintf(stderr, "Warning: drain current degradation greater than 100%%\n"); } else if (currdeg > 0.) { + fprintf(stderr, "Warning: drain current increases\n"); + currd = TRUE; + } + else { /* parallel drain current */ currd = TRUE; } @@ -437,15 +452,28 @@ static int add_degmodel(struct card* deck, double* result) { /* modify the instance line */ char* instline = NULL; - if (vts && currd) + if (vts && currd) { instline = tprintf("%s delvto=%e factuo=%e\n", curr_line, result[0], 1.+ currdeg); - else if (vts && !currd) - instline = tprintf("%s delvto=%e\n", + if (ft_ngdebug) { + fprintf(stdout, "Instance now has extra delvto=%e factuo=%e\n", result[0], 1. + currdeg); + } + } + else if (vts && !currd) { + instline = tprintf("%s delvto=%e\n", curr_line, result[0]); - else if (!vts && currd) + if (ft_ngdebug) { + fprintf(stdout, "Instance now has extra delvto=%e\n", result[0]); + } + } + else if (!vts && currd) { instline = tprintf("%s factuo=%e\n", - curr_line, 1.+ currdeg); + curr_line, 1. + currdeg); + if (ft_ngdebug) { + fprintf(stdout, "Instance now has extra factuo=%e\n", 1. + currdeg); + } + } + if (instline) { tfree(deck->line); deck->line = instline; diff --git a/src/xspice/icm/xtradev/degmonitor/cfunc.mod b/src/xspice/icm/xtradev/degmonitor/cfunc.mod index 39614ac73..c620b9010 100644 --- a/src/xspice/icm/xtradev/degmonitor/cfunc.mod +++ b/src/xspice/icm/xtradev/degmonitor/cfunc.mod @@ -69,6 +69,7 @@ NON-STANDARD FEATURES struct agemod { char* devmodel; char* simmodel; + int type; int numparams; char *paramnames[DEGPARAMAX]; char *paramvalstr[DEGPARAMAX]; @@ -196,6 +197,11 @@ getdata(struct agemod *agemodptr, degLocal_Data_t *loc, char *devmod) cm_cexit(1); } + if (agemodptr[no].numparams < 1) { + cm_message_printf("Error: Could not retrieve model parameters from the %s degradation model data!\n", devmod); + cm_cexit(1); + } + /* Retrive model parameters from hash table. Sequence in pvals[i] is as set by names[i] above. */ for (ii = 0; ii < agemodptr[no].numparams; ii++) { double* fval; @@ -314,6 +320,7 @@ void cm_degmon(ARGS) /* structure holding parms, devmod = PARAM(devmod); tfut = PARAM(tfuture); + devtype = PARAM(type); L = PARAM(L); tsim = TSTOP; @@ -367,9 +374,7 @@ void cm_degmon(ARGS) /* structure holding parms, else if (strstr(devmod, "_pmos")) loc->devtype = -1; else { - loc->devtype = 0; - cm_message_send("Error: could not extract device type from model name\n"); - cm_cexit(1); + loc->devtype = devtype; } /* retrieve the parent instance name, e.g. a.xtop.xcolumnblock.xcolumn@0@.xperiph2.xclkwe.xwenand.adegmon63_xi1_pmos @@ -424,7 +429,6 @@ void cm_degmon(ARGS) /* structure holding parms, vb *= -1.; } - for (ii = 0; ii < 3; ii++) { double x1, x2; constfac = loc->constfac[ii]; diff --git a/src/xspice/icm/xtradev/degmonitor/ifspec.ifs b/src/xspice/icm/xtradev/degmonitor/ifspec.ifs index fab3030bb..c63aabe00 100644 --- a/src/xspice/icm/xtradev/degmonitor/ifspec.ifs +++ b/src/xspice/icm/xtradev/degmonitor/ifspec.ifs @@ -63,6 +63,17 @@ Vector_Bounds: - - Null_Allowed: yes no +PARAMETER_TABLE: + +Parameter_Name: type +Description: "model type PMOS, NMOS" +Data_Type: int +Default_Value: 1 +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes + STATIC_VAR_TABLE: Static_Var_Name: locdata