coriolis/crlcore/python/helpers/Alliance.py

228 lines
8.8 KiB
Python
Raw Normal View History

# -*- Mode:Python; explicit-buffer-name: "Alliance.py<crlcore/helpers>" -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2012-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./crlcore/helpers/Alliance.py" |
# +-----------------------------------------------------------------+
import os
import os.path
import sys
import Hurricane
from Hurricane import DbU
from Hurricane import DataBase
from Hurricane import Layer
import CRL
from CRL import Environment
from CRL import AllianceFramework
from CRL import RoutingGauge
from CRL import RoutingLayerGauge
from CRL import CellGauge
import helpers
from helpers import ErrorMessage
from helpers import Debug
allianceFile = '<allianceFile has not been set>'
class AddMode ( object ):
Append = 1
Prepend = 2
Replace = 3
@staticmethod
def toEnvironment ( mode ):
if mode == AddMode.Prepend: return Environment.Prepend
if mode == AddMode.Replace: return Environment.Replace
return Environment.Append
class Gauge ( object ):
Vertical = 1
Horizontal = 2
PinOnly = 3
Default = 4
@staticmethod
def toRlGauge ( value ):
if value == Gauge.Vertical: return RoutingLayerGauge.Vertical
if value == Gauge.Horizontal: return RoutingLayerGauge.Horizontal
if value == Gauge.PinOnly: return RoutingLayerGauge.PinOnly
if value == Gauge.Default: return RoutingLayerGauge.Default
return None
def xmlToConf ( xmlPath ):
hasExtention = False
components = xmlPath.split(os.sep)
filename = components[-1]
if filename.endswith('.xml'):
hasExtention = True
filename = filename[:-4]
if filename.endswith('.conf'):
hasExtention = True
filename = filename[:-5]
filename = filename.replace('.','_')
confPath = os.sep.join(components[:-1] + [filename])
if hasExtention:
confPath += '.conf'
return confPath
def _loadAllianceConfig ( af, allianceConfig ):
env = af.getEnvironment()
entryNo = 0
for entry in allianceConfig:
entryNo += 1
try:
if len(entry) != 2:
raise ErrorMessage(1,['Malformed entry in <allianceConfig>.'
,'Must have exactly two fields ("key", <value>).'
,str(entry)
])
key, value = entry
if key == 'DISPLAY': env.setDISPLAY(value)
if key == 'CATALOG': env.setCATALOG(value)
if key == 'SCALE_X': env.setSCALE_X(value)
if key == 'IN_LO': env.setIN_LO(value)
if key == 'IN_PH': env.setIN_PH(value)
if key == 'OUT_PH': env.setOUT_PH(value)
if key == 'OUT_LO': env.setOUT_LO(value)
if key == 'POWER': env.setPOWER(value)
if key == 'GROUND': env.setGROUND(value)
if key == 'CLOCK': env.setCLOCK(value)
if key == 'BLOCKAGE': env.setBLOCKAGE(value)
Correction in plugins to support msxlib compatible pads. * New: In CRL Core, in helpers & alliance.conf, set and read a "PAD" variable to define the pad model name extension ("px" for "sxlib and "pxr" for vsxlib, this is provisional). * New: In CRL Core, in plugin.conf, add parameters to define the name of used for power & clock supply. We may remove the extention in the future (to be more coherent with the previous modification). * New: In Cumulus, in chip.Configuration.GaugeConf._rpAccess(), no longer place the accessing contact *at the center* of the RoutingPad. It works under sxlib because buffers & registers all have same size terminals. But this is not true under vsxlib, leading to misaligned contacts & wires. Now systematically place on the slice midlle track (maybe with one pitch above or below). This is still very weak as we do not check if the terminal reach were the contact is being put. Has to be strenthened in the future. * New: In Cumulus, in chip.Configuration.ChipConf, read the new clock & power pad parameters. * Change: In Isobar (and all other Python wrappers), uses PyLong instead of PyInt for DbU conversions. In PyHurricane argument converter, automatically check for both PyLong and then PyInt. * Change: In Cumulus, in chip.PadsCorona, more accurate error message in case of discrepency in global net connections (i.e. no net of the same name in instance model and instance model owner. * Change: In Kite, in BuildPowerRails, when looking up at the pads model name to find "pck_" or "pvddeck_", do not compare the extension part. But we still use hard-coded stem pad names, maybe we shouldn't. * Bug: In Katabatic, in GCellConfiguration::_do_xG_xM1_xM3(), there was a loop in the search of the best N/E initial RoutingPad. * Bug: In Kite, in KiteEngine::protectRoutingPads(), *do not* protect RoutingPads of fixed nets, they are already through the BuildPowerRails stage (and it's causing scary overlap warning messages). * Bug: In Cumulus, in ClockTree.HTreeNode.addLeaf(), do not create deep-plug when the core is flat (not sub-modules). All the new nets are at core level. * Bug: In Cumulus, in ChipPlugin.PlaceCore.doFloorplan(), ensure that the core is aligned on the GCell grid (i.e. the slice grid of the overall chip). * Bug: In Kite, in GCellTopology::_do_xG_xM1_xM3(), infinite loop while looking for the bigger N-E RoutingPad. Forgot to decrement the index...
2014-09-13 10:45:30 -05:00
if key == 'PAD': env.setPad(value)
if key == 'WORKING_LIBRARY': env.setWORKING_LIBRARY(value)
if key == 'SYSTEM_LIBRARY':
for libraryEntry in value:
if len(libraryEntry) != 2:
raise ErrorMessage(1,['Malformed system library entry in <allianceConfig>.'
,'Must have exactly two fields ("path", <mode>).'
,str(libraryEntry)
])
libPath, mode = libraryEntry
env.addSYSTEM_LIBRARY(library=libPath,mode=AddMode.toEnvironment(mode))
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<Alliance> at index %d.' % (allianceFile,entryNo))
try:
env.validate()
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<Alliance>.' % (allianceFile))
sys.exit(1)
return
def loadRoutingGaugesTable ( routingGaugesTable, fromFile ):
global allianceFile
allianceFile = fromFile
af = AllianceFramework.get()
for gaugeName in routingGaugesTable.keys():
gaugeDatas = routingGaugesTable[gaugeName]
technology = DataBase.getDB().getTechnology()
gauge = RoutingGauge.create(gaugeName)
entryNo = 0
for entry in gaugeDatas:
entryNo += 1
try:
if len(entry) != 2:
Basic support for FreePDK 45 completed. * New: In Commons, inspector support for std::pair<T,U>. * New: In Hurricane::Layer, ContactLayer & ViaLayer, support for non square VIAs. The hole (cut) remains square, but the various metal extensions can now be different in X and Y. The ::getEnclosure() method now takes a flag EnclosureH / EnclosureV. * New: In Hurricane::DbU, inspector support for: std::pair<DbU::Unit,DbU::Unit> std::array<DbU::Unit,3> Must be defined here as DbU do not exists yet in Commons.h * Bug: In Hurricane::Interval::getSize(), when the interval is "full span", do not return the difference between min and max, but directly DbU::Max. (the previous result was -1 !) * New: In CRL Core Python/Technology.py, support for non square VIAs in the configuration files. Applied to FreePDK 45. * New: In CRL::RoutingGauge, added a "symbolic" flag to tell if a gauge is for symbolic layout or not. Exported to Python. * New: In Anabatic::AutoHorizontal::updatePosition(), differentiated computation for soure or target taking account of the VIA extension in the right segment metal (due to non-square VIAs). * Change: In Anabatic::AutoHorizontal::_makeDogleg(), the dogleg is UP for HV gauges and DOWN for VH. * New: In Anabatic::AutoSegment::_initialize(), create a cache of the various extension length for each layer (viaToTop, viaToBottom, viaToSame). New implementation of getExtensionCap() using the previous cached extension table. See updatePositions(). New static functions to access the extension cache in the header: getViaTotopCap() ... * Change: In Anabatic::AutoSegment, in various update methods, updateOrient() must always be called *before* updatePositions() as extensions are dependant on source/target. * New: In Anabatic::AutoSegment::getEndAxes() compute the position of the first source and last target position (center/axes) on an *aligned* set of segments. * New: In Anabatic::AutoSegment, add a new state flag SegAxisFixed to signal segments that can be put on only one track. Specific case to VH gauge for a M1 vertical terminal with a M2 vertical segment. The M2 is effectively bound to the M1 axis position. * Bug: In Anabatic::NetBuilderVH::_do_xG_xM1_xM3(), in case of E/W global and only one RoutingPad the connexion to the RoutingPad was duplicated. It was valid, but totally stupid. * Bug: In Anabatic::Session::_canonize(), for an aligned segment set, intersect the user constraints from all segments instead of only considering the canonical one. Issue a warning about too tight constraints only for symbolic gauges. It may be correct for the real ones. * New: In Katata::DataNegociate::update(), more accurate computation of the perpandicular free interval. Use segment extension cap calculation. Create a special case for fixed axis segments allowing them to find alternative free interval, try under source and under target as they are likely to be draggable segments. * Change: In Katana::Manipulator::relax(), use the extension cap value to compute the axis of the perpandicular segemnts. * Change: In Katana::Manipulator::moveUp(), now move up the whole set of aligned segments instead of just the canonical one. * Change: In Katana::NegociateWindow::loadRoutingPads(), more accurate TrackMarkers insertions for fixed terminals. * New: In Katana::RoutingEvent::Key::Compare::operator(), segments with fixed axis are processed prior to any others. * New: In Katana::RoutingEventLoop, store segment pointers instead of ids to generate more accurate error messages. * Change: In Katana::RoutingPlane::create(), perform local track assignment only for HV gauges. * Change: In Katana::SegmentFsm::_slackenLocal(), add a "dragMinimize" step in the automaton. Mutliple states transitions can occurs in a row if an action fails. * New: In Katana::Session::_toIntervalAxis(), normalize interval bounds so they are on track positions (by shrinking the interval). * Bug: In Katana::TrackMarker CTOR, the weigh computation was wrong.
2018-02-17 13:27:38 -06:00
raise ErrorMessage(1,['Malformed entry in <routingGaugesTable[%s]>.' % gaugeName
,'Must have exactly two fields ("METAL_LAYER", (parameters_list)).'
,str(entry)
])
if entry[0] == 'symbolic':
gauge.setSymbolic( entry[1] )
continue
if len(entry[1]) != 9:
Basic support for FreePDK 45 completed. * New: In Commons, inspector support for std::pair<T,U>. * New: In Hurricane::Layer, ContactLayer & ViaLayer, support for non square VIAs. The hole (cut) remains square, but the various metal extensions can now be different in X and Y. The ::getEnclosure() method now takes a flag EnclosureH / EnclosureV. * New: In Hurricane::DbU, inspector support for: std::pair<DbU::Unit,DbU::Unit> std::array<DbU::Unit,3> Must be defined here as DbU do not exists yet in Commons.h * Bug: In Hurricane::Interval::getSize(), when the interval is "full span", do not return the difference between min and max, but directly DbU::Max. (the previous result was -1 !) * New: In CRL Core Python/Technology.py, support for non square VIAs in the configuration files. Applied to FreePDK 45. * New: In CRL::RoutingGauge, added a "symbolic" flag to tell if a gauge is for symbolic layout or not. Exported to Python. * New: In Anabatic::AutoHorizontal::updatePosition(), differentiated computation for soure or target taking account of the VIA extension in the right segment metal (due to non-square VIAs). * Change: In Anabatic::AutoHorizontal::_makeDogleg(), the dogleg is UP for HV gauges and DOWN for VH. * New: In Anabatic::AutoSegment::_initialize(), create a cache of the various extension length for each layer (viaToTop, viaToBottom, viaToSame). New implementation of getExtensionCap() using the previous cached extension table. See updatePositions(). New static functions to access the extension cache in the header: getViaTotopCap() ... * Change: In Anabatic::AutoSegment, in various update methods, updateOrient() must always be called *before* updatePositions() as extensions are dependant on source/target. * New: In Anabatic::AutoSegment::getEndAxes() compute the position of the first source and last target position (center/axes) on an *aligned* set of segments. * New: In Anabatic::AutoSegment, add a new state flag SegAxisFixed to signal segments that can be put on only one track. Specific case to VH gauge for a M1 vertical terminal with a M2 vertical segment. The M2 is effectively bound to the M1 axis position. * Bug: In Anabatic::NetBuilderVH::_do_xG_xM1_xM3(), in case of E/W global and only one RoutingPad the connexion to the RoutingPad was duplicated. It was valid, but totally stupid. * Bug: In Anabatic::Session::_canonize(), for an aligned segment set, intersect the user constraints from all segments instead of only considering the canonical one. Issue a warning about too tight constraints only for symbolic gauges. It may be correct for the real ones. * New: In Katata::DataNegociate::update(), more accurate computation of the perpandicular free interval. Use segment extension cap calculation. Create a special case for fixed axis segments allowing them to find alternative free interval, try under source and under target as they are likely to be draggable segments. * Change: In Katana::Manipulator::relax(), use the extension cap value to compute the axis of the perpandicular segemnts. * Change: In Katana::Manipulator::moveUp(), now move up the whole set of aligned segments instead of just the canonical one. * Change: In Katana::NegociateWindow::loadRoutingPads(), more accurate TrackMarkers insertions for fixed terminals. * New: In Katana::RoutingEvent::Key::Compare::operator(), segments with fixed axis are processed prior to any others. * New: In Katana::RoutingEventLoop, store segment pointers instead of ids to generate more accurate error messages. * Change: In Katana::RoutingPlane::create(), perform local track assignment only for HV gauges. * Change: In Katana::SegmentFsm::_slackenLocal(), add a "dragMinimize" step in the automaton. Mutliple states transitions can occurs in a row if an action fails. * New: In Katana::Session::_toIntervalAxis(), normalize interval bounds so they are on track positions (by shrinking the interval). * Bug: In Katana::TrackMarker CTOR, the weigh computation was wrong.
2018-02-17 13:27:38 -06:00
raise ErrorMessage(1,['Malformed entry in <routingGaugesTable[%s]>.' % gaugeName
,'Parameters list must have exactly nine fields:'
,' (direction, type, depth, density, offset, pitch, wire_width, via_width, obs_dw)'
,str(entry)
])
gauge.addLayerGauge( RoutingLayerGauge.create( technology.getLayer(entry[0])
, Gauge.toRlGauge(entry[1][0]) # Direction.
, Gauge.toRlGauge(entry[1][1]) # Type.
, entry[1][2] # Depth.
, entry[1][3] # Density.
, helpers.toDbU(entry[1][4]) # Offset.
, helpers.toDbU(entry[1][5]) # Pitch.
, helpers.toDbU(entry[1][6]) # Wire width.
, helpers.toDbU(entry[1][7]) # Via width.
, helpers.toDbU(entry[1][8]) # Obstacle dW.
) )
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<routingGaugesTable> at index %d.' % (allianceFile,entryNo))
af.addRoutingGauge(gauge)
return
def loadCellGaugesTable ( cellGaugesTable, fromFile ):
global allianceFile
allianceFile = fromFile
af = AllianceFramework.get()
for gaugeName in cellGaugesTable.keys():
gaugeDatas = cellGaugesTable[gaugeName]
gauge = None
try:
if len(gaugeDatas) != 4:
raise ErrorMessage(1,['Malformed gaugeDatas in <cellGaugesTable[%s]>.' % gaugeName
,'Parameters list must have exactly four fields:'
,' (terminal_metal, xy_common_pitch, slice_height, slice_step)'
,str(gaugeDatas)
])
gauge = CellGauge.create( gaugeName
, gaugeDatas[0] # pinLayerName.
, helpers.toDbU(gaugeDatas[1]) # pitch.
, helpers.toDbU(gaugeDatas[2]) # sliceHeight.
, helpers.toDbU(gaugeDatas[3]) # sliceStep.
)
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<cellGaugesTable> at index %d.' % (allianceFile,gaugeDatasNo))
if gauge: af.addCellGauge(gauge)
return
def loadAllianceConfig ( table, fromFile ):
global allianceFile
allianceFile = fromFile
af = AllianceFramework.get()
db = DataBase.getDB()
technology = db.getTechnology()
if not technology:
technology = Hurricane.Technology.create(db,'Alliance')
_loadAllianceConfig( af, table )
env = af.getEnvironment()
return