diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index 28acae08..e69bb386 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -405,17 +405,18 @@ calmaParseStructure(filename) */ if (CalmaFlattenUses && (!was_called) && (npaths < 10) && (nsrefs == 0)) { - /* To-do: If CDFLATGDS is already set, need to remove */ + /* If CDFLATGDS is already set, may need to remove */ /* existing planes and free memory. */ - if (cifReadCellDef->cd_flags & CDFLATGDS) + if ((cifReadCellDef->cd_client != (ClientData)CLIENTDEFAULT) && + (cifReadCellDef->cd_flags & CDFLATGDS)) { Plane **cifplanes = (Plane **)cifReadCellDef->cd_client; int pNum; for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++) { - if (cifplanes[pNum] != NULL) + if (cifplanes[pNum] != NULL) { DBFreePaintPlane(cifplanes[pNum]); TiFreePlane(cifplanes[pNum]); @@ -903,7 +904,8 @@ calmaElementSref(filename) for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++) { - if (gdsplanes[pNum] != NULL) + if ((def->cd_client != (ClientData)CLIENTDEFAULT) && + (gdsplanes[pNum] != NULL)) { gdsCopyRec.plane = cifCurReadPlanes[pNum]; if (isArray) diff --git a/database/DBlabel2.c b/database/DBlabel2.c index 91c1908d..c060ac14 100644 --- a/database/DBlabel2.c +++ b/database/DBlabel2.c @@ -296,18 +296,25 @@ DBTreeFindUse(name, use, scx) if ((def->cd_flags & CDAVAILABLE) == 0) (void) DBCellRead(def, (char *) NULL, TRUE, NULL); - /* - * Pull off the next component of path up to but not including - * any array subscripts. - */ - for (cp = name; *cp && *cp != '[' && *cp != '/'; cp++) - /* Nothing */; - csave = *cp; - *cp = '\0'; he = HashLookOnly(&def->cd_idHash, name); - *cp = csave; if (he == NULL || HashGetValue(he) == NULL) - return; + { + /* + * Pull off the next component of path up to but not including + * any array subscripts. + * NOTE: This should check the array bounds and only remove + * array components that are expected, not array components + * embedded in the name. + */ + for (cp = name; *cp && *cp != '[' && *cp != '/'; cp++) + /* Nothing */; + csave = *cp; + *cp = '\0'; + he = HashLookOnly(&def->cd_idHash, name); + *cp = csave; + if (he == NULL || HashGetValue(he) == NULL) + return; + } use = (CellUse *) HashGetValue(he); def = use->cu_def; diff --git a/database/DBprop.c b/database/DBprop.c index c2ded840..85574435 100644 --- a/database/DBprop.c +++ b/database/DBprop.c @@ -66,6 +66,15 @@ DBPropPut(cellDef, name, value) HashInit( (HashTable *) cellDef->cd_props, 8, 0); } htab = (HashTable *) cellDef->cd_props; + + /* Special handling of FIXED_BBOX, which uses CDFIXEDBBOX as a quick lookup */ + if (!strcmp(name, "FIXED_BBOX")) + { + if (value == (ClientData)NULL) + cellDef->cd_flags &= ~CDFIXEDBBOX; + else + cellDef->cd_flags |= CDFIXEDBBOX; + } entry = HashFind(htab, name); oldvalue = (char *)HashGetValue(entry); @@ -202,4 +211,8 @@ DBPropClearAll(cellDef) HashKill(htab); freeMagic((char *) htab); cellDef->cd_props = (ClientData) NULL; + + /* Since CDFIXEDBBOX requires a FIXED_BBOX property, clearing all */ + /* properties necessarily means this flag must be clear. */ + cellDef->cd_flags &= ~CDFIXEDBBOX; } diff --git a/extract/ExtBasic.c b/extract/ExtBasic.c index 89e32cb7..57f12df1 100644 --- a/extract/ExtBasic.c +++ b/extract/ExtBasic.c @@ -123,18 +123,6 @@ LinkedBoundary **extSpecialBounds; /* Linked Boundary List */ NodeRegion *glob_subsnode = NULL; /* Global substrate node */ NodeRegion *temp_subsnode = NULL; /* Last subsnode found */ -/* Structure used for finding substrate connections on implicitly-defined - * substrates - */ - -typedef struct TSD1 -{ - bool found; /* Set to 1 if a substrate connection was found */ - Rect rtrans; /* Rectangle of device */ - Rect rhalo; /* Search halo around device */ - NodeRegion *nreg; /* Closest substrate region within halo */ -} TransSubsData; - #define EDGENULL(r) ((r)->r_xbot > (r)->r_xtop || (r)->r_ybot > (r)->r_ytop) /* Forward declarations */ @@ -3396,9 +3384,11 @@ extFindNodes(def, clipArea, subonly) { int extNodeAreaFunc(); int extSubsFunc(); + int extSubsFunc2(); FindRegion arg; int pNum, n; TileTypeBitMask subsTypesNonSpace; + bool space_is_substrate; /* Reset perimeter and area prior to node extraction */ for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) @@ -3418,19 +3408,52 @@ extFindNodes(def, clipArea, subonly) /* call extNodeAreaFunc() on the first of these to generate */ /* a single substrate node. */ + /* Refinement: Split search into two parts, one on the */ + /* globSubstratePlane and one on all other planes. ONLY */ + /* search other planes if TT_SPACE is in the list of */ + /* substrate types, and then only consider those types to */ + /* be part of the substrate node if they have only space */ + /* below them on the globSubstratePlane. This method lets */ + /* a single type like "psd" operate on, for example, both */ + /* the substrate and an isolated pwell, without implicitly */ + /* connecting the isolated pwell to the substrate. */ + temp_subsnode = (NodeRegion *)NULL; // Reset for new search + if (TTMaskHasType(&ExtCurStyle->exts_globSubstrateTypes, TT_SPACE)) + space_is_substrate = True; + else + space_is_substrate = False; + TTMaskZero(&subsTypesNonSpace); TTMaskSetMask(&subsTypesNonSpace, &ExtCurStyle->exts_globSubstrateTypes); TTMaskClearType(&subsTypesNonSpace, TT_SPACE); + pNum = ExtCurStyle->exts_globSubstratePlane; + /* Does the type set of this plane intersect the substrate types? */ + if (TTMaskIntersect(&DBPlaneTypes[pNum], &subsTypesNonSpace)) + { + arg.fra_pNum = pNum; + DBSrPaintClient((Tile *) NULL, def->cd_planes[pNum], + &TiPlaneRect, &subsTypesNonSpace, extUnInit, + extSubsFunc, (ClientData) &arg); + } + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { + if (pNum == ExtCurStyle->exts_globSubstratePlane) continue; + /* Does the type set of this plane intersect the substrate types? */ + if (TTMaskIntersect(&DBPlaneTypes[pNum], &subsTypesNonSpace)) { arg.fra_pNum = pNum; - DBSrPaintClient((Tile *) NULL, def->cd_planes[pNum], + if (space_is_substrate) + DBSrPaintClient((Tile *) NULL, def->cd_planes[pNum], + &TiPlaneRect, &subsTypesNonSpace, extUnInit, + extSubsFunc2, (ClientData) &arg); + else + DBSrPaintClient((Tile *) NULL, def->cd_planes[pNum], &TiPlaneRect, &subsTypesNonSpace, extUnInit, extSubsFunc, (ClientData) &arg); } @@ -3503,6 +3526,39 @@ extSubsFunc(tile, arg) return (0); } +int +extSubsFunc2(tile, arg) + Tile *tile; + FindRegion *arg; +{ + int pNum; + Rect tileArea; + int extSubsFunc3(); + + TiToRect(tile, &tileArea); + + /* Run second search in the area of the tile on the substrate plane */ + /* to make sure that nothing but space is under these tiles. */ + + pNum = ExtCurStyle->exts_globSubstratePlane; + + if (DBSrPaintArea((Tile *) NULL, arg->fra_def->cd_planes[pNum], + &tileArea, &DBAllButSpaceBits, + extSubsFunc3, (ClientData)NULL) == 0) + { + /* Mark this tile as pending and push it */ + PUSHTILE(tile, arg->fra_pNum); + } + return (0); +} + +int +extSubsFunc3(tile) + Tile *tile; +{ + /* Stops the search because something that was not space was found */ + return 1; +} int extNodeAreaFunc(tile, arg)