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.
This commit is contained in:
Tim Edwards 2023-05-21 12:13:01 -04:00
parent c514f5ce0b
commit 666c3c2c97
3 changed files with 73 additions and 25 deletions

View File

@ -1 +1 @@
8.3.399
8.3.400

View File

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

View File

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