Tests of substrate extraction

This commit is contained in:
Tim Edwards 2021-04-04 20:43:43 -04:00
parent a2f7831b17
commit 75e4fbe5ad
6 changed files with 414 additions and 13 deletions

View File

@ -342,6 +342,248 @@ DBCellCheckCopyAllPaint(scx, mask, xMask, targetUse, func)
DBTreeSrTiles(scx, &locMask, xMask, dbCopyAllPaint, (ClientData) &arg);
}
/* Client data structure used by DBCellCopySubstrate() */
struct dbCopySubData {
Plane *csd_plane;
TileType csd_subtype;
int csd_pNum;
bool csd_modified;
};
/*
*-----------------------------------------------------------------------------
*
* DBCellCopySubstrate --
*
* This function is used by the extraction code in ExtSubtree.c.
* Paint substrate into the target use. Similar to DBCellCopyAllPaint(),
* but it finds space tiles on the substrate plane and converts them to
* a substrate type in the target, clipped to the cell boundary. This
* allows the extraction to find and record all substrate regions, both
* common (global substrate) and local (isolated substrate), without
* requiring a physical substrate type to be drawn into all cells.
*
* Unlike normal paint copying, this can only be done by painting the
* substrate type over the entire cell area and then erasing all areas
* belonging to not-substrate types in the source.
*
* Returns:
* Nothing.
*
* Side Effects:
* Paints into the targetUse's CellDef. This only happens if two
* conditions are met:
* (1) The techfile has defined "substrate"
* (2) The techfile defines a type corresponding to the substrate
*
* ----------------------------------------------------------------------------
*/
void
DBCellCopySubstrate(scx, subType, notSubMask, targetUse)
SearchContext *scx;
TileType subType; /* Substrate paint type */
TileTypeBitMask *notSubMask; /* Mask of types that are not substrate */
CellUse *targetUse;
{
struct dbCopySubData csd;
Plane *tempPlane;
int plane;
Rect rect;
int dbEraseNonSub();
int dbCopySubFunc();
GEOTRANSRECT(&scx->scx_trans, &scx->scx_area, &rect);
/* Clip to bounding box of the top level cell */
GEOCLIP(&rect, &scx->scx_use->cu_def->cd_bbox);
plane = DBPlane(subType);
tempPlane = DBNewPlane((ClientData) TT_SPACE);
DBClearPaintPlane(tempPlane);
/* First paint the substrate type in the temporary plane over the whole cell area */
DBPaintPlane(tempPlane, &rect, DBStdPaintTbl(subType, plane),
(PaintUndoInfo *)NULL);
csd.csd_subtype = subType;
csd.csd_plane = tempPlane;
csd.csd_pNum = plane;
/* Now erase all areas that are non-substrate types in the source */
/* Note: xMask is always zero, as this is only called from extract routines */
DBTreeSrTiles(scx, notSubMask, 0, dbEraseNonSub, (ClientData)&csd);
/* Finally, copy the temp plane contents into the destination */
csd.csd_plane = targetUse->cu_def->cd_planes[plane];
DBSrPaintArea((Tile *)NULL, tempPlane, &TiPlaneRect,
&DBAllButSpaceBits, dbCopySubFunc, (ClientData)&csd);
/* Clean up by removing the temp plane */
DBFreePaintPlane(tempPlane);
TiFreePlane(tempPlane);
}
/* Create a canonical substrate. Return the modified plane */
Plane *
DBCellCanonicalSubstrate(scx, subType, notSubMask, subShieldMask, targetUse)
SearchContext *scx;
TileType subType; /* Substrate paint type */
TileTypeBitMask *notSubMask; /* Mask of types that are not substrate */
TileTypeBitMask *subShieldMask; /* Mask of types that shield substrate */
CellUse *targetUse;
{
struct dbCopySubData csd;
Plane *tempPlane;
int plane;
Rect rect;
int dbPaintSubFunc();
int dbEraseNonSub();
int dbCopySubFunc();
GEOTRANSRECT(&scx->scx_trans, &scx->scx_area, &rect);
/* Clip to bounding box of the top level cell */
GEOCLIP(&rect, &scx->scx_use->cu_def->cd_bbox);
plane = DBPlane(subType);
tempPlane = DBNewPlane((ClientData) TT_SPACE);
DBClearPaintPlane(tempPlane);
csd.csd_subtype = subType;
csd.csd_plane = tempPlane;
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. */
/* Note: xMask is always zero, as this is only called from extract routines */
DBTreeSrTiles(scx, subShieldMask, 0, dbPaintSubFunc, (ClientData)&csd);
if (csd.csd_modified == FALSE) return NULL;
/* Now erase all areas that are non-substrate types in the source */
DBTreeSrTiles(scx, notSubMask, 0, dbEraseNonSub, (ClientData)&csd);
/* Finally, copy the destination plane contents onto tempPlane */
DBSrPaintArea((Tile *)NULL, targetUse->cu_def->cd_planes[plane], &TiPlaneRect,
&DBAllButSpaceBits, dbCopySubFunc, (ClientData)&csd);
return tempPlane;
}
/*
* Callback function for DBCellCopySubstrate()
* Finds tiles on the substrate plane in the source def that are not the
* substrate type, and erases those areas from the target.
*/
int
dbEraseNonSub(tile, cxp)
Tile *tile; /* Pointer to tile to erase from target */
TreeContext *cxp; /* Context from DBTreeSrTiles */
{
SearchContext *scx;
Rect sourceRect, targetRect;
Plane *plane; /* Plane of target data */
TileType type, loctype, subType;
struct dbCopySubData *csd;
int pNum;
csd = (struct dbCopySubData *)cxp->tc_filter->tf_arg;
plane = csd->csd_plane;
subType = csd->csd_subtype;
pNum = csd->csd_pNum;
scx = cxp->tc_scx;
type = TiGetTypeExact(tile);
if (IsSplit(tile))
{
loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
if (loctype == TT_SPACE) return 0;
}
else
loctype = type;
/* Construct the rect for the tile */
TITORECT(tile, &sourceRect);
/* Transform to target coordinates */
GEOTRANSRECT(&scx->scx_trans, &sourceRect, &targetRect);
/* Erase the substrate type from the area of this tile in the target plane. */
return DBNMPaintPlane(plane, loctype, &targetRect, DBStdEraseTbl(subType, pNum),
(PaintUndoInfo *)NULL);
}
/*
* Callback function for DBCellCopySubstrate()
* Simple paint function to copy substrate paint from a temporary plane into
* a target plane.
*/
int
dbCopySubFunc(tile, csd)
Tile *tile; /* Pointer to tile to erase from target */
struct dbCopySubData *csd; /* Client data */
{
Rect rect;
int pNum;
TileType type, loctype;
Plane *plane;
plane = csd->csd_plane;
pNum = csd->csd_pNum;
type = TiGetTypeExact(tile);
if (IsSplit(tile))
{
loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
if (loctype == TT_SPACE) return 0;
}
else
loctype = type;
/* Construct the rect for the tile */
TITORECT(tile, &rect);
return DBNMPaintPlane(plane, type, &rect, DBStdPaintTbl(loctype, pNum),
(PaintUndoInfo *)NULL);
}
int
dbPaintSubFunc(tile, cxp)
Tile *tile; /* Pointer to source tile with shield type */
TreeContext *cxp; /* Context from DBTreeSrTiles */
{
Rect rect;
int pNum;
TileType type, loctype, subType;
Plane *plane;
struct dbCopySubData *csd; /* Client data */
csd = (struct dbCopySubData *)cxp->tc_filter->tf_arg;
plane = csd->csd_plane;
pNum = csd->csd_pNum;
subType = csd->csd_subtype;
type = TiGetTypeExact(tile);
if (IsSplit(tile))
{
loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
if (loctype == TT_SPACE) return 0;
}
/* Construct the rect for the tile */
TITORECT(tile, &rect);
csd->csd_modified = TRUE;
return DBNMPaintPlane(plane, type, &rect, DBStdPaintTbl(subType, pNum),
(PaintUndoInfo *)NULL);
}
/*
*-----------------------------------------------------------------------------
*

View File

@ -819,6 +819,8 @@ extern char *DBPrintUseId();
extern void DBCellCopyPaint();
extern void DBCellCopyAllPaint();
extern void DBCellCheckCopyAllPaint();
extern void DBCellCopySubstrate();
extern Plane *DBCellCanonicalSubstrate();
extern void DBCellCopyLabels();
extern void DBCellCopyAllLabels();
extern void DBCellCopyCells();

View File

@ -484,7 +484,10 @@ extHardFreeAll(def, tReg)
/* Free all LabelLists and then the region */
for (ll = reg->treg_labels; ll; ll = ll->ll_next)
{
if (ll->ll_label->lab_flags & LABEL_GENERATE) freeMagic(ll->ll_label);
freeMagic((char *) ll);
}
freeMagic((char *) reg);
}
}

View File

@ -127,6 +127,69 @@ ExtFindRegions(def, area, mask, connectsTo, uninit, first, each)
return (arg.fra_region);
}
/*
* ----------------------------------------------------------------------------
* ExtFindSubstrateRegions --
*
* This is a subset of ExtFindRegions that looks only at the substrate
* plane. It is called on the first pass, when only the parent paint
* has been added to the cumulative def.
*
* ----------------------------------------------------------------------------
*/
Region *
ExtFindSubstrateRegions(def, area, mask, connectsTo, uninit, first, each)
CellDef *def; /* Cell definition being searched */
Rect *area; /* Area to search initially for tiles */
TileTypeBitMask *mask; /* In the initial area search, only visit
* tiles whose types are in this mask.
*/
TileTypeBitMask *connectsTo;/* Connectivity table for determining regions.
* If t1 and t2 are the types of adjacent
* tiles, then t1 and t2 belong to the same
* region iff:
* TTMaskHasType(&connectsTo[t1], t2)
*
* We assume that connectsTo[] is symmetric,
* so this is the same as:
* TTMaskHasType(&connectsTo[t2], t1)
*/
ClientData uninit; /* Contents of a ti_client field indicating
* that the tile has not yet been visited.
*/
Region * (*first)(); /* Applied to first tile in region */
int (*each)(); /* Applied to each tile in region */
{
FindRegion arg;
TileTypeBitMask subMask;
int extRegionAreaFunc();
ASSERT(first != NULL, "ExtFindRegions");
arg.fra_pNum = ExtCurStyle->exts_globSubstratePlane;
if (arg.fra_pNum < 0) return NULL;
arg.fra_connectsTo = connectsTo;
arg.fra_def = def;
arg.fra_uninit = uninit;
arg.fra_first = first;
arg.fra_each = each;
arg.fra_region = (Region *) NULL;
SigDisableInterrupts();
TTMaskZero(&subMask);
TTMaskSetMask(&subMask, mask);
TTMaskAndMask(&subMask, &ExtCurStyle->exts_globSubstrateTypes);
DBSrPaintClient((Tile *) NULL, def->cd_planes[arg.fra_pNum],
area, &subMask, uninit, extRegionAreaFunc, (ClientData) &arg);
SigEnableInterrupts();
return (arg.fra_region);
}
/*
* ----------------------------------------------------------------------------
*

View File

@ -170,6 +170,11 @@ extSubtree(parentUse, reg, f)
float pdone, plast;
SearchContext scx;
TileType subType;
TileTypeBitMask subMask, notSubMask;
Plane *subPlane, *savePlane;
bool hasSubDef = FALSE;
/* Use the display timer to force a 5-second progress check */
GrDisplayStatus = DISPLAY_IN_PROGRESS;
SigSetTimer(5); /* Print at 5-second intervals */
@ -195,6 +200,54 @@ extSubtree(parentUse, reg, f)
ha.ha_cumFlat.et_use = extYuseCum;
HashInit(&ha.ha_connHash, 32, 0);
/* Determine if substrate copying is required. */
hasSubDef = (ExtCurStyle->exts_globSubstratePlane != -1) ? TRUE : FALSE;
if (hasSubDef)
{
/* Find a type to use for the substrate, and the mask of all types */
/* in the same plane as the substrate that are not connected to the */
/* substrate. If there is not a simple type representing the substrate */
/* then do not attempt to resolve substrate regions. */
TTMaskZero(&subMask);
TTMaskSetMask(&subMask, &ExtCurStyle->exts_globSubstrateTypes);
for (subType = TT_TECHDEPBASE; subType < DBNumUserLayers; subType++)
if (TTMaskHasType(&subMask, subType))
if (DBPlane(subType) == ExtCurStyle->exts_globSubstratePlane)
break;
TTMaskCom2(&notSubMask, &subMask);
TTMaskAndMask(&notSubMask, &DBPlaneTypes[ExtCurStyle->exts_globSubstratePlane]);
if (subType == DBNumUserLayers) hasSubDef = FALSE;
}
/* Generate the full flattened substrate into ha->ha_cumFlat (which */
/* was empty initially). This adds layer geometry for the */
/* substrate in the typical case where the substrate may be space */
/* (implicitly defined substrate). */
if (hasSubDef)
{
int pNum;
scx.scx_trans = GeoIdentityTransform;
scx.scx_area = def->cd_bbox;
scx.scx_use = parentUse;
subPlane = DBCellCanonicalSubstrate(&scx, subType, &notSubMask,
&ExtCurStyle->exts_globSubstrateShieldTypes, parentUse);
if (subPlane != NULL)
{
pNum = ExtCurStyle->exts_globSubstratePlane;
savePlane = parentUse->cu_def->cd_planes[pNum];
parentUse->cu_def->cd_planes[pNum] = subPlane;
}
else
hasSubDef = FALSE; /* CellDef has no isolated substrate regions */
}
#ifndef exactinteractions
/*
* Cookie-cutter up def into pieces ExtCurStyle->exts_stepSize by
@ -331,6 +384,17 @@ done:
/* Clear the CU_SUB_EXTRACTED flag from all children instances */
DBCellEnum(def, extClearUseFlags, (ClientData)NULL);
/* Replace the modified substrate plane with the original */
if (hasSubDef)
{
int pNum;
pNum = ExtCurStyle->exts_globSubstratePlane;
parentUse->cu_def->cd_planes[pNum] = savePlane;
DBFreePaintPlane(subPlane);
TiFreePlane(subPlane);
}
}
#ifdef exactinteractions
@ -429,26 +493,30 @@ extSubtreeInteraction(ha)
NodeRegion *reg;
SearchContext scx;
/* Copy parent paint into ha->ha_cumFlat (which was initially empty) */
scx.scx_trans = GeoIdentityTransform;
scx.scx_area = ha->ha_interArea;
scx.scx_use = ha->ha_parentUse;
/*
if (hasSubDef)
DBCellCopySubstrate(&scx, subType, &notSubMask, ha->ha_cumFlat.et_use);
*/
/* Copy parent paint into ha->ha_cumFlat */
DBCellCopyPaint(&scx, &DBAllButSpaceBits, 0, ha->ha_cumFlat.et_use);
#ifdef notdef
extCopyPaint(ha->ha_parentUse->cu_def, &ha->ha_interArea, cumDef);
#endif /* notdef */
/*
* First element on the subtree list will be parent mask info.
* First element on the subtree list will be parent mask info,
* including the full flattened substrate.
* Extract nodes and capacitors. Node names come from parent.
*/
oneFlat = extHierNewOne();
oneDef = oneFlat->et_use->cu_def;
/*
if (hasSubDef)
DBCellCopySubstrate(&scx, subType, &notSubMask, oneFlat->et_use);
*/
DBCellCopyPaint(&scx, &DBAllButSpaceBits, 0, oneFlat->et_use);
#ifdef notdef
extCopyPaint(ha->ha_parentUse->cu_def, &ha->ha_interArea, oneDef);
#endif /* notdef */
oneFlat->et_nodes = extFindNodes(oneDef, &ha->ha_clipArea, FALSE);
if ((ExtOptions & (EXT_DOCOUPLING|EXT_DOADJUST))
== (EXT_DOCOUPLING|EXT_DOADJUST))
@ -569,6 +637,7 @@ extSubtreeInteraction(ha)
ha->ha_cumFlat.et_nodes = (NodeRegion *) NULL;
extHierFreeLabels(cumDef);
DBCellClearDef(cumDef);
}
/*
@ -732,6 +801,18 @@ extSubtreeFunc(scx, ha)
/* Record information for finding node names the hard way later */
ha->ha_subUse = use;
/* Copy the substrate into the oneFlat target */
/*
if (ha->ha_subType != -1)
{
newscx.scx_use = ha->ha_cumFlat.et_use;
newscx.scx_area = use->cu_bbox;
GEOCLIP(&newscx.scx_area, &ha->ha_interArea);
newscx.scx_trans = GeoIdentityTransform;
DBCellCopySubstrate(&newscx, ha->ha_subType, ha->ha_notSubMask, oneFlat->et_use);
}
*/
/*
* Yank all array elements of this subcell that lie in the interaction
* area. Transform to parent coordinates. Prefix is true, meaning that
@ -743,6 +824,7 @@ extSubtreeFunc(scx, ha)
hy.hy_area = &ha->ha_subArea;
hy.hy_target = oneFlat->et_use;
hy.hy_prefix = TRUE;
(void) DBArraySr(use, &ha->ha_subArea, extHierYankFunc, (ClientData) &hy);
/*
@ -767,6 +849,8 @@ extSubtreeFunc(scx, ha)
*/
if (extFirstPass)
{
extFirstPass = FALSE;
// On the first pass, run through et_lookName's label list.
// Copy any sticky labels to cumUse->cu_def, so that the labels
// can be found even when there is no geometry underneath in
@ -796,7 +880,17 @@ extSubtreeFunc(scx, ha)
cumUse->cu_def->cd_labels = newlab;
}
}
extFirstPass = FALSE;
/*
ha->ha_cumFlat.et_nodes =
(NodeRegion *) ExtFindSubstrateRegions(cumUse->cu_def,
&TiPlaneRect,
&ExtCurStyle->exts_activeTypes,
ExtCurStyle->exts_nodeConn,
extUnInit, extHierLabFirst, (int (*)()) NULL);
ExtLabelRegions(cumUse->cu_def, ExtCurStyle->exts_nodeConn,
&(ha->ha_cumFlat.et_nodes), &TiPlaneRect);
*/
}
else
{
@ -861,9 +955,6 @@ extSubtreeFunc(scx, ha)
newscx.scx_area = ha->ha_subArea;
newscx.scx_trans = GeoIdentityTransform;
DBCellCopyPaint(&newscx, &DBAllButSpaceBits, 0, cumUse);
#ifdef notdef
extCopyPaint(oneFlat->et_use->cu_def, &ha->ha_subArea, cumUse->cu_def);
#endif /* notdef */
extHierCopyLabels(oneFlat->et_use->cu_def, cumUse->cu_def);
/* Prepend this tree to the list of trees we've processed so far */
@ -1216,7 +1307,6 @@ extSubtreeHardSearch(et, arg)
HierExtractArg *ha = arg->hw_ha;
ExtTree *oneFlat;
arg->hw_proc = extHardProc;
if (et == &ha->ha_cumFlat)
{

View File

@ -1016,6 +1016,7 @@ extern ClientData extUnInit;
/* ------------------------- Region finding --------------------------- */
extern Region *ExtFindRegions();
extern Region *ExtFindSubstrateRegions();
/* Filter functions for ExtFindRegions() */
extern Region *extTransFirst(); extern int extTransEach();