From bf9ce7399ac435aa5491529f4432542e96b3f5b3 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Jan 2024 19:51:47 +0100 Subject: [PATCH] More accurate search for obstacle of the H-Tree sub-branches. --- cumulus/src/plugins/block/spares.py | 64 +++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/cumulus/src/plugins/block/spares.py b/cumulus/src/plugins/block/spares.py index b5b93b373..a2406b2ce 100644 --- a/cumulus/src/plugins/block/spares.py +++ b/cumulus/src/plugins/block/spares.py @@ -21,7 +21,7 @@ from ...Hurricane import Breakpoint, DbU, Box, Transformation, Box, \ Path, Layer, Occurrence, Net, RoutingPad, \ Horizontal, Vertical, Contact, Pin, Plug, \ - Instance + Instance, Point from ...CRL import AllianceFramework, RoutingLayerGauge from ...helpers import trace, dots, l, u, n from ...helpers.io import ErrorMessage, WarningMessage, catch @@ -276,27 +276,54 @@ def create ( spares ): @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) ) + if rtag[-2:] == 'bl': + vWireArea = Box( area.getXCenter(), area.getYCenter() + , area.getXCenter(), area.getYMax () ) + hWireArea = Box( area.getXCenter(), area.getYMax() + , area.getXMax (), area.getYMax() ) + elif rtag[-2:] == 'br': + vWireArea = Box( area.getXCenter(), area.getYCenter() + , area.getXCenter(), area.getYMax () ) + hWireArea = Box( area.getXCenter(), area.getYMax() + , area.getXMin (), area.getYMax() ) + elif rtag[-2:] == 'tl': + vWireArea = Box( area.getXCenter(), area.getYCenter() + , area.getXCenter(), area.getYMin () ) + hWireArea = Box( area.getXCenter(), area.getYMin() + , area.getXMax (), area.getYMin() ) + elif rtag[-2:] == 'tr': + vWireArea = Box( area.getXCenter(), area.getYCenter() + , area.getXCenter(), area.getYMin () ) + hWireArea = Box( area.getXCenter(), area.getYMin() + , area.getXMin (), area.getYMin() ) + else: + vWireArea = Box( area.getXCenter(), area.getYCenter() ) + hWireArea = vWireArea + vWireArea.inflate( 0, sliceHeight ) + hWireArea.inflate( sliceHeight, 0 ) + trace( 540, '\tQuadTree.isUsedArea(): {} {} of {}\n'.format(rtag,hWireArea,vWireArea,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 + for treeBox in vWireArea, hWireArea: + for occurrence in spares.conf.cellPnR.getTerminalNetlistInstanceOccurrencesUnder( treeBox ): + if not isinstance(occurrence.getEntity(),Instance): + continue + instance = occurrence.getEntity() + masterCell = instance.getMasterCell() + if not masterCell.isTerminalNetlist(): + continue + if instance.getName().startswith('spare_'): + 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() + trace( 540, '\t-> Area is clear.\n' ) return False @staticmethod @@ -305,6 +332,7 @@ def _create ( spares, parent, area, tag, raiseError=False ): if QuadTree.isUsedArea( spares, area, childRtag, raiseError ): return None qt = QuadTree( spares, parent, area, childRtag ) + trace( 540, '\tQuadTree._create(): {}\n'.format(qt) ) return qt def __init__ ( self, spares, parent, area, rtag='root' ):