Fix offset track and extension problem in the H-Tree.
* Bug: In cumulus/plugins.block.htree._connectLeaf(), when HEAVY_LEAF_LOAD was used, the additionnal horizontal segment added to connect the extra buffer may have been: 1. Misaligned, causing the blockage to be wrongly taken into account and leading to potential short circuits. 2. In some RoutingGauge configurations, the extra length added to the segment left extention was too short, leading to DRC violations. So created new GaugeConf methods to manage thoses problems: * GaugeConf.getStackX() & GaugeConf.getStackY() to get back the contact coordinates of the *deep* part (typically the METAL2). So be able to align on them. * GaugeConf.createHorizontal(), added a parameter to explicitely state the additional length of the *left* extension. This is lazy, will soon add both.
This commit is contained in:
parent
53f019d165
commit
dcc26f23c7
|
@ -245,22 +245,18 @@ class GaugeConf ( object ):
|
|||
else: depth = self.verticalDepth
|
||||
return self.getTrack( x, depth, offset )
|
||||
|
||||
def createHorizontal ( self, source, target, y, flags ):
|
||||
def createHorizontal ( self, source, target, y, flags, dxSource=0 ):
|
||||
if flags & GaugeConf.DeepDepth: depth = self.horizontalDeepDepth
|
||||
else: depth = self.horizontalDepth
|
||||
|
||||
layer = self._routingGauge.getRoutingLayer(depth)
|
||||
|
||||
dxSource = 0
|
||||
if flags & GaugeConf.SourceExtend: dxSource = self._routingGauge.getPitch(layer)
|
||||
|
||||
if not dxSource and flags & GaugeConf.SourceExtend:
|
||||
dxSource = self._routingGauge.getPitch(layer)
|
||||
if flags & GaugeConf.UseContactWidth:
|
||||
width = source.getBoundingBox(layer.getBasicLayer()).getHeight()
|
||||
else:
|
||||
width = self._routingGauge.getLayerGauge(depth).getWireWidth()
|
||||
if flags & GaugeConf.ExpandWidth:
|
||||
width += DbU.fromLambda( 1.0 )
|
||||
|
||||
segment = Horizontal.create( source, target, layer, y, width )
|
||||
segment.setDxSource( -dxSource )
|
||||
trace( 550, segment )
|
||||
|
@ -449,6 +445,98 @@ class GaugeConf ( object ):
|
|||
self.expandMinArea( topContact )
|
||||
return
|
||||
|
||||
def getStackY ( self, topContact, flags ):
|
||||
"""
|
||||
Get the Y coordinate of a stack contact, on the top level or in
|
||||
the deep routing level.
|
||||
|
||||
:param topContact: The topmost contact of the VIA stack.
|
||||
|
||||
.. note:: A stacked contact is a set of contacts with short
|
||||
segments to connect them. Segments are alternately
|
||||
H & V, according to the routing gauge. Segments are
|
||||
put on the routing tracks, so the X/Y coordinates
|
||||
of the various contacts *may* slighlty vary.
|
||||
"""
|
||||
trace( 550, '\tgetStackY() {}\n'.format( topContact ))
|
||||
y = topContact.getY()
|
||||
lg = self.routingGauge.getLayerGauge( topContact.getLayer().getTop() )
|
||||
if lg:
|
||||
if lg.getDirection() == RoutingLayerGauge.Horizontal:
|
||||
y = topContact.getY()
|
||||
if not (flags & GaugeConf.DeepDepth):
|
||||
return y
|
||||
contact = topContact
|
||||
depth = -1
|
||||
while contact:
|
||||
count = 0
|
||||
segment = None
|
||||
for component in contact.getSlaveComponents():
|
||||
if isinstance(component,Horizontal):
|
||||
horizontal = component
|
||||
lg = self.routingGauge.getLayerGauge( horizontal.getLayer() )
|
||||
if depth == -1 or lg.getDepth() < depth:
|
||||
segment = horizontal
|
||||
depth = lg.getDepth()
|
||||
if isinstance(component,Vertical):
|
||||
vertical = component
|
||||
lg = self.routingGauge.getLayerGauge( vertical.getLayer() )
|
||||
if depth == -1 or lg.getDepth() < depth:
|
||||
segment = vertical
|
||||
depth = lg.getDepth()
|
||||
if not segment:
|
||||
return y
|
||||
if depth == self.horizontalDeepDepth:
|
||||
return segment.getY()
|
||||
contact = segment.getOppositeAnchor( contact )
|
||||
return y
|
||||
|
||||
def getStackX ( self, topContact, flags ):
|
||||
"""
|
||||
Get the X coordinate of a stack contact, on the top level or in
|
||||
the deep routing level.
|
||||
|
||||
:param topContact: The topmost contact of the VIA stack.
|
||||
|
||||
.. note:: A stacked contact is a set of contacts with short
|
||||
segments to connect them. Segments are alternately
|
||||
H & V, according to the routing gauge. Segments are
|
||||
put on the routing tracks, so the X/Y coordinates
|
||||
of the various contacts *may* slighlty vary.
|
||||
"""
|
||||
trace( 550, '\tgetStackX() {}\n'.format( topContact ))
|
||||
x = topContact.getX()
|
||||
lg = self.routingGauge.getLayerGauge( topContact.getLayer().getTop() )
|
||||
if lg:
|
||||
if lg.getDirection() == RoutingLayerGauge.Horizontal:
|
||||
x = topContact.getX()
|
||||
if not (flags & GaugeConf.DeepDepth):
|
||||
return y
|
||||
contact = topContact
|
||||
depth = -1
|
||||
while contact:
|
||||
count = 0
|
||||
segment = None
|
||||
for component in contact.getSlaveComponents():
|
||||
if isinstance(component,Horizontal):
|
||||
horizontal = component
|
||||
lg = self.routingGauge.getLayerGauge( horizontal.getLayer() )
|
||||
if depth == -1 or lg.getDepth() < depth:
|
||||
segment = horizontal
|
||||
depth = lg.getDepth()
|
||||
if isinstance(component,Vertical):
|
||||
vertical = component
|
||||
lg = self.routingGauge.getLayerGauge( vertical.getLayer() )
|
||||
if depth == -1 or lg.getDepth() < depth:
|
||||
segment = vertical
|
||||
depth = lg.getDepth()
|
||||
if not segment:
|
||||
return x
|
||||
if depth == self.verticalDeepDepth:
|
||||
return segment.getX()
|
||||
contact = segment.getOppositeAnchor( contact )
|
||||
return x
|
||||
|
||||
def expandMinArea ( self, topContact ):
|
||||
segments = []
|
||||
contacts = [ topContact ]
|
||||
|
|
|
@ -96,14 +96,18 @@ class HTree ( object ):
|
|||
hLeafDepth = gaugeConf.horizontalDepth - 2
|
||||
gaugeConf.setStackPosition( contact, x, y )
|
||||
gaugeConf.createVertical ( contact, forkContact, x, 0 )
|
||||
trace( 550, '\tLeaf contact:{}\n'.format( contact ))
|
||||
if len(leaf.buffers) > 1:
|
||||
tl1Contact = gaugeConf.rpAccessByPlugName( leaf.buffers[1], bufferConf.input , ckNet, GaugeConf.DeepDepth|GaugeConf.HAccess )
|
||||
tl2Contact = gaugeConf.rpAccessByPlugName( leaf.buffers[2], bufferConf.input , ckNet )
|
||||
tl2Y = gaugeConf.getTrack( tl2Contact.getY(), hLeafDepth, 2 )
|
||||
left1X = gaugeConf.getNearestVerticalTrack( tl1Contact.getX(), 0, 0 )
|
||||
left1Y = gaugeConf.getStackY( contact, GaugeConf.DeepDepth )
|
||||
dxLeft = contact.getX() - gaugeConf.getStackX( contact, GaugeConf.DeepDepth )
|
||||
gaugeConf.expandMinArea( tl2Contact )
|
||||
gaugeConf.setStackPosition( tl1Contact, left1X , y )
|
||||
gaugeConf.createHorizontal( contact , tl1Contact, y , GaugeConf.DeepDepth|GaugeConf.SourceExtend )
|
||||
gaugeConf.setStackPosition( tl1Contact, left1X , left1Y )
|
||||
#gaugeConf.createHorizontal( contact , tl1Contact, left1Y , GaugeConf.DeepDepth|GaugeConf.SourceExtend )
|
||||
gaugeConf.createHorizontal( contact , tl1Contact, left1Y , GaugeConf.DeepDepth, dxLeft )
|
||||
gaugeConf.createVertical ( contact , tl2Contact, x, 0 )
|
||||
|
||||
def _rrouteHTree ( self, qt ):
|
||||
|
@ -173,6 +177,7 @@ class HTree ( object ):
|
|||
if qt.tl:
|
||||
self._connectLeaf( qt.tl, ckNet, leftContact, tlContact, leftX, tlY )
|
||||
if qt.bl:
|
||||
trace( 550, '\tConnect BL leaf, leftX={} blY={}\n'.format( DbU.getValueString(leftX), DbU.getValueString(blY) ))
|
||||
self._connectLeaf( qt.bl, ckNet, leftContact, blContact, leftX, blY )
|
||||
if qt.tr:
|
||||
self._connectLeaf( qt.tr, ckNet, rightContact, trContact, rightX, tlY )
|
||||
|
|
Loading…
Reference in New Issue