diff --git a/README b/README index f7048e2f..30874ef9 100644 --- a/README +++ b/README @@ -1454,4 +1454,443 @@ path, and looks like it has a good chance of being produced by the same bug, and I'd rather debug from the ENABLE_H signal. Also it's harder to figure out what to change in the netlist to correct it manually. -Most likely involves a plane-to-plane connection through a via +Most likely involves a plane-to-plane connection through a via? +Problem should be found around extHierConnections(). However, since +the problem is a *failure* to merge two nodes, watching the node merge +function isn't going to be much help. + +Will need to track specific locations. Top cell will be +sky130_fd_io__top_gpiov2. ENABLE_H starts with the pin on metal2 at +at (7092, 0) to (7144, 402). Since the connection to the right is +found, then any disconnect happens above. There is an angled wire +that starts at y=402. The connection between the two nodes happens +in the area of (7028, 672) to (7078, 782). The connecting cell +underneath is sky130_fd_io__gpiov2_ctl. The same connecting area in +the coordinates of the child cell are around (10536, 4166) to +(10584, 4280). The child and parent are in the same oriention, +with X and Y offsets. However, the connection passes only a brief +distance before descending again to cell sky130_fd_io__com_ctl_hldv2, +which is not rotated 180 degrees. + +It should be able to be determined from the .ext files if the lower +connection was made. The node name in sky130_fd_io__com_ctl_hldv2 +is a_2671_3554#. The node name in the parent is ENABLE_H, but only +through the child connection. The connecting m1 piece should have +a name m1_10103_4165#. This might be the likely point of failure, +because the metal line has a split tile at the lower left corner +which has the unusal property of coming to a point at the lower +left, because of the horrid layout job done on these cells. + +Conclusion: The sky130_fd_io__gpiov2_ctl.ext file does connect +ENABLE_H to both m1_10103_4165# and to +sky130_fd_io__com_ctl_hldv2_0/a_2671_3554#. + +Clue! sky130_fd_io__gpiov2_ctl DOES make the connection, but to +"sky130_fd_io__gpiov2_ctl_0/m1_10103_4165x#". Therefore, the error +is that the "x" is not accounting for the subcell rotation (or +something like that). +No, I don't think it's rotation, and the code is very clear that "x" +is added when the type is on the right side, and that is indicated +by lreg->lreg_type. There is no rotation going on here between +sky130_fd_io__top_gpiov2 and sky130_fd_io__gpiov2_ctl. That means +that TT_SIDE got set for lreg_type incorrectly + +Should be easily checkable, as it indicates that extSetNodeNum() +was called with tile->ti_ll = (10103, 4165) and dinfo & TT_SIDE != 0. +(Should probably have started when running extraction on the top +cell, because the conditional severely impacts extraction time. +But did confirm that extSetNodeNum() is called properly within +sky130_fd_io__gpiov2_ctl with dinfo only set to zero.) + +Did not happen. + +There is a fundamental issue: The LabRegion structure doesn't even +have a tile type. "lreg_type" is being used to track the dinfo for +"treg_tile", which is probably stupid. "lreg_type" upper bits should +ether follow the type of the tile at "lreg_ll" or else flag when +"lreg_ll" is the right side of the node (thus triggering the "x" in +the name, or maybe change that to "r" for "right"). The treg_tile +dinfo should be an extra field in the TransRegion type. + +Not entirely sure it's necessary to have an extra field. If treg_type +is just the type of treg_tile, then treg_type is not needed other than +to store TT_SIDE. May be okay just to always reassign TT_SIDE when +reassigning lreg_ll and lreg_type to a new tile position. + +Okay, that's probably an incorrect assumption given that "(none)" +nodes started appearing in the output. + +Went back and did the other idea, which is to add a record to TransRegion +for "dinfo" and leave treg_type with TT_SIDE corresponding to the region +lreg_ll position, not necessarily treg_tile. Seemed to work. Now there +is one LVS error which is the netlist issue with gpiov2 vs. gpio_ovtv2 +for the connection to buf_localesd, a change which I reverted because I +wasn't sure if it was needed or not. Applying the change again. . . +And voila! gpiov2 is LVS clean again! +(Except for the ESD transistor width calculation, which now needs to +be modified to properly handle non-Manhattan edges of the device.) + +Now to work on the newer I/O cells gpio_ovtv2, sio, etc. +Quick pass at both gpio_ovtv2 and sio result in netlists that do not +appear to be too far from clean; as in just a few shorts/opens. +Specifically: +1. For gpio_ovtv2, it looks like two nets in the netlist are shorted to + the pad, and those are the only errors. There is one component + mismatch, but that appears to be due to the shorted nets. + + There was at one time a hack solution for gpio_ovtv2 to remove the + flanged gates from the layout; this might still be being done in + the open_pdks install. Need to check. Should be resolved now. + +2. For sio (not macro), vssd and vssio are shorted in the layout. + There seem to be a few other shorts/opens elsewhere. + +3. The gpio_ovtv2 cell LVS from the existing PDK .mag view still + requires the flattening-in-place of the amux_i2c_fix cell, or else + the ground nets get shorted. + +4. run_top_pwrdetv2.sh is LVS clean. +5. run_top_analog_pad.sh is LVS clean. +6. run_top_refgen_new.sh has an LVS match but a property error (which + is not new and apparently has not been fixed) + +Digression (but important bug): source and drain calculations are off. +Test: The default nMOS device from the device generator. Source and +drain are exactly symmetric. .ext file output has correct length of +the terminals (84, same as device gate width), but "2088,101" for +drain area/perimeter and "2436,142" for source area/perimeter. +Actual area and perimeter for both are: A=4872, P=284. "Source" has +exactly half of these values---Suggests it was being "shared" with +another non-existing device. Where it got the drain values from is +unclear. Since the area/drain searching algorithm is the one that +got rewritten, it is probably at fault. Routine is now "extEnumTerminal()"; +break on that. +1st call: Tile at -73, -42 (type ndiff) +2nd call: Tile at 15, 30 (type ndiff). +There is a contact on each side and the terminal region for each side should +be 5 tiles total. + +Tile at -73, -42 is tile below the contact on the left side. +Tile at 15, 30 is the tile above the contact on the right side. + +(1) tileArea = -73, -42 to -15, -30 +(2) eapd_area = 696 eapd_perim = 82 (added 6 lengths) +(3) added shared device (self) +(4) continue search, added tile above (-27, -30) to linked list. +(5) continue search, added tile above (-61, -30) to linked list. +(6) went to termdone. . . missed a tile. Two sides are using the wrong + comparison. + +Drain and source match now. But values are still cut in half. The "addShared" +subroutine only ever sees one gate node, so nothing is shared. It is starting +"shared" at one, but there is always one record, so minimum "shared" is coming +out 2---Has it always been this way??? Anyway, it's correct now. + +--------------- + +Back to study of gpio_ovtv2 and sio. +gpio_ovtv2: From magic, no flattening in place. Results in ground short. +gpio_ovtv2: From magic, use flatten-in-place. Issue is a short between +PAD and two other nets which in the netlist are: +1) sky130_fd_io__gpio_ovtv2_opath_i2c_fix_leak_fix:opath_q0/\ + sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix:odrvr_q0/p2g +2) sky130_fd_io__gpio_ovtv2_opath_i2c_fix_leak_fix:opath_q0/\ + sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix:odrvr_q0/net74 + +The schematic has the esd_nfets and esd_pfets divided into three nets. +The division looks pretty clear from the layout; one esd_nfet is offset +from the others; the three esd_pfets on the left and right sides are +connected differently. However, at issue is what happens to the esd_pfet +gates. The layout-extracted netlist has the esd_pfet gates shorted and +tied to pad. This does not match the connectivity selection view. + +This had been a problem before and I was hoping it would have been resolved +by the new code. At issue are numerous flanged gates on the ESD pFETs. +The "fix_leak_fix" cell, which is where the errors are located, is "nearly" +matching with the layout having an isolated and unmarked section of VDDIO. + +"p2g" net has two rm1 resistor ends, an ESD pfet gate (may be multiple +devices in parallel), and one each 5V pFET and 5V nFET source/drain. +This looks like it is the gates of the 5 pairs of ESD pfets on the top +row except for the rightmost pair (which is "net74", see below). If so, +then the node is a_7678_12770#. + +"net74" has one rm1 resistor end, one rm2 resistor end, one ESD pfet gate, +and one poly resistor end. Any such net in the layout? Looks like maybe +the gates of the ESD pfet pair at top right. If so, this would be +node a_20646_12770# in sky130_fd_io__gpio_ovtv2_opath_i2c_fix_leak_fix. + +Therefore, find in the .ext files where a_7678_12770# is merged to PAD +and where a_20646_12770# is merged to PAD, or where they are merged to +each other. Extraction doesn't match connectivity. Connectivity selection +is correct. + +If I recall correctly from before, there was an issue with the flanged +gates shorting across gate to source, or rather the node region being +confused between the two. This should not happen any more, but obviously +just did. + +The two nodes cited above do not appear in the top level .ext file. +"getnode" is producing garbled crap for the prefixes in the net names +(need to fix!) but at the top level, the suffixes on the nets are showing +as: + +"net74": a_21780_5642# +"p2g": m1_3189_4326# + +These two names are not found at the top level, either. +The "merge" lines for PAD are found in sky130_fd_io__top_gpio_ovtv2.ext +at lines 1468 to 1497. + +There is a clear issue although it doesn't appear to be exactly related +to the problem at hand; the PAD net is merging to nodes which are showing +as being the gate side of a split tile while the PAD net is the source/drain +side. + +A survey shows that "x#" shows up exactly nowhere in the .ext output. So +this might be relatively simple! But it implies that lreg_type never has +TT_SIDE set. Why not? Ech, changing something that was supposedly fixed +already, so will have to re-check other layouts involving split regions. +After fixing (again), nothing changed. . . + +Really need to fix "getnode", this is interfering with debugging. +(Specifically, SimGetnode()). This could be a malloc issue? +SimSeletArea() returns TileListElt pointer. . . Where does this list +get deallocated?? SimFreeNodeList(); bleah, it's a global variable and +the linked list just hangs around until the routine is called again. +Seems like this needs work and has not yet been addressed. +See SimTreeCopyConnect(). . . +At SimDBstuff.c:132, tpath->tp_last is the garbled part. tp_first has the +path that should be returned but somehow the garbled part is what's getting +returned. tp_last is a sentinel pointer at the end of the pathName string, +and it should not be in the output as far as I can tell. +SimGetNodeName() somewhere returned a bogus result. +SimGetNodeName() was called from SimDBstuff.c:136 with bogus tpath->tp_first +from cx->tc_filter->tf_tpath +cx deifned at SimDBstuff.c:766 and tc_filter set to fp (= cdata). +fp is itself a TreeFilter pointer. and fp->tf_arg is, too? +fp is cxp->tc_filter. +cxp is a contact which took tf_arg from cdarg +cdarg set at SimDBstuff.c:820 from "fp" +fp from cdata passed to SimCellTileSrFunc +So ultimately, tpath came from SimDBstuff.c:399. +Maybe watch tpath.tp_first changes starting from SimDBstuff.c:366 +It changed to a bogus value in SimCellTileSrFunc() but that specific location +appears to have been deallocated. +Try valgrind again. . . +Valgrind comes through. . . +Looks like csa->csa_clientDefault needs to change to match other things I did +with "clientDefault" in the DBconnect routines. . . Fixed. . . +But still no joy. +Might be faster to parse DBconnect against SimDBstuff? Did that, nothing obvious. +Now valgrind shows no error but the tpath prefix is missing. Produced garbage +in prefix but not when running under valgrind. Don't know why. + +Ugh. Will need investigating. Doesn't even address the current problem with +extraction. + +"getnode" has issues, but maybe can debug the problem with "goto" only? +The shorted nodes seem not to be in the merge list at all. . . +Assuming that the .spice file is wrong, then there are two conflicting +names in the .ext file somewhere such that nodes are effectively shorted +without a "merge" statement. + +Could possibly happen between sky130_fd_io__gpio_ovtv2_opath_i2c_fix_leak_fix +and sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix? Actually, this is likely, +given the issues with "getnode". + +Could be in sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix itself, but for +example node a_19583_5855# has only 2 merge lines: + +sky130_fd_io__gpio_ovtv2_odrvr_sub_leak_fix_0/sky130_fd_io__gpio_ovtv2_pudrvr_sub_0/\ + sky130_fd_io__gpio_ovtv2_pudrvr_strong_0/a_21780_5642# +sky130_fd_io__gpio_ovtv2_odrvr_sub_leak_fix_0/m1_24520_7190# +a_19583_5855# + +Oh, sky130_fd_io__gpio_ovtv2_opath_i2c_fix_leak_fix.ext is a mess. . . +There is a "(none)" node in this set, among 39 "merge" entries. +Also there are FETs drawn on top of FETs here. Will at least produce device +size errors. + +Yes, the node shorts are here. +Debugging: The "(none)" is returned for tp = tile at 4436, 12770, mvpmosesd +on left side, mvpdiff on right side, dir=0. dinfo indicates looking at the +right side. + +Breaking on extSubtreeHardNode for this tile. +lreg for this tile has ll=4436, 12488 and lreg_type has TT_SIDE. +extSubtreeHardSearch() did nothing. Now sets "autogen" and retries. + +ExtFindRegions() produced nothing. +def is sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix +scx_area is 3423, 6287 to 3443, 6307. +scx_area is 3574 3773 to 3594 3793 +def is sky130_fd_io__gpio_ovtv2_pudrvr_sub +scx_area is 579 2474 to 599 2494 +def is sky130_fd_io__gpio_ovtv2_hotswap_vpb_bias +scx_area is 2722 9349 to 2742 9369 +... + +go back and check what's in the first search area. +It's the flanged gate of the leftmost of the ESD pFETs. +The area is an exact match to the split tile, so if it found nothing it would +have to be because the wrong side of the tile was being searched, or the split +was mishandled somehow. + +Do that again, break on ExtSubtree.c:1255 if tp->ti_ll.p_x == 4436 && tp->ti_ll.p_y == 12770. + +So dinfo has TT_SIDE set to 1, so it is ostensibly looking at the right side of +the tile where the tile has pdiff (not transistor). + +extHierConnections() called extHierConnectFunc1() (ha_subArea = 4335 12350 5737 13752) +From here, it is looking for connections to the right side of the tile, so that seems +correct insofar as it goes. + +This is at one point hwere mvpmos is on top of mvpmosesd. This could account for +the (none) type since these types do not necessarily connect. May be a red herring. +Will instead need to do the same thing as done once previously, which is to watch +the node merges. Divide the (long) list of nodes into the three expected nets. + +The three nets are: PAD (1), the ESD pFET gates on the right (2), and the ESD pFET gates +on the left (3). + +sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix_0/a_19583_5855# (2) +a_20646_12358# (2) (split tile, left side) +a_20646_12770# (2) +a_17404_12358# (2) + +The four nodes above are the easiest to check for because there are only +four of them. When they end up in the connection list with anything else, +an error has occurred. + +a_20646_12488r# (1) (split tile, right side) +a_17404_12488r# (1) +a_14162_12488r# (1) +a_7678_12488r# (1) +a_4436_12488r# (1) +a_10920_12488r# (1) +sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix_0/a_3423_6005r# (1) + +sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix_0/a_1560_18645# (3) +a_20646_12900r# (4) ??? This is net VPB_DRVR. Now I'm very confused. +a_17404_12770# (3) +a_17404_12900r# (4) +a_14162_12358# (3) +a_14162_12770# (3) +a_14162_12900r# (4) +a_10920_12358# (3) +a_10920_12770# (3) +a_10920_12900r# (4) +a_7678_12358# (3) +a_7678_12770# (3) +a_7678_12900r# (4) +a_4436_12358# (3) +sky130_fd_io__gpio_ovtv2_octl_dat_i2c_fix_leak_fix_0/w_2900_10961# (4) +a_4436_12770# (3) +a_4436_12900r# (4) +a_20646_12146# (4) +a_17404_12146# (4) +a_14162_12146# (4) +a_10920_12146# (4) +a_7678_12146# (4) +a_4436_12146# (4) +sky130_fd_io__gpio_ovtv2_octl_dat_i2c_fix_leak_fix_0/w_2457_9746# (4) +sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix_0/sky130_fd_io__gpio_ovtv2_odrvr_sub_leak_fix_0/VPB_DRVR (4) +sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix_0/sky130_fd_io__gpio_ovtv2_odrvr_sub_leak_fix_0/sky130_fd_io__gpio_ovtv2_pudrvr_sub_0/sky130_fd_io__gpio_ovtv2_pudrvr_weak_1_0/VPB_DRVR (4) +sky130_fd_io__gpio_ovtv2_odrvr_i2c_fix_leak_fix_0/VPB_DRVR (4) + +---------------- +Okay, caught it trying to merge net (2) with something: + +node1 length 1 "a_20646_12900r#" +node2 length 35 (has already merged node (2) with something? How can that be?) + +So run again while looking for any node from (2) appearing in either list. +Inconclusive. Do more string comparisons to catch another net? +I'm so confused. . . + +Using net (1) looks better. . . +node 1 length 1 "a_4436_12358#" (from net 3) +node 2 length 3: ".../a_3423_6005r#" (net 1) + "(none)" (who knows?) + "a_4436_12488r#" (also net 1) + +Okay, then, caught magic trying to merge net 1 to net 3, ExtHier.c:693 +cum @ (4436, 12488) to (4456, 12508) + type mvpmos on left, type mvpdiff on right, + SIDE=1 so looking at mvpdiff +ha->hierOneTile at (4436, 12508) to (5737, 12588) + type mvpdiff (not split) + +Now check these two tiles. cum is on the leftmost flanged gate but the + right side points to the middle node which is (1). + hierOneTile is right above this so it is also (1). + +The mismatch is that "cum" is looking at the right side but picked up +a node name for net3. "cum" does not have a region associated with it, +so it would have had to pick up this node from the hash table. + +Run again: +Go up one: +name1 = "a_4436_12358#". How in heck did it get that name from that tile?? +extSubtreeTileToNode(): ttype = mvpdiff. Looking in this triangle for +a region in the original layout cell. So for this area, extConnFindFunc() +returned the wrong region. Run again but be sure to break at extConnFindFunc(). + +extConnFindFunc looks at a tile at (4436, 12488) but dinfo has SIDE 0. Why? +Okay, apparently DBTestNMInteract() failed. +Make sure this is true: +rect = (4436, 12488) to (4456 12508), ttype = TT_SIDE +tp = (4436, 12488) to (4456, 12508), tpdi = !TT_SIDE +Pretty clear failure. +Need to figure out why, but also worth considering a quick check in +DBTestNMInteract() for the somewhat common case of the same area, same +diagonal, which can be analyzed instantly. + +But for now, break on DBtiles.c:436 if tp is at 4436, 12488. +Oh, one has the wrong direction. . . The dinfo record is not guaranteed +to have TT_DIRECTION. Uh, but tt1 passed to DBTestNMInteract needs to +have TT_DIRECTION, because there's no tile associated with it. It +should be, though, because DBSrPaintNMArea gets ttype. + +Need to check this throughout the code! In most (many? some?) cases, +routines are passed tile + dinfo, where dinfo is only guaranteed to +contain TT_SIDE. If the routine then calls DBNMPaintPlane, the +TT_DIRECTION and TT_DIAGONAL must be set appropriately! This may be +wrong in more than one place! (Yes, it was.) + +Yet, I'm still seeing conflicting nodes. Why? +Looking at the .ext file, doesn't seem to have fixed a damn thing. +Fixed an error in the diagnostic reporting, should help with the confusion. + +node1 length 1 "a_4436_12488r#" (1) +node2 length 5 "...sub_leak_fix_0/PU_H_N[2]" + "(none)" (?!) + "...pudrvr_strong_0/PU_H_N[2]" + "...fix_leak_fix_0/PU_H_N[2]" + "m1_2996_14802#" +Leading to this: +cum : split tile at (4436, 12770) DIR=0, mvpmos on left, mvpdiff on right. +dinfo: SIDE=1. +ha->hierOneTile : split tile at (4436, 12770) DIR=0, hierType SIDE=1. +But name2 = "(none)". "(none)" is causing the crossover. "(none)" +is being caused by the improper type overlays but should not be used to +find a net. + +That helped a lot, but I'm still getting one conflicting node message. + +node1 length 1 "a_17404_12358#" (2) +node2 length 10 "...i2c_fix_leak_fix_0/a_1560_18645#" (3) + "a_17404_12770#" (3) +Leading to this: +cum : split tile at (17404, 12488) to (17424, 12508) +DIR=1, mvpmos on left, mvpdiff on right. +dinfo: SIDE=0 (looking at mvpmos) +ha->hierOneTile : poly at (17262, 12484) to (17404, 12508) + +name1 seems not right for tile cum. Take a look on the layout: +"cum" is not even close to net (2). That might be my own clerical error. + +Oh, my, I got an LVS match!!! + + diff --git a/commands/CmdCD.c b/commands/CmdCD.c index e9fa40eb..c03146c3 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -2550,8 +2550,9 @@ cmdContactFunc( break; TTMaskSetOnlyType(&smask, stype); - DBSrPaintNMArea((Tile *)NULL, ccs->rootDef->cd_planes[DBPlane(stype)], dinfo, - &ccs->area, &smask, cmdContactFunc2, (ClientData)ccs); + DBSrPaintNMArea((Tile *)NULL, ccs->rootDef->cd_planes[DBPlane(stype)], + TiGetTypeExact(tile) | dinfo, &ccs->area, &smask, + cmdContactFunc2, (ClientData)ccs); return 0; } diff --git a/commands/CmdFI.c b/commands/CmdFI.c index d9b6d9d2..2e7a2b99 100644 --- a/commands/CmdFI.c +++ b/commands/CmdFI.c @@ -1219,7 +1219,7 @@ CmdGetnode( TxError("Put the cursor in a layout window\n"); return; } - if( is_fast == TRUE ) + if (is_fast == TRUE) { SimRecomputeSel = TRUE; SimGetsnode(); @@ -1227,7 +1227,8 @@ CmdGetnode( else SimGetnode(); - if (SimGetnodeAlias) { /* "erase" the hash table */ + if (SimGetnodeAlias) /* "erase" the hash table */ + { HashKill(&SimGNAliasTbl); HashInit(&SimGNAliasTbl, 120, STRINGS); } @@ -1704,7 +1705,7 @@ CmdFindNetProc( */ hashpos = strrchr(s, '#'); if (hashpos != NULL) - if (*(hashpos - 1) == 'x') + if (*(hashpos - 1) == 'r') dinfo = TT_DIAGONAL | TT_SIDE; } } diff --git a/database/DBconnect.c b/database/DBconnect.c index 1fef0d4d..c8c767ed 100644 --- a/database/DBconnect.c +++ b/database/DBconnect.c @@ -626,7 +626,7 @@ donesides: if (IsSplit(tile)) { if (DBSrPaintNMArea((Tile *) NULL, csa->csa_def->cd_planes[i], - TiGetTypeExact(tile), &newArea, connectMask, + TiGetTypeExact(tile) | dinfo, &newArea, connectMask, dbcFindTileFunc, (ClientData)&tad) != 0) { STACKPUSH(PTR2CD(tad.tad_tile), dbConnectStack); diff --git a/database/DBtiles.c b/database/DBtiles.c index 8e0b9549..69fbba9e 100644 --- a/database/DBtiles.c +++ b/database/DBtiles.c @@ -449,148 +449,6 @@ nm_enum: return 1; } -#if 0 - rheight = rect->r_ytop - rect->r_ybot; - rwidth = rect->r_xtop - rect->r_xbot; - rmax = MAX(rheight, rwidth); - f1 = (BOTTOM(tp) > MINFINITY + 2) ? - ((dlong)(rect->r_ytop - BOTTOM(tp)) * rwidth) : DLONG_MAX; - f2 = (TOP(tp) < INFINITY - 2) ? - ((dlong)(TOP(tp) - rect->r_ybot) * rwidth) : DLONG_MAX; - - if (ttype & TT_SIDE) - { - /* Outside-of-triangle check---ignore sub-integer slivers */ - if (RIGHT(tp) < INFINITY - 2) - { - f3 = (dlong)(rect->r_xtop - RIGHT(tp)) * rheight; - f3 += rmax; - } - else - f3 = DLONG_MIN; - if ((ttype & TT_DIRECTION) ? (f2 < f3) : (f1 < f3)) - goto enum_next; - } - else - { - /* Outside-of-triangle check---ignore sub-integer slivers */ - if (LEFT(tp) > MINFINITY + 2) - { - f4 = (dlong)(LEFT(tp) - rect->r_xbot) * rheight; - f4 += rmax; - } - else - f4 = DLONG_MIN; - if ((ttype & TT_DIRECTION) ? (f1 < f4) : (f2 < f4)) - goto enum_next; - } - - /* Secondary checks---if tile is also non-Manhattan, is */ - /* either side of it outside the area? If so, restrict it. */ - /* This check is only necessary if the split directions are */ - /* the same, so we have to see if either of the neighboring */ - /* points is also inside the search triangle. */ - - ignore_sides = 0; - - if (IsSplit(tp)) - { - if (!TTMaskHasType(mask, SplitLeftType(tp))) - ignore_sides |= IGNORE_LEFT; - if (!TTMaskHasType(mask, SplitRightType(tp))) - ignore_sides |= IGNORE_RIGHT; - - tpt = TiGetTypeExact(tp); - if ((tpt & TT_DIRECTION) == (ttype & TT_DIRECTION)) - { - f3 = (LEFT(tp) > MINFINITY + 2) ? - ((dlong)(rect->r_xtop - LEFT(tp)) * rheight) : DLONG_MAX; - f4 = (RIGHT(tp) < INFINITY - 2) ? - ((dlong)(RIGHT(tp) - rect->r_xbot) * rheight) : DLONG_MAX; - - if (ttype & TT_SIDE) - { - /* Ignore sub-integer slivers */ - if (f4 != DLONG_MAX) f4 -= rmax; - if (f3 != DLONG_MAX) f3 += rmax; - - if (ttype & TT_DIRECTION) - { - if ((f2 < f3) && (f1 > f4)) - /* Tile bottom left is outside search area */ - ignore_sides |= IGNORE_LEFT; - } - else - { - if ((f1 < f3) && (f2 > f4)) - /* Tile top left is outside search area */ - ignore_sides |= IGNORE_LEFT; - } - } - else - { - /* Ignore sub-integer slivers */ - if (f4 != DLONG_MAX) f4 += rmax; - if (f3 != DLONG_MAX) f3 -= rmax; - - if (ttype & TT_DIRECTION) - { - if ((f2 > f3) && (f1 < f4)) - /* Tile top right is outside search area */ - ignore_sides |= IGNORE_RIGHT; - } - else - { - if ((f1 > f3) && (f2 < f4)) - /* Tile bottom right is outside search area */ - ignore_sides |= IGNORE_RIGHT; - } - } - } - - /* If the tile is larger than the search area or overlaps */ - /* the search area, we need to check if one of the sides */ - /* of the tile is disjoint from the search area. */ - - rheight = TOP(tp) - BOTTOM(tp); - rwidth = RIGHT(tp) - LEFT(tp); - rmax = MAX(rheight, rwidth); - f1 = (TOP(tp) < INFINITY - 2) ? - ((dlong)(TOP(tp) - rect->r_ybot) * rwidth) : DLONG_MAX; - f2 = (BOTTOM(tp) > MINFINITY + 2) ? - ((dlong)(rect->r_ytop - BOTTOM(tp)) * rwidth) : DLONG_MAX; - f3 = (RIGHT(tp) < INFINITY - 2) ? - ((dlong)(RIGHT(tp) - rect->r_xtop) * rheight) : DLONG_MAX; - f4 = (LEFT(tp) > MINFINITY + 2) ? - ((dlong)(rect->r_xbot - LEFT(tp)) * rheight) : DLONG_MAX; - - /* ignore sub-integer slivers */ - if (f4 < DLONG_MAX) f4 += rmax; - if (f3 < DLONG_MAX) f3 += rmax; - - if (SplitDirection(tp) ? (f1 < f4) : (f2 < f4)) - ignore_sides |= IGNORE_LEFT; - - if (SplitDirection(tp) ? (f2 < f3) : (f1 < f3)) - ignore_sides |= IGNORE_RIGHT; - - /* May call function twice to paint both sides of */ - /* the split tile, if necessary. */ - - if (!(ignore_sides & IGNORE_LEFT)) - { - if ((*func)(tp, (TileType)TT_DIAGONAL, arg)) return (1); - } - if (!(ignore_sides & IGNORE_RIGHT)) - { - if ((*func)(tp, (TileType)TT_DIAGONAL | TT_SIDE, arg)) return (1); - } - } - else - if (TTMaskHasType(mask, TiGetType(tp)) && (*func)(tp, (TileType)0, arg)) - return (1); -#endif - enum_next: tpnew = TR(tp); if (LEFT(tpnew) < rect->r_xtop) diff --git a/drc/DRCbasic.c b/drc/DRCbasic.c index 983342a5..a7fb088b 100644 --- a/drc/DRCbasic.c +++ b/drc/DRCbasic.c @@ -378,7 +378,8 @@ areaNMCheck(tile, dinfo, arg) TTMaskSetOnlyType(&mask, TiGetLeftType(tile)); TTMaskSetType(&mask, TiGetRightType(tile)); - if (DBSrPaintNMArea((Tile *)tile, (Plane *)NULL, dinfo, arg->dCD_rlist, + if (DBSrPaintNMArea((Tile *)tile, (Plane *)NULL, + TiGetTypeExact(tile) | dinfo, arg->dCD_rlist, &mask, areaNMReject, (ClientData)tile) == 0) return 0; } diff --git a/extract/ExtBasic.c b/extract/ExtBasic.c index 9ee7476a..a81f5b8c 100644 --- a/extract/ExtBasic.c +++ b/extract/ExtBasic.c @@ -265,7 +265,10 @@ extBasic(def, outFile) if (DBTreeSrTiles(&scontext, &transPlaneMask, 0, extFoundFunc, (ClientData)def) != 0) + { reg->treg_type = TT_SPACE; /* Disables the trans record */ + reg->treg_dinfo = (TileType)0; + } } /* @@ -912,7 +915,7 @@ extMakeNodeNumPrint(buf, lreg) * side, because otherwise if there is a valid type on the * left side, it will have the same generated node name. */ - sprintf(buf, "%s_%s%d_%s%dx#", + sprintf(buf, "%s_%s%d_%s%dr#", DBPlaneShortName(plane), (p->p_x < 0) ? "n": "", abs(p->p_x), (p->p_y < 0) ? "n": "", abs(p->p_y)); @@ -1889,8 +1892,8 @@ extOutputDevParams(reg, devptr, outFile, length, width, areavec, perimvec) else { resvalue = (ResValue)( - (double)ExtCurStyle->exts_sheetResist[reg->treg_type & TT_LEFTMASK] - * (double)length / (double)width); + (double)ExtCurStyle->exts_sheetResist[reg->treg_type + & TT_LEFTMASK] * (double)length / (double)width); he = HashLookOnly(&extTransRec.tr_devrec->exts_deviceResist, "terminal"); @@ -2207,7 +2210,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, reg->treg_type)). + * the gate node (ExtGetRegion(reg->treg_tile, reg->treg_dinfo)). */ extTransRec.tr_devrec = (ExtDevice *)NULL; extTransRec.tr_devmatch = 0; @@ -2234,7 +2237,8 @@ extOutputDevices(def, transList, outFile) arg.fra_def = def; arg.fra_connectsTo = ExtCurStyle->exts_deviceConn; - extTransRec.tr_gatenode = (NodeRegion *) ExtGetRegion(reg->treg_tile, reg->treg_type); + extTransRec.tr_gatenode = (NodeRegion *) ExtGetRegion(reg->treg_tile, + reg->treg_dinfo); t = reg->treg_type & TT_LEFTMASK; arg.fra_pNum = DBPlane(t); @@ -2250,13 +2254,13 @@ extOutputDevices(def, transList, outFile) arg.fra_uninit = (ClientData) extTransRec.tr_gatenode; arg.fra_region = (ExtRegion *) reg; arg.fra_each = extTransTileFunc; - ntiles = ExtFindNeighbors(reg->treg_tile, reg->treg_type, arg.fra_pNum, &arg); + ntiles = ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); /* Re-mark with extTransRec.tr_gatenode */ arg.fra_uninit = (ClientData) reg; arg.fra_region = (ExtRegion *) extTransRec.tr_gatenode; arg.fra_each = (int (*)()) NULL; - (void) ExtFindNeighbors(reg->treg_tile, reg->treg_type, arg.fra_pNum, &arg); + (void) ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); /* Are the terminal types on a compeletely different */ /* plane than the top type? If so, do an area search */ @@ -2310,7 +2314,8 @@ extOutputDevices(def, transList, outFile) node = NULL; /* First try to find a region under the device */ - extTransFindSubs(reg->treg_tile, reg->treg_type, tmask, def, &node, &tt); + extTransFindSubs(reg->treg_tile, reg->treg_dinfo, tmask, + def, &node, &tt); /* If the device has multiple tiles, then check all of them. * This is inefficient, so this routine first assumes that @@ -2333,18 +2338,18 @@ extOutputDevices(def, transList, outFile) arg.fra_uninit = (ClientData)extTransRec.tr_gatenode; arg.fra_region = (ExtRegion *)reg; arg.fra_each = extSDTileFunc; - ExtFindNeighbors(reg->treg_tile, reg->treg_type, + ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); arg.fra_uninit = (ClientData) reg; arg.fra_region = (ExtRegion *) extTransRec.tr_gatenode; arg.fra_each = (int (*)()) NULL; - ExtFindNeighbors(reg->treg_tile, reg->treg_type, + ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); for (lt = extSpecialDevice; lt; lt = lt->t_next) { - extTransFindSubs(lt->t, reg->treg_type, tmask, def, + extTransFindSubs(lt->t, reg->treg_dinfo, tmask, def, &node, &tt); if (node != NULL) { @@ -2528,7 +2533,7 @@ extOutputDevices(def, transList, outFile) /* are shorted. */ /* gate */ - node = (NodeRegion *)ExtGetRegion(reg->treg_tile, reg->treg_type); + node = (NodeRegion *)ExtGetRegion(reg->treg_tile, reg->treg_dinfo); fprintf(outFile, "\"%s\" ", extNodeName((LabRegion *)node)); /* First non-gate terminal */ @@ -2663,7 +2668,7 @@ extOutputDevices(def, transList, outFile) arg.fra_region = (ExtRegion *) reg; arg.fra_each = extAnnularTileFunc; - (void) ExtFindNeighbors(reg->treg_tile, reg->treg_type, + (void) ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); extSeparateBounds(n - 1); /* Handle MOScaps (if necessary) */ @@ -2687,7 +2692,7 @@ extOutputDevices(def, transList, outFile) arg.fra_uninit = (ClientData) reg; arg.fra_region = (ExtRegion *) extTransRec.tr_gatenode; arg.fra_each = (int (*)()) NULL; - (void) ExtFindNeighbors(reg->treg_tile, reg->treg_type, + (void) ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); } @@ -2754,7 +2759,7 @@ extOutputDevices(def, transList, outFile) arg.fra_uninit = (ClientData) extTransRec.tr_gatenode; arg.fra_region = (ExtRegion *) reg; arg.fra_each = extAnnularTileFunc; - (void) ExtFindNeighbors(reg->treg_tile, reg->treg_type, + (void) ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); if (extComputeCapLW(&length, &width) == FALSE) @@ -2784,7 +2789,7 @@ extOutputDevices(def, transList, outFile) arg.fra_uninit = (ClientData) reg; arg.fra_region = (ExtRegion *) extTransRec.tr_gatenode; arg.fra_each = (int (*)()) NULL; - (void) ExtFindNeighbors(reg->treg_tile, reg->treg_type, + (void) ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); } } @@ -2850,7 +2855,7 @@ extOutputDevices(def, transList, outFile) arg.fra_each = extAnnularTileFunc; else arg.fra_each = extResistorTileFunc; - (void) ExtFindNeighbors(reg->treg_tile, reg->treg_type, + (void) ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); if (extSpecialBounds[0] != NULL) @@ -2888,7 +2893,7 @@ extOutputDevices(def, transList, outFile) arg.fra_uninit = (ClientData) reg; arg.fra_region = (ExtRegion *) extTransRec.tr_gatenode; arg.fra_each = (int (*)()) NULL; - (void) ExtFindNeighbors(reg->treg_tile, reg->treg_type, + (void) ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); } else @@ -3012,7 +3017,7 @@ extOutputDevices(def, transList, outFile) arg.fra_uninit = (ClientData) extTransRec.tr_gatenode; arg.fra_region = (ExtRegion *) reg; arg.fra_each = extAnnularTileFunc; - (void) ExtFindNeighbors(reg->treg_tile, reg->treg_type, + (void) ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); if (extComputeCapLW(&length, &width) == FALSE) @@ -3042,7 +3047,7 @@ extOutputDevices(def, transList, outFile) arg.fra_uninit = (ClientData) reg; arg.fra_region = (ExtRegion *) extTransRec.tr_gatenode; arg.fra_each = (int (*)()) NULL; - (void) ExtFindNeighbors(reg->treg_tile, reg->treg_type, + (void) ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); } @@ -3086,7 +3091,7 @@ extOutputDevices(def, transList, outFile) } /* gate */ - node = (NodeRegion *) ExtGetRegion(reg->treg_tile, reg->treg_type); + node = (NodeRegion *) ExtGetRegion(reg->treg_tile, reg->treg_dinfo); ll = node->nreg_labels; extTransOutTerminal((LabRegion *) node, ll, LL_GATEATTR, extTransRec.tr_gatelen, 0, 0, 0, outFile); @@ -3159,8 +3164,10 @@ extTransFindSubs(tile, dinfo, mask, def, sn, layerptr) { if (TTMaskIntersect(&DBPlaneTypes[pNum], &lmask)) { - if (DBSrPaintNMArea((Tile *)NULL, def->cd_planes[pNum], dinfo, &tileAreaPlus, - mask, extTransFindSubsFunc1, (ClientData)&noderec)) + if (DBSrPaintNMArea((Tile *)NULL, def->cd_planes[pNum], + TiGetTypeExact(tile) | dinfo, &tileAreaPlus, + mask, extTransFindSubsFunc1, + (ClientData)&noderec)) { *sn = noderec.region; if (layerptr) *layerptr = noderec.layer; @@ -3224,8 +3231,10 @@ extTransFindId(tile, dinfo, mask, def, idtypeptr) { if (TTMaskIntersect(&DBPlaneTypes[pNum], mask)) { - if (DBSrPaintNMArea((Tile *)NULL, def->cd_planes[pNum], dinfo, &tileArea, - mask, extTransFindIdFunc1, (ClientData)idtypeptr)) + if (DBSrPaintNMArea((Tile *)NULL, def->cd_planes[pNum], + TiGetTypeExact(tile) | dinfo, + &tileArea, mask, extTransFindIdFunc1, + (ClientData)idtypeptr)) return 1; } } @@ -3878,7 +3887,7 @@ extTransPerimFunc(bp) extEnumTerminal(bp->b_outside, dinfo, DBConnectTbl, extTermAPFunc, (ClientData)&eapd); - shared = 1; + shared = 0; free_magic1_t mm1 = freeMagic1_init(); while (eapd.eapd_shared) { @@ -4356,6 +4365,10 @@ extTransOutTerminal(lreg, ll, whichTerm, len, area, perim, shared, outFile) int n; char fmt; + /* If a terminal did not abut a device identifier layer, then + * automatically treat this is a a single, non-shared terminal. + */ + if (shared == 0) shared = 1; fprintf(outFile, " \"%s\" %d", extNodeName(lreg), len); for (fmt = ' '; ll; ll = ll->ll_next) @@ -4664,38 +4677,22 @@ 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. + * to the node at the given plane and location. If there is a split + * tile at the location, then the upper bits of reg->lreg_type include + * the split information including TT_SIDE, and the tile type is always + * in the lower bits. */ - /* (only TT_SIDE is relevant here) */ - TileType regdinfo = reg->lreg_type & (TT_DIAGONAL | TT_SIDE | TT_DIRECTION); + TileType regdinfo = dinfo & (TT_DIAGONAL | TT_SIDE | TT_DIRECTION); if (IsSplit(tile)) - { - /* Only consider split tiles if the lower-left-hand corner */ - /* is only the type under consideration. */ - - if (!(dinfo & TT_SIDE) && SplitDirection(tile)) - type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); - else - { - type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); - /* (Are these type checks necessary?) */ - if ((type == TT_SPACE) || !TTMaskHasType(&DBPlaneTypes[plane], type)) - type = (dinfo & TT_SIDE) ? SplitLeftType(tile) : SplitRightType(tile); - if ((type == TT_SPACE) || !TTMaskHasType(&DBPlaneTypes[plane], type)) - return; - } - } + type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); else type = TiGetType(tile); if (plane < reg->lreg_pnum) { - reg->lreg_type = (type & TT_LEFTMASK) | regdinfo; + reg->lreg_type = type | regdinfo; reg->lreg_pnum = plane; reg->lreg_ll = tile->ti_ll; } @@ -4704,13 +4701,13 @@ extSetNodeNum(reg, plane, tile, dinfo) if (LEFT(tile) < reg->lreg_ll.p_x) { reg->lreg_ll = tile->ti_ll; - reg->lreg_type = (type & TT_LEFTMASK) | regdinfo; + reg->lreg_type = type | 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 & TT_LEFTMASK) | regdinfo; + reg->lreg_type = type | regdinfo; } } } @@ -4756,10 +4753,13 @@ extTransFirst(tile, dinfo, arg) 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); + reg->treg_dinfo = dinfo; } else + { reg->treg_type = TiGetTypeExact(tile); + reg->treg_dinfo = (TileType)0; + } /* Prepend it to the region list */ reg->treg_next = (TransRegion *) arg->fra_region; @@ -5495,8 +5495,7 @@ donesides: if (is_split) DBSrPaintNMArea((Tile *) NULL, arg->fra_def->cd_planes[pNum], - (TiGetTypeExact(tile) | dinfo) & - (TT_DIAGONAL | TT_SIDE | TT_DIRECTION), + TiGetTypeExact(tile) | dinfo, &biggerArea, mask, extNbrPushFunc, (ClientData) &pla); else diff --git a/extract/ExtHard.c b/extract/ExtHard.c index 8c1811bf..e4c182f1 100644 --- a/extract/ExtHard.c +++ b/extract/ExtHard.c @@ -83,7 +83,11 @@ extLabFirst(tile, dinfo, arg) reg->treg_pnum = DBNumPlanes; reg->treg_area = DBNumPlanes; reg->treg_tile = tile; - reg->treg_type = dinfo; + reg->treg_dinfo = dinfo; + + /* Setting treg_pnum to DBNumPlanes ensures that treg_ll and treg_type + * will be set for identifying the node when extSetNodeNum() is called. + */ /* Prepend it to the region list */ reg->treg_next = (TransRegion *) arg->fra_region; @@ -498,7 +502,7 @@ extHardFreeAll(def, tReg) if (reg->treg_tile) { arg.fra_pNum = reg->treg_area; - ExtFindNeighbors(reg->treg_tile, reg->treg_type, arg.fra_pNum, &arg); + ExtFindNeighbors(reg->treg_tile, reg->treg_dinfo, arg.fra_pNum, &arg); } /* Free all LabelLists and then the region */ diff --git a/extract/ExtHier.c b/extract/ExtHier.c index b676da96..997c2033 100644 --- a/extract/ExtHier.c +++ b/extract/ExtHier.c @@ -183,6 +183,7 @@ extHierSubstrate(ha, use, x, y) /* The parent def's substrate node is in glob_subsnode */ name1 = extNodeName(glob_subsnode); + if (*name1 == '(' && !strcmp(name1, "(none)")) return; /* Don't process "(none)" nodes! */ he = HashFind(table, name1); nn = (NodeName *) HashGetValue(he); node1 = nn ? nn->nn_node : extHierNewNode(he); @@ -478,6 +479,7 @@ extHierConnectFunc1(oneTile, dinfo, ha) name = (*ha->ha_nodename)(ha->hierOneTile, ha->hierType, ha->hierPNum, extHierOneFlat, ha, TRUE); + if (*name == '(' && !strcmp(name, "(none)")) return 0; /* Don't process "(none)" nodes! */ he = HashFind(table, name); nn = (NodeName *) HashGetValue(he); node2 = nn ? nn->nn_node : extHierNewNode(he); @@ -592,12 +594,14 @@ extHierConnectFunc2(cum, dinfo, ha) if (extConnectsTo(ha->hierType & TT_LEFTMASK, ttype, ExtCurStyle->exts_nodeConn)) { name1 = (*ha->ha_nodename)(cum, dinfo, ha->hierPNumBelow, extHierCumFlat, ha, TRUE); + if (*name1 == '(' && !strcmp(name1, "(none)")) return 0; /* Don't process "(none)" nodes! */ he = HashFind(table, name1); nn = (NodeName *) HashGetValue(he); node1 = nn ? nn->nn_node : extHierNewNode(he); name2 = (*ha->ha_nodename)(ha->hierOneTile, ha->hierType, ha->hierPNum, extHierOneFlat, ha, TRUE); + if (*name2 == '(' && !strcmp(name2, "(none)")) return 0; /* Don't process "(none)" nodes! */ he = HashFind(table, name2); nn = (NodeName *) HashGetValue(he); node2 = nn ? nn->nn_node : extHierNewNode(he); @@ -703,11 +707,13 @@ extHierConnectFunc3(cum, dinfo, ha) { name1 = (*ha->ha_nodename)(cum, ha->hierType, ha->hierPNumBelow, extHierCumFlat, ha, TRUE); + if (*name1 == '(' && !strcmp(name1, "(none)")) return 0; /* Don't process "(none)" nodes! */ he = HashFind(table, name1); nn = (NodeName *) HashGetValue(he); node1 = nn ? nn->nn_node : extHierNewNode(he); name2 = lab->lab_text; + if (*name2 == '(' && !strcmp(name2, "(none)")) return 0; /* Don't process "(none)" nodes! */ he = HashFind(table, name2); nn = (NodeName *) HashGetValue(he); node2 = nn ? nn->nn_node : extHierNewNode(he); diff --git a/extract/ExtNghbors.c b/extract/ExtNghbors.c index 770e8a7f..4347480a 100644 --- a/extract/ExtNghbors.c +++ b/extract/ExtNghbors.c @@ -334,7 +334,8 @@ donesides: { pla.plane = pNum; (void) DBSrPaintNMArea((Tile *) NULL, - arg->fra_def->cd_planes[pNum], dinfo, &biggerArea, + arg->fra_def->cd_planes[pNum], + TiGetTypeExact(tile) | dinfo, &biggerArea, mask, extNbrPushFunc, (ClientData) &pla); } } @@ -562,7 +563,7 @@ termbottom: termright: if (IsSplit(tp) && !(tpdi & TT_SIDE)) goto termtop; - for (t2 = TR(tp); BOTTOM(t2) > tileArea.r_ybot; t2 = LB(t2)) + for (t2 = TR(tp); TOP(t2) > tileArea.r_ybot; t2 = LB(t2)) { if (IsSplit(t2)) checktype = SplitLeftType(t2); @@ -589,7 +590,7 @@ termtop: if (IsSplit(tp) && (((tpdi & TT_SIDE) ? 1 : 0) ^ SplitDirection(tp))) goto termdone; - for (t2 = RT(tp); LEFT(t2) > tileArea.r_xbot; t2 = BL(t2)) + for (t2 = RT(tp); RIGHT(t2) > tileArea.r_xbot; t2 = BL(t2)) { if (IsSplit(t2)) checktype = SplitBottomType(t2); diff --git a/extract/ExtSubtree.c b/extract/ExtSubtree.c index b49cba42..f3be58cb 100644 --- a/extract/ExtSubtree.c +++ b/extract/ExtSubtree.c @@ -1100,7 +1100,7 @@ extSubtreeTileToNode(tp, dinfo, pNum, et, ha, doHard) { if (DBSrPaintNMArea((Tile *) NULL, et->et_lookNames->cd_planes[pNum], - dinfo, &r, &DBAllButSpaceBits, + TiGetTypeExact(tp) | dinfo, &r, &DBAllButSpaceBits, extConnFindFunc, (ClientData) ®)) { if (SigInterruptPending) diff --git a/extract/extractInt.h b/extract/extractInt.h index 88964c1c..01873c01 100644 --- a/extract/extractInt.h +++ b/extract/extractInt.h @@ -225,19 +225,14 @@ typedef struct treg { struct treg *treg_next; /* Next region in list */ int treg_pnum; /* UNUSED */ - int treg_type; /* Type of treg_tile* */ + int treg_type; /* UNUSED */ Point treg_ll; /* UNUSED */ LabelList *treg_labels; /* Attribute list */ Tile *treg_tile; /* Some tile in the channel */ + TileType treg_dinfo; /* Diagonal information for treg_tile* */ 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(). */ diff --git a/netmenu/NMshowcell.c b/netmenu/NMshowcell.c index f74e249c..74b79fd1 100644 --- a/netmenu/NMshowcell.c +++ b/netmenu/NMshowcell.c @@ -131,8 +131,10 @@ nmscRedrawFunc(tile, dinfo, window) extern int nmscAlways1(); /* Forward reference. */ TiToRect(tile, &area); - if (!DBSrPaintNMArea((Tile *)NULL, nmscPlane, dinfo, &area, - &DBAllButSpaceBits, nmscAlways1, (ClientData) NULL)) + if (!DBSrPaintNMArea((Tile *)NULL, nmscPlane, + TiGetTypeExact(tile) | dinfo, + &area, &DBAllButSpaceBits, nmscAlways1, + (ClientData) NULL)) return 0; WindSurfaceToScreen(window, &area, &screenArea); GrFastBox(&screenArea); diff --git a/sim/SimDBstuff.c b/sim/SimDBstuff.c index 259889dc..7aac505c 100644 --- a/sim/SimDBstuff.c +++ b/sim/SimDBstuff.c @@ -601,6 +601,7 @@ SimSrConnect( csa.csa_clientFunc = func; csa.csa_clientData = clientData; + csa.csa_clientDefault = CLIENTDEFAULT; csa.csa_clear = FALSE; csa.csa_connect = connect; csa.csa_pNum = startPlane;