diff --git a/README b/README index 643382ac..97cadc77 100644 --- a/README +++ b/README @@ -58,6 +58,9 @@ To be fixed: STACKPUSH/STACKPOP stuff in resis/ResUtils.c extract to handle two clientData records for split tiles in ResAddPlumbing and ResRemovePlumbing. + Some changes to stack handling were pretty hastily done and all should + be checked for consistency. + dbcUnconnectFunc() --- Need to handle side, or is this already handled? extConnFindFunc() --- Select proper region depending on side @@ -79,6 +82,7 @@ To be fixed: STACKPUSH/STACKPOP stuff in resis/ResUtils.c ResMultiPlaneFunc() --- Needs to call ResNewSDDevice() with dinfo information Any routine that does not use "dinfo" should do "if (dinfo & TT_SIDE) return 0". +No, that's not needed. Ought to create a single function for simply returning "1" and replace all the assorted functions that do that individually. @@ -90,7 +94,7 @@ completed. Moving on to compiling. . . CIFgen.c has lots of warnings around PUSHTILE(). Probably an incorrect cast, but -I need to check all of the uses of PUSH and POP everywhere, anyway. +I need to check all of the uses of PUSH and POP everywhere, anyway. (done) 1/2/2026: Compiles now! @@ -98,26 +102,274 @@ Debug. . . Errors in dbwind (missed a DBSrPaintArea() call) Need to pass dinfo to GrBox() and GrBoxOutline() -Issue: Paint square on top of diagonal edge, ends up with one part of the tile -not properly split at the edge; the tile goes to infinity and has a non-space -type. - Reminder: Need to check for all instances of SplitSide(), as there should not -be any. There are still 38 references that need to be removed. +be any. There are still 38 references that need to be removed. (done) Fix: extWalkTop (Bottom, Right, Left). . . type should not have been set by the split side of tile "tp". Should be according to the side being searched -and the diagonal directions of "tile" and "tp". +and the diagonal directions of "tile" and "tp". (done) ResUtils: Cannot use STACKPUSH and STACKPOP A number of remaining uses of SplitSide() are in routines that were not fixed for dinfo or are not directly called from modified search functions, so will -need to fix each one in turn. +need to fix each one in turn. (done) Add dinfo to extSubtreeTileToNode() and extSubtreeHardNode() -extNodeToTile needs to return dinfo. . . +extNodeToTile needs to return dinfo. . . (done) extGetRegion() will need to be handled but only when I'm done with this and working on being able to attach two regions to a split tile. +=============== +To do: Fix the several places where the compiler spits out warnings. +(1) ExtHier.c:43 use of TileType in extNodeToTile (extractInt.h:1060) (done) + +(2) CIFgen.c:1237, 1339: Issues with using PUSHTILE and STACKPUSH, + should not cast dinfo to type ClientData; use INT2CD(dinfo). + Also didn't like (TileType)STACKPOP. . . Use (TileType)CD2INT(STACKPOP(...)) + (done) + +Okay, those are fixed. + +=============== +Large-scale tests: +(1) Ran on gf180mcu_ocd_sram_test; + Running full DRC. (passed) (not exhaustive!) + +Also need to test: + GDS output (passed) (eh, not exactly) (okay, good now) + GDS input (passed) + extraction (oops, segfault) (ExtHier.c:518) + extresist + net selection + antenna checks + LEF read + LEF write + DEF read + DEF write + +Especially need to check the sky130 I/O where there are split tiles with both +sides active. Still need to resolve the issue with attaching two net regions +to a single split tile, and to return the correct region entry. + +Oops, reading gf180mcu_ocd_sram_top.gds.gz back after writing, then letting +DRC run, crashed at some point. Probably in DRC, but unsure. Will try to +repeat. Yes, missed a routine drcSubCopyErrors(). Because it's run from +DBNoTreeSrTiles(). + +Another issue---GDS input failed to read in some non-manhattan tiles; use +klayout to make sure that GDS output was correct. (yes) GDS may have just +been corrected after an error was found; check GDS read again (nope). +Doesn't happen with metal1, for example, only with psd (in the GF tech). +Issue is that PPLUS triangles are inverted in a number of places, so +output generation was messed up somewhere. + +Tested and found "shrink" to be the cause. +DBDiagonalProc() was the cause. Its setting of TT_SIDE at the end was +non-functional (DBUndo does not use it, as claimed), and the bit was +getting set in the tile and disrupting any code using "TiGetTypeExact(tile) | dinfo". +Maybe there should be a guard against anything setting the TT_SIDE bit in a +Tile's ti_body field? + +Re-running run_gen_gds.sh on the SRAM test chip to see if that fixed the I/O +corner cell. + +Well. . . Almost. cifoutput hierarchical checks generated extra non-manhattan +geometry on the top level which is not *wrong* but shouldn't be there and was +not there before the code changes. + +Found a place where "dinfo" was not handled; fixed, and retrying. . . Good. + +------------------------- + +Next major error: PUSHTILE caused a "corrupted double-linked list (not small)" +error, from ExtNghbors.c:197. Modifications to the code that shouldn't have +changed anything seem to have made this pass, although can't tell yet if it +works correctly. Getting another error "free(): invalid next size (fast)" +error on ExtFreeLabRegions() now. . . + +Maybe best debugged with valgrind. . . +Looks like it comes down to "extSubtreeHardNode()" being passed a split tile. +Before that, extSubtreeTileToNode() on a split tile. +From extHierConnectFunc2(), + ha->hierOneTile is split. + Split dir = 1, right type = 117 (metal 3), left type = space + Typical case. . . + ha->hierType looks correct. TT_SIDE set, looking at right side, + which is metal3. +Down in extSubtreeHardNode(), ttype = 117 (okay) +extSubtreeHardUseFunc called on POWER_RAIL_COR_1_0. +Then it calls ExtFindRegions on POWER_RAIL_COR_1, which created the label region, +and then calls ExtLabelRegions, where tile tp is a simple metal 3 tile +at (46068, 14000), "reg" is its ti_client, but reg had been freed. + +Therefore, ExtFindNeighbors() at extract/ExtHard.c:509 did not search all of the +tiles that were originally tagged by ExtFindRegions() at extract/ExtHard.c:207. +Maybe this is due to how reg->treg_tile and reg->treg_type are set? + +ExtFindRegions calls DBSrPaintClient() with callback extRegionAreaFunc() +extRegionAreaFunc() calls ExtFindNeighbors(). + +ExtFindNeighbors() uses macros like PUSHTILERIGHT, etc., which could always be +wrong, as could the use use of dinfo when deciding what to check and what to +skip. Double-check everything in this routine. (looks okay) + +The most problematic case is if a region's tile is set to a split tile. +This will eventually not be a problem when the regions are handled between +splits. But for now, it might cause serious problems. Try breaking when +this happens and see if that might be related (as it, it only happens right +before magic crashes). + +Or. . . just rewrite some of this so that magic doesn't try to move the +region's tile off of the split tile? (There was one instance of this. +Changed it and re-running). Presumably was a good thing to do, but didn't +change anything regarding the crash condition. +Hm. But also: ExtBasic.c:4547 is doing the same thing. +Changed that, still no luck. Grrr. +Might be the missing treg_type in ExtLabFirst, which would need to be added; +the routine does not depend on the tile type, but would still require the +dinfo to be saved. +And. . . Still no luck. *sob* +"sublist" is related to sticky labels and is not being freed under some +circumstances. I don't think this is related, but should be fixed. + +Huh. Maybe try a careful check between the original and new versions of +each of these files? + extract/ExtRegion.c + extract/ExtNghbors.c + extract/ExtHard.c + extract/ExtSubtree.c + extract/ExtHier.c + +If all else fails, create a routine to dump a list of tiles being set to +regions, and tiles being cleared of regions, to be activated on POWER_RAIL_COR_0, +so that the complete list of tiles being visted to set regions and tiles being +visited to clear regions can be compared directly. + +Actually, this is probably more productive than looking at the file differences. +Run again so that at the point of failure, can move up the call stack to find +a routine where a node or def can be checked for turning the diagnostic on or +off. + +When valgrind catches the use of freed memory, ExtLabelRegions def->cd_name is +"POWER_RAIL_COR_1", although the last printed statement said that POWER_RAIL_COR_0 +was being extracted; I think it's because this is a use. +The routine common to both the error and the place where the memory was freed +is extSubtreeHardUseFunc(). So: +1) At extSubtreeHardUseFunc, if use->cu_id is "POWER_RAIL_COR_1_0", enable the + diagnostic +2) With the diagnostic enabled, list every region and every tile encountered by + ExtFindNeighbors() that is connected to that region. + Or maybe can get more targeted than that? + +Oh, no, . . . when I output diagnostics, the error doesn't occur. . . +So how does LVS validation do? +The diagnostic output is long. May need to redo it as two files, so that +the "set" and "reset" lists can be checked side by side for any discrepancies. +But if no error occurs when diagnostic output is enabled, then how can I catch +the error? + +Well, divergent behavior *did* show up. At line 22266 of the output: +It appears that ExtFindNeighbors() called from extHardFreeAll() stopped after +the first tile. + +Tile @(46528 17492) type 0x50000075 +Confirmed that this is +(1) Not the first time that a split tile is the first encountered, BUT +(2) This is the first time that a split tile is encountered with the active tile + type on the left. +Need to redo this and print the diagonal information. Not really necessary, though. +Can stop printing diagnostics now and concentrate on finding what happens when +ExtFindNeighbors encounters the tile at (46528, 17492) immediately after being +called from extRegionAreaFunc or from FreeAll. + +Now can break on ExtNghbors.c:138 and 142 when tile->ti_ll.p_x == 46528 && +tile->ti_ll.p_y == 17492 and see what's going on. + +Dinfo is 0x40000000 = TT_DIAGONAL. +topside skips. +leftside is run, pushes m3 (not split) tile at 42868, 17492. +Dinfo is 0x70000075 --> TT_SIDE has been set here, but should not have been. +Moving up, treg_type has been set to 0x70000075 for this region. Note that +treg_ll is not the location of treg_tile (treg_ll = 14000, 42497). + +Need to find when treg_type was set inappropriately. +Note that extractInt.h says that "treg_type" is the type of treg_tile, which was +changed from "type of tile that contains treg_ll", which may be an indicator of +the issue. . . + +Watch where treg_type is set in ExtBasic.c and ExtHard.c. . . +We've got: ExtHard.c:91 + ExtBasic.c:4610 (not relevant) + +Setting reg->treg_type to dinfo is missing from extTransFirst. + +Still not clear what's going on. +The "labRegList" generated by ExtFindRegions() should be the same one as originally +added in extLabFirst(). + +So rerun (again), break as above on ExtHard.c:91, and track when the reg->treg_type +changed. + +Looks like "extSetNodeNum" is the culprit. The type is changed to the new tile +representing the lower left-hand corner and plane. It is not immediately clear if +not saving dinfo with the the lreg_ll and lreg_pnum information will cause problems, +but that information should be recoverable in other ways (i.e., if the tile at point +lreg_ll on lreg_pnum is split and the type at lreg_ll is not lreg_type, then the +side must be changed). + +$$#!@ still caused a segfault. +Okay, I screwed something up badly. +The two processes now diverge on the very first call. +Now fails at tile (42868, 14000) +I do see an error, so try again. . . +Ah, some light at the end of the tunnel! Maybe joy! + +Looks right. Removing diagnostics from the code and re-running with valgrind. +. . . And now it seems to have gone into an infinite loop. But I forgot to +do a "make install" and may have just caused a massive issue. +Did the install and re-ran. POWER_RAIL_COR does take a long time to run, +so each parent cell will be worse, so it's likely just an issue with this cell, +extraction, and valgrind. Let it run to completion, and then later compare to +running without valgrind. Make sure that in both cases, the final netlist +result passes LVS. (Conclusion: Yes, it finished running under valgrind, +eventually, and valgrind did not have any more issues. But that was a long +running process and I will try to do that as little as possible.) + +Side note: This example has another interesting feature which is that halfway +through, it goes back to the prompt, which is a known issue with "extract" but +it hasn't been obvious how it happens. It should be possible to Ctrl-C out of +a long-running extraction but it should *not* be possible to run commands while +the extraction is ongoing. It appears to happen because only part of the design +is loaded when extraction starts. When magic goes to load the rest of the design, +it returns to the prompt. + +--------------- + +NOTE to self: The main thing now needing handling for extraction is to have + extGetRegion(tp, dinfo) +and call this appropriately everywhere. Where tp is part of a boundary +record, it should be possible to derive dinfo. + +--------------- +For now, from January 5: +Back to general checks: +Repeating the list from above: +Need to test: + + GDS output (passed) + GDS input (passed) + extraction (pending) (fixed cap coupling issues) + net selection (seems okay) + antenna checks + LEF read + LEF write + DEF read + DEF write + extresist + +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. diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index 0e4d4f0d..afbaa0d0 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -1309,7 +1309,7 @@ gdsCopyPaintFunc( TiToRect(tile, &sourceRect); GeoTransRect(trans, &sourceRect, &targetRect); if (IsSplit(tile)) - newdinfo = DBTransformDiagonal(TiGetTypeExact(tile), trans); + newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, trans); } else TiToRect(tile, &targetRect); diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 95a923c0..df5037df 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -1233,18 +1233,18 @@ endbloat: #define PUSHTILE(tp, dinfo, stack) \ if (TiGetClient(tp) == CIF_UNPROCESSED) { \ TiSetClientINT(tp, CIF_PENDING); \ - STACKPUSH((ClientData)(tp), stack); \ - STACKPUSH((ClientData)(dinfo), stack); \ + STACKPUSH(PTR2CD(tp), stack); \ + STACKPUSH(INT2CD(dinfo), stack); \ } /* Unconditional push */ #define PUSHTILEALWAYS(tp, dinfo, stack) { \ - STACKPUSH((ClientData)(tp), stack); \ - STACKPUSH((ClientData)(dinfo), stack); \ + STACKPUSH(PTR2CD(tp), stack); \ + STACKPUSH(INT2CD(dinfo), stack); \ } #define POPTILE(tp, dinfo, stack) { \ - dinfo = (TileType)STACKPOP(stack); \ + dinfo = (TileType)CD2INT(STACKPOP(stack)); \ tp = (Tile *)STACKPOP(stack); \ } @@ -1253,7 +1253,7 @@ endbloat: #define PUSHTILEONLY(tp, stack) \ if (TiGetClient(tp) == CIF_UNPROCESSED) { \ TiSetClientINT(tp, CIF_PENDING); \ - STACKPUSH((ClientData)(tp), stack); \ + STACKPUSH(PTR2CD(tp), stack); \ } #define POPTILEONLY(tp, stack) { \ @@ -1407,9 +1407,7 @@ cifBloatAllFunc( /* processed that belongs to the connect mask, and use that as the */ /* starting tile. */ - type = TiGetType(tile); /* NOTE: This does not correctly handls - * split tiles. - */ + type = (dinfo & TT_SIDE) ? TiGetRightType(tile) : TiGetLeftType(tile); if (type == CIF_SOLIDTYPE) { diff --git a/cif/CIFhier.c b/cif/CIFhier.c index 6a75bc6c..f4d1ae94 100644 --- a/cif/CIFhier.c +++ b/cif/CIFhier.c @@ -619,7 +619,7 @@ cifHierCheckFunc( DBSrPaintNMArea((Tile *)NULL, plane, TiGetTypeExact(tile) | dinfo, &area, &DBSpaceBits, cifHierErrorFunc, (ClientData) &area); - DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFEraseTable, + DBNMPaintPlane(plane, TiGetTypeExact(tile) | dinfo, &area, CIFEraseTable, (PaintUndoInfo *) NULL); } else @@ -699,7 +699,7 @@ cifHierPaintFunc( Rect area; TiToRect(tile, &area); - if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, &area); + if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, dinfo, &area); if (IsSplit(tile)) DBNMPaintPlane(plane, TiGetTypeExact(tile) | dinfo, &area, CIFPaintTable, (PaintUndoInfo *) NULL); @@ -1073,6 +1073,7 @@ cifHierElementFunc( int cifGrowSliver( Tile *tile, + TileType dinfo, /* Split tile information, needs to be handled */ Rect *area) { int height, width, expand_up, expand_side; @@ -1141,16 +1142,16 @@ cifHierPaintArrayFunc( int i, j, xbot, xtop; TiToRect(tile, &area); - if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, &area); + if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, dinfo, &area); xbot = area.r_xbot; xtop = area.r_xtop; for (i=0; iscx_trans); + newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, &scx->scx_trans); } + else + newdinfo = (TileType)0; /* Construct the rect for the tile */ TITORECT(tile, &sourceRect); @@ -1032,8 +1034,10 @@ dbPaintSubFunc(tile, dinfo, cxp) { loctype = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); if (loctype == TT_SPACE) return 0; - newdinfo = DBTransformDiagonal(dinfo, &scx->scx_trans); + newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, &scx->scx_trans); } + else + newdinfo = (TileType)0; /* Construct the rect for the tile */ TITORECT(tile, &sourceRect); @@ -1079,8 +1083,10 @@ dbEraseNonSub(tile, dinfo, cxp) { loctype = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); if (loctype == TT_SPACE) return 0; - newdinfo = DBTransformDiagonal(dinfo, &scx->scx_trans); + newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, &scx->scx_trans); } + else + newdinfo = (TileType)0; /* Construct the rect for the tile */ TITORECT(tile, &sourceRect); diff --git a/database/DBpaint.c b/database/DBpaint.c index 37371de6..751c2e91 100644 --- a/database/DBpaint.c +++ b/database/DBpaint.c @@ -1435,10 +1435,6 @@ DBDiagonalProc(oldtype, dinfo) else return -1; - /* For purposes of "undo" recording, record which side we just painted */ - if (dinfo->side) - newtype |= TT_SIDE; - return newtype; } diff --git a/drc/DRCsubcell.c b/drc/DRCsubcell.c index 3c714d3e..d328c4b0 100644 --- a/drc/DRCsubcell.c +++ b/drc/DRCsubcell.c @@ -158,8 +158,9 @@ drcFindOtherCells(use, dlu) */ int -drcSubCopyErrors(tile, cxp) +drcSubCopyErrors(tile, dinfo, cxp) Tile *tile; + TileType dinfo; /* (unused) */ TreeContext *cxp; { Rect area; @@ -421,7 +422,6 @@ DRCFindInteractions(def, area, radius, interaction) CellUse *use; SearchContext scx; Rect searchArea, intArea; - int flags; struct drcSubcellArg dsa; struct drcLinkedUse *curDLU; @@ -494,24 +494,21 @@ DRCFindInteractions(def, area, radius, interaction) /* If errors are being propagated up from child to parent, */ /* then the interaction area is always valid. */ - if (!(flags & PROPAGATE_FLAG)) + for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++) { - for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++) + if (DBSrPaintArea((Tile *) NULL, def->cd_planes[i], + &intArea, &DBAllButSpaceBits, drcAlwaysOne, + (ClientData) NULL) != 0) { - if (DBSrPaintArea((Tile *) NULL, def->cd_planes[i], - &intArea, &DBAllButSpaceBits, drcAlwaysOne, - (ClientData) NULL) != 0) - { - use = (CellUse *) -1; - break; - } + use = (CellUse *) -1; + break; } - scx.scx_use = DRCDummyUse; - scx.scx_trans = GeoIdentityTransform; - scx.scx_area = intArea; - if (DBTreeSrCells(&scx, 0, drcSubCheckPaint, (ClientData) &use) == 0) - return 0; } + scx.scx_use = DRCDummyUse; + scx.scx_trans = GeoIdentityTransform; + scx.scx_area = intArea; + if (DBTreeSrCells(&scx, 0, drcSubCheckPaint, (ClientData) &use) == 0) + return 0; /* OK, no more excuses, there's really an interaction area here. */ diff --git a/extract/Depend3734592.tmp b/extract/Depend3734592.tmp new file mode 100644 index 00000000..2d09a5d6 --- /dev/null +++ b/extract/Depend3734592.tmp @@ -0,0 +1,113 @@ +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 589eb503..8a78b1aa 100644 --- a/extract/ExtArray.c +++ b/extract/ExtArray.c @@ -713,14 +713,15 @@ extArrayNodeName(np, ha, et1, et2) ExtTree *et1, *et2; { Tile *tp; + TileType dinfo; - tp = extNodeToTile(np, et1, NULL); + tp = extNodeToTile(np, et1, &dinfo); if (tp && TiGetType(tp) != TT_SPACE && extHasRegion(tp, extUnInit)) - return (extArrayTileToNode(tp, np->nreg_pnum, et1, ha, TRUE)); + return (extArrayTileToNode(tp, dinfo, np->nreg_pnum, et1, ha, TRUE)); - tp = extNodeToTile(np, et2, NULL); + tp = extNodeToTile(np, et2, &dinfo); if (tp && TiGetType(tp) != TT_SPACE && extHasRegion(tp, extUnInit)) - return (extArrayTileToNode(tp, np->nreg_pnum, et2, ha, TRUE)); + return (extArrayTileToNode(tp, dinfo, np->nreg_pnum, et2, ha, TRUE)); return ("(none)"); } @@ -768,8 +769,9 @@ extArrayNodeName(np, ha, et1, et2) */ char * -extArrayTileToNode(tp, pNum, et, ha, doHard) +extArrayTileToNode(tp, dinfo, pNum, et, ha, doHard) Tile *tp; + TileType dinfo; int pNum; ExtTree *et; HierExtractArg *ha; @@ -799,7 +801,7 @@ extArrayTileToNode(tp, pNum, et, ha, doHard) } if (!DebugIsSet(extDebugID, extDebNoHard)) - if ((reg = (LabRegion *) extArrayHardNode(tp, pNum, def, ha))) + if ((reg = (LabRegion *) extArrayHardNode(tp, dinfo, pNum, def, ha))) goto found; /* Blew it */ @@ -934,17 +936,23 @@ extArrayRange(dstp, lo, hi, prevRange, followRange) */ LabRegion * -extArrayHardNode(tp, pNum, def, ha) +extArrayHardNode(tp, dinfo, pNum, def, ha) Tile *tp; + TileType dinfo; int pNum; CellDef *def; HierExtractArg *ha; { - TileType type = TiGetType(tp); + TileType type; char labelBuf[4096]; SearchContext scx; HardWay arg; + if (IsSplit(tp)) + type = (dinfo & TT_SIDE) ? TiGetRightType(tp) : TiGetLeftType(tp); + else + type = TiGetType(tp); + arg.hw_ha = ha; arg.hw_label = (Label *) NULL; arg.hw_mask = DBPlaneTypes[pNum]; diff --git a/extract/ExtBasic.c b/extract/ExtBasic.c index 3d06c32c..ce3c63d7 100644 --- a/extract/ExtBasic.c +++ b/extract/ExtBasic.c @@ -727,23 +727,9 @@ extOutputNodes(nodeList, outFile) /* Output its location (lower-leftmost point and type name) */ - if (reg->nreg_type & TT_DIAGONAL) { - /* Node may be recorded as a diagonal tile if no other */ - /* non-diagonal tiles are adjoining it. */ - - TileType loctype = (reg->nreg_type & TT_SIDE) ? ((reg->nreg_type & - TT_RIGHTMASK) >> 14) : (reg->nreg_type & TT_LEFTMASK); - - fprintf(outFile, " %d %d %s", + fprintf(outFile, " %d %d %s", reg->nreg_ll.p_x, reg->nreg_ll.p_y, - DBTypeShortName(loctype)); - } - else - { - fprintf(outFile, " %d %d %s", - reg->nreg_ll.p_x, reg->nreg_ll.p_y, - DBTypeShortName(reg->nreg_type)); - } + DBTypeShortName(reg->nreg_type & TT_LEFTMASK)); /* Output its area and perimeter for each resistivity class */ for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) @@ -1647,13 +1633,7 @@ extOutputParameters(def, transList, outFile) TileType loctype = reg->treg_type; if (loctype == TT_SPACE) continue; /* This has been disabled */ - - /* Watch for rare split reg->treg_type */ - if (loctype & TT_DIAGONAL) - loctype = (reg->treg_type & TT_SIDE) ? ((reg->treg_type & - TT_RIGHTMASK) >> 14) : (reg->treg_type & TT_LEFTMASK); - - TTMaskSetType(&tmask, loctype); + TTMaskSetType(&tmask, loctype & TT_LEFTMASK); } /* Check for the presence of property "device" followed by a device type @@ -1899,7 +1879,7 @@ extOutputDevParams(reg, devptr, outFile, length, width, areavec, perimvec) else { resvalue = (ResValue)( - (double)ExtCurStyle->exts_sheetResist[reg->treg_type] + (double)ExtCurStyle->exts_sheetResist[reg->treg_type & TT_LEFTMASK] * (double)length / (double)width); he = HashLookOnly(&extTransRec.tr_devrec->exts_deviceResist, @@ -2245,12 +2225,7 @@ extOutputDevices(def, transList, outFile) arg.fra_connectsTo = ExtCurStyle->exts_deviceConn; extTransRec.tr_gatenode = (NodeRegion *) extGetRegion(reg->treg_tile); - t = reg->treg_type; - - /* Watch for rare split reg->treg_type */ - if (t & TT_DIAGONAL) - t = (reg->treg_type & TT_SIDE) ? ((reg->treg_type & - TT_RIGHTMASK) >> 14) : (reg->treg_type & TT_LEFTMASK); + t = reg->treg_type & TT_LEFTMASK; arg.fra_pNum = DBPlane(t); @@ -2325,7 +2300,7 @@ extOutputDevices(def, transList, outFile) node = NULL; /* First try to find a region under the device */ - extTransFindSubs(reg->treg_tile, t, tmask, def, &node, &tt); + extTransFindSubs(reg->treg_tile, reg->treg_type, tmask, def, &node, &tt); /* If the device has multiple tiles, then check all of them. * This is inefficient, so this routine first assumes that @@ -2359,7 +2334,8 @@ extOutputDevices(def, transList, outFile) for (lt = extSpecialDevice; lt; lt = lt->t_next) { - extTransFindSubs(lt->t, t, tmask, def, &node, &tt); + extTransFindSubs(lt->t, reg->treg_type, tmask, def, + &node, &tt); if (node != NULL) { TiToRect(lt->t, &r); @@ -3139,9 +3115,9 @@ typedef struct _node_type { } NodeAndType; int -extTransFindSubs(tile, t, mask, def, sn, layerptr) +extTransFindSubs(tile, dinfo, mask, def, sn, layerptr) Tile *tile; - TileType t; + TileType dinfo; TileTypeBitMask *mask; CellDef *def; NodeRegion **sn; @@ -3173,7 +3149,7 @@ extTransFindSubs(tile, t, mask, def, sn, layerptr) { if (TTMaskIntersect(&DBPlaneTypes[pNum], &lmask)) { - if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &tileAreaPlus, + if (DBSrPaintNMArea((Tile *)NULL, def->cd_planes[pNum], dinfo, &tileAreaPlus, mask, extTransFindSubsFunc1, (ClientData)&noderec)) { *sn = noderec.region; @@ -3221,8 +3197,9 @@ extTransFindSubsFunc1(tile, dinfo, noderecptr) } int -extTransFindId(tile, mask, def, idtypeptr) +extTransFindId(tile, dinfo, mask, def, idtypeptr) Tile *tile; + TileType dinfo; TileTypeBitMask *mask; CellDef *def; TileType *idtypeptr; @@ -3237,7 +3214,7 @@ extTransFindId(tile, mask, def, idtypeptr) { if (TTMaskIntersect(&DBPlaneTypes[pNum], mask)) { - if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &tileArea, + if (DBSrPaintNMArea((Tile *)NULL, def->cd_planes[pNum], dinfo, &tileArea, mask, extTransFindIdFunc1, (ClientData)idtypeptr)) return 1; } @@ -3442,7 +3419,7 @@ extTransTileFunc(tile, dinfo, pNum, arg) { sublayer = TT_SPACE; region = NULL; - extTransFindSubs(tile, loctype, &cmask, arg->fra_def, ®ion, &sublayer); + extTransFindSubs(tile, dinfo, &cmask, arg->fra_def, ®ion, &sublayer); /* If the device does not connect to a defined node, and * the substrate types include "space", then it is assumed to @@ -3513,7 +3490,7 @@ extTransTileFunc(tile, dinfo, pNum, arg) if (!TTMaskIsZero(&cmask)) { idlayer = TT_SPACE; - extTransFindId(tile, &cmask, arg->fra_def, &idlayer); + extTransFindId(tile, dinfo, &cmask, arg->fra_def, &idlayer); if ((idlayer == TT_SPACE) && !TTMaskIsZero(&devptr->exts_deviceIdentifierTypes)) { @@ -4542,6 +4519,16 @@ extSetNodeNum(reg, plane, tile, dinfo) { TileType type; + /* NOTE: reg->lreg_type will be updated to reflect the type assigned + * to the node at the given plane and location. However, the upper + * bits of reg->lreg_type are being used to track which side of + * reg->lreg_tile belongs to the node in the case that reg->lreg_tile + * is a split tile. So protect the upper bits during this process. + */ + + /* (only TT_SIDE is relevant here) */ + TileType regdinfo = reg->lreg_type & (TT_DIAGONAL | TT_SIDE | TT_DIRECTION); + if (IsSplit(tile)) { /* Only consider split tiles if the lower-left-hand corner */ @@ -4562,9 +4549,9 @@ extSetNodeNum(reg, plane, tile, dinfo) else type = TiGetType(tile); - if ((plane < reg->lreg_pnum) || (reg->lreg_type & TT_DIAGONAL)) + if (plane < reg->lreg_pnum) { - reg->lreg_type = type; + reg->lreg_type = (type & TT_LEFTMASK) | regdinfo; reg->lreg_pnum = plane; reg->lreg_ll = tile->ti_ll; } @@ -4573,13 +4560,13 @@ extSetNodeNum(reg, plane, tile, dinfo) if (LEFT(tile) < reg->lreg_ll.p_x) { reg->lreg_ll = tile->ti_ll; - reg->lreg_type = type; + reg->lreg_type = (type & TT_LEFTMASK) | regdinfo; } else if (LEFT(tile) == reg->lreg_ll.p_x && BOTTOM(tile) < reg->lreg_ll.p_y) { reg->lreg_ll.p_y = BOTTOM(tile); - reg->lreg_type = type; + reg->lreg_type = (type & TT_LEFTMASK) | regdinfo; } } } @@ -4623,7 +4610,10 @@ extTransFirst(tile, dinfo, arg) reg->treg_pnum = DBNumPlanes; if (IsSplit(tile)) + { reg->treg_type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); + reg->treg_type |= (dinfo & TT_SIDE) | TT_DIAGONAL | (TiGetTypeExact(tile) & TT_DIRECTION); + } else reg->treg_type = TiGetTypeExact(tile); @@ -4645,12 +4635,6 @@ extTransEach(tile, dinfo, pNum, arg) int area = TILEAREA(tile); if (IsSplit(tile)) area /= 2; /* Split tiles are 1/2 area! */ - else if (IsSplit(reg->treg_tile)) - { - /* Avoid setting the region's tile pointer to a split tile */ - reg->treg_tile = tile; - reg->treg_type = TiGetTypeExact(tile); - } /* The following is non-ideal. It assumes that the lowest plane of */ /* types connected to a device is the plane of the device itself. */ diff --git a/extract/ExtCouple.c b/extract/ExtCouple.c index 97e88641..47676645 100644 --- a/extract/ExtCouple.c +++ b/extract/ExtCouple.c @@ -411,8 +411,9 @@ struct sideoverlap }; int -extAddOverlap(tbelow, ecpls) +extAddOverlap(tbelow, dinfo, ecpls) Tile *tbelow; + TileType dinfo; /* unused, but needs to be handled */ extCoupleStruct *ecpls; { int extSubtractOverlap(), extSubtractOverlap2(); @@ -540,8 +541,9 @@ extAddOverlap(tbelow, ecpls) /* Simple overlap. The area of overlap is subtracted from ov->o_area */ int -extSubtractOverlap(tile, ov) +extSubtractOverlap(tile, dinfo, ov) Tile *tile; + TileType dinfo; /* (unused) */ struct overlap *ov; { Rect r; @@ -550,6 +552,7 @@ extSubtractOverlap(tile, ov) TITORECT(tile, &r); GEOCLIP(&r, &ov->o_clip); area = (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot); + if (IsSplit(tile)) area /= 2; if (area > 0) ov->o_area -= area; @@ -562,8 +565,9 @@ extSubtractOverlap(tile, ov) /* shielding plane. */ int -extSubtractOverlap2(tile, ov) +extSubtractOverlap2(tile, dinfo, ov) Tile *tile; + TileType dinfo; /* (unused) */ struct overlap *ov; { struct overlap ovnew; @@ -575,6 +579,7 @@ extSubtractOverlap2(tile, ov) area = (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot); if (area <= 0) return (0); + if (IsSplit(tile)) area /= 2; /* This tile shields everything below */ if (TTMaskHasType(&ov->o_tmask, TiGetType(tile))) @@ -615,8 +620,9 @@ extSubtractOverlap2(tile, ov) */ int -extSubtractSideOverlap(tile, sov) +extSubtractSideOverlap(tile, dinfo, sov) Tile *tile; + TileType dinfo; /* (unused) */ struct sideoverlap *sov; { Rect r; @@ -692,14 +698,21 @@ extSubtractSideOverlap(tile, sov) /* shielding plane. */ int -extSubtractSideOverlap2(tile, sov) +extSubtractSideOverlap2(tile, dinfo, sov) Tile *tile; + TileType dinfo; struct sideoverlap *sov; { + TileType ttype; struct sideoverlap sovnew; int area, pNum; Rect r; + if (IsSplit(tile)) + ttype = (dinfo & TT_SIDE) ? TiGetRightType(tile) : TiGetLeftType(tile); + else + ttype = TiGetTypeExact(tile); + TITORECT(tile, &r); GEOCLIP(&r, &sov->so_clip); area = (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot); @@ -707,9 +720,9 @@ extSubtractSideOverlap2(tile, sov) return (0); /* This tile shields everything below */ - if (TTMaskHasType(&sov->so_tmask, TiGetType(tile))) + if (TTMaskHasType(&sov->so_tmask, ttype)) { - extSubtractSideOverlap(tile, sov); + extSubtractSideOverlap(tile, dinfo, sov); return (0); } @@ -1057,8 +1070,9 @@ extFindOverlap(tp, area, esws) */ int -extSideOverlapHalo(tp, esws) +extSideOverlapHalo(tp, dinfo, esws) Tile *tp; /* Overlapped tile */ + TileType dinfo; /* Split tile information */ extSidewallStruct *esws; /* Overlapping edge and plane information */ { Boundary *bp = esws->bp; /* Overlapping edge */ @@ -1078,7 +1092,10 @@ extSideOverlapHalo(tp, esws) /* Nothing to do for space tiles, so just return. */ /* (TO DO: Make sure TT_SPACE is removed from all exts_sideOverlapOtherTypes */ - tb = TiGetType(tp); + if (IsSplit(tp)) + tb = (dinfo & TT_SIDE) ? TiGetRightType(tp) : TiGetLeftType(tp); + else + tb = TiGetTypeExact(tp); if (tb == TT_SPACE) return (0); /* Get the area of the coupling tile, and clip to the fringe area */ @@ -1154,7 +1171,7 @@ extSideOverlapHalo(tp, esws) if (!PlaneMaskHasPlane(e->ec_pmask, esws->plane_checked)) continue; /* Does this rule "e" include the tile we found? */ - if (TTMaskHasType(&e->ec_near, TiGetType(tp))) + if (TTMaskHasType(&e->ec_near, tb)) { /* We have a possible capacitor, but are the tiles shielded from * each other part of the way? @@ -1284,8 +1301,9 @@ extSideOverlapHalo(tp, esws) */ int -extSideOverlap(tp, esws) +extSideOverlap(tp, dinfo, esws) Tile *tp; /* Overlapped tile */ + TileType dinfo; /* Split tile information */ extSidewallStruct *esws; /* Overlapping edge and plane information */ { Boundary *bp = esws->bp; /* Overlapping edge */ @@ -1303,7 +1321,10 @@ extSideOverlap(tp, esws) /* Nothing to do for space tiles, so just return. */ /* (TO DO: Make sure TT_SPACE is removed from all exts_sideOverlapOtherTypes */ - tb = TiGetType(tp); + if (IsSplit(tp)) + tb = (dinfo & TT_SIDE) ? TiGetRightType(tp) : TiGetLeftType(tp); + else + tb = TiGetTypeExact(tp); if (tb == TT_SPACE) return (0); if (bp->b_segment.r_xtop == bp->b_segment.r_xbot) @@ -1338,7 +1359,7 @@ extSideOverlap(tp, esws) if (!PlaneMaskHasPlane(e->ec_pmask, esws->plane_checked)) continue; /* Does this rule "e" include the tile we found? */ - if (TTMaskHasType(&e->ec_near, TiGetType(tp))) + if (TTMaskHasType(&e->ec_near, tb)) { /* We have a possible capacitor, but are the tiles shielded from * each other part of the way? diff --git a/extract/ExtHard.c b/extract/ExtHard.c index f4be36ce..7f85cd83 100644 --- a/extract/ExtHard.c +++ b/extract/ExtHard.c @@ -83,6 +83,7 @@ extLabFirst(tile, dinfo, arg) reg->treg_pnum = DBNumPlanes; reg->treg_area = DBNumPlanes; reg->treg_tile = tile; + reg->treg_type = dinfo; /* Prepend it to the region list */ reg->treg_next = (TransRegion *) arg->fra_region; @@ -98,16 +99,6 @@ extLabEach(tile, dinfo, pNum, arg) int pNum; FindRegion *arg; { - - /* Avoid setting the region's tile pointer to a split tile if we can */ - /* - if (IsSplit(reg->treg_tile) && !IsSplit(tile)) - { - reg->treg_tile = tile; - reg->treg_area = pNum; - } - */ - TransRegion *reg = (TransRegion *) arg->fra_region; if (reg->treg_area == DBNumPlanes) reg->treg_area = pNum; @@ -174,7 +165,7 @@ extHardProc(scx, arg) CellDef *def = scx->scx_use->cu_def; TransRegion *reg; TransRegion *labRegList; - LabelList *subList; + LabelList *subList = NULL; char *savenext; int ret = 0; @@ -242,7 +233,8 @@ extHardProc(scx, arg) */ if (ExtCurStyle->exts_globSubstrateDefaultType != -1) for (reg = labRegList; reg; reg = reg->treg_next) - if (TTMaskHasType(&ExtCurStyle->exts_globSubstrateTypes, reg->treg_type)) + if (TTMaskHasType(&ExtCurStyle->exts_globSubstrateTypes, + reg->treg_type & TT_LEFTMASK)) if (reg->treg_pnum != ExtCurStyle->exts_globSubstratePlane) { reg->treg_labels = subList; @@ -263,6 +255,7 @@ extHardProc(scx, arg) goto done; success: + if (subList != NULL) freeMagic(subList); extHardFreeAll(def, labRegList); ret = 1; @@ -505,7 +498,7 @@ extHardFreeAll(def, tReg) if (reg->treg_tile) { arg.fra_pNum = reg->treg_area; - ExtFindNeighbors(reg->treg_tile, arg.fra_pNum, &arg); + ExtFindNeighbors(reg->treg_tile, reg->treg_type, arg.fra_pNum, &arg); } /* Free all LabelLists and then the region */ diff --git a/extract/ExtHier.c b/extract/ExtHier.c index 96e54ff7..eba5b685 100644 --- a/extract/ExtHier.c +++ b/extract/ExtHier.c @@ -350,12 +350,16 @@ extHierConnectFunc1(oneTile, dinfo, ha) if (IsSplit(oneTile)) { - rtype = ha->hierType; - ha->hierType = (rtype & TT_SIDE) ? SplitRightType(oneTile) : + /* For split tiles, move the tile type to lower (right side) field + * but retain the TT_SIDE bit, to indicate which side of hierOneTile + * is the connected side. + */ + ha->hierType = (dinfo & TT_SIDE) ? SplitRightType(oneTile) : SplitLeftType(oneTile); + ha->hierType |= (dinfo & (TT_DIAGONAL | TT_DIRECTION | TT_SIDE)); } - connected = &(ExtCurStyle->exts_nodeConn[ha->hierType]); + connected = &(ExtCurStyle->exts_nodeConn[ha->hierType & TT_LEFTMASK]); TITORECT(oneTile, &r); GEOCLIP(&r, &ha->ha_subArea); r.r_xbot--, r.r_ybot--, r.r_xtop++, r.r_ytop++; @@ -367,7 +371,7 @@ extHierConnectFunc1(oneTile, dinfo, ha) { if (IsSplit(oneTile)) DBSrPaintNMArea((Tile *) NULL, cumDef->cd_planes[i], - rtype, &r, + ha->hierType, &r, ((i == ha->hierPNum) ? &ExtCurStyle->exts_activeTypes : connected), extHierConnectFunc2, (ClientData) ha); else @@ -415,7 +419,7 @@ extHierConnectFunc1(oneTile, dinfo, ha) nn = (NodeName *) HashGetValue(he); node1 = nn ? nn->nn_node : extHierNewNode(he); - name = (*ha->ha_nodename)(ha->hierOneTile, ha->hierPNum, + name = (*ha->ha_nodename)(ha->hierOneTile, ha->hierType, ha->hierPNum, extHierOneFlat, ha, TRUE); he = HashFind(table, name); nn = (NodeName *) HashGetValue(he); @@ -513,14 +517,14 @@ extHierConnectFunc2(cum, dinfo, ha) if (IsSplit(cum)) ttype = (dinfo & TT_SIDE) ? SplitRightType(cum) : SplitLeftType(cum); - if (extConnectsTo(ha->hierType, ttype, ExtCurStyle->exts_nodeConn)) + if (extConnectsTo(ha->hierType & TT_LEFTMASK, ttype, ExtCurStyle->exts_nodeConn)) { - name1 = (*ha->ha_nodename)(cum, ha->hierPNumBelow, extHierCumFlat, ha, TRUE); + name1 = (*ha->ha_nodename)(cum, dinfo, ha->hierPNumBelow, extHierCumFlat, ha, TRUE); he = HashFind(table, name1); nn = (NodeName *) HashGetValue(he); node1 = nn ? nn->nn_node : extHierNewNode(he); - name2 = (*ha->ha_nodename)(ha->hierOneTile, ha->hierPNum, extHierOneFlat, + name2 = (*ha->ha_nodename)(ha->hierOneTile, ha->hierType, ha->hierPNum, extHierOneFlat, ha, TRUE); he = HashFind(table, name2); nn = (NodeName *) HashGetValue(he); @@ -566,7 +570,7 @@ extHierConnectFunc2(cum, dinfo, ha) snprintf(message, sizeof(message), "Illegal overlap between %s and %s (types do not connect)", - DBTypeLongNameTbl[ha->hierType], DBTypeLongNameTbl[ttype]); + DBTypeLongNameTbl[ha->hierType & TT_LEFTMASK], DBTypeLongNameTbl[ttype]); extNumErrors++; if (!DebugIsSet(extDebugID, extDebNoFeedback)) @@ -623,9 +627,10 @@ extHierConnectFunc3(cum, dinfo, ha) if (IsSplit(cum)) ttype = (dinfo & TT_SIDE) ? SplitRightType(cum) : SplitLeftType(cum); - if (extConnectsTo(ha->hierType, ttype, ExtCurStyle->exts_nodeConn)) + if (extConnectsTo(ha->hierType & TT_LEFTMASK, ttype, ExtCurStyle->exts_nodeConn)) { - name1 = (*ha->ha_nodename)(cum, ha->hierPNumBelow, extHierCumFlat, ha, TRUE); + name1 = (*ha->ha_nodename)(cum, ha->hierType, ha->hierPNumBelow, + extHierCumFlat, ha, TRUE); he = HashFind(table, name1); nn = (NodeName *) HashGetValue(he); node1 = nn ? nn->nn_node : extHierNewNode(he); @@ -675,7 +680,7 @@ extHierConnectFunc3(cum, dinfo, ha) snprintf(message, sizeof(message), "Illegal overlap between %s and %s (types do not connect)", - DBTypeLongNameTbl[ha->hierType], DBTypeLongNameTbl[ttype]); + DBTypeLongNameTbl[ha->hierType & TT_LEFTMASK], DBTypeLongNameTbl[ttype]); extNumErrors++; if (!DebugIsSet(extDebugID, extDebNoFeedback)) @@ -776,10 +781,12 @@ extHierAdjustments(ha, cumFlat, oneFlat, lookFlat) */ for (np = oneFlat->et_nodes; np; np = np->nreg_next) { + TileType dinfo; + /* Ignore orphaned nodes (non-Manhattan shards outside the clip box) */ if (np->nreg_pnum == DBNumPlanes) continue; - tp = extNodeToTile(np, lookFlat, NULL); + tp = extNodeToTile(np, lookFlat, &dinfo); /* Ignore regions that do not participate in extraction */ if (!extHasRegion(tp, extUnInit)) continue; @@ -787,7 +794,7 @@ extHierAdjustments(ha, cumFlat, oneFlat, lookFlat) /* Ignore substrate nodes (failsafe: should not happen) */ if (TiGetTypeExact(tp) == TT_SPACE) continue; - if (tp && (name = (*ha->ha_nodename)(tp, np->nreg_pnum, lookFlat, ha, FALSE)) + if (tp && (name = (*ha->ha_nodename)(tp, dinfo, np->nreg_pnum, lookFlat, ha, FALSE)) && (he = HashLookOnly(&ha->ha_connHash, name)) && (nn = (NodeName *) HashGetValue(he))) { diff --git a/extract/ExtNghbors.c b/extract/ExtNghbors.c index 03a0f710..42e6cf48 100644 --- a/extract/ExtNghbors.c +++ b/extract/ExtNghbors.c @@ -110,6 +110,8 @@ ExtFindNeighbors(tile, dinfo, tilePlaneNum, arg) else type = TiGetTypeExact(tile); + ASSERT(type != TT_SPACE, "ExtFindNeighbors"); + mask = &connTo[type]; /* @@ -134,8 +136,8 @@ topside: if (IsSplit(tp)) { t = SplitBottomType(tp); - // if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) - if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t)) + // if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t)) + if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) { PUSHTILEBOTTOM(tp, tilePlaneNum); } @@ -145,7 +147,7 @@ topside: t = TiGetTypeExact(tp); if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) { - PUSHTILE(tp, (TileType)0, tilePlaneNum); + PUSHTILELEFT(tp, tilePlaneNum); } } } @@ -158,8 +160,8 @@ leftside: if (IsSplit(tp)) { t = SplitRightType(tp); - // if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) - if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t)) + // if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t)) + if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) { PUSHTILERIGHT(tp, tilePlaneNum); } @@ -169,7 +171,7 @@ leftside: t = TiGetTypeExact(tp); if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) { - PUSHTILE(tp, (TileType)0, tilePlaneNum); + PUSHTILELEFT(tp, tilePlaneNum); } } } @@ -183,8 +185,8 @@ bottomside: if (IsSplit(tp)) { t = SplitTopType(tp); - // if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) - if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t)) + // if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t)) + if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) { PUSHTILETOP(tp, tilePlaneNum); } @@ -194,7 +196,7 @@ bottomside: t = TiGetTypeExact(tp); if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) { - PUSHTILE(tp, (TileType)0, tilePlaneNum); + PUSHTILELEFT(tp, tilePlaneNum); } } } @@ -207,8 +209,8 @@ rightside: if (IsSplit(tp)) { t = SplitLeftType(tp); - // if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) - if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t)) + // if (TiGetClientPTR(tp) != arg->fra_region && TTMaskHasType(mask, t)) + if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) { PUSHTILELEFT(tp, tilePlaneNum); } @@ -218,7 +220,7 @@ rightside: t = TiGetTypeExact(tp); if (TiGetClient(tp) == extNbrUn && TTMaskHasType(mask, t)) { - PUSHTILE(tp, (TileType)0, tilePlaneNum); + PUSHTILELEFT(tp, tilePlaneNum); } } } @@ -285,7 +287,7 @@ donesides: t = TiGetTypeExact(tp); if (TTMaskHasType(mask, t)) { - PUSHTILE(tp, (TileType)0, pNum); + PUSHTILELEFT(tp, pNum); } } } @@ -308,8 +310,8 @@ donesides: if ((pNum != tilePlaneNum) && PlaneMaskHasPlane(pMask, pNum)) { pla.plane = pNum; - (void) DBSrPaintArea((Tile *) NULL, - arg->fra_def->cd_planes[pNum], &biggerArea, + (void) DBSrPaintNMArea((Tile *) NULL, + arg->fra_def->cd_planes[pNum], dinfo, &biggerArea, mask, extNbrPushFunc, (ClientData) &pla); } } diff --git a/extract/ExtSubtree.c b/extract/ExtSubtree.c index 613fc61f..9eabcfeb 100644 --- a/extract/ExtSubtree.c +++ b/extract/ExtSubtree.c @@ -197,6 +197,7 @@ extSubtree(parentUse, reg, f) ha.ha_parentUse = parentUse; ha.ha_parentReg = reg; ha.ha_nodename = extSubtreeTileToNode; + ha.ha_interArea = GeoNullRect; ha.ha_cumFlat.et_use = extYuseCum; HashInit(&ha.ha_connHash, 32, 0); @@ -687,19 +688,21 @@ extSubtreeOutputCoupling(ha) HashStartSearch(&hs); while ((he = HashNext(&ha->ha_cumFlat.et_coupleHash, &hs))) { + TileType dinfo; + cap = extGetCapValue(he) / ExtCurStyle->exts_capScale; if (cap == 0) continue; ck = (CoupleKey *) he->h_key.h_words; - tp = extNodeToTile(ck->ck_1, &ha->ha_cumFlat, NULL); - name = extSubtreeTileToNode(tp, (TileType)0, ck->ck_1->nreg_pnum, + tp = extNodeToTile(ck->ck_1, &ha->ha_cumFlat, &dinfo); + name = extSubtreeTileToNode(tp, dinfo, ck->ck_1->nreg_pnum, &ha->ha_cumFlat, ha, TRUE); fprintf(ha->ha_outf, "cap \"%s\" ", name); - tp = extNodeToTile(ck->ck_2, &ha->ha_cumFlat, NULL); - name = extSubtreeTileToNode(tp, (TileType)0, ck->ck_2->nreg_pnum, + tp = extNodeToTile(ck->ck_2, &ha->ha_cumFlat, &dinfo); + name = extSubtreeTileToNode(tp, dinfo, ck->ck_2->nreg_pnum, &ha->ha_cumFlat, ha, TRUE); fprintf(ha->ha_outf, "\"%s\" %lg\n", name, cap); } diff --git a/extract/extractInt.h b/extract/extractInt.h index ead7658f..7791be6f 100644 --- a/extract/extractInt.h +++ b/extract/extractInt.h @@ -212,13 +212,19 @@ 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 */ + int treg_type; /* Type of treg_tile* */ Point treg_ll; /* UNUSED */ LabelList *treg_labels; /* Attribute list */ Tile *treg_tile; /* Some tile in the channel */ int treg_area; /* Area of channel */ } TransRegion; +/* *NOTE: If treg_tile is a split tile, then treg_type consists of + * the transistor type in the left-side position (lower bits). This + * assumes that only one side of a split tile can be a transistor + * type. + */ + typedef struct { /* Maintain plane information when pushing */ Rect area; /* tiles on the node stack. For use with */ int plane; /* function extNbrPushFunc(). */ @@ -342,6 +348,7 @@ typedef struct extTree * char * * proc(tp, et, ha) * Tile *tp; + * TileType dinfo; * ExtTree *et; * HierExtractArg *ha; * { @@ -372,7 +379,7 @@ typedef struct */ 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 */ + TileType hierType; /* Used in ExtHier.c, type of tile above, incl. TT_SIDE */ int hierPNumBelow; /* Used in ExtHier.c, plane of tile below */ } HierExtractArg; @@ -1057,7 +1064,7 @@ extern Tile *extNodeToTile(); Tile *tp; \ \ (nnew) = (NodeRegion *) NULL; \ - tp = extNodeToTile((nold), (et), (TileType)NULL); \ + tp = extNodeToTile((nold), (et), (TileType *)NULL); \ if (tp && extHasRegion(tp, extUnInit)) \ (nnew) = (NodeRegion *) extGetRegion(tp); \ }