More updates. . . Got it to the point were gpio_ovtv2 is LVS

clean, which has never happened before.
This commit is contained in:
R. Timothy Edwards 2026-01-17 20:49:52 -05:00
parent 846c8e0f65
commit 3de9ed9cbf
14 changed files with 527 additions and 219 deletions

441
README
View File

@ -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!!!

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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) &reg))
{
if (SigInterruptPending)

View File

@ -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(). */

View File

@ -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);

View File

@ -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;