remove deprecated components
|
@ -1,65 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2020-2021, 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.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
"""
|
||||
This script hook the Block plugin inside GCT/Unicorn.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import helpers
|
||||
from helpers.io import ErrorMessage
|
||||
from helpers.io import WarningMessage
|
||||
from helpers.overlay import UpdateSession
|
||||
from helpers import trace
|
||||
import plugins
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import DbU
|
||||
from Hurricane import Box
|
||||
from Hurricane import Net
|
||||
from Hurricane import Cell
|
||||
from Hurricane import Instance
|
||||
from Hurricane import Transformation
|
||||
from plugins.alpha.block.block import Block
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Plugin hook functions, unicornHook:menus, ScritMain:call
|
||||
|
||||
def unicornHook ( **kw ):
|
||||
kw['beforeAction'] = 'misc.alpha'
|
||||
plugins.kwUnicornHook( 'misc.alpha.block'
|
||||
, 'Block P&&R'
|
||||
, 'Perform block-level placement'
|
||||
, sys.modules[__name__].__file__
|
||||
, **kw
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The mandatory function that Coriolis CGT/Unicorn will look for."""
|
||||
rvalue = True
|
||||
try:
|
||||
helpers.setTraceLevel( 550 )
|
||||
cell, editor = plugins.kwParseMain( **kw )
|
||||
block = Block.create( cell )
|
||||
if editor: block.setEditor( editor )
|
||||
rvalue = block.build()
|
||||
except Exception as e:
|
||||
helpers.io.catch( e )
|
||||
rvalue = False
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
return rvalue
|
|
@ -1,130 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2014-2021, 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/chip/vchannels.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import sys
|
||||
from Hurricane import DbU
|
||||
from Hurricane import Point
|
||||
from Hurricane import Transformation
|
||||
from Hurricane import Box
|
||||
from Hurricane import Interval
|
||||
from Hurricane import Path
|
||||
from Hurricane import Occurrence
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import Net
|
||||
from Hurricane import Contact
|
||||
from Hurricane import Horizontal
|
||||
from Hurricane import Vertical
|
||||
from Hurricane import Query
|
||||
import CRL
|
||||
import helpers
|
||||
from helpers import trace
|
||||
from helpers.io import ErrorMessage
|
||||
from helpers.io import WarningMessage
|
||||
from helpers.io import vprint
|
||||
from helpers import l, u, n
|
||||
import plugins
|
||||
import chip
|
||||
|
||||
|
||||
class VChannels ( object ):
|
||||
|
||||
def __init__ ( self, cell ):
|
||||
self.gauge = chip.Configuration.GaugeConf()
|
||||
self.cell = cell
|
||||
self.vchannels = [ ]
|
||||
|
||||
topAb = self.cell.getAbutmentBox()
|
||||
topTransf = Transformation()
|
||||
for occurrence in cell.getNonTerminalNetlistInstanceOccurrences():
|
||||
transf = occurrence.getPath().getTransformation()
|
||||
if transf != topTransf:
|
||||
raise ErrorMessage( 1, [ 'VChannels.__init__(): Transformation of non-terminal instances must be (0,0,ID),'
|
||||
, 'instead of %s.' % str(transf)
|
||||
, 'on %s' % str(occurrence) ] )
|
||||
|
||||
ab = occurrence.getEntity().getMasterCell().getAbutmentBox()
|
||||
if ab != topAb:
|
||||
raise ErrorMessage( 1, [ 'VChannels.__init__(): Abutment box of non-terminal instances must be equal to the top level %s.' % str(topAb)
|
||||
, 'on %s' % str(occurrence) ] )
|
||||
return
|
||||
|
||||
|
||||
def addChannelAt ( self, x, width ):
|
||||
xMin = self.cell.getAbutmentBox().getXMin()
|
||||
xMax = self.cell.getAbutmentBox().getXMax()
|
||||
if x < xMin or x >= xMax:
|
||||
print( ErrorMessage( 1, [ 'VChannels.addChannelAt(): Attempt to add a channel outside abutment box, ignored.'
|
||||
, '({} must be included in [{}..{}]'.format( DbU.getValueString(x)
|
||||
, DbU.getValueString(xMin)
|
||||
, DbU.getValueString(xMax) ) ] ))
|
||||
return False
|
||||
|
||||
for i in range(len(self.vchannels)):
|
||||
if self.vchannels[i][0] == x:
|
||||
print( ErrorMessage( 1, 'VChannels.addChannelAt(): Attempt to add a channel twice at position {}, ignored.' \
|
||||
.format(DbU.getValueString(x)) ))
|
||||
return False
|
||||
if self.vchannels[i][0] > x:
|
||||
self.vchannels.insert( i, (x,width) )
|
||||
return True
|
||||
|
||||
self.vchannels.append( (x,width) )
|
||||
return True
|
||||
|
||||
|
||||
def getDeltaWidth ( self ):
|
||||
deltaWidth = 0
|
||||
for x,w in self.vchannels: deltaWidth += w
|
||||
return deltaWidth
|
||||
|
||||
|
||||
def expandChannels ( self ):
|
||||
UpdateSession.open()
|
||||
|
||||
dw = self.getDeltaWidth()
|
||||
|
||||
ab = self.cell.getAbutmentBox()
|
||||
ab.inflate( 0, 0, dw, 0 )
|
||||
self.cell.setAbutmentBox( ab )
|
||||
|
||||
for occurrence in self.cell.getNonTerminalNetlistInstanceOccurrences():
|
||||
masterCell = occurrence.getEntity().getMasterCell()
|
||||
ab = masterCell.getAbutmentBox()
|
||||
ab.inflate( 0, 0, dw, 0 )
|
||||
masterCell.setAbutmentBox( ab )
|
||||
|
||||
for occurrence in self.cell.getTerminalNetlistInstanceOccurrences():
|
||||
instance = occurrence.getEntity()
|
||||
transf = occurrence.getPath().getTransformation()
|
||||
instance.getTransformation().applyOn( transf )
|
||||
xcenter = transf.getTx() + instance.getMasterCell().getAbutmentBox().getXCenter()
|
||||
|
||||
xshift = 0
|
||||
for x,w in self.vchannels:
|
||||
if x < xcenter: xshift += w
|
||||
else: break
|
||||
|
||||
if xshift:
|
||||
baseTransf = instance.getTransformation()
|
||||
baseTransf = Transformation( baseTransf.getTx() + xshift
|
||||
, baseTransf.getTy()
|
||||
, baseTransf.getOrientation() )
|
||||
instance.setTransformation( baseTransf )
|
||||
|
||||
UpdateSession.close()
|
||||
|
||||
spaceMargin = (float(dw) * 100.0) / float(ab.getWidth())
|
||||
vprint( 1, ' - V-Channels space margin: {}%%.'.format(spaceMargin) )
|
||||
return
|
|
@ -1,51 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2014-2021, 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/chip/__init__.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from helpers.io import WarningMessage
|
||||
|
||||
|
||||
# Common constants used through all <chip> modules.
|
||||
|
||||
# For Corona's sides.
|
||||
North = 0x0001
|
||||
South = 0x0002
|
||||
East = 0x0004
|
||||
West = 0x0008
|
||||
|
||||
# For Corona's corners.
|
||||
SouthWest = South|West
|
||||
SouthEast = South|East
|
||||
NorthWest = North|West
|
||||
NorthEast = North|East
|
||||
|
||||
# For rounding functions.
|
||||
Superior = 0x0010
|
||||
Inferior = 0x0020
|
||||
Inwards = 0x0040
|
||||
OnHorizontalPitch = 0x0080
|
||||
OnVerticalPitch = 0x0100
|
||||
|
||||
|
||||
def importConstants ( symbols ):
|
||||
if not isinstance(symbols,dict):
|
||||
print( WarningMessage( 'plugins.chip.__init__.importConstants(), argument is not a symbol table.' ))
|
||||
return
|
||||
|
||||
for symbol in globals().items():
|
||||
if isinstance(symbol[1],int):
|
||||
if not symbol[0] in symbols:
|
||||
symbols[ symbol[0] ] = symbol[1]
|
||||
|
||||
return
|
|
@ -1,632 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2014-2021, 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/chip/blockcorona.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import bisect
|
||||
from operator import methodcaller
|
||||
import Cfg
|
||||
from Hurricane import DbU
|
||||
from Hurricane import Point
|
||||
from Hurricane import Interval
|
||||
from Hurricane import Box
|
||||
from Hurricane import Transformation
|
||||
from Hurricane import Path
|
||||
from Hurricane import Occurrence
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import Net
|
||||
from Hurricane import Contact
|
||||
from Hurricane import Horizontal
|
||||
from Hurricane import Vertical
|
||||
from Hurricane import Pad
|
||||
import CRL
|
||||
from CRL import RoutingLayerGauge
|
||||
from helpers import trace
|
||||
from helpers.io import ErrorMessage
|
||||
from helpers.io import WarningMessage
|
||||
import plugins
|
||||
from plugins import StackedVia
|
||||
import plugins.chip
|
||||
|
||||
|
||||
plugins.chip.importConstants( globals() )
|
||||
|
||||
|
||||
class IntervalSet ( object ):
|
||||
|
||||
def __init__ ( self ):
|
||||
self.chunks = []
|
||||
return
|
||||
|
||||
def merge ( self, min, max ):
|
||||
toMerge = Interval( min, max )
|
||||
imerge = len(self.chunks)
|
||||
length = len(self.chunks)
|
||||
i = 0
|
||||
|
||||
while i < length:
|
||||
if imerge >= length:
|
||||
if toMerge.getVMax() < self.chunks[i].getVMin():
|
||||
self.chunks.insert( i, toMerge )
|
||||
length += 1
|
||||
imerge = 0
|
||||
break
|
||||
if toMerge.intersect(self.chunks[i]):
|
||||
imerge = i
|
||||
self.chunks[imerge].merge( toMerge )
|
||||
else:
|
||||
if toMerge.getVMax() >= self.chunks[i].getVMin():
|
||||
self.chunks[imerge].merge( self.chunks[i] )
|
||||
del self.chunks[ i ]
|
||||
length -= 1
|
||||
continue
|
||||
else:
|
||||
break
|
||||
i += 1
|
||||
|
||||
if imerge >= length:
|
||||
self.chunks.insert( length, toMerge )
|
||||
return
|
||||
|
||||
|
||||
class Rail ( object ):
|
||||
|
||||
def __init__ ( self, side, order, axis ):
|
||||
self.side = side
|
||||
self.order = order
|
||||
self.axis = axis
|
||||
self.vias = { } # Key:pos Element:[pos,railContact,blockContact]
|
||||
return
|
||||
|
||||
@property
|
||||
def net ( self ): return self.side.getRailNet(self.order)
|
||||
|
||||
|
||||
class HorizontalRail ( Rail ):
|
||||
|
||||
def __init__ ( self, side, order, axis ):
|
||||
Rail.__init__( self, side, order, axis )
|
||||
return
|
||||
|
||||
def connect ( self, contact ):
|
||||
contactBb = contact.getBoundingBox()
|
||||
if contactBb.getXMin() < self.side.innerBb.getXMin() \
|
||||
or contactBb.getXMax() > self.side.innerBb.getXMax():
|
||||
raise ErrorMessage( 1, [ '%s is outside rail/corona X range,' % str(contact)
|
||||
, 'power pad is likely to be to far off west or east.'
|
||||
, '(core:%s)' % str(self.side.innerBb) ] )
|
||||
|
||||
#print( ' HorizontalRail.connect() net:{} contact:{}'.format(self.net.getName(),contact) )
|
||||
#if self.net != contact.getNet(): return False
|
||||
if contact.getX() in self.vias: return False
|
||||
|
||||
keys = list( self.vias.keys() )
|
||||
keys.sort()
|
||||
insertIndex = bisect.bisect_left( keys, contact.getX() )
|
||||
|
||||
if len(keys) > 0:
|
||||
if insertIndex < len(keys):
|
||||
insertPosition = keys[ insertIndex ]
|
||||
if contactBb.getXMax() >= self.vias[insertPosition][2].getBoundingBox().getXMin():
|
||||
#print( 'Reject contact {} intersect NEXT'.format(contact) )
|
||||
return False
|
||||
if insertIndex > 0:
|
||||
if self.vias[keys[insertIndex-1]][2].getBoundingBox().getXMax() >= contactBb.getXMin():
|
||||
#print( 'Reject contact {} intersect PREVIOUS'.format(contact) )
|
||||
return False
|
||||
|
||||
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)
|
||||
)
|
||||
, contact ]
|
||||
trace( 550, '\tADD "%s" contact "%s" @ [%s %s]\n'
|
||||
% ( contact.getNet().getName()
|
||||
, contact.getLayer().getName()
|
||||
, DbU.getValueString(contact.getX())
|
||||
, DbU.getValueString(self.axis)) )
|
||||
self.vias[ contact.getX() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) )
|
||||
return True
|
||||
|
||||
def doLayout ( self ):
|
||||
#print( 'HorizontalRail[{}] @{}'.format(self.order,DbU.toLambda(self.axis)) )
|
||||
|
||||
railVias = [ self.side.corner0(self.order)
|
||||
, self.side.corner1(self.order) ]
|
||||
|
||||
for via in self.vias.values():
|
||||
if via[1].getNet() != via[2].getNet(): continue
|
||||
|
||||
via[1].mergeDepth( self.side.getLayerDepth(self.side.getVLayer()) )
|
||||
via[1].doLayout()
|
||||
#print( ' Connect:', via[2], via[1].getVia( via[2].getLayer() ))
|
||||
Vertical.create( via[1].getVia( via[2].getLayer() )
|
||||
, via[2]
|
||||
, via[2].getLayer()
|
||||
, via[2].getX()
|
||||
, via[2].getWidth()
|
||||
)
|
||||
#print( via[1]._vias, '[{} {}]' % ( via[1]._bottomDepth, via[1]._topDepth ))
|
||||
#print( via[1], self.side.getVLayer(), via[1].getVia( self.side.getVLayer() ))
|
||||
railVias.append( via[1].getVia( self.side.getVLayer()) )
|
||||
|
||||
for i in range(1,len(railVias)):
|
||||
Horizontal.create( railVias[i-1]
|
||||
, railVias[i]
|
||||
, self.side.getHLayer()
|
||||
, self.axis
|
||||
, self.side.hRailWidth
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
class VerticalRail ( Rail ):
|
||||
|
||||
def __init__ ( self, side, order, axis ):
|
||||
Rail.__init__( self, side, order, axis )
|
||||
return
|
||||
|
||||
def doLayout ( self ):
|
||||
#print( 'VerticalRail[{}] @{}'.format(self.order,DbU.toLambda(self.axis)))
|
||||
|
||||
railVias = [ self.side.corner0(self.order)
|
||||
, self.side.corner1(self.order) ]
|
||||
|
||||
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() )
|
||||
, via[2]
|
||||
, via[2].getLayer()
|
||||
, via[2].getY()
|
||||
, via[2].getHeight()
|
||||
)
|
||||
railVias.append( via[1].getVia(self.side.getVLayer()) )
|
||||
|
||||
railVias.sort( key=methodcaller('getY') )
|
||||
|
||||
for i in range(1,len(railVias)):
|
||||
Vertical.create( railVias[i-1]
|
||||
, railVias[i]
|
||||
, self.side.getVLayer()
|
||||
, self.axis
|
||||
, self.side.vRailWidth
|
||||
)
|
||||
|
||||
#routingGauge = CRL.AllianceFramework.get().getRoutingGauge()
|
||||
#for depth in range(self.side.verticalDepth-2,self.vias.values()[0][1]._bottomDepth,-2):
|
||||
# blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
|
||||
# pitch = routingGauge.getLayerPitch(depth)
|
||||
#
|
||||
# for i in range(1,len(railVias)):
|
||||
# Vertical.create( self.side.blockageNet
|
||||
# , blockageLayer
|
||||
# , self.axis
|
||||
# , self.side.vRailWidth + 2*pitch
|
||||
# , railVias[i-1].getBoundingBox().getYMax() + pitch
|
||||
# , railVias[i ].getBoundingBox().getYMin() - pitch
|
||||
# )
|
||||
|
||||
return
|
||||
|
||||
def connect ( self, contact ):
|
||||
contactBb = contact.getBoundingBox()
|
||||
if contactBb.getYMin() < self.side.innerBb.getYMin() \
|
||||
or contactBb.getYMax() > self.side.innerBb.getYMax():
|
||||
raise ErrorMessage( 1, [ '%s is outside rail/corona Y range' % str(contact)
|
||||
, 'power pad is likely to be to far off north or south.'
|
||||
, '(core:%s)' % str(self.side.innerBb) ] )
|
||||
|
||||
#if self.net != contact.getNet(): return False
|
||||
if contact.getY() in self.vias: return False
|
||||
|
||||
trace( 550, ',+', '\tVerticalRail.connect() [%s] @%d\n' % (self.order,DbU.toLambda(self.axis)) )
|
||||
trace( 550, contact )
|
||||
|
||||
keys = list( self.vias.keys() )
|
||||
keys.sort()
|
||||
insertIndex = bisect.bisect_left( keys, contact.getY() )
|
||||
trace( 550, ',+', '\tkeys:' )
|
||||
for key in keys:
|
||||
trace( 550, ' %d' % DbU.toLambda(key) )
|
||||
trace( 550, '\n' )
|
||||
|
||||
if len(keys) > 0:
|
||||
if insertIndex < len(keys):
|
||||
insertPosition = keys[ insertIndex ]
|
||||
trace( 550, '\tinsertIndex:%d' % insertIndex )
|
||||
trace( 550, '\tCheck NEXT contactBb:%s via:%s\n' \
|
||||
% ( contactBb
|
||||
, self.vias[insertPosition][2].getBoundingBox()) )
|
||||
if contactBb.getYMax() >= self.vias[insertPosition][2].getBoundingBox().getYMin():
|
||||
trace( 550, ',--', '\tReject %s intersect NEXT\n' % contact )
|
||||
return False
|
||||
if insertIndex > 0:
|
||||
trace( 550, '\tcheck PREVIOUS contactBb:%s via:%s\n' \
|
||||
% ( contactBb
|
||||
, self.vias[keys[insertIndex-1]][2].getBoundingBox()) )
|
||||
if self.vias[keys[insertIndex-1]][2].getBoundingBox().getYMax() >= contactBb.getYMin():
|
||||
trace( 550, ',--', '\tReject %s intersect PREVIOUS\n' % contact )
|
||||
return False
|
||||
|
||||
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)
|
||||
)
|
||||
, contact ]
|
||||
trace(550, ',--' '\tADD %s\n' % contact )
|
||||
self.vias[ contact.getY() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) )
|
||||
return True
|
||||
|
||||
|
||||
class Side ( object ):
|
||||
|
||||
def __init__ ( self, corona ):
|
||||
self.corona = corona
|
||||
return
|
||||
|
||||
@property
|
||||
def railsNb ( self ): return self.corona.railsNb
|
||||
@property
|
||||
def innerBb ( self ): return self.corona.innerBb
|
||||
@property
|
||||
def hRailWidth ( self ): return self.corona.hRailWidth
|
||||
@property
|
||||
def hRailSpace ( self ): return self.corona.hRailSpace
|
||||
@property
|
||||
def vRailWidth ( self ): return self.corona.vRailWidth
|
||||
@property
|
||||
def vRailSpace ( self ): return self.corona.vRailSpace
|
||||
@property
|
||||
def corners ( self ): return self.corona.corners
|
||||
@property
|
||||
def horizontalDepth ( self ): return self.corona.horizontalDepth
|
||||
@property
|
||||
def verticalDepth ( self ): return self.corona.verticalDepth
|
||||
@property
|
||||
def blockageNet ( self ): return self.corona.blockageNet
|
||||
|
||||
def getLayerDepth ( self, metal ): return self.corona.getLayerDepth(metal)
|
||||
def getRail ( self, i ): return self.rails[i]
|
||||
def getRailNet ( self, i ): return self.corona.getRailNet(i)
|
||||
def getHLayer ( self ): return self.corona.getHLayer()
|
||||
def getVLayer ( self ): return self.corona.getVLayer()
|
||||
|
||||
def getRailAxis ( self, i ):
|
||||
raise ErrorMessage( 1, 'Side.getRailAxis(): Must never be called on base class.' )
|
||||
|
||||
def getInnerRail ( self, i ):
|
||||
if i >= len(self.rails):
|
||||
raise ErrorMessage( 1, 'Side.getInnerRail(): no rail %d (only: %d).' % (i,len(self.rails)) )
|
||||
return self.rails[i]
|
||||
|
||||
def getOuterRail ( self, i ):
|
||||
if i >= len(self.rails):
|
||||
raise ErrorMessage( 1, 'Side.getOuterRail(): no rail %d (only: %d).' % (i,len(self.rails)) )
|
||||
return self.rails[-(i+1)]
|
||||
|
||||
def connect ( self, blockSide ):
|
||||
for terminal in blockSide.terminals:
|
||||
for rail in self.rails:
|
||||
rail.connect( terminal[1] )
|
||||
return
|
||||
|
||||
def connectPads ( self, padSide ):
|
||||
for contact in padSide.pins:
|
||||
if not contact.getNet().isSupply() and not contact.getNet().isClock(): continue
|
||||
#print( ' Connect to [-{}] @{}'.format(0, DbU.toLambda(self.getOuterRail(0).axis)))
|
||||
self.getOuterRail( 0 ).connect( contact )
|
||||
|
||||
halfRails = (len(self.rails)-1)//2
|
||||
trace( 550, 'halfRails:%i' % halfRails )
|
||||
for contact in padSide.pins:
|
||||
if not contact.getNet().isSupply() and not contact.getNet().isClock(): continue
|
||||
trace( 550, ',+', '\tConnect pad contact %s\n' % contact )
|
||||
for i in range(halfRails):
|
||||
trace( 550, '\tConnect to [-%i] @%d\n' % (i+1, DbU.toLambda(self.getOuterRail(i+1).axis)) )
|
||||
self.getOuterRail(i+1).connect( contact )
|
||||
trace( 550, '-' )
|
||||
return
|
||||
|
||||
def doLayout ( self ):
|
||||
for rail in self.rails: rail.doLayout()
|
||||
return
|
||||
|
||||
|
||||
class HorizontalSide ( Side ):
|
||||
|
||||
def __init__ ( self, corona ):
|
||||
Side.__init__( self, corona )
|
||||
|
||||
self.rails = []
|
||||
for i in range(self.railsNb):
|
||||
self.rails.append( HorizontalRail(self,i,self.getRailAxis(i)) )
|
||||
#print( ' Rail [{}] @{}'.format(i,DbU.toLambda(self._rails[-1].axis)))
|
||||
return
|
||||
|
||||
|
||||
class SouthSide ( HorizontalSide ):
|
||||
|
||||
def __init__ ( self, corona ):
|
||||
HorizontalSide.__init__( self, corona )
|
||||
return
|
||||
|
||||
def getRailAxis ( self, i ):
|
||||
return self.innerBb.getYMin() - self.hRailWidth//2 - self.hRailSpace \
|
||||
- i*(self.hRailWidth + self.hRailSpace)
|
||||
|
||||
def corner0 ( self, i ): return self.corners[SouthWest][i]
|
||||
def corner1 ( self, i ): return self.corners[SouthEast][i]
|
||||
|
||||
|
||||
class NorthSide ( HorizontalSide ):
|
||||
|
||||
def __init__ ( self, corona ):
|
||||
HorizontalSide.__init__( self, corona )
|
||||
return
|
||||
|
||||
def getRailAxis ( self, i ):
|
||||
return self.innerBb.getYMax() + self.hRailWidth//2 + self.hRailSpace \
|
||||
+ i*(self.hRailWidth + self.hRailSpace)
|
||||
|
||||
def corner0 ( self, i ): return self.corners[NorthWest][i]
|
||||
def corner1 ( self, i ): return self.corners[NorthEast][i]
|
||||
|
||||
|
||||
class VerticalSide ( Side ):
|
||||
|
||||
def __init__ ( self, corona ):
|
||||
Side.__init__( self, corona )
|
||||
|
||||
self.rails = []
|
||||
for i in range(self.railsNb):
|
||||
self.rails.append( VerticalRail(self,i,self.getRailAxis(i)) )
|
||||
return
|
||||
|
||||
def addBlockages ( self, sideXMin, sideXMax ):
|
||||
spans = IntervalSet()
|
||||
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 )
|
||||
|
||||
routingGauge = self.corona.routingGauge
|
||||
if len(self.getInnerRail(0).vias):
|
||||
for depth in range(next(iter(self.getInnerRail(0).vias.values()))[1].bottomDepth
|
||||
,next(iter(self.getInnerRail(0).vias.values()))[1].topDepth ):
|
||||
blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
|
||||
pitch = routingGauge.getLayerPitch(depth)
|
||||
|
||||
for chunk in spans.chunks:
|
||||
Horizontal.create( self.blockageNet
|
||||
, blockageLayer
|
||||
, (chunk.getVMax() + chunk.getVMin())//2
|
||||
, chunk.getVMax() - chunk.getVMin() + pitch*2
|
||||
, sideXMin
|
||||
, sideXMax
|
||||
)
|
||||
|
||||
depth -= 2
|
||||
if depth > 0:
|
||||
blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
|
||||
pitch = routingGauge.getLayerPitch(depth)
|
||||
|
||||
for chunk in spans.chunks:
|
||||
Horizontal.create( self.blockageNet
|
||||
, blockageLayer
|
||||
, (chunk.getVMax() + chunk.getVMin())//2
|
||||
, chunk.getVMax() - chunk.getVMin() + pitch*2
|
||||
, sideXMin
|
||||
, sideXMax
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
class WestSide ( VerticalSide ):
|
||||
|
||||
def __init__ ( self, corona ):
|
||||
VerticalSide.__init__( self, corona )
|
||||
return
|
||||
|
||||
def getRailAxis ( self, i ):
|
||||
return self.innerBb.getXMin() - self.vRailWidth//2 - self.vRailSpace \
|
||||
- i*(self.vRailWidth + self.vRailSpace)
|
||||
|
||||
def corner0 ( self, i ): return self.corners[SouthWest][i]
|
||||
def corner1 ( self, i ): return self.corners[NorthWest ][i]
|
||||
|
||||
def addBlockages ( self ):
|
||||
sideXMin = self.getOuterRail(0).axis - self.vRailWidth
|
||||
sideXMax = self.getInnerRail(0).axis + self.vRailWidth
|
||||
VerticalSide.addBlockages( self, sideXMin, sideXMax )
|
||||
return
|
||||
|
||||
|
||||
class EastSide ( VerticalSide ):
|
||||
|
||||
def __init__ ( self, corona ):
|
||||
VerticalSide.__init__( self, corona )
|
||||
return
|
||||
|
||||
def getRailAxis ( self, i ):
|
||||
return self.innerBb.getXMax() + self.vRailWidth//2 + self.vRailSpace \
|
||||
+ i*(self.vRailWidth + self.vRailSpace)
|
||||
|
||||
def corner0 ( self, i ): return self.corners[SouthEast][i]
|
||||
def corner1 ( self, i ): return self.corners[NorthEast ][i]
|
||||
|
||||
def addBlockages ( self ):
|
||||
sideXMin = self.getInnerRail(0).axis - self.vRailWidth
|
||||
sideXMax = self.getOuterRail(0).axis + self.vRailWidth
|
||||
VerticalSide.addBlockages( self, sideXMin, sideXMax )
|
||||
return
|
||||
|
||||
|
||||
class Corona ( object ):
|
||||
|
||||
def __init__ ( self, block ):
|
||||
self.block = block
|
||||
self.railsNb = Cfg.getParamInt('chip.block.rails.count' ).asInt()
|
||||
self.hRailWidth = Cfg.getParamInt('chip.block.rails.hWidth' ).asInt()
|
||||
self.vRailWidth = Cfg.getParamInt('chip.block.rails.vWidth' ).asInt()
|
||||
self.hRailSpace = Cfg.getParamInt('chip.block.rails.hSpacing').asInt()
|
||||
self.vRailSpace = Cfg.getParamInt('chip.block.rails.vSpacing').asInt()
|
||||
|
||||
self.innerBb = self.block.bb
|
||||
self.block.path.getTransformation().applyOn( self.innerBb )
|
||||
self.innerBb.inflate( self.hRailSpace//2, self.vRailSpace//2 )
|
||||
|
||||
if not self.conf.useClockTree: self.railsNb -= 1
|
||||
|
||||
self.southSide = SouthSide( self )
|
||||
self.northSide = NorthSide( self )
|
||||
self.westSide = WestSide ( self )
|
||||
self.eastSide = EastSide ( self )
|
||||
|
||||
return
|
||||
|
||||
@property
|
||||
def conf ( self ): return self.block.conf
|
||||
@property
|
||||
def routingGauge ( self ): return self.conf.gaugeConf.routingGauge
|
||||
@property
|
||||
def topLayerDepth ( self ): return self.conf.gaugeConf.topLayerDepth
|
||||
@property
|
||||
def horizontalDepth ( self ): return self.conf.gaugeConf.horizontalDepth
|
||||
@property
|
||||
def verticalDepth ( self ): return self.conf.gaugeConf.verticalDepth
|
||||
@property
|
||||
def blockageNet ( self ): return self.conf.blockageNet
|
||||
|
||||
def getLayerDepth ( self, metal ):
|
||||
return self.conf.gaugeConf.routingGauge.getLayerDepth( metal )
|
||||
|
||||
def getRailNet ( self, i ):
|
||||
if self.conf.useClockTree and i == self.railsNb-1: return self.conf.coronaCk
|
||||
if i % 2: return self.conf.coronaVss
|
||||
return self.conf.coronaVdd
|
||||
|
||||
def getHLayer ( self ):
|
||||
return self.routingGauge.getLayerGauge( self.horizontalDepth ).getLayer()
|
||||
|
||||
def getVLayer ( self ):
|
||||
return self.routingGauge.getLayerGauge( self.verticalDepth ).getLayer()
|
||||
|
||||
def connectBlock ( self ):
|
||||
for plane in self.block.planes.values():
|
||||
for side in plane.sides.values():
|
||||
self.southSide.connect( side[South] )
|
||||
self.northSide.connect( side[North] )
|
||||
self.westSide .connect( side[West ] )
|
||||
self.eastSide .connect( side[East ] )
|
||||
return
|
||||
|
||||
def connectPads ( self, padsCorona ):
|
||||
self.southSide.connectPads( padsCorona.southSide )
|
||||
self.northSide.connectPads( padsCorona.northSide )
|
||||
self.eastSide .connectPads( padsCorona.eastSide )
|
||||
self.westSide .connectPads( padsCorona.westSide )
|
||||
return
|
||||
|
||||
def doLayout ( self ):
|
||||
self.corners = { SouthWest : []
|
||||
, SouthEast : []
|
||||
, NorthWest : []
|
||||
, NorthEast : []
|
||||
}
|
||||
|
||||
contactDepth = self.horizontalDepth
|
||||
if self.horizontalDepth > self.verticalDepth:
|
||||
contactDepth = self.verticalDepth
|
||||
|
||||
UpdateSession.open()
|
||||
blBox = Box()
|
||||
brBox = Box()
|
||||
tlBox = Box()
|
||||
trBox = Box()
|
||||
|
||||
for i in range(self.railsNb):
|
||||
xBL = self.westSide .getRail(i).axis
|
||||
yBL = self.southSide.getRail(i).axis
|
||||
xTR = self.eastSide .getRail(i).axis
|
||||
yTR = self.northSide.getRail(i).axis
|
||||
net = self.getRailNet( i )
|
||||
|
||||
blBox.merge( xBL, yBL )
|
||||
brBox.merge( xTR, yBL )
|
||||
tlBox.merge( xBL, yTR )
|
||||
trBox.merge( xTR, yTR )
|
||||
|
||||
self.routingGauge.getContactLayer(contactDepth)
|
||||
self.corners[SouthWest].append(
|
||||
Contact.create( net
|
||||
, self.routingGauge.getContactLayer(contactDepth)
|
||||
, xBL, yBL
|
||||
, self.hRailWidth
|
||||
, self.vRailWidth
|
||||
) )
|
||||
self.corners[NorthWest].append(
|
||||
Contact.create( net
|
||||
, self.routingGauge.getContactLayer(contactDepth)
|
||||
, xBL, yTR
|
||||
, self.hRailWidth
|
||||
, self.vRailWidth
|
||||
) )
|
||||
self.corners[SouthEast].append(
|
||||
Contact.create( net
|
||||
, self.routingGauge.getContactLayer(contactDepth)
|
||||
, xTR, yBL
|
||||
, self.hRailWidth
|
||||
, self.vRailWidth
|
||||
) )
|
||||
self.corners[NorthEast].append(
|
||||
Contact.create( net
|
||||
, self.routingGauge.getContactLayer(contactDepth)
|
||||
, xTR, yTR
|
||||
, self.hRailWidth
|
||||
, self.vRailWidth
|
||||
) )
|
||||
|
||||
self.southSide.doLayout()
|
||||
self.northSide.doLayout()
|
||||
self.westSide .doLayout()
|
||||
self.eastSide .doLayout()
|
||||
|
||||
self.westSide.addBlockages()
|
||||
self.eastSide.addBlockages()
|
||||
|
||||
blBox.inflate( self.hRailWidth, self.vRailWidth )
|
||||
brBox.inflate( self.hRailWidth, self.vRailWidth )
|
||||
tlBox.inflate( self.hRailWidth, self.vRailWidth )
|
||||
trBox.inflate( self.hRailWidth, self.vRailWidth )
|
||||
|
||||
for depth in range( 1, self.conf.gaugeConf.topLayerDepth + 1 ):
|
||||
blockageLayer = self.routingGauge.getRoutingLayer(depth).getBlockageLayer()
|
||||
|
||||
Pad.create( self.blockageNet, blockageLayer, blBox )
|
||||
Pad.create( self.blockageNet, blockageLayer, brBox )
|
||||
Pad.create( self.blockageNet, blockageLayer, tlBox )
|
||||
Pad.create( self.blockageNet, blockageLayer, trBox )
|
||||
|
||||
UpdateSession.close()
|
||||
return
|
|
@ -1,282 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2014-2021, 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/chip/blockpower.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import sys
|
||||
from Hurricane import DbU, Point, Transformation, Box, Interval, \
|
||||
Path, Occurrence, UpdateSession, Net, \
|
||||
Contact, Horizontal, Vertical, Query
|
||||
import CRL
|
||||
import helpers
|
||||
from helpers import trace
|
||||
from helpers.io import ErrorMessage, WarningMessage
|
||||
import plugins
|
||||
import plugins.chip
|
||||
|
||||
plugins.chip.importConstants( globals() )
|
||||
|
||||
|
||||
class Side ( object ):
|
||||
|
||||
def __init__ ( self, block, side, net, metal ):
|
||||
self.block = block
|
||||
self.side = side
|
||||
self.net = net
|
||||
self.metal = metal
|
||||
self.deltaWidth = metal.getExtentionWidth()*2
|
||||
self.terminals = [ ]
|
||||
return
|
||||
|
||||
def addTerminal ( self, position, width ):
|
||||
toMerge = Interval( position-width//2, position+width//2 )
|
||||
|
||||
length = len(self.terminals)
|
||||
imerge = length
|
||||
ichunk = 0
|
||||
|
||||
while ichunk < length:
|
||||
if imerge == length:
|
||||
if toMerge.getVMax() < self.terminals[ichunk][0].getVMin():
|
||||
self.terminals.insert( ichunk, [ toMerge, None ] )
|
||||
imerge = ichunk
|
||||
length += 1
|
||||
break
|
||||
|
||||
if toMerge.intersect(self.terminals[ichunk][0]):
|
||||
imerge = ichunk
|
||||
self.terminals[ichunk][0].merge( toMerge )
|
||||
else:
|
||||
if toMerge.getVMax() >= self.terminals[ichunk][0].getVMin():
|
||||
self.terminals[imerge][0].merge( self.terminals[ichunk][0] )
|
||||
del self.terminals[ichunk]
|
||||
length -= 1
|
||||
continue
|
||||
else:
|
||||
break
|
||||
ichunk += 1
|
||||
|
||||
if ichunk == length:
|
||||
self.terminals.append( [ toMerge, None ] )
|
||||
|
||||
return
|
||||
|
||||
def doLayout ( self ):
|
||||
if self.side == West:
|
||||
width = 0
|
||||
x = self.block.bb.getXMin()
|
||||
elif self.side == East:
|
||||
width = 0
|
||||
x = self.block.bb.getXMax()
|
||||
elif self.side == South:
|
||||
height = 0
|
||||
y = self.block.bb.getYMin()
|
||||
elif self.side == North:
|
||||
height = 0
|
||||
y = self.block.bb.getYMax()
|
||||
|
||||
minWidth = DbU.fromLambda( 6.0 )
|
||||
for terminal in self.terminals:
|
||||
if self.side == West or self.side == East:
|
||||
center = Point( x, terminal[0].getCenter() )
|
||||
height = terminal[0].getSize() - self.deltaWidth
|
||||
if height < minWidth: height = minWidth
|
||||
elif self.side == North or self.side == South:
|
||||
center = Point( terminal[0].getCenter(), y )
|
||||
width = terminal[0].getSize() - self.deltaWidth
|
||||
if width < minWidth: width = minWidth
|
||||
|
||||
self.block.path.getTransformation().applyOn( center )
|
||||
|
||||
contact = Contact.create( self.net, self.metal, center.getX(), center.getY(), width, height )
|
||||
terminal[ 1 ] = contact
|
||||
return
|
||||
|
||||
|
||||
class Plane ( object ):
|
||||
|
||||
Horizontal = 1
|
||||
Vertical = 2
|
||||
|
||||
def __init__ ( self, block, metal ):
|
||||
self.block = block
|
||||
self.metal = metal
|
||||
self.sides = { }
|
||||
return
|
||||
|
||||
def addTerminal ( self, net, direction, bb ):
|
||||
if not net in self.sides:
|
||||
self.sides[ net ] = { North : Side(self.block,North,net,self.metal)
|
||||
, South : Side(self.block,South,net,self.metal)
|
||||
, East : Side(self.block,East ,net,self.metal)
|
||||
, West : Side(self.block,West ,net,self.metal)
|
||||
}
|
||||
sides = self.sides[ net ]
|
||||
trace( 550, '\tPlane.addTerminal() net={} bb={} direction={}\n' \
|
||||
.format( net.getName(), bb, direction ))
|
||||
|
||||
if direction == Plane.Horizontal:
|
||||
if bb.getXMin() <= self.block.bb.getXMin():
|
||||
sides[West].addTerminal( bb.getCenter().getY(), bb.getHeight() )
|
||||
if bb.getXMax() >= self.block.bb.getXMax():
|
||||
sides[East].addTerminal( bb.getCenter().getY(), bb.getHeight() )
|
||||
|
||||
if direction == Plane.Vertical:
|
||||
if bb.getYMin() <= self.block.bb.getYMin():
|
||||
sides[South].addTerminal( bb.getCenter().getX(), bb.getWidth() )
|
||||
if bb.getYMax() >= self.block.bb.getYMax():
|
||||
sides[North].addTerminal( bb.getCenter().getX(), bb.getWidth() )
|
||||
return
|
||||
|
||||
def doLayout ( self ):
|
||||
for sidesOfNet in self.sides.values():
|
||||
for side in sidesOfNet.values():
|
||||
side.doLayout()
|
||||
return
|
||||
|
||||
|
||||
|
||||
class GoCb ( object ):
|
||||
|
||||
def __init__ ( self, block ):
|
||||
self.block = block
|
||||
return
|
||||
|
||||
def __call__ ( self, query, go ):
|
||||
direction = None
|
||||
if isinstance(go,Horizontal): direction = Plane.Horizontal
|
||||
if isinstance(go,Vertical): direction = Plane.Vertical
|
||||
if not direction: return
|
||||
|
||||
rootNet = None
|
||||
if go.getNet().getType() == int(Net.Type.POWER): rootNet = self.block.conf.coronaVdd
|
||||
if go.getNet().getType() == int(Net.Type.GROUND): rootNet = self.block.conf.coronaVss
|
||||
if not rootNet: return
|
||||
|
||||
if self.block.activePlane:
|
||||
bb = go.getBoundingBox( self.block.activePlane.metal.getBasicLayer() )
|
||||
query.getPath().getTransformation().applyOn( bb )
|
||||
self.block.activePlane.addTerminal( rootNet, direction, bb )
|
||||
else:
|
||||
print( WarningMessage( 'BlockPower.GoCb() callback called without an active plane.' ))
|
||||
return
|
||||
|
||||
|
||||
class Block ( object ):
|
||||
|
||||
def __init__ ( self, conf ):
|
||||
self.conf = conf
|
||||
self.path = Path( self.conf.icore )
|
||||
self.block = self.path.getTailInstance().getMasterCell()
|
||||
self.bb = self.block.getAbutmentBox()
|
||||
self.planes = { }
|
||||
self.activePlane = None
|
||||
|
||||
for layerGauge in self.conf.gaugeConf.routingGauge.getLayerGauges():
|
||||
self.planes[ layerGauge.getLayer().getName() ] = Plane( self, layerGauge.getLayer() )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def connectPower ( self ):
|
||||
if not self.conf.coronaVdd or not self.conf.coronaVss:
|
||||
raise ErrorMessage( 1, 'Cannot build block power terminals as core vdd and/or vss are not known.' )
|
||||
return
|
||||
|
||||
goCb = GoCb( self )
|
||||
query = Query()
|
||||
query.setGoCallback( goCb )
|
||||
query.setCell( self.block )
|
||||
query.setArea( self.block.getAbutmentBox() )
|
||||
query.setFilter( Query.DoComponents|Query.DoTerminalCells )
|
||||
|
||||
for layerGauge in self.conf.gaugeConf.routingGauge.getLayerGauges():
|
||||
self.activePlane = self.planes[ layerGauge.getLayer().getName() ]
|
||||
query.setBasicLayer( layerGauge.getLayer().getBasicLayer() )
|
||||
query.doQuery()
|
||||
self.activePlane = None
|
||||
return
|
||||
|
||||
|
||||
def connectClock ( self ):
|
||||
if not self.conf.useClockTree:
|
||||
print( WarningMessage( "Clock tree generation has been disabled ('chip.clockTree':False)." ))
|
||||
return
|
||||
|
||||
if not self.conf.coronaCk:
|
||||
raise ErrorMessage( 1, 'Cannot build clock terminal as ck is not known.' )
|
||||
return
|
||||
|
||||
blockCk = None
|
||||
for plug in self.path.getTailInstance().getPlugs():
|
||||
if plug.getNet() == self.conf.coronaCk:
|
||||
blockCk = plug.getMasterNet()
|
||||
|
||||
if not blockCk:
|
||||
raise ErrorMessage( 1, 'Block "%s" has no net connected to the clock "%s".'
|
||||
% (self.path.getTailInstance().getName(),self.ck.getName()) )
|
||||
return
|
||||
|
||||
htPlugs = []
|
||||
ffPlugs = []
|
||||
for plug in blockCk.getPlugs():
|
||||
if plug.getInstance().getName() == 'ck_htree':
|
||||
htPlugs.append( plug )
|
||||
else:
|
||||
if plug.getInstance().getMasterCell().isTerminal():
|
||||
ffPlugs.append( plug )
|
||||
|
||||
if len(ffPlugs) > 0:
|
||||
message = 'Clock <%s> of block <%s> is not organized as a H-Tree.' \
|
||||
% (blockCk.getName(),self.path.getTailInstance().getName())
|
||||
raise ErrorMessage( 1, message )
|
||||
return
|
||||
|
||||
if len(htPlugs) > 1:
|
||||
message = 'Block <%s> has not exactly one H-Tree connecteds to the clock <%s>:' \
|
||||
% (self.path.getTailInstance().getName(),blockCk.getName())
|
||||
for plug in htPlugs:
|
||||
message += '\n - %s' % plug
|
||||
raise ErrorMessage( 1, message )
|
||||
return
|
||||
|
||||
UpdateSession.open()
|
||||
bufferRp = self.conf.rpAccessByOccurrence( Occurrence(htPlugs[0], self.path), self.conf.coronaCk )
|
||||
blockAb = self.block.getAbutmentBox()
|
||||
self.path.getTransformation().applyOn( blockAb )
|
||||
layerGauge = self.conf.routingGauge.getLayerGauge(self.conf.verticalDepth)
|
||||
|
||||
contact = Contact.create( self.conf.coronaCk
|
||||
, self.conf.routingGauge.getRoutingLayer(self.conf.verticalDepth)
|
||||
, bufferRp.getX()
|
||||
, blockAb.getYMax()
|
||||
, layerGauge.getViaWidth()
|
||||
, layerGauge.getViaWidth()
|
||||
)
|
||||
segment = self.conf.createVertical( bufferRp, contact, bufferRp.getX() )
|
||||
|
||||
self.activePlane = self.planes[ layerGauge.getLayer().getName() ]
|
||||
bb = segment.getBoundingBox( self.activePlane.metal.getBasicLayer() )
|
||||
self.path.getTransformation().getInvert().applyOn( bb )
|
||||
self.activePlane.addTerminal( self.conf.coronaCk, Plane.Vertical, bb )
|
||||
|
||||
UpdateSession.close()
|
||||
|
||||
return
|
||||
|
||||
def doLayout ( self ):
|
||||
UpdateSession.open()
|
||||
for plane in self.planes.values():
|
||||
plane.doLayout()
|
||||
UpdateSession.close()
|
||||
return
|
|
@ -1,240 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2014-2021, 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/chip/chip.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import os.path
|
||||
import optparse
|
||||
import math
|
||||
import cProfile
|
||||
import pstats
|
||||
import Cfg
|
||||
import Hurricane
|
||||
from Hurricane import DataBase
|
||||
from Hurricane import DbU
|
||||
from Hurricane import Point
|
||||
from Hurricane import Transformation
|
||||
from Hurricane import Box
|
||||
from Hurricane import Path
|
||||
from Hurricane import Occurrence
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import Net
|
||||
from Hurricane import RoutingPad
|
||||
from Hurricane import Contact
|
||||
from Hurricane import Horizontal
|
||||
from Hurricane import Vertical
|
||||
from Hurricane import Instance
|
||||
from Hurricane import HyperNet
|
||||
from Hurricane import Query
|
||||
import Viewer
|
||||
import CRL
|
||||
from CRL import RoutingLayerGauge
|
||||
import helpers
|
||||
from helpers.io import ErrorMessage
|
||||
from helpers.io import WarningMessage
|
||||
import Etesian
|
||||
import Anabatic
|
||||
import Katana
|
||||
import Unicorn
|
||||
import plugins
|
||||
import plugins.cts.clocktree
|
||||
import plugins.chip
|
||||
import plugins.chip.padscorona
|
||||
import plugins.chip.blockpower
|
||||
import plugins.chip.blockcorona
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# PlaceRoute class
|
||||
|
||||
|
||||
class PlaceRoute ( object ):
|
||||
|
||||
def __init__ ( self, conf ):
|
||||
self.conf = conf
|
||||
self.validated = True
|
||||
return
|
||||
|
||||
|
||||
def _refresh ( self ):
|
||||
if self.conf.viewer: self.conf.viewer.fit()
|
||||
return
|
||||
|
||||
|
||||
def validate ( self ):
|
||||
self.validated = True
|
||||
if len(self.conf.cores) < 1: self.validated = False
|
||||
|
||||
coreAb = self.conf.core.getAbutmentBox()
|
||||
if (not coreAb.isEmpty()):
|
||||
if coreAb.getWidth () <= self.conf.coreSize.getWidth() \
|
||||
and coreAb.getHeight() <= self.conf.coreSize.getHeight():
|
||||
self.conf.coreSize = coreAb
|
||||
else:
|
||||
raise ErrorMessage( 1, [ 'Core %s already have an abutment box, bigger than the requested one:'
|
||||
% self.conf.cores[0].getName()
|
||||
, " Cell abutment box: %s" % str(coreAb)
|
||||
, " Maximum abutment box: %s" % str(self.conf.coreSize) ] )
|
||||
self.validated = False
|
||||
|
||||
return self.validated
|
||||
|
||||
|
||||
def doCoronaFloorplan ( self ):
|
||||
if not self.validated:
|
||||
raise ErrorMessage( 1, 'chip.doCoronaFloorplan(): Chip is not valid, aborting.' )
|
||||
return
|
||||
|
||||
self.railsNb = Cfg.getParamInt('chip.block.rails.count' ).asInt()
|
||||
self.hRailWidth = Cfg.getParamInt('chip.block.rails.hWidth' ).asInt()
|
||||
self.vRailWidth = Cfg.getParamInt('chip.block.rails.vWidth' ).asInt()
|
||||
self.hRailSpace = Cfg.getParamInt('chip.block.rails.hSpacing').asInt()
|
||||
self.vRailSpace = Cfg.getParamInt('chip.block.rails.vSpacing').asInt()
|
||||
|
||||
if not self.conf.useClockTree: self.railsNb -= 1
|
||||
|
||||
innerBb = Box( self.conf.coreSize )
|
||||
innerBb.inflate( self.railsNb * self.vRailWidth + (self.railsNb+1) * self.vRailSpace
|
||||
, self.railsNb * self.hRailWidth + (self.railsNb+1) * self.hRailSpace )
|
||||
|
||||
coronaAb = self.conf.corona.getAbutmentBox()
|
||||
if innerBb.getWidth() > coronaAb.getWidth():
|
||||
raise ErrorMessage( 1, 'Core is too wide to fit into the corona, needs %s but only has %s.'
|
||||
% ( DbU.getValueString(innerBb .getWidth())
|
||||
, DbU.getValueString(coronaAb.getWidth()) ) )
|
||||
|
||||
if innerBb.getHeight() > coronaAb.getHeight():
|
||||
raise ErrorMessage( 1, 'Core is too tall to fit into the corona, needs %s but only has %s.'
|
||||
% ( DbU.getValueString(innerBb .getHeight())
|
||||
, DbU.getValueString(coronaAb.getHeight()) ) )
|
||||
|
||||
UpdateSession.open()
|
||||
self.conf.core.setAbutmentBox( self.conf.coreSize )
|
||||
x = (coronaAb.getWidth () - self.conf.coreSize.getWidth ()) // 2
|
||||
y = (coronaAb.getHeight() - self.conf.coreSize.getHeight()) // 2
|
||||
x = x - (x % self.conf.getSliceHeight())
|
||||
y = y - (y % self.conf.getSliceHeight())
|
||||
self.conf.icore.setTransformation ( Transformation(x,y,Transformation.Orientation.ID) )
|
||||
self.conf.icore.setPlacementStatus( Instance.PlacementStatus.FIXED )
|
||||
UpdateSession.close()
|
||||
return
|
||||
|
||||
|
||||
def doCorePlacement ( self ):
|
||||
if not self.validated:
|
||||
raise ErrorMessage( 1, 'chip.doCorePlacement(): Chip is not valid, aborting.' )
|
||||
return
|
||||
|
||||
coreCell = self.conf.core
|
||||
|
||||
checkUnplaced = plugins.CheckUnplaced( coreCell, plugins.NoFlags )
|
||||
if not checkUnplaced.check(): return
|
||||
|
||||
coreCk = None
|
||||
if self.conf.coronaCk:
|
||||
for plug in self.conf.coronaCk.getPlugs():
|
||||
if plug.getInstance() == self.conf.icore:
|
||||
coreCk = plug.getMasterNet()
|
||||
if not coreCk:
|
||||
print( WarningMessage( 'Core "{}" is not connected to chip clock.'.format(self.conf.icore.getName()) ))
|
||||
|
||||
if self.conf.useClockTree and coreCk:
|
||||
ht = plugins.cts.clocktree.HTree.create( self.conf, coreCell, coreCk, coreCell.getAbutmentBox() )
|
||||
ht.addCloned( self.conf.cell )
|
||||
ht.addCloned( self.conf.corona )
|
||||
etesian = Etesian.EtesianEngine.create( self.conf.corona )
|
||||
etesian.setBlock( self.conf.icore )
|
||||
etesian.setViewer( self.conf.viewer )
|
||||
etesian.place()
|
||||
etesian.toHurricane()
|
||||
etesian.flattenPower()
|
||||
etesian.destroy()
|
||||
|
||||
ht.connectLeaf()
|
||||
ht.route()
|
||||
ht.save( self.conf.cell )
|
||||
else:
|
||||
etesian = Etesian.EtesianEngine.create( self.conf.corona )
|
||||
etesian.setBlock( self.conf.icore )
|
||||
etesian.place()
|
||||
etesian.toHurricane()
|
||||
etesian.flattenPower()
|
||||
etesian.destroy()
|
||||
return
|
||||
|
||||
|
||||
def doChipPlacement ( self ):
|
||||
if not self.validated:
|
||||
raise ErrorMessage( 1, 'chip.doChipPlacement(): Chip is not valid, aborting.' )
|
||||
return
|
||||
|
||||
padsCorona = plugins.chip.padscorona.Corona( self.conf )
|
||||
self.validated = padsCorona.validate()
|
||||
if not self.validated: return False
|
||||
|
||||
padsCorona.doLayout()
|
||||
self.validate()
|
||||
self.doCoronaFloorplan()
|
||||
self._refresh()
|
||||
|
||||
self.doCorePlacement()
|
||||
self._refresh()
|
||||
|
||||
coreBlock = plugins.chip.blockpower.Block( self.conf )
|
||||
coreBlock.connectPower()
|
||||
coreBlock.connectClock()
|
||||
coreBlock.doLayout()
|
||||
self._refresh()
|
||||
|
||||
coreCorona = plugins.chip.blockcorona.Corona( coreBlock )
|
||||
coreCorona.connectPads ( padsCorona )
|
||||
coreCorona.connectBlock()
|
||||
coreCorona.doLayout()
|
||||
self._refresh()
|
||||
|
||||
return
|
||||
|
||||
|
||||
def doChipRouting ( self ):
|
||||
if not self.validated:
|
||||
raise ErrorMessage( 1, 'chip.doChipRouting(): Chip is not valid, aborting.' )
|
||||
return
|
||||
|
||||
self.conf.corona.setName( self.conf.corona.getName()+"_r" )
|
||||
katana = Katana.KatanaEngine.create( self.conf.corona )
|
||||
#katana.printConfiguration ()
|
||||
katana.digitalInit ()
|
||||
#katana.runNegociatePreRouted()
|
||||
katana.runGlobalRouter ( Katana.Flags.NoFlags )
|
||||
katana.loadGlobalRouting ( Anabatic.EngineLoadGrByNet )
|
||||
katana.layerAssign ( Anabatic.EngineNoNetLayerAssign )
|
||||
katana.runNegociate ( Katana.Flags.NoFlags )
|
||||
success = katana.getSuccessState()
|
||||
katana.finalizeLayout()
|
||||
katana.destroy()
|
||||
|
||||
return
|
||||
|
||||
|
||||
def save ( self ):
|
||||
if not self.validated:
|
||||
raise ErrorMessage( 1, 'chip.save(): Chip is not valid, aborting.' )
|
||||
return
|
||||
|
||||
af = CRL.AllianceFramework.get()
|
||||
af.saveCell( self.conf.cell , CRL.Catalog.State.Views )
|
||||
af.saveCell( self.conf.corona, CRL.Catalog.State.Views )
|
||||
return
|
|
@ -1,57 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2014-2021, 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/chipplace.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import helpers
|
||||
from helpers.io import ErrorMessage
|
||||
from helpers.io import WarningMessage
|
||||
import plugins
|
||||
import plugins.chip.chip
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Plugin hook functions, unicornHook:menus, ScritMain:call
|
||||
|
||||
def unicornHook ( **kw ):
|
||||
kw['beforeAction'] = 'placeAndRoute.stepByStep'
|
||||
#kw['beforeAction'] = 'placeAndRoute.clockTree'
|
||||
plugins.kwAddMenu ( 'placeAndRoute', 'P&&R', **kw )
|
||||
plugins.kwUnicornHook( 'placeAndRoute.placeChip'
|
||||
, 'PLace Chip'
|
||||
, 'Place a Complete Chip (pads && core)'
|
||||
, sys.modules[__name__].__file__
|
||||
, **kw
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
rvalue = True
|
||||
try:
|
||||
#helpers.setTraceLevel( 550 )
|
||||
cell, editor = plugins.kwParseMain( **kw )
|
||||
conf = plugins.chip.configuration.loadConfiguration( cell, editor )
|
||||
conf.chipValidate()
|
||||
if not conf.validated: return False
|
||||
placeChip = plugins.chip.chip.PlaceRoute( conf )
|
||||
placeChip.doChipPlacement()
|
||||
return placeChip.validated
|
||||
except Exception as e:
|
||||
helpers.io.catch( e )
|
||||
rvalue = False
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
return rvalue
|
|
@ -1,64 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2014-2021, 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/chiproute.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import Viewer
|
||||
import helpers
|
||||
from helpers.io import ErrorMessage
|
||||
from helpers.io import WarningMessage
|
||||
import plugins
|
||||
import plugins.chip.chip
|
||||
from Hurricane import Breakpoint
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Plugin hook functions, unicornHook:menus, ScritMain:call
|
||||
|
||||
def unicornHook ( **kw ):
|
||||
kw['beforeAction'] = 'placeAndRoute.stepByStep'
|
||||
#kw['beforeAction'] = 'placeAndRoute.placeChip'
|
||||
|
||||
plugins.kwAddMenu ( 'placeAndRoute', 'P&&R', **kw )
|
||||
plugins.kwUnicornHook( 'placeAndRoute.placeRouteChip'
|
||||
, 'PLace && Route Chip'
|
||||
, 'Place & route a Complete Chip (pads && core)'
|
||||
, sys.modules[__name__].__file__
|
||||
, **kw
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
rvalue = True
|
||||
try:
|
||||
Breakpoint.setStopLevel( 99 )
|
||||
helpers.setTraceLevel( 550 )
|
||||
cell, editor = plugins.kwParseMain( **kw )
|
||||
conf = plugins.chip.configuration.loadConfiguration( cell, editor )
|
||||
conf.chipValidate()
|
||||
if not conf.validated: return False
|
||||
prChip = plugins.chip.chip.PlaceRoute( conf )
|
||||
prChip.validate()
|
||||
prChip.doChipPlacement()
|
||||
prChip.doChipRouting()
|
||||
prChip.save()
|
||||
return prChip.validated
|
||||
except Exception as e:
|
||||
helpers.io.catch( e )
|
||||
rvalue = False
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
return rvalue
|
|
@ -1,90 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2014-2021, 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/clocktreeplugin.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import os.path
|
||||
import math
|
||||
import Cfg
|
||||
import Hurricane
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import UpdateSession
|
||||
import Viewer
|
||||
import CRL
|
||||
from CRL import RoutingLayerGauge
|
||||
import helpers
|
||||
from helpers import trace
|
||||
from helpers.io import ErrorMessage
|
||||
import Etesian
|
||||
import Unicorn
|
||||
import plugins
|
||||
from plugins.cts.clocktree import HTree
|
||||
from plugins.cts.clocktree import computeAbutmentBox
|
||||
from plugins.chip.configuration import ChipConf
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Plugin hook functions, unicornHook:menus, ScritMain:call
|
||||
|
||||
def unicornHook ( **kw ):
|
||||
kw['beforeAction'] = 'placeAndRoute.placeChip'
|
||||
plugins.kwAddMenu ( 'placeAndRoute', 'P&&R', **kw )
|
||||
plugins.kwUnicornHook( 'placeAndRoute.clockTree'
|
||||
, 'Place Block && Clock Tree'
|
||||
, 'Place a block with a buffered H-Tree for the clock'
|
||||
, sys.modules[__name__].__file__
|
||||
, **kw
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
try:
|
||||
#helpers.setTraceLevel( 550 )
|
||||
errorCode = 0
|
||||
print( ' o Cleaning up any previous run.' )
|
||||
for fileName in os.listdir('.'):
|
||||
if fileName.endswith('.ap'):
|
||||
print( ' - "{}"'.format(fileName) )
|
||||
os.unlink(fileName)
|
||||
cell = None
|
||||
if ('cell' in kw) and kw['cell']:
|
||||
cell = kw['cell']
|
||||
editor = None
|
||||
if ('editor' in kw) and kw['editor']:
|
||||
editor = kw['editor']
|
||||
print( ' o Editor detected, running in graphic mode.' )
|
||||
if cell == None: cell = editor.getCell()
|
||||
if cell == None:
|
||||
raise ErrorMessage( 3, 'ClockTree: No cell loaded yet.' )
|
||||
conf = ChipConf( {}, cell, editor )
|
||||
if cell.getAbutmentBox().isEmpty():
|
||||
spaceMargin = Cfg.getParamPercentage('etesian.spaceMargin').asPercentage() / 100.0 + 0.01
|
||||
aspectRatio = Cfg.getParamPercentage('etesian.aspectRatio').asPercentage() / 100.0
|
||||
computeAbutmentBox( cell, spaceMargin, aspectRatio, conf.cellGauge )
|
||||
if editor: editor.fit()
|
||||
ht = HTree.create( conf, cell, None, cell.getAbutmentBox() )
|
||||
if editor: editor.refresh()
|
||||
etesian = Etesian.EtesianEngine.create( cell )
|
||||
etesian.place()
|
||||
ht.connectLeaf()
|
||||
#ht.prune()
|
||||
ht.route()
|
||||
etesian.toHurricane()
|
||||
etesian.flattenPower()
|
||||
etesian.destroy()
|
||||
ht.save( cell )
|
||||
except Exception as e:
|
||||
helpers.io.catch( e )
|
||||
return 0
|
|
@ -1,155 +0,0 @@
|
|||
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2021, 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/core2chip/cmos.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
import sys
|
||||
import re
|
||||
from Hurricane import DbU
|
||||
from Hurricane import DataBase
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import Transformation
|
||||
from Hurricane import Instance
|
||||
from Hurricane import Net
|
||||
import Viewer
|
||||
from CRL import Catalog
|
||||
from CRL import AllianceFramework
|
||||
from helpers.io import ErrorMessage
|
||||
from plugins.core2chip.core2chip import IoPad
|
||||
from plugins.core2chip.core2chip import CoreToChip
|
||||
|
||||
|
||||
class cmos ( CoreToChip ):
|
||||
|
||||
def __init__ ( self, core ):
|
||||
CoreToChip.__init__ ( self, core )
|
||||
self.ringNetNames = [ 'vsse', 'vssi', 'vdde', 'vddi', ('cki', 'ck') ]
|
||||
self.ioPadInfos = { IoPad.IN : CoreToChip.IoPadInfo( 'pi_px' , 'pad', ['t',] )
|
||||
, IoPad.OUT : CoreToChip.IoPadInfo( 'po_px' , 'pad', ['i',] )
|
||||
, IoPad.TRI_OUT : CoreToChip.IoPadInfo( 'pot_px' , 'pad', ['i', 'b' ] )
|
||||
, IoPad.BIDIR : CoreToChip.IoPadInfo( 'piot_px', 'pad', ['i', 't', 'b' ] )
|
||||
}
|
||||
self._getPadLib()
|
||||
return
|
||||
|
||||
def _getPadLib ( self ):
|
||||
self.padLib = AllianceFramework.get().getLibrary( "pxlib" )
|
||||
|
||||
if not self.padLib:
|
||||
message = [ 'CoreToChip.cmos._getPadLib(): Unable to find Alliance "pxlib" library' ]
|
||||
raise ErrorMessage( 1, message )
|
||||
|
||||
return
|
||||
|
||||
def getNetType ( self, netName ):
|
||||
if netName.startswith('vss'): return Net.Type.GROUND
|
||||
if netName.startswith('vdd'): return Net.Type.POWER
|
||||
if netName in ('cki', 'ck'): return Net.Type.CLOCK
|
||||
return Net.Type.LOGICAL
|
||||
|
||||
def isGlobal ( self, netName ):
|
||||
if netName in self.ringNetNames: return True
|
||||
return False
|
||||
|
||||
def getCell ( self, masterCellName ):
|
||||
#cell = self.padLib.getCell( masterCellName )
|
||||
cell = AllianceFramework.get().getCell( masterCellName, Catalog.State.Views )
|
||||
if not cell:
|
||||
raise ErrorMessage( 1, 'cmos.getCell(): I/O pad library "%s" does not contain cell named "%s"' \
|
||||
% (self.padLib.getName(),masterCellName) )
|
||||
return cell
|
||||
|
||||
def _buildGroundPads ( self, ioNet ):
|
||||
ioNet.buildNets()
|
||||
vssi = self.chip.getNet( 'vssi' )
|
||||
vssi.setExternal( True )
|
||||
vssi.setGlobal ( True )
|
||||
vssi.setType ( Net.Type.GROUND )
|
||||
vssi.merge( ioNet.chipIntNet )
|
||||
ioNet.chipIntNet = vssi
|
||||
|
||||
vsse = self.chip.getNet( 'vsse' )
|
||||
vsse.setExternal( True )
|
||||
vsse.setGlobal ( True )
|
||||
vsse.setType ( Net.Type.GROUND )
|
||||
vsse.merge( ioNet.chipExtNet )
|
||||
ioNet.chipExtNet = vsse
|
||||
|
||||
pads = []
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + 'ick_%d' % self.groundPadCount
|
||||
, self.getCell('pvssick_px') ) )
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + 'eck_%d' % self.groundPadCount
|
||||
, self.getCell('pvsseck_px') ) )
|
||||
|
||||
CoreToChip._connect( pads[0], ioNet.chipIntNet, 'vssi' )
|
||||
CoreToChip._connect( pads[1], ioNet.chipExtNet, 'vsse' )
|
||||
|
||||
for pad in pads: self._connectRing( pad )
|
||||
self.groundPadCount += 1
|
||||
self.chipPads += pads
|
||||
return
|
||||
|
||||
def _buildPowerPads ( self, ioNet ):
|
||||
ioNet.buildNets()
|
||||
vddi = self.chip.getNet( 'vddi' )
|
||||
vddi.setExternal( True )
|
||||
vddi.setGlobal ( True )
|
||||
vddi.setType ( Net.Type.POWER )
|
||||
vddi.merge( ioNet.chipIntNet )
|
||||
ioNet.chipIntNet = vddi
|
||||
|
||||
vdde = self.chip.getNet( 'vdde' )
|
||||
vdde.setExternal( True )
|
||||
vdde.setGlobal ( True )
|
||||
vdde.setType ( Net.Type.POWER )
|
||||
vdde.merge( ioNet.chipExtNet )
|
||||
ioNet.chipExtNet = vdde
|
||||
|
||||
pads = [ ]
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + 'ick_%d' % self.powerPadCount
|
||||
, self.getCell('pvddick_px') ) )
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + 'eck_%d' % self.powerPadCount
|
||||
, self.getCell('pvddeck_px') ) )
|
||||
|
||||
CoreToChip._connect( pads[0], ioNet.chipIntNet, 'vddi' )
|
||||
CoreToChip._connect( pads[1], ioNet.chipExtNet, 'vdde' )
|
||||
|
||||
for pad in pads: self._connectRing( pad )
|
||||
self.powerPadCount += 1
|
||||
self.chipPads += pads
|
||||
return
|
||||
|
||||
def _buildClockPads ( self, ioNet ):
|
||||
ioNet.buildNets()
|
||||
pads = [ ]
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + '_%d' % self.clockPadCount
|
||||
, self.getCell('pck_px') ) )
|
||||
|
||||
CoreToChip._connect( pads[0], ioNet.chipExtNet, 'pad' )
|
||||
|
||||
for pad in pads: self._connectRing( pad )
|
||||
self.clockPadCount += 1
|
||||
self.chipPads += pads
|
||||
|
||||
p = re.compile( r'pv[ds]{2}[ei]ck_px' )
|
||||
for pad in self.chipPads:
|
||||
if p.match( pad.getMasterCell().getName() ):
|
||||
CoreToChip._connect( pad, ioNet.chipIntNet, 'cko' )
|
||||
return
|
|
@ -1,451 +0,0 @@
|
|||
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2018, 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/core2chip/core2chip.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
import re
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import Net
|
||||
from Hurricane import Instance
|
||||
from CRL import Catalog
|
||||
from CRL import AllianceFramework
|
||||
from helpers import netDirectionToStr
|
||||
from helpers.io import ErrorMessage
|
||||
import plugins.chip
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Class : "IoNet".
|
||||
|
||||
|
||||
class IoNet ( object ):
|
||||
|
||||
IsElem = 0x0001
|
||||
IsEnable = 0x0002
|
||||
DoExtNet = 0x0008
|
||||
reVHDLVector = re.compile( r'(?P<name>[^(]*)\((?P<index>[\d]+)\)$' )
|
||||
|
||||
def __init__ ( self, coreToChip, coreNet ):
|
||||
self.coreToChip = coreToChip
|
||||
self._flags = 0
|
||||
self._chipExtNetName = None # In the case of bidir pad, force external net name.
|
||||
self.coreNet = coreNet
|
||||
self.coronaNet = None # Corona net going from core to corona.
|
||||
self.chipIntNet = None # Chip net going from corona to I/O pad.
|
||||
self.chipExtNet = None # Chip net going from I/O pad to the outside world.
|
||||
|
||||
m = IoNet.reVHDLVector.match( self.coreNet.getName() )
|
||||
if m:
|
||||
self._flags |= IoNet.IsElem
|
||||
self._name = m.group('name')
|
||||
self._index = m.group('index')
|
||||
else:
|
||||
self._name = self.coreNet.getName()
|
||||
self._index = 0
|
||||
|
||||
self._type = self.coreToChip.getNetType( self._name )
|
||||
return
|
||||
|
||||
def __repr__ ( self ):
|
||||
s = '<IoNet "%s" ext:' % self.coreNet.getName()
|
||||
if self.chipExtNet: s += self.chipExtNet.getName()
|
||||
else: s += 'None'
|
||||
s += ' int:'
|
||||
if self.chipIntNet: s += self.chipIntNet.getName()
|
||||
else: s += 'None'
|
||||
s += '>'
|
||||
return s
|
||||
|
||||
def isElem ( self ): return self._flags & IoNet.IsElem
|
||||
def isEnable ( self ): return self._flags & IoNet.IsEnable
|
||||
|
||||
def isGlobal ( self ): return self.isGlobal( self._name )
|
||||
|
||||
@property
|
||||
def name ( self ): return self._name
|
||||
|
||||
@property
|
||||
def index ( self ): return self._index
|
||||
|
||||
@property
|
||||
def coreNetName ( self ): return self.coreNet.getName()
|
||||
|
||||
@property
|
||||
def coronaNetName ( self ):
|
||||
s = self._name + '_core'
|
||||
if self._flags & IoNet.IsElem: s += '(' + self._index + ')'
|
||||
return s
|
||||
|
||||
@property
|
||||
def padNetName ( self ):
|
||||
if self._chipExtNetName is not None: return self._chipExtNetName
|
||||
|
||||
s = self._name
|
||||
if self._flags & IoNet.IsElem: s += '(' + self._index + ')'
|
||||
return s
|
||||
|
||||
@padNetName.setter
|
||||
def padNetName ( self, name ): self._chipExtNetName = name
|
||||
|
||||
@property
|
||||
def padInstanceName ( self ):
|
||||
s = self._name
|
||||
if self._flags & IoNet.IsElem: s += '_' + self._index
|
||||
return s
|
||||
|
||||
def setChipExtNetName ( self, name ): self.chipExtNetName = name
|
||||
|
||||
def setEnable ( self, state ):
|
||||
if state == True: self._flags |= IoNet.IsEnable
|
||||
else: self._flags &= ~IoNet.IsEnable
|
||||
return
|
||||
|
||||
def buildNets ( self, context=DoExtNet ):
|
||||
netType = Net.Type.LOGICAL
|
||||
if self.coreNet.isPower (): netType = Net.Type.POWER
|
||||
if self.coreNet.isGround(): netType = Net.Type.GROUND
|
||||
if self.coreNet.isClock (): netType = Net.Type.CLOCK
|
||||
|
||||
# Corona net, connect to Core instance net.
|
||||
if not self.coronaNet:
|
||||
self.coronaNet = Net.create( self.coreToChip.corona, self.coreNetName )
|
||||
self.coronaNet.setExternal ( True )
|
||||
self.coronaNet.setDirection( self.coreNet.getDirection() )
|
||||
if netType != Net.Type.LOGICAL:
|
||||
self.coronaNet.setType ( netType )
|
||||
self.coronaNet.setGlobal( True )
|
||||
|
||||
self.coreToChip.icore.getPlug( self.coreNet ).setNet( self.coronaNet )
|
||||
|
||||
# Chip "internal" net, connect Corona instance net to I/O inside the chip.
|
||||
if not self.chipIntNet:
|
||||
self.chipIntNet = Net.create( self.coreToChip.chip, self.coronaNetName )
|
||||
if netType != Net.Type.LOGICAL:
|
||||
self.chipIntNet.setType( netType )
|
||||
|
||||
self.coreToChip.icorona.getPlug( self.coronaNet ).setNet( self.chipIntNet )
|
||||
|
||||
# Chip "external" net, connected to the pad I/O to the outside world.
|
||||
if not self.chipExtNet and (context & IoNet.DoExtNet):
|
||||
self.chipExtNet = self.coreToChip.chip.getNet( self.padNetName )
|
||||
if not self.chipExtNet:
|
||||
self.chipExtNet = Net.create( self.coreToChip.chip, self.padNetName )
|
||||
self.chipExtNet.setExternal ( True )
|
||||
self.chipExtNet.setDirection( self.coreNet.getDirection() )
|
||||
|
||||
return
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Class : "IoPad".
|
||||
|
||||
|
||||
class IoPad ( object ):
|
||||
|
||||
IN = 0x0001
|
||||
OUT = 0x0002
|
||||
BIDIR = 0x0004
|
||||
TRI_OUT = 0x0008
|
||||
UNSUPPORTED = 0x0010
|
||||
|
||||
|
||||
@staticmethod
|
||||
def directionToStr ( direction ):
|
||||
if direction == IoPad.IN: return "IN"
|
||||
if direction == IoPad.OUT: return "OUT"
|
||||
if direction == IoPad.BIDIR: return "BIDIR"
|
||||
if direction == IoPad.TRI_OUT: return "TRI_OUT"
|
||||
if direction == IoPad.UNSUPPORTED: return "UNSUPPORTED"
|
||||
return "Invalid value"
|
||||
|
||||
|
||||
def __init__ ( self, coreToChip, padInstanceName ):
|
||||
self.coreToChip = coreToChip
|
||||
self.padInstanceName = padInstanceName
|
||||
self.direction = 0
|
||||
self.nets = [ ]
|
||||
self.pads = [ ]
|
||||
return
|
||||
|
||||
|
||||
def __str__ ( self ):
|
||||
s = '<IoPad "%s" ' % self.padInstanceName
|
||||
for ioNet in self.nets:
|
||||
s += ' %s' % ioNet.coreNetName
|
||||
s += '>'
|
||||
return s
|
||||
|
||||
|
||||
def addNet ( self, ioNet ):
|
||||
self.nets.append( ioNet )
|
||||
if len(self.nets) == 1:
|
||||
if self.nets[0].coreNet.getDirection() == Net.Direction.IN: self.direction = IoPad.IN
|
||||
elif self.nets[0].coreNet.getDirection() == Net.Direction.OUT: self.direction = IoPad.OUT
|
||||
elif self.nets[0].coreNet.getName() == 'scout': self.direction = IoPad.OUT
|
||||
else:
|
||||
raise ErrorMessage( 1, 'IoPad.addNet(): Unsupported direction %d (%s) for core net "%s" in I/O pad \"%s\".' \
|
||||
% ( self.nets[0].coreNet.getDirection()
|
||||
, netDirectionToStr(self.nets[0].coreNet.getDirection())
|
||||
, self.nets[0].coreNet.getName()
|
||||
, self.padInstanceName ) )
|
||||
elif len(self.nets) == 2:
|
||||
self.direction = IoPad.TRI_OUT
|
||||
elif len(self.nets) == 3:
|
||||
self.direction = IoPad.BIDIR
|
||||
else:
|
||||
message = [ 'IoPad.addNet(): More than three core nets on I/O pad "%s".' % self.padInstanceName ]
|
||||
for ioNet in self.nets:
|
||||
message += [ "%s" % ioNet.coreNet ]
|
||||
raise ErrorMessage( 1, message )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def createPad ( self ):
|
||||
fromCoreNet = None
|
||||
toCoreNet = None
|
||||
enableNet = None
|
||||
|
||||
for ioNet in self.nets:
|
||||
context = 0
|
||||
|
||||
if self.direction == IoPad.TRI_OUT:
|
||||
if ioNet.isEnable(): enableNet = ioNet
|
||||
else:
|
||||
fromCoreNet = ioNet
|
||||
context |= IoNet.DoExtNet
|
||||
elif self.direction == IoPad.BIDIR:
|
||||
if ioNet.coreNet.getDirection() == Net.Direction.IN: toCoreNet = ioNet
|
||||
if ioNet.coreNet.getDirection() == Net.Direction.OUT:
|
||||
if ioNet.isEnable(): enableNet = ioNet
|
||||
else:
|
||||
fromCoreNet = ioNet
|
||||
context |= IoNet.DoExtNet
|
||||
else:
|
||||
context |= IoNet.DoExtNet
|
||||
fromCoreNet = ioNet
|
||||
|
||||
ioNet.buildNets( context )
|
||||
|
||||
if not self.direction in self.coreToChip.ioPadInfos:
|
||||
raise ErrorMessage( 1, 'IoPad.createPad(): Unsupported direction %d (%s) for pad "%s".' \
|
||||
% (self.direction
|
||||
,IoPad.directionToStr(self.direction)
|
||||
,self.padInstanceName) )
|
||||
padInfo = self.coreToChip.ioPadInfos[ self.direction ]
|
||||
|
||||
self.pads.append( Instance.create( self.coreToChip.chip
|
||||
, self.padInstanceName
|
||||
, self.coreToChip.getCell(padInfo.name) ) )
|
||||
|
||||
CoreToChip._connect( self.pads[0], fromCoreNet.chipExtNet, padInfo.padNet )
|
||||
CoreToChip._connect( self.pads[0], fromCoreNet.chipIntNet, padInfo.coreNets[0] )
|
||||
|
||||
if toCoreNet: CoreToChip._connect( self.pads[0], toCoreNet.chipIntNet, padInfo.coreNets[-2] )
|
||||
if enableNet: CoreToChip._connect( self.pads[0], enableNet.chipIntNet, padInfo.coreNets[-1] )
|
||||
|
||||
self.coreToChip._connectRing( self.pads[0] )
|
||||
self.coreToChip.chipPads += self.pads
|
||||
return
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Class : "CoreToChip".
|
||||
|
||||
|
||||
class CoreToChip ( object ):
|
||||
|
||||
class IoPadInfo ( object ):
|
||||
|
||||
def __init__ ( self, padName, padNet, coreNets ):
|
||||
self.name = padName
|
||||
self.padNet = padNet
|
||||
self.coreNets = coreNets
|
||||
return
|
||||
|
||||
|
||||
def getNetType ( self, netName ):
|
||||
raise ErrorMessage( 1, 'coreToChip.getNetType(): This method must be overloaded.' )
|
||||
|
||||
def isGlobal ( self, netName ):
|
||||
raise ErrorMessage( 1, 'coreToChip.isGlobal(): This method must be overloaded.' )
|
||||
|
||||
def getCell ( self, masterCellName ):
|
||||
raise ErrorMessage( 1, 'coreToChip.getCell(): This method must be overloaded.' )
|
||||
|
||||
@staticmethod
|
||||
def _connect ( instance, netO, masterNetO=None ):
|
||||
if isinstance(netO,Net): chipNet = netO
|
||||
else: chipNet = instance.getCell().getNet( netO )
|
||||
|
||||
if not masterNetO: masterNet = instance.getMasterCell().getNet( chipNet.getName() )
|
||||
elif isinstance(masterNetO,Net): masterNet = masterNetO
|
||||
else: masterNet = instance.getMasterCell().getNet( masterNetO )
|
||||
|
||||
instance.getPlug( masterNet ).setNet( chipNet )
|
||||
return
|
||||
|
||||
def __init__ ( self, core ):
|
||||
self.conf = plugins.chip.configuration.loadConfiguration( core )
|
||||
self.ringNetNames = [ ]
|
||||
self.ioPadInfos = { }
|
||||
self.chipPads = [ ]
|
||||
self.padLib = None
|
||||
self.core = core
|
||||
self.chip = None
|
||||
self.corona = None
|
||||
self.icorona = None
|
||||
self.icore = None
|
||||
self._ioNets = { }
|
||||
self.powerPadCount = 0
|
||||
self.groundPadCount = 0
|
||||
self.clockPadCount = 0
|
||||
return
|
||||
|
||||
|
||||
def hasIoNet ( self, netName ):
|
||||
if netName in self._ioNets: return True
|
||||
return False
|
||||
|
||||
|
||||
def getIoNet ( self, coreNet ):
|
||||
if isinstance(coreNet,str):
|
||||
if coreNet in self._ioNets: return self._ioNet[ coreNet ]
|
||||
raise ErrorMessage( 1, 'CoreToChip.getIoNet(): Cannot lookup net "%s" by name.' % coreNet )
|
||||
|
||||
if not coreNet.getName() in self._ioNets:
|
||||
self._ioNets[ coreNet.getName() ] = IoNet( self, coreNet )
|
||||
|
||||
return self._ioNets[ coreNet.getName() ]
|
||||
|
||||
|
||||
def _connectRing ( self, padInstance ):
|
||||
for ringNetName in self.ringNetNames:
|
||||
if isinstance(ringNetName,tuple):
|
||||
CoreToChip._connect( padInstance, ringNetName[0], ringNetName[1] )
|
||||
else:
|
||||
CoreToChip._connect( padInstance, ringNetName )
|
||||
return
|
||||
|
||||
def _buildRingNets ( self ):
|
||||
for ringNetSpec in self.ringNetNames:
|
||||
if isinstance(ringNetSpec,tuple): ringNetName = ringNetSpec[0]
|
||||
else: ringNetName = ringNetSpec
|
||||
ringNet = self.chip.getNet( ringNetName )
|
||||
if not ringNet:
|
||||
ringNet = Net.create( self.chip, ringNetName )
|
||||
ringNet.setType ( self.getNetType(ringNetName) )
|
||||
ringNet.setGlobal( self.isGlobal (ringNetName) )
|
||||
return
|
||||
|
||||
def _buildStandardPad ( self, ioNet ):
|
||||
if not ioNet.coreNet.getDirection() in self.ioPadInfos:
|
||||
raise ErrorMessage( 1, 'CoreToChip._buildStandardPad(): Unsupported direction %d (%s) for core net "%s".' \
|
||||
% (ioNet.coreNet.getDirection()
|
||||
,netDirectionToStr(ioNet.coreNet.getDirection())
|
||||
,ioNet.coreNet.getName()) )
|
||||
|
||||
padInfo = self.ioPadInfos[ ioNet.coreNet.getDirection() ]
|
||||
|
||||
ioNet.pads.append( Instance.create( self.chip
|
||||
, ioNet.padInstanceName
|
||||
, self.getCell(padInfo.name) ) )
|
||||
CoreToChip._connect( ioNet.pads[0], ioNet.chipExtNet, padInfo.padNet )
|
||||
CoreToChip._connect( ioNet.pads[0], ioNet.chipIntNet, padInfo.coreNets[0] )
|
||||
self._connectRing( ioNet.pads[0] )
|
||||
self.chipPads += ioNet.pads
|
||||
return
|
||||
|
||||
def _buildGroundPads ( self, ioNet ):
|
||||
raise ErrorMessage( 1, 'coreToChip._buildGroundPads(): This method must be overloaded.' )
|
||||
|
||||
def _buildPowerPads ( self, ioNet ):
|
||||
raise ErrorMessage( 1, 'coreToChip._buildPowerPads(): This method must be overloaded.' )
|
||||
|
||||
def _buildClockPads ( self, ioNet ):
|
||||
raise ErrorMessage( 1, 'coreToChip._buildClockPads(): This method must be overloaded.' )
|
||||
|
||||
def buildChip ( self ):
|
||||
af = AllianceFramework.get()
|
||||
|
||||
UpdateSession.open()
|
||||
|
||||
self.chip = af.createCell( self.conf.chipName )
|
||||
self.corona = af.createCell( 'corona' )
|
||||
self.icore = Instance.create( self.corona, 'core' , self.core )
|
||||
self.icorona = Instance.create( self.chip , 'corona', self.corona )
|
||||
|
||||
self._buildRingNets()
|
||||
|
||||
ioPads = [ ]
|
||||
clockIoNets = [ ]
|
||||
|
||||
for padConf in self.conf.padInstances:
|
||||
padConf.udata = IoPad( self, padConf.padInstanceName )
|
||||
|
||||
for netName in padConf.nets:
|
||||
coreNet = self.core.getNet(netName)
|
||||
if not coreNet:
|
||||
raise ErrorMessage( 1, 'CoreToChip.buildChip(): "%s" doesn\'t have a "%s" net.'
|
||||
% (self.core.getName(),netName) )
|
||||
ioNet = self.getIoNet( coreNet )
|
||||
|
||||
if padConf.isBidir() or padConf.isTristate():
|
||||
if coreNet.getName() == padConf.enableNet:
|
||||
ioNet.setEnable( True )
|
||||
|
||||
if not ioNet.isEnable():
|
||||
ioNet.padNetName = padConf.padNetName
|
||||
|
||||
padConf.udata.addNet( ioNet )
|
||||
ioPads.append( padConf )
|
||||
|
||||
for coreNet in self.core.getNets():
|
||||
if not coreNet.isExternal(): continue
|
||||
|
||||
# Case of special nets (power, ground & clocks).
|
||||
if coreNet.isPower():
|
||||
self._buildPowerPads( IoNet( self, coreNet ) )
|
||||
continue
|
||||
elif coreNet.isGround():
|
||||
self._buildGroundPads( IoNet( self, coreNet ) )
|
||||
continue
|
||||
elif coreNet.isClock():
|
||||
clockIoNets.append( IoNet( self, coreNet ) )
|
||||
continue
|
||||
|
||||
if self.hasIoNet(coreNet.getName()):
|
||||
continue
|
||||
|
||||
# Remaining non configured Standard I/O pads.
|
||||
ioNet = IoNet( self, coreNet )
|
||||
directPad = plugins.chip.configuration.IoPadConf( [ ioNet.padInstanceName
|
||||
, ioNet.padNetName
|
||||
, ioNet.coreNetName
|
||||
] )
|
||||
directPad.udata = IoPad( self, directPad.padInstanceName )
|
||||
directPad.udata.addNet( ioNet )
|
||||
ioPads.append( directPad )
|
||||
|
||||
for ioPad in ioPads:
|
||||
ioPad.udata.createPad()
|
||||
|
||||
for clockIoNet in clockIoNets:
|
||||
self._buildClockPads( clockIoNet )
|
||||
|
||||
UpdateSession.close()
|
||||
|
||||
af.saveCell( self.chip , Catalog.State.Logical )
|
||||
af.saveCell( self.corona, Catalog.State.Logical )
|
||||
return
|
|
@ -1,154 +0,0 @@
|
|||
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2021, 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/core2chip/cmos.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
import re
|
||||
from Hurricane import DbU
|
||||
from Hurricane import DataBase
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import Transformation
|
||||
from Hurricane import Instance
|
||||
from Hurricane import Net
|
||||
import Viewer
|
||||
from CRL import Catalog
|
||||
from CRL import AllianceFramework
|
||||
from helpers.io import ErrorMessage
|
||||
from core2chip.core2chip import IoPad
|
||||
from core2chip.core2chip import CoreToChip
|
||||
|
||||
|
||||
class cmos ( CoreToChip ):
|
||||
|
||||
def __init__ ( self, core ):
|
||||
CoreToChip.__init__ ( self, core )
|
||||
self.ringNetNames = [ 'vsse', 'vssi', 'vdde', 'vddi', ('cki', 'ck') ]
|
||||
self.ioPadInfos = { IoPad.IN : CoreToChip.IoPadInfo( 'pi_px' , 'pad', ['t',] )
|
||||
, IoPad.OUT : CoreToChip.IoPadInfo( 'po_px' , 'pad', ['i',] )
|
||||
, IoPad.TRI_OUT : CoreToChip.IoPadInfo( 'pot_px' , 'pad', ['i', 'b' ] )
|
||||
, IoPad.BIDIR : CoreToChip.IoPadInfo( 'piot_px', 'pad', ['i', 't', 'b' ] )
|
||||
}
|
||||
self._getPadLib()
|
||||
return
|
||||
|
||||
def _getPadLib ( self ):
|
||||
self.padLib = AllianceFramework.get().getLibrary( "pxlib" )
|
||||
|
||||
if not self.padLib:
|
||||
message = [ 'CoreToChip.cmos._getPadLib(): Unable to find Alliance "pxlib" library' ]
|
||||
raise ErrorMessage( 1, message )
|
||||
|
||||
return
|
||||
|
||||
def getNetType ( self, netName ):
|
||||
if netName.startswith('vss'): return Net.Type.GROUND
|
||||
if netName.startswith('vdd'): return Net.Type.POWER
|
||||
if netName in ('cki', 'ck'): return Net.Type.CLOCK
|
||||
return Net.Type.LOGICAL
|
||||
|
||||
def isGlobal ( self, netName ):
|
||||
if netName in self.ringNetNames: return True
|
||||
return False
|
||||
|
||||
def getCell ( self, masterCellName ):
|
||||
#cell = self.padLib.getCell( masterCellName )
|
||||
cell = AllianceFramework.get().getCell( masterCellName, Catalog.State.Views )
|
||||
if not cell:
|
||||
raise ErrorMessage( 1, 'cmos.getCell(): I/O pad library "%s" does not contain cell named "%s"' \
|
||||
% (self.padLib.getName(),masterCellName) )
|
||||
return cell
|
||||
|
||||
def _buildGroundPads ( self, ioNet ):
|
||||
ioNet.buildNets()
|
||||
vssi = self.chip.getNet( 'vssi' )
|
||||
vssi.setExternal( True )
|
||||
vssi.setGlobal ( True )
|
||||
vssi.setType ( Net.Type.GROUND )
|
||||
vssi.merge( ioNet.chipIntNet )
|
||||
ioNet.chipIntNet = vssi
|
||||
|
||||
vsse = self.chip.getNet( 'vsse' )
|
||||
vsse.setExternal( True )
|
||||
vsse.setGlobal ( True )
|
||||
vsse.setType ( Net.Type.GROUND )
|
||||
vsse.merge( ioNet.chipExtNet )
|
||||
ioNet.chipExtNet = vsse
|
||||
|
||||
pads = []
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + 'ick_%d' % self.groundPadCount
|
||||
, self.getCell('pvssick_px') ) )
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + 'eck_%d' % self.groundPadCount
|
||||
, self.getCell('pvsseck_px') ) )
|
||||
|
||||
CoreToChip._connect( pads[0], ioNet.chipIntNet, 'vssi' )
|
||||
CoreToChip._connect( pads[1], ioNet.chipExtNet, 'vsse' )
|
||||
|
||||
for pad in pads: self._connectRing( pad )
|
||||
self.groundPadCount += 1
|
||||
self.chipPads += pads
|
||||
return
|
||||
|
||||
def _buildPowerPads ( self, ioNet ):
|
||||
ioNet.buildNets()
|
||||
vddi = self.chip.getNet( 'vddi' )
|
||||
vddi.setExternal( True )
|
||||
vddi.setGlobal ( True )
|
||||
vddi.setType ( Net.Type.POWER )
|
||||
vddi.merge( ioNet.chipIntNet )
|
||||
ioNet.chipIntNet = vddi
|
||||
|
||||
vdde = self.chip.getNet( 'vdde' )
|
||||
vdde.setExternal( True )
|
||||
vdde.setGlobal ( True )
|
||||
vdde.setType ( Net.Type.POWER )
|
||||
vdde.merge( ioNet.chipExtNet )
|
||||
ioNet.chipExtNet = vdde
|
||||
|
||||
pads = [ ]
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + 'ick_%d' % self.powerPadCount
|
||||
, self.getCell('pvddick_px') ) )
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + 'eck_%d' % self.powerPadCount
|
||||
, self.getCell('pvddeck_px') ) )
|
||||
|
||||
CoreToChip._connect( pads[0], ioNet.chipIntNet, 'vddi' )
|
||||
CoreToChip._connect( pads[1], ioNet.chipExtNet, 'vdde' )
|
||||
|
||||
for pad in pads: self._connectRing( pad )
|
||||
self.powerPadCount += 1
|
||||
self.chipPads += pads
|
||||
return
|
||||
|
||||
def _buildClockPads ( self, ioNet ):
|
||||
ioNet.buildNets()
|
||||
pads = [ ]
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + '_%d' % self.clockPadCount
|
||||
, self.getCell('pck_px') ) )
|
||||
|
||||
CoreToChip._connect( pads[0], ioNet.chipExtNet, 'pad' )
|
||||
|
||||
for pad in pads: self._connectRing( pad )
|
||||
self.clockPadCount += 1
|
||||
self.chipPads += pads
|
||||
|
||||
p = re.compile( r'pv[ds]{2}[ei]ck_px' )
|
||||
for pad in self.chipPads:
|
||||
if p.match( pad.getMasterCell().getName() ):
|
||||
CoreToChip._connect( pad, ioNet.chipIntNet, 'cko' )
|
||||
return
|
|
@ -1,133 +0,0 @@
|
|||
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2021, 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/core2chip/phlib80.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import re
|
||||
from Hurricane import DbU
|
||||
from Hurricane import DataBase
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import Transformation
|
||||
from Hurricane import Instance
|
||||
from Hurricane import Net
|
||||
import Viewer
|
||||
from CRL import Catalog
|
||||
from CRL import AllianceFramework
|
||||
from helpers.io import ErrorMessage
|
||||
from plugins.core2chip.core2chip import IoPad
|
||||
from plugins.core2chip.core2chip import CoreToChip
|
||||
|
||||
|
||||
class phlib80 ( CoreToChip ):
|
||||
|
||||
def __init__ ( self, core ):
|
||||
CoreToChip.__init__ ( self, core )
|
||||
self.ringNetNames = [ 'vss', 'vss', ('cki', 'ck') ]
|
||||
self.ioPadInfos = { IoPad.IN : CoreToChip.IoPadInfo( 'pi_sp' , 'pad', ['t',] )
|
||||
, IoPad.OUT : CoreToChip.IoPadInfo( 'po_sp' , 'pad', ['i',] )
|
||||
#, IoPad.TRI_OUT : CoreToChip.IoPadInfo( 'pot_sp' , 'pad', ['i', 'b' ] )
|
||||
#, IoPad.BIDIR : CoreToChip.IoPadInfo( 'piot_sp', 'pad', ['i', 't', 'b' ] )
|
||||
}
|
||||
self._getPadLib()
|
||||
return
|
||||
|
||||
def _getPadLib ( self ):
|
||||
self.padLib = AllianceFramework.get().getLibrary( 'phlib80' )
|
||||
|
||||
if not self.padLib:
|
||||
message = [ 'CoreToChip.phlib80._getPadLib(): Unable to find Alliance "phlib80" library' ]
|
||||
raise ErrorMessage( 1, message )
|
||||
|
||||
return
|
||||
|
||||
def getNetType ( self, netName ):
|
||||
if netName.startswith('vss'): return Net.Type.GROUND
|
||||
if netName.startswith('vdd'): return Net.Type.POWER
|
||||
if netName in ('cko', 'ck'): return Net.Type.CLOCK
|
||||
return Net.Type.LOGICAL
|
||||
|
||||
def isGlobal ( self, netName ):
|
||||
if netName in self.ringNetNames: return True
|
||||
return False
|
||||
|
||||
def getCell ( self, masterCellName ):
|
||||
#cell = self.padLib.getCell( masterCellName )
|
||||
cell = AllianceFramework.get().getCell( masterCellName, Catalog.State.Views )
|
||||
if not cell:
|
||||
raise ErrorMessage( 1, 'cmos.getCell(): I/O pad library "%s" does not contain cell named "%s"' \
|
||||
% (self.padLib.getName(),masterCellName) )
|
||||
return cell
|
||||
|
||||
def _buildGroundPads ( self, ioNet ):
|
||||
ioNet.buildNets()
|
||||
vss = self.chip.getNet( 'vss' )
|
||||
vss.setExternal( True )
|
||||
vss.setGlobal ( True )
|
||||
vss.setType ( Net.Type.GROUND )
|
||||
vss.merge( ioNet.chipIntNet )
|
||||
ioNet.chipIntNet = vss
|
||||
|
||||
pads = []
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + 'ck_%d' % self.groundPadCount
|
||||
, self.getCell('pvssck2_sp') ) )
|
||||
|
||||
CoreToChip._connect( pads[0], ioNet.chipIntNet, 'vss' )
|
||||
|
||||
for pad in pads: self._connectRing( pad )
|
||||
self.groundPadCount += 1
|
||||
self.chipPads += pads
|
||||
return
|
||||
|
||||
def _buildPowerPads ( self, ioNet ):
|
||||
ioNet.buildNets()
|
||||
vdd = self.chip.getNet( 'vdd' )
|
||||
vdd.setExternal( True )
|
||||
vdd.setGlobal ( True )
|
||||
vdd.setType ( Net.Type.POWER )
|
||||
vdd.merge( ioNet.chipIntNet )
|
||||
ioNet.chipIntNet = vdd
|
||||
|
||||
pads = [ ]
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + 'ck_%d' % self.powerPadCount
|
||||
, self.getCell('pvddck2_sp') ) )
|
||||
|
||||
CoreToChip._connect( pads[0], ioNet.chipIntNet, 'vdd' )
|
||||
|
||||
for pad in pads: self._connectRing( pad )
|
||||
self.powerPadCount += 1
|
||||
self.chipPads += pads
|
||||
return
|
||||
|
||||
def _buildClockPads ( self, ioNet ):
|
||||
ioNet.buildNets()
|
||||
pads = [ ]
|
||||
pads.append( Instance.create( self.chip
|
||||
, 'p_' + ioNet.padInstanceName + '_%d' % self.clockPadCount
|
||||
, self.getCell('pck_sp') ) )
|
||||
|
||||
CoreToChip._connect( pads[0], ioNet.chipExtNet, 'pad' )
|
||||
|
||||
for pad in pads: self._connectRing( pad )
|
||||
self.clockPadCount += 1
|
||||
self.chipPads += pads
|
||||
|
||||
p = re.compile( r'pv[ds]{2}ck2_sp' )
|
||||
for pad in self.chipPads:
|
||||
if p.match( pad.getMasterCell().getName() ):
|
||||
CoreToChip._connect( pad, ioNet.chipIntNet, 'cko' )
|
||||
return
|
|
@ -1,57 +0,0 @@
|
|||
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2021, 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/core2chip_cmos.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
import sys
|
||||
import helpers
|
||||
from helpers.io import ErrorMessage
|
||||
from helpers.io import WarningMessage
|
||||
import plugins
|
||||
import plugins.core2chip.cmos
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Plugin hook functions, unicornHook:menus, ScritMain:call
|
||||
|
||||
def unicornHook ( **kw ):
|
||||
kw['beforeAction'] = 'placeAndRoute.stepByStep'
|
||||
#kw['beforeAction'] = 'placeAndRoute.clockTree'
|
||||
plugins.kwAddMenu ( 'placeAndRoute' , 'P&&R', **kw )
|
||||
plugins.kwAddMenu ( 'placeAndRoute.core2chip', 'Core To Chip', **kw )
|
||||
plugins.kwUnicornHook( 'placeAndRoute.core2chip.cmos'
|
||||
, 'Symbolic CMOS I/O pads'
|
||||
, 'Wrap a complete chip around a Core for Alliance generic CMOS'
|
||||
, sys.modules[__name__].__file__
|
||||
, **kw
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
rvalue = True
|
||||
try:
|
||||
#helpers.setTraceLevel( 550 )
|
||||
cell, editor = plugins.kwParseMain( **kw )
|
||||
if not cell:
|
||||
raise ErrorMessage( 1, 'CoreToChip_cmos.scriptMain(): No cell (core) loaded in the editor yet.' )
|
||||
chip_cmos = plugins.core2chip.cmos.cmos( cell )
|
||||
chip_cmos.buildChip()
|
||||
if editor: editor.setCell( chip_cmos.chip )
|
||||
except Exception as e:
|
||||
helpers.io.catch( e )
|
||||
rvalue = False
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
return rvalue
|
|
@ -1,57 +0,0 @@
|
|||
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2021, 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/core2chip_phlib80.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
import sys
|
||||
import helpers
|
||||
from helpers.io import ErrorMessage
|
||||
from helpers.io import WarningMessage
|
||||
import plugins
|
||||
import core2chip.phlib80
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Plugin hook functions, unicornHook:menus, ScritMain:call
|
||||
|
||||
def unicornHook ( **kw ):
|
||||
kw['beforeAction'] = 'placeAndRoute.stepByStep'
|
||||
#kw['beforeAction'] = 'placeAndRoute.clockTree'
|
||||
plugins.kwAddMenu ( 'placeAndRoute' , 'P&&R', **kw )
|
||||
plugins.kwAddMenu ( 'placeAndRoute.core2chip', 'Core To Chip', **kw )
|
||||
plugins.kwUnicornHook( 'placeAndRoute.core2chip.phlib80'
|
||||
, 'Phenitec08 Symbolic CMOS I/O pads'
|
||||
, 'Wrap a complete chip around a Core for Phenitec generic CMOS'
|
||||
, sys.modules[__name__].__file__
|
||||
, **kw
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
rvalue = True
|
||||
try:
|
||||
#helpers.setTraceLevel( 550 )
|
||||
cell, editor = plugins.kwParseMain( **kw )
|
||||
if not cell:
|
||||
raise ErrorMessage( 1, 'CoreToChip_phlib80.scriptMain(): No cell (core) loaded in the editor yet.' )
|
||||
chip_phlib80 = core2chip.phlib80.phlib80( cell )
|
||||
chip_phlib80.buildChip()
|
||||
if editor: editor.setCell( chip_phlib80.chip )
|
||||
except Exception as e:
|
||||
helpers.io.catch( e )
|
||||
rvalue = False
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
return rvalue
|
|
@ -1,607 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2014-2021, 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/clocktree/clocktree.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
import os.path
|
||||
import optparse
|
||||
import math
|
||||
import Cfg
|
||||
import Hurricane
|
||||
from Hurricane import DbU
|
||||
from Hurricane import Transformation
|
||||
from Hurricane import Box
|
||||
from Hurricane import Path
|
||||
from Hurricane import Occurrence
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import Net
|
||||
from Hurricane import RoutingPad
|
||||
from Hurricane import Contact
|
||||
from Hurricane import Horizontal
|
||||
from Hurricane import Vertical
|
||||
from Hurricane import Plug
|
||||
from Hurricane import Instance
|
||||
from Hurricane import HyperNet
|
||||
import Viewer
|
||||
import CRL
|
||||
from CRL import RoutingLayerGauge
|
||||
import helpers
|
||||
from helpers import trace
|
||||
from helpers.io import ErrorMessage
|
||||
import Etesian
|
||||
import Unicorn
|
||||
import plugins
|
||||
from plugins.cts.rsmt import RSMT
|
||||
from plugins.chip.configuration import GaugeConf
|
||||
from plugins.chip.configuration import getPlugByNet
|
||||
from plugins.chip.configuration import getPlugByName
|
||||
from plugins.chip.configuration import getRpBb
|
||||
from plugins.chip.configuration import destroyNetComponents
|
||||
|
||||
|
||||
class HTree ( object ):
|
||||
|
||||
@staticmethod
|
||||
def create ( conf, cell, clockNet, clockBox ):
|
||||
if clockBox.isEmpty(): raise ErrorMessage( 3, 'ClockTree: The clock area is empty.' )
|
||||
|
||||
aspectRatio = DbU.toLambda( clockBox.getWidth() ) / DbU.toLambda( clockBox.getHeight() )
|
||||
if aspectRatio > 1.5 or aspectRatio < 0.5:
|
||||
raise ErrorMessage( 3, 'ClockTree: aspect ratio %f is disproportionate, must be between 0.5 and 1.5.' \
|
||||
% aspectRatio )
|
||||
|
||||
ht = HTree( conf, cell, clockNet, clockBox )
|
||||
print( ' o Creating clock H-Tree for "{}".'.format(cell.getName()) )
|
||||
print( ' - Clock is "{}"'.format(ht.masterClock.getName()) )
|
||||
ht.build()
|
||||
trace( 550, '\tht.build() OK\n' )
|
||||
ht.place()
|
||||
trace( 550, '\tht.place() OK\n' )
|
||||
#ht.route()
|
||||
print( ' - H-Tree depth: {}'.format(ht.getTreeDepth()) )
|
||||
trace( 550, '\tusedVTracks: %s\n' % str(ht.usedVTracks) )
|
||||
return ht
|
||||
|
||||
def __init__ ( self, conf, cell, clockNet, area ):
|
||||
self.conf = conf
|
||||
|
||||
self.minSide = Cfg.getParamInt('clockTree.minimumSide').asInt()
|
||||
if self.minSide < DbU.fromLambda(100.0):
|
||||
raise ErrorMessage( 3, 'ClockTree: clockTree.minimumSide (%g) is less than 100 lambda.' \
|
||||
% DbU.toLambda(self.minSide) )
|
||||
print( ' - Minimum side for clock area: {}'.format(DbU.toLambda(self.minSide)) )
|
||||
|
||||
UpdateSession.open()
|
||||
self.framework = CRL.AllianceFramework.get()
|
||||
self.cell = cell
|
||||
self.area = area
|
||||
self.childs = []
|
||||
self._getBufferIo()
|
||||
self.tieCell = self.framework.getCell( 'rowend_x0', CRL.Catalog.State.Views )
|
||||
self.topBuffer = Instance.create( self.cell, 'ck_htree', self.bufferCell )
|
||||
self.cloneds = [ self.cell ]
|
||||
self.usedVTracks = []
|
||||
self._feedCount = 0
|
||||
|
||||
self.masterClock = clockNet
|
||||
if not self.masterClock:
|
||||
for net in cell.getNets():
|
||||
if net.isClock():
|
||||
self.masterClock = net
|
||||
break
|
||||
if not self.masterClock:
|
||||
raise ErrorMessage( 3, 'ClockTree: Cell %s has no clock net.' % cell.getName() )
|
||||
self._createChildNet( self.topBuffer, 'ck_htree' )
|
||||
UpdateSession.close()
|
||||
|
||||
return
|
||||
|
||||
def _getBufferIo ( self ):
|
||||
self.bufferCell = self.framework.getCell( Cfg.getParamString('clockTree.buffer').asString()
|
||||
, CRL.Catalog.State.Views )
|
||||
if not self.bufferCell:
|
||||
raise ErrorMessage( 3, [ 'ClockTree: Buffer cell "%s" not found in library,' \
|
||||
% Cfg.getParamString('clockTree.buffer').asString()
|
||||
, ' please check the "clockTree.buffer" configuration parameter in "plugins.conf".' ] )
|
||||
|
||||
for net in self.bufferCell.getNets():
|
||||
if not net.isExternal(): continue
|
||||
if net.isGlobal(): continue
|
||||
if net.getDirection() & Net.Direction.IN: self.bufferIn = net.getName()
|
||||
elif net.getDirection() & Net.Direction.OUT: self.bufferOut = net.getName()
|
||||
|
||||
trace( 550, '\tbufferIn :<%s>\n' % self.bufferIn )
|
||||
trace( 550, '\tbufferOut:<%s>\n' % self.bufferOut )
|
||||
return
|
||||
|
||||
def _createChildNet ( self, ibuffer, tag ):
|
||||
childNet = Net.create( self.cell, tag )
|
||||
childNet.setType( Net.Type.CLOCK )
|
||||
getPlugByName(ibuffer, self.bufferOut).setNet( childNet )
|
||||
return
|
||||
|
||||
def feedCounter ( self ):
|
||||
self._feedCount += 1
|
||||
return self._feedCount
|
||||
|
||||
def toXCellGrid ( self, x ): return x - (x % self.conf.cellGauge.getSliceStep ())
|
||||
def toYCellGrid ( self, y ): return y - (y % self.conf.cellGauge.getSliceHeight())
|
||||
|
||||
def rpDistance ( self, rp1, rp2 ):
|
||||
dx = abs( rp1.getX() - rp2.getX() )
|
||||
dy = abs( self.toYCellGrid(rp1.getY()) - self.toYCellGrid(rp2.getY()) )
|
||||
return dx+dy
|
||||
|
||||
def placeInstance ( self, instance, x, y ):
|
||||
xslice = self.toXCellGrid(x)
|
||||
yslice = self.toYCellGrid(y)
|
||||
|
||||
transformation = Transformation.Orientation.ID
|
||||
if ((yslice-self.area.getYMin()) // self.conf.cellGauge.getSliceHeight()) % 2 != 0:
|
||||
transformation = Transformation.Orientation.MY
|
||||
yslice += self.conf.cellGauge.getSliceHeight()
|
||||
|
||||
instance.setTransformation ( Transformation(xslice, yslice, transformation) )
|
||||
instance.setPlacementStatus( Instance.PlacementStatus.FIXED )
|
||||
return
|
||||
|
||||
def destroyInstance ( self, instance ):
|
||||
transformation = instance.getTransformation()
|
||||
instanceWidth = instance.getMasterCell().getAbutmentBox().getWidth()
|
||||
tieWidth = self.tieCell.getAbutmentBox().getWidth()
|
||||
|
||||
instance.destroy()
|
||||
x = transformation.getTx()
|
||||
for i in range(instanceWidth//tieWidth):
|
||||
feed = Instance.create( self.cell
|
||||
, 'htree_feed_%i' % self.feedCounter()
|
||||
, self.tieCell
|
||||
, Transformation(x,transformation.getTy(),transformation.getOrientation())
|
||||
, Instance.PlacementStatus.PLACED
|
||||
)
|
||||
x += tieWidth
|
||||
return
|
||||
|
||||
def getTreeDepth ( self ):
|
||||
return self.childs[0].getTreeDepth()
|
||||
|
||||
def getLeafBufferUnder ( self, point ):
|
||||
return self.childs[0].getLeafBufferUnder( point )
|
||||
|
||||
def addLeaf ( self, point, plugOccurrence ):
|
||||
self.childs[0].addLeaf( point, plugOccurrence )
|
||||
|
||||
def build ( self ):
|
||||
self.childs.append( HTreeNode( self, self.topBuffer, self.area, '', HTreeNode.RootBranch ) )
|
||||
return
|
||||
|
||||
def place ( self ):
|
||||
UpdateSession.open()
|
||||
center = self.area.getCenter()
|
||||
self.placeInstance( self.topBuffer, center.getX(), center.getY() )
|
||||
trace( 550, '\rplace top level\n' )
|
||||
self.usedVTracks += [ getRpBb(self.topBuffer, self.bufferIn).getCenter().getX() ]
|
||||
self.childs[0].place()
|
||||
UpdateSession.close()
|
||||
return
|
||||
|
||||
def route ( self ):
|
||||
UpdateSession.open()
|
||||
self.childs[0].route()
|
||||
UpdateSession.close()
|
||||
return
|
||||
|
||||
def prune ( self ):
|
||||
UpdateSession.open()
|
||||
self.childs[0].prune()
|
||||
UpdateSession.close()
|
||||
return
|
||||
|
||||
def addCloned ( self, masterCell ):
|
||||
if not masterCell in self.cloneds: self.cloneds.append( masterCell )
|
||||
return
|
||||
|
||||
def addDeepPlug ( self, topNet, path ):
|
||||
if path.isEmpty(): return None
|
||||
|
||||
tailPath = path.getTailPath()
|
||||
headInstance = path.getHeadInstance()
|
||||
headPlug = getPlugByNet(headInstance,topNet)
|
||||
if headPlug:
|
||||
if tailPath.isEmpty(): return headPlug
|
||||
return self.addDeepPlug( headPlug.getMasterNet(), tailPath )
|
||||
|
||||
masterCell = headInstance.getMasterCell()
|
||||
masterNet = Net.create( masterCell, topNet.getName() )
|
||||
masterNet.setExternal ( True )
|
||||
masterNet.setType ( Net.Type.CLOCK )
|
||||
masterNet.setDirection( Net.Direction.IN )
|
||||
headPlug = headInstance.getPlug( masterNet )
|
||||
if not headPlug:
|
||||
raise ErrorMessage( 3, 'Plug not created for %s on instance %s of %s' \
|
||||
% (topNet.getName(),headInstance.getName(),masterCell.getName()) )
|
||||
headPlug.setNet( topNet )
|
||||
self.addCloned( masterCell )
|
||||
|
||||
if tailPath.isEmpty(): return headPlug
|
||||
return self.addDeepPlug( masterNet, tailPath )
|
||||
|
||||
def _RSMTtoLayout( self, mst, net ):
|
||||
for node in mst.nodes:
|
||||
if not node.component:
|
||||
x = node.realX
|
||||
if node.realX in self.usedVTracks:
|
||||
x += self.conf.routingGauge.getLayerGauge(self.conf.verticalDeepDepth).getPitch()
|
||||
# This is a Steiner point.
|
||||
node.component = self.conf.createContact( net
|
||||
, x
|
||||
, node.y + self.conf.cellGauge.getSliceHeight()//2 - self.conf.routingGauge.getLayerGauge(self.horizontalDeepDepth).getPitch()
|
||||
, GaugeConf.DeepDepth )
|
||||
trace( 550, '\tCreate (Steiner) node.component: @Y%d (y:%d - %d) %s\n' \
|
||||
% (DbU.toLambda(node.realY)
|
||||
,DbU.toLambda(node.y)
|
||||
,DbU.toLambda(self.conf.routingGauge.getLayerGauge(self.horizontalDeepDepth).getPitch())
|
||||
,node.component) )
|
||||
else:
|
||||
# This a terminal (graph) point
|
||||
for edge in node.edges:
|
||||
flags = GaugeConf.HAccess|GaugeConf.DeepDepth
|
||||
if not edge.isHorizontal():
|
||||
if node.isSame(edge.source) or edge.isVertical():
|
||||
flags &= ~GaugeConf.HAccess
|
||||
break
|
||||
flags |= GaugeConf.OffsetTop1
|
||||
if node.realX in self.usedVTracks:
|
||||
flags |= GaugeConf.OffsetRight1
|
||||
node.component = self.conf.rpAccess( node.component, flags )
|
||||
|
||||
for edge in mst.edges:
|
||||
sourceContact = edge.source.component
|
||||
targetContact = edge.target.component
|
||||
|
||||
if edge.isHorizontal():
|
||||
self.createHorizontal( sourceContact, targetContact, targetContact.getY(), GaugeConf.DeepDepth )
|
||||
elif edge.isVertical():
|
||||
self.createVertical ( sourceContact, targetContact, sourceContact.getX(), GaugeConf.DeepDepth )
|
||||
else:
|
||||
turn = self.conf.createContact( edge.source.component.getNet()
|
||||
, sourceContact.getX()
|
||||
, targetContact.getY()
|
||||
, GaugeConf.DeepDepth )
|
||||
self.conf.createVertical ( sourceContact, turn, sourceContact.getX(), GaugeConf.DeepDepth )
|
||||
self.conf.createHorizontal( turn, targetContact, targetContact.getY(), GaugeConf.DeepDepth )
|
||||
return
|
||||
|
||||
def _connectLeafs ( self, leafBuffer, leafs ):
|
||||
trace( 550, ',+', '\tBuffer <%s> has %i leafs.\n' % (leafBuffer.getName(),len(leafs)) )
|
||||
#if len(leafs) == 0: return
|
||||
#
|
||||
#leafCk = getPlugByName(leafBuffer,self.bufferOut).getNet()
|
||||
#bufferRp = self.rpByPlugName( leafBuffer, self.bufferOut, leafCk )
|
||||
#
|
||||
#rsmt = RSMT( leafCk.getName() )
|
||||
#rsmt.addNode( bufferRp, bufferRp.getX(), self.toYCellGrid(bufferRp.getY()) )
|
||||
#for leaf in leafs:
|
||||
# registerRp = self.rpByOccurrence( leaf, leafCk )
|
||||
# rsmt.addNode( registerRp, registerRp.getX(), self.toYCellGrid(registerRp.getY()) )
|
||||
#
|
||||
#rsmt.runI1S()
|
||||
#self._RSMTtoLayout( rsmt, leafCk )
|
||||
|
||||
trace( 550, '-' )
|
||||
return
|
||||
|
||||
def connectLeaf ( self ):
|
||||
trace( 550, '\tConnecting leafs.\n' )
|
||||
UpdateSession.open()
|
||||
|
||||
leafsByBuffer = {}
|
||||
hyperMasterClock = HyperNet.create( Occurrence(self.masterClock) )
|
||||
for plugOccurrence in hyperMasterClock.getTerminalNetlistPlugOccurrences():
|
||||
trace( 550, '\tAdding leaf <%s>.\n' % plugOccurrence )
|
||||
position = plugOccurrence.getBoundingBox().getCenter()
|
||||
self.addLeaf( position, plugOccurrence )
|
||||
|
||||
self.childs[0].connectLeafs()
|
||||
sys.stdout.flush()
|
||||
|
||||
getPlugByName( self.topBuffer, self.bufferIn ).setNet( self.masterClock )
|
||||
UpdateSession.close()
|
||||
|
||||
return
|
||||
|
||||
def _rsave ( self, cell ):
|
||||
flags = CRL.Catalog.State.Physical
|
||||
if cell.getName().endswith('_cts'):
|
||||
flags = flags | CRL.Catalog.State.Logical
|
||||
self.framework.saveCell( cell, flags )
|
||||
|
||||
for instance in cell.getInstances():
|
||||
masterCell = instance.getMasterCell()
|
||||
if not masterCell.isTerminal():
|
||||
self._rsave( masterCell )
|
||||
|
||||
def save ( self, topCell ):
|
||||
for cell in self.cloneds:
|
||||
cell.setName( cell.getName()+'_cts' )
|
||||
|
||||
self._rsave( topCell )
|
||||
return
|
||||
|
||||
|
||||
class HTreeNode ( object ):
|
||||
|
||||
RootBranch = 0x0001
|
||||
LeftBranch = 0x0002
|
||||
RightBranch = 0x0004
|
||||
UpBranch = 0x0008
|
||||
DownBranch = 0x0010
|
||||
|
||||
def __init__ ( self, topTree, sourceBuffer, area, prefix, flags ):
|
||||
UpdateSession.open()
|
||||
self.topTree = topTree
|
||||
self.childs = []
|
||||
self.blLeafs = []
|
||||
self.brLeafs = []
|
||||
self.tlLeafs = []
|
||||
self.trLeafs = []
|
||||
self.flags = flags
|
||||
self.sourceBuffer = sourceBuffer
|
||||
self.area = area
|
||||
self.prefix = prefix
|
||||
|
||||
self.blBuffer = Instance.create( self.topTree.cell, 'ck_htree'+self.prefix+'_bl_ins', self.topTree.bufferCell )
|
||||
self.brBuffer = Instance.create( self.topTree.cell, 'ck_htree'+self.prefix+'_br_ins', self.topTree.bufferCell )
|
||||
self.tlBuffer = Instance.create( self.topTree.cell, 'ck_htree'+self.prefix+'_tl_ins', self.topTree.bufferCell )
|
||||
self.trBuffer = Instance.create( self.topTree.cell, 'ck_htree'+self.prefix+'_tr_ins', self.topTree.bufferCell )
|
||||
self.ckNet = getPlugByName(self.sourceBuffer, self.topTree.bufferOut).getNet()
|
||||
getPlugByName(self.blBuffer, self.topTree.bufferIn).setNet( self.ckNet )
|
||||
getPlugByName(self.brBuffer, self.topTree.bufferIn).setNet( self.ckNet )
|
||||
getPlugByName(self.tlBuffer, self.topTree.bufferIn).setNet( self.ckNet )
|
||||
getPlugByName(self.trBuffer, self.topTree.bufferIn).setNet( self.ckNet )
|
||||
|
||||
self.topTree._createChildNet( self.blBuffer, 'ck_htree'+self.prefix+'_bl' )
|
||||
self.topTree._createChildNet( self.brBuffer, 'ck_htree'+self.prefix+'_br' )
|
||||
self.topTree._createChildNet( self.tlBuffer, 'ck_htree'+self.prefix+'_tl' )
|
||||
self.topTree._createChildNet( self.trBuffer, 'ck_htree'+self.prefix+'_tr' )
|
||||
|
||||
halfWidth = self.area.getHalfWidth ()
|
||||
halfHeight = self.area.getHalfHeight()
|
||||
if halfWidth >= self.topTree.minSide and halfHeight >= self.topTree.minSide:
|
||||
# Recursive call.
|
||||
self.childs.append( HTreeNode( self.topTree, self.blBuffer, self.blArea(), self.prefix+'_bl', 0 ) )
|
||||
self.childs.append( HTreeNode( self.topTree, self.brBuffer, self.brArea(), self.prefix+'_br', 0 ) )
|
||||
self.childs.append( HTreeNode( self.topTree, self.tlBuffer, self.tlArea(), self.prefix+'_tl', 0 ) )
|
||||
self.childs.append( HTreeNode( self.topTree, self.trBuffer, self.trArea(), self.prefix+'_tr', 0 ) )
|
||||
|
||||
UpdateSession.close()
|
||||
return
|
||||
|
||||
def xmin ( self ): return self.area.getXMin()
|
||||
def xmax ( self ): return self.area.getXMax()
|
||||
def ymin ( self ): return self.area.getYMin()
|
||||
def ymax ( self ): return self.area.getYMax()
|
||||
def halfWidth ( self ): return self.area.getHalfWidth()
|
||||
def halfHeight( self ): return self.area.getHalfHeight()
|
||||
|
||||
def blArea ( self ):
|
||||
return Box( self.xmin() , self.ymin()
|
||||
, self.xmin()+self.halfWidth(), self.ymin()+self.halfHeight() )
|
||||
|
||||
def brArea ( self ):
|
||||
return Box( self.xmin()+self.halfWidth(), self.ymin()
|
||||
, self.xmax() , self.ymin()+self.halfHeight() )
|
||||
|
||||
def tlArea ( self ):
|
||||
return Box( self.xmin() , self.ymin()+self.halfHeight()
|
||||
, self.xmin()+self.halfWidth(), self.ymax() )
|
||||
|
||||
def trArea ( self ):
|
||||
return Box( self.xmin()+self.halfWidth(), self.ymin()+self.halfHeight()
|
||||
, self.xmax() , self.ymax() )
|
||||
|
||||
def getTreeDepth ( self ):
|
||||
if self.childs: return self.childs[0].getTreeDepth()+1
|
||||
return 1
|
||||
|
||||
def hasLeafs ( self ):
|
||||
hasLeafsFlag = False
|
||||
if self.childs:
|
||||
hasLeafsFlag |= self.childs[0].hasLeafs()
|
||||
hasLeafsFlag |= self.childs[1].hasLeafs()
|
||||
hasLeafsFlag |= self.childs[2].hasLeafs()
|
||||
hasLeafsFlag |= self.childs[3].hasLeafs()
|
||||
return hasLeafsFlag
|
||||
|
||||
hasLeafsFlag |= (len(self.blLeafs) != 0)
|
||||
hasLeafsFlag |= (len(self.brLeafs) != 0)
|
||||
hasLeafsFlag |= (len(self.tlLeafs) != 0)
|
||||
hasLeafsFlag |= (len(self.trLeafs) != 0)
|
||||
return hasLeafsFlag
|
||||
|
||||
def addLeaf ( self, point, plugOccurrence ):
|
||||
if self.childs:
|
||||
if self.blArea().contains(point): self.childs[0].addLeaf( point, plugOccurrence )
|
||||
elif self.brArea().contains(point): self.childs[1].addLeaf( point, plugOccurrence )
|
||||
elif self.tlArea().contains(point): self.childs[2].addLeaf( point, plugOccurrence )
|
||||
else: self.childs[3].addLeaf( point, plugOccurrence )
|
||||
return
|
||||
|
||||
leafBuffer = None
|
||||
if self.blArea().contains(point):
|
||||
self.blLeafs.append( plugOccurrence )
|
||||
leafBuffer = self.blBuffer
|
||||
elif self.brArea().contains(point):
|
||||
self.brLeafs.append( plugOccurrence )
|
||||
leafBuffer = self.brBuffer
|
||||
elif self.tlArea().contains(point):
|
||||
self.tlLeafs.append( plugOccurrence )
|
||||
leafBuffer = self.tlBuffer
|
||||
else:
|
||||
self.trLeafs.append( plugOccurrence )
|
||||
leafBuffer = self.trBuffer
|
||||
|
||||
leafCk = getPlugByName(leafBuffer,self.topTree.bufferOut).getNet()
|
||||
deepPlug = self.topTree.addDeepPlug( leafCk, plugOccurrence.getPath() )
|
||||
if deepPlug:
|
||||
leafCk = deepPlug.getMasterNet()
|
||||
plugOccurrence.getEntity().setNet( leafCk )
|
||||
|
||||
trace( 550, '\tLeaf clock set to <%s>.\n' % plugOccurrence.getEntity() )
|
||||
|
||||
return
|
||||
|
||||
def getLeafBufferUnder ( self, point ):
|
||||
if self.childs:
|
||||
if self.blArea().contains(point): return self.childs[0].getLeafBufferUnder(point)
|
||||
if self.brArea().contains(point): return self.childs[1].getLeafBufferUnder(point)
|
||||
if self.tlArea().contains(point): return self.childs[2].getLeafBufferUnder(point)
|
||||
if self.trArea().contains(point): return self.childs[3].getLeafBufferUnder(point)
|
||||
|
||||
if self.blArea().contains(point): return self.blBuffer
|
||||
if self.brArea().contains(point): return self.brBuffer
|
||||
if self.tlArea().contains(point): return self.tlBuffer
|
||||
return self.trBuffer
|
||||
|
||||
def place ( self ):
|
||||
trace( 550, '\rplace HTreeNode %s\n' % self.ckNet.getName() )
|
||||
x = self.area.getXMin() + self.area.getWidth ()//4
|
||||
y = self.area.getYMin() + self.area.getHeight()//4
|
||||
halfWidth = self.area.getHalfWidth ()
|
||||
halfHeight = self.area.getHalfHeight()
|
||||
|
||||
self.topTree.placeInstance( self.blBuffer, x , y )
|
||||
self.topTree.placeInstance( self.brBuffer, x+halfWidth, y )
|
||||
self.topTree.placeInstance( self.tlBuffer, x , y+halfHeight )
|
||||
self.topTree.placeInstance( self.trBuffer, x+halfWidth, y+halfHeight )
|
||||
|
||||
self.topTree.usedVTracks += \
|
||||
[ self.topTree.conf.rpAccessByPlugName( self.blBuffer, self.topTree.bufferIn, self.ckNet ).getX()
|
||||
, self.topTree.conf.rpAccessByPlugName( self.brBuffer, self.topTree.bufferIn, self.ckNet ).getX() ]
|
||||
|
||||
for child in self.childs: child.place()
|
||||
return
|
||||
|
||||
def route ( self ):
|
||||
trace( 550, '\tHTreeNode.route() %s\n' % self.sourceBuffer.getName() )
|
||||
|
||||
leftSourceContact = self.topTree.conf.rpAccessByPlugName( self.sourceBuffer, self.topTree.bufferOut, self.ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 )
|
||||
rightSourceContact = self.topTree.conf.rpAccessByPlugName( self.sourceBuffer, self.topTree.bufferOut, self.ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 )
|
||||
blContact = self.topTree.conf.rpAccessByPlugName( self.blBuffer , self.topTree.bufferIn , self.ckNet )
|
||||
brContact = self.topTree.conf.rpAccessByPlugName( self.brBuffer , self.topTree.bufferIn , self.ckNet )
|
||||
tlContact = self.topTree.conf.rpAccessByPlugName( self.tlBuffer , self.topTree.bufferIn , self.ckNet )
|
||||
trContact = self.topTree.conf.rpAccessByPlugName( self.trBuffer , self.topTree.bufferIn , self.ckNet )
|
||||
leftContact = self.topTree.conf.createContact( self.ckNet, blContact.getX(), leftSourceContact.getY() )
|
||||
rightContact = self.topTree.conf.createContact( self.ckNet, brContact.getX(), rightSourceContact.getY() )
|
||||
|
||||
leftSourceX = self.topTree.conf.getNearestVerticalTrack ( self.topTree.area, leftSourceContact.getX(), 0 )
|
||||
leftSourceY = self.topTree.conf.getNearestHorizontalTrack( self.topTree.area, leftSourceContact.getY(), 0 )
|
||||
rightSourceX = self.topTree.conf.getNearestVerticalTrack ( self.topTree.area, rightSourceContact.getX(), 0 )
|
||||
rightSourceY = self.topTree.conf.getNearestHorizontalTrack( self.topTree.area, rightSourceContact.getY(), 0 )
|
||||
leftX = self.topTree.conf.getNearestVerticalTrack ( self.topTree.area, leftContact.getX(), 0 )
|
||||
rightX = self.topTree.conf.getNearestVerticalTrack ( self.topTree.area, rightContact.getX(), 0 )
|
||||
tlY = self.topTree.conf.getNearestHorizontalTrack( self.topTree.area, tlContact.getY(), 0 )
|
||||
blY = self.topTree.conf.getNearestHorizontalTrack( self.topTree.area, blContact.getY(), 0 )
|
||||
|
||||
self.topTree.conf.setStackPosition( leftSourceContact, leftSourceX, leftSourceY )
|
||||
self.topTree.conf.setStackPosition( rightSourceContact, rightSourceX, rightSourceY )
|
||||
self.topTree.conf.setStackPosition( tlContact, leftX, tlY )
|
||||
self.topTree.conf.setStackPosition( blContact, leftX, blY )
|
||||
self.topTree.conf.setStackPosition( trContact, rightX, tlY )
|
||||
self.topTree.conf.setStackPosition( brContact, rightX, blY )
|
||||
|
||||
leftContact .setX( leftX )
|
||||
leftContact .setY( leftSourceY )
|
||||
rightContact.setX( rightX )
|
||||
rightContact.setY( rightSourceY )
|
||||
|
||||
self.topTree.conf.createHorizontal( leftContact , leftSourceContact, leftSourceY , 0 )
|
||||
self.topTree.conf.createHorizontal( rightSourceContact, rightContact , rightSourceY, 0 )
|
||||
self.topTree.conf.createVertical ( leftContact , blContact , leftX , 0 )
|
||||
self.topTree.conf.createVertical ( tlContact , leftContact , leftX , 0 )
|
||||
self.topTree.conf.createVertical ( rightContact , brContact , rightX , 0 )
|
||||
self.topTree.conf.createVertical ( trContact , rightContact , rightX , 0 )
|
||||
|
||||
for child in self.childs: child.route()
|
||||
return
|
||||
|
||||
def connectLeafs ( self ):
|
||||
if not self.hasLeafs():
|
||||
trace( 550, '\tHTreeNode.connectLeafs() %s has no leafs\n' % self.sourceBuffer.getName() )
|
||||
|
||||
if self.childs:
|
||||
self.childs[0].connectLeafs()
|
||||
self.childs[1].connectLeafs()
|
||||
self.childs[2].connectLeafs()
|
||||
self.childs[3].connectLeafs()
|
||||
return
|
||||
|
||||
if len(self.blLeafs): self.topTree._connectLeafs( self.blBuffer, self.blLeafs )
|
||||
if len(self.brLeafs): self.topTree._connectLeafs( self.brBuffer, self.brLeafs )
|
||||
if len(self.tlLeafs): self.topTree._connectLeafs( self.tlBuffer, self.tlLeafs )
|
||||
if len(self.trLeafs): self.topTree._connectLeafs( self.trBuffer, self.trLeafs )
|
||||
return
|
||||
|
||||
def prune ( self ):
|
||||
for child in self.childs: child.prune()
|
||||
if self.hasLeafs(): return
|
||||
|
||||
destroyNetComponents( self.ckNet )
|
||||
|
||||
self.topTree.destroyInstance( self.blBuffer )
|
||||
self.topTree.destroyInstance( self.brBuffer )
|
||||
self.topTree.destroyInstance( self.tlBuffer )
|
||||
self.topTree.destroyInstance( self.trBuffer )
|
||||
return
|
||||
|
||||
|
||||
def computeAbutmentBox ( cell, spaceMargin, aspectRatio, cellGauge ):
|
||||
# sliceHeight = DbU.toLambda( cellGauge.getSliceHeight() )
|
||||
#
|
||||
# instancesNb = 0
|
||||
# cellLength = 0
|
||||
# for occurrence in cell.getTerminalNetlistInstanceOccurrences():
|
||||
# instance = occurrence.getEntity()
|
||||
# instancesNb += 1
|
||||
# cellLength += int( DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()) )
|
||||
#
|
||||
# # ar = x//y S = x*y = spaceMargin*SH x=S//y ar = S//y^2
|
||||
# # y = sqrt(S//AR)
|
||||
# gcellLength = float(cellLength)*(1+spaceMargin) // sliceHeight
|
||||
# rows = math.sqrt( gcellLength//aspectRatio )
|
||||
# if math.trunc(rows) != rows: rows = math.trunc(rows) + 1
|
||||
# else: rows = math.trunc(rows)
|
||||
# columns = gcellLength // rows
|
||||
# if math.trunc(columns) != columns: columns = math.trunc(columns) + 1
|
||||
# else: columns = math.trunc(columns)
|
||||
#
|
||||
# print ' o Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \
|
||||
# % (spaceMargin*100.0,aspectRatio*100.0,(cellLength//sliceHeight))
|
||||
# print ' - GCell grid: [%dx%d]' % (columns,rows)
|
||||
|
||||
UpdateSession.open()
|
||||
etesian = Etesian.EtesianEngine.create( cell )
|
||||
etesian.setDefaultAb()
|
||||
etesian.destroy()
|
||||
|
||||
#abutmentBox = Box( DbU.fromLambda(0)
|
||||
# , DbU.fromLambda(0)
|
||||
# , DbU.fromLambda(columns*sliceHeight)
|
||||
# , DbU.fromLambda(rows *sliceHeight)
|
||||
# )
|
||||
#cell.setAbutmentBox( abutmentBox )
|
||||
UpdateSession.close()
|
||||
|
||||
return cell.getAbutmentBox()
|
|
@ -1,363 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2014-2021, 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/clocktree/rsmt.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import sys
|
||||
import Cfg
|
||||
import Hurricane
|
||||
from Hurricane import DbU
|
||||
from Hurricane import Box
|
||||
from Hurricane import Path
|
||||
from Hurricane import Occurrence
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import Net
|
||||
from Hurricane import RoutingPad
|
||||
from Hurricane import Contact
|
||||
from Hurricane import Horizontal
|
||||
from Hurricane import Vertical
|
||||
from Hurricane import Instance
|
||||
import Viewer
|
||||
import CRL
|
||||
from CRL import RoutingLayerGauge
|
||||
import helpers
|
||||
from helpers import trace
|
||||
from helpers.io import ErrorMessage
|
||||
import plugins
|
||||
|
||||
|
||||
def manhattanDistance ( node1, node2 ):
|
||||
return abs(node1.x - node2.x) + abs(node1.y - node2.y)
|
||||
|
||||
|
||||
class Node ( object ):
|
||||
|
||||
GraphPoint = 0x0001
|
||||
SteinerPoint = 0x0002
|
||||
KeepPoint = 0x0004
|
||||
|
||||
@staticmethod
|
||||
def showNodes ( level, nodes ):
|
||||
for node in nodes:
|
||||
trace( level, node )
|
||||
return
|
||||
|
||||
def __init__ ( self, component, x, y, flags=0 ):
|
||||
self._component = component
|
||||
self._edges = [ ]
|
||||
self._x = x
|
||||
self._y = y
|
||||
self._realY = y
|
||||
self._back = None
|
||||
self._distance = DbU.fromLambda(1000.0)
|
||||
self._flags = flags
|
||||
|
||||
if component: self._flags = self._flags|Node.GraphPoint|Node.KeepPoint
|
||||
else: self._flags = self._flags|Node.SteinerPoint
|
||||
return
|
||||
|
||||
def __cmp__ ( self, other ):
|
||||
return self.distance - other.distance
|
||||
|
||||
def __str__ ( self ):
|
||||
return '<Node P:%d,%d (realY:%d) d:%d %s>' % ( DbU.toLambda(self.x)
|
||||
, DbU.toLambda(self.y)
|
||||
, DbU.toLambda(self.realY)
|
||||
, DbU.toLambda(self.distance)
|
||||
, str(self.component)
|
||||
)
|
||||
|
||||
@property
|
||||
def component ( self ): return self._component
|
||||
@property
|
||||
def x ( self ): return self._x
|
||||
@property
|
||||
def y ( self ): return self._y
|
||||
@property
|
||||
def realX ( self ): return self._x
|
||||
@property
|
||||
def realY ( self ): return self._realY
|
||||
@property
|
||||
def back ( self ): return self._back
|
||||
@property
|
||||
def distance ( self ): return self._distance
|
||||
@property
|
||||
def flags ( self ): return self._flags
|
||||
@property
|
||||
def edges ( self ): return self._edges
|
||||
@property
|
||||
def degree ( self ): return len(self._edges)
|
||||
@component.setter
|
||||
def component ( self, component ): self._component = component
|
||||
@realY.setter
|
||||
def realY ( self, y ): self._realY = y
|
||||
|
||||
def setFlags ( self, flags ): self._flags = self._flags | flags
|
||||
def unsetFlags ( self, flags ): self._flags = self._flags & ~flags
|
||||
|
||||
def addEdge ( self, edge ): self._edges.append( edge )
|
||||
def delEdge ( self, edge ):
|
||||
for i in range(len(self._edges)):
|
||||
if self._edges[i] == edge:
|
||||
del self._edges[i]
|
||||
return
|
||||
|
||||
def isSame ( self, other ): return id(self) == id(other)
|
||||
|
||||
def update ( self, node ):
|
||||
distance = manhattanDistance( self, node )
|
||||
if distance < self.distance:
|
||||
self._distance = distance
|
||||
self._back = node
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Edge ( object ):
|
||||
|
||||
def __init__ ( self, source, target ):
|
||||
self._source = source
|
||||
self._target = target
|
||||
self._length = manhattanDistance( self._source, self._target )
|
||||
self._source.addEdge( self )
|
||||
self._target.addEdge( self )
|
||||
return
|
||||
|
||||
def __del__ ( self ):
|
||||
self._source.delEdge( self )
|
||||
self._target.delEdge( self )
|
||||
return
|
||||
|
||||
def __str__ ( self ):
|
||||
return '<Edge S:%d,%d T:%d,%d len:%d>' % ( DbU.toLambda(self.source.x)
|
||||
, DbU.toLambda(self.source.y)
|
||||
, DbU.toLambda(self.target.x)
|
||||
, DbU.toLambda(self.target.y)
|
||||
, DbU.toLambda(self.length)
|
||||
)
|
||||
|
||||
@property
|
||||
def source ( self ): return self._source
|
||||
@property
|
||||
def target ( self ): return self._target
|
||||
@property
|
||||
def length ( self ): return self._length
|
||||
|
||||
def isHorizontal ( self ): return self.source.y == self.target.y
|
||||
def isVertical ( self ): return self.source.x == self.target.x
|
||||
|
||||
|
||||
class Graph ( object ):
|
||||
|
||||
def __init__ ( self, name ):
|
||||
self._nodes = [ ]
|
||||
self._edges = [ ]
|
||||
self._length = 0
|
||||
self._name = name
|
||||
return
|
||||
|
||||
def __len__ ( self ): return self._length
|
||||
|
||||
@property
|
||||
def name ( self ): return self._name
|
||||
@property
|
||||
def length ( self ): return self._length
|
||||
@property
|
||||
def nodes ( self ): return self._nodes
|
||||
@property
|
||||
def edges ( self ): return self._edges
|
||||
|
||||
def addNode ( self, component, x, y ):
|
||||
self._nodes.append( Node( component, x, y ) )
|
||||
return self._nodes[-1]
|
||||
|
||||
def copyNode ( self, node ):
|
||||
self.addNode( node.component, node.x, node.y )
|
||||
self._nodes[-1].realY = node.realY
|
||||
|
||||
def setNodes ( self, nodes ):
|
||||
self.__init__( self.name )
|
||||
for node in nodes:
|
||||
self.copyNode( node )
|
||||
return
|
||||
|
||||
def showNodes ( self, level ):
|
||||
trace( level, '+,+', '\tGraph Nodes:\n' )
|
||||
for node in self._nodes:
|
||||
trace( level, node )
|
||||
trace(level, '--')
|
||||
return
|
||||
|
||||
def showEdges ( self, level ):
|
||||
trace( level, '+,+', '\tGraph Edges:\n' )
|
||||
for edge in self._edges:
|
||||
trace( level, edge )
|
||||
trace(level, '--')
|
||||
return
|
||||
|
||||
|
||||
class RMST ( Graph ):
|
||||
|
||||
def __init__ ( self, name ):
|
||||
Graph.__init__( self, name )
|
||||
return
|
||||
|
||||
def runPrim ( self ):
|
||||
self._edges = [ ]
|
||||
self._length = 0
|
||||
|
||||
if len(self._nodes) < 2: return
|
||||
if len(self._nodes) == 2:
|
||||
self._edges.append( Edge( self._nodes[0], self._nodes[1] ) )
|
||||
self._length = self._edges[0].length
|
||||
return
|
||||
|
||||
trace(500, '+')
|
||||
|
||||
toReach = [ ]
|
||||
self._nodes[0]._distance = 0
|
||||
for node in self._nodes[1:]:
|
||||
node.update( self._nodes[0] )
|
||||
toReach.append( node )
|
||||
toReach.sort()
|
||||
|
||||
trace( 500, '+' , '\tPrim (initial stack)\n' )
|
||||
trace( 500, '+,+', '\tS %s\n' % self._nodes[0] )
|
||||
Node.showNodes( 500, toReach )
|
||||
trace( 500, '---' )
|
||||
|
||||
while len(toReach):
|
||||
nearest = toReach.pop(0)
|
||||
self._edges.append( Edge( nearest, nearest.back ) )
|
||||
trace( 500, '++,--', '\tAdding %s\n' % self._edges[-1] )
|
||||
|
||||
for node in toReach:
|
||||
node.update( nearest )
|
||||
toReach.sort()
|
||||
|
||||
trace( 500, '+' , '\tPrim (current stack)\n' )
|
||||
trace( 500, '+,+', '\tS %s\n' % self._nodes[0] )
|
||||
Node.showNodes( 500, toReach )
|
||||
trace( 500, '---' )
|
||||
|
||||
for edge in self._edges:
|
||||
self._length += edge.length
|
||||
|
||||
trace( 500, '-' )
|
||||
return
|
||||
|
||||
|
||||
class RSMT ( Graph ):
|
||||
|
||||
def __init__ ( self, name ):
|
||||
Graph.__init__( self, name )
|
||||
self._hananNodes = [ ]
|
||||
return
|
||||
|
||||
def _computeHanan ( self ):
|
||||
xs = [ ]
|
||||
ys = [ ]
|
||||
realYs = { }
|
||||
for node in self._nodes:
|
||||
if not node.x in xs: xs.append( node.x )
|
||||
if not node.y in xs:
|
||||
ys.append( node.y )
|
||||
realYs[ node.y ] = node.component.getY()
|
||||
xs.sort()
|
||||
ys.sort()
|
||||
|
||||
trace( 550, '+,+', '\tHanan matrix: %ix%i' % (len(xs),len(ys)) )
|
||||
|
||||
self._hananNodes = [ ]
|
||||
for x in xs:
|
||||
trace( 550, '\n' )
|
||||
trace( 550, '\t' )
|
||||
for y in ys:
|
||||
isNode = False
|
||||
for node in self._nodes:
|
||||
if node.x == x and node.y == y: isNode = True
|
||||
if isNode:
|
||||
trace( 550, ' -:%04.2d,%04.2d' % (DbU.toLambda(x),DbU.toLambda(y)) )
|
||||
continue
|
||||
trace( 550, ' H:%04.2d,%04.2d' % (DbU.toLambda(x),DbU.toLambda(y)) )
|
||||
|
||||
self._hananNodes.append( Node( None, x, y ) )
|
||||
self._hananNodes[-1].realY = realYs[ y ]
|
||||
trace( 550, ',--', "\n" )
|
||||
return
|
||||
|
||||
def addNode ( self, component, x, y ):
|
||||
node = Graph.addNode( self, component, x, y )
|
||||
trace( 550, '\t New Node: %s\n' % node )
|
||||
return
|
||||
|
||||
def runI1S ( self ):
|
||||
self._edges = [ ]
|
||||
self._length = 0
|
||||
|
||||
if len(self._nodes) < 2: return
|
||||
if len(self._nodes) == 2:
|
||||
self._edges.append( Edge( self._nodes[0], self._nodes[1] ) )
|
||||
self._length = self._edges[0].length
|
||||
return
|
||||
|
||||
self._computeHanan()
|
||||
count = 0
|
||||
|
||||
trace( 550, '++' )
|
||||
minMST = RMST( 'MST[%i]' % count )
|
||||
minMST.setNodes( self._nodes )
|
||||
minMST.runPrim()
|
||||
trace( 550, '-,+', '\tInitial %s length %d\n' % (minMST.name,DbU.toLambda(len(minMST))) )
|
||||
minMST.showEdges( 550 )
|
||||
trace( 550, '-' )
|
||||
|
||||
addedSteiner = True
|
||||
while addedSteiner:
|
||||
addedSteiner = False
|
||||
for steinerNode in self._hananNodes:
|
||||
count += 1
|
||||
trace( 550, '\tTrying with Steiner point H:%d,%d\n' \
|
||||
% (DbU.toLambda(steinerNode.x),DbU.toLambda(steinerNode.y)) )
|
||||
mst = RMST( 'MST[%i]' % count )
|
||||
mst.setNodes( self._nodes )
|
||||
mst.copyNode( steinerNode )
|
||||
mst.runPrim()
|
||||
|
||||
trace( 550, '\tCurrent %s length %d\n' % (mst.name,DbU.toLambda(len(mst))) )
|
||||
mst.showEdges( 550 )
|
||||
if len(mst) < len(minMST):
|
||||
trace( 550, '\tAccept min RST.\n' )
|
||||
minMST = mst
|
||||
addedSteiner = True
|
||||
|
||||
if addedSteiner:
|
||||
self.copyNode( minMST.nodes[-1] )
|
||||
self.nodes[-1].setFlags( Node.KeepPoint )
|
||||
|
||||
i = 0
|
||||
while i < len(self._edges):
|
||||
if self._nodes[i].flags & Node.SteinerPoint \
|
||||
and self._nodes[i].degree < 3:
|
||||
trace( 550, 'Deleting unused Steiner point H:%d,%d' \
|
||||
% (DbU.toLambda(self._nodes[i].x),DbU.toLambda(self._nodes[i].y)) )
|
||||
del self._nodes[i]
|
||||
else:
|
||||
i += 1
|
||||
|
||||
self._nodes = minMST.nodes
|
||||
self._edges = minMST.edges
|
||||
self._length = minMST.length
|
||||
trace( 550, '-' )
|
||||
return
|
|
@ -1,69 +0,0 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, 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/vchannels.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
try:
|
||||
import sys
|
||||
import traceback
|
||||
import os.path
|
||||
import math
|
||||
import coriolis.Cfg as Cfg
|
||||
from ..Hurricane import Breakpoint, UpdateSession
|
||||
from ..helpers import setTraceLevel, trace, l, u, n
|
||||
from ..helpers.io import ErrorMessage, catch
|
||||
import ..plugins
|
||||
import .block.vchannels
|
||||
except Exception as e:
|
||||
catch( e )
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Plugin hook functions, unicornHook:menus, ScritMain:call
|
||||
|
||||
def unicornHook ( **kw ):
|
||||
kw['beforeAction'] = 'placeAndRoute.placeChip'
|
||||
plugins.kwAddMenu ( 'placeAndRoute', 'P&&R', **kw )
|
||||
plugins.kwUnicornHook( 'placeAndRoute.vchannels'
|
||||
, 'Add vertical routing channels'
|
||||
, 'Create vertical spacing to increase the vertical routing capacity'
|
||||
, sys.modules[__name__].__file__
|
||||
, **kw
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
try:
|
||||
#setTraceLevel( 550 )
|
||||
errorCode = 0
|
||||
cell = None
|
||||
if 'cell' in kw and kw['cell']:
|
||||
cell = kw['cell']
|
||||
editor = None
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
print( ' o Editor found, running in graphic mode.' )
|
||||
if cell == None: cell = editor.getCell()
|
||||
if cell == None:
|
||||
raise ErrorMessage( 3, 'VChannels: No cell loaded yet.' )
|
||||
if cell.getAbutmentBox().isEmpty():
|
||||
raise ErrorMessage( 3, 'VChannels: cell "%s" is not placed yet.' % cell.getName() )
|
||||
vchannels = block.VChannels.VChannels( cell )
|
||||
for i in range(48):
|
||||
vchannels.addChannelAt( l(250.0*(i+1)), l(190.0) )
|
||||
vchannels.expandChannels()
|
||||
if editor: editor.refresh()
|
||||
except Exception as e:
|
||||
catch( e )
|
||||
return 0
|
|
@ -1,157 +0,0 @@
|
|||
|
||||
import CRL
|
||||
from Hurricane import *
|
||||
|
||||
import re
|
||||
|
||||
###########
|
||||
## GetXY ##
|
||||
###########
|
||||
def pyGetXY ( masterCell, pathname, refname ) :
|
||||
'''This function returns the coordinates of a reference thanks to its name and the path of the instance it belongs to'''
|
||||
|
||||
## MasterCell ##
|
||||
if pathname != "" :
|
||||
myPath = Path ( masterCell, pathname )
|
||||
tInst = myPath.getTailInstance()
|
||||
masterCell = tInst.getMasterCell()
|
||||
|
||||
## Reference ##
|
||||
myRef = None
|
||||
for el in masterCell.getReferences():
|
||||
if str(el.getName()) == refname :
|
||||
myRef = el
|
||||
break
|
||||
|
||||
# Error : if no reference found in mastercell
|
||||
if myRef == None :
|
||||
err = "\n[Stratus ERROR] GetRefXY : No reference found with name " + refname + " in masterCell " + str(masterCell.getName()) + ".\n"
|
||||
raise err
|
||||
|
||||
## Occurrence of the Reference ##
|
||||
myOccurrence = Occurrence ( myRef, myPath )
|
||||
bb = myOccurrence.getBoundingBox()
|
||||
|
||||
return ( getValue(bb.getXCenter()), getValue(bb.getYCenter()) )
|
||||
|
||||
##############
|
||||
## PlaceRef ##
|
||||
##############
|
||||
def pyPlaceRef ( cell, name, x, y ) :
|
||||
'''This function creates a reference thanks to its coordinates'''
|
||||
|
||||
UpdateSession.open()
|
||||
|
||||
Reference ( cell
|
||||
, name
|
||||
, DbU_lambda ( x ), DbU_lambda ( y )
|
||||
)
|
||||
|
||||
UpdateSession.close()
|
||||
|
||||
##################
|
||||
## PlaceContact ##
|
||||
##################
|
||||
def pyPlaceContact ( net, layer, x, y, width, height ) :
|
||||
'''This function creates a contact'''
|
||||
|
||||
UpdateSession.open()
|
||||
|
||||
Contact ( net, layer, DbU_lambda(x), DbU_lambda(y), DbU_lambda(width), DbU_lambda(height) )
|
||||
|
||||
UpdateSession.close()
|
||||
|
||||
##############
|
||||
## PlacePin ##
|
||||
##############
|
||||
def pyPlacePin ( net, direct, placementStatus, layer, x, y, width, height ) :
|
||||
'''This function creates a pin'''
|
||||
|
||||
size = 0
|
||||
for loc in net.getPins():
|
||||
size += 1
|
||||
|
||||
UpdateSession.open()
|
||||
|
||||
Pin ( net, str(net.getName()) + "." + str(size)
|
||||
, direct
|
||||
, placementStatus
|
||||
, layer
|
||||
, DbU_lambda(x), DbU_lambda(y)
|
||||
, DbU_lambda(width), DbU_lambda(height)
|
||||
)
|
||||
|
||||
if ( not net.IsSupply() ) :
|
||||
CRL.createPartRing ( net.getCell(), net.getName() )
|
||||
|
||||
UpdateSession.close()
|
||||
|
||||
##################
|
||||
## PlaceSegment ##
|
||||
##################
|
||||
def pyPlaceSegment ( net, layer, x1, y1, x2, y2, width ) :
|
||||
'''This function creates a segment'''
|
||||
|
||||
UpdateSession.open()
|
||||
|
||||
if x1 == x2 : Vertical ( net, layer, DbU_lambda(x1), DbU_lambda(width), DbU_lambda(y1), DbU_lambda(y2) )
|
||||
elif y1 == y2 : Horizontal ( net, layer, DbU_lambda(y1), DbU_lambda(width), DbU_lambda(x1), DbU_lambda(x2) )
|
||||
|
||||
UpdateSession.close()
|
||||
|
||||
###################
|
||||
## CopyUpSegment ##
|
||||
###################
|
||||
def pyCopyUpSegment ( masterCell, pathname, netname, newnet ) :
|
||||
'''This function copies the segment of an instance in the current cell'''
|
||||
|
||||
## MasterCell ##
|
||||
if pathname != "" :
|
||||
myPath = Path ( masterCell, pathname )
|
||||
transformation = myPath.getTransformation()
|
||||
|
||||
tInst = myPath.getTailInstance()
|
||||
masterCell = tInst.getMasterCell()
|
||||
|
||||
## Net ##
|
||||
myNet = None
|
||||
for el in masterCell.getNets():
|
||||
if str(el.getName()) == netname :
|
||||
myNet = el
|
||||
break
|
||||
|
||||
# Error : if no net found in mastercell
|
||||
if myNet == None :
|
||||
err = "\n[Stratus ERROR] CopyUpSegment : No net found with name " + netname + " in masterCell " + str(masterCell.getName()) + ".\n"
|
||||
raise err
|
||||
|
||||
mySegment = None
|
||||
for mySegment in myNet.getSegments():
|
||||
# Error : copy only of CALU segments
|
||||
if str ( mySegment.getLayer().getName() ) not in ( "CALU1", "CALU2", "CALU3", "CALU4", "CALU5", "CALU6" ) :
|
||||
err = "\n[Stratus ERROR] CopyUpSegment : The segments of net " + netname + " are not of type CALU.\n"
|
||||
raise err
|
||||
|
||||
myLayer = mySegment.getLayer()
|
||||
myWidth = mySegment.getWidth()
|
||||
|
||||
pointSource = mySegment.getSourcePosition()
|
||||
pointTarget = mySegment.getTargetPosition()
|
||||
|
||||
transformation.ApplyOn ( pointSource )
|
||||
transformation.ApplyOn ( pointTarget )
|
||||
|
||||
## Occurrence of the segment ##
|
||||
myOccurrence = Occurrence ( mySegment, myPath )
|
||||
|
||||
if pointSource.getY() == pointTarget.getY() :
|
||||
Horizontal ( newnet, myLayer, pointSource.getY(), myWidth, pointSource.getX(), pointTarget.getX() )
|
||||
elif pointSource.getX() == pointTarget.getX() :
|
||||
Vertical ( newnet, myLayer, pointSource.getX(), myWidth, pointSource.getY(), pointTarget.getY() )
|
||||
|
||||
# Error : if no segment found
|
||||
if not mySegment:
|
||||
err = "\n[Stratus ERROR] CopyUpSegment : No segment found with net " + netname + " in masterCell " + str(masterCell.getName()) + ".\n"
|
||||
raise err
|
||||
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
# -*- explicit-buffer-name: "CMakeLists.txt<katabatic>" -*-
|
||||
|
||||
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
|
||||
project(KATABATIC)
|
||||
|
||||
option(BUILD_DOC "Build the documentation (doxygen)" OFF)
|
||||
option(CHECK_DATABASE "Run database in full check mode (very slow)" OFF)
|
||||
option(USE_LIBBFD "Link with BFD libraries to print stack traces" OFF)
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(ignoreVariables "${CMAKE_INSTALL_DIR}")
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||
find_package(Bootstrap REQUIRED)
|
||||
setup_project_paths(CORIOLIS)
|
||||
|
||||
set_cmake_policies()
|
||||
setup_boost(program_options)
|
||||
setup_qt()
|
||||
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development.Module)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(FLUTE REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
find_package(CORIOLIS REQUIRED)
|
||||
find_package(KNIK REQUIRED)
|
||||
find_package(Doxygen)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(cmake_modules)
|
||||
add_subdirectory(doc)
|
||||
|
||||
if(CHECK_DATABASE)
|
||||
add_definitions(-DCHECK_DATABASE)
|
||||
message(STATUS "Checking database enabled (very slow).")
|
||||
endif(CHECK_DATABASE)
|
|
@ -1 +0,0 @@
|
|||
install ( FILES FindKATABATIC.cmake DESTINATION share/cmake/Modules )
|
|
@ -1,37 +0,0 @@
|
|||
# - Find the Katabatic includes and libraries.
|
||||
# The following variables are set if Coriolis is found. If KATABATIC is not
|
||||
# found, KATABATIC_FOUND is set to false.
|
||||
# KATABATIC_FOUND - True when the Coriolis include directory is found.
|
||||
# KATABATIC_INCLUDE_DIR - the path to where the Coriolis include files are.
|
||||
# KATABATIC_LIBRARIES - The path to where the Coriolis library files are.
|
||||
|
||||
|
||||
SET(KATABATIC_INCLUDE_PATH_DESCRIPTION "directory containing the Katabatic include files. E.g /usr/local/include/coriolis2 or /asim/coriolis/include/coriolis2")
|
||||
|
||||
SET(KATABATIC_DIR_MESSAGE "Set the KATABATIC_INCLUDE_DIR cmake cache entry to the ${KATABATIC_INCLUDE_PATH_DESCRIPTION}")
|
||||
|
||||
# don't even bother under WIN32
|
||||
IF(UNIX)
|
||||
#
|
||||
# Look for an installation.
|
||||
#
|
||||
FIND_PATH(KATABATIC_INCLUDE_PATH NAMES katabatic/KatabaticEngine.h PATHS
|
||||
# Look in other places.
|
||||
${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES include/coriolis2
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${KATABATIC_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
||||
FIND_LIBRARY(KATABATIC_LIBRARY_PATH
|
||||
NAMES katabatic
|
||||
PATHS ${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${KATABATIC_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
||||
SET_LIBRARIES_PATH(KATABATIC KATABATIC)
|
||||
HURRICANE_CHECK_LIBRARIES(KATABATIC)
|
||||
|
||||
ENDIF(UNIX)
|
|
@ -1,443 +0,0 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class AutoContact
|
||||
*
|
||||
* \brief Abstract base class for AutoContact
|
||||
*
|
||||
* \section secACCache Caching Mechanism
|
||||
*
|
||||
* To bypass the Ring/Hook mechanism \e and the subsequent Session::Lookup()
|
||||
* call, the AutoSegments anchored on an AutoContact are cached in the
|
||||
* AutoContact itself. They can be accessed through \c getHorizontalN() and
|
||||
* getVerticalN() accessors \c N depending on the subtype of AutoContact.
|
||||
*
|
||||
* Cached AutoSegments are updated in the AutoContact::updateTopology()
|
||||
* function only.
|
||||
*
|
||||
*
|
||||
* \section secACInvalidate Invalidate on AutoContacts
|
||||
*
|
||||
* The invalidation of an AutoContact invalidate all the segments
|
||||
* that are anchored on it.
|
||||
*
|
||||
* <b>Special Case of HTee & VTee</b>
|
||||
*
|
||||
* When invalidating an HTee or VTee, two out of the three anchored
|
||||
* segments are parallels. The \e aligned constraint is passed on
|
||||
* those two. By default, when we invalidate an AutoSegment, the
|
||||
* invalidation is applied to the whole aligned set through the
|
||||
* AutoSegment::getAligneds() collection. So if one of the parallel
|
||||
* is invalidated and the other not, it should only be because we
|
||||
* are already in \c getAligneds(), then we do not want to invalidate
|
||||
* again the whole aligned set. In that case, we perform an atomic only
|
||||
* invalidation (reset Katabatic::KbPropagate).
|
||||
*
|
||||
* For the complete invalidation/revalidation mechanism see
|
||||
* \ref secSessionAlgo "Session Algorithm".
|
||||
*
|
||||
*
|
||||
* \section secDiffFromKatabatic2 Notes - Differences from Katabatic 2
|
||||
*
|
||||
* From the previous version of Katabatic, AutoContact have
|
||||
* been greatly stripped down (again). They are now always punctual
|
||||
* objetcs with stricly fixed topologies:
|
||||
* <ul>
|
||||
* <li>AutoContactTerminal to connect to a terminal (one segment).
|
||||
* <li>AutoContactTurn to make a turn: two perpandiculars segments.
|
||||
* <li>AutoContactHTee an horizontal tee: two \e aligned horizonals
|
||||
* and one vertical.
|
||||
* <li>AutoContactVTee an horizontal tee: two \e aligned verticals
|
||||
* and one horizontal.
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
//! \enum AutoContactFlag
|
||||
//! Set of flags to describe the internal state of an AutoContact.
|
||||
|
||||
//! \var AutoContactFlag::CntFixed
|
||||
//! This contact cannot be moved.
|
||||
|
||||
//! \var AutoContactFlag::CntTerminal
|
||||
//! This contact is anchored on a terminal (AutoContactTerminal), <b>must not be changed</b>.
|
||||
|
||||
//! \var AutoContactFlag::CntTurn
|
||||
//! The object true class is AutoContactTurn, <b>must not be changed</b>.
|
||||
|
||||
//! \var AutoContactFlag::CntHTee
|
||||
//! The object true class is AutoContactHTee, <b>must not be changed</b>.
|
||||
|
||||
//! \var AutoContactFlag::CntVTee
|
||||
//! The object true class is AutoContactVTee, <b>must not be changed</b>.
|
||||
|
||||
//! \var AutoContactFlag::CntInvalidated
|
||||
//! At least one AutoSegment of this contact has been moved, the contact
|
||||
//! position must be recomputed (in the Session revalidation).
|
||||
|
||||
//! \var AutoContactFlag::CntInvalidatedCache
|
||||
//! At least one AutoSegment has been broken or moved up, the connexity
|
||||
//! must be checked and possibly corrected (in Session revalidation).
|
||||
|
||||
//! \var AutoContactFlag::CntInCreationStage
|
||||
//! Sets only during the initial creation process.
|
||||
|
||||
//! \var AutoContactFlag::CntBadTopology
|
||||
//! Something wrong has happened and the connexity of the AutoContact is
|
||||
//! no longer ensured (too much or too less AutoSegments, too wide span of
|
||||
//! AutoSegment layers).
|
||||
|
||||
//! \function Hook* AutoContact::getBodyHook ();
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function Hook* AutoContact::getAnchorHook ();
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function Component* AutoContact::getAnchor () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function Net* AutoContact::getNet () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function const Layer* AutoContact::getLayer () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function DbU::Unit AutoContact::getX () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function DbU::Unit AutoContact::getY () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function DbU::Unit AutoContact::getDx () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function DbU::Unit AutoContact::getDy () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function Point AutoContact::getCenter () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function Point AutoContact::getPosition () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function DbU::Unit AutoContact::getWidth () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function DbU::Unit AutoContact::getHalfWidth () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function DbU::Unit AutoContact::getHeight () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function DbU::Unit AutoContact::getHalfHeight () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function Components AutoContact::getSlaveComponents () const;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setLayer ( const Layer* ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setWidth ( DbU::Unit ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setHeight ( DbU::Unit ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setSizes ( DbU::Unit w, DbU::Unit h ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setX ( DbU::Unit ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setY ( DbU::Unit ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setPosition ( DbU::Unit w, DbU::Unit h ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setPosition ( const Point& ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setDx ( DbU::Unit ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setDy ( DbU::Unit ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::setOffset ( DbU::Unit w, DbU::Unit h ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function void AutoContact::translate ( const DbU::Unit& dx, const DbU::Unit& dy ) ;
|
||||
//! <em>Base class method proxy.</em>
|
||||
|
||||
//! \function bool AutoContact::isInCreationStage () const;
|
||||
//! \sreturn \true if the AutoContact is still in it's initial creation stage.
|
||||
|
||||
//! \function bool AutoContact::isInvalidated () const;
|
||||
//! \sreturn \true if the some AutoSegment has changed and the AutoContact needs
|
||||
//! to be repositionned (through a call to AutoContact::updateGeometry()).
|
||||
|
||||
//! \function bool AutoContact::isInvalidatedCache () const;
|
||||
//! \sreturn \true if the some AutoSegment has changed and the AutoContact
|
||||
//! topology needs to be restored, as a gap may have appeared
|
||||
//! (through a call to AutoSegment::updateTopology()).
|
||||
|
||||
//! \function bool AutoContact::isTurn () const;
|
||||
//! \sreturn \true if the dynamic type of the AutoContact is of type Turn.
|
||||
|
||||
//! \function bool AutoContact::isTee ( unsigned int direction ) const;
|
||||
//! \sreturn \true if the dynamic type of the AutoContact is either of type
|
||||
//! AutoContactHTee or AutoContactVTee, according to \c direction.
|
||||
|
||||
//! \function bool AutoContact::isHTee () const;
|
||||
//! \sreturn \true if the dynamic type of the AutoContact is of type AutoContactHTee.
|
||||
|
||||
//! \function bool AutoContact::isVTee () const;
|
||||
//! \sreturn \true if the dynamic type of the AutoContact is of type AutoContactHTee.
|
||||
|
||||
//! \function bool AutoContact::isFixed () const;
|
||||
//! \sreturn \true if the AutoContact cannot be moved.
|
||||
|
||||
//! \function bool AutoContact::hasBadTopology () const;
|
||||
//! \sreturn \true if the AutoContact topology has been broken and a gap has appeared.
|
||||
//! (sould not happen...)
|
||||
|
||||
//! \function bool AutoContact::canDestroy ( unsigned int flags ) const;
|
||||
//! \sreturn \true if the AutoContact could be destroyed, that is, no segments
|
||||
//! remains anchored on it. If \c flags contains Katabatic::KbWarnOnError,
|
||||
//! issue an error message.
|
||||
|
||||
//! \function bool AutoContact::canMoveUp ( const AutoSegment* moved ) const;
|
||||
//! \sreturn \true if \c segment can be moved up without triggering a topological
|
||||
//! modification. It meaans that:
|
||||
//! - Without \c moved, the AutoContact needs only one layer.
|
||||
//! - \c moved go from \e below the AutoContact to \e above.
|
||||
|
||||
//! \function Contact* AutoContact::base () const;
|
||||
//! \sreturn The Hurricane::Contact which is decorated.
|
||||
|
||||
//! \function size_t AutoContact::getAllocateds ();
|
||||
//! \sreturn The total number of AutoContact currently allocateds.
|
||||
|
||||
//! \function const Name& AutoContact::getStaticName ();
|
||||
//! \sreturn The name of the Hurricane::ExtensionGo slice.
|
||||
|
||||
//! \function const Name& AutoContact::getName () const;
|
||||
//! \sreturn The name of the Hurricane::ExtensionGo slice.
|
||||
|
||||
//! \function const Name& AutoContact::getId () const;
|
||||
//! \sreturn The unique \c identifer of the AutoSegment.
|
||||
|
||||
//! \function Box AutoContact::getBoundingBox () const;
|
||||
//! \see Contact::getBoundingBox().
|
||||
|
||||
//! \function GCell* AutoContact::getGCell () const;
|
||||
//! \sreturn The GCell into which the AutoContact is located.
|
||||
|
||||
//! \function AutoSegment* AutoContact::getOpposite ( const AutoSegment* reference ) const;
|
||||
//! \sreturn The other AutoSegment the \e same direction as \c reference, this is
|
||||
//! only meaningful on AutoContactHTee or AutoContactVTee. If there is
|
||||
//! no opposite, \c NULL is returned.
|
||||
|
||||
//! \function AutoSegment* AutoContact::getPerpandicular ( const AutoSegment* reference ) const;
|
||||
//! \sreturn The AutoSegment in the \e perpandicular direction to \c reference, this is
|
||||
//! only meaningful on AutoContacTurn. It there is no unique perpandicular,
|
||||
//! \c NULL is returned.
|
||||
|
||||
//! \function AutoSegment* AutoContact::getSegment ( unsigned int index ) const;
|
||||
//! \sreturn The nth anchored AutoSegment. The index is significant:
|
||||
//! - \b 0 : first horizontal (\b h1).
|
||||
//! - \b 1 : second horizontal (\b h2).
|
||||
//! - \b 2 : first vertical (\b b1).
|
||||
//! - \b 3 : second vertical (\b b2).
|
||||
//!
|
||||
//! Not all the indexes are filled for every AutoContact. For example
|
||||
//! \c Turn have \b h1 and \b b1, and \c HTee have \b h1, \b h2 and
|
||||
//! \b v1.
|
||||
|
||||
//! \function unsigned int AutoContact::getMinDepth () const;
|
||||
//! \sreturn The layer depth of the bottom layer of the AutoContact.
|
||||
|
||||
//! \function unsigned int AutoContact::getMaxDepth () const;
|
||||
//! \sreturn The layer depth of the top layer of the AutoContact.
|
||||
|
||||
//! \function void AutoContact::getLengths ( DbU::Unit* lengths, AutoSegment::DepthLengthSet& processeds );
|
||||
//! \param lengths A table of DbU::Unit, the size of all routing layers used.
|
||||
//! \param processeds An AutoSegment sorted set holding all the already processeds
|
||||
//! AutoSegments.
|
||||
//!
|
||||
//! Compute the lengths over the owning GCell of all the AutoSegments anchored
|
||||
//! on this AutoContact. The lengths are added to the total length table
|
||||
//! \c lengths. To avoid double accounting of the local AutoSegments
|
||||
//! that have both source & target in the same GCell, we keep a set
|
||||
//! of already processeds AutoSegments in \c processeds.
|
||||
|
||||
//! \function Box AutoContact::getNativeConstraintBox () const;
|
||||
//! \sreturn The native constraint box (that is, whithout any user constraints
|
||||
//! applied). For AutoContactTerminal, this is the Box of the supporting
|
||||
//! external component, and for all others the bounding box of the
|
||||
//! owning GCell.
|
||||
|
||||
//! \function Interval AutoContact::getUConstraints ( unsigned int direction ) const;
|
||||
//! \sreturn The constraint interval in \c direction (that is, the relevant side
|
||||
//! of the constraint box).
|
||||
|
||||
//! \function DbU::Unit AutoContact::getCBXMin () const;
|
||||
//! \sreturn The X coordinate of the bottom left corner of the constraint box.
|
||||
|
||||
//! \function DbU::Unit AutoContact::getCBYMin () const;
|
||||
//! \sreturn The Y coordinate of the bottom left corner of the constraint box.
|
||||
|
||||
//! \function DbU::Unit AutoContact::getCBXMax () const;
|
||||
//! \sreturn The X coordinate of the top right corner of the constraint box.
|
||||
|
||||
//! \function DbU::Unit AutoContact::getCBYMax () const;
|
||||
//! \sreturn The Y coordinate of the top right corner of the constraint box.
|
||||
|
||||
//! \function Box AutoContact::getConstraintBox () const;
|
||||
//! \sreturn The current constraint box: the native constraint box with all
|
||||
//! the user's contraints applieds.
|
||||
|
||||
//! \function Box& AutoContact::intersectConstraintBox ( Box& box ) const;
|
||||
//! \sreturn The intersection between \c box and the constraint box. The
|
||||
//! result is stored into \c box and a reference to it is returned.
|
||||
|
||||
//! \function void AutoContact::invalidate ( unsigned int flags=0 );
|
||||
//! Invalidate the AutoContact, schedule it for revalidation in the
|
||||
//! Session. If flag containt Katabatic::CntInvalidTopology,
|
||||
//! the topology of the AutoContact will also be checked and
|
||||
//! possible gap closeds.
|
||||
//!
|
||||
//! The revalidations methods associated are:
|
||||
//! - AutoSegment::updateGeometry(), recompute the punctual contact position.
|
||||
//! - AutoSegment::updateTopology(), restore the connexity.
|
||||
|
||||
//! \function void AutoContact::updateGeometry ();
|
||||
//! Compute the new position of the AutoContact based on the AutoSegment
|
||||
//! positions. The Session mechanism ensure that all AutoSegment are
|
||||
//! set into their final positions before calling this updator.
|
||||
|
||||
//! \function void AutoContact::updateTopology ();
|
||||
//! Modificate the AutoContact topology to close any gap. This could
|
||||
//! be by changing layer or creating a new dogleg on an incident
|
||||
//! AutoSegment.
|
||||
|
||||
//! \function void AutoContact::_getTopology ( Component*& anchor, Horizontal**& hs, Vertical**& vs, size_t sz );
|
||||
//! \param anchor The anchor, if any.
|
||||
//! \param hs The Hurricane::Horizontal anchored.
|
||||
//! \param vs The Hurricane::Vertical anchored.
|
||||
//! \param sz The size of boths \c hs & \c vs table passed as arguments.
|
||||
//!
|
||||
//! Fill \c anchor , \c hs and \c vs with the components anchored on this
|
||||
//! AutoContact.
|
||||
|
||||
//! \function void AutoContact::showTopologyError ( const std::string& message );
|
||||
//! Comprensive display of the topology of the AutoContact to ease the
|
||||
//! debug work. Prepend with the error message \c message. Do no throw
|
||||
//! an error.
|
||||
|
||||
//! \function void AutoContact::checkTopology ();
|
||||
//! Check for topology correctness (no gaps), display an error message
|
||||
//! if needed.
|
||||
|
||||
//! \function void AutoContact::setGCell ( GCell* gcell );
|
||||
//! Set the owning GCell.
|
||||
|
||||
//! \function void AutoContact::setCBXMin ( DbU::Unit xMin );
|
||||
//! Set the lower left X coordinate of the constraint box.
|
||||
//!
|
||||
//! \remark It cannot go outside the GCell bounding box.
|
||||
|
||||
//! \function void AutoContact::setCBYMin ( DbU::Unit yMin );
|
||||
//! Set the lower left Y coordinate of the constraint box.
|
||||
//!
|
||||
//! \remark It cannot go outside the GCell bounding box.
|
||||
|
||||
//! \function void AutoContact::setCBXMax ( DbU::Unit xMax );
|
||||
//! Set the upper right X coordinate of the constraint box.
|
||||
//!
|
||||
//! \remark It cannot go outside the GCell bounding box.
|
||||
|
||||
//! \function void AutoContact::setCBYMax ( DbU::Unit yMax );
|
||||
//! Set the upper right Y coordinate of the constraint box.
|
||||
//!
|
||||
//! \remark It cannot go outside the GCell bounding box.
|
||||
|
||||
//! \function void AutoContact::setConstraintBox ( const Box& box );
|
||||
//! Set the constraint box.
|
||||
//!
|
||||
//! \remark It cannot go outside the GCell bounding box.
|
||||
|
||||
//! \function bool AutoContact::restrictConstraintBox ( DbU::Unit min, DbU::Unit max, unsigned int flags=KbWarnOnError );
|
||||
//! \param min The minimum of the restriction interval.
|
||||
//! \param max The maximum of the restriction interval.
|
||||
//! \param flags Gives the direction of the restriction.
|
||||
//! \return \true if the restriction was actually applied.
|
||||
//!
|
||||
//! Restrict the current constraint box but check if the restriction
|
||||
//! will not lead to an empty interval, in that case, do nothing and
|
||||
//! return \false.
|
||||
|
||||
//! \function void AutoContact::migrateConstraintBox ( AutoContact* other );
|
||||
//! Transfer the user constraint box from \c other to the current
|
||||
//! object \c this. The constraints of \c other are restored to their
|
||||
//! native values. The two contacts must belong to the same GCell for
|
||||
//! this method to take effect.
|
||||
|
||||
|
||||
/*! \class LocatorHelper
|
||||
*
|
||||
* \brief Locator Helper Collection's Locators
|
||||
*
|
||||
* Provide a small uniform walktough over the AutoSegments anchored
|
||||
* on AutoContacts. The \c flags argument allows to choose between
|
||||
* direction and include perpandiculars (in that case all segments
|
||||
* are processeds).
|
||||
*
|
||||
*
|
||||
* \section secLocHelperImplementation Implementation Details
|
||||
*
|
||||
* As, at most, two horizontals and two verticals may be anchored on
|
||||
* any AutoContact subtype, the locator helper perform a walk through
|
||||
* a virtual table of 4 elements. The two first are the horizontals,
|
||||
* the two last the verticals. The meaning of this index is consistent
|
||||
* whith the \c index argument of AutoContact::getSegment(). When
|
||||
* a segment is not present in an AutoContact, the \c getSegment()
|
||||
* returns \c NULL and the LocatorHelper::progress() function will
|
||||
* skip it.
|
||||
*
|
||||
* The private methods:
|
||||
* - \c LocatorHelper::_min()
|
||||
* - \c LocatorHelper::_max()
|
||||
*
|
||||
* Computes the bounds of \c _index according to the value of \c _flags:
|
||||
* - \c KbHorizontal : \c 0 to less than \c 2.
|
||||
* - \c KbVertical : \c 2 to less than \c 4.
|
||||
* - \c KbHorizontal|KbVertical : \c 0 to less than \c 4.
|
||||
*/
|
||||
|
||||
//! \function LocatorHelper::LocatorHelper ( AutoContact* contact, unsigned int flags );
|
||||
//! Create a helper to iterate over the AutoSegments anchored on \c contact.
|
||||
//! The \c flags arguments allow to select:
|
||||
//! - The direction: Katabatic::KbHorizontal or Katabatic::KbVertical.
|
||||
//! - Perpandicular inclusion: Katabatic::KbWithPerpands.
|
||||
//!
|
||||
//! When setting KbWithPerpands, all the segments will be iterated over.
|
||||
//! It may seems a somewhat contorted way of doing things, the reason is
|
||||
//! the ability to share (an pass) flags directly between different
|
||||
//! functions.
|
||||
|
||||
//! \function bool LocatorHelper::isValid() const;
|
||||
//! \sreturn \true if there is an AutoSegment to be processed.
|
||||
|
||||
//! \function AutoSegment* LocatorHelper::getSegment() const;
|
||||
//! \sreturn The current AutoSegment. \c NULL if the loop is over.
|
||||
|
||||
//! \function void LocatorHelper::progress();
|
||||
//! \sreturn Go to the next AutoSegment.
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class AutoContactHTee
|
||||
*
|
||||
* \brief AutoContact H-Tee (two H, one V)
|
||||
*
|
||||
* AutoContact to build an horizontal tee (two H, one V).
|
||||
*/
|
||||
|
||||
//! \function AutoContactHTee* AutoContactHTee::create ( GCell* gcell, Net* net, const Layer* layer );
|
||||
//! \param gcell The GCell into which create the AutoContact.
|
||||
//! \param net The Net to which this AutoContact belongs.
|
||||
//! \param layer The Layer of the AutoContact.
|
||||
//! \return The created AutoContactHTee.
|
||||
//!
|
||||
//! Create a new AutoContactHTee.
|
||||
|
||||
//! \function void AutoContactHTee::updateTopology ();
|
||||
//! Restore the topology (i.e. connexity) of the contact after any number
|
||||
//! of connected segments has changed layer (at least one, up to three).
|
||||
//!
|
||||
//! For any configuration, the connexity can be restored by making only
|
||||
//! one dogleg.
|
||||
//!
|
||||
//! We distinguish two kind of layer changes:
|
||||
//! -# The two horizontals (\c h1 and \c h2) are still on the same layer
|
||||
//! (either they both moved or the vertical only has moved, see figures
|
||||
//! 2 & 4).
|
||||
//! In that case, the dogleg is made on the vertical.
|
||||
//! -# The two horizontals no longer are on the same layer (figures 1 & 3).
|
||||
//! In that case, the dogleg is made on the horizontal which is at the
|
||||
//! greater distance (in a layer sense) from the vertical.
|
||||
//!
|
||||
//! \image html updateTopologyHTee.png "Update H-Tee Topology"
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class AutoContactTerminal
|
||||
*
|
||||
* \brief AutoContact Terminal (S/T is a Terminal)
|
||||
*
|
||||
* AutoContact that are directly attached by either source or target
|
||||
* or both to a terminal.
|
||||
*/
|
||||
|
||||
//! \function AutoContactTerminal* AutoContactTerminal::create ( GCell* gcell, Component* rp, const Layer* layer, const DbU::Unit x, const DbU::Unit y, const DbU::Unit width, const DbU::Unit height );
|
||||
//! \param gcell The GCell into which create the AutoContact.
|
||||
//! \param rp The Component on which to anchor the AutoContact.
|
||||
//! \param layer The Layer of the AutoContact.
|
||||
//! \param x The absolute X position.
|
||||
//! \param y The absolute Y position.
|
||||
//! \param width The width of the AutoContact.
|
||||
//! \param height The height of the AutoContact.
|
||||
//! \return The created AutoContact.
|
||||
//!
|
||||
//! Create a new AutoContactTerminal anchored on \c rp. <code>(x,y)</code> gives
|
||||
//! the \e absolute position.
|
||||
//!
|
||||
//! The anchor component \c rp is most often a Hurricane::RoutingPad (occurrencing
|
||||
//! a Hurricane::Segment) or directly a Hurricane::Segment, in case of RoutingPad
|
||||
//! layer promotion.
|
||||
|
||||
//! \function AutoContactTerminal* AutoContactTerminal::create ( GCell* gcell, Component* rp, const Layer* layer, Point point, const DbU::Unit width, const DbU::Unit height );
|
||||
//! \param gcell The GCell into which create the AutoContact.
|
||||
//! \param rp The RoutingPad on which to anchor the AutoContact.
|
||||
//! \param layer The Layer of the AutoContact.
|
||||
//! \param point The absolute position.
|
||||
//! \param width The width of the AutoContact.
|
||||
//! \param height The height of the AutoContact.
|
||||
//! \return The created AutoContact.
|
||||
//!
|
||||
//! Create a new AutoContactTerminal anchored on \c rp. \c point gives
|
||||
//! the \e absolute position.
|
||||
|
||||
//! \function void AutoContactTerminal::updateTopology ();
|
||||
//! Restore the topology (i.e. connexity) of the contact after the incident
|
||||
//! segment has changed layer.
|
||||
//!
|
||||
//! Based on the layer depth delta between the terminal and the segment
|
||||
//! three case can occurs:
|
||||
//! - The delta is \b zero, then just sets the layer of the contact
|
||||
//! to the common metal layer.
|
||||
//! - The delta is \b one, then sets the contact layer to VIA connecting
|
||||
//! the two layers.
|
||||
//! - The delta is \b two, then create a dogleg to restore the connexity.
|
||||
//! Depending on whether the terminal was attached to the source or
|
||||
//! target, sets the layer of the segments.
|
||||
//! - A delta of more than \b two is an error, and must never occurs.
|
||||
//!
|
||||
//! As, by default, the perpandicular is set in the layer above the
|
||||
//! parallel, it may be necessary to adjust his layer as well (to the
|
||||
//! one below).
|
||||
//!
|
||||
//! \image html updateTopologyTerminal.png "Update Terminal Topology"
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class AutoContactTurn
|
||||
*
|
||||
* \brief AutoContact Turn (one H, one V)
|
||||
*
|
||||
* AutoContact to make a turn (one H, one V).
|
||||
*/
|
||||
|
||||
//! \function AutoContactTurn* AutoContactTurn::create ( GCell* gcell, Net* net, const Layer* layer );
|
||||
//! \param gcell The GCell into which create the AutoContact.
|
||||
//! \param net The Net to which this AutoContact belongs.
|
||||
//! \param layer The Layer of the AutoContact.
|
||||
//! \return The created AutoContactTurn.
|
||||
//!
|
||||
//! Create a new AutoContactTurn.
|
||||
|
||||
//! \function void AutoContactTurn::updateTopology ();
|
||||
//! Restore the topology (i.e. connexity) of the contact after one or both
|
||||
//! connected segments has changed layer.
|
||||
//!
|
||||
//! Based on the layer depth delta between the two perpandiculars segments.
|
||||
//! Three case can occurs:
|
||||
//! - The delta is \b zero, then just sets the layer of the contact
|
||||
//! to the common metal layer (turn in same layer).
|
||||
//! - The delta is \b one, then sets the contact layer to VIA connecting
|
||||
//! the two layers.
|
||||
//! - The delta <b>cannot be equal to two</b>, due to the alternatives
|
||||
//! routing directions, it would mean a \e turn connecting two \e horizontals
|
||||
//! (or verticals) in different layers.
|
||||
//! - The delta is \b three, then create a dogleg to restore the connexity.
|
||||
//! The dogleg will be created on the connected segment which as been
|
||||
//! <em>layer invalidated</em>. If both of them have been invalidated,
|
||||
//! the horizontal one is preferred.
|
||||
//! - A delta of more than \b three is an error, and must never occurs.
|
||||
//!
|
||||
//! \image html updateTopologyTurn.png "Update Turn Topology"
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class AutoContactVTee
|
||||
*
|
||||
* \brief AutoContact V-Tee (one H, two V)
|
||||
*
|
||||
* AutoContact to build a vertical tee (two V, one H).
|
||||
*/
|
||||
|
||||
//! \function AutoContactVTee* AutoContactVTee::create ( GCell* gcell, Net* net, const Layer* layer );
|
||||
//! \param gcell The GCell into which create the AutoContact.
|
||||
//! \param net The Net to which this AutoContact belongs.
|
||||
//! \param layer The Layer of the AutoContact.
|
||||
//! \return The created AutoContactVTee.
|
||||
//!
|
||||
//! Create a new AutoContactVTee.
|
||||
|
||||
//! \function void AutoContactVTee::updateTopology ();
|
||||
//! Restore the topology (i.e. connexity) of the contact after any number
|
||||
//! of connected segments has changed layer (at least one, up to three).
|
||||
//!
|
||||
//! For a detailed explanation, see AutoContactHTee::updateTopology() and
|
||||
//! sawp horizontal & vertical...
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
//! \class AutoHorizontal
|
||||
//!
|
||||
//! \brief Concrete Horizontal AutoSegment
|
||||
|
||||
//! \function void AutoHorizontal::_postCreate ();
|
||||
//!
|
||||
//! In addition to AutoSegment::_postCreate(), detect whether the
|
||||
//! segment is global or local and register it in the relevant GCells
|
||||
//! (if needed).
|
||||
//!
|
||||
//! If the segment is anchored directly on a terminal, adjust the
|
||||
//! axis so it's connected.
|
||||
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
|
||||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
//! \enum FunctionFlag
|
||||
|
||||
//! \typedef typedef Hurricane::Filter<AutoSegment*> AutoSegmentHF;
|
||||
//! Shorthand for AutoSegment Hurricane Filter.
|
||||
|
||||
//! \typedef typedef Hurricane::Locator<AutoSegment*> AutoSegmentHL;
|
||||
//! Shorthand for AutoSegment Hurricane Locator.
|
||||
|
||||
//! \typedef typedef Hurricane::Collection<AutoSegment*> AutoSegmentHC;
|
||||
//! Shorthand for AutoSegment Hurricane Collection.
|
||||
|
||||
//! \typedef typedef GenericFilter<AutoSegment*> AutoSegmentFilter;
|
||||
//! Shorthand for AutoSegment Hurricane Generic Filter
|
||||
//! (filter with \c unique_ptr<> like support).
|
||||
|
||||
//! \typedef typedef GenericLocator<AutoSegment*> AutoSegmentLocator;
|
||||
//! Shorthand for AutoSegment Hurricane Generic Locator
|
||||
//! (locator with \c unique_ptr<> like support).
|
||||
|
||||
//! \typedef typedef GenericCollection<AutoSegment*> AutoSegments;
|
||||
//! Shorthand for AutoSegment Hurricane Generic Collection
|
||||
//! (collection with \c unique_ptr<> like support).
|
||||
|
||||
/*! \class AutoSegments_OnContact
|
||||
* \brief All AutoSegment anchored on a Contact
|
||||
*
|
||||
* A Collection to iterate over all the AutoSegment anchored on
|
||||
* \c contact. If supplied, the AutoSegment \c master will be
|
||||
* excluded from the list.
|
||||
*
|
||||
* \remark If a Hurricane::Segment is anchored on the \c contact, but is not
|
||||
* associated to an AutoSegment, it will be silently skipped.
|
||||
*/
|
||||
|
||||
//! \function AutoSegments_OnContact::AutoSegments_OnContact ( AutoSegment* master, Contact* contact );
|
||||
//! \param master Exclude this AutoSegment from the Collection.
|
||||
//! \param contact The Hurricane Contact over which to iterate.
|
||||
//!
|
||||
//! Construct a Collection of all the AutoSegment anchored on \c contact.
|
||||
|
||||
//! \function AutoSegments_OnContact::AutoSegments_OnContact ( AutoSegment* master, Contact* contact );
|
||||
//! Create the collection of all AutoSegments direcly anchored on \c contact,
|
||||
//! with exclusion of \c master.
|
||||
|
||||
//! \function AutoSegments_OnContact::AutoSegments_OnContact ( const AutoSegments_OnContact& );
|
||||
//! Copy constructor.
|
||||
|
||||
//! \function AutoSegmentHC* AutoSegments_OnContact::getClone () const;
|
||||
//! \sreturn A deep copy of the Collection.
|
||||
|
||||
//! \function AutoSegmentHC* AutoSegments_OnContact::getLocator () const;
|
||||
//! \sreturn A deep copy of the Collection Locator.
|
||||
|
||||
|
||||
/*! \class AutoSegments_Aligneds
|
||||
* \brief All aligned AutoSegment of a set.
|
||||
*
|
||||
* A Collection to iterate over all the AutoSegment aligned with \c master.
|
||||
* The \c master itself will not be included in the walkthrough.
|
||||
* If the Katabatic::KbWithPerpands flag is passed as argument, the collection
|
||||
* will also includes the AutoSegments directly perpandicular to the aligned
|
||||
* set.
|
||||
*
|
||||
* \remark AutoSegments are forced to be aligneds only when connected through
|
||||
* AutoContactHTee or AutoContactVTee.
|
||||
*
|
||||
*/
|
||||
|
||||
//! \function AutoSegments_Aligneds::AutoSegments_Aligneds ( AutoSegment* master, unsigned int flags );
|
||||
//! Create a collection of all the AutoSegment aligned on \c master
|
||||
//! (master itself is excluded from the Collection). If the flag Katabatic::KbWithPerpands
|
||||
//! is given the directly perpandicular AutoSegment will also be includeds.
|
||||
|
||||
//! \function AutoSegments_Aligneds::AutoSegments_Aligneds ( const AutoSegments_Aligneds& );
|
||||
//! Copy constructor.
|
||||
|
||||
//! \function AutoSegmentHC* AutoSegments_Aligneds::getClone () const;
|
||||
//! \sreturn A deep copy of the Collection.
|
||||
|
||||
//! \function AutoSegmentHC* AutoSegments_Aligneds::getLocator () const;
|
||||
//! \sreturn A deep copy of the Collection Locator.
|
||||
|
||||
|
||||
/*! \class AutoSegments_Perpandiculars
|
||||
* \brief All perpandicular AutoSegment to a set of aligneds.
|
||||
*
|
||||
* A Collection to iterate over all the AutoSegment perpandicular to
|
||||
* the set of aligned AutoSegment of \c master.
|
||||
*
|
||||
* \remark This Collection is canonical aware (work on the aligned set).
|
||||
*
|
||||
*/
|
||||
|
||||
//! \function AutoSegments_Perpandiculars::AutoSegments_Perpandiculars ( AutoSegment* master );
|
||||
//! Create a collection of all the AutoSegment perpandicular to the aligned
|
||||
//! set of \c master.
|
||||
|
||||
//! \function AutoSegments_Perpandiculars::AutoSegments_Perpandiculars ( const AutoSegments_Perpandiculars& );
|
||||
//! Copy constructor.
|
||||
|
||||
//! \function AutoSegmentHC* AutoSegments_Perpandiculars::getClone () const;
|
||||
//! \sreturn A deep copy of the Collection.
|
||||
|
||||
//! \function AutoSegmentHC* AutoSegments_Perpandiculars::getLocator () const;
|
||||
//! \sreturn A deep copy of the Collection Locator.
|
||||
|
||||
|
||||
/*! \class AutoSegments_AnchorOnGCell
|
||||
* \brief All AutoSegment Beginning and/or Stopping in a GCell
|
||||
*
|
||||
* A Collection to iterate over all the AutoSegment that begin from and/or
|
||||
* end in a GCell.
|
||||
*
|
||||
*/
|
||||
|
||||
//! \function AutoSegments_AnchorOnGCell::AutoSegments_AnchorOnGCell ( GCell* fcell, unsigned int flags );
|
||||
//! Create a collection of all the AutoSegment beginning from and/or
|
||||
//! ending in \c fcell. The set returned by the Collection is selected
|
||||
//! through \c flags :
|
||||
//! - Katabatic::KbBySource : include AutoSegment starting from \c fcell.
|
||||
//! - Katabatic::KbByTarget : include AutoSegment ending in \c fcell.
|
||||
//! - Katabatic::KbHorizontal : include horizontal AutoSegment.
|
||||
//! - Katabatic::KbVertical : include vertical AutoSegment.
|
||||
|
||||
//! \function AutoSegments_AnchorOnGCell::AutoSegments_AnchorOnGCell ( const AutoSegments_AnchorOnGCell& );
|
||||
//! Copy constructor.
|
||||
|
||||
//! \function AutoSegmentHC* AutoSegments_AnchorOnGCell::getClone () const;
|
||||
//! \sreturn A deep copy of the Collection.
|
||||
|
||||
//! \function AutoSegmentHC* AutoSegments_AnchorOnGCell::getLocator () const;
|
||||
//! \sreturn A deep copy of the Collection Locator.
|
||||
|
||||
|
||||
/*! \class AutoSegments_OnContact
|
||||
* \brief All AutoSegment Beginning from an AutoContact
|
||||
*
|
||||
* A Collection to iterate over all the AutoSegment that begin from
|
||||
* AutoContact. As AutoSegments are kept orienteds (source anchor must
|
||||
* be lower than target), selecting source anchored AutoSegments
|
||||
* implies that they are starting from this AutoContact.
|
||||
*/
|
||||
|
||||
//! \function AutoSegments_CachedOnContact::AutoSegments_CachedOnContact ( AutoContact* source, unsigned int direction=KbHorizontal|KbVertical );
|
||||
//! Create a collection of all the AutoSegment anchored on \c source.
|
||||
//! Use \c direction to select the kind of AutoSegments:
|
||||
//! - KbHorizontal : include horizontal AutoSegment.
|
||||
//! - KbVertical : include vertical AutoSegment.
|
||||
|
||||
//! \function AutoSegments_CachedOnContact::AutoSegments_CachedOnContact ( const AutoSegments_CachedOnContact& );
|
||||
//! Copy constructor.
|
||||
|
||||
//! \function AutoSegmentHC* AutoSegments_CachedOnContact::getClone () const;
|
||||
//! \sreturn A deep copy of the Collection.
|
||||
|
||||
//! \function AutoSegmentHC* AutoSegments_CachedOnContact::getLocator () const;
|
||||
//! \sreturn A deep copy of the Collection Locator.
|
||||
|
||||
|
||||
/*! \class AutoSegments_IsAccountable
|
||||
* \brief Filter to select accoutable AutoSegment.
|
||||
*
|
||||
* A Filter to select accoutable AutoSegment. An AutoSegment is said
|
||||
* to be accountable if it is canonical (in the sense of an aligned set).
|
||||
*/
|
||||
|
||||
//! \function bool AutoSegments_IsAccountable::accept ( AutoSegment* segment ) const;
|
||||
//! \sreturn \true if the \c segment is accountable (i.e. canonical).
|
||||
|
||||
//! \function AutoSegmentHF* AutoSegments_IsAccountable::getClone () const;
|
||||
//! \sreturn A deep copy of the Collection.
|
||||
|
||||
|
||||
/*! \class AutoSegments_InDirection
|
||||
* \brief Filter to select AutoSegment in a given direction.
|
||||
*
|
||||
* A Filter to select AutoSegment in a specific direction.
|
||||
*/
|
||||
|
||||
//! \function AutoSegments_InDirection::AutoSegments_InDirection ( unsigned int direction );
|
||||
//! Create a filter for AutoSegment in \c direction (Katabatic::KbHorizontal
|
||||
//! or Katabatic::KbVertical).
|
||||
|
||||
//! \function bool AutoSegments_InDirection::accept ( AutoSegment* segment ) const;
|
||||
//! \sreturn \true if the \c segment is in the correct direction.
|
||||
|
||||
//! \function AutoSegmentHF* AutoSegments_InDirection::getClone () const;
|
||||
//! \sreturn A deep copy of the Collection.
|
||||
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
//! \class AutoVertical
|
||||
//!
|
||||
//! \brief Concrete Vertical AutoSegment
|
||||
|
||||
//! \function void AutoVertical::_postCreate ();
|
||||
//!
|
||||
//! In addition to AutoSegment::_postCreate(), detect whether the
|
||||
//! segment is global or local and register it in the relevant GCells
|
||||
//! (if needed).
|
||||
//!
|
||||
//! If the segment is anchored directly on a terminal, adjust the
|
||||
//! axis so it's connected.
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
# -*- mode: CMAKE; explicit-buffer-name: # "CMakeLists.txt<katabatic/doc>" -*-
|
||||
|
||||
set ( htmlInstallDir share/doc/coriolis2/en/html/doc/katabatic )
|
||||
set ( latexInstallDir share/doc/coriolis2/en/latex/katabatic )
|
||||
set ( doxExtras customHierarchy.html
|
||||
closed.png
|
||||
open.png
|
||||
tabs.css
|
||||
)
|
||||
|
||||
if(BUILD_DOC AND DOXYGEN_FOUND)
|
||||
add_custom_target ( doc ALL
|
||||
cd ${KATABATIC_SOURCE_DIR}/doc
|
||||
&& ${DOXYGEN_EXECUTABLE} doxyfile
|
||||
&& cp -f ${doxExtras} html
|
||||
)
|
||||
endif()
|
||||
|
||||
install ( DIRECTORY html/ DESTINATION ${htmlInstallDir} )
|
||||
install ( DIRECTORY latex/ DESTINATION ${latexInstallDir} )
|
||||
install ( FILES asimbook.cls DESTINATION ${latexInstallDir} )
|
|
@ -1,62 +0,0 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class ChipTools
|
||||
*
|
||||
* \brief Utilities for Chip Level Design
|
||||
*
|
||||
* The ChipTools class provides a small set of utilities to ease
|
||||
* the managment of a complete chip following the Alliance top
|
||||
* hierarchical structure.
|
||||
*/
|
||||
|
||||
//! \function ChipTools::ChipTools ( Cell* cell );
|
||||
//! Create a ChipTool for \c cell.
|
||||
|
||||
//! \function bool ChipTools::isChip () const;
|
||||
//! \sreturn \true if the Cell is truly a top level design. If not, this
|
||||
//! object is useless and does nothing.
|
||||
|
||||
//! \function Cell* ChipTools::getCell () const;
|
||||
//! \sreturn The top-level design.
|
||||
|
||||
//! \function Instance* ChipTools::getCore () const;
|
||||
//! \sreturn The instance of the core, that is, the only instance that is
|
||||
//! \e not a pad...
|
||||
|
||||
//! \function const Box& ChipTools::getChipBb () const;
|
||||
//! \sreturn The chip complete bounding box, this *is* simply the Cell bounding box.
|
||||
|
||||
//! \function const Box& ChipTools::getLeftPadsBb () const;
|
||||
//! \sreturn The bounding box enclosing all the pads on the left side of the chip.
|
||||
//!
|
||||
//! \remark This box is computed from the chip bounding box and the pad height.
|
||||
|
||||
//! \function const Box& ChipTools::getRightPadsBb () const;
|
||||
//! \sreturn The bounding box enclosing all the pads on the right side of the chip.
|
||||
//!
|
||||
//! \remark This box is computed from the chip bounding box and the pad height.
|
||||
|
||||
//! \function const Box& ChipTools::getTopPadsBb () const;
|
||||
//! \sreturn The bounding box enclosing all the pads on the top side of the chip.
|
||||
//!
|
||||
//! \remark This box is computed from the chip bounding box and the pad height.
|
||||
|
||||
//! \function const Box& ChipTools::getBottomPadsBb () const;
|
||||
//! \sreturn The bounding box enclosing all the pads on the bottom side of the chip.
|
||||
//!
|
||||
//! \remark This box is computed from the chip bounding box and the pad height.
|
||||
|
||||
//! \function const Torus& ChipTools::getCorona () const;
|
||||
//! \sreturn The torus (in term of manhanttan distance) enclosed between the pad area
|
||||
//! and the core area.
|
||||
|
||||
//! \function bool ChipTools::intersectVPads ( const Box& ) const;
|
||||
//! \sreturn \true if \c box intersect either the left or right pad box.
|
||||
|
||||
//! \function bool ChipTools::intersectHPads ( const Box& ) const;
|
||||
//! \sreturn \true if \c box intersect either the top or bottom pad box.
|
||||
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
// -*- mode: C++; explicit-buffer-name: "Constants.dox<katabatic>" -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
//! \enum FunctionFlag
|
||||
//! A set of flags to that can be passed to functions/methods througout
|
||||
//! all Katabatic.
|
||||
|
||||
//! \var KbOpenSession
|
||||
//! Tells the function to open it's own Session, otherwise use
|
||||
//! the one that should already have been opened.
|
||||
|
||||
//! \var KbRealignate
|
||||
//! On AutoSegment axis manipulation, force the realignment of all
|
||||
//! the segment on an aligned set, even is the axis of the canonical
|
||||
//! is already at the right coordinate.
|
||||
|
||||
//! \var KbNativeConstraints
|
||||
//! Ignore user-defined constraints or terminal induced ones (for AutoContacts
|
||||
//! anchored on terminals) and return the owning GCell alone.
|
||||
|
||||
//! \var KbForceMove
|
||||
//! Tells the function to force move, even if it is not needed.
|
||||
|
||||
//! \var KbHorizontal
|
||||
//! Request some action to be done in the horizontal direction.
|
||||
|
||||
//! \var KbVertical
|
||||
//! Request some action to be done in the vertical direction.
|
||||
|
||||
//! \var KbWithPerpands
|
||||
//! Request that AutoSegments in perpandicular direction should be includeds.
|
||||
|
||||
//! \var KbSource
|
||||
//! Request AutoSegments anchored by their source anchor or that some
|
||||
//! operation has to be performed on the source.
|
||||
|
||||
//! \var KbTarget
|
||||
//! Request AutoSegments anchored by their target anchor or that some
|
||||
//! operation has to be performed on the target.
|
||||
|
||||
//! \var KbWarnOnError
|
||||
//! Display a warning if something has gone wrong.
|
||||
|
||||
//! \var KbPropagate
|
||||
//! The action will affect all the segments on an aligned set.
|
||||
|
||||
//! \var KbUseAboveLayer
|
||||
//! Request/tell the a above layer has been used.
|
||||
|
||||
//! \var KbUseBelowLayer
|
||||
//! Request/tell the a below layer has been used.
|
||||
|
||||
//! \var KbDoglegOnLeft
|
||||
//! The dogleg has occured on the left <em>of something</em>
|
||||
|
||||
//! \var KbDoglegOnRight
|
||||
//! The dogleg has occured on the right <em>of something</em>
|
||||
|
||||
//! \var KbHalfSlacken
|
||||
//! For AutoSegment::slacken(), change the overconstrained limit
|
||||
//! from 10 tracks down to 3 (hard-wired).
|
||||
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
<doxygenlayout version="1.0">
|
||||
<!-- Navigation index tabs for HTML output -->
|
||||
<navindex>
|
||||
<tab type="mainpage" visible="yes" title=""/>
|
||||
<tab type="pages" visible="yes" title=""/>
|
||||
<tab type="modules" visible="yes" title=""/>
|
||||
<tab type="namespaces" visible="yes" title="">
|
||||
<tab type="namespaces" visible="yes" title=""/>
|
||||
<tab type="namespacemembers" visible="yes" title=""/>
|
||||
</tab>
|
||||
<tab type="classes" visible="yes" title="">
|
||||
<tab type="classes" visible="yes" title=""/>
|
||||
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
|
||||
<tab type="hierarchy" visible="yes" title=""/>
|
||||
<tab type="classmembers" visible="yes" title=""/>
|
||||
</tab>
|
||||
<tab type="files" visible="yes" title="">
|
||||
<tab type="files" visible="yes" title=""/>
|
||||
<tab type="globals" visible="yes" title=""/>
|
||||
</tab>
|
||||
<!--
|
||||
<tab type="dirs" visible="yes" title=""/>
|
||||
-->
|
||||
<tab type="examples" visible="yes" title=""/>
|
||||
</navindex>
|
||||
|
||||
<!-- Layout definition for a class page -->
|
||||
<class>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<inheritancegraph visible="$CLASS_GRAPH"/>
|
||||
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
|
||||
<allmemberslink visible="yes"/>
|
||||
<memberdecl>
|
||||
<nestedclasses visible="yes" title=""/>
|
||||
<publictypes title=""/>
|
||||
<publicslots title=""/>
|
||||
<signals title=""/>
|
||||
<publicmethods title=""/>
|
||||
<publicstaticmethods title=""/>
|
||||
<publicattributes title=""/>
|
||||
<publicstaticattributes title=""/>
|
||||
<protectedtypes title=""/>
|
||||
<protectedslots title=""/>
|
||||
<protectedmethods title=""/>
|
||||
<protectedstaticmethods title=""/>
|
||||
<protectedattributes title=""/>
|
||||
<protectedstaticattributes title=""/>
|
||||
<packagetypes title=""/>
|
||||
<packagemethods title=""/>
|
||||
<packagestaticmethods title=""/>
|
||||
<packageattributes title=""/>
|
||||
<packagestaticattributes title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
<privatetypes title=""/>
|
||||
<privateslots title=""/>
|
||||
<privatemethods title=""/>
|
||||
<privatestaticmethods title=""/>
|
||||
<privateattributes title=""/>
|
||||
<privatestaticattributes title=""/>
|
||||
<friends title=""/>
|
||||
<related title="" subtitle=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<constructors title=""/>
|
||||
<functions title=""/>
|
||||
<related title=""/>
|
||||
<variables title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
</memberdef>
|
||||
<usedfiles visible="$SHOW_USED_FILES"/>
|
||||
<authorsection visible="yes"/>
|
||||
</class>
|
||||
|
||||
<!-- Layout definition for a namespace page -->
|
||||
<namespace>
|
||||
<briefdescription visible="yes"/>
|
||||
<memberdecl>
|
||||
<nestednamespaces visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</namespace>
|
||||
|
||||
<!-- Layout definition for a file page -->
|
||||
<file>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<includegraph visible="$INCLUDE_GRAPH"/>
|
||||
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
|
||||
<sourcelink visible="yes"/>
|
||||
<memberdecl>
|
||||
<classes visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection/>
|
||||
</file>
|
||||
|
||||
<!-- Layout definition for a group page -->
|
||||
<group>
|
||||
<briefdescription visible="yes"/>
|
||||
<groupgraph visible="$GROUP_GRAPHS"/>
|
||||
<memberdecl>
|
||||
<classes visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<dirs visible="yes" title=""/>
|
||||
<nestedgroups visible="yes" title=""/>
|
||||
<files visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<pagedocs/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</group>
|
||||
|
||||
<!-- Layout definition for a directory page -->
|
||||
<directory>
|
||||
<briefdescription visible="yes"/>
|
||||
<directorygraph visible="yes"/>
|
||||
<memberdecl>
|
||||
<dirs visible="yes"/>
|
||||
<files visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
</directory>
|
||||
</doxygenlayout>
|
|
@ -1,535 +0,0 @@
|
|||
|
||||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class GCell
|
||||
*
|
||||
* \brief Routing Global Cell
|
||||
*
|
||||
*
|
||||
* \section secGCellDescription GCell Description
|
||||
*
|
||||
* Please note that there are two kind of Global Cells (or GCell for short):
|
||||
* - The GCell used by the global router Knik.
|
||||
* - The GCell used by the detailed router (Katabatic & Kite).
|
||||
* Although the information they hold is obviously related, they are two
|
||||
* separate kind of objects.
|
||||
*
|
||||
* The area of the design to be routed is divided in a regular grid of
|
||||
* rectangular area, the GCellGrid. Each rectangular area is a GCell.
|
||||
*
|
||||
* The GCell contains the following informations:
|
||||
* - The AutoSegments that begins or ends in it. The list of segments
|
||||
* is not avalaible directly but through the AutoContacts that are
|
||||
* owned by the GCell.
|
||||
* - The AutoSegments that go straight \e through it (or \e over it).
|
||||
* Horizontal & Vertical segments are stored in two separeted list.
|
||||
* Those two lists are sorted by layer depth (the deepest layers
|
||||
* first).
|
||||
* - A lot of synthetic information about the density of tracks used
|
||||
* in the GCell.
|
||||
*
|
||||
* AutoContacts are affected to GCells, the area of the GCell is the
|
||||
* one into which the AutoContact is allowed to be placed. It is this
|
||||
* that way that the respect of the global routing choosen by Knik is
|
||||
* enforced. See the AutoContact constraint box.
|
||||
*
|
||||
* When tracks are aligned with the GCell boundaries they one exactly on
|
||||
* the boundary can belong to the GCell on either side of the boundary.
|
||||
* But we want a clear and mutually exclusive ownership of each GCell
|
||||
* area. So, we choose that one GCell do not own the topmost and rightmost
|
||||
* track. And to implement it, we shrink top and right coordinates by
|
||||
* the amount of GCell::getTopRightShrink(), which must be less than the
|
||||
* track spacing.
|
||||
*
|
||||
*
|
||||
* \subsection secGCellDensity Saturation & Density Computation
|
||||
*
|
||||
* At any depth (i.e. layer), in the preferred routing direction, a GCell
|
||||
* can pass a finite length of wire. For example on an horizontal preferred
|
||||
* layer:
|
||||
\f[
|
||||
WL_{max} = width(GCell) \times Htracks(GCell)
|
||||
\f]
|
||||
* Then the density, is the ratio between \f$WL_{max}\f$ and the actually
|
||||
* used wirelength:
|
||||
\f[
|
||||
Wdensity(depth) = \frac{WL_{used}(depth)}{WL_{max}(depth)}
|
||||
\f]
|
||||
* Normally, the ratio musn't exceed 1.0, but the occupied wire length computation,
|
||||
* for now, doesn't merge overlapping wires belonging to the same net, so
|
||||
* the ratio may be slightly inaccurate. Thus in some pathological cases may
|
||||
* be greater than 1.0 whithout truly been overloaded.
|
||||
*
|
||||
* A Cell is considered as \e saturated if the overall density is above the
|
||||
* saturation ratio given by Session::getSaturateRatio().
|
||||
*
|
||||
* Contact density is calculated as follow:
|
||||
\f[
|
||||
Cont_{density} = \frac{|Contacts|}{Htracks \times Vtracks \times 4}
|
||||
\f]
|
||||
* It is a ratio over the number of actual contacts in the GCell and the maximal
|
||||
* number. The maximal number being the product of the number of tracks in
|
||||
* both direction and 4 stands for the hardwired number of layers (the depth).
|
||||
*
|
||||
* Should not be hardwired... \red{<em>To be corrected in future versions.</em>}
|
||||
*
|
||||
*
|
||||
* \subsection secGCellFeedthrough Feedthrough Computation
|
||||
*
|
||||
* The feedtrough value is an estimate is of how many complete tracks have been used
|
||||
* on a given layer of the GCell. It varies between zero and the number of track on the
|
||||
* GCell (complete saturation). As an estimate, it doesn't tell you the actual
|
||||
* number of free track, but how many you <em>may expect</em> assuming the routing is
|
||||
* reasonably well done.
|
||||
*
|
||||
* Computation is done as follow:
|
||||
* <table class="DoxUser">
|
||||
* <tr><th>Wire type<th>Estimated Cost
|
||||
* <tr><td>Straight wire (feedthrough)
|
||||
* <td>\b 1.0
|
||||
* <tr><td>Beginning or ending global wire
|
||||
* <td>\b 0.5
|
||||
* <tr><td>Local wire.
|
||||
* <td>\b 1/3
|
||||
* <tr><td>Blockage wire
|
||||
* <td>The exact percentage of the track
|
||||
* </table>
|
||||
*
|
||||
*
|
||||
* \subsection secGCellTrackComputation Track Computation
|
||||
*
|
||||
* The number of track that can go through a GCell in the horizontal
|
||||
* direction is computed as follow:
|
||||
\f[
|
||||
Htracks = \frac{heigth(GCell)}{Vpitch} + 1
|
||||
\f]
|
||||
*
|
||||
* The pitch is assumed to be the same for every layer and is hardwired
|
||||
* to 5.0 lambda.
|
||||
*
|
||||
* This is a bad architectural choice. The informations pertaining to
|
||||
* routing should be held at Kite level, not be hardwired and the pitch
|
||||
* should be made variable with the layer...
|
||||
* \red{<em>To be corrected in future versions</em>}.
|
||||
*
|
||||
*
|
||||
* \section secGCellLazyEvaluation GCell Lazy Evaluation
|
||||
*
|
||||
* To save processing time, the densities are not recomputed every time a
|
||||
* segment is modified (added, removed or moved). Instead a lazy evaluation
|
||||
* mechanism is used. Densities are recomputed each time a density is queried
|
||||
* \e and the lazy evaluation \e not explicitly disabled (flag NoUpdate).
|
||||
*
|
||||
*
|
||||
* \section secGCellSortingKey GCell Sorting Key
|
||||
*
|
||||
* In order to perform a lexicographical sort on the tuple \f$(density(depth),id)\f$
|
||||
* of a GCell, a specific slave object GCell::Key is introduced. It is the
|
||||
* density on one specific depth, not the average density.
|
||||
*
|
||||
*
|
||||
* \section secGCellDesaturation GCell Desaturation / Layer Assignment
|
||||
*
|
||||
* In addition to it's geometrical and density functionality, the GCell
|
||||
* provides \e desaturation capabilities. Desaturation is the operation
|
||||
* of moving up feedthough AutoSegment from the bottom layers towards
|
||||
* the upper ones in order to balance the densities in the different
|
||||
* densities. Thoses operations provides building blocks for the layer
|
||||
* assignment stage which is provided by the Kabatic tool.
|
||||
*
|
||||
* Two strategies are avalaibles, moving one global AutoSegment at a
|
||||
* time with GCell::stepDesaturate() or, when one AutoSegment is moved
|
||||
* up, move up the whole net trunk with GCell::stepNetDesaturate().
|
||||
*
|
||||
* \section secGCellImplantation GCell Implantation
|
||||
*
|
||||
* GCell derives from Hurricane::ExtensionGo to allow a graphical rendering
|
||||
* of the routing density.
|
||||
*/
|
||||
|
||||
//! \function size_t GCell::getAllocateds ();
|
||||
//! \sreturn The number of allocated GCells.
|
||||
|
||||
//! \function const Name& GCell::getStaticName ();
|
||||
//! \sreturn The name of the Go slice: \c "Katabatic::GCell".
|
||||
//!
|
||||
//! \see Hurricane::ExtensionGo
|
||||
|
||||
//! \function const Name& GCell::getName () const;
|
||||
//! \sreturn The name of the Go slice: \c "Katabatic::GCell".
|
||||
//!
|
||||
//! \see Hurricane::ExtensionGo
|
||||
|
||||
//! \function Box GCell::getBoundingBox () const;
|
||||
//! \sreturn The bounding box of the GCell, with the top right shrink applied.
|
||||
|
||||
//! \function void GCell::translate ( const DbU::Unit&, const DbU::Unit& );
|
||||
//! Required to exists as a Hurricane::Go derived class. But must never
|
||||
//! be used...
|
||||
|
||||
//! \function GCellGrid* GCell::getGCellGrid () const;
|
||||
//! \sreturn The Grid of which GCell is part of.
|
||||
|
||||
//! \function unsigned int GCell::getIndex () const;
|
||||
//! \sreturn The linear index of the GCell in the GCellGrid vector.
|
||||
//!
|
||||
//! \see GCellGrid for the meaning of the index.
|
||||
|
||||
//! \function unsigned int GCell::getRow () const;
|
||||
//! \sreturn The row of the GCell in the GCellGrid.
|
||||
|
||||
//! \function unsigned int GCell::getColumn () const;
|
||||
//! \sreturn The Column of the GCell in the GCellGrid.
|
||||
|
||||
//! \function GCell* GCell::getLeft () const;
|
||||
//! \sreturn The left neighbor of the GCell (\c NULL if it is the leftmost GCell).
|
||||
|
||||
//! \function GCell* GCell::getRight () const;
|
||||
//! \sreturn The right neighbor of the GCell (\c NULL if it is the rightmost GCell).
|
||||
|
||||
//! \function GCell* GCell::getUp () const;
|
||||
//! \sreturn The top neighbor of the GCell (\c NULL if it is the topmost GCell).
|
||||
|
||||
//! \function GCell* GCell::getDown () const;
|
||||
//! \sreturn The bottom neighbor of the GCell (\c NULL if it is the bottommost GCell).
|
||||
|
||||
//! \function DbU::Unit GCell::getTopRightShrink ();
|
||||
//! \sreturn The amount of shrink on the top and right boundaries.
|
||||
|
||||
//! \function unsigned int GCell::getDepth () const;
|
||||
//! \sreturn The depth (i.e. number of routing layers) of the GCell.
|
||||
|
||||
//! \function bool GCell::isSaturated () const;
|
||||
//! \sreturn \true if at least one layer exceed a saturation of \c 1.0 (more wirelength
|
||||
//! that it can hold).
|
||||
|
||||
//! \function bool GCell::isSaturated ( unsigned int depth ) const;
|
||||
//! \sreturn \true if the saturation ratio of layer \c depth is over the threshold defined
|
||||
//! for the GCells.
|
||||
|
||||
//! \function bool GCell::isValid () const;
|
||||
//! \sreturn \true if all the AutoContact/AutoSegment of the GCell are valids.
|
||||
|
||||
//! \function bool GCell::isAboveDensity ( float threshold ) const;
|
||||
//! \sreturn \true if the overall saturation ratio greater than \c threshold.
|
||||
|
||||
//! \function bool GCell::hasFreeTrack ( size_t depth, float reserve ) const;
|
||||
//! \sreturn \true if there should be enough wire length to pass a wire completly
|
||||
//! trough this GCell.
|
||||
|
||||
//! \function DbU::Unit GCell::getX () const;
|
||||
//! \sreturn The lower left X coordinate of the GCell box.
|
||||
|
||||
//! \function DbU::Unit GCell::getY () const;
|
||||
//! \sreturn The lower left Y coordinate of the GCell box.
|
||||
|
||||
//! \function DbU::Unit GCell::getXMax () const;
|
||||
//! \sreturn The upper right X coordinate of the GCell box (top right shrink applied).
|
||||
|
||||
//! \function DbU::Unit GCell::getYMax () const;
|
||||
//! \sreturn The upper right Y coordinate of the GCell box (top right shrink applied).
|
||||
|
||||
//! \function Interval GCell::getSide ( unsigned int direction ) const;
|
||||
//! \sreturn The interval corresponding to the side position of the GCell box,
|
||||
//! in \c direction.
|
||||
|
||||
//! \function float GCell::getHCapacity () const;
|
||||
//! \return The number of track that can go through the GCell in the horizontal
|
||||
//! direction. For a detailed explanation of the computation see
|
||||
//! \ref secGCellTrackComputation.
|
||||
|
||||
//! \function float GCell::getVCapacity () const;
|
||||
//! \return The number of track that can go through the GCell in the vertical
|
||||
//! direction. For a detailed explanation of the computation see
|
||||
//! \ref secGCellTrackComputation.
|
||||
|
||||
//! \function float GCell::getDensity ( unsigned int flags=0 ) const;
|
||||
//! \sreturn The average density of the GCell, for all the depths.
|
||||
//!
|
||||
//! \ref secGCellDensity, \ref secGCellLazyEvaluation.
|
||||
|
||||
//! \function float GCell::getCDensity ( unsigned int flags=0 ) const;
|
||||
//! \sreturn The density of contacts.
|
||||
//!
|
||||
//! \ref secGCellDensity, \ref secGCellLazyEvaluation.
|
||||
|
||||
//! \function float GCell::getWDensity ( unsigned int depth, unsigned int flags=0 ) const;
|
||||
//! \sreturn The density of wires at \c depth.
|
||||
//!
|
||||
//! \ref secGCellDensity, \ref secGCellLazyEvaluation.
|
||||
|
||||
//! \function DbU::Unit GCell::getBlockage ( unsigned int depth ) const;
|
||||
//! \sreturn The total length of blockage wire on layer at \c depth.
|
||||
|
||||
//! \function float GCell::getFragmentation ( unsigned int depth ) const;
|
||||
//! \sreturn The longest free fragment size on layer \c depth (in percent).
|
||||
|
||||
//! \function float GCell::getFeedthroughs ( unsigned int depth ) const;
|
||||
//! \sreturn The estimate number of \e occupied tracks on layer \c depth.
|
||||
//!
|
||||
//! \see \ref secGCellFeedthrough
|
||||
|
||||
//! \function float GCell::getGlobalsCount ( unsigned int depth ) const;
|
||||
//! \sreturn The number of global wires that go completly through the GCell at layer \c depth.
|
||||
//! This do not includes the global wires that begins or ends in the GCell.
|
||||
|
||||
//! \function const vector<AutoSegment*>& GCell::getHSegments () const;
|
||||
//! \returns The vector of all horizontal AutoSegments that completly goes through the GCell.
|
||||
|
||||
//! \function const vector<AutoSegment*>& GCell::getVSegments () const;
|
||||
//! \returns The vector of all vertical AutoSegments that completly goes through the GCell.
|
||||
|
||||
//! \function const vector<AutoContact*>& GCell::getContacts () const;
|
||||
//! \returns The vector of all AutoContacts owned by the GCell.
|
||||
|
||||
//! \function AutoSegments GCell::getHStartSegments ();
|
||||
//! \returns A Collection of the horizontal AutoSegments that starts from this GCell.
|
||||
|
||||
//! \function AutoSegments GCell::getVStartSegments ();
|
||||
//! \returns A Collection of the vertical AutoSegments that starts from this GCell.
|
||||
|
||||
//! \function AutoSegments GCell::getHStopSegments ();
|
||||
//! \returns A Collection of the horizontal AutoSegments that stops in this GCell.
|
||||
|
||||
//! \function AutoSegments GCell::getVStopSegments ();
|
||||
//! \returns A Collection of the vertical AutoSegments that stops in this GCell.
|
||||
|
||||
//! \function AutoSegments GCell::getStartSegments ( unsigned int direction );
|
||||
//! \returns A Collection of the horizontal or vertical AutoSegments that starts from this GCell
|
||||
//! according to \c direction.
|
||||
|
||||
//! \function AutoSegments GCell::getStopSegments ( unsigned int direction );
|
||||
//! \returns A Collection of the horizontal or vertical AutoSegments that stops in this GCell
|
||||
//! according to \c direction.
|
||||
|
||||
//! \function size_t GCell::getRoutingPads ( set<RoutingPad*>& rps );
|
||||
//! \returns The size of the RoutingPad set.
|
||||
//!
|
||||
//! Fills the \c rps set with all the RoutingPads that appears in this GCell.
|
||||
//! (looks at all the anchors of the owned AutoContact)
|
||||
|
||||
//! \function const Key& GCell::getKey () const;
|
||||
//! \returns The sorting key of the GCell.
|
||||
//!
|
||||
//! \see \ref secGCellSortingKey
|
||||
|
||||
//! \function size_t GCell::checkDensity () const;
|
||||
//! \returns \c 1 if the GCell is saturated, 0 otherwise.
|
||||
//!
|
||||
//! Check, if the GCell is saturated, layer by layer. Issue a warning
|
||||
//! if that is the case.
|
||||
|
||||
//! \function bool GCell::checkEdgeSaturation ( float threshold ) const;
|
||||
//! \returns \true if the Up/Right edge is over the \c threshold.
|
||||
//!
|
||||
//! Check if the number of AutoSegments crossing the Up & Right edges of the GCell
|
||||
//! exceed \c threshold. The \c thresold must be expressed as a percentage of
|
||||
//! the full capacity of the edges. The overload is computed as a whole and not
|
||||
//! depth by depth.
|
||||
|
||||
//! \function void GCell::addBlockage ( unsigned int depth, DbU::Unit length );
|
||||
//! Adds \c length of wire blockage to layer \c depth.
|
||||
|
||||
//! \function void GCell::addHSegment ( AutoSegment* segment );
|
||||
//! Adds \c segment to the list of horizontal feedthroughs.
|
||||
|
||||
//! \function void GCell::addVSegment ( AutoSegment* segment );
|
||||
//! Adds \c segment to the list of vertical feedthroughs.
|
||||
|
||||
//! \function void GCell::addContact ( AutoContact* contact );
|
||||
//! Adds \c contact to the list of contacts owned by this GCell.
|
||||
|
||||
//! \function void GCell::removeHSegment ( AutoSegment* segment );
|
||||
//! Removes \c segment to the list of horizontal feedthroughs.
|
||||
|
||||
//! \function void GCell::removeVSegment ( AutoSegment* segment );
|
||||
//! Removes \c segment to the list of vertical feedthroughs.
|
||||
|
||||
//! \function void GCell::removeContact ( AutoContact* contact );
|
||||
//! Removes \c contact to the list of contacts owned by this GCell.
|
||||
|
||||
//! \function void GCell::updateContacts ();
|
||||
//! Force a geometry update on all the AutoContact of the GCell.
|
||||
|
||||
//! \function size_t GCell::updateDensity ();
|
||||
//! \sreturn \true if the GCell is saturated.
|
||||
//!
|
||||
//! Update the various densities of the GCell. No actual computation is
|
||||
//! performed if the GCell is \e not invalidated.
|
||||
|
||||
//! \function void GCell::updateKey ( unsigned int depth );
|
||||
//! Update the GCell key with the new density at layer \c depth.
|
||||
//!
|
||||
//! \see \ref secGCellSortingKey.
|
||||
|
||||
//! \function bool GCell::stepDesaturate ( unsigned int depth, set<Net*>& globalNets, AutoSegment*& moved, unsigned int flags=0 );
|
||||
//! \param depth The depth to desaturate.
|
||||
//! \param globalNets The set of Nets of which at least one segment has been moved up.
|
||||
//! \param moved The moved up AutoSegment.
|
||||
//! \param flags If KbForceMove is set, force one AutoSegment to move up, event if
|
||||
//! the GCell is not saturated in the relevant depth.
|
||||
//!
|
||||
//! \sreturn \true if an AutoSegment has actually been moved up.
|
||||
//!
|
||||
//! Perform the atomic desaturation, that is move up one AutoSegment from
|
||||
//! layer \c depth to layer <code>depth+2</code>, longuests AutoSegments are
|
||||
//! moved first. Only global feedthrough AutoSegments are candidates to be
|
||||
//! moved up. The Net owning the moved up segment is added to the \c globalNets
|
||||
//! set. If the GCell is not saturated on layer \c depth, nothing is
|
||||
//! done. If the \c forced flag is set, one global AutoSegment is moved up
|
||||
//! regardless of the saturation status.
|
||||
//!
|
||||
//! \see \ref secGCellDesaturation
|
||||
|
||||
//! \function bool GCell::stepNetDesaturate ( unsigned int depth, set<Net*>& globalNets, SetIndex& invalidateds );
|
||||
//! \param depth The depth to desaturate.
|
||||
//! \param globalNets The set of Nets of which at least one segment has been moved up.
|
||||
//! \param invalidateds The set of GCell ids that have been invalidateds.
|
||||
//!
|
||||
//! \sreturn \true if a Net has been moved up.
|
||||
//!
|
||||
//! Perform a desaturation by whole Net trunk. Select the longest feedthrough
|
||||
//! AutoSegment in layer \c depth, then attempt to move up the whole Net (all
|
||||
//! it's global AutoSegments are moved up).
|
||||
//!
|
||||
//! \see \ref secGCellDesaturation
|
||||
|
||||
//! \function bool GCell::rpDesaturate ( set<Net*>& nets );
|
||||
//! If the number of RoutingPad in the first routing layer exceed the
|
||||
//! Session::getSaturateRp() threshold, force a desaturation of layer
|
||||
//! \c depth 1 until it is below 0.5.
|
||||
//!
|
||||
//! \see \ref secGCellDesaturation
|
||||
|
||||
|
||||
/*! \class GCell::CompareByIndex
|
||||
*
|
||||
* \brief GCell Index Comparison Functor
|
||||
*
|
||||
* A comparison functor for GCell, compare by \c index (the linear
|
||||
* index in the GCellGrid vector.
|
||||
*/
|
||||
|
||||
//! \typedef typedef set<GCell*,CompareByIndex> GCell::SetIndex;
|
||||
//! Shorthand for a set of GCell sorted on their index.
|
||||
|
||||
|
||||
/*! \class GCell::CompareByDensity
|
||||
*
|
||||
* \brief GCell Density Comparison Functor
|
||||
*
|
||||
* A comparison functor for GCell, compare by density on layer \c depth.
|
||||
*/
|
||||
|
||||
//! \function GCell::CompareByDensity::CompareByDensity ( unsigned int depth );
|
||||
//! Build a density comparator for GCells on layer \c depth.
|
||||
|
||||
|
||||
/*! \class GCell::Key
|
||||
*
|
||||
* \brief GCell Key - Density Cache
|
||||
*
|
||||
* This class is used to create a GCell internal cache on density, mainly
|
||||
* to be used by GCellDensitySet.
|
||||
*/
|
||||
|
||||
//! \function GCell::Key::Key ( GCell* owner, unsigned int depth );
|
||||
//! \param owner The GCell owning the key.
|
||||
//! \param depth The layer \c depth of the density to use.
|
||||
//!
|
||||
//! Key constructor, with an initial value for the cached density.
|
||||
|
||||
//! \function GCell* GCell::Key::getGCell () const;
|
||||
//! \sreturn The owning GCell.
|
||||
|
||||
//! \function float GCell::Key::getDensity () const;
|
||||
//! \sreturn The value of the cached density.
|
||||
|
||||
//! \function void GCell::Key::update ( unsigned int depth );
|
||||
//! \sreturn Update the density
|
||||
|
||||
|
||||
/*! \class GCellDensitySet
|
||||
*
|
||||
* \brief GCell Set, sorted by density
|
||||
*
|
||||
* A small container helper to manage a set of GCell sorted by density
|
||||
* on a specific layer \c depth.
|
||||
*
|
||||
* The helper is implemented in term of a set. Once inserted in a set
|
||||
* an element must not have is sorting key changed. But GCell density
|
||||
* may change due to AutoSegment modifications during the lifetime of
|
||||
* the set. To circumvent this problem, the GCell provide a key attribute
|
||||
* to be used specifically with GCellDensitySet. This key act as a cached
|
||||
* copy of the GCell density which is updated \e only by a call to
|
||||
* GCell::updateKey() (and \e not GCell::updateDensity()). GCell which
|
||||
* density have changed and key has to be updated must be signaled to
|
||||
* set with the GCellDensityQueue::unqueue() method. When we want to
|
||||
* update the sorting of the set on the new densities, we call
|
||||
* GCellDensitySet::requeue() which, for each invalidated GCell do:
|
||||
* - Remove the GCell from the set.
|
||||
* - Update the key (call GCell::updateKey()).
|
||||
* - Reinsert the GCell in the set (thus with the updated key).
|
||||
*
|
||||
* Typical usage:
|
||||
\code
|
||||
GCellDensitySet gcells ( 2, *(getGCellGrid()->getGCellVector()) );
|
||||
|
||||
while ( true ) {
|
||||
bool optimized = false;
|
||||
|
||||
std::set<GCell*,GCell::CompareByKey>::const_iterator igcell = gcells.getGCells().begin();
|
||||
for ( ; igcell != gcells.getGCells().end() ; ++igcell ) {
|
||||
if ( doSomeOptimization(*igcell) ) {
|
||||
optimized = true;
|
||||
gcells.unqueue( *igcell );
|
||||
}
|
||||
}
|
||||
|
||||
if (not optimized) break;
|
||||
|
||||
gcells.requeue();
|
||||
}
|
||||
\endcode
|
||||
*
|
||||
*/
|
||||
|
||||
//! \function GCellDensitySet::GCellDensitySet ( unsigned int depth );
|
||||
//! Create a new empty GCellDensitySet, sorting on density of layer \c depth.
|
||||
|
||||
//! \function GCellDensitySet::GCellDensitySet ( unsigned int depth, const std::vector<GCell*>& gcells );
|
||||
//! Create a new empty GCellDensitySet, sorting on density of layer \c depth.
|
||||
//! Load the queue with the GCells supplied in the \c gcells vector.
|
||||
|
||||
//! \function GCellDensitySet::~GCellDensitySet ();
|
||||
//! Delete a GCellDensitySet, if the queue is not empty, issue a warning.
|
||||
|
||||
//! \function bool GCellDensitySet::empty () const;
|
||||
//! \sreturn \true if the queue is empty.
|
||||
|
||||
//! \function size_t GCellDensitySet::size () const;
|
||||
//! \sreturn the numbers of elements in the queue.
|
||||
|
||||
//! \function const std::set<GCell*,GCell::CompareByKey>& GCellDensitySet::getGCells () const;
|
||||
//! \sreturn the list of GCells currently in the queue.
|
||||
|
||||
//! \function size_t GCellDensitySet::insert ( GCell* gcell );
|
||||
//! Insert \c gcell into the set.
|
||||
|
||||
//! \function size_t GCellDensitySet::erase ( GCell* gcell );
|
||||
//! Remove \c gcell from the set.
|
||||
|
||||
//! \function void GCellDensitySet::unqueue ( GCell* gcell );
|
||||
//! Invalidate \c gcell. The density of \c gcell may have changed and needs to be
|
||||
//! reinserted into the queue. It is temporarily set asides until the next
|
||||
//! call to GCellDensitySet::requeue().
|
||||
|
||||
//! \function void GCellDensitySet::requeue ();
|
||||
//! Reinsert in the queue all the GCells that have been previously
|
||||
//! invalidated by a call to GCellDensitySet::unqueue(). This function calls
|
||||
//! GCell::updateKey() before reinserting the GCell.
|
||||
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class GCellGrid
|
||||
*
|
||||
* \brief GCell Grid
|
||||
*
|
||||
* The GCell Grid of Katabatic. Although the base template class
|
||||
* Grid support irregular grid, the GCellGrid is regular, following
|
||||
* the Knik global router GCells. Only the topmost row and leftmost
|
||||
* column may have different height or width to cope with the
|
||||
* design real size.
|
||||
*
|
||||
* Due to the regular nature of the grid, the horizontal & vertical
|
||||
* edges capacities are all identical, and initialized from the
|
||||
* Katabatic Configuration.
|
||||
*
|
||||
* The grid is build from the Knik global routing, so obviously
|
||||
* a KnikEngine must be attached to the Cell when building the
|
||||
* GCellGrid. An error is thrown otherwise.
|
||||
*/
|
||||
|
||||
//! \function GCellGrid* GCellGrid::create( KatabaticEngine* ktbt );
|
||||
//! API-space contructor.
|
||||
|
||||
//! \function void GCellGrid::_postCreate ();
|
||||
//! Perform the GCell & GCell vector allocation.
|
||||
//! - Read the horizontal and vertical cut lines from Knik and translate
|
||||
//! them into BaseGrid::Axis.
|
||||
//! - From the BaseGrid::Axis, deduces the exact positions of the GCells and
|
||||
//! allocate them.
|
||||
//! - The GCell allocation is done in a "row by row" fashion consistent
|
||||
//! with BaseGrid implicit assumptions.
|
||||
|
||||
//! \function void GCellGrid::_preDestroy ();
|
||||
//! The GCells are deleted at this point.
|
||||
|
||||
//! \function Cell* GCellGrid::getCell() const;
|
||||
//! \sreturn The associated Cell.
|
||||
|
||||
//! \function KatabaticEngine* GCellGrid::getKatabatic() const;
|
||||
//! \sreturn The associated KatabaticEngine.
|
||||
|
||||
//! \function unsigned int GCellGrid::getDensityMode() const;
|
||||
//! \sreturn The computation mode of the GCell densities.
|
||||
|
||||
//! \function size_t GCellGrid::getHEdgeCapacity() const;
|
||||
//! \sreturn The horizontal edge capacity. As the matrix is regular it is
|
||||
//! identical for all horizontal edges.
|
||||
|
||||
//! \function size_t GCellGrid::getVEdgeCapacity() const;
|
||||
//! \sreturn The vertical edge capacity. As the matrix is regular it is
|
||||
//! identical for all vertical edges.
|
||||
|
||||
//! \function Interval GCellGrid::getUSide( unsigned int direction ) const;
|
||||
//! \sreturn The side of the whole grid in \c direction.
|
||||
|
||||
//! \function size_t GCellGrid::checkDensity() const;
|
||||
//! \sreturn The number of GCell saturateds.
|
||||
//!
|
||||
//! Check all GCells for saturations.
|
||||
|
||||
//! \function bool GCellGrid::checkEdgeSaturation( float threshold ) const;
|
||||
//! \sreturn \true if at least one edge is over \c threshold (percentage
|
||||
//! of occupation).
|
||||
//!
|
||||
//! Check all the edges for saturations.
|
||||
|
||||
//! \function void GCellGrid::setDensityMode( unsigned int mode );
|
||||
//! Sets the density computation mode.
|
||||
|
||||
//! \function void GCellGrid::updateContacts( unsigned int flags=KbOpenSession );
|
||||
//! Force an update on all AutoContact on all the GCells.
|
||||
//! if \c openSession is \true, enclose the update in a Session.
|
||||
|
||||
//! \function size_t GCellGrid::updateDensity();
|
||||
//! \sreturn The number of GCell saturateds.
|
||||
//!
|
||||
//! Force a density update on all the GCells.
|
||||
|
||||
//! \enum GCellGrid::DensityMode
|
||||
//! Various ways of computing the overall density of a GCell.
|
||||
|
||||
//! \var GCellGrid::AverageHVDensity
|
||||
//! The average density all depths accounted.
|
||||
|
||||
//! \var GCellGrid::AverageHDensity
|
||||
//! The average density of horizontal layers.
|
||||
|
||||
//! \var GCellGrid::AverageVDensity
|
||||
//! The average density of horizontal layers.
|
||||
|
||||
//! \var GCellGrid::MaxHVDensity
|
||||
//! The maximum of the average horizontal & vertical densities taken
|
||||
//! as a whole.
|
||||
|
||||
//! \var GCellGrid::MaxVDensity
|
||||
//! The maximum of the average vertical densities taken depth by depth.
|
||||
|
||||
//! \var GCellGrid::MaxHDensity
|
||||
//! The maximum of the average horizontal densities taken depth by depth.
|
||||
|
||||
//! \var GCellGrid::MaxDensity
|
||||
//! The maximum of the average horizontal & vertical densities
|
||||
//! taken depth by depth.
|
||||
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
//! \typedef typedef GenericCollection<GCell*> GCells;
|
||||
//! GCell Collection with auto-pointer like support.
|
||||
|
||||
//! \typedef typedef GenericLocator<GCell*> GCellLocator;
|
||||
//! GCell Locator with auto-pointer like support.
|
||||
|
||||
//! \typedef typedef GenericFilter<GCell*> GCellFilter;
|
||||
//! GCell Filter with auto-pointer like support.
|
||||
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class BaseGrid
|
||||
*
|
||||
* \brief Abstract Base Class for Irregular Grid
|
||||
*
|
||||
* An abstract class for a 2-D matrix of objects. The grid is irregular
|
||||
* in the sense that the horizontal and vertical cut lines may not be
|
||||
* evenly spaced.
|
||||
*
|
||||
* The coordinates of cut lines in horizontal and vertical direction
|
||||
* are stored BaseGrid::Axis structure.
|
||||
*
|
||||
* The BaseGrid contains all the non-template methods of the Grid,
|
||||
* that is that do not depend of the matrix element type.
|
||||
*
|
||||
* The internal storage implemented in derived classes is expected to
|
||||
* store "row by row" (rows are put one after another in the vector).
|
||||
*/
|
||||
|
||||
//! \function void BaseGrid::destroy();
|
||||
//! The user-level destructor.
|
||||
|
||||
//! \function BaseGrid::BaseGrid ( const Box& bb );
|
||||
//! Construct a new BaseGrid on area \c bb. Graduations, rows & columns are
|
||||
//! sets to zero.
|
||||
|
||||
//! \function const Box& BaseGrid::getBoundingBox() const;
|
||||
//! \sreturn The grid bounding box.
|
||||
|
||||
//! \function unsigned int BaseGrid::getColumns() const;
|
||||
//! \sreturn The numbers of columns in the grid.
|
||||
|
||||
//! \function unsigned int BaseGrid::getRows() const;
|
||||
//! \sreturn The numbers of rows in the grid.
|
||||
|
||||
//! \function unsigned int BaseGrid::getRawSize() const;
|
||||
//! \sreturn The total number of elements in the grid (i.e. \f$ rows \times columns \f$)
|
||||
|
||||
//! \function unsigned int BaseGrid::getIndex( unsigned int c, unsigned int r ) const;
|
||||
//! An helper function that compute the linear index in the element
|
||||
//! vector from a \c (c,r) coordinate pair:
|
||||
//! \f[ index = c + r \times columns \f]
|
||||
|
||||
//! \function unsigned int BaseGrid::getRow( unsigned int i ) const;
|
||||
//! An helper function that compute the row number from the linear index in
|
||||
//! the vector:
|
||||
//! \f[ row = index / columns \f]
|
||||
|
||||
//! \function unsigned int BaseGrid::getColumn( unsigned int i ) const;
|
||||
//! An helper function that compute the column number from the linear index in
|
||||
//! the vector:
|
||||
//! \f[ column = index \div columns \f]
|
||||
|
||||
//! \function const Axis& BaseGrid::getXGrads() const;
|
||||
//! \sreturn The graduations on the X axis.
|
||||
|
||||
//! \function const Axis& BaseGrid::getYGrads() const;
|
||||
//! \sreturn The graduations on the Y axis.
|
||||
|
||||
|
||||
|
||||
/*! \class BaseGrid::Axis
|
||||
*
|
||||
* \brief Graduations on a BaseGrid Axis (H or V).
|
||||
*
|
||||
* Describe the list of graduations on either X or Y axis of a
|
||||
* BaseGrid. Graduations correspond to cut lines and may not be
|
||||
* evenly spaced.
|
||||
*
|
||||
* Graduations are internally stored into a vector that needs to be
|
||||
* sorted whenever new graduations are added (BaseGrid::Axis::sort()).
|
||||
*/
|
||||
|
||||
//! \function void BaseGrid::Axis::addGraduation ( DbU::Unit pos );
|
||||
//! Adds a new graduation. After adding new graduations, do not forget
|
||||
//! to perform a sort.
|
||||
|
||||
//! \function void BaseGrid::Axis::sort ();
|
||||
//! Re-order the graduations after an addition.
|
||||
|
||||
//! \function size_t BaseGrid::Axis::getSize () const;
|
||||
//! \sreturn The number of graduations on the axis.
|
||||
|
||||
//! \function DbU::Unit BaseGrid::Axis::getGraduationNumber ( DbU::Unit pos, bool& onGraduation ) const;
|
||||
//! \sreturn The index of the graduation which is immediatly inferior or equal to \c pos.
|
||||
//! In case of strict equality, \c onGraduation is set to \true.
|
||||
|
||||
//! \function DbU::Unit BaseGrid::Axis::operator[] ( unsigned int index ) const;
|
||||
//! \sreturn The graduation at \c index.
|
||||
|
||||
|
||||
/*! \class Grid
|
||||
*
|
||||
* \brief Template Class for Regular Grid
|
||||
*
|
||||
* Contains all general purpose methods depending on the GCell type
|
||||
* and geometrical computations. The internal storage is still not implemented
|
||||
* in this class.
|
||||
*/
|
||||
|
||||
//! \function Grid::Grid ( const Box& );
|
||||
//! Grid constructor.
|
||||
|
||||
//! \function CGellT* Grid::getGCell ( unsigned int index ) const;
|
||||
//! \sreturn The grid object at linear index \c index in the vector.
|
||||
//! If \c index is out of bounds, return \c NULL.
|
||||
|
||||
//! \function CGellT* Grid::getGCell ( const Point p ) const;
|
||||
//! \sreturn The grid object which is under position \c p.
|
||||
//!
|
||||
|
||||
//! \function CGellT* Grid::getGCell ( const Point p1, const Point p2 ) const;
|
||||
//! \sreturn The grid object which is under position \c p1 and \c p2.
|
||||
//! Not very clear though.
|
||||
|
||||
//! \function CGellT* Grid::getGCellLeft ( const GCellT* gcell ) const;
|
||||
//! \sreturn The left neighbor of \c gcell, \c NULL if it is the leftmost one.
|
||||
//!
|
||||
|
||||
//! \function CGellT* Grid::getGCellRight ( const GCellT* gcell ) const;
|
||||
//! \sreturn The rigth neighbor of \c gcell, \c NULL if it is the rightmost one.
|
||||
//!
|
||||
|
||||
//! \function CGellT* Grid::getGCellUp ( const GCellT* gcell ) const;
|
||||
//! \sreturn The upper neighbor of \c gcell, \c NULL if it is the uppermost one.
|
||||
//!
|
||||
|
||||
//! \function CGellT* Grid::getGCellDown ( const GCellT* gcell ) const;
|
||||
//! \sreturn The down neighbor of \c gcell, \c NULL if it is the downmost one.
|
||||
//!
|
||||
|
||||
//! \function GenericCollection<CGellT*> Grid::getGCells ();
|
||||
//! \sreturn A GCellT Hurricane collection built upon the linear GCellT vector of
|
||||
//! the grid.
|
||||
|
||||
//! \function GenericCollection<CGellT*> Grid::getGCellsColumn ( unsigned int column, unsigned int rowStart, unsigned int rowStop );
|
||||
//! \sreturn A GCellT Hurricane collection that contains the part of \c column starting
|
||||
//! from \c rowStart to \c rowStop inclusive.
|
||||
|
||||
//! \function GenericCollection<CGellT*> Grid::getGCellsRow ( unsigned int row, unsigned int columnStart, unsigned int columnStop );
|
||||
//! \sreturn A GCellT Hurricane collection that contains the part of \c row starting
|
||||
//! from \c columnStart to \c columnStop inclusive.
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
//! \mainpage Katabatic Documentation
|
||||
//!
|
||||
//! Additionnal documents:
|
||||
//! - \ref grpSynthHierarchy
|
||||
//!
|
||||
//! \defgroup grpSynthHierarchy Synthetic Class Hierarchy
|
||||
//! \brief Simplificated class hierarchy
|
||||
//!
|
||||
//! \htmlinclude customHierarchy.html
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \namespace Katabatic
|
||||
* \brief The namespace dedicated to Katabatic.
|
||||
*/
|
||||
|
||||
}
|
|
@ -1,307 +0,0 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class KatabaticEngine
|
||||
*
|
||||
* \brief The Katabatic Tool
|
||||
*
|
||||
*
|
||||
* \section secEngineStates States of KatabaticEngine
|
||||
*
|
||||
* During it's lifecycle, the engine go through a serie of states.
|
||||
* It only can go forward between states.
|
||||
* - \b EngineCreation : just after C++ object creation until
|
||||
* the global routing is loaded.
|
||||
* - \b EngineGlobalLoaded : \e after the global routing has
|
||||
* been done. This state must be set by an external tool,
|
||||
* Katabatic cannot know by itself when the global routing
|
||||
* has been done (see Kite).
|
||||
* - \b EngineActive : \e after the global routing has been
|
||||
* converted into the Katabatic data structure. At this point
|
||||
* the tool is ready to run.
|
||||
* - \b EngineDriving : \e during the stage of stripping all
|
||||
* the decorations the tool has added over the Hurricane data
|
||||
* structure (mostly: AutoContact & AutoSegment).
|
||||
* - \b EngineGutted : \e after the tool decorations have been
|
||||
* removed. The tool is now useless and can only be destroyed.
|
||||
* - \b EnginePreDestroying : this special state is reached when
|
||||
* going straight from EngineActive to the destructor, that is,
|
||||
* skipping the EngineDriving state. That means we <em>do not</em>
|
||||
* want to save whatever routing has been done. In that case,
|
||||
* not only the tool decorations are destroyeds, but also the
|
||||
* Hurricane data-structures they relies on (Contact, Segments).
|
||||
*
|
||||
*
|
||||
* \section secEngineImpl KatabaticEngine Implementation Details
|
||||
*
|
||||
* Due to the size of the code and the fact that the main body
|
||||
* of some methods do not need to be present in the class,
|
||||
* the implementation of KatabaticEngine is split in several
|
||||
* files. The list below summarize them:
|
||||
* - \c KatabaticEngine.cpp : the core of the class, methods that really
|
||||
* need their bodies here.
|
||||
* - \c PowerRails.cpp : utilities to construct an abstract from all
|
||||
* the power rails through the hierarchy.
|
||||
* - \c LayerAssign.cpp : layer assignement related methods and helpers.
|
||||
* - \c LoadGrByNet.cpp : global routing loader, transform global routing
|
||||
* into Katabatic data-structure.
|
||||
* - \c NetConstraints.cpp : compute the topological constraints of all
|
||||
* AutoSegment/AutoContact of a Net.
|
||||
* - \c NetOptimals.cpp : compute the optimal positions of all AutoSegment
|
||||
* of a Net.
|
||||
*/
|
||||
|
||||
//! \enum EngineState
|
||||
//! Describe the current state of the KatabaticEngine.
|
||||
|
||||
//! \var EngineCreation
|
||||
//! The tool is created, but still in the \c _postCreate stage.
|
||||
|
||||
//! \var EngineGlobalLoaded
|
||||
//! The global routing has been loaded from Knik.
|
||||
|
||||
//! \var EngineActive
|
||||
//! The Engine is in normal running mode (routing ordinary wires).
|
||||
|
||||
//! \var EngineDriving
|
||||
//! The Engine is transforming the AutoContact/AutoSegment into
|
||||
//! normal Contact/Segment (prior to tool deletion).
|
||||
|
||||
//! \var EnginePreDestroying
|
||||
//! This state is used whenever the tool is destroyed without passing
|
||||
//! through the EngineDriving state.
|
||||
|
||||
//! \var EngineGutted
|
||||
//! After the EngineDriving state, all the working structures are
|
||||
//! removed and the tool can no longer be used. It only awaits clean
|
||||
//! destruction.
|
||||
|
||||
//! \typedef set<Net*, NetCompareByName> KatabaticEngine::NetSet;
|
||||
//! Set of Net to be routed, alphabetically sorteds.
|
||||
|
||||
|
||||
//! \function KatabaticEngine* KatabaticEngine::create ( Cell* cell );
|
||||
//! Create a KatabaticEngine on \c cell.
|
||||
|
||||
//! \function const Name& KatabaticEngine::staticGetName ();
|
||||
//! \sreturn The unique string identifier for the KatabaticEngine class of ToolEngine.
|
||||
|
||||
//! \function bool KatabaticEngine::isGMetal ( const Layer* layer ) const;
|
||||
//! \sreturn \true if \c layer is one of the special (fake) metals used to build
|
||||
//! the global routing.
|
||||
|
||||
//! \function bool KatabaticEngine::isChip () const;
|
||||
//! \sreturn \true if the hierarchy top-level of the Cell matches the one of a complete
|
||||
//! design (i.e. pads and one core instance).
|
||||
|
||||
//! \function bool KatabaticEngine::isInDemoMode () const;
|
||||
//! \sreturn \true if the tool is in demo mode, that is suppress almost all warning
|
||||
//! and debug messages.
|
||||
|
||||
//! \function bool KatabaticEngine::doWarnOnGCellOverload () const;
|
||||
//! \sreturn \true if the tool should issue a warning when a GCell is overloaded
|
||||
//! (overload could be transient).
|
||||
|
||||
//! \function bool KatabaticEngine::doDestroyBaseContact () const;
|
||||
//! \sreturn \true if the EngineDestroyBaseContact is set, meaning that when an
|
||||
//! AutoContact is destroyed, the Contact it decorates is destroyed
|
||||
//! altogether.
|
||||
|
||||
//! \function bool KatabaticEngine::doDestroyBaseSegment () const;
|
||||
//! \sreturn \true if the EngineDestroyBaseSegment is set, meaning that when an
|
||||
//! AutoSegment is destroyed, the Segment it decorates is destroyed
|
||||
//! altogether.
|
||||
|
||||
//! \function bool KatabaticEngine::doDestroyTool () const;
|
||||
//! \sreturn \true if the tool state is beyond EngineStateGutted, that is, only
|
||||
//! waits for \c destroy() to be called.
|
||||
|
||||
//! \function const Name& KatabaticEngine::getName () const;
|
||||
//! \sreturn The unique string identifier for the KatabaticEngine class of ToolEngine.
|
||||
|
||||
//! \function EngineState KatabaticEngine::getState () const;
|
||||
//! \sreturn The state the tool is currently in.
|
||||
|
||||
//! \function unsigned int KatabaticEngine::getFlags ( unsigned int mask ) const;
|
||||
//! \sreturn The \e anded combination of the tool flags and \c mask.
|
||||
|
||||
//! \function Configuration* KatabaticEngine::getKatabaticConfiguration ();
|
||||
//! \sreturn The Configuration of Katabatic. In this class it is redundant with
|
||||
//! getConfiguration(), but may be useful in derived classes.
|
||||
|
||||
//! \function Configuration* KatabaticEngine::getConfiguration ();
|
||||
//! \sreturn The Configuration of the current ToolEngine.
|
||||
|
||||
//! \function RoutingGauge* KatabaticEngine::getRoutingGauge () const;
|
||||
//! \sreturn The RoutingGauge (Configuration shortcut).
|
||||
|
||||
//! \function RoutingLayerGauge* KatabaticEngine::getLayerGauge ( size_t depth ) const;
|
||||
//! \sreturn The RoutingLayerGauge associated to \c depth (Configuration shortcut).
|
||||
|
||||
//! \function const Layer* KatabaticEngine::getRoutingLayer ( size_t depth ) const;
|
||||
//! \sreturn The routing Layer associated to \c depth (Configuration shortcut).
|
||||
|
||||
//! \function Layer* KatabaticEngine::getContactLayer ( size_t depth ) const;
|
||||
//! \sreturn The contact Layer associated to \c depth (Configuration shortcut).
|
||||
|
||||
//! \function DbU::Unit KatabaticEngine::getGlobalThreshold () const;
|
||||
//! \sreturn The length above which a global wire is moved up in the layer assignment
|
||||
//! stage (Configuration shortcut).
|
||||
|
||||
//! \function float KatabaticEngine::getSaturateRatio () const;
|
||||
//! \sreturn The ratio above which a GCell is considered to be saturated
|
||||
//! (Configuration shortcut).
|
||||
|
||||
//! \function DbU::Unit KatabaticEngine::getExtensionCap () const;
|
||||
//! \sreturn The wires extension cap, same for all layers for the time beeing
|
||||
//! (Configuration shortcut).
|
||||
|
||||
//! \function size_t KatabaticEngine::getSaturateRp () const;
|
||||
//! \sreturn The number of RoutingPad above which a GCell is saturated, causing
|
||||
//! extras global segments to be moved up.
|
||||
//! (Configuration shortcut).
|
||||
|
||||
//! \function GCellGrid* KatabaticEngine::getGCellGrid () const;
|
||||
//! \sreturn The GCellGrid.
|
||||
|
||||
//! \function const NetSet& KatabaticEngine::getRoutingNets () const;
|
||||
//! \sreturn The set of nets to be routeds.
|
||||
|
||||
//! \function const ChipTools& KatabaticEngine::getChipTools () const;
|
||||
//! \sreturn The chip tools (for whole designs).
|
||||
|
||||
//! \function void KatabaticEngine::xmlWriteGCellGrid ( ostream& );
|
||||
//! Write in a stream all informations on the GCells in XML format.
|
||||
|
||||
//! \function void KatabaticEngine::xmlWriteGCellGrid ( const string& );
|
||||
//! Write in a file all informations on the GCells in XML format.
|
||||
|
||||
//! \function void KatabaticEngine::setState ( EngineState state );
|
||||
//! Force the state of the tool. Must be used with caution, as no sanity
|
||||
//! checks are performeds. This method is normally invoked from inside
|
||||
//! the KatabaticEngine various methods.
|
||||
|
||||
//! \function void KatabaticEngine::setFlags ( unsigned int flags );
|
||||
//! Set the flags given in \c flags.
|
||||
|
||||
//! \function void KatabaticEngine::unsetFlags ( unsigned int flags );
|
||||
//! Reset the flags given in \c flags.
|
||||
|
||||
//! \function void KatabaticEngine::setGlobalThreshold ( DbU::Unit );
|
||||
//! (Configuration shortcut).
|
||||
|
||||
//! \function void KatabaticEngine::setSaturateRatio ( float );
|
||||
//! (Configuration shortcut).
|
||||
|
||||
//! \function void KatabaticEngine::setSaturateRp ( size_t );
|
||||
//! (Configuration shortcut).
|
||||
|
||||
//! \function void KatabaticEngine::startMeasures ();
|
||||
//! Starts memory consuption & time measurements.
|
||||
|
||||
//! \function void KatabaticEngine::stopMeasures ();
|
||||
//! Stops memory consuption & time measurements. Recorded measures are
|
||||
//! kept until the next call to Katabatic::startMeasures().
|
||||
|
||||
//! \function void KatabaticEngine::printMeasures ( const string& tag ) const;
|
||||
//! Print memory & time measurement on ``cmess1``. If \c tag is not empty,
|
||||
//! also adds the measurement to the internal table (with \c tag as label).
|
||||
|
||||
//! \function void KatabaticEngine::refresh ( unsigned int flags=KbOpenSession );
|
||||
//! In case the tool is associated with a graphic display, trigger
|
||||
//! a full redraw of the Cell. Slow the router but allow to see work
|
||||
//! in progress... If \c flags <em>do not</em> contains \c KbOpenSession
|
||||
//! the refresh operation will not be enclosed inside it's own session.
|
||||
//! This assumes that a session is already opened.
|
||||
|
||||
//! \function void KatabaticEngine::makePowerRails ();
|
||||
//! Detect all the aligned segments of same width that compose power
|
||||
//! rails, unificate them and copy them at the design top level.
|
||||
|
||||
//! \function void KatabaticEngine::createDetailedGrid ();
|
||||
//! Allocate the GCellGrid.
|
||||
|
||||
//! \function void KatabaticEngine::loadGlobalRouting ( unsigned int method, NetSet& nets );
|
||||
//! \param method the loading algorithm
|
||||
//! \param nets the set of nets to route.
|
||||
//!
|
||||
//! Convert the global routing into the initial detailed routing. For the
|
||||
//! time beeing, only one loading algorithm is available: <em>net by net</em>
|
||||
//! (EngineLoadGrByNet). Only Net given in \c nets are routeds. If \c nets is empty
|
||||
//! then all ordinary nets are routeds. In either cases the set of nets to route
|
||||
//! is pruned from any power, ground or clock signals.
|
||||
//!
|
||||
//! \remark The tool state must be \b EngineGlobalLoaded \e before calling this method
|
||||
//! and will be set to \b EngineActive on exit.
|
||||
|
||||
//! \function void KatabaticEngine::layerAssign ( unsigned int method );
|
||||
//! Perform the layer assignment. The global routing loading stage uses only
|
||||
//! the two bottom most layers, this method spread them on all the availables
|
||||
//! routing layers, according to GCell and RoutingPad density criterions.
|
||||
//!
|
||||
//! Two algorithms are availables:
|
||||
//! - \b EngineLayerAssignByLength : the global wires are moved up one by
|
||||
//! one.
|
||||
//! - \b EngineLayerAssignByTrunk : if one global wire of a net is to be
|
||||
//! moved up, then all the global trunk of the net is moved along.
|
||||
//! This methods gives the best results for now.
|
||||
|
||||
//! \function void KatabaticEngine::finalizeLayout ();
|
||||
//! Transform the Katabatic wires into the Hurricane data-structure.
|
||||
//! Mostly by removing the AutoSegment/AutoContact \e without removing
|
||||
//! their Hurricane conterparts. May also fill gaps that may have appeared.
|
||||
//!
|
||||
//! \remark The tool state must be \b EngineActive \e before calling this method
|
||||
//! and will be set to \b EngineGutted on exit.
|
||||
|
||||
//! \function void KatabaticEngine::slackenBorder ( Box bb, Layer::Mask mask, unsigned int flags );
|
||||
//! \param bb The bounding box, defines the edges.
|
||||
//! \param mask Consider only layers that are fully included in that mask.
|
||||
//! \param flags Consider only segment in that direction.
|
||||
//!
|
||||
//! Perform a preventive break on all global segments going through the
|
||||
//! \e vertical left and right edges of the \c bb box. The set of global
|
||||
//! segments to be broken could be further restricted using \c mask and
|
||||
//! \c flags.
|
||||
//!
|
||||
//! <span class="red">The Semantic of \c flags is not clear, must review the
|
||||
//! code more closely.</span>
|
||||
|
||||
//! \function void KatabaticEngine::slackenBlockIos ( Instance* core );
|
||||
//! Perform a preventive break on horizontal segments in the GCell immediatly
|
||||
//! \e outside the instance \c core area in the routing layer of index \c 1.
|
||||
//!
|
||||
//! \red{This method is too much hardwired to the \c SxLib gauge. It's effect is to break all \b METAL2 outside the core (in a chip).}
|
||||
|
||||
//! \function bool KatabaticEngine::moveUpNetTrunk ( AutoSegment* seed, set<Net*>& globalNets, GCell::SetIndex& invalidateds );
|
||||
//! \param seed The AutoSegment to take the net from.
|
||||
//! \param globalNets The set of nets that has been moved up.
|
||||
//! \param invalidateds The set of GCells that have been invalidated.
|
||||
//! \sreturn \true if the net trunk have been moved up.
|
||||
//!
|
||||
//! Try to move up a whole net trunk. The net is supplied through the \c seed
|
||||
//! argument (the segment that triggers the move). If the net is actually moved
|
||||
//! up, it is added to \c globalNets and all GCells that have been invalidateds
|
||||
//! are added to \c invalidateds.
|
||||
//!
|
||||
//! <span class="red">An individual AutoSegment of the net is moved up if it's length
|
||||
//! is greater that \c 150 lambdas, that is, three times the side of a GCell. This is
|
||||
//! hard-wired and should be parametrized in the future.</span>
|
||||
|
||||
//! \function void KatabaticEngine::computeNetConstraints ( Net* net );
|
||||
//! Compute the box constraints on AutoContacts (and therefore those applied to
|
||||
//! AutoSegments). Constraints comes from AutoContacts anchoreds on RoutingPads
|
||||
//! and transmitted through AutoContactHTee or AutoContactVTee. Constraints are
|
||||
//! applied to all AutoContacts of an aligned set.
|
||||
//!
|
||||
//! \remark The \c net must have been canonized before this function to be called.
|
||||
|
||||
//! \function void KatabaticEngine::toOptimals ( Net* net );
|
||||
//! Move all AutoSegment of \c net so that their axis are inside their
|
||||
//! optimals interval. If a AutoSegment is already inside the interval is
|
||||
//! not moved, otherwise it is put on the nearest bound of the optimal
|
||||
//! interval.
|
||||
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
|
||||
.. -*- Mode: rst -*-
|
||||
|
||||
.. role:: raw-latex(raw)
|
||||
:format: latex
|
||||
|
||||
.. role:: ul
|
||||
.. role:: cb
|
||||
.. role:: sc
|
||||
|
||||
|
||||
=========================
|
||||
Katabatic 3 Modifications
|
||||
=========================
|
||||
|
||||
|
||||
General Structuration
|
||||
=====================
|
||||
|
||||
* Short-circuit the usage of the Hurricane DataBase. Now AutoContacts
|
||||
& AutoSegments are cached directly in the relevant objects. This is
|
||||
way bigger, but should be faster. And anyway simpler to write by
|
||||
suppressing Ring walkthrough and Session::lookup() calls.
|
||||
|
||||
|
||||
AutoContact
|
||||
===========
|
||||
|
||||
* Now splitted in four sub-classes:
|
||||
|
||||
* AutoContactTerminal
|
||||
* AutoContactTurn
|
||||
* AutoContactHTee
|
||||
* AutoContactVTee
|
||||
|
||||
* isCorner() renamed isTurn().
|
||||
* isTerminal() is now ambiguous. It may be flag an AutoContact which *is*
|
||||
an AutoContactTurn indeed or an AutoContactTurn leading uniquely toward
|
||||
a Terminal.
|
||||
|
||||
|
||||
AutoHorizontal/AutoVertical
|
||||
===========================
|
||||
|
||||
* New AutoSegment::makeTopologyDogLeg() creates dogleg needed by topological
|
||||
adjustments on AutoContact. They are not counted (nor signaled) as explicit
|
||||
dogleg request. **To Implement**.
|
||||
|
||||
* The local ``slacken()`` methods are, in fact AutoSegment::makeTopologyDogLeg().
|
||||
|
||||
* We now must be able to create AutoHorizontal/AutoContact without suppling
|
||||
the anchor AutoContacts. Allows more supple building constructions.
|
|
@ -1,86 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class Observable
|
||||
*
|
||||
* \brief Observer Design Pattern, Subject part.
|
||||
*
|
||||
*
|
||||
* Observable is the implementation of the \e subject part of the
|
||||
* Observer design pattern. For the time beeing it's a simplificated
|
||||
* version that allows only one Observer to watch the subject.
|
||||
*
|
||||
* Observable is designed to be an attribute of the subject, not one
|
||||
* of it's base class.
|
||||
*
|
||||
* This implantation is completly generic and has nothing specific
|
||||
* to Katabatic. It may be moved sometimes in Hurricane at Property
|
||||
* level in Hurricane::DBo.
|
||||
*
|
||||
* <b>Note to Myself:</b> Observer pattern is the one behind signal/slots.
|
||||
*/
|
||||
|
||||
//! \function Observable::Observable ();
|
||||
//! Default and only constructor. The copy constructor is disabled
|
||||
//! (made private and unimplemented).
|
||||
|
||||
//! \function T* Observable::getObserver ();
|
||||
//! \sreturn The (only) observer, \c NULL if there is none. It is the object
|
||||
//! of which the Observer is an attribute, that is, it's \e owner, and not
|
||||
//! the Observer itself which is returned.
|
||||
|
||||
//! \function void Observable::addObserver ( BaseObserver* observer );
|
||||
//! Adds an observer. If more than one is added, throw an error.
|
||||
|
||||
//! \function void Observable::removeObserver ( BaseObserver* observer );
|
||||
//! Removes an observer. If the observer do not belong to this observable,
|
||||
//! throw an exception.
|
||||
|
||||
//! \function void Observable::notify ( unsigned int flags );
|
||||
//! Used by the subject to signal a change in it's state to the observers.
|
||||
//! The \c flags parameter can be used to indicates what kind of change
|
||||
//! is occuring. Values for \c flags are defined between the subject and
|
||||
//! the observers.
|
||||
|
||||
|
||||
/*! \class BaseObserver
|
||||
*
|
||||
* \brief Observer Design Pattern, Observer part.
|
||||
*
|
||||
* This class is used as a non-template base class for the templatized
|
||||
* Observer one. It is used to avoid propagating template to the whole
|
||||
* Observable class. It only contains the Observer::notify() virtual
|
||||
* method.
|
||||
*/
|
||||
|
||||
//! \function void BaseObserver::notify ( unsigned int flags );
|
||||
//! The method which will be called whenever a change occurs on the Observable.
|
||||
|
||||
|
||||
/*! \class Observer
|
||||
*
|
||||
* \brief Observer Design Pattern, Observer part.
|
||||
*
|
||||
* <b>First, a warning about names:</b> although this class is named
|
||||
* Observer, it is intended to be an attribute nested inside the
|
||||
* whole object which is indeed, the true Observer. This nesting object
|
||||
* is called, most of the time the \b owner in the following. But
|
||||
* sometimes, for simplification it may also be called the Observer.
|
||||
*
|
||||
* \section secImplObserver Observer Implementation Notes
|
||||
*
|
||||
* To retrieve the \e owner from the Observer attribute, we uses the
|
||||
* offset from the attribute in the \e owner. This offset is computed
|
||||
* once and for all the first time the template constructor is called.
|
||||
*/
|
||||
|
||||
//! \function Observer::Observer ( const T* owner );
|
||||
//! The owner of the oberver is needed to compute, on the first creation
|
||||
//! only, the offset of the Observer attribute inside the \c owner complete
|
||||
//! object.
|
||||
|
||||
//! \function T* Observer::getOwner () const;
|
||||
//! \sreturn The owner of the observer.
|
||||
|
||||
}
|
|
@ -1,218 +0,0 @@
|
|||
// -*- mode: C++; explicit-buffer-name: "Session.dox<katabatic>" -*-
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
/*! \class Session
|
||||
*
|
||||
* \brief Modification Session for Katabatic
|
||||
*
|
||||
* To perform modifications, the Katabatic data structure uses a session
|
||||
* mechanism built on top of the Hurricane::UpdateSession one. Sessions
|
||||
* obeys very simples rules:
|
||||
* - Only one Session can be opened at a time with Session::open().
|
||||
* - Subsequent calls to Session::open() returns the currently
|
||||
* opened session until Session::close() is called.
|
||||
* - Revalidation can take place whithout closing the Session by
|
||||
* calling Session::revalidate().
|
||||
*
|
||||
* The task of a Session is to keep track of the AutoContact and
|
||||
* AutoSegment that have been modificateds (i.e. invalidated) and,
|
||||
* to restore connexity and/or topology when closed.
|
||||
*
|
||||
* Two kinds of revalidation could be performed:
|
||||
* <ul>
|
||||
* <li>\b Geometrical : only positions of AutoContacts and AutoSegments
|
||||
* extensions are recomputed.
|
||||
* <li>\b Topological : a whole net have been invalidated because of a
|
||||
* dogleg creation or a move up/move down of a segment.
|
||||
* <ul>
|
||||
* <li>\b Dogleg : needs to insert the newly created AutoSegments
|
||||
* and AutoContacts.
|
||||
* <li><b>Move up/Move down</b> : may needs to create additional
|
||||
* dogleg to restore connexity (gaps), and then insert them
|
||||
* like above.
|
||||
* </ul>
|
||||
* After a topological mofication has been done, the net needs to
|
||||
* be re-canonized then the geometrical step takes place.
|
||||
* </ul>
|
||||
*
|
||||
* The kind of revalidation needed is automatically detected by
|
||||
* the Session.
|
||||
*
|
||||
* In addition to it's main purpose, Session also provides cached
|
||||
* access to frequently needed variables either from Hurricane
|
||||
* or Katabatic Configuration and access to the AutoContact &
|
||||
* AutoSegment LUTs of KatabaticEngine.
|
||||
*
|
||||
* From a software point of view, Session is a singleton object.
|
||||
*
|
||||
*
|
||||
* \section secSessionAlgo Session Algorithm
|
||||
*
|
||||
* Main attributes of a Session:
|
||||
* - \c _netInvalidateds, nets on which topology has changed.
|
||||
* - \c _autoSegments, that have been moved or createds.
|
||||
* - \c _autoContacts, that have been created or one of their
|
||||
* slave segment has moved.
|
||||
* - \c _revalidateds, the list of AutoSegments that have just
|
||||
* been revalidated (after calling \c revalidate()).
|
||||
*
|
||||
* Schematic description of how a Session works:
|
||||
*
|
||||
* <ul class="algo1">
|
||||
* <li> If at least one net has been invalidated, meaning that it's
|
||||
* topology has changed, perform \c _revalidateTopology().
|
||||
* <ul class="algo2">
|
||||
* <li> Update net topology: correct the topology of each
|
||||
* contacts, making dogleg when needed. The AutoContact
|
||||
* segment caching is updated at this point.
|
||||
* <li> Compute net constraints (on AutoContacts & AutoSegments).
|
||||
* <li> Compute net optimal positions (on AutoSegments).
|
||||
* <li> Compute the state of the segments regarding to terminals.
|
||||
* <li> Canonize sets of aligneds segments. The canonical segment
|
||||
* is the one with the lowest \c id.
|
||||
* <li> If the segments has just been created, put it on its
|
||||
* optimal axis.
|
||||
* </ul>
|
||||
* This stage can add itself more invalidated AutoSegments and
|
||||
* AutoContacts as it create doglegs.
|
||||
*
|
||||
* <li> Revalidate geometry of AutoContacts. That is, expand or shrink
|
||||
* the extremities of the invalidated AutoSegments. Note that
|
||||
* AutoSegments are already at on their final axis position.
|
||||
*
|
||||
* <li> Revalidate AutoSegments. Just before this stage, they are
|
||||
* on the correct axis and their extensions are also correct,
|
||||
* so we may update the caching of their characteristics
|
||||
* (mostly the extension).
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
//! \function Session* Session::get ( const char* message=NULL );
|
||||
//! Return the Session singleton, if no session is currently open
|
||||
//! throw an exception carrying \c message.
|
||||
|
||||
//! \function Technology* Session::getTechnology ();
|
||||
//! Hurricane shortcut.
|
||||
|
||||
//! \function KatabaticEngine* Session::getKatabatic ();
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function const Configuration* Session::getConfiguration ();
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function RoutingGauge* Session::getRoutingGauge ();
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function unsigned int Session::getLayerDirection ( const Layer* layer );
|
||||
//! Returns the preferred routing direction of \c layer, as per defined
|
||||
//! in the RoutingGauge.
|
||||
//!
|
||||
//! \remark The value returned is transformed from the CRL Constants value
|
||||
//! into Katabatic constants (Katabatic::KbHorizontal, Katabatic::KbVertical).
|
||||
|
||||
//! \function bool Session::isInDemoMode ();
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function float Session::getSaturateRatio ();
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function size_t Session::getSaturateRp ();
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function bool Session::doWarnGCellOverload ();
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function DbU::Unit Session::getExtensionCap ();
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function const Layer* Session::getRoutingLayer ( size_t );
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function const Layer* Session::getContactLayer ( size_t );
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function size_t Session::getSegmentStackSize ();
|
||||
//! \sreturn The number of AutoSegment in the invalidated stack.
|
||||
|
||||
//! \function size_t Session::getContactStackSize ();
|
||||
//! \sreturn The number of AutoSegment in the invalidated stack.
|
||||
|
||||
//! \function const vector<AutoSegment*>& Session::getInvalidateds ();
|
||||
//! \sreturn The stack (vector) of invalidateds AutoSegments.
|
||||
|
||||
//! \function const vector<AutoSegment*>& Session::getRevalidateds ();
|
||||
//! \sreturn The stack (vector) of AutoSegments that have been revalidateds.
|
||||
|
||||
//! \function const vector<AutoSegment*>& Session::getDoglegs ();
|
||||
//! \sreturn The vector of AutoSegments part of a newly created dogleg.
|
||||
//! The dogleg creation functions in AutoHorizontal and AutoVertical
|
||||
//! put a triplet (for example in horizontal direction \c (h1,v1,h2) )
|
||||
//! for each dogleg composed of:
|
||||
//! - \b h1 the segment \e before the dogleg (which is also the original one).
|
||||
//! - \b v1 the segment \b perpandicular (new).
|
||||
//! - \b h2 the segment \b after (new).
|
||||
|
||||
//! \function const set<Net*>& Session::getNetsModificateds ();
|
||||
//! \sreturn The set of Nets that needs either a topological update or a new
|
||||
//! canonization.
|
||||
|
||||
//! \function Session* Session::open ( KatabaticEngine* );
|
||||
//! Opens a new session or returns the already opened one, if any.
|
||||
|
||||
//! \function void Session::close ();
|
||||
//! Close the Session, triggering the revalidation of the AutoSegemnts
|
||||
//! and AutoContacts. If no Session is opened, throws an execption.
|
||||
|
||||
//! \function void Session::setKatabaticFlags ( unsigned int );
|
||||
//! Katabatic shortcut.
|
||||
|
||||
//! \function void Session::dogleg ( AutoSegment* );
|
||||
//! Adds an AutoSegment to the dogleg vector.
|
||||
|
||||
// \function void Session::doglegReset ();
|
||||
// Clears the dogleg vector.
|
||||
|
||||
//! \function void Session::revalidateTopology ();
|
||||
//! Revalidate Net that have been invalidateds and re-canonize them.
|
||||
|
||||
//! \function void Session::setInvalidateMask ( unsigned int flags );
|
||||
//! Tells what kind of revalidation must be performed.
|
||||
|
||||
//! \function void Session::invalidate ( Net* net );
|
||||
//! Schedule \c net for a full revalidation, topological correction
|
||||
//! and canonization.
|
||||
|
||||
//! \function void Session::invalidate ( AutoSegment* segment );
|
||||
//! Schedule \c segment for revalidation.
|
||||
|
||||
//! \function void Session::invalidate ( AutoContact* contact );
|
||||
//! Schedule \c contact for revalidation.
|
||||
|
||||
//! \function size_t Session::revalidate ();
|
||||
//! Perform the revalidation. Returns the sum of AutoContacts and
|
||||
//! AutoSegemnts that have been revalidated.
|
||||
|
||||
//! \function void Session::link ( AutoContact* ac );
|
||||
//! Adds \c ac in the AutoContact lookup table (allow to retrieve an
|
||||
//! AutoContact by it's base Contact).
|
||||
|
||||
//! \function void Session::link ( AutoSegment* as );
|
||||
//! Adds \c as in the AutoSegment lookup table (allow to retrieve an
|
||||
//! AutoSegment by it's base Segment).
|
||||
|
||||
//! \function void Session::unlink ( AutoContact* ac );
|
||||
//! Removes \c ac from the AutoContact lookup table.
|
||||
|
||||
//! \function void Session::unlink ( AutoSegment* as );
|
||||
//! Removes \c as from the AutoSegment lookup table.
|
||||
|
||||
//! \function AutoContact* Session::lookup ( Contact* contact );
|
||||
//! Lookup the AutoContact associated with \c contact. \c NULL if not found.
|
||||
|
||||
//! \function AutoSegment* Session::lookup ( Segment* segment );
|
||||
//! Lookup the AutoSegment associated with \c segment. \c NULL if not found.
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,882 +0,0 @@
|
|||
|
||||
|
||||
/*
|
||||
* +-----------------------------------------------------------------+
|
||||
* | HTML Standart Tags |
|
||||
* +-----------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 {
|
||||
font-size: 11pt;
|
||||
/* The Open Sans font family is supplied by TexLive. */
|
||||
font-family: "Roboto", "Open Sans", Verdana, sans-serif;;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #dddddd;
|
||||
}
|
||||
|
||||
body {
|
||||
color: black;
|
||||
background: white;
|
||||
background-color: white;
|
||||
background-position: top left;
|
||||
background-attachment: fixed;
|
||||
background-repeat: no-repeat;
|
||||
margin-top: 2em;
|
||||
width: 600pt;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding: 30pt;
|
||||
/*
|
||||
margin-right: 12%;
|
||||
margin-left: 12%;
|
||||
*/
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
color: #004400;
|
||||
background-color: #004400;
|
||||
}
|
||||
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
/*font-family: "URW Bookman L", "Liberation Serif", sans-serif;*/
|
||||
font-family: "URW Bookman L";
|
||||
}
|
||||
|
||||
h1.header { text-align: center; }
|
||||
h1 { text-align: left; }
|
||||
h2, h3, h4, h5, h6 { text-align: left;
|
||||
padding-top: 11pt;
|
||||
}
|
||||
h1, h2, h3 { /*font-family: "Liberation Serif", sans-serif; */
|
||||
/*color: #09550B;*/
|
||||
}
|
||||
h1 { font-weight: bold; font-size: 170%; /*letter-spacing:0.2em; word-spacing:0.4em;*/ }
|
||||
h2 { font-weight: bold; font-size: 140%; /*letter-spacing:0.2em; word-spacing:0.4em;*/ }
|
||||
h3 { font-weight: bold; font-size: 118%; /*letter-spacing:0.2em; word-spacing:0.4em;*/ }
|
||||
h4 { font-weight: bold; font-size: 100%; }
|
||||
h5 { font-style: italic; font-size: 100%; }
|
||||
h6 { font-variant: small-caps; font-size: 100%; }
|
||||
|
||||
h2.classHierarchy {
|
||||
/*border: 1px none #008500;*/
|
||||
border: 1px none #000000;
|
||||
border-top-width: 1px;
|
||||
border-top-style: dotted;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
p {
|
||||
margin-top: 0.6em;
|
||||
margin-bottom: 0.6em;
|
||||
margin-left: 0.0em;
|
||||
margin-right: 0.0em;
|
||||
}
|
||||
|
||||
|
||||
address {
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
|
||||
caption { font-weight: bold }
|
||||
|
||||
|
||||
blockquote {
|
||||
margin-left: 4em;
|
||||
margin-right: 4em;
|
||||
margin-top: 0.8em;
|
||||
margin-bottom: 0.8em;
|
||||
font-style: italic;
|
||||
color: #003300;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
blockquote address {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
dt, dd { margin-top: 0; margin-bottom: 0; }
|
||||
dt { font-weight: bold; }
|
||||
|
||||
|
||||
pre, tt, code {
|
||||
/*font-family: "andale mono", monospace;*/
|
||||
font-size: 100%;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 80%;
|
||||
/*border: dashed;*/
|
||||
border-width: thin;
|
||||
border-color: #003300;
|
||||
/*background-color: #EEEEEE;*/
|
||||
background-color: #FCFCE1;
|
||||
padding: 0.5em;
|
||||
margin-left: 2em;
|
||||
margin-right: 2em
|
||||
}
|
||||
|
||||
/*
|
||||
tt { color: green; }
|
||||
*/
|
||||
em { font-style: italic;
|
||||
font-weight: normal; }
|
||||
strong { font-weight: bold; }
|
||||
|
||||
span.textit { font-style: italic; }
|
||||
span.textbf { font-weight: bold; }
|
||||
|
||||
.small { font-size: 90%; }
|
||||
.white { color: #FFFFFF; }
|
||||
|
||||
|
||||
ul.toc {
|
||||
list-style: disc;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
a:link img, a:visited img { border-style: none; }
|
||||
a img { color: white; }
|
||||
|
||||
a {
|
||||
color: black;
|
||||
border-bottom: 1px solid black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:link, a:active, a:visited {
|
||||
/*color: #09550B;*/
|
||||
/*text-decoration: none;*/
|
||||
}
|
||||
|
||||
a:hover, a:focus {
|
||||
/*color: #FF9900; */
|
||||
border-bottom: 2px solid black;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* +-----------------------------------------------------------------+
|
||||
* | Doxygen Specific Classes |
|
||||
* +-----------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Header & Footer Classes (customized top page navigation bar).
|
||||
*/
|
||||
|
||||
h1.header {
|
||||
font-size: 200%;
|
||||
/*font-family: times, verdana, sans-serif;*/
|
||||
}
|
||||
|
||||
h2.memtitle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
center.header {
|
||||
background-color: #CCE6CA;
|
||||
}
|
||||
|
||||
table.header {
|
||||
/*width: 100%;*/
|
||||
/*background-color: #EEEEEE;*/
|
||||
background-color: #CCE6CA;
|
||||
}
|
||||
|
||||
div.header {
|
||||
text-align: center;
|
||||
margin: 14pt 0pt 0pt 0pt;
|
||||
}
|
||||
|
||||
div.summary {
|
||||
color: white;
|
||||
background-color: black;
|
||||
border: 4px solid black;
|
||||
}
|
||||
|
||||
div.summary a {
|
||||
font-size: 90%;
|
||||
color: white;
|
||||
padding: 2px 0px;
|
||||
text-align: center;
|
||||
background-color: black;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table.header td {
|
||||
padding: 2px 14px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
/*font-family: verdana, sans-serif;*/
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
table.UserDefined {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
table.UserDefined th {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
table.UserDefined td {
|
||||
padding: 0px 5px;
|
||||
}
|
||||
|
||||
table.DoxUser td, table.DoxUser th {
|
||||
padding: 0px 5px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
table.DoxUser th {
|
||||
background-color: #CCE6CA;
|
||||
}
|
||||
|
||||
table.footer1, table.footer2 { width: 100%; }
|
||||
td.LFooter { text-align: left; }
|
||||
td.RFooter { text-align: right; }
|
||||
td.CFooter { text-align: center;}
|
||||
table.footer2 td.RFooter { font-weight: bold; width: 35% }
|
||||
table.footer2 td.CFooter { width: 30% }
|
||||
table.footer2 td.LFooter { font-weight: bold; width: 35%; /*font-family: time;*/ }
|
||||
|
||||
table.classHierarchy {
|
||||
border-collapse: separate;
|
||||
border-spacing: 5px;
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
table.classHierarchy a {
|
||||
border-style: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table.classHierarchy tr {
|
||||
border: 1px solid blue;
|
||||
}
|
||||
|
||||
table.classHierarchy td.normal {
|
||||
border: 1px solid #dddddd;
|
||||
width: 140pt;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
background-color: #dddddd;
|
||||
}
|
||||
|
||||
table.classHierarchy td.virtual {
|
||||
border: 1px solid black;
|
||||
width: 140pt;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.classHierarchy td.wnormal {
|
||||
border: 1px solid #dddddd;
|
||||
width: 240pt;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
background-color: #dddddd;
|
||||
}
|
||||
|
||||
table.classHierarchy td.wvirtual {
|
||||
border: 1px solid black;
|
||||
width: 240pt;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.ah, span.ah {
|
||||
font-family: Times;
|
||||
font-size: 300%;
|
||||
font-weight: bold;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
div.title {
|
||||
text-align: center;
|
||||
font-size: 200%;
|
||||
font-weight: bold;
|
||||
padding: 20px;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
div.center, div.image {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Top navigation lists.
|
||||
*/
|
||||
|
||||
span.mlabels {
|
||||
font-size: 90%;
|
||||
font-style: italic;
|
||||
padding-left: 10pt;
|
||||
margin: 10pt;
|
||||
border-left: 1px solid black
|
||||
}
|
||||
|
||||
div.contents {
|
||||
padding-top: 20pt;
|
||||
}
|
||||
|
||||
div.tabs {
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
div.tabs, div.tabs1, div.tabs2, div.tabs3, div.tabs4 {
|
||||
border-left: 1px solid black;
|
||||
}
|
||||
|
||||
ul.tablist {
|
||||
/*
|
||||
padding: 5pt;
|
||||
background-color: red;
|
||||
*/
|
||||
margin: 0pt;
|
||||
padding: 0pt;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
ul.tablist li {
|
||||
/*
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
overflow: auto;
|
||||
display: inline;
|
||||
background-color: yellow;
|
||||
*/
|
||||
font-size: 90%;
|
||||
border-top: none;
|
||||
border-bottom: 1px solid black;
|
||||
border-left: none;
|
||||
border-right: 1px solid black;
|
||||
display: table-cell;
|
||||
text-align: center;
|
||||
padding: 2pt;
|
||||
width: 5%;
|
||||
}
|
||||
|
||||
ul.tablist li:hover {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
ul.tablist li:hover a {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
ul.tablist * a { border-bottom: none; }
|
||||
|
||||
ul.tablist * a:link img, ul.tablist * a:visited img { border-style: none; border-bottom: none; }
|
||||
|
||||
ul.tablist * a:link, ul.tablist * a:visited {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul.tablist * a:hover, ul.tablist * a:focus, ul.tablist * a:active {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.navpath {
|
||||
padding: 5pt 0pt 0pt 0pt;
|
||||
}
|
||||
|
||||
.navpath ul {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.navpath ul li {
|
||||
display: inline;
|
||||
list-style-type: none;
|
||||
padding-left: 20px;
|
||||
padding-right: 10px;
|
||||
background-image: url('closed.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: left;
|
||||
color: #364D7C;
|
||||
}
|
||||
|
||||
.navpath ul li a {
|
||||
border: 2px solid black;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Quick Index Class (top page navigation bar).
|
||||
*/
|
||||
|
||||
div.qindex, div.nav {
|
||||
width: 100%-4px;
|
||||
/*background-color: #DADAEF;*/
|
||||
/*background-color: #eeeeff;*/
|
||||
background-color: #cccccc;
|
||||
/*background-color: #CCE6CA;*/
|
||||
border: 0px solid #003300;
|
||||
text-align: center;
|
||||
margin: 0px;
|
||||
padding: 2px;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
a.qindex, a.qindex:visited, a.qindex:hover, a.qindexHL, a.el, a.elRef {
|
||||
text-decoration: none;
|
||||
/*font-family: Courier;*/
|
||||
font-weight: normal;
|
||||
/*font-size: 110%;*/
|
||||
}
|
||||
|
||||
a.qindex, a.qindex:visited {
|
||||
/*color: #09550B;*/
|
||||
color: black;
|
||||
border: 2px solid #cccccc;
|
||||
padding: 2px 2px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
a.qindex:hover {
|
||||
/*background-color: #ddddff;*/
|
||||
font-weight: bold;
|
||||
padding: 2px 2px;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
a.qindexHL, a.qindexHL:hover, a.qindexHL:visited {
|
||||
background-color: #0c780c;
|
||||
color: #ffffff;
|
||||
border: 1px double #9295C2;
|
||||
}
|
||||
|
||||
a.code:link, a.code:visited, a.codeRef:link, a.codeRef:visited {
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
color: #0000ff;
|
||||
}
|
||||
|
||||
.indexkey {
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 2px 15px;
|
||||
}
|
||||
|
||||
.indexkey, .indexvalue {
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 2px 15px;
|
||||
}
|
||||
|
||||
.indexkey {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.indexvalue {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
h3 a[name="index__"],
|
||||
h3 a[name="index_a"],
|
||||
h3 a[name="index_b"],
|
||||
h3 a[name="index_c"],
|
||||
h3 a[name="index_d"],
|
||||
h3 a[name="index_e"],
|
||||
h3 a[name="index_f"],
|
||||
h3 a[name="index_g"],
|
||||
h3 a[name="index_h"],
|
||||
h3 a[name="index_i"],
|
||||
h3 a[name="index_j"],
|
||||
h3 a[name="index_k"],
|
||||
h3 a[name="index_l"],
|
||||
h3 a[name="index_m"],
|
||||
h3 a[name="index_n"],
|
||||
h3 a[name="index_o"],
|
||||
h3 a[name="index_p"],
|
||||
h3 a[name="index_q"],
|
||||
h3 a[name="index_r"],
|
||||
h3 a[name="index_s"],
|
||||
h3 a[name="index_t"],
|
||||
h3 a[name="index_u"],
|
||||
h3 a[name="index_v"],
|
||||
h3 a[name="index_w"],
|
||||
h3 a[name="index_x"],
|
||||
h3 a[name="index_y"],
|
||||
h3 a[name="index_z"],
|
||||
h3 a[name="index_0"],
|
||||
h3 a[name="index_1"],
|
||||
h3 a[name="index_2"],
|
||||
h3 a[name="index_3"],
|
||||
h3 a[name="index_4"],
|
||||
h3 a[name="index_5"],
|
||||
h3 a[name="index_6"],
|
||||
h3 a[name="index_7"],
|
||||
h3 a[name="index_8"],
|
||||
h3 a[name="index_9"]
|
||||
h3 a[id="index__"],
|
||||
h3 a#index_a,
|
||||
h3 a#index_b,
|
||||
h3 a#index_c,
|
||||
h3 a#index_d,
|
||||
h3 a#index_e,
|
||||
h3 a#index_f,
|
||||
h3 a#index_g,
|
||||
h3 a#index_h,
|
||||
h3 a#index_i,
|
||||
h3 a#index_j,
|
||||
h3 a#index_k,
|
||||
h3 a#index_l,
|
||||
h3 a#index_m,
|
||||
h3 a#index_n,
|
||||
h3 a#index_o,
|
||||
h3 a#index_p,
|
||||
h3 a#index_q,
|
||||
h3 a#index_r,
|
||||
h3 a#index_s,
|
||||
h3 a#index_t,
|
||||
h3 a#index_u,
|
||||
h3 a#index_v,
|
||||
h3 a#index_w,
|
||||
h3 a#index_x,
|
||||
h3 a#index_y,
|
||||
h3 a#index_z,
|
||||
h3 a#index_0,
|
||||
h3 a#index_1,
|
||||
h3 a#index_2,
|
||||
h3 a#index_3,
|
||||
h3 a#index_4,
|
||||
h3 a#index_5,
|
||||
h3 a#index_6,
|
||||
h3 a#index_7,
|
||||
h3 a#index_8,
|
||||
h3 a#index_9,
|
||||
h3 a#index_0x7e
|
||||
{
|
||||
font-family: time;
|
||||
font-size: 250%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Verbatim Source Code / Examples.
|
||||
*/
|
||||
|
||||
div.fragment {
|
||||
font-family: "Roboto Mono", "Monospace";
|
||||
font-size: 80%;
|
||||
border: none;
|
||||
/*border-width: thin; */
|
||||
/*border-color: #003300;*/
|
||||
/*background-color: #FCFCE1;*/
|
||||
background-color: #fefefe;
|
||||
padding: 0.5em;
|
||||
margin-left: 5%;
|
||||
margin-right: 5%
|
||||
}
|
||||
|
||||
div.fragment a.code:link,
|
||||
div.fragment a.code:visited,
|
||||
div.fragment a.codeRef:link,
|
||||
div.fragment a.codeRef:visited {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.line {
|
||||
white-space: pre;
|
||||
padding: 0pt;
|
||||
margin: 0pt;
|
||||
}
|
||||
|
||||
span.keyword { color: #008000 }
|
||||
span.keywordtype { color: #604020 }
|
||||
span.keywordflow { color: #e08000 }
|
||||
span.comment { color: #800000 }
|
||||
span.preprocessor { color: #806020 }
|
||||
span.stringliteral { color: #002080 }
|
||||
span.charliteral { color: #008080 }
|
||||
span.red { color: red }
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Attributes Listing.
|
||||
*/
|
||||
|
||||
a.el, a.elRef {
|
||||
font-family: "Roboto Mono", Courier;
|
||||
font-weight: bold;
|
||||
font-size: 110%;
|
||||
color: black;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
p.formulaDsp {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mdTable {
|
||||
/*border: 1px solid #868686;*/
|
||||
/*background-color: #DADAEF;*/
|
||||
/*background-color: #F4F4FB;*/
|
||||
border: 1px none #008500;
|
||||
border-left-width: 1px;
|
||||
border-left-style: solid;
|
||||
/*background-color: #B8E6B8;*/
|
||||
/*background-color: #CCE6CA;*/
|
||||
margin-top: 25px;
|
||||
font-size: 105%;
|
||||
}
|
||||
|
||||
.mdRow {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
/* This Mozilla/Firefox bug has been corrected from v1.5.
|
||||
* .mdname1 {
|
||||
* padding: 3px 0px 0px 0px;
|
||||
* }
|
||||
*/
|
||||
|
||||
.mdescLeft, .mdescRight {
|
||||
padding: 0px 8px 4px 8px;
|
||||
font-size: 11px;
|
||||
font-style: italic;
|
||||
/*background-color: #FAFAFA;*/
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.memitem {
|
||||
margin-bottom: 30px;
|
||||
border: 1px none #008500;
|
||||
}
|
||||
|
||||
.memproto {
|
||||
/*background-color: #CCE6CA;*/
|
||||
background-color: #cccccc;
|
||||
border-left-width: 4px;
|
||||
border-left-style: solid;
|
||||
/*border-color: #008500;*/
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
.memname {
|
||||
white-space: nowrap;
|
||||
padding-left: 5px;
|
||||
font-size: 105%;
|
||||
}
|
||||
|
||||
table.memname * {
|
||||
font-family: "Roboto Mono", "Monospace";
|
||||
}
|
||||
|
||||
|
||||
.memdoc{
|
||||
padding-left: 5px;
|
||||
/*margin-top: -8px;*/
|
||||
border-left-width: 1px;
|
||||
border-left-style: solid;
|
||||
/*border-color: #008500;*/
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
div.contents * table tr {
|
||||
padding: 3px 3px 3px 8px;
|
||||
}
|
||||
|
||||
.memSeparator {
|
||||
font-size: 1pt;
|
||||
}
|
||||
|
||||
.memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight {
|
||||
vertical-align: top;
|
||||
/*padding: 1px 0px 0px 8px;*/
|
||||
padding: 3px 3px 3px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
/*
|
||||
border-top-color: #0c0c0c;
|
||||
border-right-color: #0c0c0c;
|
||||
border-bottom-color: #0c0c0c;
|
||||
border-left-color: #0c0c0c;
|
||||
*/
|
||||
border-top-style: none;
|
||||
border-right-style: none;
|
||||
/*
|
||||
border-bottom-style: dotted;
|
||||
*/
|
||||
border-left-style: none;
|
||||
/*background-color: #DADAEF;*/
|
||||
/*background-color: #eeeeff;*/
|
||||
/*background-color: #EEEEEE;*/
|
||||
/*background-color: #CCE6CA;*/
|
||||
font-family: "Roboto Mono", "Monospace";
|
||||
}
|
||||
|
||||
.memTemplItemLeft, .memTemplItemRight {
|
||||
border-bottom-width: 2px;
|
||||
border-bottom-style: solid;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.memItemLeft { font-size: 11px; width: 100pt; }
|
||||
.memItemRight { font-size: 12px; }
|
||||
.memTemplItemLeft { font-size: 11px; }
|
||||
.memTemplItemRight { font-size: 12px; }
|
||||
|
||||
.memTemplParams {
|
||||
color: #FFFFFF;
|
||||
background-color: #000000;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.groupText, .groupHeader {
|
||||
color: #09550B;
|
||||
font-size: 130%;
|
||||
font-weight: bold;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.groupHeader {
|
||||
margin-bottom: -30pt;
|
||||
}
|
||||
|
||||
.inherit {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* General Classes Index.
|
||||
*/
|
||||
|
||||
span.icona {
|
||||
margin-right: 10pt;
|
||||
}
|
||||
|
||||
div.toc li.level1 {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
div.toc li.level2 {
|
||||
margin-left: 15px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.toc li.level3 {
|
||||
margin-left: 30px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.toc li.level4 {
|
||||
margin-left: 45px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.directory .levels {
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
.directory .levels span {
|
||||
cursor: pointer;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
color: #3D578C;
|
||||
}
|
||||
|
||||
|
||||
div.directory {
|
||||
margin: 10px 0px;
|
||||
border-top: 2px solid black;
|
||||
border-bottom: 2px solid black;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.directory table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.directory td {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.directory td.entry {
|
||||
white-space: nowrap;
|
||||
padding-right: 6px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.directory td.entry a {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.directory td.entry a img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.directory td.desc {
|
||||
width: 100%;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
padding-top: 3px;
|
||||
border-left: 1px solid rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.directory tr.even {
|
||||
padding-left: 6px;
|
||||
background-color: #F7F8FB;
|
||||
}
|
||||
|
||||
.directory img {
|
||||
vertical-align: -30%;
|
||||
}
|
|
@ -1,798 +0,0 @@
|
|||
%%
|
||||
%% This is file `book.cls',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% classes.dtx (with options: `book')
|
||||
%%
|
||||
%% This is a generated file.
|
||||
%%
|
||||
%% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001
|
||||
%% The LaTeX3 Project and any individual authors listed elsewhere
|
||||
%% in this file.
|
||||
%%
|
||||
%% This file was generated from file(s) of the LaTeX base system.
|
||||
%% --------------------------------------------------------------
|
||||
%%
|
||||
%% It may be distributed and/or modified under the
|
||||
%% conditions of the LaTeX Project Public License, either version 1.2
|
||||
%% of this license or (at your option) any later version.
|
||||
%% The latest version of this license is in
|
||||
%% http://www.latex-project.org/lppl.txt
|
||||
%% and version 1.2 or later is part of all distributions of LaTeX
|
||||
%% version 1999/12/01 or later.
|
||||
%%
|
||||
%% This file may only be distributed together with a copy of the LaTeX
|
||||
%% base system. You may however distribute the LaTeX base system without
|
||||
%% such generated files.
|
||||
%%
|
||||
%% The list of all files belonging to the LaTeX base distribution is
|
||||
%% given in the file `manifest.txt'. See also `legal.txt' for additional
|
||||
%% information.
|
||||
%%
|
||||
%% \CharacterTable
|
||||
%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
|
||||
%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
|
||||
%% Digits \0\1\2\3\4\5\6\7\8\9
|
||||
%% Exclamation \! Double quote \" Hash (number) \#
|
||||
%% Dollar \$ Percent \% Ampersand \&
|
||||
%% Acute accent \' Left paren \( Right paren \)
|
||||
%% Asterisk \* Plus \+ Comma \,
|
||||
%% Minus \- Point \. Solidus \/
|
||||
%% Colon \: Semicolon \; Less than \<
|
||||
%% Equals \= Greater than \> Question mark \?
|
||||
%% Commercial at \@ Left bracket \[ Backslash \\
|
||||
%% Right bracket \] Circumflex \^ Underscore \_
|
||||
%% Grave accent \` Left brace \{ Vertical bar \|
|
||||
%% Right brace \} Tilde \~}
|
||||
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
|
||||
\ProvidesClass{asimbook}
|
||||
[2005/11/21 v1.0
|
||||
ASIM LaTeX document class]
|
||||
\newcommand\@ptsize{}
|
||||
\newif\if@restonecol
|
||||
\newif\if@titlepage
|
||||
\@titlepagetrue
|
||||
\newif\if@openright
|
||||
\newif\if@mainmatter \@mainmattertrue
|
||||
\if@compatibility\else
|
||||
\DeclareOption{a4paper}
|
||||
{\setlength\paperheight {297mm}%
|
||||
\setlength\paperwidth {210mm}}
|
||||
\DeclareOption{a5paper}
|
||||
{\setlength\paperheight {210mm}%
|
||||
\setlength\paperwidth {148mm}}
|
||||
\DeclareOption{b5paper}
|
||||
{\setlength\paperheight {250mm}%
|
||||
\setlength\paperwidth {176mm}}
|
||||
\DeclareOption{letterpaper}
|
||||
{\setlength\paperheight {11in}%
|
||||
\setlength\paperwidth {8.5in}}
|
||||
\DeclareOption{legalpaper}
|
||||
{\setlength\paperheight {14in}%
|
||||
\setlength\paperwidth {8.5in}}
|
||||
\DeclareOption{executivepaper}
|
||||
{\setlength\paperheight {10.5in}%
|
||||
\setlength\paperwidth {7.25in}}
|
||||
\DeclareOption{landscape}
|
||||
{\setlength\@tempdima {\paperheight}%
|
||||
\setlength\paperheight {\paperwidth}%
|
||||
\setlength\paperwidth {\@tempdima}}
|
||||
\fi
|
||||
\if@compatibility
|
||||
\renewcommand\@ptsize{0}
|
||||
\else
|
||||
\DeclareOption{10pt}{\renewcommand\@ptsize{0}}
|
||||
\fi
|
||||
\DeclareOption{11pt}{\renewcommand\@ptsize{1}}
|
||||
\DeclareOption{12pt}{\renewcommand\@ptsize{2}}
|
||||
\if@compatibility\else
|
||||
\DeclareOption{oneside}{\@twosidefalse \@mparswitchfalse}
|
||||
\fi
|
||||
\DeclareOption{twoside}{\@twosidetrue \@mparswitchtrue}
|
||||
\DeclareOption{draft}{\setlength\overfullrule{5pt}}
|
||||
\if@compatibility\else
|
||||
\DeclareOption{final}{\setlength\overfullrule{0pt}}
|
||||
\fi
|
||||
\DeclareOption{titlepage}{\@titlepagetrue}
|
||||
\if@compatibility\else
|
||||
\DeclareOption{notitlepage}{\@titlepagefalse}
|
||||
\fi
|
||||
\if@compatibility
|
||||
\@openrighttrue
|
||||
\else
|
||||
\DeclareOption{openright}{\@openrighttrue}
|
||||
\DeclareOption{openany}{\@openrightfalse}
|
||||
\fi
|
||||
\if@compatibility\else
|
||||
\DeclareOption{onecolumn}{\@twocolumnfalse}
|
||||
\fi
|
||||
\DeclareOption{twocolumn}{\@twocolumntrue}
|
||||
\DeclareOption{leqno}{\input{leqno.clo}}
|
||||
\DeclareOption{fleqn}{\input{fleqn.clo}}
|
||||
\DeclareOption{openbib}{%
|
||||
\AtEndOfPackage{%
|
||||
\renewcommand\@openbib@code{%
|
||||
\advance\leftmargin\bibindent
|
||||
\itemindent -\bibindent
|
||||
\listparindent \itemindent
|
||||
\parsep \z@
|
||||
}%
|
||||
\renewcommand\newblock{\par}}%
|
||||
}
|
||||
\ExecuteOptions{letterpaper,10pt,twoside,onecolumn,final,openright}
|
||||
\ProcessOptions
|
||||
\input{bk1\@ptsize.clo}
|
||||
\setlength\lineskip{1\p@}
|
||||
\setlength\normallineskip{1\p@}
|
||||
\renewcommand\baselinestretch{}
|
||||
\setlength\parskip{0\p@ \@plus \p@}
|
||||
\@lowpenalty 51
|
||||
\@medpenalty 151
|
||||
\@highpenalty 301
|
||||
\setcounter{topnumber}{2}
|
||||
\renewcommand\topfraction{.7}
|
||||
\setcounter{bottomnumber}{1}
|
||||
\renewcommand\bottomfraction{.3}
|
||||
\setcounter{totalnumber}{3}
|
||||
\renewcommand\textfraction{.2}
|
||||
\renewcommand\floatpagefraction{.5}
|
||||
\setcounter{dbltopnumber}{2}
|
||||
\renewcommand\dbltopfraction{.7}
|
||||
\renewcommand\dblfloatpagefraction{.5}
|
||||
%%%% Select Chapter font.
|
||||
\newcommand \textchapter [1] {\textsf{\textbf{#1}}}
|
||||
\newcommand \fontchapter {\sffamily \bfseries}
|
||||
\if@twoside
|
||||
\def\ps@headings{%
|
||||
\let\@oddfoot\@empty\let\@evenfoot\@empty
|
||||
\def\@evenhead{\thepage\hfil\slshape\leftmark}%
|
||||
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
|
||||
\let\@mkboth\markboth
|
||||
\def\chaptermark##1{%
|
||||
\markboth {\MakeUppercase{%
|
||||
\ifnum \c@secnumdepth >\m@ne
|
||||
\if@mainmatter
|
||||
\@chapapp\ \thechapter. \ %
|
||||
\fi
|
||||
\fi
|
||||
##1}}{}}%
|
||||
\def\sectionmark##1{%
|
||||
\markright {\MakeUppercase{%
|
||||
\ifnum \c@secnumdepth >\z@
|
||||
\thesection. \ %
|
||||
\fi
|
||||
##1}}}}
|
||||
\else
|
||||
\def\ps@headings{%
|
||||
\let\@oddfoot\@empty
|
||||
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
|
||||
\let\@mkboth\markboth
|
||||
\def\chaptermark##1{%
|
||||
\markright {\MakeUppercase{%
|
||||
\ifnum \c@secnumdepth >\m@ne
|
||||
\if@mainmatter
|
||||
\@chapapp\ \thechapter. \ %
|
||||
\fi
|
||||
\fi
|
||||
##1}}}}
|
||||
\fi
|
||||
\def\ps@myheadings{%
|
||||
\let\@oddfoot\@empty\let\@evenfoot\@empty
|
||||
\def\@evenhead{\thepage\hfil\slshape\leftmark}%
|
||||
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
|
||||
\let\@mkboth\@gobbletwo
|
||||
\let\chaptermark\@gobble
|
||||
\let\sectionmark\@gobble
|
||||
}
|
||||
\if@titlepage
|
||||
\newcommand\maketitle{\begin{titlepage}%
|
||||
\let\footnotesize\small
|
||||
\let\footnoterule\relax
|
||||
\let \footnote \thanks
|
||||
\null\vfil
|
||||
\vskip 60\p@
|
||||
\begin{center}%
|
||||
{\LARGE \@title \par}%
|
||||
\vskip 3em%
|
||||
{\large
|
||||
\lineskip .75em%
|
||||
\begin{tabular}[t]{c}%
|
||||
\@author
|
||||
\end{tabular}\par}%
|
||||
\vskip 1.5em%
|
||||
{\large \@date \par}% % Set date in \large size.
|
||||
\end{center}\par
|
||||
\@thanks
|
||||
\vfil\null
|
||||
\end{titlepage}%
|
||||
\setcounter{footnote}{0}%
|
||||
\global\let\thanks\relax
|
||||
\global\let\maketitle\relax
|
||||
\global\let\@thanks\@empty
|
||||
\global\let\@author\@empty
|
||||
\global\let\@date\@empty
|
||||
\global\let\@title\@empty
|
||||
\global\let\title\relax
|
||||
\global\let\author\relax
|
||||
\global\let\date\relax
|
||||
\global\let\and\relax
|
||||
}
|
||||
\else
|
||||
\newcommand\maketitle{\par
|
||||
\begingroup
|
||||
\renewcommand\thefootnote{\@fnsymbol\c@footnote}%
|
||||
\def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}%
|
||||
\long\def\@makefntext##1{\parindent 1em\noindent
|
||||
\hb@xt@1.8em{%
|
||||
\hss\@textsuperscript{\normalfont\@thefnmark}}##1}%
|
||||
\if@twocolumn
|
||||
\ifnum \col@number=\@ne
|
||||
\@maketitle
|
||||
\else
|
||||
\twocolumn[\@maketitle]%
|
||||
\fi
|
||||
\else
|
||||
\newpage
|
||||
\global\@topnum\z@ % Prevents figures from going at top of page.
|
||||
\@maketitle
|
||||
\fi
|
||||
\thispagestyle{plain}\@thanks
|
||||
\endgroup
|
||||
\setcounter{footnote}{0}%
|
||||
\global\let\thanks\relax
|
||||
\global\let\maketitle\relax
|
||||
\global\let\@maketitle\relax
|
||||
\global\let\@thanks\@empty
|
||||
\global\let\@author\@empty
|
||||
\global\let\@date\@empty
|
||||
\global\let\@title\@empty
|
||||
\global\let\title\relax
|
||||
\global\let\author\relax
|
||||
\global\let\date\relax
|
||||
\global\let\and\relax
|
||||
}
|
||||
\def\@maketitle{%
|
||||
\newpage
|
||||
\null
|
||||
\vskip 2em%
|
||||
\begin{center}%
|
||||
\let \footnote \thanks
|
||||
{\LARGE \@title \par}%
|
||||
\vskip 1.5em%
|
||||
{\large
|
||||
\lineskip .5em%
|
||||
\begin{tabular}[t]{c}%
|
||||
\@author
|
||||
\end{tabular}\par}%
|
||||
\vskip 1em%
|
||||
{\large \@date}%
|
||||
\end{center}%
|
||||
\par
|
||||
\vskip 1.5em}
|
||||
\fi
|
||||
\newcommand*\chaptermark[1]{}
|
||||
\setcounter{secnumdepth}{2}
|
||||
\newcounter {part}
|
||||
\newcounter {chapter}
|
||||
\newcounter {section}[chapter]
|
||||
\newcounter {subsection}[section]
|
||||
\newcounter {subsubsection}[subsection]
|
||||
\newcounter {paragraph}[subsubsection]
|
||||
\newcounter {subparagraph}[paragraph]
|
||||
\renewcommand \thepart {\@Roman\c@part}
|
||||
\renewcommand \thechapter {\@arabic\c@chapter}
|
||||
\renewcommand \thesection {\thechapter.\@arabic\c@section}
|
||||
\renewcommand\thesubsection {\thesection.\@arabic\c@subsection}
|
||||
\renewcommand\thesubsubsection{\thesubsection .\@arabic\c@subsubsection}
|
||||
\renewcommand\theparagraph {\thesubsubsection.\@arabic\c@paragraph}
|
||||
\renewcommand\thesubparagraph {\theparagraph.\@arabic\c@subparagraph}
|
||||
\newcommand\@chapapp{\chaptername}
|
||||
\newcommand\frontmatter{%
|
||||
\cleardoublepage
|
||||
\@mainmatterfalse
|
||||
\pagenumbering{roman}}
|
||||
\newcommand\mainmatter{%
|
||||
\cleardoublepage
|
||||
\@mainmattertrue
|
||||
\pagenumbering{arabic}}
|
||||
\newcommand\backmatter{%
|
||||
\if@openright
|
||||
\cleardoublepage
|
||||
\else
|
||||
\clearpage
|
||||
\fi
|
||||
\@mainmatterfalse}
|
||||
\newcommand\part{%
|
||||
\if@openright
|
||||
\cleardoublepage
|
||||
\else
|
||||
\clearpage
|
||||
\fi
|
||||
\thispagestyle{plain}%
|
||||
\if@twocolumn
|
||||
\onecolumn
|
||||
\@tempswatrue
|
||||
\else
|
||||
\@tempswafalse
|
||||
\fi
|
||||
\null\vfil
|
||||
\secdef\@part\@spart}
|
||||
|
||||
\def\@part[#1]#2{%
|
||||
\ifnum \c@secnumdepth >-2\relax
|
||||
\refstepcounter{part}%
|
||||
\addcontentsline{toc}{part}{\thepart\hspace{1em}#1}%
|
||||
\else
|
||||
\addcontentsline{toc}{part}{#1}%
|
||||
\fi
|
||||
\markboth{}{}%
|
||||
{\centering
|
||||
\interlinepenalty \@M
|
||||
\normalfont
|
||||
\ifnum \c@secnumdepth >-2\relax
|
||||
\huge\bfseries \partname\nobreakspace\thepart
|
||||
\par
|
||||
\vskip 20\p@
|
||||
\fi
|
||||
\Huge \bfseries #2\par}%
|
||||
\@endpart}
|
||||
\def\@spart#1{%
|
||||
{\centering
|
||||
\interlinepenalty \@M
|
||||
\normalfont
|
||||
\Huge \bfseries #1\par}%
|
||||
\@endpart}
|
||||
\def\@endpart{\vfil\newpage
|
||||
\if@twoside
|
||||
\if@openright
|
||||
\null
|
||||
\thispagestyle{empty}%
|
||||
\newpage
|
||||
\fi
|
||||
\fi
|
||||
\if@tempswa
|
||||
\twocolumn
|
||||
\fi}
|
||||
\newcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi
|
||||
\thispagestyle{plain}%
|
||||
\global\@topnum\z@
|
||||
\@afterindentfalse
|
||||
\secdef\@chapter\@schapter}
|
||||
\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
|
||||
\if@mainmatter
|
||||
\refstepcounter{chapter}%
|
||||
\typeout{\@chapapp\space\thechapter.}%
|
||||
\addcontentsline{toc}{chapter}%
|
||||
{\protect\numberline{\thechapter}#1}%
|
||||
\else
|
||||
\addcontentsline{toc}{chapter}{#1}%
|
||||
\fi
|
||||
\else
|
||||
\addcontentsline{toc}{chapter}{#1}%
|
||||
\fi
|
||||
\chaptermark{#1}%
|
||||
\addtocontents{lof}{\protect\addvspace{10\p@}}%
|
||||
\addtocontents{lot}{\protect\addvspace{10\p@}}%
|
||||
\if@twocolumn
|
||||
\@topnewpage[\@makechapterhead{#2}]%
|
||||
\else
|
||||
\@makechapterhead{#2}%
|
||||
\@afterheading
|
||||
\fi}
|
||||
%%%%\def\@makechapterhead#1{%
|
||||
%%%% \vspace*{50\p@}%
|
||||
%%%% {\parindent \z@ \raggedright \normalfont
|
||||
%%%% \ifnum \c@secnumdepth >\m@ne
|
||||
%%%% \if@mainmatter
|
||||
%%%% \huge\bfseries \@chapapp\space \thechapter
|
||||
%%%% \par\nobreak
|
||||
%%%% \vskip 20\p@
|
||||
%%%% \fi
|
||||
%%%% \fi
|
||||
%%%% \interlinepenalty\@M
|
||||
%%%% \Huge \bfseries #1\par\nobreak
|
||||
%%%% \vskip 40\p@
|
||||
%%%% }}
|
||||
\newlength \titlewidth
|
||||
\setlength \titlewidth {\textwidth}
|
||||
\addtolength \titlewidth {\marginparwidth}
|
||||
\addtolength \titlewidth {\marginparsep}
|
||||
\def\@makechapterhead#1{%
|
||||
\vspace*{50\p@}%
|
||||
{\parindent \z@ \raggedleft \fontchapter
|
||||
\ifnum \c@secnumdepth >\m@ne
|
||||
\if@mainmatter
|
||||
\huge \@chapapp\space \thechapter
|
||||
\par\nobreak
|
||||
\vskip 20\p@
|
||||
\fi
|
||||
\fi
|
||||
\interlinepenalty\@M
|
||||
\hsize=\titlewidth
|
||||
\Huge #1 \par\nobreak
|
||||
\hsize=\textwidth
|
||||
\vskip 40\p@
|
||||
}}
|
||||
\def\@schapter#1{\if@twocolumn
|
||||
\@topnewpage[\@makeschapterhead{#1}]%
|
||||
\else
|
||||
\@makeschapterhead{#1}%
|
||||
\@afterheading
|
||||
\fi}
|
||||
%%%%\def\@makeschapterhead#1{%
|
||||
%%%% \vspace*{50\p@}%
|
||||
%%%% {\parindent \z@ \raggedright
|
||||
%%%% \normalfont
|
||||
%%%% \interlinepenalty\@M
|
||||
%%%% \Huge \bfseries #1\par\nobreak
|
||||
%%%% \vskip 40\p@
|
||||
%%%% }}
|
||||
\def\@makeschapterhead#1{%
|
||||
\vspace*{50\p@}%
|
||||
{\parindent \z@ \raggedright
|
||||
\normalfont
|
||||
\interlinepenalty\@M
|
||||
\hsize=\titlewidth
|
||||
\flushright
|
||||
\Huge \bfseries #1\par\nobreak
|
||||
\hsize=\textwidth
|
||||
\vskip 40\p@
|
||||
}}
|
||||
\newcommand\section{\@startsection {section}{1}{\z@}%
|
||||
{-3.5ex \@plus -1ex \@minus -.2ex}%
|
||||
{2.3ex \@plus.2ex}%
|
||||
{\normalfont\Large\bfseries}}
|
||||
\newcommand\subsection{\@startsection{subsection}{2}{\z@}%
|
||||
{-3.25ex\@plus -1ex \@minus -.2ex}%
|
||||
{1.5ex \@plus .2ex}%
|
||||
{\normalfont\large\bfseries}}
|
||||
\newcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}%
|
||||
{-3.25ex\@plus -1ex \@minus -.2ex}%
|
||||
{1.5ex \@plus .2ex}%
|
||||
{\normalfont\normalsize\bfseries}}
|
||||
\newcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
|
||||
{3.25ex \@plus1ex \@minus.2ex}%
|
||||
{-1em}%
|
||||
{\normalfont\normalsize\bfseries}}
|
||||
\newcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}%
|
||||
{3.25ex \@plus1ex \@minus .2ex}%
|
||||
{-1em}%
|
||||
{\normalfont\normalsize\bfseries}}
|
||||
\if@twocolumn
|
||||
\setlength\leftmargini {2em}
|
||||
\else
|
||||
\setlength\leftmargini {2.5em}
|
||||
\fi
|
||||
\leftmargin \leftmargini
|
||||
\setlength\leftmarginii {2.2em}
|
||||
\setlength\leftmarginiii {1.87em}
|
||||
\setlength\leftmarginiv {1.7em}
|
||||
\if@twocolumn
|
||||
\setlength\leftmarginv {.5em}
|
||||
\setlength\leftmarginvi {.5em}
|
||||
\else
|
||||
\setlength\leftmarginv {1em}
|
||||
\setlength\leftmarginvi {1em}
|
||||
\fi
|
||||
\setlength \labelsep {.5em}
|
||||
\setlength \labelwidth{\leftmargini}
|
||||
\addtolength\labelwidth{-\labelsep}
|
||||
\@beginparpenalty -\@lowpenalty
|
||||
\@endparpenalty -\@lowpenalty
|
||||
\@itempenalty -\@lowpenalty
|
||||
\renewcommand\theenumi{\@arabic\c@enumi}
|
||||
\renewcommand\theenumii{\@alph\c@enumii}
|
||||
\renewcommand\theenumiii{\@roman\c@enumiii}
|
||||
\renewcommand\theenumiv{\@Alph\c@enumiv}
|
||||
\newcommand\labelenumi{\theenumi.}
|
||||
\newcommand\labelenumii{(\theenumii)}
|
||||
\newcommand\labelenumiii{\theenumiii.}
|
||||
\newcommand\labelenumiv{\theenumiv.}
|
||||
\renewcommand\p@enumii{\theenumi}
|
||||
\renewcommand\p@enumiii{\theenumi(\theenumii)}
|
||||
\renewcommand\p@enumiv{\p@enumiii\theenumiii}
|
||||
\newcommand\labelitemi{\textbullet}
|
||||
\newcommand\labelitemii{\normalfont\bfseries \textendash}
|
||||
\newcommand\labelitemiii{\textasteriskcentered}
|
||||
\newcommand\labelitemiv{\textperiodcentered}
|
||||
\newenvironment{description}
|
||||
{\list{}{\labelwidth\z@ \itemindent-\leftmargin
|
||||
\let\makelabel\descriptionlabel}}
|
||||
{\endlist}
|
||||
\newcommand*\descriptionlabel[1]{\hspace\labelsep
|
||||
\normalfont\bfseries #1}
|
||||
\newenvironment{verse}
|
||||
{\let\\\@centercr
|
||||
\list{}{\itemsep \z@
|
||||
\itemindent -1.5em%
|
||||
\listparindent\itemindent
|
||||
\rightmargin \leftmargin
|
||||
\advance\leftmargin 1.5em}%
|
||||
\item\relax}
|
||||
{\endlist}
|
||||
\newenvironment{quotation}
|
||||
{\list{}{\listparindent 1.5em%
|
||||
\itemindent \listparindent
|
||||
\rightmargin \leftmargin
|
||||
\parsep \z@ \@plus\p@}%
|
||||
\item\relax}
|
||||
{\endlist}
|
||||
\newenvironment{quote}
|
||||
{\list{}{\rightmargin\leftmargin}%
|
||||
\item\relax}
|
||||
{\endlist}
|
||||
\if@compatibility
|
||||
\newenvironment{titlepage}
|
||||
{%
|
||||
\cleardoublepage
|
||||
\if@twocolumn
|
||||
\@restonecoltrue\onecolumn
|
||||
\else
|
||||
\@restonecolfalse\newpage
|
||||
\fi
|
||||
\thispagestyle{empty}%
|
||||
\setcounter{page}\z@
|
||||
}%
|
||||
{\if@restonecol\twocolumn \else \newpage \fi
|
||||
}
|
||||
\else
|
||||
\newenvironment{titlepage}
|
||||
{%
|
||||
\cleardoublepage
|
||||
\if@twocolumn
|
||||
\@restonecoltrue\onecolumn
|
||||
\else
|
||||
\@restonecolfalse\newpage
|
||||
\fi
|
||||
\thispagestyle{empty}%
|
||||
\setcounter{page}\@ne
|
||||
}%
|
||||
{\if@restonecol\twocolumn \else \newpage \fi
|
||||
\if@twoside\else
|
||||
\setcounter{page}\@ne
|
||||
\fi
|
||||
}
|
||||
\fi
|
||||
\newcommand\appendix{\par
|
||||
\setcounter{chapter}{0}%
|
||||
\setcounter{section}{0}%
|
||||
\gdef\@chapapp{\appendixname}%
|
||||
\gdef\thechapter{\@Alph\c@chapter}}
|
||||
\setlength\arraycolsep{5\p@}
|
||||
\setlength\tabcolsep{6\p@}
|
||||
\setlength\arrayrulewidth{.4\p@}
|
||||
\setlength\doublerulesep{2\p@}
|
||||
\setlength\tabbingsep{\labelsep}
|
||||
\skip\@mpfootins = \skip\footins
|
||||
\setlength\fboxsep{3\p@}
|
||||
\setlength\fboxrule{.4\p@}
|
||||
\@addtoreset {equation}{chapter}
|
||||
\renewcommand\theequation
|
||||
{\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@equation}
|
||||
\newcounter{figure}[chapter]
|
||||
\renewcommand \thefigure
|
||||
{\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@figure}
|
||||
\def\fps@figure{tbp}
|
||||
\def\ftype@figure{1}
|
||||
\def\ext@figure{lof}
|
||||
\def\fnum@figure{\figurename\nobreakspace\thefigure}
|
||||
\newenvironment{figure}
|
||||
{\@float{figure}}
|
||||
{\end@float}
|
||||
\newenvironment{figure*}
|
||||
{\@dblfloat{figure}}
|
||||
{\end@dblfloat}
|
||||
\newcounter{table}[chapter]
|
||||
\renewcommand \thetable
|
||||
{\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@table}
|
||||
\def\fps@table{tbp}
|
||||
\def\ftype@table{2}
|
||||
\def\ext@table{lot}
|
||||
\def\fnum@table{\tablename\nobreakspace\thetable}
|
||||
\newenvironment{table}
|
||||
{\@float{table}}
|
||||
{\end@float}
|
||||
\newenvironment{table*}
|
||||
{\@dblfloat{table}}
|
||||
{\end@dblfloat}
|
||||
\newlength\abovecaptionskip
|
||||
\newlength\belowcaptionskip
|
||||
\setlength\abovecaptionskip{10\p@}
|
||||
\setlength\belowcaptionskip{0\p@}
|
||||
\long\def\@makecaption#1#2{%
|
||||
\vskip\abovecaptionskip
|
||||
\sbox\@tempboxa{#1: #2}%
|
||||
\ifdim \wd\@tempboxa >\hsize
|
||||
#1: #2\par
|
||||
\else
|
||||
\global \@minipagefalse
|
||||
\hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
|
||||
\fi
|
||||
\vskip\belowcaptionskip}
|
||||
\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm}
|
||||
\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
|
||||
\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt}
|
||||
\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf}
|
||||
\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit}
|
||||
\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl}
|
||||
\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc}
|
||||
\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal}
|
||||
\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal}
|
||||
\newcommand\@pnumwidth{1.55em}
|
||||
\newcommand\@tocrmarg{2.55em}
|
||||
\newcommand\@dotsep{4.5}
|
||||
\setcounter{tocdepth}{2}
|
||||
\newcommand\tableofcontents{%
|
||||
\if@twocolumn
|
||||
\@restonecoltrue\onecolumn
|
||||
\else
|
||||
\@restonecolfalse
|
||||
\fi
|
||||
\chapter*{\contentsname
|
||||
\@mkboth{%
|
||||
\MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
|
||||
\@starttoc{toc}%
|
||||
\if@restonecol\twocolumn\fi
|
||||
}
|
||||
\newcommand*\l@part[2]{%
|
||||
\ifnum \c@tocdepth >-2\relax
|
||||
\addpenalty{-\@highpenalty}%
|
||||
\addvspace{2.25em \@plus\p@}%
|
||||
\setlength\@tempdima{3em}%
|
||||
\begingroup
|
||||
\parindent \z@ \rightskip \@pnumwidth
|
||||
\parfillskip -\@pnumwidth
|
||||
{\leavevmode
|
||||
\large \bfseries #1\hfil \hb@xt@\@pnumwidth{\hss #2}}\par
|
||||
\nobreak
|
||||
\global\@nobreaktrue
|
||||
\everypar{\global\@nobreakfalse\everypar{}}%
|
||||
\endgroup
|
||||
\fi}
|
||||
%%%%\newcommand*\l@chapter[2]{%
|
||||
%%%% \ifnum \c@tocdepth >\m@ne
|
||||
%%%% \addpenalty{-\@highpenalty}%
|
||||
%%%% \vskip 1.0em \@plus\p@
|
||||
%%%% \setlength\@tempdima{1.5em}%
|
||||
%%%% \begingroup
|
||||
%%%% \parindent \z@ \rightskip \@pnumwidth
|
||||
%%%% \parfillskip -\@pnumwidth
|
||||
%%%% \leavevmode \bfseries
|
||||
%%%% \advance\leftskip\@tempdima
|
||||
%%%% \hskip -\leftskip
|
||||
%%%% #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
|
||||
%%%% \penalty\@highpenalty
|
||||
%%%% \endgroup
|
||||
%%%% \fi}
|
||||
\newcommand\l@chapter[2]{%
|
||||
\ifnum \c@tocdepth >\m@ne
|
||||
\addpenalty{-\@highpenalty}%
|
||||
\vskip 1.0em \@plus\p@
|
||||
\setlength\@tempdima{1.5em}%
|
||||
\begingroup
|
||||
\parindent \z@ \rightskip \@pnumwidth
|
||||
\parfillskip -\@pnumwidth
|
||||
\leavevmode \fontchapter
|
||||
\advance\leftskip\@tempdima
|
||||
\hskip -\leftskip
|
||||
#1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
|
||||
\penalty\@highpenalty
|
||||
\endgroup
|
||||
\fi}
|
||||
\newcommand*\l@section{\@dottedtocline{1}{1.5em}{2.3em}}
|
||||
\newcommand*\l@subsection{\@dottedtocline{2}{3.8em}{3.2em}}
|
||||
\newcommand*\l@subsubsection{\@dottedtocline{3}{7.0em}{4.1em}}
|
||||
\newcommand*\l@paragraph{\@dottedtocline{4}{10em}{5em}}
|
||||
\newcommand*\l@subparagraph{\@dottedtocline{5}{12em}{6em}}
|
||||
\newcommand\listoffigures{%
|
||||
\if@twocolumn
|
||||
\@restonecoltrue\onecolumn
|
||||
\else
|
||||
\@restonecolfalse
|
||||
\fi
|
||||
\chapter*{\listfigurename}%
|
||||
\@mkboth{\MakeUppercase\listfigurename}%
|
||||
{\MakeUppercase\listfigurename}%
|
||||
\@starttoc{lof}%
|
||||
\if@restonecol\twocolumn\fi
|
||||
}
|
||||
\newcommand*\l@figure{\@dottedtocline{1}{1.5em}{2.3em}}
|
||||
\newcommand\listoftables{%
|
||||
\if@twocolumn
|
||||
\@restonecoltrue\onecolumn
|
||||
\else
|
||||
\@restonecolfalse
|
||||
\fi
|
||||
\chapter*{\listtablename}%
|
||||
\@mkboth{%
|
||||
\MakeUppercase\listtablename}%
|
||||
{\MakeUppercase\listtablename}%
|
||||
\@starttoc{lot}%
|
||||
\if@restonecol\twocolumn\fi
|
||||
}
|
||||
\let\l@table\l@figure
|
||||
\newdimen\bibindent
|
||||
\setlength\bibindent{1.5em}
|
||||
\newenvironment{thebibliography}[1]
|
||||
{\chapter*{\bibname}%
|
||||
\@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}%
|
||||
\list{\@biblabel{\@arabic\c@enumiv}}%
|
||||
{\settowidth\labelwidth{\@biblabel{#1}}%
|
||||
\leftmargin\labelwidth
|
||||
\advance\leftmargin\labelsep
|
||||
\@openbib@code
|
||||
\usecounter{enumiv}%
|
||||
\let\p@enumiv\@empty
|
||||
\renewcommand\theenumiv{\@arabic\c@enumiv}}%
|
||||
\sloppy
|
||||
\clubpenalty4000
|
||||
\@clubpenalty \clubpenalty
|
||||
\widowpenalty4000%
|
||||
\sfcode`\.\@m}
|
||||
{\def\@noitemerr
|
||||
{\@latex@warning{Empty `thebibliography' environment}}%
|
||||
\endlist}
|
||||
\newcommand\newblock{\hskip .11em\@plus.33em\@minus.07em}
|
||||
\let\@openbib@code\@empty
|
||||
\newenvironment{theindex}
|
||||
{\if@twocolumn
|
||||
\@restonecolfalse
|
||||
\else
|
||||
\@restonecoltrue
|
||||
\fi
|
||||
\columnseprule \z@
|
||||
\columnsep 35\p@
|
||||
\twocolumn[\@makeschapterhead{\indexname}]%
|
||||
\@mkboth{\MakeUppercase\indexname}%
|
||||
{\MakeUppercase\indexname}%
|
||||
\thispagestyle{plain}\parindent\z@
|
||||
\parskip\z@ \@plus .3\p@\relax
|
||||
\let\item\@idxitem}
|
||||
{\if@restonecol\onecolumn\else\clearpage\fi}
|
||||
\newcommand\@idxitem{\par\hangindent 40\p@}
|
||||
\newcommand\subitem{\@idxitem \hspace*{20\p@}}
|
||||
\newcommand\subsubitem{\@idxitem \hspace*{30\p@}}
|
||||
\newcommand\indexspace{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax}
|
||||
\renewcommand\footnoterule{%
|
||||
\kern-3\p@
|
||||
\hrule\@width.4\columnwidth
|
||||
\kern2.6\p@}
|
||||
\@addtoreset{footnote}{chapter}
|
||||
\newcommand\@makefntext[1]{%
|
||||
\parindent 1em%
|
||||
\noindent
|
||||
\hb@xt@1.8em{\hss\@makefnmark}#1}
|
||||
\newcommand\contentsname{Contents}
|
||||
\newcommand\listfigurename{List of Figures}
|
||||
\newcommand\listtablename{List of Tables}
|
||||
\newcommand\bibname{Bibliography}
|
||||
\newcommand\indexname{Index}
|
||||
\newcommand\figurename{Figure}
|
||||
\newcommand\tablename{Table}
|
||||
\newcommand\partname{Part}
|
||||
\newcommand\chaptername{Chapter}
|
||||
\newcommand\appendixname{Appendix}
|
||||
\def\today{\ifcase\month\or
|
||||
January\or February\or March\or April\or May\or June\or
|
||||
July\or August\or September\or October\or November\or December\fi
|
||||
\space\number\day, \number\year}
|
||||
\setlength\columnsep{10\p@}
|
||||
\setlength\columnseprule{0\p@}
|
||||
\pagestyle{headings}
|
||||
\pagenumbering{arabic}
|
||||
\if@twoside
|
||||
\else
|
||||
\raggedbottom
|
||||
\fi
|
||||
\if@twocolumn
|
||||
\twocolumn
|
||||
\sloppy
|
||||
\flushbottom
|
||||
\else
|
||||
\onecolumn
|
||||
\fi
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `book.cls'.
|
Before Width: | Height: | Size: 125 B |
|
@ -1,65 +0,0 @@
|
|||
<br>
|
||||
<p><b>The complete class hierarchy could be accessed <a href="hierarchy.html">here</a>.</b></p>
|
||||
<p>All the classes below are in the <a href="namespaceKatabatic.html">Katabatic</a> namespace.</p>
|
||||
<p>The inheritance tree has been splitted/simplificated.</p>
|
||||
<b>Legend :</b><br>
|
||||
<pre class="fragment">
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="70"><td class="virtual"><a href="#pagetop">ClassA</a><td><b> <tt>ClassA</tt> is abstract</b></tr>
|
||||
<tr><td width="70"><td class="normal"><a href="#pagetop">ClassB</a><td><b> <tt>ClassB</tt> is instanciable</b></tr>
|
||||
</table>
|
||||
</pre>
|
||||
<br>
|
||||
|
||||
<h2 class="classHierarchy">Utilities</h2>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="70"><td class="virtual"><a href="classKatabatic_1_1BaseObserver.html">BaseObserver</a>
|
||||
</table>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="140"><td class="normal"><a href="classKatabatic_1_1Observer.html">Observer</a>
|
||||
</table>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="70"><td class="normal"><a href="classKatabatic_1_1Observable.html">Observable</a>
|
||||
</table>
|
||||
|
||||
<h2 class="classHierarchy">Katabatic Engine</h2>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="70"><td class="normal"><a href="namespaceKatabatic.html">Katabatic</a>
|
||||
<tr><td width="70"><td class="normal"><a href="classKatabatic_1_1ChipTools.html">ChipTools</a>
|
||||
<tr><td width="70"><td class="normal"><a href="classKatabatic_1_1KatabaticEngine.html">KatabaticEngine</a>
|
||||
<tr><td width="70"><td class="normal"><a href="classKatabatic_1_1Session.html">Session</a>
|
||||
<tr><td width="70"><td class="normal"><a href="classKatabatic_1_1DataAlgorithm.html">DataAlgorithm</a>
|
||||
</table>
|
||||
|
||||
<h2 class="classHierarchy">Contacts</h2>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="70"><td class="virtual"><a href="classKatabatic_1_1AutoContact.html">AutoContact</a>
|
||||
</table>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="140"><td class="normal"><a href="classKatabatic_1_1AutoContactTerminal.html">AutoContactTerminal</a>
|
||||
<tr><td width="140"><td class="normal"><a href="classKatabatic_1_1AutoContactTurn.html">AutoContactTurn</a>
|
||||
<tr><td width="140"><td class="normal"><a href="classKatabatic_1_1AutoContactHTee.html">AutoContactHTee</a>
|
||||
<tr><td width="140"><td class="normal"><a href="classKatabatic_1_1AutoContactVTee.html">AutoContactVTee</a>
|
||||
</table>
|
||||
|
||||
<h2 class="classHierarchy">Segments</h2>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="70"><td class="virtual"><a href="classKatabatic_1_1AutoSegment.html">AutoSegment</a>
|
||||
</table>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="140"><td class="normal"><a href="classKatabatic_1_1AutoHorizontal.html">AutoHorizontal</a>
|
||||
<tr><td width="140"><td class="normal"><a href="classKatabatic_1_1AutoVertical.html">AutoVertical</a>
|
||||
</table>
|
||||
|
||||
<h2 class="classHierarchy">GCell</h2>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="70"><td class="normal"><a href="classKatabatic_1_1GCell.html">GCell</a>
|
||||
<tr><td width="70"><td class="normal"><a href="classKatabatic_1_1BaseGrid_1_1Axis.html">BaseGrid::Axis</a>
|
||||
<tr><td width="70"><td class="virtual"><a href="classKatabatic_1_1BaseGrid.html">BaseGrid</a>
|
||||
</table>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="140"><td class="virtual"><a href="classKatabatic_1_1Grid.html">Grid</a>
|
||||
</table>
|
||||
<table class="classHierarchy">
|
||||
<tr><td width="210"><td class="normal"><a href="classKatabatic_1_1GCellGrid.html">GCellGrid</a>
|
||||
</table>
|
|
@ -1,81 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
|
||||
<!-- $Id: customSummary.html,v 1.1 2007/09/15 13:10:13 jpc Exp $ -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||
<title>Katabatic Documentation</title>
|
||||
<link href="SoC.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<h1 class="header">Katabatic Documentation</h1>
|
||||
<center class="header">
|
||||
<table class="header">
|
||||
<tr>
|
||||
<td><a href="customSummary.html">Summary</a></td>
|
||||
<td><a href="namespaces.html">Namespaces</a></td>
|
||||
<td><a href="customHierarchy.html">Class Hierarchy</a></td>
|
||||
<td><a href="annotated.html">Classes</a></td>
|
||||
<td><a href="functions.html">Member Index</a></td>
|
||||
<!-- <td><a href="classes.html">Index2</a></td> -->
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
<br>
|
||||
<hr>
|
||||
<body>
|
||||
|
||||
|
||||
<h1>Katabatic Documentation Summary</h1>
|
||||
<br>
|
||||
<p><b>The classical Doxygen module documentation could be accessed <a href="modules.html">here</a>.</b></p>
|
||||
|
||||
<!--
|
||||
<h2>Katabatic Concepts (internal)</h2>
|
||||
<ol>
|
||||
<li><a class="el" href="group__buildRules.html">Rules for building wires.</a>
|
||||
<br>Rules for building AutoContacts. Global/Locals AutoSegments.
|
||||
<li><a class="el" href="group__loadGlobalRouting.html">Global Routing Loading.</a>
|
||||
<br>How the Knik global routing is loaded into Katabatic data-base.
|
||||
Details the wiring topologies used to complete the routing to the
|
||||
terminals.
|
||||
<li><a class="el" href="group__collapseCanonical.html">AutoSegment Collapse & Canonical.</a>
|
||||
<br>How to force alignment of AutoSegments.
|
||||
<li><a class="el" href="group__layerAssign.html">Layer Assignment.</a>
|
||||
<br>Simple strategy to put long wires on higher routing metals.
|
||||
<li><a class="el" href="group__NetConstraints.html">Constraints Computations.</a>
|
||||
<br>Compute the legal range of variation of each wire (note that the
|
||||
constraints are stored on AutoContacts).
|
||||
<li><a class="el" href="group__NetOptimals.html">AutoSegment Optimal Placement.</a>
|
||||
<br>Compute the optimal range of variation of each wire.
|
||||
<li><a class="el" href="group__katabaticSession.html">Katabatic Update Session Mechanism.</a>
|
||||
<br>The Session mechanism for modifying the Katabatic data-base.
|
||||
</ol>
|
||||
-->
|
||||
|
||||
<h2>API documentations</h2>
|
||||
<ul>
|
||||
<li><b><a href="customHierarchy.html">Synthetic Class Hierarchy.</a></b>
|
||||
<li><b><a href="hierarchy.html">Complete Class Hierarchy (doxygen).</a></b>
|
||||
<li><b><a href="annotated.html">Class List (doxygen).</a></b>
|
||||
<li><b><a href="classes.html">Class Index (doxygen).</a></b>
|
||||
<li><b><a href="modules.html">Modules (raw concepts).</a></b>
|
||||
<li><b><a href="functions.html">Member Functions Index (doxygen).</a></b>
|
||||
<li><b><a href="namespaces.html">Namespaces (doxygen).</a></b>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
|
||||
<hr>
|
||||
<table class="footer1">
|
||||
<tr>
|
||||
<td class="LFooter"><small>Customized Concepts (a.k.a. modules)</small></td>
|
||||
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="footer2">
|
||||
<tr>
|
||||
<td class="LFooter">Katabatic Documentation</td>
|
||||
<td class="RFooter"><small>Copyright © 2005-2007 LIP6. All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -1,290 +0,0 @@
|
|||
# -*- explicit-buffer-name: "doxyfile<katabatic/doc>" -*-
|
||||
# Doxyfile 1.3.4
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
|
||||
PROJECT_NAME = "Katabatic - Routing Toolbox"
|
||||
PROJECT_NUMBER = 1.0
|
||||
OUTPUT_DIRECTORY = .
|
||||
OUTPUT_LANGUAGE = English
|
||||
MARKDOWN_SUPPORT = NO
|
||||
#USE_WINDOWS_ENCODING = NO
|
||||
#LAYOUT_FILE = DoxygenLayout.xml
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
#DETAILS_AT_TOP = YES
|
||||
INHERIT_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 2
|
||||
ALIASES = "function=\fn"\
|
||||
"important=\par Important:\n"\
|
||||
"remark=\par Remark:\n"\
|
||||
"sreturn=\b Returns:"\
|
||||
"True=\b True"\
|
||||
"true=\b true"\
|
||||
"False=\b False"\
|
||||
"false=\b false"\
|
||||
"VERTICAL=\b VERTICAL"\
|
||||
"HORIZONTAL=\b HORIZONTAL"\
|
||||
"NULL=\c NULL"\
|
||||
"vector=\c vector"\
|
||||
"Collection=\c Collection"\
|
||||
"Collections=\c Collections"\
|
||||
"Box=\c Box"\
|
||||
"box=\c box"\
|
||||
"Layer=\c Layer"\
|
||||
"Layers=\c Layers"\
|
||||
"Net=\c Net"\
|
||||
"Nets=\c Nets"\
|
||||
"Pin=\c Pin"\
|
||||
"Pins=\c Pins"\
|
||||
"Plug=\c Plug"\
|
||||
"Plugs=\c Plugs"\
|
||||
"RoutingPad=\c RoutingPad"\
|
||||
"RoutingPads=\c RoutingPads"\
|
||||
"Cell=\c Cell"\
|
||||
"Cells=\c Cells"\
|
||||
"ToolEngine=\c ToolEngine"\
|
||||
"ToolEngines=\c ToolEngines"\
|
||||
"GCell=\c GCell"\
|
||||
"GCells=\c GCells"\
|
||||
"Splitter=\c Splitter"\
|
||||
"Splitters=\c Splitters"\
|
||||
"SplitterContact=\c SplitterContact"\
|
||||
"SplitterContacts=\c SplitterContacts"\
|
||||
"Hurricane=<a href='../hurricane/Index.html'>Hurricane</a>"\
|
||||
"STL=<a href='http://www.sgi.com/tech/stl/'>STL</a>"\
|
||||
"red{1}=<span class=\"red\">\1</span>"
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SUBGROUPING = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_ANON_NSPACES = YES
|
||||
HIDE_UNDOC_MEMBERS = YES
|
||||
HIDE_UNDOC_CLASSES = YES
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = YES
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 1
|
||||
SHOW_USED_FILES = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to warning and progress messages
|
||||
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the input files
|
||||
|
||||
INPUT = \
|
||||
Katabatic.dox \
|
||||
../src/katabatic/Observer.h ../src/Observer.cpp Observer.dox \
|
||||
../src/katabatic/Constants.h Constants.dox \
|
||||
../src/katabatic/AutoContact.h ../src/AutoContact.cpp AutoContact.dox \
|
||||
../src/katabatic/AutoContactTerminal.h ../src/AutoContactTerminal.cpp AutoContactTerminal.dox \
|
||||
../src/katabatic/AutoContactTurn.h ../src/AutoContactTurn.cpp AutoContactTurn.dox \
|
||||
../src/katabatic/AutoContactHTee.h ../src/AutoContactHTee.cpp AutoContactHTee.dox \
|
||||
../src/katabatic/AutoContactVTee.h ../src/AutoContactVTee.cpp AutoContactVTee.dox \
|
||||
../src/katabatic/AutoSegment.h ../src/AutoSegment.cpp AutoSegment.dox \
|
||||
../src/katabatic/AutoSegments.h AutoSegments.dox \
|
||||
../src/katabatic/AutoHorizontal.h ../src/AutoHorizontal.cpp AutoHorizontal.dox \
|
||||
../src/katabatic/AutoVertical.h ../src/AutoVertical.cpp AutoVertical.dox \
|
||||
../src/katabatic/GCell.h ../src/GCell.cpp GCell.dox \
|
||||
../src/katabatic/GCells.h GCells.dox \
|
||||
../src/katabatic/Grid.h ../src/Grid.cpp Grid.dox \
|
||||
../src/katabatic/GCellGrid.h ../src/GCellGrid.cpp GCellGrid.dox \
|
||||
../src/katabatic/Session.h ../src/Session.cpp Session.dox \
|
||||
../src/katabatic/ChipTools.h ../src/ChipTools.cpp ChipTools.dox \
|
||||
../src/LoadGrByNet.cpp \
|
||||
../src/katabatic/KatabaticEngine.h ../src/KatabaticEngine.cpp KatabaticEngine.dox
|
||||
|
||||
FILE_PATTERNS = *.h \
|
||||
*.cpp \
|
||||
*.dox
|
||||
|
||||
RECURSIVE = YES
|
||||
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH = .
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH = images
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to source browsing
|
||||
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
VERBATIM_HEADERS = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the alphabetical class index
|
||||
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 2
|
||||
IGNORE_PREFIX =
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the HTML output
|
||||
|
||||
GENERATE_HTML = YES
|
||||
#HTML_DYNAMIC_SECTIONS = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER = header.html
|
||||
HTML_FOOTER = footer.html
|
||||
HTML_STYLESHEET = SoC.css
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 1
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the LaTeX output
|
||||
|
||||
GENERATE_LATEX = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER = header.tex
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the RTF output
|
||||
|
||||
GENERATE_RTF = YES
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the man page output
|
||||
|
||||
GENERATE_MAN = YES
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the XML output
|
||||
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options for the AutoGen Definitions output
|
||||
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the Perl module output
|
||||
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = __DOXYGEN__
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
|
||||
TAGFILES = ../../hurricane/doc/hurricane/html/hurricane.tag=../hurricane \
|
||||
../../hurricane/doc/viewer/html/viewer.tag=../viewer \
|
||||
../../crlcore/doc/crlcore/html/crlcore.tag=../crlcore
|
||||
GENERATE_TAGFILE = html/katabatic.tag
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
|
||||
CLASS_DIAGRAMS = NO
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = YES
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = NO
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = NO
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
#MAX_DOT_GRAPH_WIDTH = 512
|
||||
#MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
#MAX_DOT_GRAPH_DEPTH = 0
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
|
||||
SEARCHENGINE = NO
|
|
@ -1,97 +0,0 @@
|
|||
function toggleVisibility(linkObj)
|
||||
{
|
||||
var base = $(linkObj).attr('id');
|
||||
var summary = $('#'+base+'-summary');
|
||||
var content = $('#'+base+'-content');
|
||||
var trigger = $('#'+base+'-trigger');
|
||||
var src=$(trigger).attr('src');
|
||||
if (content.is(':visible')===true) {
|
||||
content.hide();
|
||||
summary.show();
|
||||
$(linkObj).addClass('closed').removeClass('opened');
|
||||
$(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
|
||||
} else {
|
||||
content.show();
|
||||
summary.hide();
|
||||
$(linkObj).removeClass('closed').addClass('opened');
|
||||
$(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateStripes()
|
||||
{
|
||||
$('table.directory tr').
|
||||
removeClass('even').filter(':visible:even').addClass('even');
|
||||
}
|
||||
function toggleLevel(level)
|
||||
{
|
||||
$('table.directory tr').each(function(){
|
||||
var l = this.id.split('_').length-1;
|
||||
var i = $('#img'+this.id.substring(3));
|
||||
var a = $('#arr'+this.id.substring(3));
|
||||
if (l<level+1) {
|
||||
i.attr('src','ftv2folderopen.png');
|
||||
a.attr('src','ftv2mnode.png');
|
||||
$(this).show();
|
||||
} else if (l==level+1) {
|
||||
i.attr('src','ftv2folderclosed.png');
|
||||
a.attr('src','ftv2pnode.png');
|
||||
$(this).show();
|
||||
} else {
|
||||
$(this).hide();
|
||||
}
|
||||
});
|
||||
updateStripes();
|
||||
}
|
||||
|
||||
function toggleFolder(id)
|
||||
{
|
||||
//The clicked row
|
||||
var currentRow = $('#row_'+id);
|
||||
var currentRowImages = currentRow.find("img");
|
||||
|
||||
//All rows after the clicked row
|
||||
var rows = currentRow.nextAll("tr");
|
||||
|
||||
//Only match elements AFTER this one (can't hide elements before)
|
||||
var childRows = rows.filter(function() {
|
||||
var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
|
||||
return this.id.match(re);
|
||||
});
|
||||
|
||||
//First row is visible we are HIDING
|
||||
if (childRows.filter(':first').is(':visible')===true) {
|
||||
currentRowImages.filter("[id^=arr]").attr('src', 'ftv2pnode.png');
|
||||
currentRowImages.filter("[id^=img]").attr('src', 'ftv2folderclosed.png');
|
||||
rows.filter("[id^=row_"+id+"]").hide();
|
||||
} else { //We are SHOWING
|
||||
//All sub images
|
||||
var childImages = childRows.find("img");
|
||||
var childImg = childImages.filter("[id^=img]");
|
||||
var childArr = childImages.filter("[id^=arr]");
|
||||
|
||||
currentRow.find("[id^=arr]").attr('src', 'ftv2mnode.png'); //open row
|
||||
currentRow.find("[id^=img]").attr('src', 'ftv2folderopen.png'); //open row
|
||||
childImg.attr('src','ftv2folderclosed.png'); //children closed
|
||||
childArr.attr('src','ftv2pnode.png'); //children closed
|
||||
childRows.show(); //show all children
|
||||
}
|
||||
updateStripes();
|
||||
}
|
||||
|
||||
|
||||
function toggleInherit(id)
|
||||
{
|
||||
var rows = $('tr.inherit.'+id);
|
||||
var img = $('tr.inherit_header.'+id+' img');
|
||||
var src = $(img).attr('src');
|
||||
if (rows.filter(':first').is(':visible')===true) {
|
||||
rows.css('display','none');
|
||||
$(img).attr('src',src.substring(0,src.length-8)+'closed.png');
|
||||
} else {
|
||||
rows.css('display','table-row'); // using show() causes jump in firefox
|
||||
$(img).attr('src',src.substring(0,src.length-10)+'open.png');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<br>
|
||||
<hr>
|
||||
<table class="footer1">
|
||||
<tr>
|
||||
<td class="LFooter"><small>Generated by doxygen $doxygenversion on $date</small></td>
|
||||
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="footer2">
|
||||
<tr>
|
||||
<td class="LFooter">Katabatic - Routing Toolbox</td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2020 Sorbonne Universite. All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -1,26 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||
<title>Katabatic Documentation</title>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="SoC.css" rel="stylesheet" type="text/css">
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<h1 id="pagetop" class="header">Katabatic - Routing Toolbox</h1>
|
||||
<!--
|
||||
<center class="header">
|
||||
<table class="header">
|
||||
<tr>
|
||||
<td><a href="customSummary.html">Summary</a></td>
|
||||
<td><a href="namespaces.html">Namespaces</a></td>
|
||||
<td><a href="customHierarchy.html">Class Hierarchy</a></td>
|
||||
<td><a href="annotated.html">Classes</a></td>
|
||||
<td><a href="functions.html">Member Index</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
-->
|
||||
<br>
|
||||
<body onload="javascript:toggleLevel(1)">
|
|
@ -1,47 +0,0 @@
|
|||
|
||||
|
||||
\documentclass[a4paper]{asimbook}
|
||||
|
||||
\usepackage{a4wide}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{fancyhdr}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{multicol}
|
||||
\usepackage{float}
|
||||
\usepackage{textcomp}
|
||||
\usepackage{alltt}
|
||||
\usepackage{times}
|
||||
\ifx\pdfoutput\undefined
|
||||
\usepackage[ps2pdf,pagebackref=true,colorlinks=true,linkcolor=blue]{hyperref}
|
||||
\usepackage{pspicture}
|
||||
\else
|
||||
\usepackage[pdftex,pagebackref=true,colorlinks=true,linkcolor=blue]{hyperref}
|
||||
\fi
|
||||
\usepackage{doxygen}
|
||||
|
||||
\makeindex
|
||||
\setcounter{tocdepth}{1}
|
||||
\renewcommand{\footrulewidth}{0.4pt}
|
||||
\raggedbottom
|
||||
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{titlepage}
|
||||
\vspace*{7cm}
|
||||
\begin{center}
|
||||
{\Large $projectname Reference Manual\\[1ex]\large $projectnumber }\\
|
||||
\vspace*{1cm}
|
||||
{\large Generated by Doxygen $doxygenversion}\\
|
||||
\vspace*{0.5cm}
|
||||
{\small $datetime}\\
|
||||
\end{center}
|
||||
\end{titlepage}
|
||||
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{roman}
|
||||
|
||||
\tableofcontents
|
||||
\clearemptydoublepage
|
||||
|
||||
\pagenumbering{arabic}
|
|
@ -1 +0,0 @@
|
|||
<li><a class="entry" href="katabatic/customSummary.html">Katabatic</a><br>Routing Database<br><br>
|
|
@ -1,882 +0,0 @@
|
|||
|
||||
|
||||
/*
|
||||
* +-----------------------------------------------------------------+
|
||||
* | HTML Standart Tags |
|
||||
* +-----------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 {
|
||||
font-size: 11pt;
|
||||
/* The Open Sans font family is supplied by TexLive. */
|
||||
font-family: "Roboto", "Open Sans", Verdana, sans-serif;;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #dddddd;
|
||||
}
|
||||
|
||||
body {
|
||||
color: black;
|
||||
background: white;
|
||||
background-color: white;
|
||||
background-position: top left;
|
||||
background-attachment: fixed;
|
||||
background-repeat: no-repeat;
|
||||
margin-top: 2em;
|
||||
width: 600pt;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding: 30pt;
|
||||
/*
|
||||
margin-right: 12%;
|
||||
margin-left: 12%;
|
||||
*/
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
color: #004400;
|
||||
background-color: #004400;
|
||||
}
|
||||
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
/*font-family: "URW Bookman L", "Liberation Serif", sans-serif;*/
|
||||
font-family: "URW Bookman L";
|
||||
}
|
||||
|
||||
h1.header { text-align: center; }
|
||||
h1 { text-align: left; }
|
||||
h2, h3, h4, h5, h6 { text-align: left;
|
||||
padding-top: 11pt;
|
||||
}
|
||||
h1, h2, h3 { /*font-family: "Liberation Serif", sans-serif; */
|
||||
/*color: #09550B;*/
|
||||
}
|
||||
h1 { font-weight: bold; font-size: 170%; /*letter-spacing:0.2em; word-spacing:0.4em;*/ }
|
||||
h2 { font-weight: bold; font-size: 140%; /*letter-spacing:0.2em; word-spacing:0.4em;*/ }
|
||||
h3 { font-weight: bold; font-size: 118%; /*letter-spacing:0.2em; word-spacing:0.4em;*/ }
|
||||
h4 { font-weight: bold; font-size: 100%; }
|
||||
h5 { font-style: italic; font-size: 100%; }
|
||||
h6 { font-variant: small-caps; font-size: 100%; }
|
||||
|
||||
h2.classHierarchy {
|
||||
/*border: 1px none #008500;*/
|
||||
border: 1px none #000000;
|
||||
border-top-width: 1px;
|
||||
border-top-style: dotted;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
p {
|
||||
margin-top: 0.6em;
|
||||
margin-bottom: 0.6em;
|
||||
margin-left: 0.0em;
|
||||
margin-right: 0.0em;
|
||||
}
|
||||
|
||||
|
||||
address {
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
|
||||
caption { font-weight: bold }
|
||||
|
||||
|
||||
blockquote {
|
||||
margin-left: 4em;
|
||||
margin-right: 4em;
|
||||
margin-top: 0.8em;
|
||||
margin-bottom: 0.8em;
|
||||
font-style: italic;
|
||||
color: #003300;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
blockquote address {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
dt, dd { margin-top: 0; margin-bottom: 0; }
|
||||
dt { font-weight: bold; }
|
||||
|
||||
|
||||
pre, tt, code {
|
||||
/*font-family: "andale mono", monospace;*/
|
||||
font-size: 100%;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 80%;
|
||||
/*border: dashed;*/
|
||||
border-width: thin;
|
||||
border-color: #003300;
|
||||
/*background-color: #EEEEEE;*/
|
||||
background-color: #FCFCE1;
|
||||
padding: 0.5em;
|
||||
margin-left: 2em;
|
||||
margin-right: 2em
|
||||
}
|
||||
|
||||
/*
|
||||
tt { color: green; }
|
||||
*/
|
||||
em { font-style: italic;
|
||||
font-weight: normal; }
|
||||
strong { font-weight: bold; }
|
||||
|
||||
span.textit { font-style: italic; }
|
||||
span.textbf { font-weight: bold; }
|
||||
|
||||
.small { font-size: 90%; }
|
||||
.white { color: #FFFFFF; }
|
||||
|
||||
|
||||
ul.toc {
|
||||
list-style: disc;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
a:link img, a:visited img { border-style: none; }
|
||||
a img { color: white; }
|
||||
|
||||
a {
|
||||
color: black;
|
||||
border-bottom: 1px solid black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:link, a:active, a:visited {
|
||||
/*color: #09550B;*/
|
||||
/*text-decoration: none;*/
|
||||
}
|
||||
|
||||
a:hover, a:focus {
|
||||
/*color: #FF9900; */
|
||||
border-bottom: 2px solid black;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* +-----------------------------------------------------------------+
|
||||
* | Doxygen Specific Classes |
|
||||
* +-----------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Header & Footer Classes (customized top page navigation bar).
|
||||
*/
|
||||
|
||||
h1.header {
|
||||
font-size: 200%;
|
||||
/*font-family: times, verdana, sans-serif;*/
|
||||
}
|
||||
|
||||
h2.memtitle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
center.header {
|
||||
background-color: #CCE6CA;
|
||||
}
|
||||
|
||||
table.header {
|
||||
/*width: 100%;*/
|
||||
/*background-color: #EEEEEE;*/
|
||||
background-color: #CCE6CA;
|
||||
}
|
||||
|
||||
div.header {
|
||||
text-align: center;
|
||||
margin: 14pt 0pt 0pt 0pt;
|
||||
}
|
||||
|
||||
div.summary {
|
||||
color: white;
|
||||
background-color: black;
|
||||
border: 4px solid black;
|
||||
}
|
||||
|
||||
div.summary a {
|
||||
font-size: 90%;
|
||||
color: white;
|
||||
padding: 2px 0px;
|
||||
text-align: center;
|
||||
background-color: black;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table.header td {
|
||||
padding: 2px 14px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
/*font-family: verdana, sans-serif;*/
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
table.UserDefined {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
table.UserDefined th {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
table.UserDefined td {
|
||||
padding: 0px 5px;
|
||||
}
|
||||
|
||||
table.DoxUser td, table.DoxUser th {
|
||||
padding: 0px 5px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
table.DoxUser th {
|
||||
background-color: #CCE6CA;
|
||||
}
|
||||
|
||||
table.footer1, table.footer2 { width: 100%; }
|
||||
td.LFooter { text-align: left; }
|
||||
td.RFooter { text-align: right; }
|
||||
td.CFooter { text-align: center;}
|
||||
table.footer2 td.RFooter { font-weight: bold; width: 35% }
|
||||
table.footer2 td.CFooter { width: 30% }
|
||||
table.footer2 td.LFooter { font-weight: bold; width: 35%; /*font-family: time;*/ }
|
||||
|
||||
table.classHierarchy {
|
||||
border-collapse: separate;
|
||||
border-spacing: 5px;
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
table.classHierarchy a {
|
||||
border-style: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table.classHierarchy tr {
|
||||
border: 1px solid blue;
|
||||
}
|
||||
|
||||
table.classHierarchy td.normal {
|
||||
border: 1px solid #dddddd;
|
||||
width: 140pt;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
background-color: #dddddd;
|
||||
}
|
||||
|
||||
table.classHierarchy td.virtual {
|
||||
border: 1px solid black;
|
||||
width: 140pt;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.classHierarchy td.wnormal {
|
||||
border: 1px solid #dddddd;
|
||||
width: 240pt;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
background-color: #dddddd;
|
||||
}
|
||||
|
||||
table.classHierarchy td.wvirtual {
|
||||
border: 1px solid black;
|
||||
width: 240pt;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.ah, span.ah {
|
||||
font-family: Times;
|
||||
font-size: 300%;
|
||||
font-weight: bold;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
div.title {
|
||||
text-align: center;
|
||||
font-size: 200%;
|
||||
font-weight: bold;
|
||||
padding: 20px;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
div.center, div.image {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Top navigation lists.
|
||||
*/
|
||||
|
||||
span.mlabels {
|
||||
font-size: 90%;
|
||||
font-style: italic;
|
||||
padding-left: 10pt;
|
||||
margin: 10pt;
|
||||
border-left: 1px solid black
|
||||
}
|
||||
|
||||
div.contents {
|
||||
padding-top: 20pt;
|
||||
}
|
||||
|
||||
div.tabs {
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
div.tabs, div.tabs1, div.tabs2, div.tabs3, div.tabs4 {
|
||||
border-left: 1px solid black;
|
||||
}
|
||||
|
||||
ul.tablist {
|
||||
/*
|
||||
padding: 5pt;
|
||||
background-color: red;
|
||||
*/
|
||||
margin: 0pt;
|
||||
padding: 0pt;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
ul.tablist li {
|
||||
/*
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
overflow: auto;
|
||||
display: inline;
|
||||
background-color: yellow;
|
||||
*/
|
||||
font-size: 90%;
|
||||
border-top: none;
|
||||
border-bottom: 1px solid black;
|
||||
border-left: none;
|
||||
border-right: 1px solid black;
|
||||
display: table-cell;
|
||||
text-align: center;
|
||||
padding: 2pt;
|
||||
width: 5%;
|
||||
}
|
||||
|
||||
ul.tablist li:hover {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
ul.tablist li:hover a {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
ul.tablist * a { border-bottom: none; }
|
||||
|
||||
ul.tablist * a:link img, ul.tablist * a:visited img { border-style: none; border-bottom: none; }
|
||||
|
||||
ul.tablist * a:link, ul.tablist * a:visited {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul.tablist * a:hover, ul.tablist * a:focus, ul.tablist * a:active {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.navpath {
|
||||
padding: 5pt 0pt 0pt 0pt;
|
||||
}
|
||||
|
||||
.navpath ul {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.navpath ul li {
|
||||
display: inline;
|
||||
list-style-type: none;
|
||||
padding-left: 20px;
|
||||
padding-right: 10px;
|
||||
background-image: url('closed.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: left;
|
||||
color: #364D7C;
|
||||
}
|
||||
|
||||
.navpath ul li a {
|
||||
border: 2px solid black;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Quick Index Class (top page navigation bar).
|
||||
*/
|
||||
|
||||
div.qindex, div.nav {
|
||||
width: 100%-4px;
|
||||
/*background-color: #DADAEF;*/
|
||||
/*background-color: #eeeeff;*/
|
||||
background-color: #cccccc;
|
||||
/*background-color: #CCE6CA;*/
|
||||
border: 0px solid #003300;
|
||||
text-align: center;
|
||||
margin: 0px;
|
||||
padding: 2px;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
a.qindex, a.qindex:visited, a.qindex:hover, a.qindexHL, a.el, a.elRef {
|
||||
text-decoration: none;
|
||||
/*font-family: Courier;*/
|
||||
font-weight: normal;
|
||||
/*font-size: 110%;*/
|
||||
}
|
||||
|
||||
a.qindex, a.qindex:visited {
|
||||
/*color: #09550B;*/
|
||||
color: black;
|
||||
border: 2px solid #cccccc;
|
||||
padding: 2px 2px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
a.qindex:hover {
|
||||
/*background-color: #ddddff;*/
|
||||
font-weight: bold;
|
||||
padding: 2px 2px;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
a.qindexHL, a.qindexHL:hover, a.qindexHL:visited {
|
||||
background-color: #0c780c;
|
||||
color: #ffffff;
|
||||
border: 1px double #9295C2;
|
||||
}
|
||||
|
||||
a.code:link, a.code:visited, a.codeRef:link, a.codeRef:visited {
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
color: #0000ff;
|
||||
}
|
||||
|
||||
.indexkey {
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 2px 15px;
|
||||
}
|
||||
|
||||
.indexkey, .indexvalue {
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 2px 15px;
|
||||
}
|
||||
|
||||
.indexkey {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.indexvalue {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
h3 a[name="index__"],
|
||||
h3 a[name="index_a"],
|
||||
h3 a[name="index_b"],
|
||||
h3 a[name="index_c"],
|
||||
h3 a[name="index_d"],
|
||||
h3 a[name="index_e"],
|
||||
h3 a[name="index_f"],
|
||||
h3 a[name="index_g"],
|
||||
h3 a[name="index_h"],
|
||||
h3 a[name="index_i"],
|
||||
h3 a[name="index_j"],
|
||||
h3 a[name="index_k"],
|
||||
h3 a[name="index_l"],
|
||||
h3 a[name="index_m"],
|
||||
h3 a[name="index_n"],
|
||||
h3 a[name="index_o"],
|
||||
h3 a[name="index_p"],
|
||||
h3 a[name="index_q"],
|
||||
h3 a[name="index_r"],
|
||||
h3 a[name="index_s"],
|
||||
h3 a[name="index_t"],
|
||||
h3 a[name="index_u"],
|
||||
h3 a[name="index_v"],
|
||||
h3 a[name="index_w"],
|
||||
h3 a[name="index_x"],
|
||||
h3 a[name="index_y"],
|
||||
h3 a[name="index_z"],
|
||||
h3 a[name="index_0"],
|
||||
h3 a[name="index_1"],
|
||||
h3 a[name="index_2"],
|
||||
h3 a[name="index_3"],
|
||||
h3 a[name="index_4"],
|
||||
h3 a[name="index_5"],
|
||||
h3 a[name="index_6"],
|
||||
h3 a[name="index_7"],
|
||||
h3 a[name="index_8"],
|
||||
h3 a[name="index_9"]
|
||||
h3 a[id="index__"],
|
||||
h3 a#index_a,
|
||||
h3 a#index_b,
|
||||
h3 a#index_c,
|
||||
h3 a#index_d,
|
||||
h3 a#index_e,
|
||||
h3 a#index_f,
|
||||
h3 a#index_g,
|
||||
h3 a#index_h,
|
||||
h3 a#index_i,
|
||||
h3 a#index_j,
|
||||
h3 a#index_k,
|
||||
h3 a#index_l,
|
||||
h3 a#index_m,
|
||||
h3 a#index_n,
|
||||
h3 a#index_o,
|
||||
h3 a#index_p,
|
||||
h3 a#index_q,
|
||||
h3 a#index_r,
|
||||
h3 a#index_s,
|
||||
h3 a#index_t,
|
||||
h3 a#index_u,
|
||||
h3 a#index_v,
|
||||
h3 a#index_w,
|
||||
h3 a#index_x,
|
||||
h3 a#index_y,
|
||||
h3 a#index_z,
|
||||
h3 a#index_0,
|
||||
h3 a#index_1,
|
||||
h3 a#index_2,
|
||||
h3 a#index_3,
|
||||
h3 a#index_4,
|
||||
h3 a#index_5,
|
||||
h3 a#index_6,
|
||||
h3 a#index_7,
|
||||
h3 a#index_8,
|
||||
h3 a#index_9,
|
||||
h3 a#index_0x7e
|
||||
{
|
||||
font-family: time;
|
||||
font-size: 250%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Verbatim Source Code / Examples.
|
||||
*/
|
||||
|
||||
div.fragment {
|
||||
font-family: "Roboto Mono", "Monospace";
|
||||
font-size: 80%;
|
||||
border: none;
|
||||
/*border-width: thin; */
|
||||
/*border-color: #003300;*/
|
||||
/*background-color: #FCFCE1;*/
|
||||
background-color: #fefefe;
|
||||
padding: 0.5em;
|
||||
margin-left: 5%;
|
||||
margin-right: 5%
|
||||
}
|
||||
|
||||
div.fragment a.code:link,
|
||||
div.fragment a.code:visited,
|
||||
div.fragment a.codeRef:link,
|
||||
div.fragment a.codeRef:visited {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.line {
|
||||
white-space: pre;
|
||||
padding: 0pt;
|
||||
margin: 0pt;
|
||||
}
|
||||
|
||||
span.keyword { color: #008000 }
|
||||
span.keywordtype { color: #604020 }
|
||||
span.keywordflow { color: #e08000 }
|
||||
span.comment { color: #800000 }
|
||||
span.preprocessor { color: #806020 }
|
||||
span.stringliteral { color: #002080 }
|
||||
span.charliteral { color: #008080 }
|
||||
span.red { color: red }
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Attributes Listing.
|
||||
*/
|
||||
|
||||
a.el, a.elRef {
|
||||
font-family: "Roboto Mono", Courier;
|
||||
font-weight: bold;
|
||||
font-size: 110%;
|
||||
color: black;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
p.formulaDsp {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mdTable {
|
||||
/*border: 1px solid #868686;*/
|
||||
/*background-color: #DADAEF;*/
|
||||
/*background-color: #F4F4FB;*/
|
||||
border: 1px none #008500;
|
||||
border-left-width: 1px;
|
||||
border-left-style: solid;
|
||||
/*background-color: #B8E6B8;*/
|
||||
/*background-color: #CCE6CA;*/
|
||||
margin-top: 25px;
|
||||
font-size: 105%;
|
||||
}
|
||||
|
||||
.mdRow {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
/* This Mozilla/Firefox bug has been corrected from v1.5.
|
||||
* .mdname1 {
|
||||
* padding: 3px 0px 0px 0px;
|
||||
* }
|
||||
*/
|
||||
|
||||
.mdescLeft, .mdescRight {
|
||||
padding: 0px 8px 4px 8px;
|
||||
font-size: 11px;
|
||||
font-style: italic;
|
||||
/*background-color: #FAFAFA;*/
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.memitem {
|
||||
margin-bottom: 30px;
|
||||
border: 1px none #008500;
|
||||
}
|
||||
|
||||
.memproto {
|
||||
/*background-color: #CCE6CA;*/
|
||||
background-color: #cccccc;
|
||||
border-left-width: 4px;
|
||||
border-left-style: solid;
|
||||
/*border-color: #008500;*/
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
.memname {
|
||||
white-space: nowrap;
|
||||
padding-left: 5px;
|
||||
font-size: 105%;
|
||||
}
|
||||
|
||||
table.memname * {
|
||||
font-family: "Roboto Mono", "Monospace";
|
||||
}
|
||||
|
||||
|
||||
.memdoc{
|
||||
padding-left: 5px;
|
||||
/*margin-top: -8px;*/
|
||||
border-left-width: 1px;
|
||||
border-left-style: solid;
|
||||
/*border-color: #008500;*/
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
div.contents * table tr {
|
||||
padding: 3px 3px 3px 8px;
|
||||
}
|
||||
|
||||
.memSeparator {
|
||||
font-size: 1pt;
|
||||
}
|
||||
|
||||
.memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight {
|
||||
vertical-align: top;
|
||||
/*padding: 1px 0px 0px 8px;*/
|
||||
padding: 3px 3px 3px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
/*
|
||||
border-top-color: #0c0c0c;
|
||||
border-right-color: #0c0c0c;
|
||||
border-bottom-color: #0c0c0c;
|
||||
border-left-color: #0c0c0c;
|
||||
*/
|
||||
border-top-style: none;
|
||||
border-right-style: none;
|
||||
/*
|
||||
border-bottom-style: dotted;
|
||||
*/
|
||||
border-left-style: none;
|
||||
/*background-color: #DADAEF;*/
|
||||
/*background-color: #eeeeff;*/
|
||||
/*background-color: #EEEEEE;*/
|
||||
/*background-color: #CCE6CA;*/
|
||||
font-family: "Roboto Mono", "Monospace";
|
||||
}
|
||||
|
||||
.memTemplItemLeft, .memTemplItemRight {
|
||||
border-bottom-width: 2px;
|
||||
border-bottom-style: solid;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.memItemLeft { font-size: 11px; width: 100pt; }
|
||||
.memItemRight { font-size: 12px; }
|
||||
.memTemplItemLeft { font-size: 11px; }
|
||||
.memTemplItemRight { font-size: 12px; }
|
||||
|
||||
.memTemplParams {
|
||||
color: #FFFFFF;
|
||||
background-color: #000000;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.groupText, .groupHeader {
|
||||
color: #09550B;
|
||||
font-size: 130%;
|
||||
font-weight: bold;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.groupHeader {
|
||||
margin-bottom: -30pt;
|
||||
}
|
||||
|
||||
.inherit {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* General Classes Index.
|
||||
*/
|
||||
|
||||
span.icona {
|
||||
margin-right: 10pt;
|
||||
}
|
||||
|
||||
div.toc li.level1 {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
div.toc li.level2 {
|
||||
margin-left: 15px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.toc li.level3 {
|
||||
margin-left: 30px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.toc li.level4 {
|
||||
margin-left: 45px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.directory .levels {
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
.directory .levels span {
|
||||
cursor: pointer;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
color: #3D578C;
|
||||
}
|
||||
|
||||
|
||||
div.directory {
|
||||
margin: 10px 0px;
|
||||
border-top: 2px solid black;
|
||||
border-bottom: 2px solid black;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.directory table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.directory td {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.directory td.entry {
|
||||
white-space: nowrap;
|
||||
padding-right: 6px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.directory td.entry a {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.directory td.entry a img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.directory td.desc {
|
||||
width: 100%;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
padding-top: 3px;
|
||||
border-left: 1px solid rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.directory tr.even {
|
||||
padding-left: 6px;
|
||||
background-color: #F7F8FB;
|
||||
}
|
||||
|
||||
.directory img {
|
||||
vertical-align: -30%;
|
||||
}
|
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 12 KiB |
|
@ -1,96 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||
<title>Katabatic Documentation</title>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="SoC.css" rel="stylesheet" type="text/css">
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<h1 id="pagetop" class="header">Katabatic - Routing Toolbox</h1>
|
||||
<!--
|
||||
<center class="header">
|
||||
<table class="header">
|
||||
<tr>
|
||||
<td><a href="customSummary.html">Summary</a></td>
|
||||
<td><a href="namespaces.html">Namespaces</a></td>
|
||||
<td><a href="customHierarchy.html">Class Hierarchy</a></td>
|
||||
<td><a href="annotated.html">Classes</a></td>
|
||||
<td><a href="functions.html">Member Index</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
-->
|
||||
<br>
|
||||
<body onload="javascript:toggleLevel(1)">
|
||||
<!-- Generated by Doxygen 1.8.14 -->
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||
$(function() {
|
||||
initMenu('',false,false,'search.php','Search');
|
||||
});
|
||||
/* @license-end */</script>
|
||||
<div id="main-nav"></div>
|
||||
</div><!-- top -->
|
||||
<div class="header">
|
||||
<div class="headertitle">
|
||||
<div class="title">Class List</div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
<div class="textblock">Here are the classes, structs, unions and interfaces with brief descriptions:</div><div class="directory">
|
||||
<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span><span onclick="javascript:toggleLevel(3);">3</span>]</div><table class="directory">
|
||||
<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceanonymous__namespace_02LoadGrByNet_8cpp_03.html" target="_self">anonymous_namespace{LoadGrByNet.cpp}</a></td><td class="desc"></td></tr>
|
||||
<tr id="row_0_0_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classanonymous__namespace_02LoadGrByNet_8cpp_03_1_1GCellTopology.html" target="_self">GCellTopology</a></td><td class="desc">Build the wiring for a Net inside a GCell (<b>internal</b>) </td></tr>
|
||||
<tr id="row_1_" class="even"><td class="entry"><span style="width:0px;display:inline-block;"> </span><span id="arr_1_" class="arrow" onclick="toggleFolder('1_')">▼</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespaceKatabatic.html" target="_self">Katabatic</a></td><td class="desc">The namespace dedicated to <a class="el" href="namespaceKatabatic.html" title="The namespace dedicated to Katabatic. ">Katabatic</a> </td></tr>
|
||||
<tr id="row_1_0_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoContact.html" target="_self">AutoContact</a></td><td class="desc">Abstract base class for <a class="el" href="classKatabatic_1_1AutoContact.html" title="Abstract base class for AutoContact. ">AutoContact</a> </td></tr>
|
||||
<tr id="row_1_1_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoContactHTee.html" target="_self">AutoContactHTee</a></td><td class="desc"><a class="el" href="classKatabatic_1_1AutoContact.html" title="Abstract base class for AutoContact. ">AutoContact</a> H-Tee (two H, one V) </td></tr>
|
||||
<tr id="row_1_2_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoContactTerminal.html" target="_self">AutoContactTerminal</a></td><td class="desc"><a class="el" href="classKatabatic_1_1AutoContact.html" title="Abstract base class for AutoContact. ">AutoContact</a> Terminal (S/T is a Terminal) </td></tr>
|
||||
<tr id="row_1_3_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoContactTurn.html" target="_self">AutoContactTurn</a></td><td class="desc"><a class="el" href="classKatabatic_1_1AutoContact.html" title="Abstract base class for AutoContact. ">AutoContact</a> Turn (one H, one V) </td></tr>
|
||||
<tr id="row_1_4_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoContactVTee.html" target="_self">AutoContactVTee</a></td><td class="desc"><a class="el" href="classKatabatic_1_1AutoContact.html" title="Abstract base class for AutoContact. ">AutoContact</a> V-Tee (one H, two V) </td></tr>
|
||||
<tr id="row_1_5_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoHorizontal.html" target="_self">AutoHorizontal</a></td><td class="desc">Concrete Horizontal <a class="el" href="classKatabatic_1_1AutoSegment.html" title="Abstract base class for AutoSegment. ">AutoSegment</a> </td></tr>
|
||||
<tr id="row_1_6_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoSegment.html" target="_self">AutoSegment</a></td><td class="desc">Abstract base class for <a class="el" href="classKatabatic_1_1AutoSegment.html" title="Abstract base class for AutoSegment. ">AutoSegment</a> </td></tr>
|
||||
<tr id="row_1_7_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoSegments__Aligneds.html" target="_self">AutoSegments_Aligneds</a></td><td class="desc">All aligned <a class="el" href="classKatabatic_1_1AutoSegment.html" title="Abstract base class for AutoSegment. ">AutoSegment</a> of a set </td></tr>
|
||||
<tr id="row_1_8_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoSegments__AnchorOnGCell.html" target="_self">AutoSegments_AnchorOnGCell</a></td><td class="desc">All <a class="el" href="classKatabatic_1_1AutoSegment.html" title="Abstract base class for AutoSegment. ">AutoSegment</a> Beginning and/or Stopping in a <a class="el" href="classKatabatic_1_1GCell.html" title="Routing Global Cell. ">GCell</a> </td></tr>
|
||||
<tr id="row_1_9_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoSegments__InDirection.html" target="_self">AutoSegments_InDirection</a></td><td class="desc">Filter to select <a class="el" href="classKatabatic_1_1AutoSegment.html" title="Abstract base class for AutoSegment. ">AutoSegment</a> in a given direction </td></tr>
|
||||
<tr id="row_1_10_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoSegments__IsAccountable.html" target="_self">AutoSegments_IsAccountable</a></td><td class="desc">Filter to select accoutable <a class="el" href="classKatabatic_1_1AutoSegment.html" title="Abstract base class for AutoSegment. ">AutoSegment</a> </td></tr>
|
||||
<tr id="row_1_11_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoSegments__OnContact.html" target="_self">AutoSegments_OnContact</a></td><td class="desc">All <a class="el" href="classKatabatic_1_1AutoSegment.html" title="Abstract base class for AutoSegment. ">AutoSegment</a> anchored on a Contact </td></tr>
|
||||
<tr id="row_1_12_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoSegments__Perpandiculars.html" target="_self">AutoSegments_Perpandiculars</a></td><td class="desc">All perpandicular <a class="el" href="classKatabatic_1_1AutoSegment.html" title="Abstract base class for AutoSegment. ">AutoSegment</a> to a set of aligneds </td></tr>
|
||||
<tr id="row_1_13_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1AutoVertical.html" target="_self">AutoVertical</a></td><td class="desc">Concrete Vertical <a class="el" href="classKatabatic_1_1AutoSegment.html" title="Abstract base class for AutoSegment. ">AutoSegment</a> </td></tr>
|
||||
<tr id="row_1_14_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_1_14_" class="arrow" onclick="toggleFolder('1_14_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1BaseGrid.html" target="_self">BaseGrid</a></td><td class="desc">Abstract Base Class for Irregular <a class="el" href="classKatabatic_1_1Grid.html" title="Template Class for Regular Grid. ">Grid</a> </td></tr>
|
||||
<tr id="row_1_14_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1BaseGrid_1_1Axis.html" target="_self">Axis</a></td><td class="desc">Graduations on a <a class="el" href="classKatabatic_1_1BaseGrid.html" title="Abstract Base Class for Irregular Grid. ">BaseGrid</a> <a class="el" href="classKatabatic_1_1BaseGrid_1_1Axis.html" title="Graduations on a BaseGrid Axis (H or V). ">Axis</a> (H or V) </td></tr>
|
||||
<tr id="row_1_15_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1BaseObserver.html" target="_self">BaseObserver</a></td><td class="desc"><a class="el" href="classKatabatic_1_1Observer.html" title="Observer Design Pattern, Observer part. ">Observer</a> Design Pattern, <a class="el" href="classKatabatic_1_1Observer.html" title="Observer Design Pattern, Observer part. ">Observer</a> part </td></tr>
|
||||
<tr id="row_1_16_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1ChipTools.html" target="_self">ChipTools</a></td><td class="desc">Utilities for Chip Level Design </td></tr>
|
||||
<tr id="row_1_17_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span id="arr_1_17_" class="arrow" onclick="toggleFolder('1_17_')">▼</span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1GCell.html" target="_self">GCell</a></td><td class="desc">Routing Global Cell </td></tr>
|
||||
<tr id="row_1_17_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1GCell_1_1CompareByDensity.html" target="_self">CompareByDensity</a></td><td class="desc"><a class="el" href="classKatabatic_1_1GCell.html" title="Routing Global Cell. ">GCell</a> Density Comparison Functor </td></tr>
|
||||
<tr id="row_1_17_1_"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1GCell_1_1CompareByIndex.html" target="_self">CompareByIndex</a></td><td class="desc"><a class="el" href="classKatabatic_1_1GCell.html" title="Routing Global Cell. ">GCell</a> Index Comparison Functor </td></tr>
|
||||
<tr id="row_1_17_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1GCell_1_1Key.html" target="_self">Key</a></td><td class="desc"><a class="el" href="classKatabatic_1_1GCell.html" title="Routing Global Cell. ">GCell</a> <a class="el" href="classKatabatic_1_1GCell_1_1Key.html" title="GCell Key - Density Cache. ">Key</a> - Density Cache </td></tr>
|
||||
<tr id="row_1_18_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1GCellDensitySet.html" target="_self">GCellDensitySet</a></td><td class="desc"><a class="el" href="classKatabatic_1_1GCell.html" title="Routing Global Cell. ">GCell</a> Set, sorted by density </td></tr>
|
||||
<tr id="row_1_19_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1GCellGrid.html" target="_self">GCellGrid</a></td><td class="desc"><a class="el" href="classKatabatic_1_1GCell.html" title="Routing Global Cell. ">GCell</a> <a class="el" href="classKatabatic_1_1Grid.html" title="Template Class for Regular Grid. ">Grid</a> </td></tr>
|
||||
<tr id="row_1_20_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1Grid.html" target="_self">Grid</a></td><td class="desc">Template Class for Regular <a class="el" href="classKatabatic_1_1Grid.html" title="Template Class for Regular Grid. ">Grid</a> </td></tr>
|
||||
<tr id="row_1_21_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1KatabaticEngine.html" target="_self">KatabaticEngine</a></td><td class="desc">The <a class="el" href="namespaceKatabatic.html" title="The namespace dedicated to Katabatic. ">Katabatic</a> Tool </td></tr>
|
||||
<tr id="row_1_22_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1LocatorHelper.html" target="_self">LocatorHelper</a></td><td class="desc">Locator Helper Collection's Locators </td></tr>
|
||||
<tr id="row_1_23_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1Observable.html" target="_self">Observable</a></td><td class="desc"><a class="el" href="classKatabatic_1_1Observer.html" title="Observer Design Pattern, Observer part. ">Observer</a> Design Pattern, Subject part </td></tr>
|
||||
<tr id="row_1_24_"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1Observer.html" target="_self">Observer</a></td><td class="desc"><a class="el" href="classKatabatic_1_1Observer.html" title="Observer Design Pattern, Observer part. ">Observer</a> Design Pattern, <a class="el" href="classKatabatic_1_1Observer.html" title="Observer Design Pattern, Observer part. ">Observer</a> part </td></tr>
|
||||
<tr id="row_1_25_" class="even"><td class="entry"><span style="width:32px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="classKatabatic_1_1Session.html" target="_self">Session</a></td><td class="desc">Modification <a class="el" href="classKatabatic_1_1Session.html" title="Modification Session for Katabatic. ">Session</a> for <a class="el" href="namespaceKatabatic.html" title="The namespace dedicated to Katabatic. ">Katabatic</a> </td></tr>
|
||||
</table>
|
||||
</div><!-- directory -->
|
||||
</div><!-- contents -->
|
||||
<br>
|
||||
<hr>
|
||||
<table class="footer1">
|
||||
<tr>
|
||||
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Sun Nov 21 2021</small></td>
|
||||
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="footer2">
|
||||
<tr>
|
||||
<td class="LFooter">Katabatic - Routing Toolbox</td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2020 Sorbonne Universite. All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -1,10 +0,0 @@
|
|||
var annotated =
|
||||
[
|
||||
[ "anonymous_namespace{AutoSegment.cpp}", "namespaceanonymous__namespace_02AutoSegment_8cpp_03.html", null ],
|
||||
[ "anonymous_namespace{ChipTools.cpp}", "namespaceanonymous__namespace_02ChipTools_8cpp_03.html", null ],
|
||||
[ "anonymous_namespace{GCell.cpp}", "namespaceanonymous__namespace_02GCell_8cpp_03.html", null ],
|
||||
[ "anonymous_namespace{KatabaticEngine.cpp}", "namespaceanonymous__namespace_02KatabaticEngine_8cpp_03.html", null ],
|
||||
[ "anonymous_namespace{LoadGrByNet.cpp}", "namespaceanonymous__namespace_02LoadGrByNet_8cpp_03.html", "namespaceanonymous__namespace_02LoadGrByNet_8cpp_03" ],
|
||||
[ "anonymous_namespace{Session.cpp}", "namespaceanonymous__namespace_02Session_8cpp_03.html", null ],
|
||||
[ "Katabatic", "namespaceKatabatic.html", "namespaceKatabatic" ]
|
||||
];
|
Before Width: | Height: | Size: 676 B |
Before Width: | Height: | Size: 147 B |
Before Width: | Height: | Size: 2.9 KiB |
|
@ -1,140 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||
<title>Katabatic Documentation</title>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="SoC.css" rel="stylesheet" type="text/css">
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<h1 id="pagetop" class="header">Katabatic - Routing Toolbox</h1>
|
||||
<!--
|
||||
<center class="header">
|
||||
<table class="header">
|
||||
<tr>
|
||||
<td><a href="customSummary.html">Summary</a></td>
|
||||
<td><a href="namespaces.html">Namespaces</a></td>
|
||||
<td><a href="customHierarchy.html">Class Hierarchy</a></td>
|
||||
<td><a href="annotated.html">Classes</a></td>
|
||||
<td><a href="functions.html">Member Index</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
-->
|
||||
<br>
|
||||
<body onload="javascript:toggleLevel(1)">
|
||||
<!-- Generated by Doxygen 1.8.14 -->
|
||||
<script type="text/javascript" src="menudata.js"></script>
|
||||
<script type="text/javascript" src="menu.js"></script>
|
||||
<script type="text/javascript">
|
||||
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||||
$(function() {
|
||||
initMenu('',false,false,'search.php','Search');
|
||||
});
|
||||
/* @license-end */</script>
|
||||
<div id="main-nav"></div>
|
||||
<div id="nav-path" class="navpath">
|
||||
<ul>
|
||||
<li class="navelem"><a class="el" href="namespaceKatabatic.html">Katabatic</a></li><li class="navelem"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></li> </ul>
|
||||
</div>
|
||||
</div><!-- top -->
|
||||
<div class="header">
|
||||
<div class="headertitle">
|
||||
<div class="title">AutoContact Member List</div> </div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
|
||||
<p>This is the complete list of members for <a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a>, including all inherited members.</p>
|
||||
<table class="directory">
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a2294ddd6bd4bda59c3453cc4dbd4f4fa">_getTopology</a>(Contact *, Component *&anchor, Horizontal **&, Vertical **&, size_t)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">static</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ab422116c7edfacedd31711c96e3ec95b">base</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#af783b79a1398450e28e2ea55c3eb8476">canDestroy</a>(unsigned int flags=0) const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a69d29e4d230a0111ca18e6e661a48f8b">canMoveUp</a>(const AutoSegment *moved) const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ac371cd5b837a8965c11297c197e70a45">checkTopology</a>()</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a91c8bc1a6bdb1b15c3c084ebfd38af47">getAllocateds</a>()</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">static</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a142af2208e8c058c672bbad3640a6c46">getAnchor</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ad4a1ca46647528c32c5fbd4c45ac866c">getAnchorHook</a>()</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a4092778435abf3fb25a986a802bdb6c6">getBodyHook</a>()</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ab5d8bf98ab5af6fcfebea1b9f446d5d7">getBoundingBox</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a798750f964050c53c269a2e56d44b690">getCBXMax</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a347244bd3f3a59881a2dee9801c74618">getCBXMin</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a4e4061a17285b0c08c31cfee65947cb6">getCBYMax</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ad7ee1befb03ee85f237a36e2f5ab8e45">getCBYMin</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ac2ba7fbe2fad7d4910aa71ee034078e7">getCenter</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ae9d087a6cd3d459d7f4bea6bc8b08b49">getConstraintBox</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ad1ef5843ef3eabe27e548f24ca222876">getDx</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ae4046e6ed80cbba54a48953ef4d2ca6d">getDy</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a819cf639562a031a1e2e061fe1293d66">getGCell</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a3ab7b800879862100636b003a5d168f3">getHalfHeight</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a5a345a7129c2a07f10f9f10c959616b9">getHalfWidth</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a3ade412549810d29d5ce3c860fc965b9">getHeight</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a1e57c42301b9e58648863e7d5dc055e7">getId</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ab045567c4f529dca7790d66c17c3084f">getLayer</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ac607a624c0698056c5bccf405cf05ea7">getLengths</a>(DbU::Unit *lengths, AutoSegment::DepthLengthSet &)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ac350bb9d2d038287530fcf474987ba55">getMaxDepth</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ada381cbb88211a7f63d30691b669b5e1">getMinDepth</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a9e76ae5cee9320b65251387419c9432b">getName</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a00ed934305dd186a284b7a13b5798cb6">getNativeConstraintBox</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a692492374623a5c6096b2c4a51190359">getNet</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a48ab1d3bdf85712e4784ef83ef136939">getOpposite</a>(const AutoSegment *) const =0</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a994371005874f946cc0ac78005d38423">getPerpandicular</a>(const AutoSegment *) const =0</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a4fa9bb12d79f6645884d567986c9b0a5">getPosition</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a50531ded68cc5206fe104b8d8bf3bd87">getSegment</a>(unsigned int) const =0</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ad59f45aaefd5acc8fb9795d4c0e49a7f">getSlaveComponents</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a00e56270cfb31f56e52e31afbc33ba71">getStaticName</a>()</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">static</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ab1fd3fec6dd56d40217b8a5ecacb1719">getUConstraints</a>(unsigned int direction) const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a9c63fe7288748eaf5332ca796a36d872">getWidth</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a00b8f54c8171f6699e57de1b8c18eeb1">getX</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a4580de6b074712e400d5d238ce3af054">getY</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#acc77b6de9050a86dc41e25888c8f81f6">hasBadTopology</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ac2fe070a286356a24baa466b4fe5b74d">intersectConstraintBox</a>(Box &box) const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#aabac50fd9b8e1bba7289573973658d18">invalidate</a>(unsigned int flags=0)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#afd7362b850709bed8b61c1aa22399f97">isFixed</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#aeb66931d535cbd3d0f9bc525968e15f5">isHTee</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a77e5036ce0c3628f5bf65e729ba875ba">isInCreationStage</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ac540608485240ff88970131ebc02c1ab">isInvalidated</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a6d1120fc8800af5d269e72ce5c3ba629">isInvalidatedCache</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ae4ba7bc2888f990818cbdb808260c47e">isTee</a>(unsigned int direction) const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a249530ac086dbf92f981887cc633facf">isTurn</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ae38846b6213cccbc6f008b175b4604b0">isVTee</a>() const</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a7fc4029992d75a62ce718e5e622f8ce9">migrateConstraintBox</a>(AutoContact *other)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ac893802d1c5518cab86f8341af817abe">restrictConstraintBox</a>(DbU::Unit constraintMin, DbU::Unit constraintMax, unsigned int flags=KbWarnOnError)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#aaa7652f5db46cab9edb066d06ea979f9">setCBXMax</a>(DbU::Unit xMax)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a9fcb986110e79bc0044f7bfe503acc0c">setCBXMin</a>(DbU::Unit xMin)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a1fdb3737d910a966e150a86d885f3c05">setCBYMax</a>(DbU::Unit yMax)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a5b598929b39ad3ec202405b31ac02b1d">setCBYMin</a>(DbU::Unit yMin)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a5e5f791613d0ef8f4cf9e7d8f35dc4c5">setConstraintBox</a>(const Box &box)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a2c83ac6a03bbac090a8ab120d62c6e44">setDx</a>(DbU::Unit)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a123478e15e2544598851d0e907212841">setDy</a>(DbU::Unit)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#aa1a02e206437f1371a74cafc724b00d7">setGCell</a>(GCell *)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a106f372cee0916ebb6544627e47bb58d">setHeight</a>(DbU::Unit)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#aad4271c35e0162c8a4d034dca07f5a4b">setLayer</a>(const Layer *)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a9881d5e969669b641c5de4f4d94e5d15">setOffset</a>(DbU::Unit dx, DbU::Unit dy)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a12d3bfdce07580db21b17cf87f912cc3">setPosition</a>(DbU::Unit width, DbU::Unit height)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a52707afec84391e898e01c75b2713d32">setPosition</a>(const Point &)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a0284fcec9bd41b26648e7bef3d4f1952">setSizes</a>(DbU::Unit width, DbU::Unit height)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a9a0ec0a0ac85f23cfad6c069ea8dade7">setWidth</a>(DbU::Unit)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a154f993d0262c92bfc0dc95154faf794">setX</a>(DbU::Unit)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#ac862ce450a533f0544d2168b132ba165">setY</a>(DbU::Unit)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">inline</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a66f92d8233776fb858075f78af451997">showTopologyError</a>(const std::string &, unsigned int flags=0)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a9161f1e2832e5e141a13863223322aa5">translate</a>(const DbU::Unit &tx, const DbU::Unit &ty)</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">virtual</span></td></tr>
|
||||
<tr class="even"><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#af6a2454547eeb7f5a519970dcb467e90">updateGeometry</a>()=0</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
|
||||
<tr><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html#a690764ddc997fe9766a79c4b8e0c3e2f">updateTopology</a>()=0</td><td class="entry"><a class="el" href="classKatabatic_1_1AutoContact.html">AutoContact</a></td><td class="entry"><span class="mlabel">pure virtual</span></td></tr>
|
||||
</table></div><!-- contents -->
|
||||
<br>
|
||||
<hr>
|
||||
<table class="footer1">
|
||||
<tr>
|
||||
<td class="LFooter"><small>Generated by doxygen 1.8.14 on Sun Nov 21 2021</small></td>
|
||||
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="footer2">
|
||||
<tr>
|
||||
<td class="LFooter">Katabatic - Routing Toolbox</td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2020 Sorbonne Universite. All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|