diff --git a/cumulus/src/plugins/alpha/block/block.py b/cumulus/src/plugins/alpha/block/block.py index 17fdf133..e7c13cb6 100644 --- a/cumulus/src/plugins/alpha/block/block.py +++ b/cumulus/src/plugins/alpha/block/block.py @@ -306,13 +306,15 @@ class Block ( object ): self.hfnTrees = [] self.blockInstances = [] self.placeHolderCount = 0 - self.excludedNets = deepcopy( self.conf.hTreeNames ) self.sides = { IoPin.WEST : Side( self.conf, IoPin.WEST ) , IoPin.EAST : Side( self.conf, IoPin.EAST ) , IoPin.SOUTH : Side( self.conf, IoPin.SOUTH ) , IoPin.NORTH : Side( self.conf, IoPin.NORTH ) } self.etesian = None + self.excludedNets = [] + for item in self.conf.hTreeDatas: + self.excludedNets.append( item[0] ) if not self.conf.cell.getAbutmentBox().isEmpty(): isBuilt = True for instance in self.conf.cell.getInstances(): @@ -503,7 +505,7 @@ class Block ( object ): hTreeNets = [] netOcc = None self.flattenNets() - for netName in self.conf.hTreeNames: + for netName, flags in self.conf.hTreeDatas: netOcc = self.getFlattenedNet( netName ) #if self.conf.isCoreBlock: # coreNet = self.conf.cell.getNet( netName ) @@ -520,13 +522,13 @@ class Block ( object ): .format( self.conf.cellPnR.getName(), netName ))) continue trace( 550, '\tBlock.addHTrees(): Found H-Tree {}.\n'.format(netOcc) ) - hTreeNets.append( netOcc ) + hTreeNets.append( [ netOcc, flags ] ) self.etesian.exclude( netName ) with UpdateSession(): - for hTreeNet in hTreeNets: - print( ' - "{}".'.format(hTreeNet.getName()) ) - trace( 550, ',+', '\tBlock.addHTrees(): Build clock tree for {}.\n'.format(hTreeNet) ) - self.hTrees.append( HTree(self.spares,hTreeNet,len(self.hTrees)) ) + for netOcc, flags in hTreeNets: + print( ' - "{}".'.format(netOcc.getName()) ) + trace( 550, ',+', '\tBlock.addHTrees(): Build clock tree for {}.\n'.format(netOcc) ) + self.hTrees.append( HTree(self.spares,netOcc,len(self.hTrees),flags) ) self.hTrees[-1].buildHTree() for net in self.hTrees[-1].subNets: self.etesian.exclude( net.getName() ) diff --git a/cumulus/src/plugins/alpha/block/configuration.py b/cumulus/src/plugins/alpha/block/configuration.py index ee52136e..27bb23f2 100644 --- a/cumulus/src/plugins/alpha/block/configuration.py +++ b/cumulus/src/plugins/alpha/block/configuration.py @@ -70,6 +70,7 @@ class GaugeConf ( object ): DeepDepth = 0x0010 UseContactWidth = 0x0020 ExpandWidth = 0x0040 + SourceExtend = 0x0080 def __init__ ( self ): self._cellGauge = None @@ -235,21 +236,24 @@ class GaugeConf ( object ): trace( 550, ' -> utrack={}\n'.format( DbU.getValueString(utrack) )) return utrack + offset*rg.getPitch() - def getNearestHorizontalTrack ( self, y, flags ): + def getNearestHorizontalTrack ( self, y, flags, offset=0 ): if flags & GaugeConf.DeepDepth: depth = self.horizontalDeepDepth else: depth = self.horizontalDepth - return self.getTrack( y, depth, 0 ) + return self.getTrack( y, depth, offset ) - def getNearestVerticalTrack ( self, x, flags ): + def getNearestVerticalTrack ( self, x, flags, offset=0 ): if flags & GaugeConf.DeepDepth: depth = self.verticalDeepDepth else: depth = self.verticalDepth - return self.getTrack( x, depth, 0 ) + return self.getTrack( x, depth, offset ) def createHorizontal ( self, source, target, y, flags ): 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 flags & GaugeConf.UseContactWidth: width = source.getBoundingBox(layer.getBasicLayer()).getHeight() @@ -259,6 +263,7 @@ class GaugeConf ( object ): width += DbU.fromLambda( 1.0 ) segment = Horizontal.create( source, target, layer, y, width ) + segment.setDxSource( -dxSource ) trace( 550, segment ) return segment @@ -1109,7 +1114,7 @@ class BlockConf ( GaugeConf ): self.placeArea = None self.deltaAb = [ 0, 0, 0, 0 ] self.useClockTree = False - self.hTreeNames = [ ] + self.hTreeDatas = [ ] self.useHFNS = False self.useSpares = True self.isBuilt = False @@ -1212,9 +1217,13 @@ class BlockConf ( GaugeConf ): self.cloneds.append( masterCell ) return - def useHTree ( self, netName ): - if not netName in self.hTreeNames: - self.hTreeNames.append( netName ); + def useHTree ( self, netName, flags=0 ): + for item in self.hTreeDatas: + if item[0] == netName: + print( WarningMessage( 'block.configuration.useHTree(): Redefinition of "{}" H-Tree ignored.' \ + .format(netName)) ) + return + self.hTreeDatas.append( [ netName, flags ] ); def save ( self, flags ): """ diff --git a/cumulus/src/plugins/alpha/block/htree.py b/cumulus/src/plugins/alpha/block/htree.py index 35ef89cc..4f2063cf 100644 --- a/cumulus/src/plugins/alpha/block/htree.py +++ b/cumulus/src/plugins/alpha/block/htree.py @@ -40,10 +40,11 @@ class HTree ( object ): Build a H-Tree on a net occurrene. """ - def __init__ ( self, spares, treeNetOcc, index ): + def __init__ ( self, spares, treeNetOcc, index, flags ): self.spares = spares self.treeNetOcc = treeNetOcc self.treeIndex = index + self.flags = flags self.subNets = [] #if not self.treeNetOcc.getEntity().isClock(): # print( WarningMessage( 'HTree.__init__(): Net "{}" is not of CLOCK type.' \ @@ -80,25 +81,44 @@ class HTree ( object ): def _rconnectHTree ( self, qt ): if qt.isLeaf(): return False qt.rconnectBuffer() - driverNet = qt.bOutputPlug.getNet() + driverNet = qt.bOutputPlug(0).getNet() driverNet.setType( self.treeNet.getType() ) for leaf in qt.leafs: - leaf.bInputPlug.setNet( driverNet ) + for plug in leaf.bInputPlugs: + plug.setNet( driverNet ) self._rconnectHTree( leaf ) return True + def _connectLeaf ( self, leaf, ckNet, forkContact, contact, x, y ): + gaugeConf = self.spares.conf + bufferConf = self.spares.conf.bufferConf + hLeafDepth = gaugeConf.horizontalDepth + if gaugeConf.horizontalDepth > 2 and (gaugeConf.horizontalDepth > gaugeConf.verticalDepth): + hLeafDepth = gaugeConf.horizontalDepth - 2 + gaugeConf.setStackPosition( contact, x, y ) + gaugeConf.createVertical ( contact, forkContact, x, 0 ) + 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 ) + gaugeConf.expandMinArea( tl2Contact ) + gaugeConf.setStackPosition( tl1Contact, left1X , y ) + gaugeConf.createHorizontal( contact , tl1Contact, y , GaugeConf.DeepDepth|GaugeConf.SourceExtend ) + gaugeConf.createVertical ( contact , tl2Contact, x, 0 ) + def _rrouteHTree ( self, qt ): """ Recursively build one HTree branch for all non-terminal nodes of the QuadTree. """ - trace( 550, ',+', '\tHTree._rrouteHTree() {}\n'.format(qt.bOutputPlug.getNet()) ) + trace( 550, ',+', '\tHTree._rrouteHTree() {}\n'.format(qt.bOutputPlug(0).getNet()) ) trace( 550, '\tOn: {}\n'.format(qt) ) if qt.isLeaf(): trace( 550, '-' ) return False gaugeConf = self.spares.conf bufferConf = self.spares.conf.bufferConf - ckNet = qt.bOutputPlug.getNet() + ckNet = qt.bOutputPlug(0).getNet() self.subNets.append( ckNet ) hLeafDepth = gaugeConf.horizontalDepth if gaugeConf.horizontalDepth > 2 and (gaugeConf.horizontalDepth > gaugeConf.verticalDepth): @@ -110,16 +130,16 @@ class HTree ( object ): leftContact = None rigthContact = None if qt.bl: - blContact = gaugeConf.rpAccessByPlugName( qt.bl.buffer, bufferConf.input , ckNet ) + blContact = gaugeConf.rpAccessByPlugName( qt.bl.buffers[0], bufferConf.input , ckNet ) if qt.br: - brContact = gaugeConf.rpAccessByPlugName( qt.br.buffer, bufferConf.input , ckNet ) + brContact = gaugeConf.rpAccessByPlugName( qt.br.buffers[0], bufferConf.input , ckNet ) if qt.tl: - tlContact = gaugeConf.rpAccessByPlugName( qt.tl.buffer, bufferConf.input , ckNet ) + tlContact = gaugeConf.rpAccessByPlugName( qt.tl.buffers[0], bufferConf.input , ckNet ) if qt.tr: - trContact = gaugeConf.rpAccessByPlugName( qt.tr.buffer, bufferConf.input , ckNet ) + trContact = gaugeConf.rpAccessByPlugName( qt.tr.buffers[0], bufferConf.input , ckNet ) if qt.bl or qt.tl: leafContact = blContact if brContact else tlContact - leftSourceContact = gaugeConf.rpAccessByPlugName( qt.buffer, bufferConf.output, ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 ) + leftSourceContact = gaugeConf.rpAccessByPlugName( qt.buffers[0], bufferConf.output, ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 ) leftSourceX = gaugeConf.getNearestVerticalTrack ( leftSourceContact.getX(), 0 ) leftSourceY = gaugeConf.getNearestHorizontalTrack( leftSourceContact.getY(), 0 ) leftContact = gaugeConf.createContact( ckNet, leafContact.getX(), leftSourceContact.getY(), 0 ) @@ -129,7 +149,7 @@ class HTree ( object ): leftContact .setY( leftSourceY ) if qt.br or qt.tr: leafContact = brContact if brContact else trContact - rightSourceContact = gaugeConf.rpAccessByPlugName( qt.buffer, bufferConf.output, ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 ) + rightSourceContact = gaugeConf.rpAccessByPlugName( qt.buffers[0], bufferConf.output, ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 ) rightSourceX = gaugeConf.getNearestVerticalTrack( rightSourceContact.getX(), 0 ) rightSourceY = gaugeConf.getNearestHorizontalTrack( rightSourceContact.getY(), 0 ) rightContact = gaugeConf.createContact( ckNet, leafContact.getX(), rightSourceContact.getY(), 0 ) @@ -152,17 +172,13 @@ class HTree ( object ): blY = gaugeConf.getTrack( brContact.getY(), hLeafDepth, 0 ) trace( 550, '\tblY:{}\n'.format( DbU.getValueString(blY) )) if qt.tl: - gaugeConf.setStackPosition( tlContact, leftX, tlY ) - gaugeConf.createVertical ( tlContact, leftContact, leftX, 0 ) + self._connectLeaf( qt.tl, ckNet, leftContact, tlContact, leftX, tlY ) if qt.bl: - gaugeConf.setStackPosition( blContact, leftX, blY ) - gaugeConf.createVertical ( leftContact, blContact, leftX, 0 ) + self._connectLeaf( qt.bl, ckNet, leftContact, blContact, leftX, blY ) if qt.tr: - gaugeConf.setStackPosition( trContact, rightX, tlY ) - gaugeConf.createVertical ( trContact, rightContact, rightX, 0 ) + self._connectLeaf( qt.tr, ckNet, rightContact, trContact, rightX, tlY ) if qt.br: - gaugeConf.setStackPosition( brContact, rightX, blY ) - gaugeConf.createVertical ( rightContact, brContact, rightX, 0 ) + self._connectLeaf( qt.br, ckNet, rightContact, brContact, rightX, blY ) if qt.isRoot(): ckNet = self.treeNet if not self.spares.conf.isCoreBlock: @@ -173,7 +189,7 @@ class HTree ( object ): print( WarningMessage('HTree._rrouteHTree(): Removing {}.'.format(pin)) ) pin.destroy() layerGauge = gaugeConf.vRoutingGauge - rootContact = gaugeConf.rpAccessByPlugName( qt.buffer, bufferConf.input, ckNet, 0 ) + rootContact = gaugeConf.rpAccessByPlugName( qt.buffers[0], bufferConf.input, ckNet, 0 ) x = gaugeConf.getNearestVerticalTrack ( rootContact.getX(), 0 ) y = gaugeConf.getNearestHorizontalTrack( rootContact.getY(), 0 ) rootPin = Pin.create( ckNet @@ -202,7 +218,10 @@ class HTree ( object ): """ qt = self.spares.quadTree qt.bufferTag = self.treeNet.getName() - qt.rselectBuffer( self.treeIndex, self.treeIndex, Spares.CHECK_USED|Spares.MARK_USED) + qt.runselect() + qt.rselectBuffer( self.treeIndex + , self.treeIndex + , Spares.CHECK_USED|Spares.MARK_USED|self.flags) with UpdateSession(): self._rconnectHTree( qt ) self._rrouteHTree ( qt ) @@ -215,7 +234,8 @@ class HTree ( object ): bufferConf = self.spares.conf.bufferConf quadTree = self.spares.quadTree quadTree.bufferTag = self.treeNet.getName() - quadTree.rselectBuffer( self.treeIndex, self.treeIndex, 0 ) + quadTree.runselect() + quadTree.rselectBuffer( self.treeIndex, self.treeIndex, self.flags) with UpdateSession(): driverPlugs = [] hyperNet = HyperNet.create( Occurrence(self.treeNet) ) @@ -229,7 +249,7 @@ class HTree ( object ): driverPlugs.append( plugOcc ) quadTree.rsplitNetlist() if self.spares.conf.isCoreBlock: - plug = utils.getPlugByName( quadTree.buffer, bufferConf.input ) + plug = utils.getPlugByName( quadTree.buffers[0], bufferConf.input ) plug.setNet( self.treeNet ) trace( 550, '\tCore mode, setting only root plug "{}"\n'.format(self.treeNet.getName()) ) trace( 550, '\tPlug of "{}" (Cell:{})\n'.format(self.treeNet.getName() diff --git a/cumulus/src/plugins/alpha/block/spares.py b/cumulus/src/plugins/alpha/block/spares.py index e0008b6e..6fe69135 100644 --- a/cumulus/src/plugins/alpha/block/spares.py +++ b/cumulus/src/plugins/alpha/block/spares.py @@ -15,6 +15,7 @@ import sys import os.path +import math import Cfg from operator import itemgetter from Hurricane import Breakpoint, DbU, Box, Transformation, Box, \ @@ -44,30 +45,35 @@ class BufferPool ( object ): """ def __init__ ( self, quadTree ): - self.quadTree = quadTree - self.columns = quadTree.spares.conf.bColumns - self.rows = quadTree.spares.conf.bRows - self.area = Box() - self.buffers = [] - self.selectedIndex = None + self.quadTree = quadTree + self.columns = quadTree.spares.conf.bColumns + self.rows = quadTree.spares.conf.bRows + self.area = Box() + self.buffers = [] + self.selectedIndexes = [] for i in range(self.rows*self.columns): self.buffers.append( [ 0, None ] ) self._createBuffers() @property - def selected ( self ): + def selecteds ( self ): """ - Returns the selected buffer instance within the pool. Selection is to + Returns the selected(s) buffer(s) instance(s) within the pool. Selection is to be made with either select() or selectFree(). """ - if self.selectedIndex is None: - raise ErrorMessage( 3, 'BufferPool.selected: No buffer has been selected yet.' ) - return self.buffers[ self.selectedIndex ][ 1 ] + if not len(self.selectedIndexes): + raise ErrorMessage( 3, 'BufferPool.selecteds: No buffer has been selected yet.' ) + selectedBuffers = [] + for index in self.selectedIndexes: + selectedBuffers.append( self.buffers[ index ][ 1 ] ) + return selectedBuffers def toIndex ( self, column, row ): return column + row*self.columns def fromIndex ( self, index ): return (index%self.columns, index/self.columns) + def unselect ( self ): self.selectedIndexes = [] + def select ( self, column, row, flags=0 ): """ Select a specific buffer in the pool matrix. The ``flags`` arguments are @@ -99,11 +105,15 @@ class BufferPool ( object ): trace( 540, '-' ) def _select ( self, index, flags ): - self.selectedIndex = index - selectedBuffer = self.buffers[ self.selectedIndex ] + for i in range(len(self.selectedIndexes)): + if index == self.selectedIndexes[i]: + del self.selectedIndexes[i] + break + self.selectedIndexes.append( index ) + selectedBuffer = self.buffers[ self.selectedIndexes[-1] ] if flags & Spares.CHECK_USED and selectedBuffer[0] & Spares.USED: raise ErrorMessage( 3, 'BufferPool.select(): Buffer a index {} is already used.' \ - .format(self.selectedIndex) ) + .format(self.selectedIndexes[-1]) ) if flags & Spares.MARK_USED: selectedBuffer[0] |= Spares.USED @@ -428,19 +438,25 @@ class QuadTree ( object ): return parent @property - def buffer ( self ): - """The the currently selected buffer instance in the pool.""" - return self.pool.selected + def buffers ( self ): + """The the currently selected set of buffer instances in the pool.""" + return self.pool.selecteds @property - def bInputPlug ( self ): + def bInputPlugs ( self ): + """The list of input Plugs of the currently selected buffers in the pool.""" + plugs = [] + for buffer in self.buffers: + plugs.append( utils.getPlugByName( buffer, self.spares.conf.bufferConf.input )) + return plugs + + def bInputPlug ( self, index ): """The input Plug of the currently selected buffer in the pool.""" - return utils.getPlugByName( self.buffer, self.spares.conf.bufferConf.input ) + return utils.getPlugByName( self.buffers[index], self.spares.conf.bufferConf.input ) - @property - def bOutputPlug ( self ): + def bOutputPlug ( self, index ): """The output Plug of the currently selected buffer in the pool.""" - return utils.getPlugByName( self.buffer, self.spares.conf.bufferConf.output ) + return utils.getPlugByName( self.buffers[index], self.spares.conf.bufferConf.output ) def selectFree ( self ): """ @@ -451,20 +467,21 @@ class QuadTree ( object ): def connectBuffer ( self, doLeaf=False ): """ - Create output nets for the currently selected buffer, if they do not + Create output nets for the currently selected buffers, if they do not already exists. The nets are created in the top level cell, and their names are derived from the `rtag` attribute. """ if self.isLeaf() and not doLeaf: return trace( 540, '\tQuadTree.connectBuffer(): rtag:"{}"\n'.format(self.rtag) ) - plug = self.bOutputPlug - if not plug.getNet(): - outputNetBuff = Net.create( self.spares.conf.cellPnR,'{}_{}' \ - .format(self.root.bufferTag,self.rtag) ) - plug.setNet( outputNetBuff ) - trace( 540, '\t| {}\n'.format(plug) ) - trace( 540, '\t| {}\n'.format(outputNetBuff) ) + for ibuffer in range(len(self.buffers)): + plug = self.bOutputPlug(ibuffer) + if not plug.getNet(): + outputNetBuff = Net.create( self.spares.conf.cellPnR,'{}_{}_{}' \ + .format(self.root.bufferTag,self.rtag,ibuffer) ) + plug.setNet( outputNetBuff ) + trace( 540, '\t| {}\n'.format(plug) ) + trace( 540, '\t| {}\n'.format(outputNetBuff) ) def rconnectBuffer ( self ): """[R]ecursive call of connectBuffer()""" @@ -484,8 +501,20 @@ class QuadTree ( object ): self.pool.select( column, row, flags ) if not self.isLeaf(): for leaf in self.leafs: leaf.rselectBuffer( column, row, flags ) + else: + if flags & Spares.HEAVY_LEAF_LOAD: + self.pool.select( column+1, row , flags ) + self.pool.select( column , row+1, flags ) trace( 540, '-' ) + def runselect ( self ): + """ + Clear any previous buffer selection. + """ + self.pool.unselect() + if not self.isLeaf(): + for leaf in self.leafs: leaf.runselect() + def _mergeLeafX ( self, leafX ): for x in leafX: if not (x in self.rleafX): @@ -774,27 +803,80 @@ class QuadTree ( object ): output net created. """ trace( 540, ',+', '\tQuadTree.spliNetlist()\n' ) + trace( 540, '\tPlug numbers {}\n'.format(len(self.plugs)) ) + trace( 540, '\tBuffers numbers {}\n'.format(len(self.buffers)) ) self.connectBuffer( doLeaf=True ) - netBuff = self.bOutputPlug.getNet() - trace( 540, '\tBuffer: {}\n'.format(self.buffer) ) - trace( 540, '\tBuffer output: {}\n'.format(netBuff) ) if not self.plugs: trace( 540, '-' ) return - for plug in self.plugs: - trace( 540, '\t| Leaf: {}\n'.format(plug) ) + coreTransf = Transformation() + if self.spares.conf.isCoreBlock: + coreTransf = self.spares.conf.icore.getTransformation() + maxSinks = self.spares.conf.bufferConf.maxSinks + #maxSinks = 7 + plugOccsByAngle = [] + areaCenter = self.area.getCenter() + #coreTransf.applyOn( areaCenter ) + trace( 540, '\tArea {}\n'.format(self.area) ) + trace( 540, '\tArea center {}\n'.format(areaCenter) ) + for plugOcc in self.plugs: + instCenter = plugOcc.getEntity().getInstance().getAbutmentBox().getCenter() + plugOcc.getPath().getTransformation().applyOn( instCenter ) + dx = instCenter.getX() - areaCenter.getX() + dy = instCenter.getY() - areaCenter.getY() + angle = math.atan2( dy, dx ) + plugOccsByAngle.append( [ angle, plugOcc ] ) + plugOccsByAngle.sort( key=itemgetter(0) ) + splitIndexes = [] + if (len(plugOccsByAngle) > maxSinks) and (len(self.buffers) > 1): + partSize = len(plugOccsByAngle) / len(self.buffers) + trace( 540, '\tpartSize: {}\n'.format(partSize) ) + for isplit in range(1,len(self.buffers)): + maxdAngle = 0 + maxisplit = partSize*isplit-2 + for i in range(maxisplit,maxisplit+4): + dAngle = plugOccsByAngle[i+1][0] - plugOccsByAngle[i][0] + trace( 540, '\t{:-2} dAngle={}\n'.format(i,dAngle) ) + if dAngle > maxdAngle: + maxdAngle = dAngle + maxisplit = i + splitIndexes.append( maxisplit ) + splitIndexes.append( len(plugOccsByAngle) ) + for i in range(len(plugOccsByAngle)): + angle, plugOcc = plugOccsByAngle[i] + instCenter = plugOcc.getEntity().getInstance().getAbutmentBox().getCenter() + plugOcc.getPath().getTransformation().applyOn( instCenter ) + dx = instCenter.getX() + dy = instCenter.getY() + trace( 540, '\t {:-2} | {:-5.2} : dx:{} dy:{} {}\n' \ + .format(i,angle,DbU.getValueString(dx),DbU.getValueString(dy),plugOcc) ) + trace( 540, '\tspitIndexes = {}\n'.format(splitIndexes) ) + minIndex = 0 + for i in range(len(splitIndexes)): + sinks = splitIndexes[i] - minIndex + minIndex = splitIndexes[i] + if sinks > maxSinks: + print( WarningMessage( 'QuadTree.splitNetlist(): More than {} sink points ({}) on "{}".' \ + .format( maxSinks + , sinks + , self.bOutputPlug(i).getNet().getName())) ) + ibuffer = 0 + netBuff = self.bOutputPlug(ibuffer).getNet() + for i in range(len(plugOccsByAngle)): + angle, plugOcc = plugOccsByAngle[i] + if i > splitIndexes[ibuffer]: + ibuffer += 1 + netBuff = self.bOutputPlug(ibuffer).getNet() + trace( 540, '\tBuffer: {}\n'.format(self.buffers[ibuffer]) ) + trace( 540, '\tBuffer output: {}\n'.format(netBuff) ) + trace( 540, '\t| Leaf: {}\n'.format(plugOcc) ) trace( 540, '\t| netBuff: {}\n'.format(netBuff) ) - deepPlug = self.spares.raddTransNet( netBuff, plug.getPath() ) + deepPlug = self.spares.raddTransNet( netBuff, plugOcc.getPath() ) trace( 540, '\t| netBuff: {}\n'.format(netBuff) ) trace( 540, '\t| Deep Plug: {}\n'.format(deepPlug) ) deepNetBuff = deepPlug.getMasterNet() if deepPlug else netBuff trace( 540, '\t| deepNetBuff: {} {}\n'.format(deepNetBuff,netBuff) ) - plug.getEntity().setNet( deepNetBuff ) - - maxSinks = self.spares.conf.bufferConf.maxSinks - if len(self.plugs) > maxSinks: - print( WarningMessage( 'QuadTree.splitNetlist(): More than {} sink points ({}) on "{}".' \ - .format(maxSinks,len(self.plugs),netBuff.getName())) ) + plugOcc.getEntity().setNet( deepNetBuff ) trace( 540, '-' ) def rsplitNetlist ( self ): @@ -815,9 +897,10 @@ class Spares ( object ): Excess area is put in the topmost and rightmost pools. """ - USED = 0x00000001 - CHECK_USED = 0x00010000 - MARK_USED = 0x00020000 + USED = 0x00000001 + CHECK_USED = 0x00010000 + MARK_USED = 0x00020000 + HEAVY_LEAF_LOAD = 0x00040000 def __init__ ( self, block ): self.conf = block.conf