Add jumpers (antenna protection) on I/O pads and SRAM macro-block.

* New: In cumulus/plugins.chip.pads, add METAL5 jumpers on all wires
    going to/from the I/O pads on the East & West side. This is a
    quick hack as:
      1. We should put it also on North/South, but no violation
         happens here.
      2. We should put it on *ouput* wire only (for only those are
         connected to transistors gates).
* New: In cumulus/plugins.chip.macro, put jumpers on the East side
    connectors for the SRAM block. Also a quick hack, not robust for
    anything else than the SRAM.
This commit is contained in:
Jean-Paul Chaput 2021-06-08 12:20:05 +02:00
parent dd49a185af
commit 92a3e32aaf
2 changed files with 159 additions and 38 deletions

View File

@ -513,6 +513,7 @@ class CoreWire ( object ):
self.offset = 0 self.offset = 0
self.offsetType = CoreWire.NoOffset self.offsetType = CoreWire.NoOffset
self.side = side self.side = side
self.addJumper = False
self.preferredDir = preferredDir self.preferredDir = preferredDir
self.inCoronaRange = True self.inCoronaRange = True
self.arraySize = None self.arraySize = None
@ -520,6 +521,8 @@ class CoreWire ( object ):
self.viaPitch = DbU.fromLambda( 4.0 ) self.viaPitch = DbU.fromLambda( 4.0 )
self.gapWidth = 0 self.gapWidth = 0
self._computeCoreLayers() self._computeCoreLayers()
if self.conf.routingGauge.getName() == 'FlexLib':
self.addJumper = True
@property @property
def conf ( self ): return self.corona.conf def conf ( self ): return self.corona.conf
@ -627,6 +630,61 @@ class CoreWire ( object ):
if not self.preferredDir: if not self.preferredDir:
#xPadMin -= self.bbSegment.getHeight()/2 #xPadMin -= self.bbSegment.getHeight()/2
xPadMin -= 3*vPitch xPadMin -= 3*vPitch
if self.addJumper:
rg = self.conf.routingGauge
gaugeM5 = rg.getLayerGauge( 4 )
wwidthM5 = gaugeM5.getWireWidth()
jumperGap = 3*gaugeM5.getPitch()
if self.side == East:
gapCenter = xPadMin + 5*gaugeM5.getPitch()
else:
gapCenter = xPadMax - 5*gaugeM5.getPitch()
xJumpMin = gapCenter - jumperGap/2
xJumpMax = gapCenter + jumperGap/2
hReal1 = Horizontal.create( self.chipNet
, self.padSegment.getLayer()
, self.bbSegment.getCenter().getY()
, self.bbSegment.getHeight()
, xPadMin
, xJumpMin
)
trace( 550, '\thReal1: %s\n' % str(hReal1) )
hReal2 = Horizontal.create( self.chipNet
, self.padSegment.getLayer()
, self.bbSegment.getCenter().getY()
, self.bbSegment.getHeight()
, xJumpMax
, xPadMax
)
trace( 550, '\thReal2: %s\n' % str(hReal2) )
hReal = hReal2 if self.side == West else hReal1
bvia1 = BigVia( self.chipNet
, rg.getLayerDepth( self.padSegment.getLayer() )
, xJumpMin
, self.bbSegment.getCenter().getY()
, wwidthM5
, 2*wwidthM5
, flags=BigVia.AllowAllExpand )
bvia1.mergeDepth( gaugeM5.getDepth() )
trace( 550, '\tbvia1: %s\n' % str(bvia1) )
bvia1.doLayout()
bvia2 = BigVia( self.chipNet
, rg.getLayerDepth( self.padSegment.getLayer() )
, xJumpMax
, self.bbSegment.getCenter().getY()
, wwidthM5
, 2*wwidthM5
, flags=BigVia.AllowAllExpand )
bvia2.mergeDepth( gaugeM5.getDepth() )
bvia2.doLayout()
trace( 550, '\tbvia2: %s\n' % str(bvia2) )
Horizontal.create( bvia1.getPlate( gaugeM5.getLayer() )
, bvia2.getPlate( gaugeM5.getLayer() )
, gaugeM5.getLayer()
, self.bbSegment.getCenter().getY()
, wwidthM5
)
else:
hReal = Horizontal.create( self.chipNet hReal = Horizontal.create( self.chipNet
, self.padSegment.getLayer() , self.padSegment.getLayer()
, self.bbSegment.getCenter().getY() , self.bbSegment.getCenter().getY()

View File

@ -134,19 +134,33 @@ class Macro ( object ):
gaugeMetal2 = self.rg.getLayerGauge( 1 ) gaugeMetal2 = self.rg.getLayerGauge( 1 )
gaugeMetal3 = self.rg.getLayerGauge( 2 ) gaugeMetal3 = self.rg.getLayerGauge( 2 )
gaugeMetal4 = self.rg.getLayerGauge( 3 ) gaugeMetal4 = self.rg.getLayerGauge( 3 )
gaugeMetal5 = self.rg.getLayerGauge( 4 )
blockageMetal2 = gaugeMetal2.getBlockageLayer() blockageMetal2 = gaugeMetal2.getBlockageLayer()
blockageMetal3 = gaugeMetal3.getBlockageLayer() blockageMetal3 = gaugeMetal3.getBlockageLayer()
blockageMetal4 = gaugeMetal4.getBlockageLayer() blockageMetal4 = gaugeMetal4.getBlockageLayer()
minSpacingMetal2 = gaugeMetal2.getLayer().getMinimalSpacing() minSpacingMetal2 = gaugeMetal2.getLayer().getMinimalSpacing()
minSpacingMetal3 = gaugeMetal3.getLayer().getMinimalSpacing() minSpacingMetal3 = gaugeMetal3.getLayer().getMinimalSpacing()
minSpacingMetal4 = gaugeMetal4.getLayer().getMinimalSpacing() minSpacingMetal4 = gaugeMetal4.getLayer().getMinimalSpacing()
useJumper = False
xMinAdjust = 0
yMinAdjust = 0
xMaxAdjust = 0
yMaxAdjust = 0
if self.cell.getName().lower() == 'spblock_512w64b8w': if self.cell.getName().lower() == 'spblock_512w64b8w':
print( ' o Ad-hoc patch for "{}".'.format(self.cell.getName()) ) print( ' o Ad-hoc patch for "{}".'.format(self.cell.getName()) )
useJumper = True
xMinAdjust = 3*self.rg.getPitch( gaugeMetal5.getLayer() )
pitch = gaugeMetal2.getPitch()
if xMinAdjust % pitch:
xMinAdjust += pitch - (xMinAdjust % pitch)
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:
bb = component.getBoundingBox() bb = component.getBoundingBox()
bb.inflate( minSpacingMetal2 ) bb.inflate( minSpacingMetal2 + xMinAdjust
, minSpacingMetal2
, minSpacingMetal2
, minSpacingMetal2 )
Horizontal.create( component.getNet() Horizontal.create( component.getNet()
, blockageMetal2 , blockageMetal2
, bb.getYCenter() , bb.getYCenter()
@ -192,11 +206,9 @@ class Macro ( object ):
elif ab.getXMin() == bb.getXMin(): westPins.append( component ) elif ab.getXMin() == bb.getXMin(): westPins.append( component )
elif ab.getYMax() == bb.getYMax(): northPins.append( component ) elif ab.getYMax() == bb.getYMax(): northPins.append( component )
elif ab.getYMin() == bb.getYMin(): southPins.append( component ) elif ab.getYMin() == bb.getYMin(): southPins.append( component )
xAdjust = 0 if ab.getWidth () % sliceHeight: xMaxAdjust = sliceHeight - (ab.getWidth ()+xMinAdjust) % sliceHeight
yAdjust = 0 if ab.getHeight() % sliceHeight: yMaxAdjust = sliceHeight - (ab.getHeight()+yMinAdjust) % sliceHeight
if ab.getWidth () % sliceHeight: xAdjust = sliceHeight - ab.getWidth () % sliceHeight self.innerAb.inflate( xMinAdjust, 0, xMaxAdjust, yMaxAdjust )
if ab.getHeight() % sliceHeight: yAdjust = sliceHeight - ab.getHeight() % sliceHeight
self.innerAb.inflate( 0, 0, xAdjust, yAdjust )
self.outerAb = Box( 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() )
@ -225,6 +237,57 @@ class Macro ( object ):
else: else:
ppYAxis += width/2 ppYAxis += width/2
ppYOngrid -= wwidth/2 ppYOngrid -= wwidth/2
if useJumper:
jpitch = self.rg.getPitch ( gaugeMetal5.getLayer() )
jwwidth = self.rg.getWireWidth( gaugeMetal5.getLayer() )
xMin -= 4*jpitch
bvia1 = BigVia( component.getNet()
, self.getLayerDepth(component.getLayer())
, xMax
, yOngrid
, wwidth
, 3*wwidth
, flags=BigVia.AllowAllExpand )
bvia1.mergeDepth( gaugeMetal5.getDepth() )
bvia1.doLayout()
bvia2 = BigVia( component.getNet()
, self.getLayerDepth(component.getLayer())
, xMax - 3*jpitch
, yOngrid
, wwidth
, 3*wwidth
, flags=BigVia.AllowAllExpand )
bvia2.mergeDepth( gaugeMetal5.getDepth() )
bvia2.doLayout()
Horizontal.create( bvia1.getPlate( gaugeMetal5.getLayer() )
, bvia2.getPlate( gaugeMetal5.getLayer() )
, gaugeMetal5.getLayer()
, yOngrid
, jwwidth
)
horizontal = Horizontal.create( component.getNet()
, component.getLayer()
, yOngrid
, wwidth
, xMin
, xMax - 3*jpitch
)
horizontal = Horizontal.create( component.getNet()
, component.getLayer()
, yOngrid
, wwidth
, xMin
, xMin + ppitch + ppitch/2
)
blockageNet = self.cell.getNet( '*' )
for gauge in [ gaugeMetal3, gaugeMetal3, gaugeMetal4, gaugeMetal5 ]:
bb = bvia1.getPlate( gauge.getLayer() ).getBoundingBox()
bb.merge( bvia2.getPlate( gauge.getLayer() ).getBoundingBox() )
bb.inflate( gauge.getLayer().getMinimalSpacing() )
Pad.create( blockageNet
, gauge.getLayer().getBlockageLayer()
, bb )
else:
vertical = Vertical.create( component.getNet() vertical = Vertical.create( component.getNet()
, component.getLayer() , component.getLayer()
, bb.getXMin() , bb.getXMin()
@ -259,8 +322,8 @@ class Macro ( object ):
bb = component.getBoundingBox() bb = component.getBoundingBox()
yAxis = bb.getYCenter() yAxis = bb.getYCenter()
yOngrid = self.getNearestTrackAxis( layer, yAxis ) yOngrid = self.getNearestTrackAxis( layer, yAxis )
xMin = self.innerAb.getXMax() - xAdjust xMin = self.innerAb.getXMax() - xMaxAdjust
xMax = xMin + xAdjust + hMargin*ppitch xMax = xMin + xMaxAdjust + hMargin*ppitch
width = bb.getHeight() width = bb.getHeight()
ppYAxis = yAxis ppYAxis = yAxis
ppYOngrid = yOngrid ppYOngrid = yOngrid
@ -289,7 +352,7 @@ class Macro ( object ):
, layer , layer
, yOngrid , yOngrid
, wwidth , wwidth
, xMin + xAdjust + ppitch , xMin + xMaxAdjust + ppitch
, xMax , xMax
) )
NetExternalComponents.setExternal( horizontal ) NetExternalComponents.setExternal( horizontal )
@ -347,8 +410,8 @@ class Macro ( object ):
bb = component.getBoundingBox() bb = component.getBoundingBox()
xAxis = bb.getXCenter() xAxis = bb.getXCenter()
xOngrid = self.getNearestTrackAxis( layer, xAxis ) xOngrid = self.getNearestTrackAxis( layer, xAxis )
yMin = self.innerAb.getYMax() - yAdjust yMin = self.innerAb.getYMax() - yMaxAdjust
yMax = yMin + yAdjust + vMargin*ppitch yMax = yMin + yMaxAdjust + vMargin*ppitch
width = bb.getWidth() width = bb.getWidth()
ppXAxis = xAxis ppXAxis = xAxis
ppXOngrid = xOngrid ppXOngrid = xOngrid
@ -388,7 +451,7 @@ class Macro ( object ):
, layer , layer
, xOngrid , xOngrid
, wwidth , wwidth
, yMin + ppitch + yAdjust , yMin + ppitch + yMaxAdjust
, yMax , yMax
) )
NetExternalComponents.setExternal( vertical ) NetExternalComponents.setExternal( vertical )