From 92a3e32aaff59260e2e9fac5e3cc758b4f0e0816 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 8 Jun 2021 12:20:05 +0200 Subject: [PATCH] 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. --- cumulus/src/plugins/alpha/chip/pads.py | 72 +++++++++++-- cumulus/src/plugins/alpha/macro/macro.py | 125 +++++++++++++++++------ 2 files changed, 159 insertions(+), 38 deletions(-) diff --git a/cumulus/src/plugins/alpha/chip/pads.py b/cumulus/src/plugins/alpha/chip/pads.py index e8fa53c9..2257a859 100644 --- a/cumulus/src/plugins/alpha/chip/pads.py +++ b/cumulus/src/plugins/alpha/chip/pads.py @@ -513,6 +513,7 @@ class CoreWire ( object ): self.offset = 0 self.offsetType = CoreWire.NoOffset self.side = side + self.addJumper = False self.preferredDir = preferredDir self.inCoronaRange = True self.arraySize = None @@ -520,6 +521,8 @@ class CoreWire ( object ): self.viaPitch = DbU.fromLambda( 4.0 ) self.gapWidth = 0 self._computeCoreLayers() + if self.conf.routingGauge.getName() == 'FlexLib': + self.addJumper = True @property def conf ( self ): return self.corona.conf @@ -627,13 +630,68 @@ class CoreWire ( object ): if not self.preferredDir: #xPadMin -= self.bbSegment.getHeight()/2 xPadMin -= 3*vPitch - hReal = Horizontal.create( self.chipNet - , self.padSegment.getLayer() - , self.bbSegment.getCenter().getY() - , self.bbSegment.getHeight() - , xPadMin - , xPadMax - ) + 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 + , self.padSegment.getLayer() + , self.bbSegment.getCenter().getY() + , self.bbSegment.getHeight() + , xPadMin + , xPadMax + ) trace( 550, '\tself.arraySize: %s\n' % str(self.arraySize) ) if self.arraySize: contacts = self.conf.coronaContactArray( self.chipNet diff --git a/cumulus/src/plugins/alpha/macro/macro.py b/cumulus/src/plugins/alpha/macro/macro.py index 75820c85..014a210e 100644 --- a/cumulus/src/plugins/alpha/macro/macro.py +++ b/cumulus/src/plugins/alpha/macro/macro.py @@ -134,19 +134,33 @@ class Macro ( object ): gaugeMetal2 = self.rg.getLayerGauge( 1 ) gaugeMetal3 = self.rg.getLayerGauge( 2 ) gaugeMetal4 = self.rg.getLayerGauge( 3 ) + gaugeMetal5 = self.rg.getLayerGauge( 4 ) blockageMetal2 = gaugeMetal2.getBlockageLayer() blockageMetal3 = gaugeMetal3.getBlockageLayer() blockageMetal4 = gaugeMetal4.getBlockageLayer() minSpacingMetal2 = gaugeMetal2.getLayer().getMinimalSpacing() minSpacingMetal3 = gaugeMetal3.getLayer().getMinimalSpacing() minSpacingMetal4 = gaugeMetal4.getLayer().getMinimalSpacing() + useJumper = False + xMinAdjust = 0 + yMinAdjust = 0 + xMaxAdjust = 0 + yMaxAdjust = 0 if self.cell.getName().lower() == 'spblock_512w64b8w': 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 component in net.getComponents(): if isinstance(component,Rectilinear) and component.getLayer() == blockageMetal2: bb = component.getBoundingBox() - bb.inflate( minSpacingMetal2 ) + bb.inflate( minSpacingMetal2 + xMinAdjust + , minSpacingMetal2 + , minSpacingMetal2 + , minSpacingMetal2 ) Horizontal.create( component.getNet() , blockageMetal2 , bb.getYCenter() @@ -192,11 +206,9 @@ class Macro ( object ): elif ab.getXMin() == bb.getXMin(): westPins.append( component ) elif ab.getYMax() == bb.getYMax(): northPins.append( component ) elif ab.getYMin() == bb.getYMin(): southPins.append( component ) - xAdjust = 0 - yAdjust = 0 - if ab.getWidth () % sliceHeight: xAdjust = sliceHeight - ab.getWidth () % sliceHeight - if ab.getHeight() % sliceHeight: yAdjust = sliceHeight - ab.getHeight() % sliceHeight - self.innerAb.inflate( 0, 0, xAdjust, yAdjust ) + if ab.getWidth () % sliceHeight: xMaxAdjust = sliceHeight - (ab.getWidth ()+xMinAdjust) % sliceHeight + if ab.getHeight() % sliceHeight: yMaxAdjust = sliceHeight - (ab.getHeight()+yMinAdjust) % sliceHeight + self.innerAb.inflate( xMinAdjust, 0, xMaxAdjust, yMaxAdjust ) self.outerAb = Box( self.innerAb ) self.outerAb.inflate( sliceHeight ) westPins .sort( key=lambda k: k.getBoundingBox().getYCenter() ) @@ -225,27 +237,78 @@ class Macro ( object ): else: ppYAxis += width/2 ppYOngrid -= wwidth/2 - vertical = Vertical.create( component.getNet() - , component.getLayer() - , bb.getXMin() - , width - , ppYAxis - , ppYOngrid - ) - horizontal = Horizontal.create( component.getNet() + 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() , component.getLayer() - , yOngrid - , wwidth - , xMin - , xMax - ) - horizontal = Horizontal.create( component.getNet() - , component.getLayer() - , yOngrid - , wwidth - , xMin - , xMin + ppitch + ppitch/2 + , bb.getXMin() + , width + , ppYAxis + , ppYOngrid ) + horizontal = Horizontal.create( component.getNet() + , component.getLayer() + , yOngrid + , wwidth + , xMin + , xMax + ) + horizontal = Horizontal.create( component.getNet() + , component.getLayer() + , yOngrid + , wwidth + , xMin + , xMin + ppitch + ppitch/2 + ) NetExternalComponents.setExternal( horizontal ) for component in eastPins: layer = component.getLayer() @@ -259,8 +322,8 @@ class Macro ( object ): bb = component.getBoundingBox() yAxis = bb.getYCenter() yOngrid = self.getNearestTrackAxis( layer, yAxis ) - xMin = self.innerAb.getXMax() - xAdjust - xMax = xMin + xAdjust + hMargin*ppitch + xMin = self.innerAb.getXMax() - xMaxAdjust + xMax = xMin + xMaxAdjust + hMargin*ppitch width = bb.getHeight() ppYAxis = yAxis ppYOngrid = yOngrid @@ -289,7 +352,7 @@ class Macro ( object ): , layer , yOngrid , wwidth - , xMin + xAdjust + ppitch + , xMin + xMaxAdjust + ppitch , xMax ) NetExternalComponents.setExternal( horizontal ) @@ -347,8 +410,8 @@ class Macro ( object ): bb = component.getBoundingBox() xAxis = bb.getXCenter() xOngrid = self.getNearestTrackAxis( layer, xAxis ) - yMin = self.innerAb.getYMax() - yAdjust - yMax = yMin + yAdjust + vMargin*ppitch + yMin = self.innerAb.getYMax() - yMaxAdjust + yMax = yMin + yMaxAdjust + vMargin*ppitch width = bb.getWidth() ppXAxis = xAxis ppXOngrid = xOngrid @@ -388,7 +451,7 @@ class Macro ( object ): , layer , xOngrid , wwidth - , yMin + ppitch + yAdjust + , yMin + ppitch + yMaxAdjust , yMax ) NetExternalComponents.setExternal( vertical )