Corrected some issues related to the handling of substrate hierarchy.

Most of this had to do with the incorrect use of the parent's substrate
name in extHierSubstrate().  After the correction, there still remains
an issue that is caused when a labeled isolated substrate region overlaps
an extraction tile boundary.  I believe that this particular error has
existed for some time and is not new, so I am committing these changes.
This commit is contained in:
Tim Edwards 2022-02-24 16:47:11 -05:00
parent 3d41b3e98b
commit db4fa65bfc
5 changed files with 82 additions and 59 deletions

View File

@ -1 +1 @@
8.3.271
8.3.272

View File

@ -397,6 +397,7 @@ DBCellGenerateSubstrate(scx, subType, notSubMask, subShieldMask, targetDef)
int plane;
Rect rect;
TileTypeBitMask allButSubMask;
TileTypeBitMask defaultSubTypeMask;
int dbEraseSubFunc();
int dbPaintSubFunc();
int dbEraseNonSub();
@ -417,9 +418,15 @@ DBCellGenerateSubstrate(scx, subType, notSubMask, subShieldMask, targetDef)
csd.csd_pNum = plane;
csd.csd_modified = FALSE;
/* First paint the substrate type in the temporary plane over the */
/* area of all substrate shield types. */
/* The substrate type will be redefined to denote only areas of */
/* isolated substrate. The first step is to erase the default */
/* substrate everywhere so that it can be regenerated automatically */
/* Note: xMask is always zero, as this is only called from extract routines */
TTMaskSetOnlyType(&defaultSubTypeMask, subType);
DBTreeSrTiles(scx, &defaultSubTypeMask, 0, dbEraseSubFunc, (ClientData)&csd);
/* Next, paint the substrate type in the temporary plane over the */
/* area of all substrate shield types. */
DBTreeSrTiles(scx, subShieldMask, 0, dbPaintSubFunc, (ClientData)&csd);
if (csd.csd_modified == FALSE) return NULL;

View File

@ -200,6 +200,10 @@ drcSubCopyFunc(scx, cdarg)
return DBNoTreeSrTiles(scx, &drcMask, 0, drcSubCopyErrors, cdarg);
}
/* Flags used by the client data for drcSubcellFunc() */
#define PROPAGATE_FLAG 1
#define CELLFOUND_FLAG 2
/*
* ----------------------------------------------------------------------------
*
@ -220,13 +224,16 @@ drcSubCopyFunc(scx, cdarg)
*/
int
drcSubcellFunc(subUse, propagate)
drcSubcellFunc(subUse, flags)
CellUse *subUse; /* Subcell instance. */
bool *propagate; /* Errors to propagate up */
int *flags; /* Information to propagate up */
{
Rect area, haloArea, intArea, subIntArea, locIntArea;
int i;
/* A subcell has been seen, so set the "cell found" flag */
*flags |= CELLFOUND_FLAG;
/* To determine interactions, find the bounding box of
* all paint and other subcells within one halo of this
* subcell (and also within the original area where
@ -269,7 +276,7 @@ drcSubcellFunc(subUse, propagate)
GeoInclude(&locIntArea, &intArea);
#endif
if (!GEO_RECTNULL(&subIntArea)) *propagate = TRUE;
if (!GEO_RECTNULL(&subIntArea)) *flags |= PROPAGATE_FLAG;
drcCurSub = subUse;
(void) DBSrCellPlaneArea(drcSubDef->cd_cellPlane, &haloArea,
@ -402,7 +409,7 @@ DRCFindInteractions(def, area, radius, interaction)
int i;
CellUse *use;
SearchContext scx;
bool propagate;
int flags;
drcSubDef = def;
drcSubRadius = radius;
@ -417,9 +424,9 @@ DRCFindInteractions(def, area, radius, interaction)
drcSubIntArea = GeoNullRect;
GEO_EXPAND(area, radius, &drcSubLookArea);
propagate = FALSE;
flags = 0;
(void) DBSrCellPlaneArea(def->cd_cellPlane, &drcSubLookArea,
drcSubcellFunc, (ClientData)(&propagate));
drcSubcellFunc, (ClientData)(&flags));
/* If there seems to be an interaction area, make a second pass
* to make sure there's more than one cell with paint in the
@ -427,13 +434,14 @@ DRCFindInteractions(def, area, radius, interaction)
* have overlapping bounding boxes without overlapping paint.
*/
if (GEO_RECTNULL(&drcSubIntArea)) return -1;
if (!(flags & CELLFOUND_FLAG)) return -1;
if (GEO_RECTNULL(&drcSubIntArea)) return 0;
use = NULL;
/* If errors are being propagated up from child to parent, */
/* then the interaction area is always valid. */
if (propagate == FALSE)
if (!(flags & PROPAGATE_FLAG))
{
for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++)
{

View File

@ -3723,6 +3723,14 @@ extFindNodes(def, clipArea, subonly)
TTMaskSetMask(&subsTypesNonSpace, &ExtCurStyle->exts_globSubstrateTypes);
TTMaskClearType(&subsTypesNonSpace, TT_SPACE);
/* If the default substrate type is set, it is used *only* for */
/* isolated substrate regions and does not mark the default */
/* substrate, so remove it from the list of substrate types. */
if (ExtCurStyle->exts_globSubstrateDefaultType != -1)
TTMaskClearType(&subsTypesNonSpace,
ExtCurStyle->exts_globSubstrateDefaultType);
pNum = ExtCurStyle->exts_globSubstratePlane;
/* Does the type set of this plane intersect the substrate types? */
if (TTMaskIntersect(&DBPlaneTypes[pNum], &subsTypesNonSpace))

View File

@ -255,66 +255,66 @@ ExtLabelRegions(def, connTo, nodeList, clipArea)
}
if ((found == FALSE) && (nodeList != NULL))
{
/* Unconnected node label. This may be a "sticky label".
* If it is not connected to TT_SPACE, then create a new
* node region for it.
* (3/24/2015---changed from GEO_LABEL_IN_AREA to GEO_SURROUND)
*/
if ((GEO_SURROUND(&lab->lab_rect, clipArea) ||
GEO_TOUCH(&lab->lab_rect, clipArea))
&& (lab->lab_type != TT_SPACE))
{
/* If the label is the substrate type and is over */
/* space, then assign the label to the default */
/* substrate region. */
/* Handle unconnected node label. */
if ((pNum == ExtCurStyle->exts_globSubstratePlane) &&
/* If the label is the substrate type and is over */
/* space, then assign the label to the default */
/* substrate region. The label need not be in the */
/* clip area. */
if ((pNum == ExtCurStyle->exts_globSubstratePlane) &&
TTMaskHasType(&ExtCurStyle->exts_globSubstrateTypes,
lab->lab_type))
{
if (temp_subsnode != NULL)
{
if (glob_subsnode != NULL)
{
ll = (LabelList *)mallocMagic(sizeof(LabelList));
ll->ll_label = lab;
if (lab->lab_flags & PORT_DIR_MASK)
ll->ll_attr = LL_PORTATTR;
else
ll->ll_attr = LL_NOATTR;
ll->ll_next = glob_subsnode->nreg_labels;
glob_subsnode->nreg_labels = ll;
}
}
else
{
NodeRegion *newNode;
int n;
int nclasses;
nclasses = ExtCurStyle->exts_numResistClasses;
n = sizeof (NodeRegion) + (sizeof (PerimArea) * (nclasses - 1));
newNode = (NodeRegion *)mallocMagic((unsigned) n);
ll = (LabelList *)mallocMagic(sizeof(LabelList));
ll->ll_label = lab;
ll->ll_next = NULL;
if (lab->lab_flags & PORT_DIR_MASK)
ll->ll_attr = LL_PORTATTR;
else
ll->ll_attr = LL_NOATTR;
newNode->nreg_next = *nodeList;
newNode->nreg_pnum = pNum;
newNode->nreg_type = lab->lab_type;
newNode->nreg_ll = lab->lab_rect.r_ll;
newNode->nreg_cap = (CapValue)0;
newNode->nreg_resist = 0;
for (n = 0; n < nclasses; n++)
newNode->nreg_pa[n].pa_perim = newNode->nreg_pa[n].pa_area = 0;
newNode->nreg_labels = ll;
*nodeList = newNode;
ll->ll_next = glob_subsnode->nreg_labels;
temp_subsnode->nreg_labels = ll;
}
}
/* This may be a "sticky label". If it is not connected to
* TT_SPACE, then create a new node region for it. The
* label must be within the clip area.
*/
else if ((GEO_SURROUND(&lab->lab_rect, clipArea) ||
GEO_TOUCH(&lab->lab_rect, clipArea))
&& (lab->lab_type != TT_SPACE))
{
NodeRegion *newNode;
int n;
int nclasses;
nclasses = ExtCurStyle->exts_numResistClasses;
n = sizeof (NodeRegion) + (sizeof (PerimArea) * (nclasses - 1));
newNode = (NodeRegion *)mallocMagic((unsigned) n);
ll = (LabelList *)mallocMagic(sizeof(LabelList));
ll->ll_label = lab;
ll->ll_next = NULL;
if (lab->lab_flags & PORT_DIR_MASK)
ll->ll_attr = LL_PORTATTR;
else
ll->ll_attr = LL_NOATTR;
newNode->nreg_next = *nodeList;
newNode->nreg_pnum = pNum;
newNode->nreg_type = lab->lab_type;
newNode->nreg_ll = lab->lab_rect.r_ll;
newNode->nreg_cap = (CapValue)0;
newNode->nreg_resist = 0;
for (n = 0; n < nclasses; n++)
newNode->nreg_pa[n].pa_perim = newNode->nreg_pa[n].pa_area = 0;
newNode->nreg_labels = ll;
*nodeList = newNode;
}
}
}
}