From 8bd01f55974cb5fac0e6645f76ef9b5fb433a785 Mon Sep 17 00:00:00 2001 From: "R. Timothy Edwards" Date: Fri, 9 Jan 2026 11:58:35 -0500 Subject: [PATCH] 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. --- README | 104 +++- database/DBtiles.c | 79 ++- database/database.h.in | 1 + extract/Depend3734592.tmp | 113 ---- extract/ExtArray.c | 10 +- extract/ExtBasic.c | 270 ++++++++-- extract/ExtCell.c | 11 +- extract/ExtCouple.c | 347 ++++++++++-- extract/ExtHard.c | 10 +- extract/ExtHier.c | 8 +- extract/ExtNghbors.c | 68 ++- extract/ExtPerim.c | 22 +- extract/ExtRegion.c | 63 ++- extract/ExtSubtree.c | 16 +- extract/ExtTimes.c | 6 +- extract/ExtUnique.c | 4 +- extract/extractInt.h | 31 +- extract/extractInt.h.new | 1053 ------------------------------------- resis/ResMain.c | 7 +- sim/SimExtract.c | 12 +- 20 files changed, 858 insertions(+), 1377 deletions(-) delete mode 100644 extract/Depend3734592.tmp delete mode 100644 extract/extractInt.h.new diff --git a/README b/README index 97cadc77..5545f5e1 100644 --- a/README +++ b/README @@ -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! diff --git a/database/DBtiles.c b/database/DBtiles.c index 30dd0fd4..529f5384 100644 --- a/database/DBtiles.c +++ b/database/DBtiles.c @@ -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 */; + } +} + /* * -------------------------------------------------------------------- * diff --git a/database/database.h.in b/database/database.h.in index 3c0c0172..d3fac599 100644 --- a/database/database.h.in +++ b/database/database.h.in @@ -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(); diff --git a/extract/Depend3734592.tmp b/extract/Depend3734592.tmp deleted file mode 100644 index 2d09a5d6..00000000 --- a/extract/Depend3734592.tmp +++ /dev/null @@ -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 diff --git a/extract/ExtArray.c b/extract/ExtArray.c index 8a78b1aa..6e73f59f 100644 --- a/extract/ExtArray.c +++ b/extract/ExtArray.c @@ -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; diff --git a/extract/ExtBasic.c b/extract/ExtBasic.c index ce3c63d7..ac3326a8 100644 --- a/extract/ExtBasic.c +++ b/extract/ExtBasic.c @@ -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++) diff --git a/extract/ExtCell.c b/extract/ExtCell.c index d425c4d4..98bc5898 100644 --- a/extract/ExtCell.c +++ b/extract/ExtCell.c @@ -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)) diff --git a/extract/ExtCouple.c b/extract/ExtCouple.c index 47676645..a1c17785 100644 --- a/extract/ExtCouple.c +++ b/extract/ExtCouple.c @@ -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); diff --git a/extract/ExtHard.c b/extract/ExtHard.c index 7f85cd83..8c1811bf 100644 --- a/extract/ExtHard.c +++ b/extract/ExtHard.c @@ -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) { diff --git a/extract/ExtHier.c b/extract/ExtHier.c index eba5b685..b7c563b0 100644 --- a/extract/ExtHier.c +++ b/extract/ExtHier.c @@ -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; diff --git a/extract/ExtNghbors.c b/extract/ExtNghbors.c index 42e6cf48..e292eb69 100644 --- a/extract/ExtNghbors.c +++ b/extract/ExtNghbors.c @@ -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 */ diff --git a/extract/ExtPerim.c b/extract/ExtPerim.c index 424cbeb0..965eb7d8 100644 --- a/extract/ExtPerim.c +++ b/extract/ExtPerim.c @@ -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); } diff --git a/extract/ExtRegion.c b/extract/ExtRegion.c index 8003058e..ab22ec85 100644 --- a/extract/ExtRegion.c +++ b/extract/ExtRegion.c @@ -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_pNumcd_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); } /* diff --git a/extract/ExtSubtree.c b/extract/ExtSubtree.c index 9eabcfeb..9e791680 100644 --- a/extract/ExtSubtree.c +++ b/extract/ExtSubtree.c @@ -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]; diff --git a/extract/ExtTimes.c b/extract/ExtTimes.c index 747c7236..b712877a 100644 --- a/extract/ExtTimes.c +++ b/extract/ExtTimes.c @@ -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); } /* diff --git a/extract/ExtUnique.c b/extract/ExtUnique.c index 98ca9b69..c3716a0a 100644 --- a/extract/ExtUnique.c +++ b/extract/ExtUnique.c @@ -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); diff --git a/extract/extractInt.h b/extract/extractInt.h index 7791be6f..155f9131 100644 --- a/extract/extractInt.h +++ b/extract/extractInt.h @@ -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 ------------------------ */ diff --git a/extract/extractInt.h.new b/extract/extractInt.h.new deleted file mode 100644 index 3661c6b9..00000000 --- a/extract/extractInt.h.new +++ /dev/null @@ -1,1053 +0,0 @@ -/* - * extractInt.h -- - * - * Defines things shared internally by the extract module of Magic, - * but not generally needed outside the extract module. - * - * rcsid "$Header: /usr/cvsroot/magic-8.0/extract/extractInt.h.new,v 1.2 2008/06/01 18:37:42 tim Exp $" - * - * ********************************************************************* - * * Copyright (C) 1985, 1990 Regents of the University of California. * - * * Permission to use, copy, modify, and distribute this * - * * software and its documentation for any purpose and without * - * * fee is hereby granted, provided that the above copyright * - * * notice appear in all copies. The University of California * - * * makes no representations about the suitability of this * - * * software for any purpose. It is provided "as is" without * - * * express or implied warranty. Export of this software outside * - * * of the United States of America may require an export license. * - * ********************************************************************* - * - * This module has been modified at DEC/WRL and Stanford University. - * The above disclaimers apply. - * - */ - -#ifndef _EXTRACTINT_H -#define _EXTRACTINT_H - -#include "database/database.h" - -#undef NT -#define NT TT_MAXTYPES -#undef NP -#define NP PL_MAXTYPES - -/* ------------------------ Capacitance Values ------------------------- */ - -typedef double CapValue; /* No longer allowed to define back to integer, - * as this touches too many parts of the code. - */ - -/* Procs to manipulate capacitance hash tables. */ -extern CapValue extGetCapValue(); -extern void extSetCapValue(); -extern void extCapHashKill(); - -typedef int ResValue; /* Warning: in some places resistances are stored - * as ints. This is here for documentation only. - */ - -/* -------------------------- Label lists ----------------------------- */ - -/* - * List of labels for a node. - * We keep around pointers to the entire labels for - * later figuring out which are attached to the gates, - * sources, or drains of transistors. - */ -typedef struct ll -{ - Label *ll_label; /* Actual Label in the source CellDef */ - struct ll *ll_next; /* Next LabelList in this region */ - int ll_attr; /* Which terminal of a transistor this is - * an attribute of. - */ -} LabelList; - -#define LL_NOATTR -1 /* Value for ll_attr above if the label is - * not a transistor attribute. - */ -#define LL_GATEATTR -2 /* Value for ll_attr if the label is a gate - * attribute, rather than one of the diffusion - * terminals' attributes. - */ -#define LL_SORTATTR -3 /* value for ll_attr used in - * ExtBasic.c/ExtSortTerminals() to swap - * the attributes as well as the regions - * -- Stefanos 5/96 - */ -#define LL_PORTATTR -4 /* value for ll_attr used to declare - * the label to be a subcircuit port - * -- Tim 5/02 - */ -/* - * Types of labels. - * These can be or'd into a mask and passed to extLabType(). - */ -#define LABTYPE_NAME 0x01 /* Normal node name */ -#define LABTYPE_NODEATTR 0x02 /* Node attribute */ -#define LABTYPE_GATEATTR 0x04 /* Transistor gate attribute */ -#define LABTYPE_TERMATTR 0x08 /* Transistor terminal (source/drain) - * attribute. - */ -#define LABTYPE_PORTATTR 0x10 /* Subcircuit port */ - -/* ----------------------------- Regions ------------------------------ */ - -/* - * The following are the structures built up by the various - * clients of ExtFindRegions. The general rule for these - * structures is that their initial fields must be identical - * to those in a Region, but subsequent fields are up to - * the individual client. - * - * Regions marked as GENERIC are the types accepted by - * procedures in ExtRegion.c. - */ - - /* - * GENERIC Region struct. - * All this provides is a pointer to the next Region. - * This is the type passed to functions like ExtFreeRegions, - * and is the type returned by ExtFindRegions. Clients should - * cast pointers of this type to their own, client type. - */ -typedef struct reg -{ - struct reg *reg_next; /* Next region in list */ -} Region; - - /* - * GENERIC region with labels. - * Any other structure that wants to reference node names - * must include the same fields as this one as its first part. - */ -typedef struct lreg -{ - struct lreg *lreg_next; /* Next region in list */ - int lreg_pnum; /* Lowest numbered plane in this region */ - int lreg_type; /* Type of tile that contains lreg_ll */ - Point lreg_ll; /* Lower-leftmost point in this region on - * plane lreg_pnum. We take the min first - * in X, then in Y. - */ - LabelList *lreg_labels; /* List of labels for this region. These are - * any labels connected to the geometry making - * up this region. If the list is empty, make - * up a name from lreg_pnum and lreg_ll. - */ -} LabRegion; - - /* - * Node region: labelled region with resistance and capacitance. - * Used for each node in the flat extraction of a cell. - */ - -typedef struct -{ - int pa_perim; - int pa_area; -} PerimArea; - -typedef struct nreg -{ - struct nreg *nreg_next; /* Next region in list */ - int nreg_pnum; /* Lowest numbered plane in this region */ - int nreg_type; /* Type of tile that contains nreg_ll */ - Point nreg_ll; /* Lower-leftmost point in this region on - * plane nreg_pnum. We take the min first - * in X, then in Y. - */ - LabelList *nreg_labels; /* See LabRegion for description */ - CapValue nreg_cap; /* Capacitance to ground */ - ResValue nreg_resist; /* Resistance estimate */ - PerimArea nreg_pa[1]; /* Dummy; each node actually has - * ExtCurStyle->exts_numResistClasses - * array elements allocated to it. - */ -} NodeRegion; - - /* - * Transistor region: labelled region with perimeter and area. - * Used for each transistor in the flat extraction of a cell. - */ -typedef struct treg -{ - struct treg *treg_next; /* Next region in list */ - int treg_pnum; /* UNUSED */ - int treg_type; /* Type of tile that contains treg_ll */ - Point treg_ll; /* UNUSED */ - LabelList *treg_labels; /* Attribute list */ - Tile *treg_tile; /* Some tile in the channel */ - int treg_area; /* Area of channel */ -} TransRegion; - -typedef struct { /* Maintain plane information when pushing */ - Rect area; /* tiles on the node stack. For use with */ - int plane; /* function extNbrPushFunc(). */ -} PlaneAndArea; - -/* - * The following constructs a node name from the plane number 'n' - * and lower left Point l, and places it in the string 's' (which must - * be large enough). - */ -#define extMakeNodeNumPrint(buf, plane, coord) \ - (void) sprintf((buf), "%s_%s%d_%s%d#", DBPlaneShortName(plane), \ - ((coord).p_x < 0) ? "n": "", abs((coord).p_x), \ - ((coord).p_y < 0) ? "n": "", abs((coord).p_y)) - -/* Old way: cryptic numbers, but a bit shorter - * - * #define extMakeNodeNumPrint(s, n, l) \ - * (void) sprintf((s), "%d_%d_%d#", (n), extCoord((l).p_x), extCoord((l).p_y)) - * - * The following is used to map the full coordinate space into - * the positive integers, for constructing internally generated - * node names. - * - * #define extCoord(x) (((x) < 0) ? (1 - ((x) << 1)) : ((x) << 1)) - */ - -/* - * Argument passed to filter functions for finding regions. - */ -typedef struct -{ - TileTypeBitMask *fra_connectsTo; /* Array of TileTypeBitMasks. The - * element fra_connectsTo[t] has a - * bit set for each type that - * connects to 't'. - */ - 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 - * been visited. - */ - Region *(*fra_first)(); /* Function to init new region */ - int (*fra_each)(); /* Function for each tile in region */ - Region *fra_region; /* Ptr to Region struct for current - * region. May be set by fra_first - * and used by fra_each. - */ -} FindRegion; - -#define TILEAREA(tp) ((TOP(tp) - BOTTOM(tp)) * (RIGHT(tp) - LEFT(tp))) - -/* -------------------- Perimeter of a region ------------------------- */ - -/* - * Segment of the boundary of a region whose perimeter - * is being traced by ExtTracePerimeter() and extEnumTilePerim(). - */ -typedef struct -{ - Tile *b_inside; /* Pointer to tile just inside segment */ - Tile *b_outside; /* Pointer to tile just outside segment */ - Rect b_segment; /* Actual coordinates of segment */ - unsigned char b_direction; /* Direction following segment (see below) */ - int b_plane; /* extract argument for extSideOverlap */ -} Boundary; - -#define BoundaryLength(bp) \ - ((bp)->b_segment.r_xtop - (bp)->b_segment.r_xbot \ - + (bp)->b_segment.r_ytop - (bp)->b_segment.r_ybot) - -/* Directions in which we can be following the boundary of a perimeter */ - -#define BD_LEFT 0 /* Inside is to right */ -#define BD_TOP 1 /* Inside is below */ -#define BD_RIGHT 2 /* Inside is to left */ -#define BD_BOTTOM 3 /* Inside is above */ - -/* -------- Yank buffers for hierarchical and array extraction -------- */ - -extern CellUse *extYuseCum; -extern CellDef *extYdefCum; - -/* --------------- Argument passed to extHierYankFunc ----------------- */ - -typedef struct -{ - Rect *hy_area; /* Area (in parent coordinates) to be yanked */ - CellUse *hy_target; /* Yank into this use */ - bool hy_prefix; /* If TRUE, prefix labels with use id */ -} HierYank; - -/* ----- Arguments to filter functions in hierarchical extraction ---- */ - - /* - * The following defines an extracted subtree. - * The CellUse et_use will be either a cell we are extracting, - * or a flattened subtree. If et_lookNames is non-NULL, it - * points to a CellDef that we should look in for node names. - */ -typedef struct extTree -{ - CellUse *et_use; /* Extracted cell, usually flattened */ - CellUse *et_realuse; /* If et_use is flattened, et_realuse - * points to the unflattened subtree's - * root use; otherwise it is NULL. - */ - CellDef *et_lookNames; /* See above */ - NodeRegion *et_nodes; /* List of nodes */ - HashTable et_coupleHash; /* Table for coupling capacitance. - * key is type CoupleKey - * value is pointer to type CapValue - */ - struct extTree *et_next; /* Next one in list */ -} ExtTree; - - /* - * The following structure contains information passed down - * through several levels of filter functions during hierarchical - * extraction. - * - * The procedure ha_nodename is used to map from a tile into the - * name of the node to which that tile belongs. It should be of - * the following format: - * - * char * - * proc(tp, et, ha) - * Tile *tp; - * ExtTree *et; - * HierExtractArg *ha; - * { - * } - * - * It should always return a non-NULL string; if the name of a - * node can't be determined, the string can be "(none)". - */ -typedef struct -{ - FILE *ha_outf; /* The .ext file being written */ - CellUse *ha_parentUse; /* Use pointing to the def being extracted */ - char *(*ha_nodename)();/* Map (tp, et, ha) into nodename; see above */ - ExtTree ha_cumFlat; /* Cumulative yank buffer */ - HashTable ha_connHash; /* Connections made during hier processing */ - -/* All areas are in parent coordinates */ - - Rect ha_interArea; /* Area of whole interaction being considered */ - Rect ha_clipArea; /* Only consider capacitance, perimeter, and - * area that come from inside this area. This - * rectangle is contained within ha_interArea. - */ - CellUse *ha_subUse; /* Root of the subtree being processed now */ - Rect ha_subArea; /* Area of ha_subUse inside the interaction - * area, i.e, contained within ha_interArea. - */ - Tile *hierOneTile; /* Used in ExtHier.c, tile from extHierOneFlat */ - int hierPNum; /* Used in ExtHier.c, plane of tile above */ - TileType hierType; /* Used in ExtHier.c, type of tile above */ - int hierPNumBelow; /* Used in ExtHier.c, plane of tile below */ -} HierExtractArg; - -/* - * Normally, nodes in overlapping subcells are expected to have labels - * in the area of overlap. When this is not the case, we have to use - * a much more expensive algorithm for finding the labels attached to - * the subcells' geometry in the overlap area. The following structure - * is used to hold information about the search in progress for such - * labels. - */ -typedef struct -{ - HierExtractArg *hw_ha; /* Describes context of search */ - Label *hw_label; /* We update hw_label with a ptr to a - * newly allocated label if successful. - */ - Rect hw_area; /* Area in parent coordinates of the - * area where we're searching. - */ - bool hw_autogen; /* If TRUE, we trace out all geometry - * in the first node in the first cell - * found to overlap the search area, - * and use the internal name for that - * node. - */ - TerminalPath hw_tpath; /* Hierarchical path down to label - * we are searching for, rooted at - * the parent being extracted. - */ - TileTypeBitMask hw_mask; /* Mask of tile types that connect to - * the tile whose node is to be found, - * and which are on the same plane. - * Used when calling ExtFindRegions. - */ - bool hw_prefix; /* If FALSE, we skip the initial - * use identifier when building - * hierarchical labels (as when - * extracting arrays; see hy_prefix - * in the HierYank struct). - */ - int (*hw_proc)(); -} HardWay; - -/* --------------------- Coupling capacitance ------------------------- */ - -/* - * The following structure is the hash key used for computing - * internodal coupling capacitance. Each word is a pointer to - * one of the nodes being coupled. By convention, the first - * word is the lesser of the two NodeRegion pointers. - */ -typedef struct -{ - NodeRegion *ck_1, *ck_2; -} CoupleKey; - -extern void extCoupleHashZero(); /* Clears out all pointers to data in table */ - -/* ------------------ Interface to debugging module ------------------- */ - -extern ClientData extDebugID; /* Identifier returned by the debug module */ - -/* ----------------- Technology-specific information ------------------ */ - -/* - * Structure used to define sidewall coupling capacitances. - */ -typedef struct edgecap -{ - struct edgecap *ec_next; /* Next edge capacitance rule in list */ - CapValue ec_cap; /* Capacitance (attofarads) */ - TileTypeBitMask ec_near; /* Types closest to causing edge, or in - * the case of sideOverlaps, the - * types we are overlapping. - */ - TileTypeBitMask ec_far; /* Types farthest from causing edge, or - * in the case of sideOverlaps, the - * types that shield the edge from - * the overlaped tile. - */ - int ec_plane; /* if ec_near is TT_SPACE, ec_plane */ - /* specifies which plane is to be */ - /* used. -1 if ec_near isn't space */ -} EdgeCap; - - -/* A type used to determine if current style needs planeorder or not */ -typedef enum { noPlaneOrder, needPlaneOrder, seenPlaneOrder } planeOrderStatus ; - -/* - * Because a large TT_MAXTYPES value quickly generates huge extract section - * structures, we want to keep around only the style names, and dynamically - * load and destroy the extract section values as needed, when doing an - * extraction command. - */ - -typedef struct extkeep -{ - struct extkeep *exts_next; - char *exts_name; -} ExtKeep; - -/* - * Parameters for the process being extracted. - * We try to use use integers here, rather than floats, to be nice to - * machines like Sun workstations that don't have hardware - * floating point. - * - * In the case of capacitances, though, we may have to use floats, depending - * upon the type CapValue. In some newer processes the capacitance per - * lambda^2 is less than 1 attofarad. - */ - -/*---------------------------------------------------------------*/ -/* Structure containing inter-layer information (NT x NT matrix) */ -/*---------------------------------------------------------------*/ - -typedef struct extinterlayerstyle -{ - /* - * Capacitance per unit perimeter. Sidewall capacitance depends both - * on the type inside the perimeter as well as the type outside it, - * so the table is doubly indexed by TileType. - * - * The mask exts_perimCapMask[t] contains bits for all those TileTypes - * 's' such that exts_perimCap[t][s] is nonzero. - */ - CapValue exts_perimCap; - - /* - * Both exts_overlapShieldTypes[][] and exts_overlapShieldPlanes[][] - * are indexed by the same pair of types used to index the table - * exts_overlapCap[][]; they identify the types and planes that - * shield capacitance between their index types. - */ - TileTypeBitMask exts_overlapShieldTypes; - int exts_overlapShieldPlanes; - - /* - * The table extOverlapCap[][] is indexed by two types to give the - * overlap coupling capacitance between them, per unit area. Only - * one of extOverlapCap[i][j] and extOverlapCap[j][i] should be - * nonzero. The capacitance to substrate of the tile of type 'i' - * is deducted when an overlap between i and j is detected, if - * extOverlapCap[i][j] is nonzero. This is only done, however, if - * tile i is below tile j in exts_planeOrder; - */ - CapValue exts_overlapCap; - - /* - * Sidewall coupling capacitance. This capacitance is between edges - * on the same plane, and is in units of attofarads. It is multiplied - * by the value interpolated from a fringing-field table indexed by the - * common length of the pair of edges divided by their separation: - * - * | | - * E1 +----------------------------+ - * ^ - * +--- distance between edges - * v - * +-----------------------------------+ E2 - * | | - * - * <-----------------------> length in common - */ - - /* - * The entry exts_sideCoupleCap[i][j] is a list of the coupling - * capacitance info between edges with type 'i' on the inside - * and 'j' on the outside, and other kinds of edges. - */ - EdgeCap *exts_sideCoupleCap; - - /* - * exts_sideCoupleOtherEdges[i][j] is a mask of those types on the - * far sides of edges to which an edge with 'i' on the inside and - * 'j' on the outside has coupling capacitance. - */ - TileTypeBitMask exts_sideCoupleOtherEdges; - /* - * The entry exts_sideOverlapCap[i][j] is a list of the coupling - * capacitance info between edges with type 'i' on the inside - * and 'j' on the outside, and other kinds of tiles on other - * planes. The ec_near mask in the EdgeCap record identifies the - * types to which we have sidewall overlap capacitance, and the - * ec_far mask identifies the types that shield the tiles preventing - * a capacitance. - */ - EdgeCap *exts_sideOverlapCap; - - /* - * extSideOverlapOtherTypes[i][j] is a mask of those types to which - * an edge with 'i' on the inside and 'j' on the outside has coupling - * capacitance. extSideOverlapOtherPlanes[i][j] is a mask of those - * planes to which edge [i][j] has overlap coupling capacitance. - * exts_sideOverlapShieldPlanes[s][t] is a list of the planes that - * need to be examined for shielding material when we are considering - * a sidewall overlap capacitor between types s and t. This may - * be the "or" of the planes needed by several sideoverlap rules, - * since there can be several types of edges in which type s is - * the "intype" member and the "outtype" member varies. Note that - * sideOverlapShieldPlanes is indexed like overlapShieldPlanes, not - * like sideOverlapOtherPlanes. - */ - int exts_sideOverlapOtherPlanes; - int exts_sideOverlapShieldPlanes; - TileTypeBitMask exts_sideOverlapOtherTypes; - -} ExtInterLayerStyle; - -/*-----------------------------------------------------------*/ -/* Structure containing per-layer information (1 x NT array) */ -/*-----------------------------------------------------------*/ - -typedef struct extlayerstyle -{ - /* - * Connectivity tables. - * Each table is an array of TileTypeBitMasks indexed by TileType. - * The i-th element of each array is a mask of those TileTypes - * to which type 'i' connects. - */ - - /* Everything is connected to everything else in this table */ - TileTypeBitMask exts_allConn; - - /* - * Connectivity for determining electrical nodes. - * This should be essentially the same as DBConnectTbl[]. - */ - TileTypeBitMask exts_nodeConn; - - /* - * Connectivity for determining resistive regions. - * Two types should be marked as connected here if - * they are both connected in exts_nodeConnect[], and - * if they both have the same resistance per square. - */ - TileTypeBitMask exts_resistConn; - - /* - * Connectivity for determining transistors. - * Each transistor type should connect only to itself. - * Nothing else should connect to anything else. - */ - TileTypeBitMask exts_transConn; - - /* - * Sheet resistivity for each tile type, in milli-ohms per square. - * For types that are transistors or capacitors, this corresponds - * to the sheet resistivity of the gate. - */ - - /* Maps from a tile type to the index of its sheet resistance entry */ - int exts_typeToResistClass; - - /* Gives a mask of neighbors of a type with different resistivity */ - TileTypeBitMask exts_typesResistChanged; - - /* - * Resistance information is also provided by the following tables: - * exts_typesByResistClass[] is an array of masks of those types - * having the same sheet resistivity, for each different value - * of sheet resistivity; exts_resistByResistClass[] is a parallel array - * giving the actual value of sheet resistivity. Both are indexed - * from 0 up to (but not including) exts_numResistClasses. - */ - TileTypeBitMask exts_typesByResistClass; - ResValue exts_resistByResistClass; - - /* Resistance per type */ - ResValue exts_sheetResist; - - /* - * Resistances for via holes. - * These have four parts: the size, border, and spacing - * of a minimum-size contact (it's assumed to be square), - * and the resistance of its via hole. The resistance is - * given in milliohms. - */ - int exts_viaSize; - int exts_viaSpacing; - int exts_viaBorder; - ResValue exts_viaResist; - - /* Layer height and thickness used by the geometry extractor */ - float exts_height; - float exts_thick; - - /* - * Capacitance to substrate for each tile type, in units of - * attofarads per square lambda. - */ - - /* - * Capacitance per unit area. This is zero for explicit capacitor - * types, which handle gate-channel capacitance specially. For - * transistor types, this is at best an approximation that is - * truly valid only when the transistor is switched off. - */ - CapValue exts_areaCap; - - TileTypeBitMask exts_perimCapMask; - - /* - * Overlap coupling capacitance for each pair of tile types, in units - * of attofarads per square lambda of overlap. - * Internodal capacitance due to overlap only occurs between tile - * types on different tile planes that are not shielded by intervening - * tiles. - */ - - /* - * The mask exts_overlapOtherPlanes[t] is a mask of the planes that - * must be searched for tiles having overlap capacitance with tiles - * of type 't', and exts_overlapOtherTypes[t] is a mask of the types - * with which our overlap capacitance is non-zero. - */ - TileTypeBitMask exts_overlapOtherTypes; - int exts_overlapOtherPlanes; - - /* - * Sidewall-overlap coupling capacitance. - * This is between an edge on one plane and a type on another plane - * that overlaps the edge (from the outside of the edge), and is in - * units of attofarads per lambda. - * - * When an edge with sidewall capacitance to substrate is found to - * overlap a type to which it has sidewall overlap capacitance, the - * original capacitance to substrate is replaced with the overlap - * capacitance to the tile overlapped, if the edge is above the tile - * being overlapped (according to ext_planeOrder). If the tiles are - * the other way around, then this replacement is not done. - */ - - /* - * The mask exts_sideEdges[i] is just a mask of those types j for - * which either exts_sideCoupleCap[i][j] or exts_sideOverlapCap[i][j] - * is non-empty. - */ - TileTypeBitMask exts_sideEdges; - - /* Transistors */ - - /* Name of each transistor type as output in .ext file */ - char *exts_transName; - - /* Device class */ - char exts_deviceClass; - - /* - * Per-square resistances for each possible transistor type, - * in the various regions that such a type might operate. - * The only operating region currently used is "linear", - * which the resistance extractor uses in its thresholding - * operation. NOTE: resistances in this table are in OHMS - * per square, not MILLIOHMS! - */ - HashTable exts_transResist; - ResValue exts_linearResist; - - /* - * Mask of the types of tiles that connect to the channel terminals - * of a transistor type. The intent is that these will be the - * diffusion terminals of a transistor, ie, its source and drain. - * UPDATED May, 2008: Record is a list of type masks, allowing - * multiple terminal types in the case of, e.g., high-voltage - * or other asymmetric devices. The last entry in the list should - * be equal to DBSpaceBits. - */ - TileTypeBitMask *exts_transSDTypes; - - /* - * Maximum number of terminals (source/drains) per transistor type. - * This table exists to allow the possibility of transistors with - * more than two diffusion terminals at some point in the future. - */ - int exts_transSDCount; - - /* Currently unused: gate-source capacitance per unit perimeter */ - CapValue exts_transSDCap; - - /* Currently unused: gate-channel capacitance per unit area */ - CapValue exts_transGateCap; - - /* - * Each type of transistor has a substrate node. By default, - * it is the one given by exts_transSubstrateName[t]. However, - * if the mask exts_transSubstrateTypes[t] is non-zero, and if - * the transistor overlaps material of one of the types in the - * mask, then the transistor substrate node is the node of the - * material it overlaps. - */ - char *exts_transSubstrateName; - TileTypeBitMask exts_transSubstrateTypes; - TileTypeBitMask exts_subsTransistorTypes; - - ExtInterLayerStyle *eils[NT]; /* inter-layer information */ - /* (dynamically allocated) */ -} ExtLayerStyle; - -/*-----------------------------------------------------------*/ -/* Structure containing per-plane information (1 x NP array) */ -/*-----------------------------------------------------------*/ - -typedef struct extplanestyle -{ - /* Specifies an ordering of the planes, so we can determine which - * tile is above another one. This is used only when determining - * if we should subtract capacitance to substrate for overlap and - * sideoverlap rules. If no planeorder is specified and the style - * does not contain a noplaneordering command a warning is issued - * and the default planeorder is used for the style. - */ - int exts_planeOrder; - /* - * The mask exts_overlapPlanes is a mask of those planes that must - * be searched for tiles having overlap capacitance, and the mask - * exts_overlapTypes[p] is those types having overlap capacitance - * on each plane p. The intent is that exts_overlapTypes[p] lists - * only those types t for which some entry of exts_overlapCap[t][s] - * is non-zero. - */ - TileTypeBitMask exts_overlapTypes; - - /* Common to both sidewall coupling and sidewall overlap */ - - /* - * exts_sideTypes[p] is a mask of those types 't' having sidewall - * coupling or sidewall overlap capacitance on plane p (i.e, for - * which a bin in exts_sideCoupleCap[t][] or exts_sideOverlapCap[t][] - * is non-empty), and exts_sidePlanes a mask of those planes containing - * tiles in exts_sideTypes[]. - */ - TileTypeBitMask exts_sideTypes; - -} ExtPlaneStyle; - -/*--------------------------------------------------------------*/ -/* Main extraction style information */ -/*--------------------------------------------------------------*/ - -typedef struct extstyle -{ - char exts_status; /* Loaded, not loaded, or pending */ - char *exts_name; /* Name of this style */ - - int exts_sidePlanes; - int exts_overlapPlanes; - - /* set/reset with planeorder commands to determine whether - * we will warn if no planeorder is specified. This is done - * because at Stanford we use a lot of diagnostic extraction - * styles (for floating wells etc.) and we don't want to specify - * the planeorder for each and every one of them. - */ - - planeOrderStatus exts_planeOrderStatus; - - /* - * We search out a distance exts_sideCoupleHalo from each edge - * for other types with which we have coupling capacitance. - * This value determines how much extra gets yanked when - * computing hierarchical adjustments, so should be kept - * small to insure reasonable performance. - */ - int exts_sideCoupleHalo; - - int exts_numResistClasses; - - /* Scaling */ - /* - * Step size used when breaking up a large cell for interaction - * checks during hierarchical extraction. We check exts_stepSize - * by exts_stepSize chunks for interactions one at a time. - */ - int exts_stepSize; - - /* - * Number of linear units per lambda. All perimeter dimensions - * that we output to the .ext file should be multiplied by - * exts_unitsPerLambda; we produce a "scale" line in the .ext file - * indicating this. All area dimensions should be multiplied - * by exts_unitsPerLambda**2. - * (changed to type float May 11, 2006 to accommodate, e.g., 90 - * and 130 nm technologies) - */ - float exts_unitsPerLambda; - - /* - * Scaling for resistance and capacitance. - * All resistances in the .ext file should be multiplied by - * exts_resistScale to get milliohms, and all capacitances by - * exts_capScale to get attofarads. These numbers appear in - * the "scale" line in the .ext file. - */ - int exts_capScale; - int exts_resistScale; - - /* Contains one for each type of fet, zero for all other types */ - TileTypeBitMask exts_transMask; - - ExtLayerStyle *els[NT]; /* Per-layer information (allocated) */ - ExtPlaneStyle *eps[NP]; /* Per-plane information (allocated) */ - -} ExtStyle; - -#define EXT_PLUG_GND 1 -#define EXT_PLUG_VDD 2 - -extern ExtStyle *ExtCurStyle; - -/* ------------------- Hierarchical node merging ---------------------- */ - -/* - * Table used to hold all merged nodes during hierarchical extraction. - * Used for duplicate suppression. - */ -extern HashTable extHierMergeTable; - -/* - * Each hash entry in the above table points to a NodeName struct. - * Each NodeName points to the Node corresponding to that name. - * Each Node points back to a list of NodeNames that point to that - * Node, and which are linked together along their nn_next fields. - */ -typedef struct nn -{ - struct node *nn_node; /* Node for which this is a name */ - char *nn_name; /* Text of name */ - struct nn *nn_next; /* Other names of nn_node */ -} NodeName; - -typedef struct node -{ - NodeName *node_names; /* List of names for this node. The first name - * in the list is the "official" node name. - */ - CapValue node_cap; /* Capacitance to substrate */ - PerimArea node_pa[1]; /* Dummy; each node actually has - * ExtCurStyle->exts_numResistClasses - * array elements allocated to it. - */ -} 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; - -#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 */ - -#ifdef NONMANHATTAN - -/* Note that this macro depends on MAXPLANES being small */ -/* compared to the bit position of TT_SIDE. Since tens of */ -/* thousands of planes is inconceivable, this should not be a */ -/* problem. It is necessary to push the tile's TT_SIDE bit */ -/* because the search algorithm can overwrite it between the */ -/* time the tile is pushed and the time that it is popped. */ - -#define PUSHTILE(tp, pl) \ - (tp)->ti_client = VISITPENDING; \ - STACKPUSH((ClientData)(pointertype)(pl | \ - ((TileType)(spointertype)(tp)->ti_body & TT_SIDE)), extNodeStack); \ - STACKPUSH((ClientData)(pointertype)tp, extNodeStack) - -#define POPTILE(tp, pl) \ - tp = (Tile *) STACKPOP(extNodeStack); \ - pl = (spointertype) STACKPOP(extNodeStack); \ - if (pl & TT_SIDE) { \ - TiSetBody((tp), TiGetTypeExact(tp) | TT_SIDE); \ - pl &= (~TT_SIDE); \ - } \ - else \ - TiSetBody((tp), TiGetTypeExact(tp) & (~TT_SIDE)) - -/* Variations of "pushtile" to force a specific value on TT_SIDE */ - -#define PUSHTILEBOTTOM(tp, pl) \ - (tp)->ti_client = VISITPENDING; \ - STACKPUSH((ClientData)(pointertype)(pl | \ - ((SplitDirection(tp)) ? 0 : TT_SIDE)), extNodeStack) ;\ - STACKPUSH((ClientData)(pointertype)tp, extNodeStack) - -#define PUSHTILETOP(tp, pl) \ - (tp)->ti_client = VISITPENDING; \ - STACKPUSH((ClientData)(pointertype)(pl | \ - ((SplitDirection(tp)) ? TT_SIDE : 0)), extNodeStack) ;\ - STACKPUSH((ClientData)(pointertype)tp, extNodeStack) - -#define PUSHTILELEFT(tp, pl) \ - (tp)->ti_client = VISITPENDING; \ - STACKPUSH((ClientData)(pointertype)(pl), extNodeStack); \ - STACKPUSH((ClientData)(pointertype)tp, extNodeStack) - -#define PUSHTILERIGHT(tp, pl) \ - (tp)->ti_client = VISITPENDING; \ - STACKPUSH((ClientData)(pointertype)(pl | TT_SIDE), extNodeStack); \ - STACKPUSH((ClientData)(pointertype)tp, extNodeStack) - -#else - -#define PUSHTILE(tp, pl) \ - (tp)->ti_client = VISITPENDING; \ - STACKPUSH((ClientData)pl, extNodeStack); \ - STACKPUSH((ClientData)tp, extNodeStack) - -#define POPTILE(tp, pl) \ - tp = (Tile *) STACKPOP(extNodeStack); \ - pl = (int) STACKPOP(extNodeStack) - -#endif - -/* ------------------------- Region finding --------------------------- */ - -extern Region *ExtFindRegions(); - -/* Filter functions for ExtFindRegions() */ -extern Region *extTransFirst(); extern int extTransEach(); -extern Region *extResFirst(); extern int extResEach(); -extern Region *extNodeFirst(); extern int extNodeEach(); -extern Region *extHierLabFirst(); extern int extHierLabEach(); - -/* -------- Search for matching tile/node in another ExtTree ---------- */ - -/* - * NODETOTILE(np, et, tp) - * NodeRegion *np; - * ExtTree *et; - * Tile *tp; - * - * Sets tp to be the tile containing the lower-leftmost point of the - * NodeRegion *np, but in the tile planes of the ExtTree *et instead - * of the tile planes originally containing *np. - */ -#define NODETOTILE(np, et, tp) \ - if (1) { \ - Plane *myplane = (et)->et_use->cu_def->cd_planes[(np)->nreg_pnum]; \ -\ - (tp) = myplane->pl_hint; \ - GOTOPOINT(tp, &(np)->nreg_ll); \ - myplane->pl_hint = (tp); \ - } - -/* - * NODETONODE(nold, et, nnew) - * NodeRegion *nold; - * ExtTree *et; - * NodeRegion *nnew; - * - * Like NODETOTILE above, but leaves nnew pointing to the node associated - * with the tile we find. - */ -#define NODETONODE(nold, et, nnew) \ - if (1) { \ - Tile *tp; \ - \ - (nnew) = (NodeRegion *) NULL; \ - NODETOTILE((nold), (et), tp); \ - if (tp && extHasRegion(tp, extUnInit)) \ - (nnew) = (NodeRegion *) extGetRegion(tp); \ - } - -/* -------------------- Miscellaneous procedures ---------------------- */ - -extern char *extNodeName(); -extern NodeRegion *extBasic(); -extern NodeRegion *extFindNodes(); -extern ExtTree *extHierNewOne(); -extern int extNbrPushFunc(); - -/* --------------------- Miscellaneous globals ------------------------ */ - -extern int extNumErrors; /* Number of errors encountered so far */ -extern int extNumWarnings; /* Number warning messages so far */ -extern CellUse *extParentUse; /* Dummy use for def being extracted */ -extern ClientData extNbrUn; /* Ditto */ - - /* - * This is really a (Stack *), but we use the struct tag to avoid - * having to include stack.h in every .c file. Used in the non-recursive - * flooding algorithm. - */ -extern struct stack *extNodeStack; - -/* ------------------ Connectivity table management ------------------- */ - -/* - * The following is true if tile types 'r' and 's' are connected - * according to the connectivity table 'tbl' - */ -#define extConnectsTo(r, s, tbl) ( TTMaskHasType(&(tbl)[(r)], (s)) ) - -/* -------------------------------------------------------------------- */ - -#include "extDebugInt.h" - -#endif /* _EXTRACTINT_H */ diff --git a/resis/ResMain.c b/resis/ResMain.c index ab3535bd..0d76140d 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -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 diff --git a/sim/SimExtract.c b/sim/SimExtract.c index 94874d62..26fb3281 100644 --- a/sim/SimExtract.c +++ b/sim/SimExtract.c @@ -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;