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 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/__init__.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/block/configuration.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/spares.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/block/block.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/block/block.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/block/clocktree.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 sys
import os.path import os.path
import Cfg import Cfg
from Hurricane import Breakpoint from Hurricane import Breakpoint, DbU, Box, Transformation, Point, \
from Hurricane import DbU Box, Path, Layer, Occurrence, Net, \
from Hurricane import Box NetExternalComponents, RoutingPad, Pad, \
from Hurricane import Transformation Horizontal, Vertical, Contact, Pin, Plug, \
from Hurricane import Point Instance
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
import CRL import CRL
from CRL import RoutingLayerGauge from CRL import RoutingLayerGauge
from helpers import trace from helpers import trace, dots
from helpers import dots from helpers.io import ErrorMessage, WarningMessage, catch
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
from helpers.io import catch
from helpers.overlay import UpdateSession from helpers.overlay import UpdateSession
import Etesian import Etesian
import Anabatic import Anabatic
@ -55,9 +38,7 @@ from alpha.block.clocktree import ClockTree
#from alpha.block.hfns1 import BufferTree #from alpha.block.hfns1 import BufferTree
#from alpha.block.hfns2 import BufferTree #from alpha.block.hfns2 import BufferTree
from alpha.block.hfns3 import BufferTree from alpha.block.hfns3 import BufferTree
from alpha.block.configuration import IoPin from alpha.block.configuration import IoPin, BlockConf, GaugeConf
from alpha.block.configuration import BlockConf
from alpha.block.configuration import GaugeConf
timing.staticInit() timing.staticInit()

View File

@ -38,6 +38,7 @@ from helpers.overlay import UpdateSession
import plugins import plugins
from plugins import StackedVia from plugins import StackedVia
import plugins.alpha.chip import plugins.alpha.chip
from plugins.alpha.block.bigvia import BigVia
plugins.alpha.chip.importConstants( globals() ) plugins.alpha.chip.importConstants( globals() )
@ -94,6 +95,9 @@ class Rail ( object ):
@property @property
def net ( self ): return self.side.getRailNet(self.order) def net ( self ): return self.side.getRailNet(self.order)
@property
def conf ( self ): return self.side.corona.conf
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# Class : "corona.HorizontalRail" # Class : "corona.HorizontalRail"
@ -137,14 +141,19 @@ class HorizontalRail ( Rail ):
trace( 550, ',-', '\tFailed: overlap with existing contact @{}.\n' \ trace( 550, ',-', '\tFailed: overlap with existing contact @{}.\n' \
.format(self.vias[keys[insertIndex-1]][2]) ) .format(self.vias[keys[insertIndex-1]][2]) )
return False 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() self.vias[ contact.getX() ] = [ contact.getX()
, StackedVia( self.net , BigVia( self.net
, self.side.getLayerDepth(self.side.getHLayer()) , self.side.getLayerDepth(self.side.getHLayer())
, contact.getX() , contact.getX()
, self.axis , self.axis
, contact.getWidth() - DbU.fromLambda(1.0) , viaWidth
, self.side.hRailWidth - DbU.fromLambda(1.0) , viaHeight
) )
, contact ] , contact ]
trace( 550, '\tADD "{}" contact "{}" @ [{} {}]\n' \ trace( 550, '\tADD "{}" contact "{}" @ [{} {}]\n' \
.format( contact.getNet().getName() .format( contact.getNet().getName()
@ -164,13 +173,13 @@ class HorizontalRail ( Rail ):
if via[1].getNet() != via[2].getNet(): continue if via[1].getNet() != via[2].getNet(): continue
via[1].mergeDepth( self.side.getLayerDepth(self.side.getVLayer()) ) via[1].mergeDepth( self.side.getLayerDepth(self.side.getVLayer()) )
via[1].doLayout() via[1].doLayout()
Vertical.create( via[1].getVia( via[2].getLayer() ) Vertical.create( via[1].getPlate( via[2].getLayer() )
, via[2] , via[2]
, via[2].getLayer() , via[2].getLayer()
, via[2].getX() , via[2].getX()
, via[2].getWidth() , 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)): for i in range(1,len(railVias)):
h = Horizontal.create( railVias[i-1] h = Horizontal.create( railVias[i-1]
, railVias[i] , railVias[i]
@ -202,13 +211,13 @@ class VerticalRail ( Rail ):
for via in self.vias.values(): for via in self.vias.values():
if via[1].getNet() != via[2].getNet(): continue if via[1].getNet() != via[2].getNet(): continue
via[1].doLayout() via[1].doLayout()
Horizontal.create( via[1].getVia( via[2].getLayer() ) Horizontal.create( via[1].getPlate( via[2].getLayer() )
, via[2] , via[2]
, via[2].getLayer() , via[2].getLayer()
, via[2].getY() , via[2].getY()
, via[2].getHeight() , via[2].getHeight()
) )
railVias.append( via[1].getVia(self.side.getVLayer()) ) railVias.append( via[1].getPlate(self.side.getVLayer()) )
railVias.sort( key=methodcaller('getY') ) railVias.sort( key=methodcaller('getY') )
for i in range(1,len(railVias)): for i in range(1,len(railVias)):
Vertical.create( railVias[i-1] Vertical.create( railVias[i-1]
@ -253,14 +262,19 @@ class VerticalRail ( Rail ):
if self.vias[keys[insertIndex-1]][2].getBoundingBox().getYMax() >= contactBb.getYMin(): if self.vias[keys[insertIndex-1]][2].getBoundingBox().getYMax() >= contactBb.getYMin():
trace( 550, ',--', '\tReject {} intersect PREVIOUS\n'.format(contact) ) trace( 550, ',--', '\tReject {} intersect PREVIOUS\n'.format(contact) )
return False 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() self.vias[ contact.getY() ] = [ contact.getY()
, StackedVia( self.net , BigVia( self.net
, self.side.getLayerDepth(self.side.getVLayer()) , self.side.getLayerDepth(self.side.getVLayer())
, self.axis , self.axis
, contact.getY() , contact.getY()
, self.side.vRailWidth - DbU.fromLambda(1.0) , self.side.vRailWidth - DbU.fromLambda(1.0)
, contact.getHeight() - DbU.fromLambda(1.0) , contact.getHeight() - DbU.fromLambda(1.0)
) )
, contact ] , contact ]
trace(550, ',--' '\tADD {}\n'.format(contact) ) trace(550, ',--' '\tADD {}\n'.format(contact) )
self.vias[ contact.getY() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) ) self.vias[ contact.getY() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) )
@ -449,7 +463,7 @@ class VerticalSide ( Side ):
for rail in self.rails: for rail in self.rails:
for via in rail.vias.values(): for via in rail.vias.values():
if via[1].getNet() != via[2].getNet(): continue 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 routingGauge = self.corona.routingGauge
print( self.getOuterRail(0) ) print( self.getOuterRail(0) )
print( self.getOuterRail(0).vias.values() ) print( self.getOuterRail(0).vias.values() )