Generate cut via matrixes instead of monolithic symbolic ones.
* New: In cumulus/plugins/chip.corona.HorizontalRail & VerticalRail, use the new BigVia instead of StackVia to generate a matrix of cut when in real mode. Stick to the one massive VIA when in symbolic. * New: In cumulus/plugins/block.bigvia.BigVia to generate matrixes of cut VIA.
This commit is contained in:
parent
a4eb811bcb
commit
b974795a44
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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() )
|
||||
|
|
Loading…
Reference in New Issue