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; + } } } }