diff --git a/cumulus/src/plugins/alpha/block/block.py b/cumulus/src/plugins/alpha/block/block.py index 02f2c6e4..25530744 100644 --- a/cumulus/src/plugins/alpha/block/block.py +++ b/cumulus/src/plugins/alpha/block/block.py @@ -438,6 +438,7 @@ class Block ( object ): self.clockTrees.append( ClockTree(self.spares,clockNet,len(self.clockTrees)) ) self.clockTrees[-1].buildHTree() trace( 550, '-' ) + Breakpoint.stop( 100, 'Block.addClockTrees() on {} done.'.format(self.conf.cellPnR) ) def splitClocks ( self ): """ diff --git a/cumulus/src/plugins/alpha/block/clocktree.py b/cumulus/src/plugins/alpha/block/clocktree.py index 6b93c18e..7f31852b 100644 --- a/cumulus/src/plugins/alpha/block/clocktree.py +++ b/cumulus/src/plugins/alpha/block/clocktree.py @@ -104,41 +104,66 @@ class ClockTree ( object ): hLeafDepth = gaugeConf.horizontalDepth if gaugeConf.horizontalDepth > 2 and (gaugeConf.horizontalDepth > gaugeConf.verticalDepth): hLeafDepth = gaugeConf.horizontalDepth - 2 - leftSourceContact = gaugeConf.rpAccessByPlugName( qt.buffer , bufferConf.output, ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 ) - rightSourceContact = gaugeConf.rpAccessByPlugName( qt.buffer , bufferConf.output, ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 ) - blContact = gaugeConf.rpAccessByPlugName( qt.bl.buffer, bufferConf.input , ckNet ) - brContact = gaugeConf.rpAccessByPlugName( qt.br.buffer, bufferConf.input , ckNet ) - tlContact = gaugeConf.rpAccessByPlugName( qt.tl.buffer, bufferConf.input , ckNet ) - trContact = gaugeConf.rpAccessByPlugName( qt.tr.buffer, bufferConf.input , ckNet ) - leftContact = gaugeConf.createContact( ckNet, blContact.getX(), leftSourceContact.getY(), 0 ) - rightContact = gaugeConf.createContact( ckNet, brContact.getX(), rightSourceContact.getY(), 0 ) - leftSourceX = gaugeConf.getNearestVerticalTrack ( leftSourceContact.getX(), 0 ) - leftSourceY = gaugeConf.getNearestHorizontalTrack( leftSourceContact.getY(), 0 ) - rightSourceX = gaugeConf.getNearestVerticalTrack ( rightSourceContact.getX(), 0 ) - rightSourceY = gaugeConf.getNearestHorizontalTrack( rightSourceContact.getY(), 0 ) - leftX = gaugeConf.getNearestVerticalTrack ( leftContact.getX(), 0 ) - rightX = gaugeConf.getNearestVerticalTrack ( rightContact.getX(), 0 ) - tlY = gaugeConf.getTrack( tlContact.getY(), hLeafDepth, 0 ) - blY = gaugeConf.getTrack( blContact.getY(), hLeafDepth, 0 ) - #tlY = gaugeConf.getNearestHorizontalTrack( tlContact.getY(), 0 ) - #blY = gaugeConf.getNearestHorizontalTrack( blContact.getY(), 0 ) - trace( 550, '\tblY:{}\n'.format( DbU.getValueString(blY) )) - gaugeConf.setStackPosition( leftSourceContact, leftSourceX, leftSourceY ) - gaugeConf.setStackPosition( rightSourceContact, rightSourceX, rightSourceY ) - gaugeConf.setStackPosition( tlContact, leftX, tlY ) - gaugeConf.setStackPosition( blContact, leftX, blY ) - gaugeConf.setStackPosition( trContact, rightX, tlY ) - gaugeConf.setStackPosition( brContact, rightX, blY ) - leftContact .setX( leftX ) - leftContact .setY( leftSourceY ) - rightContact.setX( rightX ) - rightContact.setY( rightSourceY ) - gaugeConf.createHorizontal( leftContact , leftSourceContact, leftSourceY , 0 ) - gaugeConf.createHorizontal( rightSourceContact, rightContact , rightSourceY, 0 ) - gaugeConf.createVertical ( leftContact , blContact , leftX , 0 ) - gaugeConf.createVertical ( tlContact , leftContact , leftX , 0 ) - gaugeConf.createVertical ( rightContact , brContact , rightX , 0 ) - gaugeConf.createVertical ( trContact , rightContact , rightX , 0 ) + blContact = None + brContact = None + tlContact = None + trContact = None + leftContact = None + rigthContact = None + if qt.bl: + blContact = gaugeConf.rpAccessByPlugName( qt.bl.buffer, bufferConf.input , ckNet ) + if qt.br: + brContact = gaugeConf.rpAccessByPlugName( qt.br.buffer, bufferConf.input , ckNet ) + if qt.tl: + tlContact = gaugeConf.rpAccessByPlugName( qt.tl.buffer, bufferConf.input , ckNet ) + if qt.tr: + trContact = gaugeConf.rpAccessByPlugName( qt.tr.buffer, 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 ) + leftSourceX = gaugeConf.getNearestVerticalTrack ( leftSourceContact.getX(), 0 ) + leftSourceY = gaugeConf.getNearestHorizontalTrack( leftSourceContact.getY(), 0 ) + leftContact = gaugeConf.createContact( ckNet, leafContact.getX(), leftSourceContact.getY(), 0 ) + leftX = gaugeConf.getNearestVerticalTrack( leftContact.getX(), 0 ) + gaugeConf.setStackPosition( leftSourceContact, leftSourceX, leftSourceY ) + leftContact .setX( leftX ) + 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 ) + rightSourceX = gaugeConf.getNearestVerticalTrack( rightSourceContact.getX(), 0 ) + rightSourceY = gaugeConf.getNearestHorizontalTrack( rightSourceContact.getY(), 0 ) + rightContact = gaugeConf.createContact( ckNet, leafContact.getX(), rightSourceContact.getY(), 0 ) + rightX = gaugeConf.getNearestVerticalTrack( rightContact.getX(), 0 ) + gaugeConf.setStackPosition( rightSourceContact, rightSourceX, rightSourceY ) + rightContact.setX( rightX ) + rightContact.setY( rightSourceY ) + if qt.bl or qt.tl: + gaugeConf.createHorizontal( leftContact, leftSourceContact, leftSourceY , 0 ) + if qt.br or qt.tr: + gaugeConf.createHorizontal( rightSourceContact, rightContact, rightSourceY, 0 ) + if tlContact: + tlY = gaugeConf.getTrack( tlContact.getY(), hLeafDepth, 0 ) + elif trContact: + tlY = gaugeConf.getTrack( trContact.getY(), hLeafDepth, 0 ) + if blContact: + blY = gaugeConf.getTrack( blContact.getY(), hLeafDepth, 0 ) + trace( 550, '\tblY:{}\n'.format( DbU.getValueString(blY) )) + elif brContact: + 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 ) + if qt.bl: + gaugeConf.setStackPosition( blContact, leftX, blY ) + gaugeConf.createVertical ( leftContact, blContact, leftX, 0 ) + if qt.tr: + gaugeConf.setStackPosition( trContact, rightX, tlY ) + gaugeConf.createVertical ( trContact, rightContact, rightX, 0 ) + if qt.br: + gaugeConf.setStackPosition( brContact, rightX, blY ) + gaugeConf.createVertical ( rightContact, brContact, rightX, 0 ) if qt.isRoot(): ckNet = self.clockNet if not self.spares.conf.isCoreBlock: diff --git a/cumulus/src/plugins/alpha/block/spares.py b/cumulus/src/plugins/alpha/block/spares.py index 7dbc88e3..da6d564b 100644 --- a/cumulus/src/plugins/alpha/block/spares.py +++ b/cumulus/src/plugins/alpha/block/spares.py @@ -1,4 +1,4 @@ -# + # This file is part of the Coriolis Software. # Copyright (c) SU 2020-2020, All Rights Reserved # @@ -253,10 +253,43 @@ class QuadTree ( object ): else: area = Box( area ) spares.conf.icore.getTransformation().applyOn( area ) - root = QuadTree( spares, None, area ) + root = QuadTree._create( spares, None, area, 'root', raiseError=True ) root.rpartition() return root + @staticmethod + def isUsedArea ( spares, area, rtag, raiseError ): + centerArea = Box( area.getCenter() ) + sliceHeight = spares.conf.sliceHeight + centerArea.inflate( 4*sliceHeight, sliceHeight ) + trace( 540, '\tQuadTree.isUnderArea(): {} {} of {}\n'.format(rtag,centerArea,spares.conf.cell) ) + trace( 540, '\t{}\n'.format( spares.conf.cellPnR )) + for occurrence in spares.conf.cellPnR.getTerminalNetlistInstanceOccurrencesUnder( centerArea ): + if not isinstance(occurrence.getEntity(),Instance): + continue + instance = occurrence.getEntity() + masterCell = instance.getMasterCell() + if not masterCell.isTerminalNetlist(): + continue + trace( 540, '\t| Overlap {}\n'.format(occurrence.getEntity()) ) + if raiseError: + raise Error%essage( 1, [ 'QuadTree.create(): Unable to create QuadTree under area {}' \ + .format(area) + , 'Area center is under fixed block {}' .format() + ] ) + return True + sys.stdout.flush() + sys.stderr.flush() + return False + + @staticmethod + def _create ( spares, parent, area, rtag, raiseError=False ): + childRtag = parent.rtag+'_'+rtag if parent else rtag + if QuadTree.isUsedArea( spares, area, childRtag, raiseError ): + return None + qt = QuadTree( spares, parent, area, childRtag ) + return qt + def __init__ ( self, spares, parent, area, rtag='root' ): self.spares = spares self.area = area @@ -474,73 +507,73 @@ class QuadTree ( object ): if aspectRatio < 0.5: self.ycut = self.spares.toYSlice( self.area.getYMin() + self.area.getHeight()/2 ) - self.bl = QuadTree( self.spares - , self - , Box( self.area.getXMin() - , self.area.getYMin() - , self.area.getXMax() - , self.ycut ) - , 'bl' ) - self.tl = QuadTree( self.spares - , self - , Box( self.area.getXMin() - , self.ycut - , self.area.getXMax() - , self.area.getYMax() ) - , 'tl' ) + self.bl = QuadTree._create( self.spares + , self + , Box( self.area.getXMin() + , self.area.getYMin() + , self.area.getXMax() + , self.ycut ) + , 'bl' ) + self.tl = QuadTree._create( self.spares + , self + , Box( self.area.getXMin() + , self.ycut + , self.area.getXMax() + , self.area.getYMax() ) + , 'tl' ) trace( 540, '\tVertical bi-partition @Y:{}\n'.format(DbU.getValueString(self.ycut)) ) trace( 540, '-' ) return True elif aspectRatio > 2.0: self.xcut = self.spares.toXPitch( self.area.getXMin() + self.area.getWidth()/2 ) - self.bl = QuadTree( self.spares - , self - , Box( self.area.getXMin() - , self.area.getYMin() - , self.xcut - , self.area.getYMax() ) - , 'bl' ) - self.br = QuadTree( self.spares - , self - , Box( self.xcut - , self.area.getYMin() - , self.area.getXMax() - , self.area.getYMax() ) - , 'br' ) + self.bl = QuadTree._create( self.spares + , self + , Box( self.area.getXMin() + , self.area.getYMin() + , self.xcut + , self.area.getYMax() ) + , 'bl' ) + self.br = QuadTree._create( self.spares + , self + , Box( self.xcut + , self.area.getYMin() + , self.area.getXMax() + , self.area.getYMax() ) + , 'br' ) trace( 540, '\tHorizontal bi-partition @X:{}\n'.format(DbU.getValueString(self.xcut)) ) trace( 540, '-' ) return True self.ycut = self.spares.toYSlice( self.area.getYMin() + self.area.getHeight()/2 ) self.xcut = self.spares.toXPitch( self.area.getXMin() + self.area.getWidth ()/2 ) - self.bl = QuadTree( self.spares - , self - , Box( self.area.getXMin() - , self.area.getYMin() - , self.xcut - , self.ycut ) - , 'bl' ) - self.br = QuadTree( self.spares - , self - , Box( self.xcut - , self.area.getYMin() - , self.area.getXMax() - , self.ycut ) - , 'br' ) - self.tl = QuadTree( self.spares - , self - , Box( self.area.getXMin() - , self.ycut - , self.xcut - , self.area.getYMax() ) - , 'tl' ) - self.tr = QuadTree( self.spares - , self - , Box( self.xcut - , self.ycut - , self.area.getXMax() - , self.area.getYMax() ) - , 'tr' ) + self.bl = QuadTree._create( self.spares + , self + , Box( self.area.getXMin() + , self.area.getYMin() + , self.xcut + , self.ycut ) + , 'bl' ) + self.br = QuadTree._create( self.spares + , self + , Box( self.xcut + , self.area.getYMin() + , self.area.getXMax() + , self.ycut ) + , 'br' ) + self.tl = QuadTree._create( self.spares + , self + , Box( self.area.getXMin() + , self.ycut + , self.xcut + , self.area.getYMax() ) + , 'tl' ) + self.tr = QuadTree._create( self.spares + , self + , Box( self.xcut + , self.ycut + , self.area.getXMax() + , self.area.getYMax() ) + , 'tr' ) trace( 540, '\tQuadri-partition @X:{} + @Y:{}\n'\ .format(DbU.getValueString(self.xcut),DbU.getValueString(self.ycut)) ) @@ -658,11 +691,21 @@ class QuadTree ( object ): if self.isVBipart(): if position.getY() < self.ycut: return self.bl.getLeafUnder(position) return self.tl.getLeafUnder(position) + leaf = None if position.getX() < self.xcut: - if position.getY() < self.ycut: return self.bl.getLeafUnder(position) - return self.tl.getLeafUnder(position) - if position.getY() < self.ycut: return self.br.getLeafUnder(position) - return self.tr.getLeafUnder(position) + if position.getY() < self.ycut: leaf = self.bl + else: leaf = self.tl + else: + if position.getY() < self.ycut: leaf = self.br + else: leaf = self.tr + if not leaf: + dx = abs( position.getX() - self.xcut ) + dy = abs( position.getY() - self.ycut ) + if self.tr and ((dx < dy) or not leaf): leaf = self.tr + if self.tl and ((dx < dy) or not leaf): leaf = self.tl + if self.br and ((dx >= dy) or not leaf): leaf = self.br + if self.bl and ((dx >= dy) or not leaf): leaf = self.bl + return leaf.getLeafUnder(position) def getFreeLeafUnder ( self, area, attractor=None ): """ @@ -867,7 +910,7 @@ class Spares ( object ): , DbU.getValueString(7*self.conf.sliceHeight ) )) with UpdateSession(): self.quadTree = QuadTree.create( self ) - self._addCapTies() + #self._addCapTies() trace( 540, '-' ) def rshowPoolUse ( self ):