From 666c3c2c97b340e7386658fdafbe6dd6678c1b9e Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 21 May 2023 12:13:01 -0400 Subject: [PATCH] Corrected an issue in which the device merging routine can generate NaN results for devices which are not FETs (specifically, devices that are declared using "msubckt" but are not FETs, although there may have been a related issue with non-FET devices not getting the correct M count), due to the device having zero measured width or length. NOTE: This may need more investigation. If a subcircuit device's method of merging cannot be understood, then such devices should never extract with "merge aggressive", and should always merge conservatively if and only if all parameters match. --- VERSION | 2 +- ext2spice/ext2hier.c | 64 ++++++++++++++++++++++++++++++++----------- ext2spice/ext2spice.c | 32 ++++++++++++++++------ 3 files changed, 73 insertions(+), 25 deletions(-) diff --git a/VERSION b/VERSION index abe35e8c..e1f1250a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.399 +8.3.400 diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index 518221d1..fd068e7e 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -1144,33 +1144,49 @@ spcdevHierMergeVisit(hc, dev, scale) { /* To-do: add back source, drain attribute check */ + /* Default case: Add the counts together */ + m = esFMult[cfp->esFMIndex] + esFMult[fp->esFMIndex]; + switch(dev->dev_class) { case DEV_MOSFET: case DEV_MSUBCKT: case DEV_ASYMMETRIC: case DEV_FET: - m = esFMult[cfp->esFMIndex] + (fp->w / cfp->w); + if (cfp->w > 0) + m = esFMult[cfp->esFMIndex] + (fp->w / cfp->w); break; case DEV_RSUBCKT: case DEV_RES: if ((fp->dev->dev_type == esNoModelType) || !strcmp(EFDevTypes[fp->dev->dev_type], "None")) - m = esFMult[cfp->esFMIndex] + (fp->dev->dev_res - / cfp->dev->dev_res); + { + if (cfp->dev->dev_res > 0) + m = esFMult[cfp->esFMIndex] + (fp->dev->dev_res + / cfp->dev->dev_res); + } else - m = esFMult[cfp->esFMIndex] + (fp->l / cfp->l); + { + if (cfp->l > 0) + m = esFMult[cfp->esFMIndex] + (fp->l / cfp->l); + } break; case DEV_CSUBCKT: case DEV_CAP: case DEV_CAPREV: if ((fp->dev->dev_type == esNoModelType) || !strcmp(EFDevTypes[fp->dev->dev_type], "None")) - m = esFMult[cfp->esFMIndex] + (fp->dev->dev_cap - / cfp->dev->dev_cap); + { + if (cfp->dev->dev_cap > 0) + m = esFMult[cfp->esFMIndex] + (fp->dev->dev_cap + / cfp->dev->dev_cap); + } else - m = esFMult[cfp->esFMIndex] + - ((fp->l * fp->w) / (cfp->l * cfp->w)); + { + if ((cfp->l > 0) && (cfp->w > 0)) + m = esFMult[cfp->esFMIndex] + + ((fp->l * fp->w) / (cfp->l * cfp->w)); + } break; } setDevMult(fp->esFMIndex, DEV_KILLED); @@ -1584,33 +1600,49 @@ devMergeHierVisit(hc, dev, scale) mergeAttr(&cd->dterm_attrs, &drain->dterm_attrs); } mergeThem: + /* Default case: Add the counts together */ + m = esFMult[cfp->esFMIndex] + esFMult[fp->esFMIndex]; + switch(dev->dev_class) { case DEV_MOSFET: case DEV_ASYMMETRIC: case DEV_MSUBCKT: case DEV_FET: - m = esFMult[cfp->esFMIndex] + ((float)fp->w / (float)cfp->w); + if (cfp->w > 0) + m = esFMult[cfp->esFMIndex] + ((float)fp->w / (float)cfp->w); break; case DEV_RSUBCKT: case DEV_RES: if ((fp->dev->dev_type == esNoModelType) || !strcmp(EFDevTypes[fp->dev->dev_type], "None")) - m = esFMult[cfp->esFMIndex] + (fp->dev->dev_res - / cfp->dev->dev_res); + { + if (cfp->dev->dev_res > 0) + m = esFMult[cfp->esFMIndex] + (fp->dev->dev_res + / cfp->dev->dev_res); + } else - m = esFMult[cfp->esFMIndex] + (fp->l / cfp->l); + { + if (cfp->l > 0) + m = esFMult[cfp->esFMIndex] + (fp->l / cfp->l); + } break; case DEV_CSUBCKT: case DEV_CAP: case DEV_CAPREV: if ((fp->dev->dev_type == esNoModelType) || !strcmp(EFDevTypes[fp->dev->dev_type], "None")) - m = esFMult[cfp->esFMIndex] + (fp->dev->dev_cap - / cfp->dev->dev_cap); + { + if (cfp->dev->dev_cap > 0) + m = esFMult[cfp->esFMIndex] + (fp->dev->dev_cap + / cfp->dev->dev_cap); + } else - m = esFMult[cfp->esFMIndex] + - ((fp->l * fp->w) / (cfp->l * cfp->w)); + { + if ((cfp->l > 0) && (cfp->w > 0)) + m = esFMult[cfp->esFMIndex] + + ((fp->l * fp->w) / (cfp->l * cfp->w)); + } break; } setDevMult(fp->esFMIndex, DEV_KILLED); diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index f3920961..3c4dfad6 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -4246,31 +4246,47 @@ devMergeVisit(dev, hc, scale, trans) else /* cfp->hierName != hierName */ break; mergeThem: + /* Default case is to add counts */ + m = esFMult[cfp->esFMIndex] + esFMult[fp->esFMIndex]; + switch(dev->dev_class) { case DEV_MSUBCKT: case DEV_MOSFET: case DEV_ASYMMETRIC: case DEV_FET: - m = esFMult[cfp->esFMIndex] + (fp->w / cfp->w); + if (cfp->w > 0) + m = esFMult[cfp->esFMIndex] + (fp->w / cfp->w); break; case DEV_RSUBCKT: case DEV_RES: if (fp->dev->dev_type == esNoModelType) - m = esFMult[cfp->esFMIndex] + (fp->dev->dev_res - / cfp->dev->dev_res); + { + if (cfp->dev->dev_res > 0) + m = esFMult[cfp->esFMIndex] + (fp->dev->dev_res + / cfp->dev->dev_res); + } else - m = esFMult[cfp->esFMIndex] + (fp->l / cfp->l); + { + if (cfp->l > 0) + m = esFMult[cfp->esFMIndex] + (fp->l / cfp->l); + } break; case DEV_CSUBCKT: case DEV_CAP: case DEV_CAPREV: if (fp->dev->dev_type == esNoModelType) - m = esFMult[cfp->esFMIndex] + (fp->dev->dev_cap - / cfp->dev->dev_cap); + { + if (cfp->dev->dev_cap > 0) + m = esFMult[cfp->esFMIndex] + (fp->dev->dev_cap + / cfp->dev->dev_cap); + } else - m = esFMult[cfp->esFMIndex] + - ((fp->l * fp->w) / (cfp->l * cfp->w)); + { + if ((cfp->l > 0) && (cfp->w > 0)) + m = esFMult[cfp->esFMIndex] + + ((fp->l * fp->w) / (cfp->l * cfp->w)); + } break; } setDevMult(fp->esFMIndex, DEV_KILLED);