Add the ability to specify the H-track position of a H-Tree.

Formerly, the H-Track could be shifted *relative* to the position of
the center of the RoutingPad. Which may become fragile in case of a
change in the standard cell library. So we create a new feature allowing
to specify the H-track as an offset *from the bottom of the slice*.
Two offset can be specified:
  * spares.htreeOffsetDriver : for the main H part, connected to the
      driver.
  * spares.htreeOffsetSink : for the small parts connecting to every
      fours sinks of the tree.
  This to avoid those two to overlap. The sink of the "N" stage with
the driver of the "N+1" stage (so input & ouput of the same buffer).
This commit is contained in:
Jean-Paul Chaput 2023-08-03 17:01:48 +02:00
parent f29e65d908
commit 49a37addae
3 changed files with 179 additions and 60 deletions

View File

@ -30,6 +30,8 @@ p = Cfg.getParamInt ( "katabatic.globalLengthThreshold" ).setInt ( 1
p = Cfg.getParamPercentage( "katabatic.saturateRatio" ).setPercentage( 80 ) p = Cfg.getParamPercentage( "katabatic.saturateRatio" ).setPercentage( 80 )
p = Cfg.getParamInt ( "katabatic.saturateRp" ).setInt ( 8 ) p = Cfg.getParamInt ( "katabatic.saturateRp" ).setInt ( 8 )
p = Cfg.getParamString ( 'katabatic.topRoutingLayer' ).setString ( 'METAL5' ) p = Cfg.getParamString ( 'katabatic.topRoutingLayer' ).setString ( 'METAL5' )
#p = Cfg.getParamInt ( "spares.htreeOffsetDriver" ).setInt ( 4 )
#p = Cfg.getParamInt ( "spares.htreeOffsetSink" ).setInt ( 6 )
# Kite parameters. # Kite parameters.
p = Cfg.getParamInt( "kite.hTracksReservedLocal" ); p.setInt( 3 ); p.setMin( 0 ); p.setMax( 20 ) p = Cfg.getParamInt( "kite.hTracksReservedLocal" ); p.setInt( 3 ); p.setMin( 0 ); p.setMax( 20 )

View File

@ -67,10 +67,12 @@ class GaugeConf ( object ):
OffsetTop1 = 0x0008 OffsetTop1 = 0x0008
OffsetTop2 = 0x0010 OffsetTop2 = 0x0010
OffsetBottom1 = 0x0020 OffsetBottom1 = 0x0020
DeepDepth = 0x0040 OffsetBottom2 = 0x0040
UseContactWidth = 0x0080 OffsetFromSlice = 0x0080
ExpandWidth = 0x0100 DeepDepth = 0x0100
SourceExtend = 0x0200 UseContactWidth = 0x0200
ExpandWidth = 0x0400
SourceExtend = 0x0800
def __init__ ( self ): def __init__ ( self ):
self._cellGauge = None self._cellGauge = None
@ -245,6 +247,11 @@ class GaugeConf ( object ):
trace( 550, ' -> utrack={}\n'.format( DbU.getValueString(utrack) )) trace( 550, ' -> utrack={}\n'.format( DbU.getValueString(utrack) ))
return utrack + offset*rg.getPitch() return utrack + offset*rg.getPitch()
def getHorizontalPitch ( self, flags ):
if flags & GaugeConf.DeepDepth: depth = self.horizontalDeepDepth
else: depth = self.horizontalDepth
return self._routingGauge.getLayerGauge( depth ).getPitch()
def getNearestHorizontalTrack ( self, y, flags, offset=0 ): def getNearestHorizontalTrack ( self, y, flags, offset=0 ):
if flags & GaugeConf.DeepDepth: depth = self.horizontalDeepDepth if flags & GaugeConf.DeepDepth: depth = self.horizontalDeepDepth
else: depth = self.horizontalDepth else: depth = self.horizontalDepth
@ -289,8 +296,9 @@ class GaugeConf ( object ):
trace( 550, segment ) trace( 550, segment )
return segment return segment
def rpAccess ( self, rp, flags ): def rpAccess ( self, rp, flags, yoffset ):
trace( 550, ',+', '\tGaugeConf.rpAccess() {}\n'.format( rp )) trace( 550, ',+', '\tGaugeConf.rpAccess() {}\n'.format( rp ))
trace( 550, '\tHAccess set : {}\n'.format( flags&GaugeConf.HAccess ))
startDepth = self.routingGauge.getLayerDepth( rp.getOccurrence().getEntity().getLayer() ) startDepth = self.routingGauge.getLayerDepth( rp.getOccurrence().getEntity().getLayer() )
trace( 550, '\tlayer:{} startDepth:{}\n'.format(rp.getOccurrence().getEntity().getLayer(),startDepth) ) trace( 550, '\tlayer:{} startDepth:{}\n'.format(rp.getOccurrence().getEntity().getLayer(),startDepth) )
if rp in self._rpToAccess: if rp in self._rpToAccess:
@ -315,15 +323,28 @@ class GaugeConf ( object ):
#if flags & GaugeConf.OffsetTop1: dy -= hpitch #if flags & GaugeConf.OffsetTop1: dy -= hpitch
#contact1.setDy( dy ) #contact1.setDy( dy )
yoffset = 0 rg = self.routingGauge.getLayerGauge( startDepth )
if flags & GaugeConf.OffsetBottom1: yoffset = 1
if flags & GaugeConf.OffsetTop1: yoffset = -1
if flags & GaugeConf.OffsetTop2: yoffset = -2
trace( 550, '\tyoffset:{}\n'.format(yoffset) )
if startDepth == 0:
rg = self.routingGauge.getLayerGauge( 0 )
rpContact = Contact.create( rp, rg.getLayer(), 0, 0 ) rpContact = Contact.create( rp, rg.getLayer(), 0, 0 )
if startDepth == 0:
if flags & GaugeConf.OffsetFromSlice:
sliceY = rpContact.getY() - (rpContact.getY() % self._cellGauge.getSliceHeight())
if yoffset < 0:
sliceY += self._cellGauge.getSliceHeight()
ytrack = self.getTrack( sliceY, self.horizontalDeepDepth, yoffset )
trace( 550, '\tyoffset (from slice):{}\n'.format(yoffset) )
trace( 550, '\tPut on Y-track:{}\n'.format(DbU.getValueString(ytrack)) )
else:
if yoffset is None:
yoffset = 0
if flags & GaugeConf.OffsetBottom1: yoffset = -1
if flags & GaugeConf.OffsetBottom2: yoffset = -2
if flags & GaugeConf.OffsetTop1: yoffset = 1
if flags & GaugeConf.OffsetTop2: yoffset = 2
trace( 550, '\tyoffset (from flags):{}\n'.format( yoffset ))
ytrack = self.getTrack( rpContact.getY(), self.horizontalDeepDepth, yoffset ) ytrack = self.getTrack( rpContact.getY(), self.horizontalDeepDepth, yoffset )
trace( 550, '\tyoffset (from contact):{}\n'.format(yoffset) )
trace( 550, '\tPut on Y-track:{}\n'.format(DbU.getValueString(ytrack)) )
contact1 = Contact.create( rp.getNet() contact1 = Contact.create( rp.getNet()
, self._routingGauge.getContactLayer( 0 ) , self._routingGauge.getContactLayer( 0 )
, rpContact.getX() , rpContact.getX()
@ -341,8 +362,6 @@ class GaugeConf ( object ):
#trace( 550, '\tPut on Y-tracks:{}\n'.format(DbU.getValueString(ytrack)) ) #trace( 550, '\tPut on Y-tracks:{}\n'.format(DbU.getValueString(ytrack)) )
#contact1.setDy( dy ) #contact1.setDy( dy )
else: else:
rg = self.routingGauge.getLayerGauge( startDepth )
rpContact = Contact.create( rp, rg.getLayer(), 0, 0 )
ytrack = self.getTrack( rpContact.getY(), startDepth, 0 ) ytrack = self.getTrack( rpContact.getY(), startDepth, 0 )
#dy = ytrack - contact1.getY() #dy = ytrack - contact1.getY()
contact1 = Contact.create( rp.getNet() contact1 = Contact.create( rp.getNet()
@ -433,14 +452,14 @@ class GaugeConf ( object ):
self._plugToRp[plug] = rp self._plugToRp[plug] = rp
return rp return rp
def rpAccessByOccurrence ( self, occurrence, net, flags ): def rpAccessByOccurrence ( self, occurrence, net, flags, yoffset=None ):
plug = occurrence.getEntity() plug = occurrence.getEntity()
if plug in self._plugToRp: if plug in self._plugToRp:
rp = self._plugToRp[plug] rp = self._plugToRp[plug]
else: else:
rp = RoutingPad.create( net, occurrence, RoutingPad.BiggestArea ) rp = RoutingPad.create( net, occurrence, RoutingPad.BiggestArea )
self._plugToRp[plug] = rp self._plugToRp[plug] = rp
return self.rpAccess( self.rpByOccurrence(occurrence,net), flags ) return self.rpAccess( self.rpByOccurrence(occurrence,net), flags, yoffset )
def rpByPlug ( self, plug, net ): def rpByPlug ( self, plug, net ):
""" """
@ -464,15 +483,15 @@ class GaugeConf ( object ):
""" """
return self.rpByPlug( getPlugByName(instance,plugName), net ) return self.rpByPlug( getPlugByName(instance,plugName), net )
def rpAccessByPlug ( self, plug, net, flags ): def rpAccessByPlug ( self, plug, net, flags, yoffset=None ):
return self.rpAccess( self.rpByPlug(plug,net), flags ) return self.rpAccess( self.rpByPlug(plug,net), flags, yoffset )
def rpAccessByPlugName ( self, instance, plugName, net, flags=0 ): def rpAccessByPlugName ( self, instance, plugName, net, flags=0, yoffset=None ):
""" """
Creates a RoutingPad from a Plug (using ``rpByPlug()``) and build a contact Creates a RoutingPad from a Plug (using ``rpByPlug()``) and build a contact
stack using a relative positionning specified by ``flags``. stack using a relative positionning specified by ``flags``.
""" """
return self.rpAccess( self.rpByPlugName(instance,plugName,net), flags ) return self.rpAccess( self.rpByPlugName(instance,plugName,net), flags, yoffset )
def setStackPosition ( self, topContact, x, y ): def setStackPosition ( self, topContact, x, y ):
trace( 550, '\tGaugeConf.setStackPosition() @({},{}) for {}\n' \ trace( 550, '\tGaugeConf.setStackPosition() @({},{}) for {}\n' \
@ -1376,6 +1395,9 @@ class BlockConf ( GaugeConf ):
self.editor = None self.editor = None
self.framework = AllianceFramework.get() self.framework = AllianceFramework.get()
self.cfg = CfgCache('',Cfg.Parameter.Priority.Interactive) self.cfg = CfgCache('',Cfg.Parameter.Priority.Interactive)
# H-Tree/Spares parameters (triggers loading from disk).
self.cfg.spares.htreeOffsetDriver = None
self.cfg.spares.htreeOffsetSink = None
self.bufferConf = None self.bufferConf = None
self.constantsConf = None self.constantsConf = None
self.feedsConf = None self.feedsConf = None

View File

@ -146,7 +146,7 @@ class HTree ( object ):
hLeafDepth = gaugeConf.horizontalDepth hLeafDepth = gaugeConf.horizontalDepth
if gaugeConf.horizontalDepth > 2 and (gaugeConf.horizontalDepth > gaugeConf.verticalDepth): if gaugeConf.horizontalDepth > 2 and (gaugeConf.horizontalDepth > gaugeConf.verticalDepth):
hLeafDepth = gaugeConf.horizontalDepth - 2 hLeafDepth = gaugeConf.horizontalDepth - 2
leafFlags = GaugeConf.OffsetLeft1 leafFlags = 0
blContact = None blContact = None
brContact = None brContact = None
tlContact = None tlContact = None
@ -160,55 +160,146 @@ class HTree ( object ):
or (qt.br and len(qt.br.buffers) > 1) \ or (qt.br and len(qt.br.buffers) > 1) \
or (qt.tr and len(qt.tr.buffers) > 1): or (qt.tr and len(qt.tr.buffers) > 1):
leafFlags |= GaugeConf.HAccess leafFlags |= GaugeConf.HAccess
yoffset = gaugeConf.cfg.spares.htreeRootOffset bufferTransf = qt.buffers[0].getTransformation()
botSinkTransf = None
topSinkTransf = None
driverY = None
sinkBotY = None
sinkTopY = None
yoffsetDriver = gaugeConf.cfg.spares.htreeOffsetDriver
yoffsetTopSink = gaugeConf.cfg.spares.htreeOffsetSink
yoffsetBotSink = gaugeConf.cfg.spares.htreeOffsetSink
trace( 550, '\tyoffsetDriver={}\n'.format( yoffsetDriver ))
trace( 550, '\tyoffsetSink={}\n'.format( yoffsetTopSink ))
if bufferTransf.getOrientation() in ( Transformation.Orientation.ID
, Transformation.Orientation.MX ):
driverFlags = leafFlags | GaugeConf.HAccess | GaugeConf.OffsetTop1
else:
driverFlags = leafFlags | GaugeConf.HAccess | GaugeConf.OffsetBottom1
if yoffsetDriver is not None:
yoffsetDriver = -yoffsetDriver
if yoffsetDriver is not None:
driverFlags = leafFlags | GaugeConf.HAccess | GaugeConf.OffsetFromSlice
driverY = gaugeConf.getNearestHorizontalTrack( bufferTransf.getTy(), 0, yoffsetDriver )
trace( 550, '\tdriverY:{}\n'.format( DbU.getValueString(driverY) ))
if qt.bl:
botSinkTransf = qt.bl.buffers[0].getTransformation()
elif qt.br:
botSinkTransf = qt.br.buffers[0].getTransformation()
if botSinkTransf:
if botSinkTransf.getOrientation() in ( Transformation.Orientation.ID
, Transformation.Orientation.MX ):
sinkBotFlags = leafFlags | GaugeConf.OffsetLeft1 | GaugeConf.OffsetBottom1
else:
sinkBotFlags = leafFlags | GaugeConf.OffsetLeft1 | GaugeConf.OffsetTop1
if yoffsetBotSink is not None:
yoffsetBotSink = -yoffsetBotSink
if yoffsetBotSink is not None:
sinkBotFlags = leafFlags | GaugeConf.OffsetLeft1 | GaugeConf.OffsetFromSlice
ty = botSinkTransf.getTy()
if yoffsetBotSink < 0:
ty += gaugeConf._cellGauge.getSliceHeight()
sinkBotY = gaugeConf.getTrack( ty, hLeafDepth, yoffsetBotSink )
trace( 550, '\tsinkBotY:{}\n'.format( DbU.getValueString(sinkBotY) ))
if qt.tl:
topSinkTransf = qt.tl.buffers[0].getTransformation()
elif qt.tr:
topSinkTransf = qt.tr.buffers[0].getTransformation()
if topSinkTransf:
if topSinkTransf.getOrientation() in ( Transformation.Orientation.ID
, Transformation.Orientation.MX ):
sinkTopFlags = leafFlags | GaugeConf.OffsetLeft1 | GaugeConf.OffsetBottom1
else:
sinkTopFlags = leafFlags | GaugeConf.OffsetLeft1 | GaugeConf.OffsetTop1
if yoffsetTopSink is not None:
yoffsetTopSink = -yoffsetTopSink
if yoffsetTopSink is not None:
sinkTopFlags = leafFlags | GaugeConf.OffsetLeft1 | GaugeConf.OffsetFromSlice
ty = topSinkTransf.getTy()
if yoffsetTopSink < 0:
ty += gaugeConf._cellGauge.getSliceHeight()
sinkTopY = gaugeConf.getTrack( ty, hLeafDepth, yoffsetTopSink )
trace( 550, '\tsinkTopY:{}\n'.format( DbU.getValueString(sinkTopY) ))
if not qt.isRoot(): if not qt.isRoot():
ckParentNet = qt.bInputPlug(0).getNet() ckParentNet = qt.bInputPlug(0).getNet()
driverContact = gaugeConf.rpAccessByPlugName( qt.buffers[0], bufferConf.input, ckParentNet ) driverContact = gaugeConf.rpAccessByPlugName( qt.buffers[0], bufferConf.input, ckParentNet )
driverY = driverContact.getY()
yoffset = gaugeConf.cfg.spares.htreeOffset
trace( 550, '\tdriverContact={}\n'.format( driverContact )) trace( 550, '\tdriverContact={}\n'.format( driverContact ))
if qt.bl: if qt.bl:
trace( 550, '+,', '\tblContact\n' ) trace( 550, '+,', '\tblContact\n' )
blContact = gaugeConf.rpAccessByPlugName( qt.bl.buffers[0], bufferConf.input, ckNet, leafFlags ) blContact = gaugeConf.rpAccessByPlugName( qt.bl.buffers[0]
, bufferConf.input
, ckNet
, sinkBotFlags
, yoffsetBotSink )
if sinkBotY is None:
sinkBotY = gaugeConf.getTrack( blContact.getY(), hLeafDepth, 0 )
trace( 550, ',-', '\tblContact={}\n'.format(blContact) ) trace( 550, ',-', '\tblContact={}\n'.format(blContact) )
if qt.br: if qt.br:
trace( 550, '+,', '\tbrContact\n' ) trace( 550, '+,', '\tbrContact\n' )
brContact = gaugeConf.rpAccessByPlugName( qt.br.buffers[0], bufferConf.input, ckNet, leafFlags ) brContact = gaugeConf.rpAccessByPlugName( qt.br.buffers[0]
, bufferConf.input
, ckNet
, sinkBotFlags
, yoffsetBotSink )
if sinkBotY is None:
sinkBotY = gaugeConf.getTrack( brContact.getY(), hLeafDepth, 0 )
trace( 550, ',-', '\tbrContact={}\n'.format(brContact) ) trace( 550, ',-', '\tbrContact={}\n'.format(brContact) )
if qt.tl: if qt.tl:
trace( 550, '+,', '\ttlContact\n' ) trace( 550, '+,', '\ttlContact\n' )
tlContact = gaugeConf.rpAccessByPlugName( qt.tl.buffers[0], bufferConf.input, ckNet, leafFlags ) tlContact = gaugeConf.rpAccessByPlugName( qt.tl.buffers[0]
, bufferConf.input
, ckNet
, sinkTopFlags
, yoffsetTopSink )
if sinkTopY is None:
sinkTopY = gaugeConf.getTrack( tlContact.getY(), hLeafDepth, 0 )
trace( 550, ',-', '\ttlContact={}\n'.format(tlContact) ) trace( 550, ',-', '\ttlContact={}\n'.format(tlContact) )
if qt.tr: if qt.tr:
trace( 550, '+,', '\ttrContact\n' ) trace( 550, '+,', '\ttrContact\n' )
trContact = gaugeConf.rpAccessByPlugName( qt.tr.buffers[0], bufferConf.input, ckNet, leafFlags ) trContact = gaugeConf.rpAccessByPlugName( qt.tr.buffers[0]
, bufferConf.input
, ckNet
, sinkTopFlags
, yoffsetTopSink )
if sinkTopY is None:
sinkTopY = gaugeConf.getTrack( trContact.getY(), hLeafDepth, 0 )
trace( 550, ',-', '\ttrContact={}\n'.format(trContact) ) trace( 550, ',-', '\ttrContact={}\n'.format(trContact) )
flags = GaugeConf.OffsetTop2
bufferTransf = qt.buffers[0].getTransformation()
if bufferTransf == Transformation.Orientation.ID:
yoffset = -yoffset
if qt.bl or qt.tl: if qt.bl or qt.tl:
trace( 550, '\tLeft branch\n' ) trace( 550, '\tLeft branch\n' )
leafContact = blContact if brContact else tlContact leafContact = blContact if brContact else tlContact
leftSourceContact = gaugeConf.rpAccessByPlugName( qt.buffers[0], bufferConf.output, ckNet , GaugeConf.HAccess|flags ) leftSourceContact = gaugeConf.rpAccessByPlugName( qt.buffers[0]
leftSourceX = gaugeConf.getNearestVerticalTrack ( leftSourceContact.getX(), 0 ) , bufferConf.output
, ckNet
, driverFlags
, yoffsetDriver )
leftSourceX = gaugeConf.getNearestVerticalTrack ( leftSourceContact.getX(), 0, 0 )
if driverY is None: if driverY is None:
driverY = leftSourceContact.getY() leftSourceY = gaugeConf.getNearestHorizontalTrack( leftSourceContact.getY(), 0, 0 )
leftSourceY = gaugeConf.getNearestHorizontalTrack( driverY, 0, yoffset ) else:
leftSourceY = driverY
leftContact = gaugeConf.createContact( ckNet, leafContact.getX(), leftSourceContact.getY(), 0 ) leftContact = gaugeConf.createContact( ckNet, leafContact.getX(), leftSourceContact.getY(), 0 )
leftX = gaugeConf.getNearestVerticalTrack( leftContact.getX(), 0 ) leftX = gaugeConf.getNearestVerticalTrack( leftContact.getX(), 0 )
gaugeConf.setStackPosition( leftSourceContact, leftSourceX, leftSourceY ) gaugeConf.setStackPosition( leftSourceContact, leftSourceX, leftSourceY )
leftContact .setX( leftX ) leftContact .setX( leftX )
leftContact .setY( leftSourceY ) leftContact .setY( leftSourceY )
flags = 0
if qt.br or qt.tr: if qt.br or qt.tr:
trace( 550, '\tRight branch\n' ) trace( 550, '\tRight branch\n' )
leafContact = brContact if brContact else trContact leafContact = brContact if brContact else trContact
rightSourceContact = gaugeConf.rpAccessByPlugName( qt.buffers[0], bufferConf.output, ckNet , GaugeConf.HAccess|flags ) rightSourceContact = gaugeConf.rpAccessByPlugName( qt.buffers[0]
, bufferConf.output
, ckNet
, driverFlags
, yoffsetDriver )
rightSourceX = gaugeConf.getNearestVerticalTrack( rightSourceContact.getX(), 0, 0 )
if driverY is None: if driverY is None:
driverY = rightSourceContact.getY() rightSourceY = gaugeConf.getNearestHorizontalTrack( rightSourceContact.getY(), 0, 0 )
rightSourceX = gaugeConf.getNearestVerticalTrack( rightSourceContact.getX(), 0 ) else:
rightSourceY = gaugeConf.getNearestHorizontalTrack( driverY, 0, yoffset ) rightSourceY = driverY
rightContact = gaugeConf.createContact( ckNet, leafContact.getX(), rightSourceContact.getY(), 0 ) rightContact = gaugeConf.createContact( ckNet, leafContact.getX(), rightSourceContact.getY(), 0 )
rightX = gaugeConf.getNearestVerticalTrack( rightContact.getX(), 0 ) rightX = gaugeConf.getNearestVerticalTrack( rightContact.getX(), 0 )
gaugeConf.setStackPosition( rightSourceContact, rightSourceX, rightSourceY ) gaugeConf.setStackPosition( rightSourceContact, rightSourceX, rightSourceY )
@ -218,27 +309,31 @@ class HTree ( object ):
gaugeConf.createHorizontal( leftContact, leftSourceContact, leftSourceY , 0 ) gaugeConf.createHorizontal( leftContact, leftSourceContact, leftSourceY , 0 )
if qt.br or qt.tr: if qt.br or qt.tr:
gaugeConf.createHorizontal( rightSourceContact, rightContact, rightSourceY, 0 ) gaugeConf.createHorizontal( rightSourceContact, rightContact, rightSourceY, 0 )
if tlContact:
tlY = gaugeConf.getTrack( tlContact.getY(), hLeafDepth, -1 ) #if tlContact:
elif trContact: # tlY = gaugeConf.getTrack( tlContact.getY(), hLeafDepth, yoffsetTopSink )
tlY = gaugeConf.getTrack( trContact.getY(), hLeafDepth, -1 ) #elif trContact:
if blContact: # tlY = gaugeConf.getTrack( trContact.getY(), hLeafDepth, yoffsetTopSink )
blY = gaugeConf.getTrack( blContact.getY(), hLeafDepth, 2 ) #if blContact:
trace( 550, '\tblY:{}\n'.format( DbU.getValueString(blY) )) # blY = gaugeConf.getTrack( blContact.getY(), hLeafDepth, yoffsetBotSink )
elif brContact: # trace( 550, '\tblY:{}\n'.format( DbU.getValueString(blY) ))
blY = gaugeConf.getTrack( brContact.getY(), hLeafDepth, 2 ) #elif brContact:
trace( 550, '\tblY:{}\n'.format( DbU.getValueString(blY) )) # blY = gaugeConf.getTrack( brContact.getY(), hLeafDepth, yoffsetBotSink )
# trace( 550, '\tblY:{}\n'.format( DbU.getValueString(blY) ))
if qt.tl: if qt.tl:
self._connectLeaf( qt.tl, ckNet, leftContact, tlContact, leftX, tlY ) self._connectLeaf( qt.tl, ckNet, leftContact, tlContact, leftX, sinkTopY )
if qt.bl: if qt.bl:
trace( 550, '\tConnect BL leaf, leftX={} blY={}\n'.format( DbU.getValueString(leftX), DbU.getValueString(blY) )) trace( 550, '\tConnect BL leaf, leftX={} blY={}\n' \
self._connectLeaf( qt.bl, ckNet, leftContact, blContact, leftX, blY ) .format( DbU.getValueString(leftX), DbU.getValueString(sinkBotY) ))
#gaugeConf.addTrackAvoid( Box( leftX, leftSourceY, leftX, blY ) ) self._connectLeaf( qt.bl, ckNet, leftContact, blContact, leftX, sinkBotY )
#gaugeConf.addTrackAvoid( Box( leftX, leftSourceY, leftX, sinkBotY ) )
if qt.tr: if qt.tr:
self._connectLeaf( qt.tr, ckNet, rightContact, trContact, rightX, tlY ) self._connectLeaf( qt.tr, ckNet, rightContact, trContact, rightX, sinkTopY )
#gaugeConf.addTrackAvoid( Box( rightX, rightSourceY, rightX, tlY ) ) #gaugeConf.addTrackAvoid( Box( rightX, rightSourceY, rightX, si,kTopY ) )
if qt.br: if qt.br:
self._connectLeaf( qt.br, ckNet, rightContact, brContact, rightX, blY ) self._connectLeaf( qt.br, ckNet, rightContact, brContact, rightX, sinkBotY )
if qt.isRoot(): if qt.isRoot():
ckNet = self.treeNet ckNet = self.treeNet
if not self.spares.conf.isCoreBlock \ if not self.spares.conf.isCoreBlock \