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.
This commit is contained in:
Holger Vogt 2026-02-17 15:47:07 +01:00
parent 19a444c72c
commit e4a33e2601
4 changed files with 56 additions and 13 deletions

View File

@ -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

View File

@ -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;

View File

@ -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];

View File

@ -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