diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index d0389c66..19dd5a0e 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -107,8 +107,8 @@ namespace Anabatic { _rg = rg->getClone(); _allowedDepth = rg->getDepth()-1; - if (Cfg::hasParameter("katabatic.topRoutingLayer")) - _setTopRoutingLayer( Cfg::getParamString("katabatic.topRoutingLayer")->asString() ); + if (Cfg::hasParameter("anabatic.topRoutingLayer")) + _setTopRoutingLayer( Cfg::getParamString("anabatic.topRoutingLayer")->asString() ); _gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh"); _gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv"); diff --git a/crlcore/etc/symbolic/cmos/plugins.conf b/crlcore/etc/symbolic/cmos/plugins.conf index 497dd405..16f3340a 100644 --- a/crlcore/etc/symbolic/cmos/plugins.conf +++ b/crlcore/etc/symbolic/cmos/plugins.conf @@ -19,7 +19,7 @@ parametersTable = \ , ('chip.pad.pvssick' , TypeString, 'pvssick_px') , ('chip.pad.pvddeck' , TypeString, 'pvddeck_px') , ('chip.pad.pvsseck' , TypeString, 'pvsseck_px') - , ('clockTree.minimumSide' , TypeInt , 300) + , ('clockTree.minimumSide' , TypeInt , l(600)) , ('clockTree.buffer' , TypeString, 'buf_x2') , ('clockTree.placerEngine' , TypeString, 'Etesian') ) diff --git a/crlcore/etc/symbolic/cmos/technology.conf b/crlcore/etc/symbolic/cmos/technology.conf index 8bdfb8ca..ae23b8e9 100644 --- a/crlcore/etc/symbolic/cmos/technology.conf +++ b/crlcore/etc/symbolic/cmos/technology.conf @@ -14,13 +14,13 @@ from helpers.Technology import initTechno # - # - -initTechno( { 'name' : 'cmos45' +initTechno( { 'name' : 'cmos' , 'precision' : 2 - , 'gridValue' : 0.005 + , 'gridValue' : 0.5 , 'gridUnit' : DbU.UnitPowerMicro - , 'gridsPerLambda' : 24 + , 'gridsPerLambda' : 2 , 'symbolicGridStep' : 1.0 - , 'polygonStep' : 24.0 + , 'polygonStep' : 2.0 } ) execfile( sysConfDir+'/common/technology.conf' ) @@ -42,21 +42,21 @@ layersExtensionsTable = symbolicLayersExtensionsTable gdsLayersTable = \ - ( ("nWell" , "NWELL" , 3, 0) - , ("nImplant", "NPLUS" , 26, 0) - , ("pImplant", "PPLUS" , 25, 0) - , ("active" , "ACTIVE" , 6, 0) - , ("poly" , "POLY" , 17, 0) - , ("cut0" , "CONTACT", 30, 0) - , ("metal1" , "METAL1" , 31, 0) - , ("cut1" , "VIA1" , 51, 0) - , ("metal2" , "METAL2" , 32, 0) - , ("cut2" , "VIA2" , 52, 0) - , ("metal3" , "METAL3" , 33, 0) - , ("cut3" , "VIA3" , 53, 0) - , ("metal4" , "METAL4" , 34, 0) - , ("cut4" , "VIA4" , 54, 0) - , ("metal5" , "METAL5" , 35, 0) - , ("cut5" , "VIA5" , 55, 0) - , ("metal6" , "METAL6" , 36, 0) + ( ("nWell" , "LNWELL" , 1, 0) + , ("nImplant", "LNIF" , 3, 0) + , ("pImplant", "LPDIF" , 4, 0) + , ("active" , "LACTIVE" , 2, 0) + , ("poly" , "LPOLY" , 7, 0) + , ("cut0" , "LCONT" , 10, 0) + , ("metal1" , "LALU1" , 11, 0) + , ("cut1" , "LVIA" , 14, 0) + , ("metal2" , "LALU2" , 16, 0) + , ("cut2" , "LVIA2" , 18, 0) + , ("metal3" , "LALU3" , 19, 0) + , ("cut3" , "LVIA3" , 21, 0) + , ("metal4" , "LALU4" , 22, 0) + , ("cut4" , "LVIA4" , 25, 0) + , ("metal5" , "LALU5" , 26, 0) + , ("cut5" , "LVIA5" , 28, 0) + , ("metal6" , "LALU6" , 29, 0) ) diff --git a/crlcore/etc/symbolic/cmos45/plugins.conf b/crlcore/etc/symbolic/cmos45/plugins.conf index e97203d0..f8eb86d8 100644 --- a/crlcore/etc/symbolic/cmos45/plugins.conf +++ b/crlcore/etc/symbolic/cmos45/plugins.conf @@ -1,6 +1,7 @@ # -*- Mode:Python; explicit-buffer-name: "plugins.conf" -*- import helpers +from helpers import l, u, n # Contains the layout (shared by all technologies). #execfile( helpers.sysConfDir+'/common/plugins.conf' ) @@ -11,17 +12,17 @@ import helpers # # Parameters for chip plugin. parametersTable = \ - ( ("chip.block.rails.count" , TypeInt , 5 ) - , ("chip.block.rails.hWidth" , TypeInt , 24 ) - , ("chip.block.rails.vWidth" , TypeInt , 24 ) - , ("chip.block.rails.hSpacing" , TypeInt , 12 ) - , ("chip.block.rails.vSpacing" , TypeInt , 12 ) + ( ("chip.block.rails.count" , TypeInt , l(5 ) ) + , ("chip.block.rails.hWidth" , TypeInt , l(24) ) + , ("chip.block.rails.vWidth" , TypeInt , l(24) ) + , ("chip.block.rails.hSpacing" , TypeInt , l(12) ) + , ("chip.block.rails.vSpacing" , TypeInt , l(12) ) , ('chip.pad.pck' , TypeString, 'pck_mpx') , ('chip.pad.pvddick' , TypeString, 'pvddick_mpx') , ('chip.pad.pvssick' , TypeString, 'pvssick_mpx') , ('chip.pad.pvddeck' , TypeString, 'pvddeck_mpx') , ('chip.pad.pvsseck' , TypeString, 'pvsseck_mpx') - , ('clockTree.minimumSide' , TypeInt , 1000) + , ('clockTree.minimumSide' , TypeInt , l(1000)) , ('clockTree.buffer' , TypeString, 'buf_x2') , ('clockTree.placerEngine' , TypeString, 'Etesian') ) diff --git a/crlcore/python/CMakeLists.txt b/crlcore/python/CMakeLists.txt index 6c7f86e1..e61239ac 100644 --- a/crlcore/python/CMakeLists.txt +++ b/crlcore/python/CMakeLists.txt @@ -1,6 +1,7 @@ install( FILES coriolisInit.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore ) install( FILES helpers/__init__.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers ) + install( FILES helpers/io.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers ) install( FILES helpers/Configuration.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers ) install( FILES helpers/Alliance.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers ) install( FILES helpers/Display.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers ) diff --git a/crlcore/python/coriolisInit.py b/crlcore/python/coriolisInit.py index 1385e0f6..aa935bd8 100644 --- a/crlcore/python/coriolisInit.py +++ b/crlcore/python/coriolisInit.py @@ -11,8 +11,8 @@ try: from CRL import Environment from CRL import RoutingLayerGauge from helpers import Configuration - from helpers import ErrorMessage - from helpers import WarningMessage + from helpers.io import ErrorMessage + from helpers.io import WarningMessage #from helpers import Devices from helpers.Configuration import TypeBool from helpers.Configuration import TypeInt diff --git a/crlcore/python/helpers/Alliance.py b/crlcore/python/helpers/Alliance.py index 058af2a4..69a6538a 100644 --- a/crlcore/python/helpers/Alliance.py +++ b/crlcore/python/helpers/Alliance.py @@ -18,18 +18,18 @@ 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 +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 +from helpers.io import ErrorMessage +from helpers import Debug allianceFile = '' @@ -103,12 +103,16 @@ def _loadAllianceConfig ( af, allianceConfig ): env.addSYSTEM_LIBRARY(library=libPath,mode=AddMode.toEnvironment(mode)) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at index %d.' % (allianceFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at index %d.' % (allianceFile,entryNo) ) + print e try: - env.validate() + env.validate() except Exception, e: - ErrorMessage.wrapPrint(e,'In %s:.' % (allianceFile)) - sys.exit(1) + e = ErrorMessage( e ) + e.addMessage( 'In %s:.' % (allianceFile) ) + print e + sys.exit(1) return @@ -159,7 +163,9 @@ def loadRoutingGaugesTable ( routingGaugesTable, fromFile ): ) ) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at index %d.' % (allianceFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at index %d.' % (allianceFile,entryNo) ) + print e af.addRoutingGauge(gauge) return @@ -189,8 +195,10 @@ def loadCellGaugesTable ( cellGaugesTable, fromFile ): , gaugeDatas[3] # sliceStep. ) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at index %d.' % (allianceFile,gaugeDatasNo)) - + e = ErrorMessage( e ) + e.addMessage( 'In %s: at index %d.' % (allianceFile,gaugeDatasNo) ) + print e + if gauge: af.addCellGauge(gauge) return diff --git a/crlcore/python/helpers/AnalogTechno.py b/crlcore/python/helpers/AnalogTechno.py index bb14270c..cc8c4170 100644 --- a/crlcore/python/helpers/AnalogTechno.py +++ b/crlcore/python/helpers/AnalogTechno.py @@ -21,7 +21,7 @@ import Hurricane from Hurricane import DbU from Hurricane import DataBase from Hurricane import Layer -from helpers import ErrorMessage +from helpers.io import ErrorMessage from helpers import Debug @@ -105,7 +105,9 @@ def _loadAnalogTechno ( techno, ruleTable ): , entry[5] ) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at index %d.' % (technoFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at index %d.' % (technoFile,entryNo) ) + print e return diff --git a/crlcore/python/helpers/Configuration.py b/crlcore/python/helpers/Configuration.py index c1f3be87..57ed187b 100644 --- a/crlcore/python/helpers/Configuration.py +++ b/crlcore/python/helpers/Configuration.py @@ -6,8 +6,8 @@ import os.path import sys import Cfg import helpers -from helpers import ErrorMessage -from helpers import Debug +from helpers.io import ErrorMessage +from helpers import Debug confFile = '' @@ -123,7 +123,9 @@ def loadParameters ( parametersData, fromFile ): param.flags = options[key] except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at index %d.' % (confFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at index %d.' % (confFile,entryNo) ) + print e return @@ -198,5 +200,7 @@ def loadLayout ( layoutData, fromFile ): layout.addParameter ( tabName, pathName, text, column, span, flags ) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at index %d.' % (confFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at index %d.' % (confFile,entryNo) ) + print e return diff --git a/crlcore/python/helpers/Devices.py b/crlcore/python/helpers/Devices.py index d6b224f3..a4b3ff5b 100644 --- a/crlcore/python/helpers/Devices.py +++ b/crlcore/python/helpers/Devices.py @@ -17,9 +17,9 @@ import os import os.path import sys -from Hurricane import DataBase -from helpers import ErrorMessage -from helpers import Debug +from Hurricane import DataBase +from helpers.io import ErrorMessage +from helpers import Debug devicesFile = '' @@ -89,7 +89,9 @@ def _loadDevices ( techno, ruleTable ): for layout in entry['layouts']: devDesc.addLayout( layout[0], layout[1] ) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at index %d.' % (devicesFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at index %d.' % (devicesFile,entryNo) ) + print e return diff --git a/crlcore/python/helpers/Display.py b/crlcore/python/helpers/Display.py index adb28d16..c85fa737 100644 --- a/crlcore/python/helpers/Display.py +++ b/crlcore/python/helpers/Display.py @@ -7,8 +7,8 @@ import sys import string import Cfg import Viewer -from helpers import ErrorMessage -from helpers import WarningMessage +from helpers.io import ErrorMessage +from helpers.io import WarningMessage from helpers import Debug from helpers.Patterns import patternsLUT @@ -238,7 +238,9 @@ def loadStyleTuple ( styleTuple ): footer = 'In %s::"%s" at index %d.' % (displayFile,style.getName(),entryNo) else: footer = 'In %s: at index %d.' % (displayFile,entryNo) - ErrorMessage.wrapPrint(e,footer) + e = ErrorMessage( e ) + e.addMessage( footer ) + print e if not style: break if style != None: @@ -271,7 +273,9 @@ def loadStyles ( stylesTable, fromFile ): ,'(putting a level of parenthesis do not create a tuple for one item)' ,'In %s:.' % displayFile ] - ErrorMessage.wrapPrint(e, styleTableExample) + e = ErrorMessage( e ) + e.addMessage( styleTableExample ) + print e return diff --git a/crlcore/python/helpers/Patterns.py b/crlcore/python/helpers/Patterns.py index f7fd297e..ae87efe3 100755 --- a/crlcore/python/helpers/Patterns.py +++ b/crlcore/python/helpers/Patterns.py @@ -3,8 +3,8 @@ import sys import math -from helpers import ErrorMessage -from helpers import WarningMessage +from helpers.io import ErrorMessage +from helpers.io import WarningMessage confFile = '' @@ -175,7 +175,9 @@ def loadPatterns ( patternsData, fromFile ): except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at index %d.' % (confFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at index %d.' % (confFile,entryNo) ) + print e return diff --git a/crlcore/python/helpers/Technology.py b/crlcore/python/helpers/Technology.py index 75821399..8ce6d99c 100644 --- a/crlcore/python/helpers/Technology.py +++ b/crlcore/python/helpers/Technology.py @@ -5,18 +5,18 @@ import os.path import string import traceback import Hurricane -from Hurricane import DbU -from Hurricane import DataBase -from Hurricane import Technology -from Hurricane import Layer -from Hurricane import BasicLayer -from Hurricane import DiffusionLayer -from Hurricane import TransistorLayer -from Hurricane import RegularLayer -from Hurricane import ContactLayer -from Hurricane import ViaLayer -from CRL import AllianceFramework -from helpers import ErrorMessage +from Hurricane import DbU +from Hurricane import DataBase +from Hurricane import Technology +from Hurricane import Layer +from Hurricane import BasicLayer +from Hurricane import DiffusionLayer +from Hurricane import TransistorLayer +from Hurricane import RegularLayer +from Hurricane import ContactLayer +from Hurricane import ViaLayer +from CRL import AllianceFramework +from helpers.io import ErrorMessage technologyFile = '' @@ -132,7 +132,9 @@ def loadRealLayers ( realLayersTable, confFile ): routingLayer.setBlockageLayer(basicLayer) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at entry %d.' % (technologyFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at entry %d.' % (technologyFile,entryNo) ) + print e return @@ -197,7 +199,9 @@ def loadCompositeLayers ( compositeLayersData, confFile ): layersLUT.add( compositeLayer ) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at entry %d.' % (technologyFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at entry %d.' % (technologyFile,entryNo) ) + print e return @@ -270,7 +274,9 @@ def loadLayersExtensions ( layersExtensionsTable, confFile ): ]) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at entry %d.' % (technologyFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at entry %d.' % (technologyFile,entryNo) ) + print e return @@ -287,7 +293,9 @@ def tagSymbolicLayers ( symbolicLayersTable, confFile ): layersLUT.lookup(layerName,LayersLUT.Real|LayersLUT.Composite|LayersLUT.MissingError) technology.setSymbolicLayer(layerName) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at entry %d.' % (technologyFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at entry %d.' % (technologyFile,entryNo) ) + print e return @@ -331,7 +339,9 @@ def loadGdsLayers ( realLayersTable, confFile ): basicLayer.setGds2Datatype( gdsiiDatatype ) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at entry %d.' % (technologyFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at entry %d.' % (technologyFile,entryNo) ) + print e return @@ -414,6 +424,7 @@ def initTechno ( technoConfig ): DbU.setSymbolicSnapGridStep( DbU.fromLambda(gridStep) ) except Exception, e: - ErrorMessage.wrapPrint(e) + e = ErrorMessage( e ) + print e return diff --git a/crlcore/python/helpers/__init__.py b/crlcore/python/helpers/__init__.py index 4a518f80..7aed46b2 100644 --- a/crlcore/python/helpers/__init__.py +++ b/crlcore/python/helpers/__init__.py @@ -24,6 +24,7 @@ import os.path import re import traceback import Hurricane +import helpers.io quiet = False sysConfDir = None @@ -58,126 +59,66 @@ def truncPath ( path, maxlength=80 ): return '...' + os.sep + trunc -def showPythonTrace ( scriptPath=None, e=None, tryContinue=True ): - if scriptPath: - print '[ERROR] An exception occured while loading the Python script module:' - print ' \"%s\"\n' % (scriptPath) - print ' You should check for simple python errors in this module.\n' +def textStackTrace ( trace, showIndent=True, scriptPath=None ): + indent = '' + if showIndent: indent = ' ' - print ' Python stack trace:' - trace = traceback.extract_tb( sys.exc_info()[2] ) + s = '' + if scriptPath: + if len(scriptPath) > 70: + filename = scriptPath[-70:] + filename = '.../' + filename[ filename.find('/')+1 : ] + + if showIndent: s += '[ERROR] ' + s += 'An exception occured while loading the Python script module:\n' + s += indent + '\"%s\"\n' % (filename) + s += indent + 'You should check for simple python errors in this module.\n\n' + + s += indent + 'Python stack trace:\n' maxdepth = len( trace ) for depth in range( maxdepth ): filename, line, function, code = trace[ maxdepth-depth-1 ] if len(filename) > 38: filename = filename[-38:] filename = '.../' + filename[ filename.find('/')+1 : ] - #print ' [%02d] %45s:%-5d in \"%s()\"' % ( maxdepth-depth-1, filename, line, function ) - print ' #%d in %25s() at %s:%d' % ( depth, function, filename, line ) + #s += indent + '[%02d] %45s:%-5d in \"%s()\"' % ( maxdepth-depth-1, filename, line, function ) + s += indent + '#%d in %25s() at %s:%d\n' % ( depth, function, filename, line ) + return s - if e: - print ' Error was:' - print ' %s\n' % e - if tryContinue: - print ' Trying to continue anyway...' +def showStackTrace ( trace ): + print textStackTrace( trace, True ) return -class ErrorMessage ( Exception ): +def textPythonTrace ( scriptPath=None, e=None, tryContinue=True ): + s = '' + if scriptPath: + if len(scriptPath) > 70: + filename = scriptPath[-70:] + filename = '.../' + filename[ filename.find('/')+1 : ] + else: + filename = scriptPath + s += '[ERROR] An exception occured while loading the Python script module:\n' + s += ' \"%s\"\n' % (filename) + s += ' You should check for simple python errors in this module.\n' - def __init__ ( self, code, *arguments ): - self._code = code - self._errors = [ 'Malformed call to ErrorMessage()' - , '%s' % str(arguments) ] + if isinstance(e,helpers.io.ErrorMessage): trace = e.trace() + else: trace = sys.exc_info()[2] + s += textStackTrace( traceback.extract_tb( trace ) ) - text = None - if len(arguments) == 1: - if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n') - else: - self._errors = arguments[0] - elif len(arguments) > 1: - text = list(arguments) + if e: + s += ' Error was:' + s += ' %s\n' % e - if text: - self._errors = [] - while len(text[0]) == 0: del text[0] - - lstrip = 0 - if text[0].startswith('[ERROR]'): lstrip = 8 - - for line in text: - if line[0:lstrip ] == ' '*lstrip or \ - line[0:lstrip-1] == '[ERROR]': - self._errors += [ line[lstrip:] ] - else: - self._errors += [ line.lstrip() ] - return - - def __str__ ( self ): - if not isinstance(self._errors,list): - return "[ERROR] %s" % self._errors - - formatted = "\n" - for i in range(len(self._errors)): - if i == 0: formatted += "[ERROR] %s" % self._errors[i] - else: formatted += " %s" % self._errors[i] - if i+1 < len(self._errors): formatted += "\n" - return formatted - - def addMessage ( self, message ): - if not isinstance(self._errors,list): - self._errors = [ self._errors ] - if isinstance(message,list): - for line in message: - self._errors += [ line ] - else: - self._errors += [ message ] - return - - def terminate ( self ): - print self - sys.exit(self._code) - - def _getCode ( self ): return self._code - - code = property(_getCode) - - @staticmethod - def wrapPrint ( e, footer=None ): - showTrace = False - if not isinstance(e,ErrorMessage): - if isinstance(e,Hurricane.ConstructorError) or \ - isinstance(e,Hurricane.HurricaneError): - ewrap = ErrorMessage(1,e) - else: - ewrap = ErrorMessage(3,'An unmanaged Python exception occurred:') - ewrap.addMessage(str(e)) - showTrace = True - else: - ewrap = e - if footer: ewrap.addMessage(footer) - print ewrap - if showTrace: showPythonTrace() - return + if tryContinue: + s += ' Trying to continue anyway...' + return s -class WarningMessage ( Exception ): - - def __init__ ( self, message ): - self._warnings = message - return - - def __str__ ( self ): - if not isinstance(self._warnings,list): - return "[WARNING] %s" % self._warnings - - formatted = "\n" - for i in range(len(self._warnings)): - if i == 0: formatted += "[WARNING] %s" % self._warnings[i] - else: formatted += " %s" % self._warnings[i] - if i+1 < len(self._warnings): formatted += "\n" - return formatted +def showPythonTrace ( scriptPath=None, e=None, tryContinue=True ): + print textPythonTrace( scriptPath, e, tryContinue ) + return class Dots ( object ): diff --git a/crlcore/python/helpers/io.py b/crlcore/python/helpers/io.py new file mode 100644 index 00000000..e74d8190 --- /dev/null +++ b/crlcore/python/helpers/io.py @@ -0,0 +1,256 @@ +# -*- mode:Python; explicit-buffer-name: "io.py" -*- +# +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2012-2018, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | C o r i o l i s / C h a m s B u i l d e r | +# | | +# | Author : Jean-Paul Chaput | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./crlcore/helpers/io.py" | +# +-----------------------------------------------------------------+ + +import sys +import os +import os.path +import re +import traceback +from PyQt4.QtCore import Qt +from PyQt4.QtGui import QSizePolicy +from PyQt4.QtGui import QDialog +from PyQt4.QtGui import QPalette +from PyQt4.QtGui import QColor +from PyQt4.QtGui import QFont +from PyQt4.QtGui import QFontMetrics +from PyQt4.QtGui import QWidget +from PyQt4.QtGui import QFrame +from PyQt4.QtGui import QLabel +from PyQt4.QtGui import QPixmap +from PyQt4.QtGui import QPushButton +from PyQt4.QtGui import QTextEdit +from PyQt4.QtGui import QVBoxLayout +from PyQt4.QtGui import QHBoxLayout +from PyQt4.QtGui import QAction +from PyQt4.QtGui import QKeySequence +import helpers +from Hurricane import UpdateSession +import Viewer + + +# ------------------------------------------------------------------- +# Class : "ErrorWidget". + + +class ErrorWidget ( QDialog ): + + def __init__ ( self, e ): + QWidget.__init__ ( self, None ) + + self.setWindowTitle( 'Error' ) + + message = QLabel( e.getLinesAsString() ) + message.setAlignment( Qt.AlignLeft ) + message.setFont( QFont('Courier',10,QFont.Bold) ) + + error = QLabel( '[ERROR]' ) + error.setAlignment( Qt.AlignLeft ) + font = error.font() + font.setWeight( QFont.Bold ) + error.setFont( font ) + + self._tryCont = QPushButton() + self._tryCont.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed ) + self._tryCont.setText ( 'Try to continue' ) + self._abort = QPushButton() + self._abort.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed ) + self._abort.setText ( 'Abort' ) + self._abort.setDefault ( True ) + + traceFont = QFont('Courier',10,QFont.Normal) + lineHeight = QFontMetrics( traceFont ).height() + traceText = helpers.textStackTrace( e.trace, False, e.scriptPath ) + lineCount = traceText.count( '\n' ) + 2 + minimumWidth = 400 + if Viewer.Graphics.isHighDpi(): minimumWidth = 2100 + self._trace = QTextEdit() + self._trace.setReadOnly ( True ); + self._trace.setLineWrapMode( QTextEdit.NoWrap ); + self._trace.setMinimumSize ( minimumWidth, lineCount*lineHeight ); + self._trace.setFont ( traceFont ) + self._trace.setText ( traceText ) + + buttonLayout = QHBoxLayout() + buttonLayout.addStretch( 1 ) + buttonLayout.addWidget ( self._tryCont ) + buttonLayout.addStretch( 1 ) + buttonLayout.addWidget ( self._abort ) + buttonLayout.addStretch( 1 ) + + vLayout = QVBoxLayout() + vLayout.addWidget ( error ) + vLayout.addStretch( 1 ) + vLayout.addWidget ( message ) + vLayout.addStretch( 1 ) + vLayout.addWidget ( self._trace ) + vLayout.addStretch( 1 ) + vLayout.addLayout ( buttonLayout ) + + pixmap = QPixmap( ':/images/angry-birds-red.png' ) + pixmap = pixmap.scaledToWidth( 150 ) + icon = QLabel() + icon.setPixmap( pixmap ) + + hLayout = QHBoxLayout() + hLayout.addWidget( icon ) + hLayout.addLayout( vLayout ) + self.setLayout( hLayout ) + + self._tryCont.clicked.connect( self.accept ) + self._abort .clicked.connect( self.reject ) + + self._exitAction = QAction( '&Exit', self ) + self._exitAction.setStatusTip( 'Exit Coriolis' ) + self._exitAction.setShortcut ( QKeySequence('CTRL+Q') ) + self._exitAction.triggered.connect( self.reject ) + self.addAction( self._exitAction ) + + self._closeAction = QAction( '&Close', self ) + self._closeAction.setStatusTip( 'Try to continue' ) + self._closeAction.setShortcut ( QKeySequence('CTRL+W') ) + self._closeAction.triggered.connect( self.reject ) + self.addAction( self._closeAction ) + + return + + def closeEvent ( self, event ): + self.setResult( QDialog.Rejected ) + event.accept() + return + + +# ------------------------------------------------------------------- +# Class : "ErrorMessage". + +class ErrorMessage ( Exception ): + + def __init__ ( self, code, *arguments ): + self.scriptPath = None + self.trace = traceback.extract_stack() + self._code = code + self._errors = [ 'Malformed call to ErrorMessage()' + , '%s' % str(arguments) ] + + text = None + if len(arguments) == 1: + if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n') + else: + self._errors = arguments[0] + elif len(arguments) > 1: + sys.stdout.flush() + text = list(arguments) + + if text: + self._errors = [] + while len(text[0]) == 0: del text[0] + + lstrip = 0 + if text[0].startswith('[ERROR]'): lstrip = 8 + + for line in text: + if line[0:lstrip] == ' '*lstrip or \ + line[0:lstrip-1] == '[ERROR]': + self._errors += [ line[lstrip:] ] + else: + self._errors += [ line.lstrip() ] + sys.stdout.flush() + return + + def __str__ ( self ): + if not isinstance(self._errors,list): + return "[ERROR] %s" % self._errors + + formatted = "\n" + for i in range(len(self._errors)): + if i == 0: formatted += "[ERROR] %s" % self._errors[i] + else: formatted += " %s" % self._errors[i] + if i+1 < len(self._errors): formatted += "\n" + return formatted + + def getLinesAsString ( self ): + if not isinstance(self._errors,list): return self._errors + + lines = '' + for line in self._errors: lines += line + '\n' + return lines + + def addMessage ( self, message ): + if not isinstance(self._errors,list): + self._errors = [ self._errors ] + if isinstance(message,list): + for line in message: + self._errors += [ line ] + else: + self._errors += [ message ] + return + + def terminate ( self ): + print self + sys.exit( self._code ) + + def _getCode ( self ): return self._code + + code = property(_getCode) + + @staticmethod + def show ( code, *arguments ): + e = ErrorMessage( code, *arguments ) + if Viewer.Graphics.get().isEnabled(): + tryCont = ErrorWidget( e ).exec_() + if not tryCont: raise e + else: + raise e + return + + +def catch ( errorObject ): + if isinstance(errorObject,ErrorMessage): + em = errorObject + else: + em = ErrorMessage( 2, errorObject ) + em.trace = traceback.extract_tb( sys.exc_info()[2] ) + em.scriptPath = __file__ + + if Viewer.Graphics.get().isEnabled(): + tryCont = ErrorWidget( em ).exec_() + print em + print helpers.textStackTrace( em.trace, True, em.scriptPath ) + + if UpdateSession.getStackSize() > 0: UpdateSession.close() + return + + + + +# ------------------------------------------------------------------- +# Class : "WarningMessage". + + +class WarningMessage ( Exception ): + + def __init__ ( self, message ): + self._warnings = message + return + + def __str__ ( self ): + if not isinstance(self._warnings,list): + return "[WARNING] %s" % self._warnings + + formatted = "\n" + for i in range(len(self._warnings)): + if i == 0: formatted += "[WARNING] %s" % self._warnings[i] + else: formatted += " %s" % self._warnings[i] + if i+1 < len(self._warnings): formatted += "\n" + return formatted diff --git a/crlcore/src/ccore/AllianceFramework.cpp b/crlcore/src/ccore/AllianceFramework.cpp index 52c6b5f2..002ef208 100644 --- a/crlcore/src/ccore/AllianceFramework.cpp +++ b/crlcore/src/ccore/AllianceFramework.cpp @@ -179,7 +179,7 @@ namespace CRL { AllianceFramework* AllianceFramework::_singleton = NULL; - const Name AllianceFramework::_parentLibraryName = "AllianceFramework"; + const Name AllianceFramework::_parentLibraryName = "Alliance"; @@ -234,7 +234,7 @@ namespace CRL { //cmess2 << " o Creating Alliance Framework root library." << endl; if ( !rootLibrary ) - rootLibrary = Library::create ( db, "RootLibrary" ); + rootLibrary = Library::create ( db, "Root" ); _parentLibrary = rootLibrary->getLibrary ( _parentLibraryName ); if ( !_parentLibrary ) diff --git a/crlcore/src/ccore/alliance/ap/ApDriver.cpp b/crlcore/src/ccore/alliance/ap/ApDriver.cpp index 467def15..c7ccc1f1 100644 --- a/crlcore/src/ccore/alliance/ap/ApDriver.cpp +++ b/crlcore/src/ccore/alliance/ap/ApDriver.cpp @@ -335,10 +335,11 @@ void DumpPins(ofstream &ccell, Cell* cell) + getString(net->getName())); } indexesSet.insert(index); - if (pin->getWidth() != pin->getHeight()) - throw Warning( "CRL::ApParser(): Pin \"" + getString(pin->getName()) + "\" of \"" - + getString(net->getName()) - + "\", AP format support only square shapes."); + // if (pin->getWidth() != pin->getHeight()) + // cerr << Warning( "CRL::ApDriver(): Pin \"" + getString(pin->getName()) + "\" of \"" + // + getString(net->getName()) + // + "\", AP format support only square shapes.") + // << endl;; DbU::Unit width = 0; switch ( pin->getAccessDirection() ) { diff --git a/crlcore/src/ccore/alliance/ap/ApParser.cpp b/crlcore/src/ccore/alliance/ap/ApParser.cpp index 1c1afeaf..a3a63157 100644 --- a/crlcore/src/ccore/alliance/ap/ApParser.cpp +++ b/crlcore/src/ccore/alliance/ap/ApParser.cpp @@ -159,7 +159,6 @@ namespace { Cell* _cell; Catalog::State* _state; double _scaleRatio; - unsigned int _anonymousId; int _parserState; size_t _lineNumber; char _rawLine[LINE_SIZE]; @@ -171,7 +170,7 @@ namespace { inline DbU::Unit _getUnit ( const char* value ); vector _splitString ( char* s, char separator ); Net* _getNet ( const char* apName ); - Net* _getAnonymousNet (); + Net* _getFusedNet (); Net* _safeGetNet ( const char* apName ); SegmentDirection _getApSegDirection ( const char* segDir ); void _parseVersion (); @@ -197,7 +196,6 @@ namespace { , _cell (NULL) , _state (NULL) , _scaleRatio (100.0) - , _anonymousId(0) , _parserState(StateVersion) , _lineNumber (0) { @@ -364,13 +362,15 @@ namespace { } - Net* ApParser::_getAnonymousNet () + Net* ApParser::_getFusedNet () { - ostringstream anonymousName ( "anonymous_" ); - anonymousName << _anonymousId++; - - Net* net = Net::create ( _cell, anonymousName.str() ); - net->setAutomatic ( true ); + Name fusedName = "fused_net"; + Net* net = _cell->getNet( fusedName ); + if (not net) { + net = Net::create ( _cell, fusedName ); + net->setAutomatic ( true ); + net->setType ( Net::Type::FUSED ); + } return net; } @@ -378,7 +378,7 @@ namespace { Net* ApParser::_safeGetNet ( const char* apName ) { if ( ( apName[0] == '\0' ) || !strcmp(apName,"*") ) - return _getAnonymousNet (); + return _getFusedNet (); return _getNet ( apName ); } @@ -459,7 +459,7 @@ namespace { void ApParser::_parseConnector () { - static DbU::Unit XCON, YCON, WIDTH; + static DbU::Unit XCON, YCON, WIDTH, HEIGHT; static int index; string pinName; static Net* net; @@ -479,6 +479,7 @@ namespace { XCON = _getUnit( fields[0] ); YCON = _getUnit( fields[1] ); WIDTH = _getUnit( fields[2] ); + HEIGHT = WIDTH; orientation = fields[5]; index = -1; @@ -503,11 +504,21 @@ namespace { net = _getNet ( fields[3] ); layerInfo = _getLayerInformation( fields[6] ); - if (orientation == NORTH) accessDirection = Pin::AccessDirection::NORTH; - else if (orientation == SOUTH) accessDirection = Pin::AccessDirection::SOUTH; - else if (orientation == WEST ) accessDirection = Pin::AccessDirection::WEST; - else if (orientation == EAST ) accessDirection = Pin::AccessDirection::EAST; - else accessDirection = Pin::AccessDirection::UNDEFINED; + if(orientation == NORTH) { + accessDirection = Pin::AccessDirection::NORTH; + HEIGHT = layerInfo->getLayer()->getMinimalSize(); + } else if (orientation == SOUTH) { + accessDirection = Pin::AccessDirection::SOUTH; + HEIGHT = layerInfo->getLayer()->getMinimalSize(); + } else if (orientation == WEST ) { + accessDirection = Pin::AccessDirection::WEST; + WIDTH = layerInfo->getLayer()->getMinimalSize(); + } else if (orientation == EAST ) { + accessDirection = Pin::AccessDirection::EAST; + WIDTH = layerInfo->getLayer()->getMinimalSize(); + } else { + accessDirection = Pin::AccessDirection::UNDEFINED; + } if (layerInfo and net) { net->setExternal( true ); @@ -519,7 +530,7 @@ namespace { , XCON , YCON , WIDTH - , WIDTH + , HEIGHT ); } if (not net ) _printError( false, "Unknown net name <%s>." , fields[5] ); diff --git a/crlcore/src/ccore/gds/GdsParser.cpp b/crlcore/src/ccore/gds/GdsParser.cpp index e3f889bc..f2ced79d 100644 --- a/crlcore/src/ccore/gds/GdsParser.cpp +++ b/crlcore/src/ccore/gds/GdsParser.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -39,6 +40,7 @@ using namespace std; #include "hurricane/Library.h" #include "hurricane/Plug.h" #include "hurricane/Instance.h" +#include "hurricane/NetExternalComponents.h" #include "hurricane/UpdateSession.h" using namespace Hurricane; @@ -184,6 +186,7 @@ namespace { inline bool isLIBDIRSIZE () const; inline bool isSRFNAME () const; inline bool isLIBSECUR () const; + inline bool hasXReflection () const; inline uint16_t getType () const; inline uint16_t getLength () const; inline const vector& getMasks () const; @@ -194,6 +197,8 @@ namespace { void clear (); void read ( istream* ); void readDummy ( bool showError ); + void readStrans (); + void readString (); void readUnits (); void readLayer (); void readStrname (); @@ -209,6 +214,7 @@ namespace { uint16_t _length; uint16_t _count; uint16_t _type; + bool _xReflection; string _name; vector _masks; vector _int16s; @@ -275,6 +281,7 @@ namespace { inline bool GdsRecord::isLIBDIRSIZE () const { return (_type == LIBDIRSIZE ); } inline bool GdsRecord::isSRFNAME () const { return (_type == SRFNAME ); } inline bool GdsRecord::isLIBSECUR () const { return (_type == LIBSECUR ); } + inline bool GdsRecord::hasXReflection () const { return _xReflection; } inline uint16_t GdsRecord::getType () const { return _type; } inline uint16_t GdsRecord::getLength () const { return _length; } inline const vector& GdsRecord::getMasks () const { return _masks; } @@ -285,29 +292,31 @@ namespace { GdsRecord::GdsRecord () - : _stream (NULL) - , _length (0) - , _count (0) - , _type (0) - , _name () - , _masks () - , _int16s () - , _int32s () - , _doubles () + : _stream (NULL) + , _length (0) + , _count (0) + , _type (0) + , _xReflection(false) + , _name () + , _masks () + , _int16s () + , _int32s () + , _doubles () { } void GdsRecord::clear () { - _stream = NULL; - _length = 0; - _count = 0; - _type = 0; - _name .clear(); - _masks .clear(); - _int16s .clear(); - _int32s .clear(); - _doubles .clear(); + _stream = NULL; + _length = 0; + _count = 0; + _type = 0; + _xReflection = false; + _name .clear(); + _masks .clear(); + _int16s .clear(); + _int32s .clear(); + _doubles.clear(); } @@ -338,17 +347,17 @@ namespace { case WIDTH: readDummy( false ); break; case XY: readXy(); break; case ENDEL: readDummy( false ); break; - case SNAME: readDummy( false ); break; + case SNAME: readStrname(); break; case COLROW: readDummy( false ); break; case TEXTNODE: readDummy( false ); break; case NODE: readDummy( false ); break; case TEXTTYPE: readDummy( false ); break; case PRESENTATION: readDummy( false ); break; case SPACING: readDummy( false ); break; - case STRING: readDummy( false ); break; - case STRANS: readDummy( false ); break; + case STRING: readString(); break; + case STRANS: readStrans(); break; case MAG: readDummy( false ); break; - case ANGLE: readDummy( false ); break; + case ANGLE: _doubles.push_back( _readDouble() ); break; case REFLIBS: readDummy( false ); break; case FONTS: readDummy( false ); break; case PATHTYPE: readDummy( false ); break; @@ -380,7 +389,7 @@ namespace { case LIBSECUR: readDummy( false ); break; } - //cerr << " GdsRecord::read() " << toStrType(_type) << endl; + cerr << " GdsRecord::read() " << toStrType(_type) << endl; } @@ -453,6 +462,7 @@ namespace { _stream->get( c ); if (c != (char)0) s.push_back(c); } + cerr << "GdsRecord::_readString(): \"" << s << "\"" << endl; return s; } @@ -468,6 +478,20 @@ namespace { } + void GdsRecord::readStrans () + { + + const uint16_t XRMask = 0x8000; + uint16_t flags = _readInt(); + _xReflection = (flags & XRMask); + + // cerr << "GdsRecord::readStrans(): length=" << _length + // << " flags:" << bitset<16>(flags) + // << " mask:" << bitset<16>(XRMask) + // << " _xR:" << _xReflection << endl; + } + + void GdsRecord::readUnits () { for ( size_t i=0 ; i<2 ; ++i ) _doubles.push_back( _readDouble() ); } @@ -476,6 +500,10 @@ namespace { { _name = _readString(); } + void GdsRecord::readString () + { _name = _readString(); } + + void GdsRecord::readLayer () { _int16s.push_back( _readInt() ); } @@ -568,6 +596,7 @@ namespace { GdsStream ( string gdsPath ); inline bool isValidSyntax () const; bool misplacedRecord (); + inline void resetStrans (); bool read ( Library* ); bool readFormatType (); bool readStructure (); @@ -582,20 +611,43 @@ namespace { bool readStrans (); bool readProperty (); void xyToComponent ( const Layer* ); - Net* anonymousNet (); + void makeInstances (); + Net* fusedNet (); private: - static vector _gdsLayerTable; - string _gdsPath; - ifstream _stream; - GdsRecord _record; - Library* _library; - Cell* _cell; - DbU::Unit _scale; - int64_t _netCount; - bool _validSyntax; + struct DelayedInstance { + inline DelayedInstance ( Cell* owner, string masterName, const Transformation& ); + + Cell* _owner; + string _masterName; + Transformation _transformation; + }; + private: + static vector _gdsLayerTable; + vector _delayedInstances; + string _gdsPath; + ifstream _stream; + GdsRecord _record; + double _angle; + bool _xReflection; + Library* _library; + Cell* _cell; + Component* _component; + string _text; + DbU::Unit _scale; + int64_t _netCount; + int64_t _SREFCount; + bool _validSyntax; + bool _skipENDEL; }; + inline GdsStream::DelayedInstance::DelayedInstance ( Cell* owner + , string masterName + , const Transformation& transf ) + : _owner(owner), _masterName(masterName), _transformation(transf) + { } + + vector GdsStream::_gdsLayerTable; @@ -609,6 +661,9 @@ namespace { } + inline void GdsStream::resetStrans () { _angle = 0.0; _xReflection = false; } + + const Layer* GdsStream::gdsToLayer ( uint16_t gdsLayer ) { return (gdsLayer < _gdsLayerTable.size()) ? _gdsLayerTable[gdsLayer] : NULL; } @@ -617,14 +672,21 @@ namespace { GdsStream::GdsStream ( string gdsPath ) - : _gdsPath (gdsPath) - , _stream () - , _record () - , _library (NULL) - , _cell (NULL) - , _scale (1) - , _netCount (0) - , _validSyntax(true) + : _delayedInstances() + , _gdsPath (gdsPath) + , _stream () + , _record () + , _angle (0.0) + , _xReflection (false) + , _library (NULL) + , _cell (NULL) + , _component (NULL) + , _text () + , _scale (1) + , _netCount (0) + , _SREFCount (0) + , _validSyntax (true) + , _skipENDEL (false) { if (_gdsLayerTable.empty()) _staticInit(); @@ -697,6 +759,8 @@ namespace { if (_validSyntax and not _record.isENDLIB()) { misplacedRecord(); } + if (_validSyntax) makeInstances(); + _library = NULL; //cerr << "GdsStream::read(Library*) - return:" << _validSyntax << endl; return _validSyntax; @@ -730,10 +794,11 @@ namespace { if (_library) { _cell = _library->getCell( _record.getName() ); if (not _cell) { - cerr << Warning( "GdsStream::readStructure(): No Cell named \"%s\" in Library \"%s\" (skipped)." + cerr << Warning( "GdsStream::readStructure(): No Cell named \"%s\" in Library \"%s\" (created)." , _record.getName().c_str() , getString(_library).c_str() ) << endl; + _cell = Cell::create( _library, _record.getName() ); } } _stream >> _record; @@ -742,7 +807,8 @@ namespace { if (_record.isSTRCLASS()) { _stream >> _record; } while ( not _record.isENDSTR() ) { - switch ( _record.getType() ) { + uint16_t rtype = _record.getType(); + switch ( rtype ) { case GdsRecord::BOUNDARY: _stream >> _record; readBoundary(); break; case GdsRecord::PATH: _stream >> _record; readPath (); break; case GdsRecord::SREF: _stream >> _record; readSref (); break; @@ -752,16 +818,24 @@ namespace { case GdsRecord::BOX: _stream >> _record; readBox (); break; case GdsRecord::PROPATTR: _stream >> _record; readProperty(); break; } - if (_record.isENDEL()) { _stream >> _record; } - else { - _validSyntax = false; break; - } + if (not _skipENDEL) { + if (_record.isENDEL()) { _stream >> _record; } + else { + _validSyntax = false; break; + } + } else + _skipENDEL = false; + if (rtype != GdsRecord::BOUNDARY) _component = NULL; } if (_validSyntax) _stream >> _record; + UpdateSession::close(); + _cell->setAbutmentBox( _cell->getBoundingBox() ); + UpdateSession::open(); _cell = NULL; - //cerr << "GdsStream::readStructure() - return:" << _validSyntax << endl; + cerr << "GdsStream::readStructure() - return:" << _validSyntax << endl; + return _validSyntax; } @@ -769,10 +843,8 @@ namespace { bool GdsStream::readText () { //cerr << "GdsStream::readText()" << endl; - if (_record.isELFLAGS()) { _stream >> _record; } if (_record.isPLEX ()) { _stream >> _record; } - if (_record.isLAYER ()) { _stream >> _record; } else { _validSyntax = false; return _validSyntax; } @@ -803,7 +875,11 @@ namespace { if (_record.isXY()) { _stream >> _record; } else { _validSyntax = false; return _validSyntax; } - if (_record.isSTRING()) { _stream >> _record; } + if (_record.isSTRING()) { + _text = _record.getName(); + _stream >> _record; + cerr << "_text:\"" << _text << "\"" << endl; + } else { _validSyntax = false; return _validSyntax; } //cerr << "GdsStream::readTextbody() - return:" << _validSyntax << endl; @@ -815,8 +891,11 @@ namespace { { //cerr << "GdsStream::readStrans()" << endl; + _angle = 0.0; + _xReflection = _record.hasXReflection(); + _stream >> _record; if (_record.isMAG ()) { _stream >> _record; } - if (_record.isANGLE()) { _stream >> _record; } + if (_record.isANGLE()) { _angle = _record.getDoubles()[0]; _stream >> _record; } //cerr << "GdsStream::readStrans() - return:" << _validSyntax << endl; return _validSyntax; @@ -849,7 +928,7 @@ namespace { if (_record.isXY()) { if (_cell and layer) xyToComponent( layer ); - _stream >> _record; + else _stream >> _record; } else { _validSyntax = false; return _validSyntax; } @@ -903,31 +982,74 @@ namespace { bool GdsStream::readSref () { //cerr << "GdsStream::readSref()" << endl; + resetStrans(); - const Layer* layer = NULL; + string masterName; + DbU::Unit xpos = 0; + DbU::Unit ypos = 0; if (_record.isELFLAGS()) { _stream >> _record; } if (_record.isPLEX ()) { _stream >> _record; } if (_record.isSNAME()) { + masterName = _record.getName(); + _stream >> _record; } else { _validSyntax = false; return _validSyntax; } if (_record.isSTRANS()) { - _stream >> _record; readStrans(); + //_stream >> _record; if (not _validSyntax) return _validSyntax; } if (_record.isXY()) { - if (_cell and layer) xyToComponent( layer ); + vector coordinates = _record.getInt32s(); + if (coordinates.size() != 2) { + _validSyntax = false; return _validSyntax; + } + + xpos = coordinates[ 0 ]*_scale; + ypos = coordinates[ 1 ]*_scale; + _stream >> _record; } else { _validSyntax = false; return _validSyntax; } + if (not masterName.empty()) { + Transformation::Orientation orient = Transformation::Orientation::ID; + if (_angle == 90.0) orient = Transformation::Orientation::R1; + else if (_angle == 180.0) orient = Transformation::Orientation::R2; + else if (_angle == 270.0) orient = Transformation::Orientation::R3; + else if (_angle != 0.0) { + cerr << Warning( "GdsStream::readSref(): Unsupported angle %d.2 for SREF (Instance) of \"%s\"" + , _angle, masterName.c_str() ) << endl; + } + + if (_xReflection) { + switch ( orient ) { + case Transformation::Orientation::ID: orient = Transformation::Orientation::MY; break; + case Transformation::Orientation::R1: orient = Transformation::Orientation::YR; break; + case Transformation::Orientation::R2: orient = Transformation::Orientation::MX; break; + case Transformation::Orientation::R3: orient = Transformation::Orientation::XR; break; + default: + cerr << Warning( "GdsStream::readSref(): Unsupported MX+Orientation (%s) combination for SREF (Instance) of \"%s\"" + , getString(orient).c_str(), masterName.c_str() ) << endl; + } + } + + // cerr << "Delayed Instance: " << masterName + // << " XR:" << _xReflection << " angle:" << _angle + // << " " << Transformation(xpos,ypos,orient) + // << " in " << _cell << endl; + _delayedInstances.push_back( DelayedInstance( _cell + , masterName + , Transformation(xpos,ypos,orient)) ); + } + //cerr << "GdsStream::readSref() - return:" << _validSyntax << endl; return _validSyntax; } @@ -1052,6 +1174,34 @@ namespace { points.push_back( Point( coordinates[i ]*_scale , coordinates[i+1]*_scale ) ); + _stream >> _record; + + if (_record.getType() == GdsRecord::ENDEL) { + _stream >> _record; + } else { + _validSyntax = false; + return; + } + + Net* net = NULL; + if (_record.getType() == GdsRecord::TEXT) { + _stream >> _record; + cerr << " BOUNDARY --> TEXT record" << endl; + readText(); + cerr << " AFTER readText()" << endl; + + if (not _text.empty()) { + net = _cell->getNet( _text ); + if (not net) { + net = Net::create( _cell, _text ); + net->setExternal( true ); + } + } + } else + _skipENDEL = true; + + if (not net) net = fusedNet(); + if (points.size() > 2) { bool isRectilinear = true; for ( size_t i=1 ; iisAutomatic()) NetExternalComponents::setExternal( _component ); + } + } + + + void GdsStream::makeInstances () + { + //cerr << "GdsStream::makeInstances(): " << endl; + + for ( const DelayedInstance& di : _delayedInstances ) { + Cell* masterCell = _library->getCell( di._masterName ); + + if (masterCell) { + string insName = "sref_" + getString(_SREFCount++); + //Instance* instance = + Instance::create( di._owner + , insName + , masterCell + , di._transformation + , Instance::PlacementStatus::FIXED + ); + //cerr << "| " << instance << " @" << di._transformation << " in " << di._owner << endl; } } } - Net* GdsStream::anonymousNet () + Net* GdsStream::fusedNet () { if (not _cell) return NULL; - string netName = "anonymous_" + getString(_netCount++); - Net* net = Net::create( _cell, netName ); + string netName = "all_nets_merged_in_gds"; + Net* net = _cell->getNet( netName ); + if (not net) { + net = Net::create( _cell, netName ); + net->setAutomatic( true ); + net->setType ( Net::Type::FUSED ); + } return net; } @@ -1098,7 +1278,11 @@ namespace CRL { GdsStream gstream ( gdsPath ); - gstream.read( library ); + if (not gstream.read( library )) + cerr << Error( "Gds::load(): An error occurred while reading GDSII stream\n" + " \"%s\"." + , gdsPath.c_str() + ) << endl; UpdateSession::close(); diff --git a/cumulus/src/Alliance.py b/cumulus/src/Alliance.py index ccff4bd0..100444c5 100644 --- a/cumulus/src/Alliance.py +++ b/cumulus/src/Alliance.py @@ -23,9 +23,9 @@ import copy import subprocess import inspect import helpers -from helpers import ErrorMessage -from helpers import WarningMessage -from helpers import Dots +from helpers.io import ErrorMessage +from helpers.io import WarningMessage +from helpers import Dots # Global display flags @@ -210,7 +210,9 @@ class Environment ( object ): self.mbkEnv['MBK_CATA_LIB'].add( libPath, mode ) except Exception, e: - ErrorMessage.wrapPrint(e,'In %s: at index %d.' % (allianceFile,entryNo)) + e = ErrorMessage( e ) + e.addMessage( 'In %s: at index %d.' % (allianceFile,entryNo) ) + print e self.mbkEnv[ 'LD_LIBRARY_PATH' ] = self.mbkEnv[ 'ALLIANCE_TOP' ] + '/lib' return diff --git a/cumulus/src/CMakeLists.txt b/cumulus/src/CMakeLists.txt index 58d502f1..9c0f0d5d 100644 --- a/cumulus/src/CMakeLists.txt +++ b/cumulus/src/CMakeLists.txt @@ -5,16 +5,25 @@ ${CMAKE_CURRENT_SOURCE_DIR}/Alliance.py ) set ( pyPlugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins/__init__.py + ${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTreePlugin.py + ${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_cmos.py + #${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_c35b4.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipPlace.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipRoute.py - ${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTreePlugin.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/RSavePlugin.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/RSavePluginAll.py + ${CMAKE_CURRENT_SOURCE_DIR}/plugins/S2R.py + ${CMAKE_CURRENT_SOURCE_DIR}/plugins/AboutWindow.py ) set ( pyPluginCT ${CMAKE_CURRENT_SOURCE_DIR}/plugins/clocktree/__init__.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/clocktree/RSMT.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/clocktree/ClockTree.py ) + set ( pyPluginC2C ${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/__init__.py + ${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/CoreToChip.py + ${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/cmos.py + #${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/c35b4.py + ) set ( pyPluginChip ${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/__init__.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/Configuration.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/BlockPower.py @@ -26,4 +35,5 @@ install ( FILES ${pySources} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus ) install ( FILES ${pyPlugins} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins ) install ( FILES ${pyPluginCT} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/clocktree ) + install ( FILES ${pyPluginC2C} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/core2chip ) install ( FILES ${pyPluginChip} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/chip ) diff --git a/cumulus/src/placeandroute.py b/cumulus/src/placeandroute.py index ad08e86f..0a6c0beb 100644 --- a/cumulus/src/placeandroute.py +++ b/cumulus/src/placeandroute.py @@ -3,8 +3,8 @@ import os import re import Cfg -from Hurricane import * -from helpers import ErrorMessage +from Hurricane import * +from helpers.io import ErrorMessage import CRL #import Mauka diff --git a/cumulus/src/plugins/AboutWindow.py b/cumulus/src/plugins/AboutWindow.py new file mode 100644 index 00000000..3026d59a --- /dev/null +++ b/cumulus/src/plugins/AboutWindow.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python +# +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2014-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@asim.lip6.fr | +# | =============================================================== | +# | Python : "./plugins/AboutWindow.py" | +# +-----------------------------------------------------------------+ + + + +try: + import sys + import traceback + from PyQt4.QtCore import Qt + from PyQt4.QtCore import QEventLoop + from PyQt4.QtGui import QDialog + from PyQt4.QtGui import QPalette + from PyQt4.QtGui import QColor + from PyQt4.QtGui import QFont + from PyQt4.QtGui import QWidget + from PyQt4.QtGui import QFrame + from PyQt4.QtGui import QLabel + from PyQt4.QtGui import QVBoxLayout + from PyQt4.QtGui import QAction + from PyQt4.QtGui import QKeySequence + from PyQt4.QtGui import QApplication + import Viewer + import helpers + from helpers.io import ErrorMessage + from helpers.io import WarningMessage + import plugins + import chip.Chip +except ImportError, e: + serror = str(e) + if serror.startswith('No module named'): + module = serror.split()[-1] + print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module + print ' Please check the integrity of the package.' + if str(e).find('cannot open shared object file'): + library = serror.split(':')[0] + print '[ERROR] The <%s> shared library cannot be loaded.' % library + print ' Under RHEL 6, you must be under devtoolset-2.' + print ' (scl enable devtoolset-2 bash)' + sys.exit(1) +except Exception, e: + print '[ERROR] A strange exception occurred while loading the basic Coriolis/Python' + print ' modules. Something may be wrong at Python/C API level.\n' + print ' %s' % e + sys.exit(2) + + +# -------------------------------------------------------------------- +# Class : "AboutWidget". + + +class AboutWidget ( QDialog ): + + def __init__ ( self, parent=None ): + QWidget.__init__ ( self, parent ) + #self.setFixedSize( 500, 400 ) + #self.setStyleSheet( 'background-color: #ffffdd;' ) + + topLine = QFrame() + topLine.setFrameShape( QFrame.HLine ) + topLine.setLineWidth ( 2 ) + botLine = QFrame() + botLine.setFrameShape( QFrame.HLine ) + botLine.setLineWidth ( 2 ) + + title = QLabel( 'CCB' ) + title.setAlignment( Qt.AlignCenter ) + font = title.font() + font.setPointSize( 72 ) + font.setWeight ( QFont.Bold ) + title.setFont( font ) + + subTitle = QLabel( 'Coriolis & Chams Builder for the Dummies' ) + subTitle.setAlignment( Qt.AlignCenter ) + subTitle.setFont( QFont('Courier',10,QFont.Bold) ) + + authors = QLabel( 'Coriolis CAD System 1.0 . . . . . . . . ccb 1.0\n' + 'Copyright (c) 2008-2016 . . . . . . . . . . UPMC\n' + 'Authors . . . . . . . . . . . . . Damien Dupuis\n' + ' . . . . . . . . . . . . Jean-Paul Chaput\n' + 'E-Mail . . . . . . . . Jean-Paul.Chaput@lip6.fr' + ) + authors.setAlignment( Qt.AlignCenter ) + authors.setFont( QFont('Courier',10,QFont.Bold) ) + + vLayout = QVBoxLayout() + vLayout.addStretch(10) + vLayout.addWidget( topLine ) + vLayout.addWidget( title ) + vLayout.addStretch(1) + vLayout.addWidget( subTitle ) + vLayout.addWidget( authors ) + vLayout.addStretch(1) + vLayout.addWidget( botLine ) + vLayout.addStretch(10) + + frame = QFrame() + frame.setFrameShape ( QFrame.Box ) + frame.setFrameShadow( QFrame.Sunken ) + frame.setLayout ( vLayout ) + frame.setLineWidth ( 1 ) + + vLayout = QVBoxLayout() + vLayout.addWidget( frame ) + + self.setLayout( vLayout ) + + self._exitAction = QAction( '&Exit', self ) + self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' ) + self._exitAction.setShortcut ( QKeySequence('CTRL+Q') ) + #self._exitAction.triggered.connect( QApplication.closeAllWindows ) + self._exitAction.triggered.connect( self.reject ) + self.addAction( self._exitAction ) + + self._closeAction = QAction( '&Close', self ) + self._closeAction.setStatusTip( 'Close the About Window' ) + self._closeAction.setShortcut ( QKeySequence('CTRL+A') ) + #self._closeAction.triggered.connect( self.close ) + self._closeAction.triggered.connect( self.accept ) + self.addAction( self._closeAction ) + + return + + +# -------------------------------------------------------------------- +# Plugin hook functions, unicornHook:menus, ScritMain:call + +def unicornHook ( **kw ): + plugins.kwUnicornHook( 'file.About' + , 'About Coriolis' + , 'Informations about the Coriolis Software' + , sys.modules[__name__].__file__ + , **kw + ) + return + + +def ScriptMain ( **kw ): + rvalue = True + try: + helpers.staticInitialization( quiet=True ) + #helpers.setTraceLevel( 550 ) + + aboutWidget = AboutWidget() + answer = aboutWidget.exec_() + print 'answer:', answer + if not answer: return True + + except Exception, e: + helpers.io.catch( e ) + + sys.stdout.flush() + sys.stderr.flush() + + return rvalue diff --git a/cumulus/src/plugins/ChipPlace.py b/cumulus/src/plugins/ChipPlace.py index 72b264b0..df293ea2 100644 --- a/cumulus/src/plugins/ChipPlace.py +++ b/cumulus/src/plugins/ChipPlace.py @@ -18,8 +18,8 @@ try: import sys import traceback import helpers - from helpers import ErrorMessage - from helpers import WarningMessage + from helpers.io import ErrorMessage + from helpers.io import WarningMessage import plugins import chip.Chip except ImportError, e: @@ -46,6 +46,7 @@ except Exception, e: def unicornHook ( **kw ): kw['beforeAction'] = 'placeAndRoute.stepByStep' + #kw['beforeAction'] = 'placeAndRoute.clockTree' plugins.kwAddMenu ( 'placeAndRoute', 'P&&R', **kw ) plugins.kwUnicornHook( 'placeAndRoute.placeChip' @@ -72,14 +73,8 @@ def ScriptMain ( **kw ): placeChip.doChipPlacement() return placeChip.validated - except ErrorMessage, e: - print e; errorCode = e.code - if locals().has_key('editor') and editor \ - and locals().has_key('cell' ) and cell: editor.fit() - rvalue = False except Exception, e: - print '\n\n', e; errorCode = 1 - traceback.print_tb(sys.exc_info()[2]) + helpers.io.catch( e ) rvalue = False sys.stdout.flush() diff --git a/cumulus/src/plugins/ChipRoute.py b/cumulus/src/plugins/ChipRoute.py index 84e4cbf9..5590f462 100644 --- a/cumulus/src/plugins/ChipRoute.py +++ b/cumulus/src/plugins/ChipRoute.py @@ -14,13 +14,14 @@ # +-----------------------------------------------------------------+ + try: import sys import traceback import Viewer import helpers - from helpers import ErrorMessage - from helpers import WarningMessage + from helpers.io import ErrorMessage + from helpers.io import WarningMessage import plugins import chip.Chip except ImportError, e: @@ -47,6 +48,7 @@ except Exception, e: def unicornHook ( **kw ): kw['beforeAction'] = 'placeAndRoute.stepByStep' + #kw['beforeAction'] = 'placeAndRoute.placeChip' plugins.kwAddMenu ( 'placeAndRoute', 'P&&R', **kw ) plugins.kwUnicornHook( 'placeAndRoute.placeRouteChip' @@ -69,18 +71,14 @@ def ScriptMain ( **kw ): if not conf.validated: return False prChip = chip.Chip.PlaceRoute( conf ) + prChip.validate() prChip.doChipPlacement() prChip.doChipRouting() + prChip.save() return prChip.validated - except ErrorMessage, e: - print e; errorCode = e.code - if locals().has_key('editor') and editor \ - and locals().has_key('cell' ) and cell: editor.fit() - rvalue = False except Exception, e: - print '\n\n', e; errorCode = 1 - traceback.print_tb(sys.exc_info()[2]) + helpers.io.catch( e ) rvalue = False sys.stdout.flush() diff --git a/cumulus/src/plugins/ClockTreePlugin.py b/cumulus/src/plugins/ClockTreePlugin.py index 488109be..f8e9042c 100755 --- a/cumulus/src/plugins/ClockTreePlugin.py +++ b/cumulus/src/plugins/ClockTreePlugin.py @@ -20,13 +20,14 @@ try: import math import Cfg import Hurricane - from Hurricane import Breakpoint + from Hurricane import Breakpoint + from Hurricane import UpdateSession import Viewer import CRL - from CRL import RoutingLayerGauge + from CRL import RoutingLayerGauge import helpers - from helpers import trace - from helpers import ErrorMessage + from helpers import trace + from helpers.io import ErrorMessage import Etesian import Unicorn import plugins @@ -55,7 +56,7 @@ except Exception, e: # Plugin hook functions, unicornHook:menus, ScritMain:call def unicornHook ( **kw ): - kw['beforeAction'] = 'beta.placeAndRoute.placeChip' + kw['beforeAction'] = 'placeAndRoute.placeChip' plugins.kwAddMenu ( 'placeAndRoute', 'P&&R', **kw ) plugins.kwUnicornHook( 'placeAndRoute.clockTree' @@ -113,10 +114,7 @@ def ScriptMain ( **kw ): ht.route() ht.save( cell ) - except ErrorMessage, e: - print e; errorCode = e.code except Exception, e: - print '\n\n', e; errorCode = 1 - traceback.print_tb(sys.exc_info()[2]) + helpers.io.catch( e ) return 0 diff --git a/cumulus/src/plugins/CoreToChip_cmos.py b/cumulus/src/plugins/CoreToChip_cmos.py new file mode 100644 index 00000000..4c757f0d --- /dev/null +++ b/cumulus/src/plugins/CoreToChip_cmos.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 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@asim.lip6.fr | +# | =============================================================== | +# | Python : "./plugins/CoreToChip_cmos.py" | +# +-----------------------------------------------------------------+ + +import sys +import re +import helpers +from helpers.io import ErrorMessage +from helpers.io import WarningMessage +import plugins +import 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.staticInitialization( quiet=True ) + #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 = core2chip.cmos.cmos( cell ) + chip_cmos.buildChip( 'chip' ) + + if editor: editor.setCell( chip_cmos.chip ) + + except Exception, e: + helpers.io.catch( e ) + rvalue = False + + sys.stdout.flush() + sys.stderr.flush() + + return rvalue diff --git a/cumulus/src/plugins/RSavePlugin.py b/cumulus/src/plugins/RSavePlugin.py index ac05777e..13a309fc 100644 --- a/cumulus/src/plugins/RSavePlugin.py +++ b/cumulus/src/plugins/RSavePlugin.py @@ -21,8 +21,8 @@ try: import Cfg import CRL import helpers - from helpers import ErrorMessage - from helpers import WarningMessage + from helpers.io import ErrorMessage + from helpers.io import WarningMessage import plugins except ImportError, e: serror = str(e) @@ -104,11 +104,8 @@ def ScriptMain ( **kw ): rsave( cell, views ) CRL.destroyAllVHDL() - except ErrorMessage, e: - print e; errorCode = e.code except Exception, e: - print '\n\n', e; errorCode = 1 - traceback.print_tb(sys.exc_info()[2]) + helpers.io.catch( e ) sys.stdout.flush() sys.stderr.flush() diff --git a/cumulus/src/plugins/RSavePluginAll.py b/cumulus/src/plugins/RSavePluginAll.py index 621dd0fc..ee7de67a 100644 --- a/cumulus/src/plugins/RSavePluginAll.py +++ b/cumulus/src/plugins/RSavePluginAll.py @@ -21,8 +21,8 @@ try: import Cfg import CRL import helpers - from helpers import ErrorMessage - from helpers import WarningMessage + from helpers.io import ErrorMessage + from helpers.io import WarningMessage import plugins except ImportError, e: serror = str(e) @@ -96,11 +96,8 @@ def ScriptMain ( **kw ): rsave( cell ) CRL.destroyAllVHDL() - except ErrorMessage, e: - print e; errorCode = e.code except Exception, e: - print '\n\n', e; errorCode = 1 - traceback.print_tb(sys.exc_info()[2]) + helpers.io.catch( e ) sys.stdout.flush() sys.stderr.flush() diff --git a/cumulus/src/plugins/S2R.py b/cumulus/src/plugins/S2R.py new file mode 100644 index 00000000..ccd78807 --- /dev/null +++ b/cumulus/src/plugins/S2R.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2014-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@asim.lip6.fr | +# | =============================================================== | +# | Python : "./plugins/S2R.py" | +# +-----------------------------------------------------------------+ + + +try: + import os + import sys + import traceback + import subprocess + import Viewer + import helpers + from helpers.io import ErrorMessage + from helpers.io import WarningMessage + from Hurricane import DataBase + from Hurricane import Library + from CRL import Gds + import plugins + import chip.Chip +except ImportError, e: + serror = str(e) + if serror.startswith('No module named'): + module = serror.split()[-1] + print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module + print ' Please check the integrity of the package.' + if str(e).find('cannot open shared object file'): + library = serror.split(':')[0] + print '[ERROR] The <%s> shared library cannot be loaded.' % library + print ' Under RHEL 6, you must be under devtoolset-2.' + print ' (scl enable devtoolset-2 bash)' + sys.exit(1) +except Exception, e: + print '[ERROR] A strange exception occurred while loading the basic Coriolis/Python' + print ' modules. Something may be wrong at Python/C API level.\n' + print ' %s' % e + sys.exit(2) + + + +# -------------------------------------------------------------------- +# S2R class + + +class S2R ( object ): + + def __init__ ( self ): + self.s2r = None + + pathes = os.environ[ "PATH" ] + for path in pathes.split(':'): + binary = os.path.join( path, 's2r' ) + if os.path.exists(binary): + self.s2r = binary + break + if not self.s2r: + print ErrorMessage( 1, 'S2R.__init__(): No s2r binary found in PATH, please setup Alliance environement.' ) + return + + + def convert ( self, cell ): + if not self.s2r: return + + os.environ[ 'RDS_IN' ] = 'gds' + os.environ[ 'RDS_OUT' ] = 'gds' + process = subprocess.Popen( [ self.s2r, cell.getName() ] + , stderr=subprocess.STDOUT + , stdout=subprocess.PIPE + , shell =False + ) + for line in process.stdout.readlines(): + print 's2r | %s' % line[:-1] + + gdsFile = os.path.join( os.environ['MBK_WORK_LIB'], cell.getName()+'.gds' ) + + rootLibrary = DataBase.getDB().getRootLibrary() + gdsLibrary = rootLibrary.getLibrary( 'gds' ) + if not gdsLibrary: + gdsLibrary = Library.create( rootLibrary, 'GDS' ) + Gds.load( gdsLibrary, gdsFile ) + return gdsLibrary.getCell( cell.getName() ) + + +# -------------------------------------------------------------------- +# Plugin hook functions, unicornHook:menus, ScritMain:call + +def unicornHook ( **kw ): + plugins.kwUnicornHook( 'tools.s2r' + , 'Symbolic to real (Alliance s2r)' + , 'Convert symbolic layout into GDSII using Alliance s2r' + , sys.modules[__name__].__file__ + , **kw + ) + return + + +def ScriptMain ( **kw ): + rvalue = True + try: + helpers.staticInitialization( quiet=True ) + #helpers.setTraceLevel( 550 ) + + cell, editor = plugins.kwParseMain( **kw ) + s2r = S2R() + gdsCell = s2r.convert( cell ) + print gdsCell + if editor: editor.setCell( gdsCell ) + + except Exception, e: + helpers.io.catch( e ) + if locals().has_key('editor') and editor \ + and locals().has_key('cell' ) and cell: editor.fit() + rvalue = False + + sys.stdout.flush() + sys.stderr.flush() + + return rvalue diff --git a/cumulus/src/plugins/__init__.py b/cumulus/src/plugins/__init__.py index bf81502a..2dad44c4 100644 --- a/cumulus/src/plugins/__init__.py +++ b/cumulus/src/plugins/__init__.py @@ -15,15 +15,15 @@ import Cfg -from helpers import ErrorMessage -from helpers import WarningMessage -from Hurricane import Contact -from Hurricane import Path -from Hurricane import Occurrence -from Hurricane import Instance +from helpers.io import ErrorMessage +from helpers.io import WarningMessage +from Hurricane import Contact +from Hurricane import Path +from Hurricane import Occurrence +from Hurricane import Instance import Viewer import CRL -from CRL import RoutingLayerGauge +from CRL import RoutingLayerGauge NoFlags = 0000 diff --git a/cumulus/src/plugins/chip/BlockCorona.py b/cumulus/src/plugins/chip/BlockCorona.py index e4f12465..e83bb9fc 100644 --- a/cumulus/src/plugins/chip/BlockCorona.py +++ b/cumulus/src/plugins/chip/BlockCorona.py @@ -15,27 +15,27 @@ 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 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 import CRL -from CRL import RoutingLayerGauge -from helpers import trace -from helpers import ErrorMessage -from helpers import WarningMessage +from CRL import RoutingLayerGauge +from helpers import trace +from helpers.io import ErrorMessage +from helpers.io import WarningMessage import plugins -from plugins import StackedVia +from plugins import StackedVia import chip.BlockPower @@ -100,8 +100,8 @@ class HorizontalRail ( Rail ): 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.' - , '(corona:%s)' % str(self.side.innerBb) ] ) + , 'power pad is likely to be to far off west or east.' + , '(corona:%s)' % str(self.side.innerBb) ] ) #print ' HorizontalRail.connect() net:%s contact:%s' % (self.net.getName(),str(contact)) #if self.net != contact.getNet(): return False @@ -131,11 +131,11 @@ class HorizontalRail ( Rail ): , self.side.hRailWidth - DbU.fromLambda(1.0) ) , contact ] - trace( 550, '\tADD "%s" contact "%s" @ [%d %d]\n' + trace( 550, '\tADD "%s" contact "%s" @ [%s %s]\n' % ( contact.getNet().getName() , contact.getLayer().getName() - , DbU.toLambda(contact.getX()) - , DbU.toLambda(self.axis)) ) + , DbU.getValueString(contact.getX()) + , DbU.getValueString(self.axis)) ) self.vias[ contact.getX() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) ) return True @@ -161,9 +161,6 @@ class HorizontalRail ( Rail ): #print via[1], self.side.getVLayer(), via[1].getVia( self.side.getVLayer() ) railVias.append( via[1].getVia( self.side.getVLayer()) ) - #print railVias - railVias.sort( key=methodcaller('getX') ) - for i in range(1,len(railVias)): Horizontal.create( railVias[i-1] , railVias[i] @@ -316,12 +313,12 @@ class Side ( object ): def getInnerRail ( self, i ): if i >= len(self.rails): - raise ErrorMessage( 1, 'Side.getInnerRail(): no rail %d (only: %d).' % (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)) ) + raise ErrorMessage( 1, 'Side.getOuterRail(): no rail %d (only: %d).' % (i,len(self.rails)) ) return self.rails[-(i+1)] def connect ( self, blockSide ): @@ -481,7 +478,7 @@ class Corona ( object ): self.block.path.getTransformation().applyOn( self.innerBb ) self.innerBb.inflate( self.hRailSpace/2, self.vRailSpace/2 ) - if not self.block.conf.useClockTree: self.railsNb -= 1 + if not self.conf.useClockTree: self.railsNb -= 1 self.southSide = SouthSide( self ) self.northSide = NorthSide( self ) @@ -491,23 +488,25 @@ class Corona ( object ): return @property - def routingGauge ( self ): return self.block.conf.gaugeConf.routingGauge + def conf ( self ): return self.block.conf @property - def topLayerDepth ( self ): return self.block.conf.gaugeConf.topLayerDepth + def routingGauge ( self ): return self.conf.gaugeConf.routingGauge @property - def horizontalDepth ( self ): return self.block.conf.gaugeConf.horizontalDepth + def topLayerDepth ( self ): return self.conf.gaugeConf.topLayerDepth @property - def verticalDepth ( self ): return self.block.conf.gaugeConf.verticalDepth + def horizontalDepth ( self ): return self.conf.gaugeConf.horizontalDepth @property - def blockageNet ( self ): return self.block.conf.blockageNet + def verticalDepth ( self ): return self.conf.gaugeConf.verticalDepth + @property + def blockageNet ( self ): return self.conf.blockageNet def getLayerDepth ( self, metal ): - return self.block.conf.gaugeConf.routingGauge.getLayerDepth( metal ) + return self.conf.gaugeConf.routingGauge.getLayerDepth( metal ) def getRailNet ( self, i ): - if self.block.conf.useClockTree and i == self.railsNb-1: return self.block.conf.coronaCk - if i % 2: return self.block.conf.coronaVss - return self.block.conf.coronaVdd + 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() diff --git a/cumulus/src/plugins/chip/BlockPower.py b/cumulus/src/plugins/chip/BlockPower.py index 2ba18c26..9901137c 100644 --- a/cumulus/src/plugins/chip/BlockPower.py +++ b/cumulus/src/plugins/chip/BlockPower.py @@ -15,24 +15,24 @@ 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 +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 import ErrorMessage -from helpers import WarningMessage +from helpers import trace +from helpers.io import ErrorMessage +from helpers.io import WarningMessage import chip.Configuration @@ -197,7 +197,7 @@ class Block ( object ): def connectPower ( self ): if not self.conf.coronaVdd or not self.conf.coronaVss: - print ErrorMessage( 1, 'Cannot build block power terminals as core vdd and/or vss are not known.' ) + raise ErrorMessage( 1, 'Cannot build block power terminals as core vdd and/or vss are not known.' ) return goCb = GoCb( self ) @@ -221,7 +221,7 @@ class Block ( object ): return if not self.conf.coronaCk: - print ErrorMessage( 1, 'Cannot build clock terminal as ck is not known.' ) + raise ErrorMessage( 1, 'Cannot build clock terminal as ck is not known.' ) return blockCk = None @@ -230,7 +230,7 @@ class Block ( object ): blockCk = plug.getMasterNet() if not blockCk: - print ErrorMessage( 1, 'Block <%s> has no net connected to the clock <%s>.' + raise ErrorMessage( 1, 'Block "%s" has no net connected to the clock "%s".' % (self.path.getTailInstance().getName(),self.ck.getName()) ) return @@ -246,7 +246,7 @@ class Block ( object ): if len(ffPlugs) > 0: message = 'Clock <%s> of block <%s> is not organized as a H-Tree.' \ % (blockCk.getName(),self.path.getTailInstance().getName()) - print ErrorMessage( 1, message ) + raise ErrorMessage( 1, message ) return if len(htPlugs) > 1: @@ -254,7 +254,7 @@ class Block ( object ): % (self.path.getTailInstance().getName(),blockCk.getName()) for plug in htPlugs: message += '\n - %s' % plug - print ErrorMessage( 1, message ) + raise ErrorMessage( 1, message ) return UpdateSession.open() diff --git a/cumulus/src/plugins/chip/Chip.py b/cumulus/src/plugins/chip/Chip.py index a395258a..2fc0b947 100644 --- a/cumulus/src/plugins/chip/Chip.py +++ b/cumulus/src/plugins/chip/Chip.py @@ -24,29 +24,29 @@ try: 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 + 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 + from CRL import RoutingLayerGauge import helpers - from helpers import ErrorMessage - from helpers import WarningMessage + from helpers.io import ErrorMessage + from helpers.io import WarningMessage import Etesian import Anabatic import Katana @@ -84,7 +84,7 @@ class PlaceRoute ( object ): def __init__ ( self, conf ): self.conf = conf - self.validated = False + self.validated = True return @@ -103,17 +103,19 @@ class PlaceRoute ( object ): and coreAb.getHeight() <= self.conf.coreSize.getHeight(): self.conf.coreSize = coreAb else: - print ErrorMessage( 1, [ 'Core %s already have an abutment box, bigger than the requested one:' + 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) ] ) + , " 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: return + if not self.validated: + raise ErrorMessage( 1, 'chip.doCoronaFloorplan(): Chip is not valid, aborting.' ) + return UpdateSession.open() self.conf.core.setAbutmentBox( self.conf.coreSize ) @@ -129,7 +131,9 @@ class PlaceRoute ( object ): def doCorePlacement ( self ): - if not self.validated: return + if not self.validated: + raise ErrorMessage( 1, 'chip.doCorePlacement(): Chip is not valid, aborting.' ) + return coreCell = self.conf.core @@ -146,6 +150,7 @@ class PlaceRoute ( object ): if self.conf.useClockTree and coreCk: ht = clocktree.ClockTree.HTree.create( self.conf, coreCell, coreCk, coreCell.getAbutmentBox() ) ht.addCloned( self.conf.cell ) + ht.addCloned( self.conf.corona ) etesian = Etesian.EtesianEngine.create( coreCell ) etesian.setViewer( self.conf.viewer ) etesian.place() @@ -162,6 +167,10 @@ class PlaceRoute ( object ): def doChipPlacement ( self ): + if not self.validated: + raise ErrorMessage( 1, 'chip.doChipPlacement(): Chip is not valid, aborting.' ) + return + padsCorona = chip.PadsCorona.Corona( self.conf ) self.validated = padsCorona.validate() if not self.validated: return False @@ -190,8 +199,13 @@ class PlaceRoute ( object ): 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.printConfiguration () katana.digitalInit () #katana.runNegociatePreRouted() katana.runGlobalRouter () @@ -203,3 +217,14 @@ class PlaceRoute ( object ): 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 diff --git a/cumulus/src/plugins/chip/Configuration.py b/cumulus/src/plugins/chip/Configuration.py index 45d30092..79cab7af 100644 --- a/cumulus/src/plugins/chip/Configuration.py +++ b/cumulus/src/plugins/chip/Configuration.py @@ -34,10 +34,10 @@ from Hurricane import Plug from Hurricane import Instance import CRL from CRL import RoutingLayerGauge -from helpers import trace -from helpers import ErrorMessage -from helpers import WarningMessage -from plugins import getParameter +from helpers import trace +from helpers.io import ErrorMessage +from helpers.io import WarningMessage +from plugins import getParameter import chip @@ -146,7 +146,7 @@ class GaugeConf ( object ): self.cellGauge = CRL.AllianceFramework.get().getCellGauge( gaugeName ) self.routingGauge = CRL.AllianceFramework.get().getRoutingGauge( gaugeName ) - topLayer = Cfg.getParamString('katabatic.topRoutingLayer').asString() + topLayer = Cfg.getParamString('anabatic.topRoutingLayer').asString() self.topLayerDepth = 0 for layerGauge in self.routingGauge.getLayerGauges(): @@ -156,13 +156,16 @@ class GaugeConf ( object ): if not self.topLayerDepth: print WarningMessage( 'Gauge top layer not defined, using top of gauge (%d).' \ % self.routingGauge.getDepth() ) - self.topLayerDepth = self.routingGauge.getDepth() + self.topLayerDepth = self.routingGauge.getDepth() - 1 self.horizontalDepth = -1 self.verticalDepth = -1 self.horizontalDeepDepth = -1 self.verticalDeepDepth = -1 for depth in range(0,self.topLayerDepth+1): + trace( 550, '\tdepth:%d\n' % depth ) + trace( 550, '\t%s\n' % self.routingGauge.getLayerGauge(depth) ) + if self.routingGauge.getLayerGauge(depth).getType() == RoutingLayerGauge.PinOnly: continue if self.routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Horizontal: @@ -281,7 +284,8 @@ class GaugeConf ( object ): if flags & GaugeConf.HAccess: stopDepth = hdepth else: stopDepth = vdepth - + trace( 550, '\tstopDepth:%d\n' % stopDepth ) + for depth in range(1,stopDepth): xoffset = 0 if flags & GaugeConf.OffsetRight1 and depth == 1: @@ -365,7 +369,7 @@ class GaugeConf ( object ): segment = component count += 1 if count != 1: - print ErrorMessage( 1, 'GaugeConf::_setStackPosition(): There must be exactly one segment connected, not %d.' % count) + raise ErrorMessage( 1, 'GaugeConf::_setStackPosition(): There must be exactly one segment connected to %s, not %d.' % (topContact,count) ) if isinstance(segment,Horizontal): segment.setY( y ) @@ -446,7 +450,7 @@ class ChipConf ( object ): def _loadIoPadGauge ( self, chipConfigDict ): if not chipConfigDict.has_key('pads.ioPadGauge'): - print ErrorMessage( 1, 'The IO pad gauge configuration paramater "pads.ioPadGauge" is missing.' ) + raise ErrorMessage( 1, 'The IO pad gauge configuration paramater "pads.ioPadGauge" is missing.' ) return self.gaugeConf._loadIoPadGauge( chipConfigDict['pads.ioPadGauge'] ) return @@ -456,7 +460,7 @@ class ChipConf ( object ): if not chipConfigDict.has_key(keyword): return [] padConfList = chipConfigDict[keyword] if not isinstance(padConfList,list): - print ErrorMessage( 1, 'The "%s" entry is not a list.' ) + raise ErrorMessage( 1, 'The "%s" entry is not a list.' ) return [] af = CRL.AllianceFramework.get() @@ -473,19 +477,19 @@ class ChipConf ( object ): instanceName = padConfList[i][1] if not instanceName: - print ErrorMessage( 1, 'The element [%d] of list %s is neither a string nor a list "[pos,name]" (skipped).' - % (i,keyword) ) + raise ErrorMessage( 1, 'The element [%d] of list %s is neither a string nor a list "[pos,name]" (skipped).' + % (i,keyword) ) continue instance = self.cell.getInstance( instanceName ) if not instance: - print ErrorMessage( 1, 'The pad [%d] (%s) of list %s do not exists in netlist (skipped).' - % (i,instanceName,keyword) ) + raise ErrorMessage( 1, 'The pad [%d] (%s) of list %s do not exists in netlist (skipped).' + % (i,instanceName,keyword) ) continue if (instance.getMasterCell().getAbutmentBox().getHeight() != self.gaugeConf.getIoPadHeight()): - print ErrorMessage( 1, 'The pad [%d] (%s) of list %s is not an instance of a pad cell (skipped).' - % (i,instanceName,keyword) ) + raise ErrorMessage( 1, 'The pad [%d] (%s) of list %s is not an instance of a pad cell (skipped).' + % (i,instanceName,keyword) ) continue padList.append( [ position, instance ] ) @@ -568,7 +572,7 @@ class ChipConf ( object ): if instance.getCell() == self.cell: return ab if instance.getCell() != self.corona: - print ErrorMessage( 1, 'ChipConf.getInstanceAb(): Instance "%s" neither belong to chip or corona.' % instance.getName() ) + raise ErrorMessage( 1, 'ChipConf.getInstanceAb(): Instance "%s" neither belong to chip or corona.' % instance.getName() ) return ab self.icorona.getTransformation().applyOn( ab ) @@ -863,7 +867,7 @@ class ChipConf ( object ): if contains(self.eastPads ,instance): continue if contains(self.westPads ,instance): continue if (instance.getMasterCell().getAbutmentBox().getHeight() == self.gaugeConf.getIoPadHeight()): - print ErrorMessage( 1, 'Pad "%s" is not on any side (N/S/E/W).' % instance.getName() ) + raise ErrorMessage( 1, 'Pad "%s" is not on any side (N/S/E/W).' % instance.getName() ) self.validated = False else: self.coronas.append( instance ) @@ -872,11 +876,11 @@ class ChipConf ( object ): message = [ 'Chip "%s" have more than one corona:' % self.cell.getName() ] for i in range(len(self.coronas)): message.append( '%4d: %s' % (i,self.coronas[i].getName()) ) - print ErrorMessage( 1, message ) + raise ErrorMessage( 1, message ) self.validated = False if len(self.coronas) < 1: - print ErrorMessage( 1, 'Chip "%s" doesn\'t seems to have a corona.' % self.cell.getName() ) + raise ErrorMessage( 1, 'Chip "%s" doesn\'t seems to have a corona.' % self.cell.getName() ) self.validated = False else: for instance in self.corona.getInstances(): self.cores.append( instance ) @@ -885,11 +889,11 @@ class ChipConf ( object ): message = [ 'Chip "%s" have more than one core:' % self.cell.getName() ] for i in range(len(self.cores)): message.append( '%4d: %s' % (i,self.cores[i].getName()) ) - print ErrorMessage( 1, message ) + raise ErrorMessage( 1, message ) self.validated = False if len(self.cores) < 1: - print ErrorMessage( 1, 'Chip "%s" doesn\'t seems to have a core.' % self.cell.getName() ) + raise ErrorMessage( 1, 'Chip "%s" doesn\'t seems to have a core.' % self.cell.getName() ) self.validated = False return @@ -909,15 +913,15 @@ class ChipConf ( object ): if not net: net = self.corona.getNet( masterNet.getName() ) if not net: - print ErrorMessage( 1, 'ChipConf.findPowerAndClockNets(): Missing global net "%s" at corona level.' - % masterNet.getName() ) + raise ErrorMessage( 1, 'ChipConf.findPowerAndClockNets(): Missing global net "%s" at corona level.' + % masterNet.getName() ) self._validated = False continue if netType == Net.Type.GROUND: if self.coronaVss and self.coronaVss != net: - print ErrorMessage( 1, 'ChipConf.findPowerAndClockNets(): Multiple ground nets "%s" and "%s" at corona level.' - % (self.coronaVss.getName(), net.getName()) ) + raise ErrorMessage( 1, 'ChipConf.findPowerAndClockNets(): Multiple ground nets "%s" and "%s" at corona level.' + % (self.coronaVss.getName(), net.getName()) ) self._validated = False continue else: @@ -925,8 +929,8 @@ class ChipConf ( object ): if netType == Net.Type.POWER: if self.coronaVdd and self.coronaVdd != net: - print ErrorMessage( 1, 'ChipConf.findPowerAndClockNets(): Multiple power nets "%s" and "%s" at corona level.' - % (self.coronaVdd.getName(), net.getName()) ) + raise ErrorMessage( 1, 'ChipConf.findPowerAndClockNets(): Multiple power nets "%s" and "%s" at corona level.' + % (self.coronaVdd.getName(), net.getName()) ) self._validated = False continue else: @@ -934,8 +938,8 @@ class ChipConf ( object ): if netType == Net.Type.CLOCK: if self.coronaCk and self.coronaCk != net: - print ErrorMessage( 1, 'ChipConf.findPowerAndClockNets(): Multiple clock nets "%s" and "%s" at corona level.' - % (self.coronaCk.getName(), net.getName()) ) + raise ErrorMessage( 1, 'ChipConf.findPowerAndClockNets(): Multiple clock nets "%s" and "%s" at corona level.' + % (self.coronaCk.getName(), net.getName()) ) self._validated = False continue else: @@ -952,6 +956,23 @@ class ChipConf ( object ): return + def checkChipSize ( self ): + #if self._coreSize.isEmpty(): return + # + #minWidth = self._coreSize.getWidth () + self._minCorona + 2*self._padHeight + #minHeight = self._coreSize.getHeight() + self._minCorona + 2*self._padHeight + # + #if self._chipSize.getWidth() < minWidth: + # raise ErrorMessage( 1, 'Core is too wide to fit into the chip. Needs: %d, but has %d' \ + # % ( DbU.toLambda(minWidth), DbU.toLambda(self._chipSize.getWidth()) ) ) + # self._validated = False + # + #if self._chipSize.getHeight() < minHeight: + # raise ErrorMessage( 1, 'Core is too wide to fit into the chip. Needs: %d, but has %d' \ + # % ( DbU.toLambda(minHeight), DbU.toLambda(self._chipSize.getHeight()) ) ) + # self._validated = False + return + def checkCorona ( self ): trace( 550, ',+', 'Configuration.checkCorona()\n' ) netPads = {} @@ -966,8 +987,8 @@ class ChipConf ( object ): trace( 550, '\t%20s <-> %-20s\n' % (padNet.getName(),coronaNet.getName()) ) netPads[ padNet ] = coronaNet else: - print ErrorMessage( 1, 'ChipConf.checkCorona(): Corona nets "%s" and "%s" connected to the same pad net "%s".' \ - % (coronaNet.getName(),netPads[padNet].getName(),padNet.getName()) ) + raise ErrorMessage( 1, 'ChipConf.checkCorona(): Corona nets "%s" and "%s" connected to the same pad net "%s".' \ + % (coronaNet.getName(),netPads[padNet].getName(),padNet.getName()) ) self._validated = False trace( 550, '-' ) @@ -1018,7 +1039,7 @@ class ChipConf ( object ): def setupCore ( self, gapX1, gapY1, gapX2, gapY2 ): ab = self.getInstanceAb( self.icorona ) if ab.isEmpty(): - print ErrorMessage( 1, 'ChipConf.setupCore(): Attempt to setup core *before* corona.' ) + raise ErrorMessage( 1, 'ChipConf.setupCore(): Attempt to setup core *before* corona.' ) return ab.inflate( -gapX1, -gapY1, -gapX2, -gapY2 ) @@ -1100,7 +1121,7 @@ def loadConfiguration ( cell, viewer=None ): confModule = __import__( confFile, globals(), locals(), confFile ) if not confModule.__dict__.has_key('chip'): - raise WarningMessage( 'Module <%s> do not provides the chip variable, skipped.' \ - % confFile ) + ErrorMessage( 1, 'Module <%s> do not provides the chip variable, skipped.' \ + % confFile ) return ChipConf( confModule.__dict__['chip'], cell, viewer ) diff --git a/cumulus/src/plugins/chip/PadsCorona.py b/cumulus/src/plugins/chip/PadsCorona.py index 961f70b7..6d8e6e16 100644 --- a/cumulus/src/plugins/chip/PadsCorona.py +++ b/cumulus/src/plugins/chip/PadsCorona.py @@ -15,30 +15,30 @@ import sys -from operator import itemgetter -import Cfg -from Hurricane import DbU -from Hurricane import Point -from Hurricane import Transformation -from Hurricane import Interval -from Hurricane import Box -from Hurricane import Path -from Hurricane import Occurrence -from Hurricane import UpdateSession -from Hurricane import Layer -from Hurricane import BasicLayer -from Hurricane import Net -from Hurricane import Pin -from Hurricane import Contact -from Hurricane import Segment -from Hurricane import Horizontal -from Hurricane import Vertical -from Hurricane import Instance -import CRL -from CRL import RoutingLayerGauge -from helpers import trace -from helpers import ErrorMessage -from helpers import WarningMessage +from operator import itemgetter +import Cfg +from Hurricane import DbU +from Hurricane import Point +from Hurricane import Transformation +from Hurricane import Interval +from Hurricane import Box +from Hurricane import Path +from Hurricane import Occurrence +from Hurricane import UpdateSession +from Hurricane import Layer +from Hurricane import BasicLayer +from Hurricane import Net +from Hurricane import Pin +from Hurricane import Contact +from Hurricane import Segment +from Hurricane import Horizontal +from Hurricane import Vertical +from Hurricane import Instance +import CRL +from CRL import RoutingLayerGauge +from helpers import trace +from helpers.io import ErrorMessage +from helpers.io import WarningMessage import chip.Configuration @@ -51,27 +51,31 @@ class Corner ( object ): return + @property + def conf ( self ): return self.corona.conf + + def _getPoints ( self, axis ): if self.type == chip.SouthWest: - xCorner = self.corona.conf.chipSize.getXMin() + axis - yCorner = self.corona.conf.chipSize.getYMin() + axis - xBb = self.corona.conf.chipSize.getXMin() + self.corona.conf.getIoPadHeight() - yBb = self.corona.conf.chipSize.getYMin() + self.corona.conf.getIoPadHeight() + xCorner = self.conf.chipSize.getXMin() + axis + yCorner = self.conf.chipSize.getYMin() + axis + xBb = self.conf.chipSize.getXMin() + self.conf.getIoPadHeight() + yBb = self.conf.chipSize.getYMin() + self.conf.getIoPadHeight() elif self.type == chip.SouthEast: - xCorner = self.corona.conf.chipSize.getXMax() - axis - yCorner = self.corona.conf.chipSize.getYMin() + axis - xBb = self.corona.conf.chipSize.getXMax() - self.corona.conf.getIoPadHeight() - yBb = self.corona.conf.chipSize.getYMin() + self.corona.conf.getIoPadHeight() + xCorner = self.conf.chipSize.getXMax() - axis + yCorner = self.conf.chipSize.getYMin() + axis + xBb = self.conf.chipSize.getXMax() - self.conf.getIoPadHeight() + yBb = self.conf.chipSize.getYMin() + self.conf.getIoPadHeight() elif self.type == chip.NorthEast: - xCorner = self.corona.conf.chipSize.getXMax() - axis - yCorner = self.corona.conf.chipSize.getYMax() - axis - xBb = self.corona.conf.chipSize.getXMax() - self.corona.conf.getIoPadHeight() - yBb = self.corona.conf.chipSize.getYMax() - self.corona.conf.getIoPadHeight() + xCorner = self.conf.chipSize.getXMax() - axis + yCorner = self.conf.chipSize.getYMax() - axis + xBb = self.conf.chipSize.getXMax() - self.conf.getIoPadHeight() + yBb = self.conf.chipSize.getYMax() - self.conf.getIoPadHeight() elif self.type == chip.NorthWest: - xCorner = self.corona.conf.chipSize.getXMin() + axis - yCorner = self.corona.conf.chipSize.getYMax() - axis - xBb = self.corona.conf.chipSize.getXMin() + self.corona.conf.getIoPadHeight() - yBb = self.corona.conf.chipSize.getYMax() - self.corona.conf.getIoPadHeight() + xCorner = self.conf.chipSize.getXMin() + axis + yCorner = self.conf.chipSize.getYMax() - axis + xBb = self.conf.chipSize.getXMin() + self.conf.getIoPadHeight() + yBb = self.conf.chipSize.getYMax() - self.conf.getIoPadHeight() return xCorner, yCorner, xBb, yBb @@ -94,8 +98,8 @@ class Corner ( object ): def _getTransformation ( self ): if self.type == chip.SouthWest: name = 'padcorner_sw' - x = self.corona.conf.chipSize.getXMin() - y = self.corona.conf.chipSize.getYMin() + x = self.conf.chipSize.getXMin() + y = self.conf.chipSize.getYMin() if self.corona.padOrient == Transformation.Orientation.ID: orientation = Transformation.Orientation.ID else: @@ -104,8 +108,8 @@ class Corner ( object ): elif self.type == chip.SouthEast: name = 'padcorner_se' - x = self.corona.conf.chipSize.getXMax() - y = self.corona.conf.chipSize.getYMin() + x = self.conf.chipSize.getXMax() + y = self.conf.chipSize.getYMin() if self.corona.padOrient == Transformation.Orientation.ID: orientation = Transformation.Orientation.R1 else: @@ -115,8 +119,8 @@ class Corner ( object ): elif self.type == chip.NorthEast: name = 'padcorner_ne' - x = self.corona.conf.chipSize.getXMax() - y = self.corona.conf.chipSize.getYMax() + x = self.conf.chipSize.getXMax() + y = self.conf.chipSize.getYMax() if self.corona.padOrient == Transformation.Orientation.ID: orientation = Transformation.Orientation.R2 else: @@ -126,8 +130,8 @@ class Corner ( object ): elif self.type == chip.NorthWest: name = 'padcorner_nw' - x = self.corona.conf.chipSize.getXMin() - y = self.corona.conf.chipSize.getYMax() + x = self.conf.chipSize.getXMin() + y = self.conf.chipSize.getYMax() if self.corona.padOrient == Transformation.Orientation.ID: orientation = Transformation.Orientation.R3 else: @@ -140,7 +144,7 @@ class Corner ( object ): def _instanciateCorner ( self ): name, transformation = self._getTransformation() - corner = Instance.create( self.corona.conf.cell + corner = Instance.create( self.conf.cell , name, self.corona.padCorner , transformation , Instance.PlacementStatus.FIXED @@ -160,29 +164,29 @@ class Side ( object ): self.type = sideType self.corona = corona self.pins = [] - self.u = self.corona.conf.getIoPadHeight() + self.u = self.conf.getIoPadHeight() self.spacerCount = 0 self.gap = 0 if self.type == chip.North: - self.pads = self.corona.conf.northPads + self.pads = self.conf.northPads self.sideName = 'north' - self.sideLength = self.corona.conf.chipSize.getWidth() + self.sideLength = self.conf.chipSize.getWidth() elif self.type == chip.South: - self.pads = self.corona.conf.southPads + self.pads = self.conf.southPads self.sideName = 'south' - self.sideLength = self.corona.conf.chipSize.getWidth() + self.sideLength = self.conf.chipSize.getWidth() elif self.type == chip.East: - self.pads = self.corona.conf.eastPads + self.pads = self.conf.eastPads self.sideName = 'east' - self.sideLength = self.corona.conf.chipSize.getHeight() + self.sideLength = self.conf.chipSize.getHeight() elif self.type == chip.West: - self.pads = self.corona.conf.westPads + self.pads = self.conf.westPads self.sideName = 'west' - self.sideLength = self.corona.conf.chipSize.getHeight() + self.sideLength = self.conf.chipSize.getHeight() else: raise ErrorMessage( 1, 'PadsCorona.Side.__init__(): Invalid value for sideType (%d)' % sideType ) @@ -191,14 +195,18 @@ class Side ( object ): return + @property + def conf ( self ): return self.corona.conf + + def toGrid ( self, u ): return self.corona.toGrid( u ) def getAxis ( self, i ): - if self.type == chip.North: return self.corona.conf.chipSize.getYMax() - self.corona.conf.getIoPadHeight() + self.corona.powerRails[i][2] - elif self.type == chip.South: return self.corona.conf.chipSize.getYMin() + self.corona.conf.getIoPadHeight() - self.corona.powerRails[i][2] - elif self.type == chip.East: return self.corona.conf.chipSize.getXMax() - self.corona.conf.getIoPadHeight() + self.corona.powerRails[i][2] - elif self.type == chip.West: return self.corona.conf.chipSize.getXMin() + self.corona.conf.getIoPadHeight() - self.corona.powerRails[i][2] + if self.type == chip.North: return self.conf.chipSize.getYMax() - self.conf.getIoPadHeight() + self.corona.powerRails[i][2] + elif self.type == chip.South: return self.conf.chipSize.getYMin() + self.conf.getIoPadHeight() - self.corona.powerRails[i][2] + elif self.type == chip.East: return self.conf.chipSize.getXMax() - self.conf.getIoPadHeight() + self.corona.powerRails[i][2] + elif self.type == chip.West: return self.conf.chipSize.getXMin() + self.conf.getIoPadHeight() - self.corona.powerRails[i][2] else: raise ErrorMessage( 1, 'PadsCorona.Side.__init__(): Invalid value for sideType (%d)' % sideType ) return 0 @@ -215,18 +223,18 @@ class Side ( object ): sideName = 'unknown' chipSize = 0 if self.type == chip.North or self.type == chip.South: - chipSize = self.corona.conf.chipSize.getWidth() + chipSize = self.conf.chipSize.getWidth() sideName = 'wide' elif self.type == chip.East or self.type == chip.West: - chipSize = self.corona.conf.chipSize.getHeight() + chipSize = self.conf.chipSize.getHeight() sideName = 'tall' if checkSize > chipSize: - sliceHeight = self.corona.conf.getSliceHeight() + sliceHeight = self.conf.getSliceHeight() if checkSize % sliceHeight != 0: checkSize += sliceHeight - (checkSize % sliceHeight) - print ErrorMessage( 1, [ 'Chip is not %s enought to accomodate the %s,' % (sideName,checkName) + raise ErrorMessage( 1, [ 'Chip is not %s enought to accomodate the %s,' % (sideName,checkName) , 'needs %s, but only has %s.' % ( DbU.getValueString(checkSize), DbU.getValueString(chipSize) ) ] ) @@ -237,26 +245,26 @@ class Side ( object ): def check ( self ): self.validated = True if self.type == chip.North: - #print DbU.getValueString(self.corona.conf.coreSize.getWidth()) - #print DbU.getValueString(self.corona.conf.minCorona) - #print DbU.getValueString(self.corona.conf.getIoPadHeight()) - self.validated = self._check( self.corona.conf.coreSize.getWidth() - + 2*self.corona.conf.minCorona - + 2*self.corona.conf.getIoPadHeight() + #print DbU.getValueString(self.conf.coreSize.getWidth()) + #print DbU.getValueString(self.conf.minCorona) + #print DbU.getValueString(self.conf.getIoPadHeight()) + self.validated = self._check( self.conf.coreSize.getWidth() + + 2*self.conf.minCorona + + 2*self.conf.getIoPadHeight() , 'core' ) checkName = 'north pads' elif self.type == chip.East: - self.validated = self._check( self.corona.conf.coreSize.getHeight() - + 2*self.corona.conf.minCorona - + 2*self.corona.conf.getIoPadHeight() + self.validated = self._check( self.conf.coreSize.getHeight() + + 2*self.conf.minCorona + + 2*self.conf.getIoPadHeight() , 'core' ) checkName = 'east pads' elif self.type == chip.South: checkName = 'south pads' elif self.type == chip.West: checkName = 'west pads' - #self.validated = self._check( len(self.pads) * self.corona.conf.padWidth - # + 2*self.corona.conf.padHeight - # , checkName ) and self.validated + self.validated = self._check( len(self.pads) * self.conf.gaugeConf.getIoPadStep () + + 2*self.conf.gaugeConf.getIoPadHeight() + , checkName ) and self.validated return self.validated @@ -354,7 +362,7 @@ class Side ( object ): while iPadSpacer < len(self.corona.padSpacers) and gapWidth > 0: gapWidth -= _getWidth( self.corona.padSpacers[iPadSpacer] ) - spacer = Instance.create( self.corona.conf.cell + spacer = Instance.create( self.conf.cell , self.spacerNames % self.spacerCount , self.corona.padSpacers[iPadSpacer]) self.spacerCount += 1 @@ -364,7 +372,7 @@ class Side ( object ): iPadSpacer = _nextSpacer( iPadSpacer ) if gapWidth != 0: - print ErrorMessage( 1, 'PadsCorona.Side._placePads(): Pad fillers cannot close the gap between pads on %s side, %s remains.' \ + raise ErrorMessage( 1, 'PadsCorona.Side._placePads(): Pad fillers cannot close the gap between pads on %s side, %s remains.' \ % (self.sideName,DbU.getValueString(gapWidth)) ) self.u += gapWidth @@ -373,28 +381,28 @@ class Side ( object ): def _placePad ( self, padInstance ): if self.type == chip.North: - x = self.corona.conf.chipSize.getXMin() + self.u - y = self.corona.conf.chipSize.getYMax() + x = self.conf.chipSize.getXMin() + self.u + y = self.conf.chipSize.getYMax() if self.corona.padOrient == Transformation.Orientation.ID: orientation = Transformation.Orientation.MY else: orientation = Transformation.Orientation.ID - y -= self.corona.conf.getIoPadHeight() + y -= self.conf.getIoPadHeight() elif self.type == chip.South: - x = self.corona.conf.chipSize.getXMin() + self.u - y = self.corona.conf.chipSize.getYMin() + x = self.conf.chipSize.getXMin() + self.u + y = self.conf.chipSize.getYMin() if self.corona.padOrient == Transformation.Orientation.ID: orientation = Transformation.Orientation.ID else: orientation = Transformation.Orientation.MY - y += self.corona.conf.getIoPadHeight() + y += self.conf.getIoPadHeight() elif self.type == chip.West: - x = self.corona.conf.chipSize.getXMin() - y = self.corona.conf.chipSize.getYMin() + self.u + x = self.conf.chipSize.getXMin() + y = self.conf.chipSize.getYMin() + self.u if self.corona.padOrient == Transformation.Orientation.ID: orientation = Transformation.Orientation.R3 @@ -404,8 +412,8 @@ class Side ( object ): x += padInstance.getMasterCell().getAbutmentBox().getHeight() elif self.type == chip.East: - x = self.corona.conf.chipSize.getXMax() - y = self.corona.conf.chipSize.getYMin() + self.u + x = self.conf.chipSize.getXMax() + y = self.conf.chipSize.getYMin() + self.u if self.corona.padOrient == Transformation.Orientation.ID: orientation = Transformation.Orientation.R1 @@ -424,9 +432,9 @@ class Side ( object ): def _placePads ( self ): padLength = 0 for pad in self.pads: padLength += pad[1].getMasterCell().getAbutmentBox().getWidth() - padSpacing = (self.sideLength - 2*self.corona.conf.getIoPadHeight() - padLength) / (len(self.pads) + 1) + padSpacing = (self.sideLength - 2*self.conf.getIoPadHeight() - padLength) / (len(self.pads) + 1) - if self.corona.conf.padsHavePosition: + if self.conf.padsHavePosition: for i in range(len(self.pads)): self.pads[i][0] = self.toGrid( self.pads[i][0] ) else: @@ -440,7 +448,7 @@ class Side ( object ): self._fillPadSpacing( pad[0] - self.u ) self._placePad( pad[1] ) - self._fillPadSpacing( self.sideLength - self.corona.conf.getIoPadHeight() - self.u ) + self._fillPadSpacing( self.sideLength - self.conf.getIoPadHeight() - self.u ) return @@ -459,7 +467,7 @@ class Side ( object ): def _createSegment ( self, rail, uMin, uMax ): net, layer, axis, width = rail - if self.corona.conf.getIoPadGauge().getName() == 'pxlib': + if self.conf.getIoPadGauge().getName() == 'pxlib': if net.isClock(): uMin -= DbU.fromLambda(5.0) uMax += DbU.fromLambda(5.0) @@ -469,46 +477,46 @@ class Side ( object ): if self.type == chip.North or self.type == chip.South: if self.type == chip.North: - axis = self.corona.conf.chipSize.getYMax() - axis + axis = self.conf.chipSize.getYMax() - axis Horizontal.create( net, layer, axis, width, uMin, uMax ) else: if self.type == chip.East: - axis = self.corona.conf.chipSize.getXMax() - axis + axis = self.conf.chipSize.getXMax() - axis Vertical.create( net, layer, axis, width, uMin, uMax ) return def _routePads ( self ): if self.type == chip.South or self.type == chip.North: - startCorner = self.corona.conf.chipSize.getXMin() - stopCorner = self.corona.conf.chipSize.getXMax() + startCorner = self.conf.chipSize.getXMin() + stopCorner = self.conf.chipSize.getXMax() elif self.type == chip.West or self.type == chip.East: - startCorner = self.corona.conf.chipSize.getYMin() - stopCorner = self.corona.conf.chipSize.getYMax() + startCorner = self.conf.chipSize.getYMin() + stopCorner = self.conf.chipSize.getYMax() else: return - startCorner += self.corona.conf.getIoPadHeight() - stopCorner -= self.corona.conf.getIoPadHeight() + startCorner += self.conf.getIoPadHeight() + stopCorner -= self.conf.getIoPadHeight() if len(self.pads) == 0: return - padAb = self.corona.conf.getInstanceAb( self.pads[0][1] ) + padAb = self.conf.getInstanceAb( self.pads[0][1] ) for irail in range(len(self.corona.padRails)): self._createSegment( self.corona.padRails[ irail ] , startCorner , self._getUMin(padAb) ) - padAb = self.corona.conf.getInstanceAb( self.pads[-1][1] ) + padAb = self.conf.getInstanceAb( self.pads[-1][1] ) for irail in range(len(self.corona.padRails)): self._createSegment( self.corona.padRails[ irail ] , self._getUMax(padAb) , stopCorner ) for i in range(len(self.pads)-1): - padAb1 = self.corona.conf.getInstanceAb( self.pads[i ][1] ) - padAb2 = self.corona.conf.getInstanceAb( self.pads[i+1][1] ) + padAb1 = self.conf.getInstanceAb( self.pads[i ][1] ) + padAb2 = self.conf.getInstanceAb( self.pads[i+1][1] ) for rail in self.corona.padRails: self._createSegment( rail, self._getUMax(padAb1), self._getUMin(padAb2) ) @@ -541,12 +549,18 @@ class CoreWire ( object ): return + @property + def conf ( self ): return self.corona.conf + + def _computeCoreLayers ( self ): - rg = self.corona.conf.gaugeConf.routingGauge + rg = self.conf.gaugeConf.routingGauge mask = self.padSegment.getLayer().getMask() self.symSegmentLayer = None for layerGauge in rg.getLayerGauges(): + if layerGauge.getDepth() > self.conf.gaugeConf.topLayerDepth: break + if layerGauge.getLayer().getMask() == mask: self.symSegmentLayer = layerGauge.getLayer() @@ -558,7 +572,7 @@ class CoreWire ( object ): self.symContactSize = ( self.bbSegment.getWidth(), layerGauge.getWireWidth() ) else: depth = layerGauge.getDepth() - if layerGauge.getDepth() + 1 >= rg.getDepth(): + if layerGauge.getDepth() + 1 > self.conf.gaugeConf.topLayerDepth: self.symSegmentLayer = rg.getLayerGauge( depth-1 ).getLayer() depth -= 1 else: @@ -584,8 +598,8 @@ class CoreWire ( object ): trace( 550, '\tarraySize = (%d,%d)\n' % (self.arraySize[0], self.arraySize[1]) ) return - print ErrorMessage( 1, 'CoreWire._computeCoreLayers(): Layer of IO pad segment "%s" is not in routing gauge.' \ - % self.chipNet.getName() ) + raise ErrorMessage( 1, 'CoreWire._computeCoreLayers(): Layer of IO pad segment "%s" is not in routing gauge.' \ + % self.chipNet.getName() ) return @@ -593,7 +607,7 @@ class CoreWire ( object ): def drawWire ( self ): trace( 550, ',+', '\tCoreWire.drawWire(): chip:"%s"\n' %(self.chipNet.getName()) ) - coreAb = self.corona.conf.getInstanceAb( self.corona.conf.icorona ) + coreAb = self.conf.getInstanceAb( self.conf.icorona ) self._computeCoreLayers() @@ -630,7 +644,7 @@ class CoreWire ( object ): ) trace( 550, '\tself.arraySize: %s\n' % str(self.arraySize) ) if self.arraySize: - contacts = self.corona.conf.coronaContactArray( self.chipNet + contacts = self.conf.coronaContactArray( self.chipNet , self.symContactLayer , xContact , self.bbSegment.getCenter().getY() @@ -641,7 +655,7 @@ class CoreWire ( object ): for contact in contacts: vStrapBb.merge( contact.getBoundingBox() ) else: - contact = self.corona.conf.coronaContact( self.chipNet + contact = self.conf.coronaContact( self.chipNet , self.symContactLayer , xContact , self.bbSegment.getCenter().getY() @@ -652,7 +666,7 @@ class CoreWire ( object ): vStrapBb = contact.getBoundingBox( padLayer ) hRealBb = hReal.getBoundingBox( padLayer ) - self.corona.conf.icorona.getTransformation().applyOn( vStrapBb ) + self.conf.icorona.getTransformation().applyOn( vStrapBb ) vStrapBb.merge( vStrapBb.getXMin(), hRealBb.getYMin() ) vStrapBb.merge( vStrapBb.getXMin(), hRealBb.getYMax() ) if self.padSegment.getLayer().isSymbolic(): @@ -671,7 +685,7 @@ class CoreWire ( object ): if self.side == chip.West: xContact = min( xContact, vStrapBb.getXMin() ) else: xContact = max( xContact, vStrapBb.getXMax() ) - self.corona.conf.coronaHorizontal( self.chipNet + self.conf.coronaHorizontal( self.chipNet , self.symSegmentLayer , self.bbSegment.getCenter().getY() , self.bbSegment.getHeight() @@ -679,7 +693,7 @@ class CoreWire ( object ): , xCore ) trace( 550, '\tCORONA PIN: %s %d\n' % (self.chipNet, self.count) ) - pin = self.corona.conf.coronaPin( self.chipNet + pin = self.conf.coronaPin( self.chipNet , self.count , accessDirection , self.symSegmentLayer @@ -717,29 +731,29 @@ class CoreWire ( object ): ) trace( 550, '\tself.arraySize: %s\n' % str(self.arraySize) ) if self.arraySize: - contacts = self.corona.conf.coronaContactArray( self.chipNet - , self.symContactLayer - , self.bbSegment.getCenter().getX() - , yContact - , self.arraySize - , flags - ) + contacts = self.conf.coronaContactArray( self.chipNet + , self.symContactLayer + , self.bbSegment.getCenter().getX() + , yContact + , self.arraySize + , flags + ) hStrapBb = Box() for contact in contacts: hStrapBb.merge( contact.getBoundingBox() ) else: - contact = self.corona.conf.coronaContact( self.chipNet - , self.symContactLayer - , self.bbSegment.getCenter().getX() - , yContact - , self.symContactSize[0] - , self.symContactSize[1] - , flags - ) + contact = self.conf.coronaContact( self.chipNet + , self.symContactLayer + , self.bbSegment.getCenter().getX() + , yContact + , self.symContactSize[0] + , self.symContactSize[1] + , flags + ) hStrapBb = contact.getBoundingBox( padLayer ) vRealBb = vReal.getBoundingBox() - self.corona.conf.icorona.getTransformation().applyOn( hStrapBb ) + self.conf.icorona.getTransformation().applyOn( hStrapBb ) hStrapBb.merge( vRealBb.getXMin(), hStrapBb.getYMin() ) hStrapBb.merge( vRealBb.getXMax(), hStrapBb.getYMin() ) if self.padSegment.getLayer().isSymbolic(): @@ -758,22 +772,22 @@ class CoreWire ( object ): if self.side == chip.South: yContact = min( yContact, hStrapBb.getYMin() ) else: yContact = max( yContact, hStrapBb.getYMax() ) - self.corona.conf.coronaVertical( self.chipNet - , self.symSegmentLayer - , self.bbSegment.getCenter().getX() - , self.bbSegment.getWidth() - , yContact - , yCore - ) - pin = self.corona.conf.coronaPin( self.chipNet - , self.count - , accessDirection - , self.symSegmentLayer - , self.bbSegment.getCenter().getX() - , yCore - , self.bbSegment.getWidth() - , DbU.fromLambda( 1.0 ) - ) + self.conf.coronaVertical( self.chipNet + , self.symSegmentLayer + , self.bbSegment.getCenter().getX() + , self.bbSegment.getWidth() + , yContact + , yCore + ) + pin = self.conf.coronaPin( self.chipNet + , self.count + , accessDirection + , self.symSegmentLayer + , self.bbSegment.getCenter().getX() + , yCore + , self.bbSegment.getWidth() + , DbU.fromLambda( 1.0 ) + ) if self.side & chip.North: self.corona.northSide.pins.append( pin ) if self.side & chip.South: self.corona.southSide.pins.append( pin ) @@ -795,8 +809,8 @@ class Corona ( object ): if width1 > width2: return -1 return 1 - self.conf = conf - self.validated = False + self.conf = conf + self.validated = False self.northSide = Side( self, chip.North ) self.southSide = Side( self, chip.South ) self.eastSide = Side( self, chip.East ) @@ -822,7 +836,7 @@ class Corona ( object ): spacerCell = self.padLib.getCell( spacerName ) if spacerCell: self.padSpacers.append( spacerCell ) else: - print ErrorMessage( 1, 'Corona.__init__(): Missing spacer cell "%s"' % spacerName ) + raise ErrorMessage( 1, 'Corona.__init__(): Missing spacer cell "%s"' % spacerName ) self.padSpacers.sort( _cmpPad ) if Cfg.hasParameter('chip.padCorner'): @@ -919,10 +933,10 @@ class Corona ( object ): if plug.getMasterNet().isGlobal(): net = self.conf.cell.getNet( plug.getMasterNet().getName() ) if not net: - print ErrorMessage( 1, 'PadsCorona._padAnalysis(): Ring net "%s" is not connected and there is no global net (in pad \"%s").' \ + raise ErrorMessage( 1, 'PadsCorona._padAnalysis(): Ring net "%s" is not connected and there is no global net (in pad \"%s").' \ % plug.getMasterNet().getName(), padCell.getName() ) else: - print ErrorMessage( 1, 'PadsCorona._padAnalysis(): Ring net "%s" is neither connected nor global (in pad \"%s").' \ + raise ErrorMessage( 1, 'PadsCorona._padAnalysis(): Ring net "%s" is neither connected nor global (in pad \"%s").' \ % plug.getMasterNet().getName(), padCell.getName() ) if net: @@ -952,6 +966,9 @@ class Corona ( object ): if bb.intersect(innerBb): lg = rg.getLayerGauge( component.getLayer() ) depth = lg.getDepth() + print 'depth:', depth, 'topLayerDepth:', self.conf.gaugeConf.topLayerDepth + if depth > self.conf.gaugeConf.topLayerDepth: continue + if lg.getDirection() == RoutingLayerGauge.Vertical: if not vsegments.has_key(depth): vsegments[ depth ] = [] vsegments[ depth ].append( (component,bb) ) @@ -959,6 +976,14 @@ class Corona ( object ): if not hsegments.has_key(depth): hsegments[ depth ] = [] hsegments[ depth ].append( (component,bb) ) + #if len(vsegments) + len(hsegments) == 0: + # raise ErrorMessage( 1, [ 'Corona._createCorewire(): No connector of "%s" in I/O pad "%s" is in routing gauge range (top layer "%s")' \ + # % ( padNet.getName() + # , padInstance.getMasterCell().getName() + # , rg.getLayerGauge(self.conf.gaugeConf.topLayerDepth).getLayer().getName() ) + # , 'while connecting corona net "%s"' % chipIntNet.getName() + # ] ) + gapWidth = 0 segments = None inPreferredDir = False @@ -993,7 +1018,7 @@ class Corona ( object ): def _placeInnerCorona ( self ): - rg = self.conf.gaugeConf.routingGauge + rg = self.conf.gaugeConf.routingGauge coronaSouthGap = 0 for layerGauge in rg.getLayerGauges(): @@ -1007,13 +1032,14 @@ class Corona ( object ): for coronaPlug in self.conf.icorona.getPlugs(): chipIntNet = coronaPlug.getNet() if not chipIntNet: - print ErrorMessage( 1, 'PadsCorona._placeInnerCorona(): Corona net "%s" is not connected to a pad.' \ + raise ErrorMessage( 1, 'PadsCorona._placeInnerCorona(): Corona net "%s" is not connected to a pad.' \ % coronaPlug.getMasterNet().getName() ) continue padConnected = 0 doneInstances = [] for chipPlug in chipIntNet.getPlugs(): + print 'plug:', chipPlug doneInstances.append( chipPlug.getInstance() ) padNet = chipPlug.getMasterNet() padWires = self._createCoreWire( chipIntNet, padNet, doneInstances[-1], padConnected ) @@ -1021,6 +1047,7 @@ class Corona ( object ): coreWires += padWires padConnected += len(padWires) + print 'chipInNet:', chipIntNet if chipIntNet.isGlobal(): for instance in self.conf.cell.getInstances(): if instance in doneInstances: continue @@ -1035,7 +1062,7 @@ class Corona ( object ): padConnected += len(padWires) if padConnected == 0: - print ErrorMessage( 1, 'PadsCorona._placeInnerCorona(): Chip net "%s" is not connected to a pad.' \ + raise ErrorMessage( 1, 'PadsCorona._placeInnerCorona(): Chip net "%s" is not connected to a pad.' \ % chipIntNet.getName() ) self.conf.setupCorona( self.westSide.gap, self.southSide.gap, self.eastSide.gap, self.northSide.gap ) diff --git a/cumulus/src/plugins/clocktree/ClockTree.py b/cumulus/src/plugins/clocktree/ClockTree.py index df01e822..d48ab17c 100755 --- a/cumulus/src/plugins/clocktree/ClockTree.py +++ b/cumulus/src/plugins/clocktree/ClockTree.py @@ -21,30 +21,30 @@ try: 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 + 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 import ErrorMessage + from helpers import trace + from helpers.io import ErrorMessage import Unicorn import plugins - from clocktree.RSMT import RSMT + from clocktree.RSMT import RSMT from chip.Configuration import GaugeConf from chip.Configuration import getPlugByNet from chip.Configuration import getPlugByName @@ -95,7 +95,7 @@ class HTree ( object ): def __init__ ( self, conf, cell, clockNet, area ): self.conf = conf - self.minSide = DbU.fromLambda( Cfg.getParamInt('clockTree.minimumSide').asInt() ) + 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) ) @@ -341,7 +341,7 @@ class HTree ( object ): def _rsave ( self, cell ): flags = CRL.Catalog.State.Physical - if cell.getName().endswith('_clocked'): + if cell.getName().endswith('_cts'): flags = flags | CRL.Catalog.State.Logical self.framework.saveCell( cell, flags ) @@ -352,7 +352,7 @@ class HTree ( object ): def save ( self, topCell ): for cell in self.cloneds: - cell.setName( cell.getName()+'_clocked' ) + cell.setName( cell.getName()+'_cts' ) self._rsave( topCell ) return diff --git a/cumulus/src/plugins/clocktree/RSMT.py b/cumulus/src/plugins/clocktree/RSMT.py index 1412f026..f7a0f7bd 100644 --- a/cumulus/src/plugins/clocktree/RSMT.py +++ b/cumulus/src/plugins/clocktree/RSMT.py @@ -18,24 +18,24 @@ try: 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 + 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 + from CRL import RoutingLayerGauge import helpers - from helpers import trace - from helpers import ErrorMessage + from helpers import trace + from helpers.io import ErrorMessage import plugins except ImportError, e: serror = str(e) diff --git a/cumulus/src/plugins/core2chip/CoreToChip.py b/cumulus/src/plugins/core2chip/CoreToChip.py new file mode 100644 index 00000000..69408614 --- /dev/null +++ b/cumulus/src/plugins/core2chip/CoreToChip.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 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@asim.lip6.fr | +# | =============================================================== | +# | Python : "./plugins/coreToChip/Core2Chip.py" | +# +-----------------------------------------------------------------+ + +import sys +import re +import traceback +import os +import os.path +import optparse +import Cfg +import Hurricane +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 +import CRL +from CRL import Catalog +from CRL import AllianceFramework +from helpers.io import ErrorMessage +import Etesian +import Anabatic +import Katana +import Unicorn + + +# ------------------------------------------------------------------- +# Class : "IoNet". + + +class IoNet ( object ): + + reVHDLVector = re.compile( r'(?P[^(]*)\((?P[\d+])\)$' ) + + def __init__ ( self, coreToChip, coreNet ): + self.coreToChip = coreToChip + 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. + self.pads = [ ] + + m = IoNet.reVHDLVector.match( self.coreNet.getName() ) + if m: + self._isElem = True + self._name = m.group('name') + self._index = m.group('index') + else: + self._isElem = False + self._name = self.coreNet.getName() + self._index = 0 + + self._type = self.coreToChip.getNetType( self._name ) + return + + def isElem ( self ): return self._isElem + + 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._isElem: s += '(' + self._index + ')' + return s + + @property + def padNetName ( self ): + s = self._name + if self._isElem: s += '(' + self._index + ')' + return s + + @property + def padInstanceName ( self ): + s = self._name + if self._isElem: s += '_' + self._index + return s + + def buildNets ( self ): + self.chipExtNet = Net.create( self.coreToChip.chip, self.padNetName ) + self.chipExtNet.setExternal ( True ) + self.chipExtNet.setDirection( self.coreNet.getDirection() ) + + self.chipIntNet = Net.create( self.coreToChip.chip, self.coronaNetName ) + + self.coronaNet = Net.create( self.coreToChip.corona, self.coreNetName ) + self.coronaNet.setExternal ( True ) + self.coronaNet.setDirection( self.coreNet.getDirection() ) + + self.coreToChip.icorona.getPlug( self.coronaNet ).setNet( self.chipIntNet ) + self.coreToChip.icore .getPlug( self.coreNet ).setNet( self.coronaNet ) + + 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 + + if netType != Net.Type.LOGICAL: + self.chipIntNet.setType ( netType ) + self.coronaNet.setType ( netType ) + self.coronaNet.setGlobal( True ) + 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.ringNetNames = [ ] + self.ioPads = { } + self.chipPads = [ ] + self.padLib = None + self.core = core + self.chip = None + self.corona = None + self.icorona = None + self.icore = None + self.powerPadCount = 0 + self.groundPadCount = 0 + self.clockPadCount = 0 + return + + 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 = Net.create( self.chip, ringNetName ) + ringNet.setType ( self.getNetType(ringNetName) ) + ringNet.setGlobal( self.isGlobal (ringNetName) ) + return + + def _buildStandardPad ( self, ioNet ): + if not self.ioPads.has_key(ioNet.coreNet.getDirection()): + raise ErrorMessage( 1, 'CoreToChip._buildStandardPad(): Unsupported direction %d for core net "%s".' \ + % ioNet.coreNet.getName() ) + + padInfo = self.ioPads[ 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, chipName ): + af = AllianceFramework.get() + + UpdateSession.open() + + self.chip = af.createCell( 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() + + clockIoNets = [ ] + for coreNet in self.core.getNets(): + if not coreNet.isExternal(): continue + + ioNet = IoNet( self, coreNet ) + ioNet.buildNets() + + if coreNet.isPower(): self._buildPowerPads ( ioNet ) + elif coreNet.isGround(): self._buildGroundPads ( ioNet ) + elif coreNet.isClock(): clockIoNets.append( ioNet ) + else: self._buildStandardPad( ioNet ) + + for clockIoNet in clockIoNets: + self._buildClockPads( clockIoNet ) + + UpdateSession.close() + + af.saveCell( self.chip , Catalog.State.Logical ) + af.saveCell( self.corona, Catalog.State.Logical ) + return diff --git a/cumulus/src/plugins/core2chip/__init__.py b/cumulus/src/plugins/core2chip/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cumulus/src/plugins/core2chip/cmos.py b/cumulus/src/plugins/core2chip/cmos.py new file mode 100644 index 00000000..b07177a0 --- /dev/null +++ b/cumulus/src/plugins/core2chip/cmos.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 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@asim.lip6.fr | +# | =============================================================== | +# | Python : "./plugins/core2chip/cmos.py" | +# +-----------------------------------------------------------------+ + +import sys +import re +import traceback +import os +import os.path +import optparse +import Cfg +import Hurricane +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 +import CRL +from CRL import Catalog +from CRL import AllianceFramework +from helpers.io import ErrorMessage +from core2chip.CoreToChip import CoreToChip + + +class cmos ( CoreToChip ): + + def __init__ ( self, core ): + CoreToChip.__init__ ( self, core ) + self.ringNetNames = [ 'vsse', 'vssi', 'vdde', 'vddi', ('cki', 'ck') ] + self.ioPads = { Net.Direction.IN : CoreToChip.IoPadInfo( 'pi_px', 'pad', ['t',] ) + , Net.Direction.OUT : CoreToChip.IoPadInfo( 'po_px', 'pad', ['i',] ) + } + 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 + 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 ): + vssi = self.chip.getNet( 'vssi' ) + vssi.merge( ioNet.chipIntNet ) + ioNet.chipIntNet = vssi + + ioNet.pads.append( Instance.create( self.chip + , ioNet.padInstanceName + '_i_%d' % self.groundPadCount + , self.getCell('pvssick_px') ) ) + ioNet.pads.append( Instance.create( self.chip + , ioNet.padInstanceName + '_o_%d' % self.groundPadCount + , self.getCell('pvsseck_px') ) ) + + CoreToChip._connect( ioNet.pads[0], ioNet.chipIntNet, 'vssi' ) + CoreToChip._connect( ioNet.pads[1], ioNet.chipExtNet, 'vsse' ) + + for pad in ioNet.pads: self._connectRing( pad ) + self.groundPadCount += 1 + self.chipPads += ioNet.pads + return + + def _buildPowerPads ( self, ioNet ): + vddi = self.chip.getNet( 'vddi' ) + vddi.merge( ioNet.chipIntNet ) + ioNet.chipIntNet = vddi + + ioNet.pads.append( Instance.create( self.chip + , ioNet.padInstanceName + '_i_%d' % self.powerPadCount + , self.getCell('pvddick_px') ) ) + ioNet.pads.append( Instance.create( self.chip + , ioNet.padInstanceName + '_o_%d' % self.powerPadCount + , self.getCell('pvddeck_px') ) ) + + CoreToChip._connect( ioNet.pads[0], ioNet.chipIntNet, 'vddi' ) + CoreToChip._connect( ioNet.pads[1], ioNet.chipExtNet, 'vdde' ) + + for pad in ioNet.pads: self._connectRing( pad ) + self.powerPadCount += 1 + self.chipPads += ioNet.pads + return + + def _buildClockPads ( self, ioNet ): + ioNet.pads.append( Instance.create( self.chip + , ioNet.padInstanceName + '_%d' % self.clockPadCount + , self.getCell('pck_px') ) ) + + CoreToChip._connect( ioNet.pads[0], ioNet.chipExtNet, 'pad' ) + + for pad in ioNet.pads: self._connectRing( pad ) + self.clockPadCount += 1 + self.chipPads += ioNet.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 diff --git a/cumulus/src/tools/px2mpx.py b/cumulus/src/tools/px2mpx.py index 422c2ff5..554d780b 100755 --- a/cumulus/src/tools/px2mpx.py +++ b/cumulus/src/tools/px2mpx.py @@ -8,32 +8,32 @@ try: import math import Cfg import Hurricane - from Hurricane import DataBase - from Hurricane import DbU - from Hurricane import Transformation - from Hurricane import Box - from Hurricane import UpdateSession - from Hurricane import Breakpoint - from Hurricane import Net - from Hurricane import NetExternalComponents - from Hurricane import BasicLayer - from Hurricane import ContactLayer - from Hurricane import ViaLayer - from Hurricane import RegularLayer - from Hurricane import TransistorLayer - from Hurricane import DiffusionLayer - from Hurricane import Cell - from Hurricane import Instance - from Hurricane import Net - from Hurricane import Contact - from Hurricane import Horizontal - from Hurricane import Vertical + from Hurricane import DataBase + from Hurricane import DbU + from Hurricane import Transformation + from Hurricane import Box + from Hurricane import UpdateSession + from Hurricane import Breakpoint + from Hurricane import Net + from Hurricane import NetExternalComponents + from Hurricane import BasicLayer + from Hurricane import ContactLayer + from Hurricane import ViaLayer + from Hurricane import RegularLayer + from Hurricane import TransistorLayer + from Hurricane import DiffusionLayer + from Hurricane import Cell + from Hurricane import Instance + from Hurricane import Net + from Hurricane import Contact + from Hurricane import Horizontal + from Hurricane import Vertical import Viewer import CRL - from CRL import RoutingLayerGauge + from CRL import RoutingLayerGauge import helpers - from helpers import trace - from helpers import ErrorMessage + from helpers import trace + from helpers.io import ErrorMessage except ImportError, e: serror = str(e) if serror.startswith('No module named'): diff --git a/etesian/src/GraphicEtesianEngine.cpp b/etesian/src/GraphicEtesianEngine.cpp index bd37c00d..e5e11994 100644 --- a/etesian/src/GraphicEtesianEngine.cpp +++ b/etesian/src/GraphicEtesianEngine.cpp @@ -136,7 +136,7 @@ namespace Etesian { , "Place a block [Etesian]" , std::bind(&GraphicEtesianEngine::_place,this) , QIcon() - , "placeAndRoute.placeChip" + , "placeAndRoute.clockTree" ); } diff --git a/hurricane/src/hurricane/Error.cpp b/hurricane/src/hurricane/Error.cpp index e13363ac..e57d52e8 100644 --- a/hurricane/src/hurricane/Error.cpp +++ b/hurricane/src/hurricane/Error.cpp @@ -55,7 +55,7 @@ namespace Hurricane { : Exception () , _reason (reason) , _code (code) - , _backtrace(true) + , _backtrace(false) { } @@ -63,7 +63,7 @@ namespace Hurricane { : Exception () , _reason () , _code (0) - , _backtrace(true) + , _backtrace(false) { static char formatted [ 8192 ]; va_list args; @@ -80,7 +80,7 @@ namespace Hurricane { : Exception () , _reason () , _code (code) - , _backtrace(true) + , _backtrace(false) { static char formatted [ 8192 ]; va_list args; diff --git a/hurricane/src/hurricane/Library.cpp b/hurricane/src/hurricane/Library.cpp index 39a7bcbe..b01b495a 100644 --- a/hurricane/src/hurricane/Library.cpp +++ b/hurricane/src/hurricane/Library.cpp @@ -101,15 +101,18 @@ string Library::getHierarchicalName () const // ***************************************** { string rpath; - Library* library = getLibrary(); - do { + Library* library = getLibrary(); + Library* rootLibrary = DataBase::getDB()->getRootLibrary(); + + while ( library and (library != rootLibrary) ) { rpath.insert( 0, getString(library->getName())+"." ); library = library->getLibrary(); - } while ( library ); + } return rpath + getString(getName()); } + void Library::_postCreate() // ************************ { diff --git a/hurricane/src/hurricane/Net.cpp b/hurricane/src/hurricane/Net.cpp index 9ab6f1d6..c503a8c5 100644 --- a/hurricane/src/hurricane/Net.cpp +++ b/hurricane/src/hurricane/Net.cpp @@ -845,6 +845,7 @@ Net::Type::Type(string s) else if (s == "POWER" ) _code = POWER; else if (s == "GROUND" ) _code = GROUND; else if (s == "BLOCKAGE" ) _code = BLOCKAGE; + else if (s == "FUSED" ) _code = FUSED; } Net::Type& Net::Type::operator=(const Type& type) diff --git a/hurricane/src/hurricane/UpdateSession.cpp b/hurricane/src/hurricane/UpdateSession.cpp index c9ce1c86..6234d944 100644 --- a/hurricane/src/hurricane/UpdateSession.cpp +++ b/hurricane/src/hurricane/UpdateSession.cpp @@ -220,6 +220,9 @@ void UpdateSession::reset() } +size_t UpdateSession::getStackSize () +{ return (UPDATOR_STACK) ? UPDATOR_STACK->size() : 0; } + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Net.h b/hurricane/src/hurricane/hurricane/Net.h index a2408ea1..0423b303 100644 --- a/hurricane/src/hurricane/hurricane/Net.h +++ b/hurricane/src/hurricane/hurricane/Net.h @@ -58,7 +58,7 @@ class Net : public Entity { public: class Type { // *************** - public: enum Code {UNDEFINED=0, LOGICAL=1, CLOCK=2, POWER=3, GROUND=4, BLOCKAGE=5}; + public: enum Code {UNDEFINED=0, LOGICAL=1, CLOCK=2, POWER=3, GROUND=4, BLOCKAGE=5, FUSED=6}; private: Code _code; @@ -215,6 +215,7 @@ class Net : public Entity { public: bool isExternal () const {return _isExternal;}; public: bool isAutomatic() const {return _isAutomatic;}; public: bool isBlockage () const {return (_type == Type::BLOCKAGE);}; + public: bool isFused () const {return (_type == Type::FUSED);}; public: bool isLogical () const {return (_type == Type::LOGICAL);}; public: bool isClock () const {return (_type == Type::CLOCK);}; public: bool isPower () const {return (_type == Type::POWER);}; @@ -375,6 +376,7 @@ inline std::string getString case Hurricane::Net::Type::POWER: return "POWER"; case Hurricane::Net::Type::GROUND: return "GROUND"; case Hurricane::Net::Type::BLOCKAGE: return "BLOCKAGE"; + case Hurricane::Net::Type::FUSED: return "FUSED"; } return "ABNORMAL"; } diff --git a/hurricane/src/hurricane/hurricane/UpdateSession.h b/hurricane/src/hurricane/hurricane/UpdateSession.h index 9a16fb45..8660d563 100644 --- a/hurricane/src/hurricane/hurricane/UpdateSession.h +++ b/hurricane/src/hurricane/hurricane/UpdateSession.h @@ -75,6 +75,7 @@ class UpdateSession : public SharedProperty { public: static void open(); public: static void close(); public: static void reset(); + public: static size_t getStackSize(); }; diff --git a/hurricane/src/isobar/PyNet.cpp b/hurricane/src/isobar/PyNet.cpp index 41bad511..a0e84d12 100644 --- a/hurricane/src/isobar/PyNet.cpp +++ b/hurricane/src/isobar/PyNet.cpp @@ -94,6 +94,8 @@ extern "C" { DirectGetBoolAttribute(PyNet_isGlobal ,isGlobal ,PyNet,Net) DirectGetBoolAttribute(PyNet_isExternal ,isExternal ,PyNet,Net) DirectGetBoolAttribute(PyNet_isLogical ,isLogical ,PyNet,Net) + DirectGetBoolAttribute(PyNet_isBlockage ,isBlockage ,PyNet,Net) + DirectGetBoolAttribute(PyNet_isFused ,isFused ,PyNet,Net) DirectGetBoolAttribute(PyNet_isClock ,isClock ,PyNet,Net) DirectGetBoolAttribute(PyNet_isGround ,isGround ,PyNet,Net) DirectGetBoolAttribute(PyNet_isPower ,isPower ,PyNet,Net) @@ -453,6 +455,8 @@ extern "C" { , { "isGlobal" , (PyCFunction)PyNet_isGlobal , METH_NOARGS , "return true if the net is global" } , { "isExternal" , (PyCFunction)PyNet_isExternal , METH_NOARGS , "return true if the the net is external." } , { "isLogical" , (PyCFunction)PyNet_isLogical , METH_NOARGS , "return true if the net is logical ." } + , { "isBlockage" , (PyCFunction)PyNet_isBlockage , METH_NOARGS , "return true if the net is used for blockage ." } + , { "isFused" , (PyCFunction)PyNet_isFused , METH_NOARGS , "return true if the net a fused net." } , { "isClock" , (PyCFunction)PyNet_isClock , METH_NOARGS , "return true if the net is a clock" } , { "isPower" , (PyCFunction)PyNet_isPower , METH_NOARGS , "return true if the net is a power" } , { "isGround" , (PyCFunction)PyNet_isGround , METH_NOARGS , "return true if the net is a ground" } diff --git a/hurricane/src/isobar/PyNetType.cpp b/hurricane/src/isobar/PyNetType.cpp index daaa5e9e..c97d937b 100644 --- a/hurricane/src/isobar/PyNetType.cpp +++ b/hurricane/src/isobar/PyNetType.cpp @@ -98,6 +98,7 @@ extern "C" { LoadObjectConstant(PyTypeNetType.tp_dict,Net::Type::POWER ,"POWER" ); LoadObjectConstant(PyTypeNetType.tp_dict,Net::Type::GROUND ,"GROUND" ); LoadObjectConstant(PyTypeNetType.tp_dict,Net::Type::BLOCKAGE ,"BLOCKAGE" ); + LoadObjectConstant(PyTypeNetType.tp_dict,Net::Type::FUSED ,"FUSED" ); } diff --git a/hurricane/src/isobar/PyUpdateSession.cpp b/hurricane/src/isobar/PyUpdateSession.cpp index 123f663f..6cb341ff 100644 --- a/hurricane/src/isobar/PyUpdateSession.cpp +++ b/hurricane/src/isobar/PyUpdateSession.cpp @@ -4,8 +4,7 @@ // This file is part of the Coriolis Software. // Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved // -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | I s o b a r - Hurricane / Python Interface | // | | @@ -13,10 +12,7 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./PyUpdateSession.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include "hurricane/isobar/PyUpdateSession.h" @@ -67,14 +63,29 @@ extern "C" { Py_RETURN_NONE; } + + + static PyObject* PyUpdateSession_getStackSize ( PyObject* ) + { + cdebug_log(20,0) << "PyUpdateSession_getStackSize()" << endl; + + size_t stackSize = 0; + HTRY + stackSize = UpdateSession::getStackSize(); + HCATCH + + return Py_BuildValue ("I",stackSize); + } PyMethodDef PyUpdateSession_Methods[] = - { { "open" , (PyCFunction)PyUpdateSession_open, METH_NOARGS|METH_CLASS - , "Opens a new Update Session." } - , { "close" , (PyCFunction)PyUpdateSession_close, METH_NOARGS|METH_CLASS - , "Closes an Update Session." } - , {NULL, NULL, 0, NULL} /* sentinel */ + { { "open" , (PyCFunction)PyUpdateSession_open, METH_NOARGS|METH_CLASS + , "Opens a new Update Session." } + , { "close" , (PyCFunction)PyUpdateSession_close, METH_NOARGS|METH_CLASS + , "Closes an Update Session." } + , { "getStackSize", (PyCFunction)PyUpdateSession_getStackSize, METH_NOARGS|METH_CLASS + , "Return the number of currently opened Update Sessions." } + , {NULL, NULL, 0, NULL} /* sentinel */ }; diff --git a/hurricane/src/viewer/BreakpointWidget.cpp b/hurricane/src/viewer/BreakpointWidget.cpp index fca2cd02..78f78e84 100644 --- a/hurricane/src/viewer/BreakpointWidget.cpp +++ b/hurricane/src/viewer/BreakpointWidget.cpp @@ -47,9 +47,9 @@ namespace Hurricane { stopLabel->setText ( "Adjust Stop Level:" ); QPushButton* ok = new QPushButton (); - ok->setIcon ( QIcon(":/images/gnome-gmush.png") ); + ok->setIcon ( QIcon(":/images/angry-birds-chuck.png") ); ok->setFlat ( true ); - ok->setIconSize ( QSize(48,48) ); + ok->setIconSize ( QSize(200,200) ); QFrame* vLine = new QFrame (); vLine->setFrameShape ( QFrame::VLine ); diff --git a/hurricane/src/viewer/CellViewer.qrc b/hurricane/src/viewer/CellViewer.qrc index 6955f120..6e7c6388 100644 --- a/hurricane/src/viewer/CellViewer.qrc +++ b/hurricane/src/viewer/CellViewer.qrc @@ -14,5 +14,8 @@ images/gnome-gmush.png images/gnome-core.png images/i-core.png + images/angry-birds-red.png + images/angry-birds-chuck.png + images/angry-birds-bomb.png diff --git a/hurricane/src/viewer/CellWidget.cpp b/hurricane/src/viewer/CellWidget.cpp index 6b334fc4..b2f79bee 100644 --- a/hurricane/src/viewer/CellWidget.cpp +++ b/hurricane/src/viewer/CellWidget.cpp @@ -1070,7 +1070,7 @@ namespace Hurricane { static const Name noCell = "None"; if ( !_cell ) return noCell; - return _cell->getName(); + return _hierarchicalName; } diff --git a/hurricane/src/viewer/ExceptionWidget.cpp b/hurricane/src/viewer/ExceptionWidget.cpp index ed792e3b..b1a992b1 100644 --- a/hurricane/src/viewer/ExceptionWidget.cpp +++ b/hurricane/src/viewer/ExceptionWidget.cpp @@ -137,7 +137,7 @@ namespace Hurricane { QLabel* leftMargin = new QLabel (); leftMargin->setSizePolicy ( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding ); - leftMargin->setPixmap ( QPixmap(":/images/gnome-core.png") ); + leftMargin->setPixmap ( QPixmap(":/images/angry-birds-bomb.png").scaledToWidth(200) ); leftMargin->setStyleSheet ( "QLabel { background-color: #FF9999;" " padding: 5px }" ); diff --git a/hurricane/src/viewer/PyGraphics.cpp b/hurricane/src/viewer/PyGraphics.cpp index 1dff74bf..a729c202 100644 --- a/hurricane/src/viewer/PyGraphics.cpp +++ b/hurricane/src/viewer/PyGraphics.cpp @@ -68,6 +68,36 @@ extern "C" { } + PyObject* PyGraphics_isEnabled ( PyGraphics* ) + { + cdebug_log(20,0) << "PyGraphics_isEnabled()" << endl; + + bool isEnabled = false; + HTRY + Graphics* graphics = Graphics::getGraphics (); + isEnabled = graphics->isEnabled(); + HCATCH + + if (isEnabled) Py_RETURN_TRUE; + Py_RETURN_FALSE; + } + + + PyObject* PyGraphics_isHighDpi ( PyGraphics* ) + { + cdebug_log(20,0) << "PyGraphics_isHighDpi()" << endl; + + bool isHighDpi = false; + HTRY + Graphics* graphics = Graphics::getGraphics (); + isHighDpi = graphics->isHighDpi(); + HCATCH + + if (isHighDpi) Py_RETURN_TRUE; + Py_RETURN_FALSE; + } + + static PyObject* PyGraphics_setStyle ( PyObject*, PyObject* args ) { cdebug_log(20,0) << "PyGraphics_setStyle()" << endl; @@ -261,10 +291,6 @@ extern "C" { Py_RETURN_NONE; } - - // Standart Accessors (Attributes). - DirectGetBoolAttribute(PyGraphics_isEnabled,isEnabled,PyGraphics,Graphics) - static PyObject* PyGraphics_getStyles ( PyObject* ) { @@ -289,6 +315,8 @@ extern "C" { PyMethodDef PyGraphics_Methods[] = { { "isEnabled" , (PyCFunction)PyGraphics_isEnabled , METH_NOARGS |METH_STATIC , "Tells if the Qt part of Graphics has been activated." } + , { "isHighDpi" , (PyCFunction)PyGraphics_isHighDpi , METH_NOARGS |METH_STATIC + , "Tells if we are running with a Hi-DPI screen." } , { "get" , (PyCFunction)PyGraphics_get , METH_NOARGS |METH_STATIC , "Gets the Viewer Graphic Configuration." } , { "getStyle" , (PyCFunction)PyGraphics_getStyle , METH_VARARGS|METH_STATIC diff --git a/hurricane/src/viewer/hurricane/viewer/CellWidget.h b/hurricane/src/viewer/hurricane/viewer/CellWidget.h index a176e958..507af8be 100644 --- a/hurricane/src/viewer/hurricane/viewer/CellWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/CellWidget.h @@ -609,6 +609,7 @@ namespace Hurricane { private: Cell* _cell; Path _topPath; + Name _hierarchicalName; CellWidget* _cellWidget; SelectorCriterions _selection; RulerSet _rulers; @@ -632,7 +633,7 @@ namespace Hurricane { inline FindStateName ( const Name& ); inline bool operator() ( const shared_ptr& ); private: - const Name _cellName; + const Name _cellHierName; }; protected: @@ -917,6 +918,7 @@ namespace Hurricane { inline CellWidget::State::State ( Cell* cell, Path topPath ) : _cell (cell) , _topPath (topPath) + , _hierarchicalName () , _cellWidget (NULL) , _selection () , _rulers () @@ -935,6 +937,7 @@ namespace Hurricane { , _historyEnable (false) { _scaleHistory.push_back ( ScaleEntry(1.0,Point(0,0)) ); + if (_cell) _hierarchicalName = Name( _cell->getHierarchicalName() ); } @@ -955,7 +958,10 @@ namespace Hurricane { inline void CellWidget::State::setCell ( Cell* cell ) - { _cell = cell; } + { + _cell = cell; + if (_cell) _hierarchicalName = Name( _cell->getHierarchicalName() ); + } inline void CellWidget::State::setTopPath ( Path topPath ) @@ -1106,14 +1112,14 @@ namespace Hurricane { { return _scaleHistory[_ihistory]._scale; } - inline CellWidget::FindStateName::FindStateName ( const Name& cellName ) + inline CellWidget::FindStateName::FindStateName ( const Name& cellHierName ) : unary_function< const shared_ptr&, bool >() - , _cellName(cellName) + , _cellHierName(cellHierName) { } inline bool CellWidget::FindStateName::operator () ( const shared_ptr& state ) - { return state->getName() == _cellName; } + { return state->getName() == _cellHierName; } inline void CellWidget::setActiveCommand ( Command* command ) diff --git a/hurricane/src/viewer/images/angry-birds-bomb.png b/hurricane/src/viewer/images/angry-birds-bomb.png new file mode 100644 index 00000000..c70723b4 Binary files /dev/null and b/hurricane/src/viewer/images/angry-birds-bomb.png differ diff --git a/hurricane/src/viewer/images/angry-birds-chuck.png b/hurricane/src/viewer/images/angry-birds-chuck.png new file mode 100644 index 00000000..89021351 Binary files /dev/null and b/hurricane/src/viewer/images/angry-birds-chuck.png differ diff --git a/hurricane/src/viewer/images/angry-birds-red.png b/hurricane/src/viewer/images/angry-birds-red.png new file mode 100644 index 00000000..a1cab832 Binary files /dev/null and b/hurricane/src/viewer/images/angry-birds-red.png differ diff --git a/karakaze/python/AnalogDesign.py b/karakaze/python/AnalogDesign.py index 1f76d22a..673b42af 100644 --- a/karakaze/python/AnalogDesign.py +++ b/karakaze/python/AnalogDesign.py @@ -14,29 +14,29 @@ # +-----------------------------------------------------------------+ -from Hurricane import * -from Hurricane import DataBase +from Hurricane import * +from Hurricane import DataBase import CRL import helpers -from helpers import isderived -from helpers import trace -from helpers import ErrorMessage as Error -from Analog import Device -from Analog import Transistor -from Analog import CommonDrain -from Analog import CommonGatePair -from Analog import CommonSourcePair -from Analog import CrossCoupledPair -from Analog import DifferentialPair -from Analog import LevelShifter -from Analog import SimpleCurrentMirror -from Analog import LayoutGenerator -from Bora import SlicingNode -from Bora import HSlicingNode -from Bora import VSlicingNode -from Bora import DSlicingNode -from Bora import RHSlicingNode -from Bora import RVSlicingNode +from helpers import isderived +from helpers import trace +from helpers.io import ErrorMessage as Error +from Analog import Device +from Analog import Transistor +from Analog import CommonDrain +from Analog import CommonGatePair +from Analog import CommonSourcePair +from Analog import CrossCoupledPair +from Analog import DifferentialPair +from Analog import LevelShifter +from Analog import SimpleCurrentMirror +from Analog import LayoutGenerator +from Bora import SlicingNode +from Bora import HSlicingNode +from Bora import VSlicingNode +from Bora import DSlicingNode +from Bora import RHSlicingNode +from Bora import RVSlicingNode import karakaze.Oceane import Anabatic import Katana diff --git a/katana/python/katanaInit.py b/katana/python/katanaInit.py index 18498976..dda64c8d 100644 --- a/katana/python/katanaInit.py +++ b/katana/python/katanaInit.py @@ -3,8 +3,8 @@ try: import sys import os.path - from helpers import ErrorMessage - from helpers import WarningMessage + from helpers.io import ErrorMessage + from helpers.io import WarningMessage import Viewer except ImportError, e: serror = str(e) diff --git a/kite/python/kiteInit.py b/kite/python/kiteInit.py index b4f75c80..ba214c74 100644 --- a/kite/python/kiteInit.py +++ b/kite/python/kiteInit.py @@ -3,8 +3,8 @@ try: import sys import os.path - from helpers import ErrorMessage - from helpers import WarningMessage + from helpers.io import ErrorMessage + from helpers.io import WarningMessage import Viewer except ImportError, e: serror = str(e) diff --git a/oroshi/python/ParamsMatrix.py b/oroshi/python/ParamsMatrix.py index d4392559..cb9788ad 100644 --- a/oroshi/python/ParamsMatrix.py +++ b/oroshi/python/ParamsMatrix.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -from Hurricane import DataBase -from Hurricane import DbU -from Hurricane import Box -from Hurricane import Net -from helpers import ErrorMessage as Error -from helpers import trace +from Hurricane import DataBase +from Hurricane import DbU +from Hurricane import Box +from Hurricane import Net +from helpers.io import ErrorMessage as Error +from helpers import trace # Rows are stacks. diff --git a/oroshi/python/Stack.py b/oroshi/python/Stack.py index a3863afa..a6db5da1 100644 --- a/oroshi/python/Stack.py +++ b/oroshi/python/Stack.py @@ -2,22 +2,22 @@ import copy import datetime -from Hurricane import DataBase -from Hurricane import UpdateSession -from Hurricane import DbU -from Hurricane import Box -from Hurricane import Net -from Hurricane import Horizontal -from Hurricane import Vertical -from Hurricane import Contact -from Hurricane import Pad -from Hurricane import NetExternalComponents -from CRL import AllianceFramework +from Hurricane import DataBase +from Hurricane import UpdateSession +from Hurricane import DbU +from Hurricane import Box +from Hurricane import Net +from Hurricane import Horizontal +from Hurricane import Vertical +from Hurricane import Contact +from Hurricane import Pad +from Hurricane import NetExternalComponents +from CRL import AllianceFramework import Constant import helpers -from helpers import ErrorMessage as Error -from helpers import trace -from Analog import Device +from helpers.io import ErrorMessage as Error +from helpers import trace +from Analog import Device import oroshi helpers.staticInitialization( quiet=True ) diff --git a/tutorial/python/runDemo.py b/tutorial/python/runDemo.py index 40d8f7df..5c6b7bff 100644 --- a/tutorial/python/runDemo.py +++ b/tutorial/python/runDemo.py @@ -21,20 +21,20 @@ try: import Viewer import CRL import helpers - from helpers import ErrorMessage - from helpers import WarningMessage - from helpers import showPythonTrace + from helpers.io import ErrorMessage + from helpers.io import WarningMessage + from helpers import showPythonTrace import plugins - from Hurricane import DataBase - from Hurricane import Breakpoint - from Hurricane import UpdateSession - from Hurricane import DbU - from Hurricane import Box - from Hurricane import Contact - from Hurricane import Vertical - from Hurricane import Horizontal - from Hurricane import Net - from Hurricane import Cell + from Hurricane import DataBase + from Hurricane import Breakpoint + from Hurricane import UpdateSession + from Hurricane import DbU + from Hurricane import Box + from Hurricane import Contact + from Hurricane import Vertical + from Hurricane import Horizontal + from Hurricane import Net + from Hurricane import Cell except ImportError, e: serror = str(e) if serror.startswith('No module named'): @@ -160,9 +160,7 @@ def ScriptMain ( **kw ): runDemo( cell, editor ) - except ErrorMessage, e: - print e; errorCode = e.code except Exception, e: - showPythonTrace( 'runDemo.py', e ) + helpers.io.catch( e ) return 0 diff --git a/tutorial/src/tutorial.py b/tutorial/src/tutorial.py index bf6a0c5e..92b8a4ce 100755 --- a/tutorial/src/tutorial.py +++ b/tutorial/src/tutorial.py @@ -8,7 +8,7 @@ try: import Cfg import Hurricane import Viewer - from helpers import showPythonTrace + import helpers.io import CRL import Unicorn import Tutorial @@ -117,6 +117,6 @@ if __name__ == '__main__': ha.qtExec() except Exception, e: - showPythonTrace( sys.argv[0], e ) + helpers.io.catch( e ) sys.exit(0) diff --git a/unicorn/python/unicornInit.py b/unicorn/python/unicornInit.py index 012c507a..141dfc9f 100644 --- a/unicorn/python/unicornInit.py +++ b/unicorn/python/unicornInit.py @@ -18,8 +18,9 @@ try: import traceback import sys import os.path - from helpers import ErrorMessage - from helpers import WarningMessage + import helpers + from helpers.io import ErrorMessage + from helpers.io import WarningMessage import Viewer except ImportError, e: serror = str(e) @@ -69,11 +70,15 @@ def unicornConfigure ( **kw ): #editor.addMenu( 'plugins', 'Plu&gins', Viewer.CellViewer.TopMenu ) + moduleNames = [] for pluginFile in os.listdir( pluginsDir ): if pluginFile == "__init__.py": continue if not pluginFile.endswith('.py'): continue - moduleName = os.path.basename(pluginFile)[:-3] + moduleNames.append( os.path.basename(pluginFile)[:-3] ) + moduleNames.sort() + + for moduleName in moduleNames: try: module = __import__( moduleName, globals(), locals(), moduleName ) @@ -83,11 +88,11 @@ def unicornConfigure ( **kw ): continue module.__dict__['unicornHook']( **kw ) + except ErrorMessage, e: print e + helpers.showStackTrace( e.trace ) except Exception, e: - print ErrorMessage( 3, 'Plugin <%s> cannot be loaded, see message below:' % moduleName ) - print e - traceback.print_tb(sys.exc_info()[2]) + helpers.showPythonTrace( __file__, e ) return diff --git a/unicorn/src/cgt.py b/unicorn/src/cgt.py index 9383a3a5..85537c5e 100755 --- a/unicorn/src/cgt.py +++ b/unicorn/src/cgt.py @@ -203,7 +203,7 @@ if __name__ == '__main__': setCgtBanner(unicorn.getBanner()) #print unicorn.getBanner() #print credits() - + if cell: unicorn.setCell(cell) unicorn.show() ha.qtExec()