diff --git a/cumulus/src/CMakeLists.txt b/cumulus/src/CMakeLists.txt index 3970fa30..fcfd11d4 100644 --- a/cumulus/src/CMakeLists.txt +++ b/cumulus/src/CMakeLists.txt @@ -48,6 +48,7 @@ set ( pyPluginAlphaBlock ${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/__init__.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/block/__init__.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/block/configuration.py + ${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/block/bigvia.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/block/spares.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/block/block.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/block/clocktree.py diff --git a/cumulus/src/plugins/alpha/block/bigvia.py b/cumulus/src/plugins/alpha/block/bigvia.py new file mode 100644 index 00000000..52ca0e8d --- /dev/null +++ b/cumulus/src/plugins/alpha/block/bigvia.py @@ -0,0 +1,125 @@ +# +# This file is part of the Coriolis Software. +# Copyright (c) SU 2020-2020, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | C u m u l u s - P y t h o n T o o l s | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./plugins/block/bigvia.py" | +# +-----------------------------------------------------------------+ + + +from __future__ import print_function +import sys +import os.path +import Cfg +from Hurricane import Breakpoint, DbU, Box, Transformation, Point, \ + Box, Path, Layer, Occurrence, Net, \ + NetExternalComponents, RoutingPad, Pad, \ + Horizontal, Vertical, Contact, Pin, Plug, \ + Instance +import CRL +from CRL import RoutingLayerGauge +from helpers import trace, dots +from helpers.io import ErrorMessage, WarningMessage, catch +from helpers.overlay import UpdateSession + +rg = None + + +# ---------------------------------------------------------------------------- +# Class : "bigvia.BigVia". + +class BigVia ( object ): + """ + Draw a large are VIA and manage the matrix of cuts. + """ + + def __init__ ( self, net, depth, x, y, width, height ): + self.hasLayout = False + self.net = net + self.bottomDepth = depth + self.topDepth = depth + self.x = x + self.y = y + self.width = width + self.height = height + self.plates = {} + self.vias = {} + + def getNet ( self ): return self.net + + def getPlate ( self, metal ): + if not self.hasLayout: return None + for plate in self.plates.values(): + if plate.getLayer().contains(metal): return plate + return None + + def mergeDepth ( self, depth ): + if self.hasLayout: + print( WarningMessage( 'BigVia.mergeDepth(): Cannot be called *after* BigVia.doLayout()' )) + return + if depth < self.bottomDepth: self.bottomDepth = depth + if depth > self.topDepth: self.topDepth = depth + + def doLayout ( self ): + global rg + if rg is None: rg = CRL.AllianceFramework.get().getRoutingGauge() + for depth in range(self.bottomDepth,self.topDepth+1): + print( 'Create plate @{} {} {}'.format(DbU.getValueString(self.x) + ,DbU.getValueString(self.y) + ,rg.getRoutingLayer(depth)) ) + self.plates[ depth ] = Contact.create( self.net + , rg.getRoutingLayer(depth) + , self.x , self.y + , self.width, self.height + ) + if rg.isSymbolic(): + for depth in range(self.bottomDepth,self.topDepth): + Contact.create( self.net + , rg.getContactLayer( depth ) + , self.x + , self.y + , self.width - DbU.fromLambda( 1.0 ) + , self.height - DbU.fromLambda( 1.0 ) ) + else: + for depth in range(self.bottomDepth,self.topDepth): + self._doCutMatrix( depth ) + self.hasLayout = True + + def _doCutMatrix ( self, depth ): + viaLayer = rg.getContactLayer( depth ) + cutLayer = viaLayer.getCut() + cutSide = cutLayer.getMinimalSize() + cutSpacing = cutLayer.getMinimalSpacing() + if not cutSide: + raise ErrorMessage( 1, 'BigVia._doCutMatrix(): Minimal side of cut layer "{}" is zero.' \ + .format( cutLayer.getName() )) + if not cutSpacing: + raise ErrorMessage( 1, 'BigVia._doCutMatrix(): Cut spacing on layer "{}" is zero.' \ + .format( cutLayer.getName() )) + topEnclosure = min( viaLayer.getTopEnclosure( Layer.EnclosureH ) + , viaLayer.getTopEnclosure( Layer.EnclosureV )) + botEnclosure = min( viaLayer.getBottomEnclosure( Layer.EnclosureH ) + , viaLayer.getBottomEnclosure( Layer.EnclosureV )) + enclosure = max( topEnclosure, botEnclosure ) + cutArea = self.plates[ depth ].getBoundingBox() + cutArea.inflate( - enclosure - 2*cutSide ) + self.vias[ depth ] = [] + y = cutArea.getYMin() + while y <= cutArea.getYMax(): + x = cutArea.getXMin() + self.vias[ depth ].append( [] ) + while x <= cutArea.getXMax(): + print( 'Create cut @{} {} {}'.format(DbU.getValueString(x) + ,DbU.getValueString(y) + ,cutLayer) ) + cut = Contact.create( self.net, cutLayer, x, y, cutSide, cutSide ) + self.vias[ depth ][ -1 ].append( cut ) + x += cutSide + cutSpacing + y += cutSide + cutSpacing + diff --git a/cumulus/src/plugins/alpha/block/block.py b/cumulus/src/plugins/alpha/block/block.py index 881bb146..4adcd5cd 100644 --- a/cumulus/src/plugins/alpha/block/block.py +++ b/cumulus/src/plugins/alpha/block/block.py @@ -17,32 +17,15 @@ from __future__ import print_function import sys import os.path import Cfg -from Hurricane import Breakpoint -from Hurricane import DbU -from Hurricane import Box -from Hurricane import Transformation -from Hurricane import Point -from Hurricane import Box -from Hurricane import Path -from Hurricane import Layer -from Hurricane import Occurrence -from Hurricane import Net -from Hurricane import NetExternalComponents -from Hurricane import RoutingPad -from Hurricane import Pad -from Hurricane import Horizontal -from Hurricane import Vertical -from Hurricane import Contact -from Hurricane import Pin -from Hurricane import Plug -from Hurricane import Instance +from Hurricane import Breakpoint, DbU, Box, Transformation, Point, \ + Box, Path, Layer, Occurrence, Net, \ + NetExternalComponents, RoutingPad, Pad, \ + Horizontal, Vertical, Contact, Pin, Plug, \ + Instance import CRL from CRL import RoutingLayerGauge -from helpers import trace -from helpers import dots -from helpers.io import ErrorMessage -from helpers.io import WarningMessage -from helpers.io import catch +from helpers import trace, dots +from helpers.io import ErrorMessage, WarningMessage, catch from helpers.overlay import UpdateSession import Etesian import Anabatic @@ -55,9 +38,7 @@ from alpha.block.clocktree import ClockTree #from alpha.block.hfns1 import BufferTree #from alpha.block.hfns2 import BufferTree from alpha.block.hfns3 import BufferTree -from alpha.block.configuration import IoPin -from alpha.block.configuration import BlockConf -from alpha.block.configuration import GaugeConf +from alpha.block.configuration import IoPin, BlockConf, GaugeConf timing.staticInit() diff --git a/cumulus/src/plugins/alpha/chip/corona.py b/cumulus/src/plugins/alpha/chip/corona.py index a632e09b..7251f6ce 100644 --- a/cumulus/src/plugins/alpha/chip/corona.py +++ b/cumulus/src/plugins/alpha/chip/corona.py @@ -38,6 +38,7 @@ from helpers.overlay import UpdateSession import plugins from plugins import StackedVia import plugins.alpha.chip +from plugins.alpha.block.bigvia import BigVia plugins.alpha.chip.importConstants( globals() ) @@ -94,6 +95,9 @@ class Rail ( object ): @property def net ( self ): return self.side.getRailNet(self.order) + @property + def conf ( self ): return self.side.corona.conf + # -------------------------------------------------------------------- # Class : "corona.HorizontalRail" @@ -137,14 +141,19 @@ class HorizontalRail ( Rail ): trace( 550, ',-', '\tFailed: overlap with existing contact @{}.\n' \ .format(self.vias[keys[insertIndex-1]][2]) ) return False + viaWidth = contact.getWidth() + viaHeight = self.side.hRailWidth + if self.conf.routingGauge.isSymbolic(): + viaWidth -= DbU.fromLambda( 1.0 ) + viaHeight -= DbU.fromLambda( 1.0 ) self.vias[ contact.getX() ] = [ contact.getX() - , StackedVia( self.net - , self.side.getLayerDepth(self.side.getHLayer()) - , contact.getX() - , self.axis - , contact.getWidth() - DbU.fromLambda(1.0) - , self.side.hRailWidth - DbU.fromLambda(1.0) - ) + , BigVia( self.net + , self.side.getLayerDepth(self.side.getHLayer()) + , contact.getX() + , self.axis + , viaWidth + , viaHeight + ) , contact ] trace( 550, '\tADD "{}" contact "{}" @ [{} {}]\n' \ .format( contact.getNet().getName() @@ -164,13 +173,13 @@ class HorizontalRail ( Rail ): if via[1].getNet() != via[2].getNet(): continue via[1].mergeDepth( self.side.getLayerDepth(self.side.getVLayer()) ) via[1].doLayout() - Vertical.create( via[1].getVia( via[2].getLayer() ) + Vertical.create( via[1].getPlate( via[2].getLayer() ) , via[2] , via[2].getLayer() , via[2].getX() , via[2].getWidth() ) - railVias.append( via[1].getVia( self.side.getVLayer()) ) + railVias.append( via[1].getPlate( self.side.getVLayer()) ) for i in range(1,len(railVias)): h = Horizontal.create( railVias[i-1] , railVias[i] @@ -202,13 +211,13 @@ class VerticalRail ( Rail ): for via in self.vias.values(): if via[1].getNet() != via[2].getNet(): continue via[1].doLayout() - Horizontal.create( via[1].getVia( via[2].getLayer() ) + Horizontal.create( via[1].getPlate( via[2].getLayer() ) , via[2] , via[2].getLayer() , via[2].getY() , via[2].getHeight() ) - railVias.append( via[1].getVia(self.side.getVLayer()) ) + railVias.append( via[1].getPlate(self.side.getVLayer()) ) railVias.sort( key=methodcaller('getY') ) for i in range(1,len(railVias)): Vertical.create( railVias[i-1] @@ -253,14 +262,19 @@ class VerticalRail ( Rail ): if self.vias[keys[insertIndex-1]][2].getBoundingBox().getYMax() >= contactBb.getYMin(): trace( 550, ',--', '\tReject {} intersect PREVIOUS\n'.format(contact) ) return False + viaWidth = self.side.vRailWidth + viaHeight = contact.getHeight() + if self.conf.routingGauge.isSymbolic(): + viaWidth -= DbU.fromLambda( 1.0 ) + viaHeight -= DbU.fromLambda( 1.0 ) self.vias[ contact.getY() ] = [ contact.getY() - , StackedVia( self.net - , self.side.getLayerDepth(self.side.getVLayer()) - , self.axis - , contact.getY() - , self.side.vRailWidth - DbU.fromLambda(1.0) - , contact.getHeight() - DbU.fromLambda(1.0) - ) + , BigVia( self.net + , self.side.getLayerDepth(self.side.getVLayer()) + , self.axis + , contact.getY() + , self.side.vRailWidth - DbU.fromLambda(1.0) + , contact.getHeight() - DbU.fromLambda(1.0) + ) , contact ] trace(550, ',--' '\tADD {}\n'.format(contact) ) self.vias[ contact.getY() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) ) @@ -449,7 +463,7 @@ class VerticalSide ( Side ): for rail in self.rails: for via in rail.vias.values(): if via[1].getNet() != via[2].getNet(): continue - spans.merge( via[1]._y - via[1]._height/2, via[1]._y + via[1]._height/2 ) + spans.merge( via[1].y - via[1].height/2, via[1].y + via[1].height/2 ) routingGauge = self.corona.routingGauge print( self.getOuterRail(0) ) print( self.getOuterRail(0).vias.values() )