More updates. . . Got it to the point were gpio_ovtv2 is LVS
clean, which has never happened before.
This commit is contained in:
parent
846c8e0f65
commit
3de9ed9cbf
441
README
441
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!!!
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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(). */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue