From db4fa65bfc096e63954b37b188ea27b90ab31839 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 24 Feb 2022 16:47:11 -0500 Subject: [PATCH] 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. --- VERSION | 2 +- database/DBcellcopy.c | 11 ++++- drc/DRCsubcell.c | 24 +++++++---- extract/ExtBasic.c | 8 ++++ extract/ExtRegion.c | 96 +++++++++++++++++++++---------------------- 5 files changed, 82 insertions(+), 59 deletions(-) diff --git a/VERSION b/VERSION index 3d7c223d..19951506 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.271 +8.3.272 diff --git a/database/DBcellcopy.c b/database/DBcellcopy.c index 9f685e8b..f8f147cf 100644 --- a/database/DBcellcopy.c +++ b/database/DBcellcopy.c @@ -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; diff --git a/drc/DRCsubcell.c b/drc/DRCsubcell.c index 34f49223..0d755c38 100644 --- a/drc/DRCsubcell.c +++ b/drc/DRCsubcell.c @@ -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++) { diff --git a/extract/ExtBasic.c b/extract/ExtBasic.c index 115a7ee9..1f1977fd 100644 --- a/extract/ExtBasic.c +++ b/extract/ExtBasic.c @@ -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)) diff --git a/extract/ExtRegion.c b/extract/ExtRegion.c index 68e4858f..87c43384 100644 --- a/extract/ExtRegion.c +++ b/extract/ExtRegion.c @@ -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; + } } } }