Additional work to incorporate handling of split tiles throughout

the extraction, especially for routines like ExtFindNeighbors where
it was previously not handled at all.  A new method was introduced
in which split tiles with neither side TT_SPACE will get an extra
allocated structure that contains pointers to two regions representing
the nodes on the tile's left and right sides, independently.  The fix
(as yet not fully tested) should resolve problems with extracting the
sky130 I/O cells, which contain a FET with 45 degree angles on the
gate, where a split tile is divided between the gate and the source or
drain, and therefore represents two different nodes.  Also, there were
extraction errors related to incorrect handling of split tiles having
only one node, where a split tile became connected to the wrong node.
This commit is contained in:
R. Timothy Edwards 2026-01-09 11:58:35 -05:00
parent 1cb58e973a
commit 8bd01f5597
20 changed files with 858 additions and 1377 deletions

104
README
View File

@ -362,14 +362,108 @@ Need to test:
GDS input (passed)
extraction (pending) (fixed cap coupling issues)
net selection (seems okay)
antenna checks
LEF read
LEF write
DEF read
DEF write
antenna checks (okay)
LEF read (okay)
LEF write (okay)
DEF read*
DEF write*
extresist
(* knowing that there are some errors with DEF read/write that are unrelated)
"def write" appears to have taken an excessively large amount of memory. This is
probably not related to recent code changes but should be investigated. While the
design tested is large, it is not large to the tune of 32GB+, which seems to be
taken up entirely by defblockageVisit. This is unreasonable and must be fixed.
Tested extraction on sky130_fd_io__top_gpiov2_flat, which crashed immediately;
however, it is known that it has split tiles with different nodes and will
require split nodes to be handled properly. Make sure that's the issue, though.
No, actually it's extAddOverlap needing an extra argument.
----------------------------------
Running some of the I/O torture test from sky130 in ~/projects/efabless/sky130_fd_io/.
These tests are important because they are part of the reason for fixing the
nonmanhattan code, since the requirement of setting two regions per tile is needed
for several cells in this I/O set.
In lvs_tests/
First pass, running "run_top_sio.sh" resulted in magic hanging in DRCFindInteractions()
while extracting "sky130_fd_io__sio_ipath_com". Here, drcSubcellFunc() is getting
called alternately on uses sky130_fd_io__sio_com_m2m3_strap_5 and
sky130_fd_io__sio_com_m2m3_strap_6. Given the recent work aroudn DRCFindInteractions()
there is a good chance this has nothing to do with split tiles. (Confirmed)
Uh oh.
subUse = sky130_fd_io__sio_com_m2m3_strap_5
subUse->cu_bbox = 627, 3428 to 1485, 214751792 which sounds bogus.
subUse = sky130_fd_io__sio_com_m2m3_strap_6
subUse->cu_bbox = 1615, 3248 to 2473, 214641792 which is equally bogus.
But this appears to derive from the .mag files in the library.
Bogus entry is in the sky130_fd_io__sio_com_m2m3_strap.mag file:
"rect 164 319 214748364 321" on layer "comment".
Remove this entry and correct the "box" entries in "sky130_fd_io__sio_ipath_com" to
"0 0 364 858".
This requires a separate investigation. I have not compiled the sky130 PDK for a while.
There are some arrows drawn with comment that appear to have been mangled on GDS
input. They should probably be removed from the database. However, this suggests an
issue with GDS read-in.
There are multiple "strap" layouts, all of which have this issue. Need to recheck
the GDS read-in. Maybe just rebuild the sky130 PDK (using the previous version of
magic)? That seems to have corrected the issue, which might have been caused by
building the PDK with a bad version of magic. Doing "run_top_sio.sh" works now,
although with the same errors as it had historically (waiting for proper handling
of regions on split tiles).
The "run_top_sio.sh" script now runs with surprisingly few issues. Three metal1
resistors are missing and the grounds are not cleanly separated, and very little
else.
"top_pwrdetv2" had been a problem but now succeeds, which is pretty significant.
---------------
Split region handling:
Still need to fix boundary checks: extTransPerimFunc(), extSideLeft(), etc., etc.
Look for "(TileType)0" for places that need fixing.
Boundaries:
Should define directions for non-Manhattan tiles.
b_inside = b_outside, b_segment follows the diagonal.
Replace extUnInit with CLIENTDEFAULT and remove extUnInit as a global variable,
as that is ridiculous. (Done, along with associated stupidity extNbrUn and
also passing the value to ExtFindRegions().)
Need to understand these functions better. . .
For example, ignoring the coupling cap stuff for now,
extOutputDevices() scans transList,
sets tr_perim = 0
calls ExtFindNeighbors() from the region's tile (a tile belonging to the device)
arg.fra_each = extTransTileFunc.
Initial perimeter is 0. For each tile called back by ExtFindNeighbors,
call extEnumTilePerim() with function extTransPerimFunc().
Anything currently with (TileType)0 or which calls simply TiGetType() needs fixing:
extSideCommon(): Pass boundary and use extGetBoundaryTypes()
Okay, but this still does not account for everything that needs to be done when
checking coupling between non-Manhattan edges. But it should keep things from
crashing or producing stupid results.
Oh, no. fra_uninit is being used to process ExtFindNeighbors with a specific node
like the transistor gate being considered "uninitialized".
ExtNghbors.c:247 --- Need to handle separately; move "continue" down into each of
the conditionals (done)
ExtNghbors.c:137, 187 --- Set dinfo appropriately for top and bottom sides. (done)
(may complete the handling of ExtFindNeighbors() and also properly eliminate
extNbrUn as a global variable.)
Whew. Is that all? (Almost certainly not.) Yes, missed code at ExtBasic.c:5203
and below. (fixed)
Okay, it compiles again! Time to test again!

View File

@ -659,7 +659,7 @@ DBResetTilePlane(plane, cdata)
/* Each iteration visits another tile on the LHS of the search area */
while (TOP(tp) > rect->r_ybot)
{
/* Each iteration frees another tile */
/* Each iteration resets another tile */
enumerate:
tp->ti_client = cdata;
@ -695,6 +695,83 @@ enumerate:
}
}
/*
* --------------------------------------------------------------------
*
* DBResetTilePlaneSpecial --
*
* This routine works like DBResetTilePlane(), but is designed
* specifically to be run after extFindNodes() or ExtFindRegions()
* to check for split tiles that have an allocated ExtSplitRegion
* structure in the ClientData; this needs to be freed before
* resetting the ClientData value to "cdata". It is not necessary
* to know anything about the ExtSplitRegion structure other than
* the condition under which it can be expected to be present,
* which is a split tile with neither side having type TT_SPACE.
*
* Results:
* None.
*
* Side effects:
* Resets the ti_client fields of all tiles.
*
* --------------------------------------------------------------------
*/
void
DBResetTilePlaneSpecial(plane, cdata)
Plane *plane; /* Plane whose tiles are to be reset */
ClientData cdata;
{
Tile *tp, *tpnew;
const Rect *rect = &TiPlaneRect;
/* Start with the leftmost non-infinity tile in the plane */
tp = TR(plane->pl_left);
/* Each iteration visits another tile on the LHS of the search area */
while (TOP(tp) > rect->r_ybot)
{
/* Each iteration resets another tile */
enumerate:
if (IsSplit(tp))
if ((TiGetLeftType(tp) != TT_SPACE) && (TiGetRightType(tp) != TT_SPACE))
freeMagic(tp->ti_client);
tp->ti_client = cdata;
/* Move along to the next tile */
tpnew = TR(tp);
if (LEFT(tpnew) < rect->r_xtop)
{
while (BOTTOM(tpnew) >= rect->r_ytop) tpnew = LB(tpnew);
if (BOTTOM(tpnew) >= BOTTOM(tp) || BOTTOM(tp) <= rect->r_ybot)
{
tp = tpnew;
goto enumerate;
}
}
/* Each iteration returns one tile further to the left */
while (LEFT(tp) > rect->r_xbot)
{
if (BOTTOM(tp) <= rect->r_ybot)
return;
tpnew = LB(tp);
tp = BL(tp);
if (BOTTOM(tpnew) >= BOTTOM(tp) || BOTTOM(tp) <= rect->r_ybot)
{
tp = tpnew;
goto enumerate;
}
}
/* At left edge -- walk down to next tile along the left edge */
for (tp = LB(tp); RIGHT(tp) <= rect->r_xbot; tp = TR(tp))
/* Nothing */;
}
}
/*
* --------------------------------------------------------------------
*

View File

@ -978,6 +978,7 @@ extern int dbIsPrimary();
extern void dbTechMatchResidues();
extern void DBUndoInit();
extern void DBResetTilePlane();
extern void DBResetTilePlaneSpecial();
extern void DBNewYank();
extern int DBSrPaintClient();
extern int DBSrConnect();

View File

@ -1,113 +0,0 @@
ExtArray.o: ExtArray.c ../utils/magic.h ../utils/magic_assert.h \
../utils/magic_stdbool.h ../utils/geometry.h ../utils/geofast.h \
../tiles/tile.h ../utils/hash.h ../database/database.h ../utils/stack.h \
../bplane/bplane.h ../bplane/bpOpaque.h ../utils/ihash.h \
../bplane/bpEnum.h ../utils/utils.h ../utils/tech.h \
../bplane/bplaneInt.h ../database/arrayinfo.h ../utils/malloc.h \
../textio/textio.h ../utils/dqueue.h ../debug/debug.h \
../extract/extract.h ../extract/extractInt.h ../extract/extDebugInt.h \
../utils/signals.h ../utils/styles.h ../windows/windows.h \
../dbwind/dbwind.h ../textio/txcommands.h
ExtBasic.o: ExtBasic.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/magic_assert.h ../utils/magic_stdbool.h ../utils/geometry.h \
../utils/geofast.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../utils/stack.h ../bplane/bplane.h \
../bplane/bpOpaque.h ../utils/ihash.h ../bplane/bpEnum.h \
../utils/utils.h ../utils/tech.h ../bplane/bplaneInt.h \
../database/arrayinfo.h ../utils/malloc.h ../textio/textio.h \
../utils/dqueue.h ../debug/debug.h ../extract/extract.h \
../extract/extractInt.h ../extract/extDebugInt.h ../utils/signals.h \
../windows/windows.h ../dbwind/dbwind.h ../textio/txcommands.h \
../utils/styles.h
ExtCell.o: ExtCell.c ../utils/magic.h ../utils/magic_assert.h \
../utils/magic_stdbool.h ../utils/geometry.h ../utils/styles.h \
../tiles/tile.h ../utils/hash.h ../database/database.h ../utils/stack.h \
../bplane/bplane.h ../bplane/bpOpaque.h ../utils/ihash.h \
../bplane/bpEnum.h ../utils/utils.h ../utils/tech.h ../utils/geofast.h \
../bplane/bplaneInt.h ../database/arrayinfo.h ../utils/malloc.h \
../textio/textio.h ../utils/dqueue.h ../debug/debug.h \
../extract/extract.h ../extract/extractInt.h ../extract/extDebugInt.h \
../utils/signals.h ../windows/windows.h ../utils/main.h ../utils/undo.h
ExtCouple.o: ExtCouple.c ../utils/magic.h ../utils/magic_assert.h \
../utils/magic_stdbool.h ../utils/geometry.h ../utils/geofast.h \
../tiles/tile.h ../utils/hash.h ../database/database.h ../utils/stack.h \
../bplane/bplane.h ../bplane/bpOpaque.h ../utils/ihash.h \
../bplane/bpEnum.h ../utils/utils.h ../utils/tech.h \
../bplane/bplaneInt.h ../database/arrayinfo.h ../extract/extract.h \
../extract/extractInt.h ../extract/extDebugInt.h ../textio/textio.h \
../utils/dqueue.h
ExtHard.o: ExtHard.c ../utils/magic.h ../utils/magic_assert.h \
../utils/magic_stdbool.h ../utils/geometry.h ../tiles/tile.h \
../utils/hash.h ../database/database.h ../utils/stack.h \
../bplane/bplane.h ../bplane/bpOpaque.h ../utils/ihash.h \
../bplane/bpEnum.h ../utils/utils.h ../utils/tech.h ../utils/geofast.h \
../bplane/bplaneInt.h ../database/arrayinfo.h ../utils/malloc.h \
../textio/textio.h ../utils/dqueue.h ../utils/styles.h ../debug/debug.h \
../extract/extract.h ../extract/extractInt.h ../extract/extDebugInt.h
ExtHier.o: ExtHier.c ../utils/magic.h ../utils/magic_assert.h \
../utils/magic_stdbool.h ../utils/geometry.h ../utils/geofast.h \
../tiles/tile.h ../utils/hash.h ../database/database.h ../utils/stack.h \
../bplane/bplane.h ../bplane/bpOpaque.h ../utils/ihash.h \
../bplane/bpEnum.h ../utils/utils.h ../utils/tech.h \
../bplane/bplaneInt.h ../database/arrayinfo.h ../utils/malloc.h \
../textio/textio.h ../utils/dqueue.h ../utils/styles.h \
../windows/windows.h ../dbwind/dbwind.h ../textio/txcommands.h \
../debug/debug.h ../extract/extract.h ../extract/extractInt.h \
../extract/extDebugInt.h
ExtLength.o: ExtLength.c ../utils/magic.h ../utils/magic_assert.h \
../utils/magic_stdbool.h ../utils/geometry.h ../utils/geofast.h \
../tiles/tile.h ../utils/hash.h ../database/database.h ../utils/stack.h \
../bplane/bplane.h ../bplane/bpOpaque.h ../utils/ihash.h \
../bplane/bpEnum.h ../utils/utils.h ../utils/tech.h \
../bplane/bplaneInt.h ../database/arrayinfo.h ../utils/malloc.h \
../textio/textio.h ../utils/dqueue.h ../debug/debug.h \
../extract/extract.h ../extract/extractInt.h ../extract/extDebugInt.h \
../utils/signals.h ../windows/windows.h ../dbwind/dbwind.h \
../textio/txcommands.h ../select/select.h ../utils/styles.h \
../utils/main.h
ExtMain.o: ExtMain.c ../utils/magic.h ../utils/magic_assert.h \
../utils/magic_stdbool.h ../utils/geometry.h ../utils/styles.h \
../tiles/tile.h ../utils/hash.h ../database/database.h ../utils/stack.h \
../bplane/bplane.h ../bplane/bpOpaque.h ../utils/ihash.h \
../bplane/bpEnum.h ../utils/utils.h ../utils/tech.h ../utils/geofast.h \
../bplane/bplaneInt.h ../database/arrayinfo.h ../utils/malloc.h \
../textio/textio.h ../utils/dqueue.h ../debug/debug.h \
../extract/extract.h ../extract/extractInt.h ../extract/extDebugInt.h \
../utils/signals.h ../windows/windows.h ../dbwind/dbwind.h \
../textio/txcommands.h ../utils/main.h ../utils/undo.h
ExtNghbors.o: ExtNghbors.c ../utils/magic.h ../utils/magic_assert.h \
../utils/magic_stdbool.h ../utils/geometry.h ../utils/geofast.h \
../tiles/tile.h ../utils/hash.h ../database/database.h ../utils/stack.h \
../bplane/bplane.h ../bplane/bpOpaque.h ../utils/ihash.h \
../bplane/bpEnum.h ../utils/utils.h ../utils/tech.h \
../bplane/bplaneInt.h ../database/arrayinfo.h ../utils/malloc.h \
../debug/debug.h ../extract/extract.h ../extract/extractInt.h \
../extract/extDebugInt.h ../utils/signals.h
ExtPerim.o: ExtPerim.c ../utils/magic.h ../utils/magic_assert.h \
../utils/magic_stdbool.h ../utils/geometry.h ../tiles/tile.h \
../utils/hash.h ../database/database.h ../utils/stack.h \
../bplane/bplane.h ../bplane/bpOpaque.h ../utils/ihash.h \
../bplane/bpEnum.h ../utils/utils.h ../utils/tech.h ../utils/geofast.h \
../bplane/bplaneInt.h ../database/arrayinfo.h ../utils/malloc.h \
../debug/debug.h ../extract/extract.h ../extract/extractInt.h \
../extract/extDebugInt.h
ExtRegion.o: ExtRegion.c ../utils/magic.h ../utils/magic_assert.h \
../utils/magic_stdbool.h ../utils/geometry.h ../tiles/tile.h \
../utils/hash.h ../database/database.h ../utils/stack.h \
../bplane/bplane.h ../bplane/bpOpaque.h ../utils/ihash.h \
../bplane/bpEnum.h ../utils/utils.h ../utils/tech.h ../utils/geofast.h \
../bplane/bplaneInt.h ../database/arrayinfo.h ../utils/malloc.h \
../textio/textio.h ../utils/dqueue.h ../debug/debug.h \
../extract/extract.h ../extract/extractInt.h ../extract/extDebugInt.h \
../utils/signals.h
ExtSubtree.o: ExtSubtree.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/magic_assert.h ../utils/magic_stdbool.h ../utils/geometry.h \
../utils/geofast.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../utils/stack.h ../bplane/bplane.h \
../bplane/bpOpaque.h ../utils/ihash.h ../bplane/bpEnum.h \
../utils/utils.h ../utils/tech.h ../bplane/bplaneInt.h \
../database/arrayinfo.h ../utils/malloc.h ../textio/textio.h \
../utils/dqueue.h ../debug/debug.h ../extract/extract.h \
../extract/extractInt.h ../extract/extDebugInt.h ../graphics/graphics.h \
../utils/signals.h ../windows/windows.h ../dbwind/dbwind.h \
../textio/txcommands.h ../utils/styles.h ../drc/drc.h

View File

@ -716,11 +716,11 @@ extArrayNodeName(np, ha, et1, et2)
TileType dinfo;
tp = extNodeToTile(np, et1, &dinfo);
if (tp && TiGetType(tp) != TT_SPACE && extHasRegion(tp, extUnInit))
if (tp && TiGetType(tp) != TT_SPACE && extHasRegion(tp, CLIENTDEFAULT))
return (extArrayTileToNode(tp, dinfo, np->nreg_pnum, et1, ha, TRUE));
tp = extNodeToTile(np, et2, &dinfo);
if (tp && TiGetType(tp) != TT_SPACE && extHasRegion(tp, extUnInit))
if (tp && TiGetType(tp) != TT_SPACE && extHasRegion(tp, CLIENTDEFAULT))
return (extArrayTileToNode(tp, dinfo, np->nreg_pnum, et2, ha, TRUE));
return ("(none)");
@ -793,9 +793,9 @@ extArrayTileToNode(tp, dinfo, pNum, et, ha, doHard)
LabRegion *reg;
Rect r;
if (extHasRegion(tp, extUnInit))
if (extHasRegion(tp, CLIENTDEFAULT))
{
reg = (LabRegion *) extGetRegion(tp);
reg = (LabRegion *) ExtGetRegion(tp, dinfo);
if (reg->lreg_labels)
goto found;
}
@ -979,7 +979,7 @@ extArrayHardNode(tp, dinfo, pNum, def, ha)
LabRegion *lreg;
LabelList *ll;
lreg = (LabRegion *) extGetRegion(tp);
lreg = (LabRegion *) ExtGetRegion(tp, dinfo);
ll = (LabelList *) mallocMagic((unsigned) (sizeof (LabelList)));
lreg->lreg_labels = ll;
ll->ll_next = (LabelList *) NULL;

View File

@ -232,8 +232,8 @@ extBasic(def, outFile)
transList = (TransRegion *) ExtFindRegions(def, &TiPlaneRect,
&ExtCurStyle->exts_deviceMask,
ExtCurStyle->exts_deviceConn,
extUnInit, extTransFirst, extTransEach);
ExtResetTiles(def, extUnInit);
extTransFirst, extTransEach);
ExtResetTiles(def, CLIENTDEFAULT);
for (reg = transList; reg && !SigInterruptPending; reg = reg->treg_next)
{
@ -2197,7 +2197,7 @@ extOutputDevices(def, transList, outFile)
*
* Algorithm: first visit all tiles in the transistor, marking
* them with 'reg', then visit them again re-marking them with
* the gate node (extGetRegion(reg->treg_tile)).
* the gate node (ExtGetRegion(reg->treg_tile, reg->treg_type)).
*/
extTransRec.tr_devrec = (ExtDevice *)NULL;
extTransRec.tr_devmatch = 0;
@ -2224,7 +2224,7 @@ extOutputDevices(def, transList, outFile)
arg.fra_def = def;
arg.fra_connectsTo = ExtCurStyle->exts_deviceConn;
extTransRec.tr_gatenode = (NodeRegion *) extGetRegion(reg->treg_tile);
extTransRec.tr_gatenode = (NodeRegion *) ExtGetRegion(reg->treg_tile, reg->treg_type);
t = reg->treg_type & TT_LEFTMASK;
arg.fra_pNum = DBPlane(t);
@ -2518,7 +2518,7 @@ extOutputDevices(def, transList, outFile)
/* are shorted. */
/* gate */
node = (NodeRegion *)extGetRegion(reg->treg_tile);
node = (NodeRegion *)ExtGetRegion(reg->treg_tile, reg->treg_type);
fprintf(outFile, "\"%s\" ", extNodeName((LabRegion *)node));
/* First non-gate terminal */
@ -3076,7 +3076,7 @@ extOutputDevices(def, transList, outFile)
}
/* gate */
node = (NodeRegion *) extGetRegion(reg->treg_tile);
node = (NodeRegion *) ExtGetRegion(reg->treg_tile, reg->treg_type);
ll = node->nreg_labels;
extTransOutTerminal((LabRegion *) node, ll, LL_GATEATTR,
extTransRec.tr_gatelen, 0, 0, 0, outFile);
@ -3173,10 +3173,10 @@ extTransFindSubsFunc1(tile, dinfo, noderecptr)
* regions under the same device)
*/
ClientData ticlient = TiGetClient(tile);
if (ticlient != extUnInit)
ExtRegion *tireg = ExtGetRegion(tile, dinfo);
if ((ClientData)tireg != CLIENTDEFAULT)
{
NodeRegion *reg = (NodeRegion *) CD2PTR(ticlient);
NodeRegion *reg = (NodeRegion *) CD2PTR(tireg);
if ((noderecptr->region != (NodeRegion *)NULL) &&
(noderecptr->region != reg))
TxError("Warning: Split substrate under device at (%d %d)\n",
@ -3376,10 +3376,7 @@ extTransTileFunc(tile, dinfo, pNum, arg)
* that borders on something of a different type.
*/
if (IsSplit(tile))
{
loctype = (dinfo & TT_SIDE) ? SplitRightType(tile): SplitLeftType(tile);
// return (0); /* Hack alert! We must properly handle diagonals! */
}
else
loctype = TiGetTypeExact(tile);
@ -3702,9 +3699,9 @@ int
extTransPerimFunc(bp)
Boundary *bp;
{
TileType tinside, toutside;
TileType tinside, toutside, dinfo;
Tile *tile;
NodeRegion *diffNode = (NodeRegion *) extGetRegion(bp->b_outside);
NodeRegion *termNode;
ExtDevice *devptr, *deventry;
int i, area, perim, len = BoundaryLength(bp);
int thisterm;
@ -3739,6 +3736,7 @@ extTransPerimFunc(bp)
}
else
tinside = TiGetTypeExact(bp->b_inside);
tile = bp->b_outside;
if (IsSplit(tile))
{
@ -3746,20 +3744,30 @@ extTransPerimFunc(bp)
{
case BD_LEFT:
toutside = TiGetRightType(tile);
dinfo = (TileType)TT_SIDE;
break;
case BD_TOP:
toutside = TiGetBottomType(tile);
dinfo = (TiGetTypeExact(tile) & TT_DIRECTION) ?
(TileType)0 : (TileType)TT_SIDE;
break;
case BD_RIGHT:
toutside = TiGetLeftType(tile);
dinfo = (TileType)0;
break;
case BD_BOTTOM:
toutside = TiGetTopType(tile);
dinfo = (TiGetTypeExact(tile) & TT_DIRECTION) ?
(TileType)TT_SIDE : (TileType)0;
break;
}
termNode = (NodeRegion *) ExtGetRegion(tile, dinfo);
}
else
{
toutside = TiGetTypeExact(bp->b_outside);
termNode = (NodeRegion *) ExtGetRegion(tile, (TileType)0);
}
if (extTransRec.tr_devrec != NULL)
devptr = extTransRec.tr_devrec;
@ -3789,7 +3797,7 @@ extTransPerimFunc(bp)
if (TTMaskIsZero(&devptr->exts_deviceSDTypes[1]))
{
for (thisterm = 0; thisterm < extTransRec.tr_nterm; thisterm++)
if (extTransRec.tr_termnode[thisterm] == diffNode)
if (extTransRec.tr_termnode[thisterm] == termNode)
break;
}
else
@ -3798,7 +3806,7 @@ extTransPerimFunc(bp)
if (extTransRec.tr_termnode[thisterm] == NULL)
{
extTransRec.tr_nterm++;
extTransRec.tr_termnode[thisterm] = diffNode;
extTransRec.tr_termnode[thisterm] = termNode;
extTransRec.tr_termlen[thisterm] = 0;
extTransRec.tr_termarea[thisterm] = 0;
extTransRec.tr_termperim[thisterm] = 0;
@ -3810,19 +3818,19 @@ extTransPerimFunc(bp)
/* Find the total area of this terminal */
}
else if (extTransRec.tr_termnode[thisterm] == diffNode)
else if (extTransRec.tr_termnode[thisterm] == termNode)
{
TermTilePos *pos = &(extTransRec.tr_termpos[thisterm]);
Tile *otile = bp->b_outside;
/* update the region tile position */
if (DBPlane(TiGetType(otile)) < pos->pnum)
if (DBPlane(toutside) < pos->pnum)
{
pos->pnum = DBPlane(TiGetType(otile));
pos->pnum = DBPlane(toutside);
pos->pt = otile->ti_ll;
}
else if (DBPlane(TiGetType(otile)) == pos->pnum)
else if (DBPlane(toutside) == pos->pnum)
{
if (LEFT(otile) < pos->pt.p_x)
pos->pt = otile->ti_ll;
@ -3855,13 +3863,10 @@ extTransPerimFunc(bp)
eapd.eapd_area = eapd.eapd_perim = 0;
TTMaskCom2(&eapd.eapd_mask, &DBConnectTbl[toutside]);
eapd.eapd_gatemask = &ExtCurStyle->exts_deviceMask;
eapd.eapd_gatenode = (NodeRegion *)extGetRegion(bp->b_inside);
eapd.eapd_gatenode = extTransRec.tr_gatenode;
eapd.eapd_shared = NULL;
/* Fix me: Set dinfo based on split tile and boundary
* direction.
*/
DBSrConnectOnePlane(bp->b_outside, (TileType)0, DBConnectTbl,
DBSrConnectOnePlane(bp->b_outside, dinfo, DBConnectTbl,
extTermAPFunc, (ClientData)&eapd);
shared = 1;
@ -3973,7 +3978,7 @@ extTransPerimFunc(bp)
/* 8/30/2022: The code at line 681 can reassign a transistor */
/* gate node off of the device plane, so the original plane of */
/* the gate node is saved in extTransRec.tr_plane and used here. */
/* Do *not* user extTransRec.tr_gatenode->nreg_pnum! */
/* Do *not* use extTransRec.tr_gatenode->nreg_pnum! */
if ((!DBIsContact(toutside) && !DBIsContact(tinside)) ||
(bp->b_plane == extTransRec.tr_plane))
@ -4104,7 +4109,7 @@ extSpecialPerimFunc(bp, sense)
bool sense;
{
TileType tinside, toutside;
NodeRegion *diffNode = (NodeRegion *) extGetRegion(bp->b_outside);
NodeRegion *termNode = (NodeRegion *) ExtGetRegion(bp->b_outside, (TileType)0);
int thisterm, extended, i;
LinkedBoundary *newBound, *lb, *lastlb;
ExtDevice *devptr;
@ -4155,7 +4160,7 @@ extSpecialPerimFunc(bp, sense)
{
if (toutside == TT_SPACE)
if (glob_subsnode != NULL)
diffNode = glob_subsnode;
termNode = glob_subsnode;
}
/* Check for terminal on different plane than the device */
@ -4172,7 +4177,7 @@ extSpecialPerimFunc(bp, sense)
if (!PlaneMaskHasPlane(pmask, DBPlane(tinside)))
{
diffNode = extTransRec.tr_termnode[i];
termNode = extTransRec.tr_termnode[i];
needSurvey = TRUE;
break;
}
@ -4189,7 +4194,7 @@ extSpecialPerimFunc(bp, sense)
else
{
for (thisterm = 0; thisterm < extTransRec.tr_nterm; thisterm++)
if (extTransRec.tr_termnode[thisterm] == diffNode)
if (extTransRec.tr_termnode[thisterm] == termNode)
break;
if (thisterm >= extTransRec.tr_nterm)
{
@ -4444,6 +4449,117 @@ extLabType(text, typeMask)
/*NOTREACHED*/
}
/*
* ----------------------------------------------------------------------------
*
* ExtSetRegion --
*
* Sets the client pointer for a tile to the given ExtRegion pointer.
* In the usual case, this just sets TiSetClientPTR(). However, if
* it is a split tile, then if neither side of the split tile is
* TT_SPACE, the tile ClientData will be given an allocated
* ExtSplitRegion structure containing two region pointers, one for
* the left side, and one for the right side.
*
* Results:
* None.
*
* Side effects:
* A tile's ClientData is modified. In the case of a split tile, an
* additional structure is allocated.
*
* ----------------------------------------------------------------------------
*/
void
ExtSetRegion(Tile *tile,
TileType dinfo,
ExtRegion *reg)
{
ExtSplitRegion *csr;
ClientData clientdata = TiGetClient(tile);
if ((ExtRegion *)CD2PTR(clientdata) == reg) return;
if (IsSplit(tile))
{
if ((TiGetLeftType(tile) != TT_SPACE) && (TiGetRightType(tile) != TT_SPACE))
{
/* Tile is a split tile with something that is not space on both sides */
if (clientdata == CLIENTDEFAULT)
{
/* First time visit: tile requires an ExtSplitRegion structure */
csr = (ExtSplitRegion *)mallocMagic(sizeof(ExtSplitRegion));
TiSetClientPTR(tile, csr);
csr->reg_right = CLIENTDEFAULT;
csr->reg_left = CLIENTDEFAULT;
}
else
csr = (ExtSplitRegion *)CD2PTR(clientdata);
/* Set the region for the specified side of the tile */
if (dinfo & TT_SIDE)
csr->reg_right = reg;
else
csr->reg_left = reg;
return;
}
}
/* In all other cases, just set the ClientData of the tile to "reg" */
TiSetClientPTR(tile, reg);
}
/*
* ----------------------------------------------------------------------------
*
* ExtResetRegion --
*
* Resets the client pointer for a tile back to CLIENTDEFAULT.
* In the case of a split tile with two regions, the region for the
* side of the tile specified by the TT_SIDE bit in "dinfo" will be
* set to CLIENTDEFAULT. If both sides have CLIENTDEFAULT, then the split
* region structure is deallocated and the tile's ClientData is set
* to CLIENTDEFAULT.
*
* Results:
* None.
*
* Side effects:
* A tile's ClientData is modified. In the case of a split tile, an
* additional structure is allocated.
*
* ----------------------------------------------------------------------------
*/
void
ExtResetRegion(Tile *tile,
TileType dinfo)
{
if (IsSplit(tile))
{
if ((TiGetLeftType(tile) != TT_SPACE) && (TiGetRightType(tile) != TT_SPACE))
{
/* Tile is a split tile with something that is not space on both sides */
ExtSplitRegion *esr;
if (TiGetClient(tile) == CLIENTDEFAULT) return;
esr = (ExtSplitRegion *)TiGetClientPTR(tile);
if (dinfo & TT_SIDE)
esr->reg_right = CLIENTDEFAULT;
else
esr->reg_left = CLIENTDEFAULT;
if ((esr->reg_right == CLIENTDEFAULT) && (esr->reg_left == CLIENTDEFAULT))
freeMagic((char *)esr);
else
return;
}
}
/* In all other cases, just set the ClientData of the tile to value CLIENTDEFAULT */
TiSetClient(tile, CLIENTDEFAULT);
}
/*
* ----------------------------------------------------------------------------
@ -4749,7 +4865,7 @@ extFindNodes(def, clipArea, subonly)
{
arg.fra_pNum = pNum;
DBSrPaintClient((Tile *) NULL, def->cd_planes[pNum],
&TiPlaneRect, &subsTypesNonSpace, extUnInit,
&TiPlaneRect, &subsTypesNonSpace, CLIENTDEFAULT,
extSubsFunc, (ClientData) &arg);
}
@ -4764,11 +4880,11 @@ extFindNodes(def, clipArea, subonly)
arg.fra_pNum = pNum;
if (space_is_substrate)
DBSrPaintClient((Tile *) NULL, def->cd_planes[pNum],
&TiPlaneRect, &subsTypesNonSpace, extUnInit,
&TiPlaneRect, &subsTypesNonSpace, CLIENTDEFAULT,
extSubsFunc2, (ClientData) &arg);
else
DBSrPaintClient((Tile *) NULL, def->cd_planes[pNum],
&TiPlaneRect, &subsTypesNonSpace, extUnInit,
&TiPlaneRect, &subsTypesNonSpace, CLIENTDEFAULT,
extSubsFunc, (ClientData) &arg);
}
}
@ -4811,7 +4927,7 @@ extFindNodes(def, clipArea, subonly)
arg.fra_pNum = pNum;
(void) DBSrPaintClient((Tile *) NULL, def->cd_planes[pNum],
&TiPlaneRect, &ExtCurStyle->exts_activeTypes,
extUnInit, extNodeAreaFunc, (ClientData) &arg);
CLIENTDEFAULT, extNodeAreaFunc, (ClientData) &arg);
}
SigEnableInterrupts();
@ -4971,7 +5087,7 @@ extNodeAreaFunc(tile, dinfo, arg)
*/
if (TiGetClientPTR(tile) == reg)
continue;
TiSetClientPTR(tile, reg);
ExtSetRegion(tile, dinfo, (ExtRegion *)reg);
if (DebugIsSet(extDebugID, extDebNeighbor))
extShowTile(tile, "neighbor", 1);
@ -5064,6 +5180,17 @@ topside:
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
{
ExtRegion *tireg;
TileType tpdinfo;
if (IsSplit(tp))
{
tpdinfo = (SplitDirection(tp)) ? (TileType)0 : (TileType)TT_SIDE;
tireg = ExtGetRegion(tp, tpdinfo);
}
else
tireg = ExtGetRegion(tp, (TileType)0);
if (extNodeClipArea)
{
r.r_ybot = r.r_ytop = TOP(tile);
@ -5073,25 +5200,24 @@ topside:
len = EDGENULL(&r) ? 0 : r.r_xtop - r.r_xbot;
}
else len = MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp));
ClientData ticlient = TiGetClient(tp);
if (IsSplit(tp))
{
t = SplitBottomType(tp);
if (ticlient == extUnInit && TTMaskHasType(mask, t))
if ((ClientData)tireg == CLIENTDEFAULT && TTMaskHasType(mask, t))
{
PUSHTILEBOTTOM(tp, tilePlaneNum);
}
else if ((NodeRegion *)CD2PTR(ticlient) != reg && TTMaskHasType(mask, t))
else if ((NodeRegion *)tireg != reg && TTMaskHasType(mask, t))
{
/* Count split tile twice, once for each node it belongs to. */
TiSetClient(tp, extUnInit);
ExtResetRegion(tp, tpdinfo);
PUSHTILEBOTTOM(tp, tilePlaneNum);
}
}
else
{
t = TiGetTypeExact(tp);
if (ticlient == extUnInit && TTMaskHasType(mask, t))
if ((ClientData)tireg == CLIENTDEFAULT && TTMaskHasType(mask, t))
{
PUSHTILE(tp, (TileType)0, tilePlaneNum);
}
@ -5110,6 +5236,17 @@ leftside:
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
{
ExtRegion *tireg;
TileType tpdinfo;
if (IsSplit(tp))
{
tpdinfo = (TileType)TT_SIDE;
tireg = ExtGetRegion(tp, tpdinfo);
}
else
tireg = ExtGetRegion(tp, (TileType)0);
if (extNodeClipArea)
{
r.r_xbot = r.r_xtop = LEFT(tile);
@ -5119,25 +5256,24 @@ leftside:
len = EDGENULL(&r) ? 0 : r.r_ytop - r.r_ybot;
}
else len = MIN(TOP(tile), TOP(tp)) - MAX(BOTTOM(tile), BOTTOM(tp));
ClientData ticlient = TiGetClient(tp);
if (IsSplit(tp))
{
t = SplitRightType(tp);
if (ticlient == extUnInit && TTMaskHasType(mask, t))
if ((ClientData)tireg == CLIENTDEFAULT && TTMaskHasType(mask, t))
{
PUSHTILERIGHT(tp, tilePlaneNum);
}
else if ((NodeRegion *)CD2PTR(ticlient) != reg && TTMaskHasType(mask, t))
else if ((NodeRegion *)tireg != reg && TTMaskHasType(mask, t))
{
/* Count split tile twice, once for each node it belongs to. */
TiSetClient(tp, extUnInit);
ExtResetRegion(tp, tpdinfo);
PUSHTILERIGHT(tp, tilePlaneNum);
}
}
else
{
t = TiGetTypeExact(tp);
if (ticlient == extUnInit && TTMaskHasType(mask, t))
if ((ClientData)tireg == CLIENTDEFAULT && TTMaskHasType(mask, t))
{
PUSHTILE(tp, (TileType)0, tilePlaneNum);
}
@ -5157,6 +5293,17 @@ bottomside:
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp))
{
ExtRegion *tireg;
TileType tpdinfo;
if (IsSplit(tp))
{
tpdinfo = (SplitDirection(tp)) ? (TileType)TT_SIDE : (TileType)0;
tireg = ExtGetRegion(tp, tpdinfo);
}
else
tireg = ExtGetRegion(tp, (TileType)0);
if (extNodeClipArea)
{
r.r_ybot = r.r_ytop = BOTTOM(tile);
@ -5166,25 +5313,24 @@ bottomside:
len = EDGENULL(&r) ? 0 : r.r_xtop - r.r_xbot;
}
else len = MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp));
ClientData ticlient = TiGetClient(tp);
if (IsSplit(tp))
{
t = SplitTopType(tp);
if (ticlient == extUnInit && TTMaskHasType(mask, t))
if ((ClientData)tireg == CLIENTDEFAULT && TTMaskHasType(mask, t))
{
PUSHTILETOP(tp, tilePlaneNum);
}
else if ((NodeRegion *)CD2PTR(ticlient) != reg && TTMaskHasType(mask, t))
else if ((NodeRegion *)tireg != reg && TTMaskHasType(mask, t))
{
/* Count split tile twice, once for each node it belongs to. */
TiSetClient(tp, extUnInit);
ExtResetRegion(tp, tpdinfo);
PUSHTILETOP(tp, tilePlaneNum);
}
}
else
{
t = TiGetTypeExact(tp);
if (ticlient == extUnInit && TTMaskHasType(mask, t))
if ((ClientData)tireg == CLIENTDEFAULT && TTMaskHasType(mask, t))
{
PUSHTILE(tp, (TileType)0, tilePlaneNum);
}
@ -5203,6 +5349,17 @@ rightside:
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
{
ExtRegion *tireg;
TileType tpdinfo;
if (IsSplit(tp))
{
tpdinfo = (TileType)0;
tireg = ExtGetRegion(tp, tpdinfo);
}
else
tireg = ExtGetRegion(tp, (TileType)0);
if (extNodeClipArea)
{
r.r_xbot = r.r_xtop = RIGHT(tile);
@ -5212,25 +5369,24 @@ rightside:
len = EDGENULL(&r) ? 0 : r.r_ytop - r.r_ybot;
}
else len = MIN(TOP(tile), TOP(tp)) - MAX(BOTTOM(tile), BOTTOM(tp));
ClientData ticlient = TiGetClient(tp);
if (IsSplit(tp))
{
t = SplitLeftType(tp);
if (ticlient == extUnInit && TTMaskHasType(mask, t))
if ((ClientData)tireg == CLIENTDEFAULT && TTMaskHasType(mask, t))
{
PUSHTILELEFT(tp, tilePlaneNum);
}
else if ((NodeRegion *)CD2PTR(ticlient) != reg && TTMaskHasType(mask, t))
else if ((NodeRegion *)tireg != reg && TTMaskHasType(mask, t))
{
/* Count split tile twice, once for each node it belongs to */
TiSetClient(tp, extUnInit);
ExtResetRegion(tp, tpdinfo);
PUSHTILELEFT(tp, tilePlaneNum);
}
}
else
{
t = TiGetTypeExact(tp);
if (ticlient == extUnInit && TTMaskHasType(mask, t))
if ((ClientData)tireg == CLIENTDEFAULT && TTMaskHasType(mask, t))
{
PUSHTILE(tp, (TileType)0, tilePlaneNum);
}
@ -5261,7 +5417,7 @@ donesides:
GOTOPOINT(tp, &tile->ti_ll);
PlaneSetHint(plane, tp);
if (TiGetClient(tp) != extUnInit) continue;
if (TiGetClient(tp) != CLIENTDEFAULT) continue;
/* tp and tile should have the same geometry for a contact */
if (IsSplit(tile) && IsSplit(tp))
@ -5322,7 +5478,7 @@ donesides:
Rect biggerArea;
bool is_split = IsSplit(tile);
extNbrUn = extUnInit;
extNbrUn = CLIENTDEFAULT;
TITORECT(tile, &pla.area);
GEO_EXPAND(&pla.area, 1, &biggerArea);
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)

View File

@ -46,15 +46,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "utils/main.h"
#include "utils/undo.h"
/* --------------------------- Global data ---------------------------- */
/*
* Value normally present in ti_client to indicate tiles that have not
* been marked with their associated region.
*/
ClientData extUnInit = (ClientData) CLIENTDEFAULT;
/* ------------------------ Data local to this file ------------------- */
/* Forward declarations */
@ -517,7 +508,7 @@ extCellFile(def, f, doLength)
/* Clean up from basic extraction */
if (reg) ExtFreeLabRegions((LabRegion *) reg);
ExtResetTiles(def, extUnInit);
ExtResetTiles(def, CLIENTDEFAULT);
/* Final pass: extract length information if desired */
if (!SigInterruptPending && doLength && (ExtOptions & EXT_DOLENGTH))

View File

@ -67,6 +67,7 @@ typedef struct _ecs {
typedef struct _ecpls {
Tile *tile;
TileType dinfo;
int plane_of_tile;
int plane_checked;
} extCoupleStruct;
@ -345,6 +346,7 @@ extBasicOverlap(tile, dinfo, ecs)
}
ecpls.tile = tile;
ecpls.dinfo = dinfo;
ecpls.plane_of_tile = thisPlane;
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
@ -432,8 +434,8 @@ extAddOverlap(tbelow, dinfo, ecpls)
/* subtract off any substrate (area) capacitance previously added */
/* (Correction made 4/29/04 by Tim from a tip by Jeff Sondeen). */
rabove = (NodeRegion *) extGetRegion(tabove);
rbelow = (NodeRegion *) extGetRegion(tbelow);
rabove = (NodeRegion *) ExtGetRegion(tabove, ecpls->dinfo);
rbelow = (NodeRegion *) ExtGetRegion(tbelow, dinfo);
/* Quick check on validity of tile's ti_client record */
if (rbelow == (NodeRegion *)CLIENTDEFAULT) return 0;
@ -450,8 +452,16 @@ extAddOverlap(tbelow, dinfo, ecpls)
}
ov.o_area = (ov.o_clip.r_ytop - ov.o_clip.r_ybot)
* (ov.o_clip.r_xtop - ov.o_clip.r_xbot);
ta = TiGetType(tabove);
tb = TiGetType(tbelow);
if (IsSplit(tabove))
ta = (ecpls->dinfo & TT_SIDE) ? TiGetRightType(tabove) : TiGetLeftType(tabove);
else
ta = TiGetTypeExact(tabove);
if (IsSplit(tbelow))
tb = (dinfo & TT_SIDE) ? TiGetRightType(tbelow) : TiGetLeftType(tbelow);
else
tb = TiGetTypeExact(tbelow);
/* Revert any contacts to their residues */
@ -570,6 +580,7 @@ extSubtractOverlap2(tile, dinfo, ov)
TileType dinfo; /* (unused) */
struct overlap *ov;
{
TileType ttype;
struct overlap ovnew;
int area, pNum;
Rect r;
@ -579,10 +590,16 @@ extSubtractOverlap2(tile, dinfo, ov)
area = (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot);
if (area <= 0)
return (0);
if (IsSplit(tile)) area /= 2;
if (IsSplit(tile))
{
area /= 2;
ttype = (dinfo & TT_SIDE) ? TiGetRightType(tile) : TiGetLeftType(tile);
}
else
ttype = TiGetTypeExact(tile);
/* This tile shields everything below */
if (TTMaskHasType(&ov->o_tmask, TiGetType(tile)))
if (TTMaskHasType(&ov->o_tmask, ttype))
{
ov->o_area -= area;
return (0);
@ -716,8 +733,8 @@ extSubtractSideOverlap2(tile, dinfo, sov)
TITORECT(tile, &r);
GEOCLIP(&r, &sov->so_clip);
area = (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot);
if (area <= 0)
return (0);
if (area <= 0) return (0);
if (IsSplit(tile)) area /= 2;
/* This tile shields everything below */
if (TTMaskHasType(&sov->so_tmask, ttype))
@ -783,11 +800,245 @@ extBasicCouple(tile, dinfo, ecs)
TileType dinfo;
extCapStruct *ecs;
{
(void) extEnumTilePerim(tile, dinfo, &ExtCurStyle->exts_sideEdges[TiGetType(tile)],
TileType ttype;
if (IsSplit(tile))
ttype = (dinfo & TT_SIDE) ? TiGetRightType(tile) : TiGetLeftType(tile);
else
ttype = TiGetTypeExact(tile);
(void) extEnumTilePerim(tile, dinfo, &ExtCurStyle->exts_sideEdges[ttype],
ecs->plane, extAddCouple, (ClientData) ecs);
return (0);
}
/*
* ----------------------------------------------------------------------------
*
* extGetBoundaryTypes ---
*
* Return the tile types of the boundary inside and outside type in the
* argument pointers. The routine takes care of deciding if either side
* of the boundary is a split tile, and choosing the correct type based
* on the direction of the boundary.
*
* Result:
* None.
*
* Side effects:
* The tile types are passed by pointer reference in the arguments.
*
* ----------------------------------------------------------------------------
*/
void
extGetBoundaryTypes(Boundary *bp,
TileType *tin,
TileType *tout)
{
TileType loctin, loctout;
if (IsSplit(bp->b_inside))
{
switch (bp->b_direction)
{
case BD_LEFT:
loctin = TiGetLeftType(bp->b_inside);
break;
case BD_RIGHT:
loctin = TiGetRightType(bp->b_inside);
break;
case BD_TOP:
loctin = TiGetTopType(bp->b_inside);
break;
case BD_BOTTOM:
loctin = TiGetBottomType(bp->b_inside);
break;
}
}
else
loctin = TiGetTypeExact(bp->b_inside);
if (IsSplit(bp->b_outside))
{
switch (bp->b_direction)
{
case BD_LEFT:
loctout = TiGetRightType(bp->b_outside);
break;
case BD_RIGHT:
loctout = TiGetLeftType(bp->b_outside);
break;
case BD_TOP:
loctout = TiGetBottomType(bp->b_outside);
break;
case BD_BOTTOM:
loctout = TiGetTopType(bp->b_outside);
break;
}
}
else
loctout = TiGetTypeExact(bp->b_outside);
*tin = loctin;
*tout = loctout;
}
/*
* ----------------------------------------------------------------------------
*
* extGetBoundaryTypes2 ---
*
* Similar to extGetBoundaryTypes(), but where the tiles for which we
* want to get the tile type are not necessarily the ones in the boundary
* record; the boundary just provides the direction that determines which
* side the tile type is on, in the case of a split tile.
*
* Result:
* None.
*
* Side effects:
* The tile types are passed by pointer reference in the arguments.
*
* ----------------------------------------------------------------------------
*/
void
extGetBoundaryTypes2(int bdir,
Tile *tbin,
Tile *tbout,
TileType *tin,
TileType *tout)
{
TileType loctin, loctout;
if (IsSplit(tbin))
{
switch (bdir)
{
case BD_LEFT:
loctin = TiGetLeftType(tbin);
break;
case BD_RIGHT:
loctin = TiGetRightType(tbin);
break;
case BD_TOP:
loctin = TiGetTopType(tbin);
break;
case BD_BOTTOM:
loctin = TiGetBottomType(tbin);
break;
}
}
else
loctin = TiGetTypeExact(tbin);
if (IsSplit(tbout))
{
switch (bdir)
{
case BD_LEFT:
loctout = TiGetRightType(tbout);
break;
case BD_RIGHT:
loctout = TiGetLeftType(tbout);
break;
case BD_TOP:
loctout = TiGetBottomType(tbout);
break;
case BD_BOTTOM:
loctout = TiGetTopType(tbout);
break;
}
}
else
loctout = TiGetTypeExact(tbout);
*tin = loctin;
*tout = loctout;
}
/*
* ----------------------------------------------------------------------------
*
* extGetBoundaryRegions ---
*
* Given a boundary direction and two tiles, one on the boundary inside
* and one on the boundary outside, find the two node regions associated
* with the facing sides of the two tiles.
*
* Results:
* None.
*
* Side effects:
* The tile types are passed by pointer reference in the arguments.
*
* ----------------------------------------------------------------------------
*/
void
extGetBoundaryRegions(int bdir,
Tile *tbin,
Tile *tbout,
NodeRegion **rinptr,
NodeRegion **routptr)
{
NodeRegion *locrin, *locrout;
if (IsSplit(tbin))
{
switch (bdir)
{
case BD_LEFT:
locrin = (NodeRegion *)ExtGetRegion(tbin, (TileType)0);
break;
case BD_RIGHT:
locrin = (NodeRegion *)ExtGetRegion(tbin, (TileType)TT_SIDE);
break;
case BD_TOP:
locrin = (NodeRegion *)ExtGetRegion(tbin,
TiGetTypeExact(tbin) & TT_DIRECTION ?
(TileType)TT_SIDE : (TileType)0);
break;
case BD_BOTTOM:
locrin = (NodeRegion *)ExtGetRegion(tbin,
TiGetTypeExact(tbin) & TT_DIRECTION ?
(TileType)0 : (TileType)TT_SIDE);
break;
}
}
else
locrin = (NodeRegion *)ExtGetRegion(tbin, (TileType)0);
if (IsSplit(tbout))
{
switch (bdir)
{
case BD_LEFT:
locrout = (NodeRegion *)ExtGetRegion(tbout, (TileType)TT_SIDE);
break;
case BD_RIGHT:
locrout = (NodeRegion *)ExtGetRegion(tbout, (TileType)0);
break;
case BD_TOP:
locrout = (NodeRegion *)ExtGetRegion(tbout,
TiGetTypeExact(tbin) & TT_DIRECTION ?
(TileType)0 : (TileType)TT_SIDE);
break;
case BD_BOTTOM:
locrout = (NodeRegion *)ExtGetRegion(tbout,
TiGetTypeExact(tbin) & TT_DIRECTION ?
(TileType)TT_SIDE : (TileType)0);
break;
}
}
else
locrout = (NodeRegion *)ExtGetRegion(tbout, (TileType)0);
*rinptr = locrin;
*routptr = locrout;
}
/*
* ----------------------------------------------------------------------------
*
@ -823,7 +1074,7 @@ extAddCouple(bp, ecs)
Boundary *bp; /* Boundary being considered */
extCapStruct *ecs;
{
TileType tin = TiGetType(bp->b_inside), tout = TiGetType(bp->b_outside);
TileType tin, tout;
int pNum;
PlaneMask pMask;
Boundary bpCopy;
@ -831,6 +1082,9 @@ extAddCouple(bp, ecs)
extSidewallStruct esws;
int distFringe;
/* Get the types on the inside and outside of the boundary */
extGetBoundaryTypes(bp, &tin, &tout);
/* Check here for a zero exts_sideCoupleOtherEdges mask.
* that handles cases such as FET types not being declared in
* defaultperimeter, as the edge between poly and FET will be
@ -951,9 +1205,10 @@ extRemoveSubcap(bp, clip, esws)
if (!esws->fringe_halo) return;
ta = TiGetType(bp->b_inside);
tb = TiGetType(bp->b_outside);
rbp = (NodeRegion *)extGetRegion(bp->b_inside);
/* Get the types on the inside and outside of the boundary */
extGetBoundaryTypes(bp, &ta, &tb);
rbp = (NodeRegion *)ExtGetRegion(bp->b_inside, (TileType)0);
if (bp->b_segment.r_xtop == bp->b_segment.r_xbot)
length = bp->b_segment.r_ytop - bp->b_segment.r_ybot;
@ -1076,8 +1331,8 @@ extSideOverlapHalo(tp, dinfo, esws)
extSidewallStruct *esws; /* Overlapping edge and plane information */
{
Boundary *bp = esws->bp; /* Overlapping edge */
NodeRegion *rtp = (NodeRegion *) extGetRegion(tp);
NodeRegion *rbp = (NodeRegion *) extGetRegion(bp->b_inside);
NodeRegion *rtp = (NodeRegion *) ExtGetRegion(tp, dinfo);
NodeRegion *rbp = (NodeRegion *) ExtGetRegion(bp->b_inside, (TileType)0);
TileType ta, tb;
Rect tpr;
struct sideoverlap sov;
@ -1307,8 +1562,8 @@ extSideOverlap(tp, dinfo, esws)
extSidewallStruct *esws; /* Overlapping edge and plane information */
{
Boundary *bp = esws->bp; /* Overlapping edge */
NodeRegion *rtp = (NodeRegion *) extGetRegion(tp);
NodeRegion *rbp = (NodeRegion *) extGetRegion(bp->b_inside);
NodeRegion *rtp = (NodeRegion *) ExtGetRegion(tp, dinfo);
NodeRegion *rbp = (NodeRegion *) ExtGetRegion(bp->b_inside, (TileType)0);
TileType ta, tb;
Rect tpr;
struct overlap ov;
@ -1924,11 +2179,13 @@ extSideLeft(tpfar, bp, esws)
Boundary *bp;
extSidewallStruct *esws;
{
NodeRegion *rinside = (NodeRegion *) extGetRegion(bp->b_inside);
NodeRegion *rfar = (NodeRegion *) extGetRegion(tpfar);
NodeRegion *rinside, *rfar;
Tile *tpnear;
if (rfar != (NodeRegion *) extUnInit && rfar != rinside)
/* Get the regions associated with bp->b_inside and tpfar */
extGetBoundaryRegions(bp->b_direction, bp->b_inside, tpfar, &rinside, &rfar);
if (rfar != (NodeRegion *)CLIENTDEFAULT && rfar != rinside)
{
int sep = bp->b_segment.r_xbot - RIGHT(tpfar);
int limit = MAX(bp->b_segment.r_ybot, BOTTOM(tpfar));
@ -1938,8 +2195,8 @@ extSideLeft(tpfar, bp, esws)
{
int overlap = MIN(TOP(tpnear), start) - MAX(BOTTOM(tpnear), limit);
if (overlap > 0)
extSideCommon(rinside, rfar, tpnear, tpfar, overlap, sep,
esws->extCoupleList);
extSideCommon(rinside, rfar, tpnear, tpfar, bp->b_direction,
overlap, sep, esws->extCoupleList);
}
}
@ -1974,11 +2231,13 @@ extSideRight(tpfar, bp, esws)
Boundary *bp;
extSidewallStruct *esws;
{
NodeRegion *rinside = (NodeRegion *) extGetRegion(bp->b_inside);
NodeRegion *rfar = (NodeRegion *) extGetRegion(tpfar);
NodeRegion *rinside, *rfar;
Tile *tpnear;
if (rfar != (NodeRegion *) extUnInit && rfar != rinside)
/* Get the regions associated with bp->b_inside and tpfar */
extGetBoundaryRegions(bp->b_direction, bp->b_inside, tpfar, &rinside, &rfar);
if (rfar != (NodeRegion *) CLIENTDEFAULT && rfar != rinside)
{
int sep = LEFT(tpfar) - bp->b_segment.r_xtop;
int limit = MIN(bp->b_segment.r_ytop, TOP(tpfar));
@ -1988,8 +2247,8 @@ extSideRight(tpfar, bp, esws)
{
int overlap = MIN(TOP(tpnear), limit) - MAX(BOTTOM(tpnear), start);
if (overlap > 0)
extSideCommon(rinside, rfar, tpnear, tpfar, overlap, sep,
esws->extCoupleList);
extSideCommon(rinside, rfar, tpnear, tpfar, bp->b_direction,
overlap, sep, esws->extCoupleList);
}
}
@ -2024,11 +2283,13 @@ extSideTop(tpfar, bp, esws)
Boundary *bp;
extSidewallStruct *esws;
{
NodeRegion *rinside = (NodeRegion *) extGetRegion(bp->b_inside);
NodeRegion *rfar = (NodeRegion *) extGetRegion(tpfar);
NodeRegion *rinside, *rfar;
Tile *tpnear;
if (rfar != (NodeRegion *) extUnInit && rfar != rinside)
/* Get the regions associated with bp->b_inside and tpfar */
extGetBoundaryRegions(bp->b_direction, bp->b_inside, tpfar, &rinside, &rfar);
if (rfar != (NodeRegion *) CLIENTDEFAULT && rfar != rinside)
{
int sep = BOTTOM(tpfar) - bp->b_segment.r_ytop;
int limit = MIN(bp->b_segment.r_xtop, RIGHT(tpfar));
@ -2038,8 +2299,8 @@ extSideTop(tpfar, bp, esws)
{
int overlap = MIN(RIGHT(tpnear), limit) - MAX(LEFT(tpnear), start);
if (overlap > 0)
extSideCommon(rinside, rfar, tpnear, tpfar, overlap, sep,
esws->extCoupleList);
extSideCommon(rinside, rfar, tpnear, tpfar, bp->b_direction,
overlap, sep, esws->extCoupleList);
}
}
@ -2074,11 +2335,13 @@ extSideBottom(tpfar, bp, esws)
Boundary *bp;
extSidewallStruct *esws;
{
NodeRegion *rinside = (NodeRegion *) extGetRegion(bp->b_inside);
NodeRegion *rfar = (NodeRegion *) extGetRegion(tpfar);
NodeRegion *rinside, *rfar;
Tile *tpnear;
if (rfar != (NodeRegion *) extUnInit && rfar != rinside)
/* Get the regions associated with bp->b_inside and tpfar */
extGetBoundaryRegions(bp->b_direction, bp->b_inside, tpfar, &rinside, &rfar);
if (rfar != (NodeRegion *) CLIENTDEFAULT && rfar != rinside)
{
int sep = bp->b_segment.r_ybot - TOP(tpfar);
int limit = MAX(bp->b_segment.r_xbot, LEFT(tpfar));
@ -2088,8 +2351,8 @@ extSideBottom(tpfar, bp, esws)
{
int overlap = MIN(RIGHT(tpnear), start) - MAX(LEFT(tpnear), limit);
if (overlap > 0)
extSideCommon(rinside, rfar, tpnear, tpfar, overlap, sep,
esws->extCoupleList);
extSideCommon(rinside, rfar, tpnear, tpfar, bp->b_direction,
overlap, sep, esws->extCoupleList);
}
}
@ -2103,7 +2366,7 @@ extSideBottom(tpfar, bp, esws)
*
* Perform the actual update to the hash table entry for
* the regions 'rinside' and 'rfar'. We assume that neither
* 'rinside' nor 'rfar' are extUnInit, and further that they
* 'rinside' nor 'rfar' are CLIENTDEFAULT, and further that they
* are not equal.
*
* Walk along the rules in extCoupleList, applying the appropriate
@ -2120,20 +2383,24 @@ extSideBottom(tpfar, bp, esws)
*/
void
extSideCommon(rinside, rfar, tpnear, tpfar, overlap, sep, extCoupleList)
extSideCommon(rinside, rfar, tpnear, tpfar, bdir, overlap, sep, extCoupleList)
NodeRegion *rinside, *rfar; /* Both must be valid */
Tile *tpnear, *tpfar; /* Tiles on near and far side of edge */
int bdir; /* Boundary direction */
int overlap, sep; /* Overlap of this edge with original one,
* and distance between the two.
*/
EdgeCap *extCoupleList; /* List of sidewall capacitance rules */
{
TileType near = TiGetType(tpnear), far = TiGetType(tpfar);
TileType near, far;
HashEntry *he;
EdgeCap *e;
CoupleKey ck;
CapValue cap;
/* Get the tile types of tpnear and tpfar */
extGetBoundaryTypes2(bdir, tpnear, tpfar, &near, &far);
if (rinside < rfar) ck.ck_1 = rinside, ck.ck_2 = rfar;
else ck.ck_1 = rfar, ck.ck_2 = rinside;
he = HashFind(extCoupleHashPtr, (char *) &ck);

View File

@ -196,7 +196,7 @@ extHardProc(scx, arg)
* single child.
*/
labRegList = (TransRegion *) ExtFindRegions(def, &scx->scx_area,
&arg->hw_mask, ExtCurStyle->exts_nodeConn, extUnInit,
&arg->hw_mask, ExtCurStyle->exts_nodeConn,
extLabFirst, extLabEach);
if (labRegList)
{
@ -333,7 +333,7 @@ extHardSetLabel(scx, reg, arg)
tp = PlaneGetHint(scx->scx_use->cu_def->cd_planes[pNum]);
GOTOPOINT(tp, &r.r_ll);
PlaneSetHint(scx->scx_use->cu_def->cd_planes[pNum], tp);
if ((TransRegion *)extGetRegion(tp) == reg)
if ((TransRegion *)ExtGetRegion(tp, (TileType)0) == reg)
{
/* found an OK point */
r.r_ur.p_x =r.r_ll.p_x+1;
@ -342,7 +342,7 @@ extHardSetLabel(scx, reg, arg)
else
{
GOTOPOINT(tp, &r.r_ur);
if ((TransRegion *)extGetRegion(tp) == reg)
if ((TransRegion *)ExtGetRegion(tp, (TileType)0) == reg)
{
r.r_ll = r.r_ur;
}
@ -488,12 +488,12 @@ extHardFreeAll(def, tReg)
arg.fra_connectsTo = ExtCurStyle->exts_nodeConn;
arg.fra_def = def;
arg.fra_each = (int (*)()) NULL;
arg.fra_region = (ExtRegion *) extUnInit;
arg.fra_region = (ExtRegion *) CLIENTDEFAULT;
free_magic1_t mm1 = freeMagic1_init();
for (reg = tReg; reg; reg = reg->treg_next)
{
/* Reset all ti_client fields to extUnInit */
/* Reset all ti_client fields to CLIENTDEFAULT */
arg.fra_uninit = (ClientData) reg;
if (reg->treg_tile)
{

View File

@ -134,7 +134,7 @@ extHierSubstrate(ha, use, x, y)
nodeList = extFindNodes(use->cu_def, (Rect *) NULL, TRUE);
if (nodeList == NULL)
{
ExtResetTiles(use->cu_def, extUnInit);
ExtResetTiles(use->cu_def, CLIENTDEFAULT);
return;
}
@ -174,7 +174,7 @@ extHierSubstrate(ha, use, x, y)
extHierSubShieldFunc, (ClientData)NULL) != 0)
{
freeMagic(nodeList);
ExtResetTiles(use->cu_def, extUnInit);
ExtResetTiles(use->cu_def, CLIENTDEFAULT);
return;
}
}
@ -183,7 +183,7 @@ extHierSubstrate(ha, use, x, y)
/* Make sure substrate labels are represented */
ExtLabelRegions(use->cu_def, ExtCurStyle->exts_nodeConn, &nodeList,
&TiPlaneRect);
ExtResetTiles(use->cu_def, extUnInit);
ExtResetTiles(use->cu_def, CLIENTDEFAULT);
name2 = extNodeName(temp_subsnode);
@ -789,7 +789,7 @@ extHierAdjustments(ha, cumFlat, oneFlat, lookFlat)
tp = extNodeToTile(np, lookFlat, &dinfo);
/* Ignore regions that do not participate in extraction */
if (!extHasRegion(tp, extUnInit)) continue;
if (!extHasRegion(tp, CLIENTDEFAULT)) continue;
/* Ignore substrate nodes (failsafe: should not happen) */
if (TiGetTypeExact(tp) == TT_SPACE) continue;

View File

@ -45,9 +45,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
* the value VISITPENDING in its ti_client field.
*/
/* Used for communicating with extNbrPushFunc */
ClientData extNbrUn;
/*
* ----------------------------------------------------------------------------
*
@ -82,16 +79,16 @@ ExtFindNeighbors(tile, dinfo, tilePlaneNum, arg)
{
TileTypeBitMask *connTo = arg->fra_connectsTo;
Tile *tp;
TileType type, t;
TileType type, t, tpdinfo;
TileTypeBitMask *mask;
Rect biggerArea;
int pNum, tilesfound;
PlaneMask pMask;
PlaneAndArea pla;
ClientData extNbrUn = arg->fra_uninit;
tilesfound = 0;
extNbrUn = arg->fra_uninit;
if (extNodeStack == (Stack *) NULL)
extNodeStack = StackNew(64);
@ -120,9 +117,9 @@ ExtFindNeighbors(tile, dinfo, tilePlaneNum, arg)
* been visited in the meantime. If it's still unvisited,
* visit it and process its neighbors.
*/
if (TiGetClientPTR(tile) == arg->fra_region)
if (ExtGetRegion(tile, dinfo) == arg->fra_region);
continue;
TiSetClientPTR(tile, arg->fra_region);
ExtSetRegion(tile, dinfo, arg->fra_region);
tilesfound++;
if (DebugIsSet(extDebugID, extDebNeighbor))
extShowTile(tile, "neighbor", 1);
@ -136,8 +133,9 @@ topside:
if (IsSplit(tp))
{
t = SplitBottomType(tp);
tpdinfo = SplitDirection(tp) ? (TileType)0 : (TileType)TT_SIDE;
// if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t))
if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t))
if (ExtGetRegion(tp, tpdinfo) == CD2PTR(extNbrUn) && TTMaskHasType(mask, t))
{
PUSHTILEBOTTOM(tp, tilePlaneNum);
}
@ -161,7 +159,8 @@ leftside:
{
t = SplitRightType(tp);
// if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t))
if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t))
if (ExtGetRegion(tp, (TileType)TT_SIDE) == CD2PTR(extNbrUn)
&& TTMaskHasType(mask, t))
{
PUSHTILERIGHT(tp, tilePlaneNum);
}
@ -185,8 +184,9 @@ bottomside:
if (IsSplit(tp))
{
t = SplitTopType(tp);
tpdinfo = SplitDirection(tp) ? (TileType)TT_SIDE : (TileType)0;
// if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t))
if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t))
if (ExtGetRegion(tp, tpdinfo) == CD2PTR(extNbrUn) && TTMaskHasType(mask, t))
{
PUSHTILETOP(tp, tilePlaneNum);
}
@ -210,7 +210,8 @@ rightside:
{
t = SplitLeftType(tp);
// if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t))
if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t))
if (ExtGetRegion(tp, (TileType)0) == CD2PTR(extNbrUn)
&& TTMaskHasType(mask, t))
{
PUSHTILELEFT(tp, tilePlaneNum);
}
@ -239,6 +240,7 @@ donesides:
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
if (PlaneMaskHasPlane(pMask, pNum))
{
ExtRegion *tpreg;
Plane *plane = arg->fra_def->cd_planes[pNum];
/* Find the point on the new plane */
@ -246,14 +248,14 @@ donesides:
GOTOPOINT(tp, &tile->ti_ll);
PlaneSetHint(plane, tp);
/* If not yet visited, process tp */
if (TiGetClient(tp) != extNbrUn) continue;
/* tp and tile should have the same geometry for a contact */
if (IsSplit(tile) && IsSplit(tp))
{
if (dinfo & TT_SIDE)
{
/* Only process tp if not yet visited */
tpreg = ExtGetRegion(tp, (TileType)TT_SIDE);
if (tpreg != CD2PTR(extNbrUn)) continue;
t = SplitRightType(tp);
if (TTMaskHasType(mask, t))
{
@ -262,6 +264,9 @@ donesides:
}
else
{
/* Only process tp if not yet visited */
tpreg = ExtGetRegion(tp, (TileType)0);
if (tpreg != CD2PTR(extNbrUn)) continue;
t = SplitLeftType(tp);
if (TTMaskHasType(mask, t))
{
@ -271,19 +276,32 @@ donesides:
}
else if (IsSplit(tp))
{
t = SplitRightType(tp);
if (TTMaskHasType(mask, t))
/* Only process tp if not yet visited */
tpreg = ExtGetRegion(tp, (TileType)TT_SIDE);
if (tpreg == CD2PTR(extNbrUn))
{
PUSHTILERIGHT(tp, pNum);
t = SplitRightType(tp);
if (TTMaskHasType(mask, t))
{
PUSHTILERIGHT(tp, pNum);
}
}
t = SplitLeftType(tp);
if (TTMaskHasType(mask, t))
/* Try both sides */
tpreg = ExtGetRegion(tp, (TileType)0);
if (tpreg == CD2PTR(extNbrUn))
{
PUSHTILELEFT(tp, pNum);
t = SplitLeftType(tp);
if (TTMaskHasType(mask, t))
{
PUSHTILELEFT(tp, pNum);
}
}
}
else
{
/* Only process tp if not yet visited */
tpreg = ExtGetRegion(tp, (TileType)0);
if (tpreg != CD2PTR(extNbrUn)) continue;
t = TiGetTypeExact(tp);
if (TTMaskHasType(mask, t))
{
@ -324,7 +342,7 @@ fail:
while (!StackEmpty(extNodeStack))
{
POPTILE(tile, dinfo, tilePlaneNum);
TiSetClientPTR(tile, arg->fra_region);
ExtSetRegion(tile, dinfo, arg->fra_region);
}
return -1;
}
@ -339,9 +357,9 @@ fail:
* with tileArea, and it hasn't already been visited, push it on the stack
* extNodeStack.
*
* Uses the global parameter extNbrUn to determine whether or not a tile
* has been visited; if the tile's client field is equal to extNbrUn, then
* this is the first time the tile has been seen.
* Uses the value pla->uninit to determine whether or not a tile has been
* visited; if the tile's client field is equal to pla->uninit, then this
* is the first time the tile has been seen.
*
* Results:
* Always returns 0.
@ -364,7 +382,7 @@ extNbrPushFunc(tile, dinfo, pla)
tileArea = &pla->area;
/* Ignore tile if it's already been visited */
if (TiGetClient(tile) != extNbrUn)
if (ExtGetRegion(tile, dinfo) != CD2PTR(pla->uninit))
return 0;
/* Only consider tile if it overlaps tileArea or shares part of a side */

View File

@ -36,7 +36,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "extract/extract.h"
#include "extract/extractInt.h"
#define POINTEQUAL(p, q) ((p)->p_x == (q)->p_x && (p)->p_y == (q)->p_y)
#define POINTEQUAL(p, q) (((p)->p_x == (q)->p_x) && ((p)->p_y == (q)->p_y))
/*
* ----------------------------------------------------------------------------
@ -57,7 +57,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
* {
* }
*
* The value returned by this function is ignored.
* The value returned by the callback function is ignored.
*
* Results:
* Returns the total length of the portion of the perimeter of
@ -87,12 +87,11 @@ extEnumTilePerim(
int (*func)(),
ClientData cdata)
{
TileTypeBitMask mask = *maskp; /* TTMaskCopy(&mask, maskp) */
TileType origType;
TileTypeBitMask mask = *maskp;
Tile *tpOut;
int perimCorrect;
Boundary b;
unsigned char sides = 0;
unsigned char sides = 0; /* Sides to be ignored */
b.b_inside = tpIn;
b.b_plane = pNum;
@ -101,9 +100,12 @@ extEnumTilePerim(
/* Diagonal */
if (IsSplit(tpIn))
{
/* Determine which two sides need to be searched and set the corresponding
* boundary direction bit in "sides". "dinfo" determines which side of the
* split tile is considered "inside" the boundary and which is "outside".
*/
TileType otype = (dinfo & TT_SIDE) ? SplitLeftType(tpIn): SplitRightType(tpIn);
TileType itype = (dinfo & TT_SIDE) ? SplitRightType(tpIn): SplitLeftType(tpIn);
origType = TiGetTypeExact(tpIn);
if (TTMaskHasType(&mask, otype))
{
int width = RIGHT(tpIn) - LEFT(tpIn);
@ -111,10 +113,9 @@ extEnumTilePerim(
perimCorrect = width * width + height * height;
perimCorrect = (int)sqrt((double)perimCorrect);
}
sides = (dinfo & TT_SIDE) ? BD_LEFT : BD_RIGHT;
sides = (dinfo & TT_SIDE) ? BD_RIGHT : BD_LEFT;
sides |= (((dinfo & TT_SIDE) ? 1 : 0) == SplitDirection(tpIn)) ?
BD_BOTTOM : BD_TOP;
TiSetBody(tpIn, itype);
BD_TOP : BD_BOTTOM;
}
else
sides = 0;
@ -179,8 +180,5 @@ extEnumTilePerim(
}
}
if (sides != 0)
TiSetBody(tpIn, origType);
return (perimCorrect);
}

View File

@ -36,6 +36,49 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "extract/extractInt.h"
#include "utils/signals.h"
/*
* ----------------------------------------------------------------------------
* ExtGetRegion ---
*
* Get the region from the ClientData of a tile. Normally this is just the
* ClientData record recast as an ExtRegion pointer. However, if the tile
* is split and neither tile side is TT_SPACE, then the Tile will be given
* an ExtSplitRegion structure, and the returned region depends on the side
* specified by "dinfo" (bit TT_SIDE).
*
* Results:
* Returns the tile's client data record cast to a region pointer.
*
* Side effects:
* None.
*
* Notes:
* This routine was previously implemented as an in-line definition
* "extGetRegion(Tile *tp)".
*
* ----------------------------------------------------------------------------
*/
ExtRegion *
ExtGetRegion(Tile *tp, /* Tile to get region record from */
TileType dinfo) /* Split tile information, if relevant */
{
ExtSplitRegion *esr;
if (IsSplit(tp))
{
if ((TiGetLeftType(tp) == TT_SPACE) || (TiGetRightType(tp) == TT_SPACE))
return (ExtRegion *)tp->ti_client;
else
{
esr = (ExtSplitRegion *)tp->ti_client;
return (dinfo & TT_SIDE) ? esr->reg_right : esr->reg_left;
}
}
else
return (ExtRegion *)tp->ti_client;
}
/*
* ----------------------------------------------------------------------------
*
@ -87,7 +130,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
*/
ExtRegion *
ExtFindRegions(def, area, mask, connectsTo, uninit, first, each)
ExtFindRegions(def, area, mask, connectsTo, 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
@ -103,9 +146,6 @@ ExtFindRegions(def, area, mask, connectsTo, uninit, first, each)
* 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.
*/
ExtRegion * (*first)(); /* Applied to first tile in region */
int (*each)(); /* Applied to each tile in region */
{
@ -115,7 +155,7 @@ ExtFindRegions(def, area, mask, connectsTo, uninit, first, each)
ASSERT(first != NULL, "ExtFindRegions");
arg.fra_connectsTo = connectsTo;
arg.fra_def = def;
arg.fra_uninit = uninit;
arg.fra_uninit = CLIENTDEFAULT;
arg.fra_first = first;
arg.fra_each = each;
arg.fra_region = (ExtRegion *) NULL;
@ -126,7 +166,7 @@ ExtFindRegions(def, area, mask, connectsTo, uninit, first, each)
SigDisableInterrupts();
for (arg.fra_pNum=PL_TECHDEPBASE; arg.fra_pNum<DBNumPlanes; arg.fra_pNum++)
(void) DBSrPaintClient((Tile *) NULL, def->cd_planes[arg.fra_pNum],
area, mask, uninit, extRegionAreaFunc, (ClientData) &arg);
area, mask, CLIENTDEFAULT, extRegionAreaFunc, (ClientData) &arg);
SigEnableInterrupts();
return (arg.fra_region);
@ -183,7 +223,7 @@ extRegionAreaFunc(tile, dinfo, arg)
* Given a CellDef whose tiles have been set to point to LabRegions
* by ExtFindRegions, walk down the label list and assign labels
* to regions. If the tile over which a label lies is still uninitialized
* ie, points to extUnInit, we skip the label.
* ie, points to CLIENTDEFAULT, we skip the label.
*
* A label is attached to the LabRegion for a tile if the label's
* type and the tile's type are connected according to the table
@ -248,10 +288,10 @@ ExtLabelRegions(def, connTo, nodeList, clipArea)
GOTOPOINT(tp, &p);
PlaneSetHint(def->cd_planes[pNum], tp);
if (extConnectsTo(TiGetType(tp), lab->lab_type, connTo)
&& extHasRegion(tp, extUnInit))
&& extHasRegion(tp, CLIENTDEFAULT))
{
found = TRUE;
reg = (LabRegion *) extGetRegion(tp);
reg = (LabRegion *) ExtGetRegion(tp, (TileType)0);
ll = (LabelList *) mallocMagic((unsigned) (sizeof (LabelList)));
ll->ll_label = lab;
if (lab->lab_flags & PORT_DIR_MASK)
@ -415,7 +455,7 @@ ExtLabelOneRegion(def, connTo, reg)
GOTOPOINT(tp, &p);
PlaneSetHint(def->cd_planes[pNum], tp);
if (extConnectsTo(TiGetType(tp), lab->lab_type, connTo)
&& (NodeRegion *) extGetRegion(tp) == reg)
&& (NodeRegion *) ExtGetRegion(tp, (TileType)0) == reg)
{
ll = (LabelList *) mallocMagic((unsigned) (sizeof (LabelList)));
ll->ll_label = lab;
@ -447,7 +487,6 @@ ExtLabelOneRegion(def, connTo, reg)
}
}
/*
* ----------------------------------------------------------------------------
*
@ -478,7 +517,7 @@ ExtResetTiles(def, resetTo)
int pNum;
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
DBResetTilePlane(def->cd_planes[pNum], resetTo);
DBResetTilePlaneSpecial(def->cd_planes[pNum], resetTo);
}
/*

View File

@ -891,7 +891,7 @@ extSubtreeFunc(scx, ha)
(NodeRegion *) ExtFindRegions(cumUse->cu_def, &TiPlaneRect,
&ExtCurStyle->exts_activeTypes,
ExtCurStyle->exts_nodeConn,
extUnInit, extHierLabFirst, (int (*)()) NULL);
extHierLabFirst, (int (*)()) NULL);
ExtLabelRegions(cumUse->cu_def, ExtCurStyle->exts_nodeConn,
&(ha->ha_cumFlat.et_nodes), &TiPlaneRect);
}
@ -928,7 +928,7 @@ extSubtreeFunc(scx, ha)
/* Free the cumulative node list we extracted above */
if (ha->ha_cumFlat.et_nodes)
{
ExtResetTiles(cumUse->cu_def, extUnInit);
ExtResetTiles(cumUse->cu_def, CLIENTDEFAULT);
ExtFreeLabRegions((LabRegion *) ha->ha_cumFlat.et_nodes);
ha->ha_cumFlat.et_nodes = (NodeRegion *) NULL;
}
@ -1071,9 +1071,9 @@ extSubtreeTileToNode(tp, dinfo, pNum, et, ha, doHard)
TileType ttype;
/* If there is a label list, use it */
if (extHasRegion(tp, extUnInit))
if (extHasRegion(tp, CLIENTDEFAULT))
{
reg = (LabRegion *) extGetRegion(tp);
reg = (LabRegion *) ExtGetRegion(tp, dinfo);
if (reg->lreg_labels)
return (extNodeName(reg));
}
@ -1124,7 +1124,7 @@ extSubtreeTileToNode(tp, dinfo, pNum, et, ha, doHard)
/* We have to do it the hard way */
if (!doHard) return ((char *) NULL);
if (extHasRegion(tp, extUnInit)
if (extHasRegion(tp, CLIENTDEFAULT)
&& (reg = extSubtreeHardNode(tp, dinfo, pNum, et, ha)))
{
if (ExtDoWarn & EXTWARN_LABELS)
@ -1164,9 +1164,9 @@ extConnFindFunc(tp, dinfo, preg)
TileType dinfo; // Unused, but needs to be handled
LabRegion **preg;
{
if (extHasRegion(tp, extUnInit))
if (extHasRegion(tp, CLIENTDEFAULT))
{
*preg = (LabRegion *)extGetRegion(tp);
*preg = (LabRegion *)ExtGetRegion(tp, dinfo);
return (1);
}
@ -1211,7 +1211,7 @@ extSubtreeHardNode(tp, dinfo, pNum, et, ha)
ExtTree *et;
HierExtractArg *ha;
{
LabRegion *lreg = (LabRegion *) extGetRegion(tp);
LabRegion *lreg = (LabRegion *) ExtGetRegion(tp, dinfo);
CellDef *def = et->et_use->cu_def;
TileType ttype;
char labelBuf[4096];

View File

@ -358,8 +358,8 @@ extTimesCellFunc(cs)
/* Count the number of transistors */
transList = (TransRegion *) ExtFindRegions(def, &TiPlaneRect,
&ExtCurStyle->exts_deviceMask, ExtCurStyle->exts_deviceConn,
extUnInit, extTransFirst, extTransEach);
ExtResetTiles(def, extUnInit);
extTransFirst, extTransEach);
ExtResetTiles(def, CLIENTDEFAULT);
for (tl = transList; tl; tl = tl->treg_next)
cs->cs_fets++;
ExtFreeLabRegions((LabRegion *) transList);
@ -844,7 +844,7 @@ extPaintOnly(def)
reg = extBasic(def, extDevNull);
if (reg) ExtFreeLabRegions((LabRegion *) reg);
ExtResetTiles(def, extUnInit);
ExtResetTiles(def, CLIENTDEFAULT);
}
/*

View File

@ -109,7 +109,7 @@ extUniqueCell(def, option)
lregList = (LabRegion *) ExtFindRegions(def, &TiPlaneRect,
&ExtCurStyle->exts_activeTypes,
ExtCurStyle->exts_nodeConn,
extUnInit, extHierLabFirst, (int (*)()) NULL);
extHierLabFirst, (int (*)()) NULL);
/* Assign the labels to their associated regions */
ExtLabelRegions(def, ExtCurStyle->exts_nodeConn, &lregList, &TiPlaneRect);
@ -187,7 +187,7 @@ extUniqueCell(def, option)
HashKill(&labelHash);
ExtFreeLabRegions((LabRegion *) lregList);
if (nodeList) freeMagic(nodeList);
ExtResetTiles(def, extUnInit);
ExtResetTiles(def, CLIENTDEFAULT);
if (nwarn)
TxError("%s: %d warnings\n", def->cd_name, nwarn);
return (nwarn);

View File

@ -154,6 +154,17 @@ typedef struct reg
struct reg *reg_next; /* Next region in list */
} ExtRegion;
/*
* Special structure for split tiles which have something other than
* TT_SPACE on both sides and require two regions to represent both
* nets connected to the tile.
*/
typedef struct split_reg
{
ExtRegion *reg_left; // Region belonging to tile left side
ExtRegion *reg_right; // Region belonging to tile right side
} ExtSplitRegion;
/*
* GENERIC region with labels.
* Any other structure that wants to reference node names
@ -228,6 +239,7 @@ typedef struct treg
typedef struct { /* Maintain plane information when pushing */
Rect area; /* tiles on the node stack. For use with */
int plane; /* function extNbrPushFunc(). */
ClientData uninit; /* Value of an unvisited region */
} PlaneAndArea;
/* Structure to be kept in a hash table of node regions for the current */
@ -259,7 +271,7 @@ typedef struct
CellDef *fra_def; /* Def being searched */
int fra_pNum; /* Plane currently searching */
ClientData fra_uninit; /* This value appears in the ti_client
* field of a tile if it's not yet
* field of a tile if it has not yet
* been visited.
*/
ExtRegion *(*fra_first)(); /* Function to init new region */
@ -975,17 +987,10 @@ typedef struct node
/* -------------------------------------------------------------------- */
/*
* Value normally resident in the ti_client field of a tile,
* indicating that the tile has not yet been visited in a
* region search.
*/
extern ClientData extUnInit;
extern ExtRegion *ExtGetRegion(Tile *tile, TileType dinfo);
#define extGetRegion(tp) ( (tp)->ti_client )
#define extHasRegion(tp,und) ( (tp)->ti_client != (und) )
/* For non-recursive flooding algorithm */
#define VISITPENDING ((ClientData) NULL) /* Marks tiles on stack */
@ -1062,11 +1067,12 @@ extern Tile *extNodeToTile();
#define NODETONODE(nold, et, nnew) \
if (1) { \
Tile *tp; \
TileType di; \
\
(nnew) = (NodeRegion *) NULL; \
tp = extNodeToTile((nold), (et), (TileType *)NULL); \
if (tp && extHasRegion(tp, extUnInit)) \
(nnew) = (NodeRegion *) extGetRegion(tp); \
tp = extNodeToTile((nold), (et), (TileType *)&di); \
if (tp && extHasRegion(tp, CLIENTDEFAULT)) \
(nnew) = (NodeRegion *) ExtGetRegion(tp, di); \
}
/* -------------------- Miscellaneous procedures ---------------------- */
@ -1078,6 +1084,7 @@ extern ExtTree *extHierNewOne();
extern int extNbrPushFunc();
extern TileType extGetDevType();
extern void extMakeNodeNumPrint();
extern void ExtSetRegion();
/* --------------------- Miscellaneous globals ------------------------ */

File diff suppressed because it is too large Load Diff

View File

@ -1121,7 +1121,7 @@ ResExtractNet(node, goodies, cellname)
}
DBReComputeBbox(ResUse->cu_def);
ExtResetTiles(scx.scx_use->cu_def, extUnInit);
ExtResetTiles(scx.scx_use->cu_def, CLIENTDEFAULT);
/* To avoid issues with overlapping stacked contact types and */
/* double-counting contacts on multiple planes, erase the top */
@ -1148,9 +1148,8 @@ ResExtractNet(node, goodies, cellname)
ResContactList = (ResContactPoint *)ExtFindRegions(ResUse->cu_def,
&(ResUse->cu_def->cd_bbox),
&DBAllButSpaceAndDRCBits,
ResConnectWithSD, extUnInit, ResFirst,
ResEach);
ExtResetTiles(ResUse->cu_def, extUnInit);
ResConnectWithSD, ResFirst, ResEach);
ExtResetTiles(ResUse->cu_def, CLIENTDEFAULT);
/*
* dissolve the contacts and find which tiles now cover the point

View File

@ -170,7 +170,7 @@ SimInitDefList(void)
while (p != (DefListElt *)NULL) {
q = p;
p = p->dl_next;
ExtResetTiles(q->dl_def, extUnInit);
ExtResetTiles(q->dl_def, CLIENTDEFAULT);
freeMagic(q);
}
DefList = (DefListElt *) NULL;
@ -596,7 +596,7 @@ SimFindOneNode(
type = TiGetTypeExact(tile);
arg.fra_pNum = DBPlane(type);
arg.fra_uninit = (ClientData) extUnInit;
arg.fra_uninit = (ClientData) CLIENTDEFAULT;
arg.fra_region = (ExtRegion *) reg;
arg.fra_each = SimFindTxtor;
(void) ExtFindNeighbors(tile, dinfo, arg.fra_pNum, &arg);
@ -607,7 +607,7 @@ SimFindOneNode(
transistor.t_pnum = DBNumPlanes;
transistor.t_do_terms = FALSE;
TiSetClient(gateTile, extUnInit);
TiSetClient(gateTile, CLIENTDEFAULT);
arg.fra_connectsTo = &SimTransMask;
if (IsSplit(tile))
@ -617,7 +617,7 @@ SimFindOneNode(
loctype = TiGetTypeExact(gateTile);
arg.fra_pNum = DBPlane(loctype);
arg.fra_uninit = (ClientData) extUnInit;
arg.fra_uninit = (ClientData) CLIENTDEFAULT;
arg.fra_region = (ExtRegion *) reg;
arg.fra_each = SimTransistorTile;
(void) ExtFindNeighbors(gateTile, gateDinfo, arg.fra_pNum, &arg);
@ -626,7 +626,7 @@ SimFindOneNode(
arg.fra_connectsTo = ExtCurStyle->exts_nodeConn;
arg.fra_pNum = DBPlane(type);
arg.fra_uninit = (ClientData) reg;
arg.fra_region = (ExtRegion *) extUnInit;
arg.fra_region = (ExtRegion *) CLIENTDEFAULT;
arg.fra_each = (int (*)()) NULL;
(void) ExtFindNeighbors(tile, dinfo, arg.fra_pNum, &arg);
@ -736,7 +736,7 @@ SimGetNodeName(
/* check to see if this tile has been extracted before */
if (TiGetClient(tp) == extUnInit)
if (TiGetClient(tp) == CLIENTDEFAULT)
{
NodeSpec *ns;