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:
Jean-Paul Chaput 2020-11-14 18:53:51 +01:00
parent a4eb811bcb
commit b974795a44
4 changed files with 167 additions and 46 deletions

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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() )