Correct handling of block orientation in block.py & macro.py.

* Bug: In cumulus/plugins.macro.Macro.__init__(), stick out the rigth number
    of pitches on North & East sides (never tested before).
* New: In cumulus/plugins.macro.Macro.__init__(), manage layer change
    if the terminal is not in the preferred routing direction. Use BigVia
    and put at least two cuts.
This commit is contained in:
Jean-Paul Chaput 2021-05-22 15:21:26 +02:00
parent d4c3cf7dbb
commit fd67ca6cda
2 changed files with 64 additions and 34 deletions

View File

@ -627,7 +627,7 @@ class Block ( object ):
, instance , instance
, Transformation( macroPosition.getX() , Transformation( macroPosition.getX()
, macroPosition.getY() , macroPosition.getY()
, Transformation.Orientation.ID ) , transf.getOrientation() )
, Instance.PlacementStatus.FIXED ) , Instance.PlacementStatus.FIXED )
trace( 550, '-' ) trace( 550, '-' )

View File

@ -28,6 +28,7 @@ from CRL import RoutingLayerGauge
from helpers import trace, dots from helpers import trace, dots
from helpers.io import ErrorMessage, WarningMessage, catch from helpers.io import ErrorMessage, WarningMessage, catch
from helpers.overlay import UpdateSession from helpers.overlay import UpdateSession
from plugins.alpha.block.bigvia import BigVia
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
@ -53,8 +54,14 @@ class Macro ( object ):
def place ( topCell, instance, transf, status ): def place ( topCell, instance, transf, status ):
macro = Macro.lookup( instance.getMasterCell() ) macro = Macro.lookup( instance.getMasterCell() )
ab = instance.getMasterCell().getAbutmentBox() ab = instance.getMasterCell().getAbutmentBox()
abShift = Transformation( -ab.getXMin(), -ab.getYMin(), Transformation.Orientation.ID ) if transf.getOrientation() == Transformation.Orientation.ID:
abShift = Transformation( -ab.getXMin(), -ab.getYMin(), Transformation.Orientation.ID )
if transf.getOrientation() == Transformation.Orientation.MX:
abShift = Transformation( ab.getXMin(), -ab.getYMin(), Transformation.Orientation.ID )
print( 'transf={}'.format(transf) )
print( 'abShift={}'.format(abShift) )
abShift.applyOn( transf ) abShift.applyOn( transf )
print( 'transf={}'.format(transf) )
instance.setTransformation( transf ) instance.setTransformation( transf )
instance.setPlacementStatus( status ) instance.setPlacementStatus( status )
@ -67,7 +74,6 @@ class Macro ( object ):
For an explanation of the parameters, see Macro.__init__(). For an explanation of the parameters, see Macro.__init__().
""" """
macro = Macro.lookup( macroCell ) macro = Macro.lookup( macroCell )
if macro is not None: if macro is not None:
trace( 550, '\tReusing macro wrapper {}\n'.format(macroCell) ) trace( 550, '\tReusing macro wrapper {}\n'.format(macroCell) )
@ -83,6 +89,9 @@ class Macro ( object ):
def getWireWidth ( self, metal ): def getWireWidth ( self, metal ):
return self.rg.getWireWidth( metal ) return self.rg.getWireWidth( metal )
def getLayerDepth ( self, metal ):
return self.rg.getLayerDepth( metal )
def getNearestTrackAxis ( self, metal, axis ): def getNearestTrackAxis ( self, metal, axis ):
lg = self.rg.getLayerGauge( metal ) lg = self.rg.getLayerGauge( metal )
if lg.getDirection() == RoutingLayerGauge.Horizontal: if lg.getDirection() == RoutingLayerGauge.Horizontal:
@ -132,7 +141,7 @@ class Macro ( object ):
minSpacingMetal3 = gaugeMetal3.getLayer().getMinimalSpacing() minSpacingMetal3 = gaugeMetal3.getLayer().getMinimalSpacing()
minSpacingMetal4 = gaugeMetal4.getLayer().getMinimalSpacing() minSpacingMetal4 = gaugeMetal4.getLayer().getMinimalSpacing()
if self.cell.getName().lower() == 'spblock_512w64b8w': if self.cell.getName().lower() == 'spblock_512w64b8w':
print( ' o Ad-hoc blockage patch for "{}".'.format(self.cell.getName()) ) print( ' o Ad-hoc patch for "{}".'.format(self.cell.getName()) )
for net in self.cell.getNets(): for net in self.cell.getNets():
for component in net.getComponents(): for component in net.getComponents():
if isinstance(component,Rectilinear) and component.getLayer() == blockageMetal2: if isinstance(component,Rectilinear) and component.getLayer() == blockageMetal2:
@ -162,6 +171,8 @@ class Macro ( object ):
, bb.getHeight() , bb.getHeight()
, bb.getXMin() , bb.getXMin()
, bb.getXMax() ) , bb.getXMax() )
if self.cell.getName().lower() in [ 'pll', 'gds_pll', 'cmpt_pll' ]:
print( ' o Ad-hoc patch for "{}".'.format(self.cell.getName()) )
self.innerAb = ab self.innerAb = ab
sliceHeight = af.getCellGauge( gaugeName ).getSliceHeight() sliceHeight = af.getCellGauge( gaugeName ).getSliceHeight()
westPins = [] westPins = []
@ -186,7 +197,7 @@ class Macro ( object ):
if ab.getWidth () % sliceHeight: xAdjust = sliceHeight - ab.getWidth () % sliceHeight if ab.getWidth () % sliceHeight: xAdjust = sliceHeight - ab.getWidth () % sliceHeight
if ab.getHeight() % sliceHeight: yAdjust = sliceHeight - ab.getHeight() % sliceHeight if ab.getHeight() % sliceHeight: yAdjust = sliceHeight - ab.getHeight() % sliceHeight
self.innerAb.inflate( 0, 0, xAdjust, yAdjust ) self.innerAb.inflate( 0, 0, xAdjust, yAdjust )
self.outerAb = self.innerAb self.outerAb = Box( self.innerAb )
self.outerAb.inflate( sliceHeight ) self.outerAb.inflate( sliceHeight )
westPins .sort( key=lambda k: k.getBoundingBox().getYCenter() ) westPins .sort( key=lambda k: k.getBoundingBox().getYCenter() )
eastPins .sort( key=lambda k: k.getBoundingBox().getYCenter() ) eastPins .sort( key=lambda k: k.getBoundingBox().getYCenter() )
@ -237,15 +248,19 @@ class Macro ( object ):
) )
NetExternalComponents.setExternal( horizontal ) NetExternalComponents.setExternal( horizontal )
for component in eastPins: for component in eastPins:
layer = component.getLayer()
if layer.getMask() != gaugeMetal2.getLayer().getMask():
useBigVia = True
layer = gaugeMetal2.getLayer()
NetExternalComponents.setInternal( component ) NetExternalComponents.setInternal( component )
pitch = self.rg.getPitch( component.getLayer() ) pitch = self.rg.getPitch( layer )
ppitch = self.getPPitch( component.getLayer() ) ppitch = self.getPPitch( layer )
wwidth = self.getWireWidth( component.getLayer() ) wwidth = self.getWireWidth( layer )
bb = component.getBoundingBox() bb = component.getBoundingBox()
yAxis = bb.getYCenter() yAxis = bb.getYCenter()
yOngrid = self.getNearestTrackAxis( component.getLayer(), yAxis ) yOngrid = self.getNearestTrackAxis( layer, yAxis )
xMin = self.innerAb.getXMax() xMin = self.innerAb.getXMax() - xAdjust
xMax = xMin + hMargin*ppitch xMax = xMin + xAdjust + hMargin*ppitch
width = bb.getHeight() width = bb.getHeight()
ppYAxis = yAxis ppYAxis = yAxis
ppYOngrid = yOngrid ppYOngrid = yOngrid
@ -264,17 +279,17 @@ class Macro ( object ):
, ppYOngrid , ppYOngrid
) )
horizontal = Horizontal.create( component.getNet() horizontal = Horizontal.create( component.getNet()
, component.getLayer() , layer
, yOngrid , yOngrid
, pitch + wwidth , wwidth
, xMin , xMin
, xMax , xMax
) )
horizontal = Horizontal.create( component.getNet() horizontal = Horizontal.create( component.getNet()
, component.getLayer() , layer
, yOngrid , yOngrid
, pitch + wwidth , wwidth
, xMin + ppitch , xMin + xAdjust + ppitch
, xMax , xMax
) )
NetExternalComponents.setExternal( horizontal ) NetExternalComponents.setExternal( horizontal )
@ -321,15 +336,19 @@ class Macro ( object ):
) )
NetExternalComponents.setExternal( vertical ) NetExternalComponents.setExternal( vertical )
for component in northPins: for component in northPins:
layer = component.getLayer()
if layer.getMask() != gaugeMetal3.getLayer().getMask():
useBigVia = True
layer = gaugeMetal3.getLayer()
NetExternalComponents.setInternal( component ) NetExternalComponents.setInternal( component )
pitch = self.rg.getPitch( component.getLayer() ) pitch = self.rg.getPitch( layer )
ppitch = self.getPPitch( component.getLayer() ) ppitch = self.getPPitch( layer )
wwidth = self.getWireWidth( component.getLayer() ) wwidth = self.getWireWidth( layer )
bb = component.getBoundingBox() bb = component.getBoundingBox()
xAxis = bb.getXCenter() xAxis = bb.getXCenter()
xOngrid = self.getNearestTrackAxis( component.getLayer(), xAxis ) xOngrid = self.getNearestTrackAxis( layer, xAxis )
yMin = self.innerAb.getYMax() yMin = self.innerAb.getYMax() - yAdjust
yMax = yMin + vMargin*ppitch yMax = yMin + yAdjust + vMargin*ppitch
width = bb.getWidth() width = bb.getWidth()
ppXAxis = xAxis ppXAxis = xAxis
ppXOngrid = xOngrid ppXOngrid = xOngrid
@ -340,25 +359,36 @@ class Macro ( object ):
else: else:
ppXAxis += width/2 ppXAxis += width/2
ppXOngrid -= wwidth/2 ppXOngrid -= wwidth/2
horizontal = Horizontal.create( component.getNet() if useBigVia:
, component.getLayer() bvia = BigVia( component.getNet()
, bb.getYMax() , self.getLayerDepth(component.getLayer())
, width , xOngrid
, ppXAxis , bb.getYMax() - wwidth
, ppXOngrid , wwidth
) , 3*wwidth
, flags=BigVia.AllowAllExpand )
bvia.mergeDepth( self.getLayerDepth(layer) )
bvia.doLayout()
else:
horizontal = Horizontal.create( component.getNet()
, component.getLayer()
, bb.getYMax()
, width
, ppXAxis
, ppXOngrid
)
vertical = Vertical.create( component.getNet() vertical = Vertical.create( component.getNet()
, component.getLayer() , layer
, xOngrid , xOngrid
, pitch + wwidth , wwidth
, yMin , yMin
, yMax , yMax
) )
vertical = Vertical.create( component.getNet() vertical = Vertical.create( component.getNet()
, component.getLayer() , layer
, xOngrid , xOngrid
, pitch + wwidth , wwidth
, yMin + ppitch , yMin + ppitch + yAdjust
, yMax , yMax
) )
NetExternalComponents.setExternal( vertical ) NetExternalComponents.setExternal( vertical )