Made a correction to the last commit, which is that when searching

a shielded substrate area for devices with terminals connecting to
substrate, search the entire cell hierarchy down to the bottom in
that area, not just the immediate child cell.  Also:  Reduced the
number of types being searched to ignore types in non-substrate
areas like nwell, although it should not make a practical difference
because those areas should not be searched.
This commit is contained in:
R. Timothy Edwards 2026-06-22 20:03:30 -04:00
parent 381714e2d5
commit f4b210a9c0
5 changed files with 76 additions and 50 deletions

View File

@ -1 +1 @@
8.3.664
8.3.665

View File

@ -147,7 +147,11 @@ extHierSubInteractFunc(tile, dinfo, clientdata)
* but do not interact with the cell, check the area of the
* substrate shield for device types that connect to substrate
* (ExtCurStyle->exts_subsDevTypes). If something is found, then
* return 1 immediately to stop the search.
* return 1 immediately to stop the search. This search needs to
* be done hierarchically over this cell and all of its descendants,
* because if any descendant cell contains a device connecting to
* the substrate under the shield, then this cell will need to
* connect the correct substrate net to it.
*
* Results: 1 if an interacting substrate shield is found, 0 otherwise.
*
@ -162,41 +166,21 @@ extHierSubShieldFunc(tile, dinfo, use)
TileType dinfo;
CellUse *use;
{
Rect r, rsub;
int pNum;
TileType ttype;
CellDef *subdef;
SearchContext scontext;
Transform t;
if (IsSplit(tile))
{
ttype = TiGetLeftType(tile);
if (!TTMaskHasType(&ExtCurStyle->exts_globSubstrateShieldTypes, ttype))
ttype = TiGetRightType(tile);
}
else
ttype = TiGetTypeExact(tile);
Rect r;
TiToRect(tile, &r);
/* Convert area of tile to the coordinates of the cell "subdef", which is
* a child of the cell containing "tile".
*/
subdef = use->cu_def;
GeoInvertTrans(&use->cu_transform, &t);
GeoTransRect(&t, &r, &rsub);
scontext.scx_use = use;
scontext.scx_trans = GeoIdentityTransform;
GEOINVERTTRANS(&use->cu_transform, &t);
GEOTRANSRECT(&t, &r, &scontext.scx_area);
if (DBTreeSrTiles(&scontext, &ExtCurStyle->exts_subsDevTypes, 0,
extHierSubInteractFunc, (ClientData)NULL) == 1)
return 1;
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
{
if (TTMaskIntersect(&DBPlaneTypes[pNum], &ExtCurStyle->exts_subsDevTypes))
{
if (DBSrPaintNMArea((Tile *)NULL,
subdef->cd_planes[pNum], dinfo, &rsub,
&ExtCurStyle->exts_subsDevTypes,
extHierSubInteractFunc, (ClientData)NULL) == 1)
return 1;
}
}
return 0;
}
@ -213,10 +197,14 @@ extHierSubShieldFunc(tile, dinfo, use)
* isolated by a substrate shield type, in which case no merge is
* done.
*
* Result:
* Return 0 if a substrate was extracted, or doesn't require
* extracting; 1 if not.
*
*----------------------------------------------------------------------
*/
void
int
extHierSubstrate(ha, use, x, y)
HierExtractArg *ha; // Contains parent def and hash table
CellUse *use; // Child use
@ -236,14 +224,14 @@ extHierSubstrate(ha, use, x, y)
/* Backwards compatibility with tech files that don't */
/* define a substrate plane or substrate connections. */
if (glob_subsnode == NULL) return;
if (glob_subsnode == NULL) return 0;
/* If the substrate has already been extracted for this use */
/* then there is no need to do it again. */
if (use->cu_flags & CU_SUB_EXTRACTED) return;
if (use->cu_flags & CU_SUB_EXTRACTED) return 0;
/* Don't extract anything from cells marked "don't use". */
if (use->cu_def->cd_flags & CDDONTUSE) return;
if (use->cu_def->cd_flags & CDDONTUSE) return 0;
def = (CellDef *)ha->ha_parentUse->cu_def;
@ -251,7 +239,8 @@ extHierSubstrate(ha, use, x, y)
/* The parent def's substrate node is in glob_subsnode */
name1 = extNodeName(glob_subsnode);
if (*name1 == '(' && !strcmp(name1, "(none)")) return; /* Don't process "(none)" nodes! */
/* Don't process "(none)" nodes! */
if (*name1 == '(' && !strcmp(name1, "(none)")) return 0;
he = HashFind(table, name1);
nn = (NodeName *) HashGetValue(he);
node1 = nn ? nn->nn_node : extHierNewNode(he);
@ -261,7 +250,7 @@ extHierSubstrate(ha, use, x, y)
if (nodeList == NULL)
{
ExtResetTiles(use->cu_def, CLIENTDEFAULT);
return;
return 0;
}
/* Check if the child's substrate node is covered by any substrate */
@ -301,7 +290,7 @@ extHierSubstrate(ha, use, x, y)
{
freeMagic(nodeList);
ExtResetTiles(use->cu_def, CLIENTDEFAULT);
return;
return 1;
}
}
}
@ -380,6 +369,7 @@ extHierSubstrate(ha, use, x, y)
}
}
freeMagic(nodeList);
return 0;
}
/*

View File

@ -181,7 +181,7 @@ extSubtree(parentUse, reg, f)
/* Use the display timer to force a 5-second progress check */
savedDisplayStatus = GrDisplayStatus;
GrDisplayStatus = DISPLAY_IN_PROGRESS;
SigSetTimer(5); /* Print at 5-second intervals */
SigSetTimer(5); /* Print at 5-second intervals */
if ((ExtOptions & (EXT_DOCOUPLING|EXT_DOADJUST))
!= (EXT_DOCOUPLING|EXT_DOADJUST))
@ -777,6 +777,7 @@ extSubtreeFunc(scx, ha)
SearchContext newscx;
ExtTree *oneFlat;
HierYank hy;
bool subok;
int x, y;
/* Allocate a new ExtTree to hold the flattened, extracted subtree */
@ -921,25 +922,31 @@ extSubtreeFunc(scx, ha)
/* connected. */
if (use->cu_xhi == use->cu_xlo && use->cu_yhi == use->cu_ylo)
extHierSubstrate(ha, use, -1, -1);
subok = (!extHierSubstrate(ha, use, -1, -1)) ? TRUE : FALSE;
else if (use->cu_xhi == use->cu_xlo && use->cu_yhi > use->cu_ylo)
{
subok = FALSE;
for (y = use->cu_ylo; y <= use->cu_yhi; y++)
extHierSubstrate(ha, use, -1, y);
if (!extHierSubstrate(ha, use, -1, y))
subok = TRUE;
}
else if (use->cu_xhi > use->cu_xlo && use->cu_yhi == use->cu_ylo)
{
subok = FALSE;
for (x = use->cu_xlo; x <= use->cu_xhi; x++)
extHierSubstrate(ha, use, x, -1);
if (!extHierSubstrate(ha, use, x, -1))
subok = TRUE;
}
else
{
subok = FALSE;
for (x = use->cu_xlo; x <= use->cu_xhi; x++)
for (y = use->cu_ylo; y <= use->cu_yhi; y++)
extHierSubstrate(ha, use, x, y);
if (!extHierSubstrate(ha, use, x, y))
subok = TRUE;
}
/* Mark substrate as having been extracted for this use. */
use->cu_flags |= CU_SUB_EXTRACTED;
if (subok) use->cu_flags |= CU_SUB_EXTRACTED;
/* Free the cumulative node list we extracted above */
if (ha->ha_cumFlat.et_nodes)

View File

@ -2356,8 +2356,6 @@ ExtTechLine(sectionName, argc, argv)
}
TTMaskSetMask(&ExtCurStyle->exts_deviceMask, &types1);
if (!TTMaskIsZero(&subsTypes))
TTMaskSetMask(&ExtCurStyle->exts_subsDevTypes, &types1);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types1, t))
@ -2872,8 +2870,6 @@ ExtTechLine(sectionName, argc, argv)
}
TTMaskSetMask(&ExtCurStyle->exts_deviceMask, &types1);
if (!TTMaskIsZero(&subsTypes))
TTMaskSetMask(&ExtCurStyle->exts_subsDevTypes, &types1);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
{
@ -3590,6 +3586,39 @@ extTechFinalStyle(style)
int p, p1, missing, conflict;
int indicis[NP];
/* Collect list of all device types that have a substrate connection
* to substrate types, and all material types not in the substrate
* plane and which are not substrate shields that connect to the
* substrate.
*/
for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
{
ExtDevice *devptr;
if (TTMaskHasType(&ExtCurStyle->exts_subsDevTypes, r)) continue;
for (devptr = ExtCurStyle->exts_device[r]; devptr; devptr = devptr->exts_next)
{
if (TTMaskIntersect(&devptr->exts_deviceSubstrateTypes,
&ExtCurStyle->exts_globSubstrateTypes))
TTMaskSetType(&ExtCurStyle->exts_subsDevTypes, r);
}
}
if (ExtCurStyle->exts_globSubstratePlane >= 0)
{
for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
{
if ((TTMaskHasType(&ExtCurStyle->exts_globSubstrateTypes, r)) &&
(!TTMaskHasType(&ExtCurStyle->exts_globSubstrateShieldTypes, r))
&& (DBPlane(r) != ExtCurStyle->exts_globSubstratePlane))
TTMaskSetType(&ExtCurStyle->exts_subsDevTypes, r);
}
}
/* Prepare resistance classes */
for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
{
maskBits = style->exts_nodeConn[r];

View File

@ -139,7 +139,7 @@ extern void extHierConnections();
extern void extHierFreeLabels();
extern void extHierFreeOne();
extern void extHierFreeOne();
extern void extHierSubstrate();
extern int extHierSubstrate();
extern int extHierYankFunc();
extern bool extLabType();
extern void extLength();