Support for mixing real pads & symbolic core. Wrapper around s2r.

* Change: In Hurricane::Error constructors disable the backtrace generation.
    (*very* slow).
* Change: In Hurricane::Library::getHierarchicalname(), more compact
    naming. Remove the name of the root library.
* New: In Hurricane::Net, new type "FUSED", for component with no net.
    More efficient than having one net for each.
* Change: In CellViewer, BreakpointWidget, use Angry Birds icons.
* Change: In CellWidget::State, use the hierarchical name (cached) as key
    to the state. This allow to load two cells with the same name but from
    different libraries in the widget history.
* Change: In PyGraphics, export "isEnabled()" and "isHighDpi()" functions.
* Change: In CRL/etc/symbolic/cmos/plugin.conf, and
    CRL/etc/common/plugin.conf use the physical dimensions converters.
* Change: In CRL/etc/symbolic/cmos/technology.conf, make the GDS layer
    table coherent with the default Alliance cmos.rds.
* New: CRL/python/helpers/io.py, put ErrorMessage new implementation here,
    along with a new ErrorWidget written in PyQt4. It seems finally that
    PyQt4 can be used alongside Coriolis Qt widgets.
      New ErrorMessage.catch() static function to manage all exceptions
    in except clauses.
* Change: In CRL/python/helpers/, no longer use ErrorMessage.wrapPrint(),
    directly print it.
      Rewrite the utilities to display Python stack traces "textStacktrace()"
    and "showStacktrace()".
* Change: In CRL::AllianceFramework, shorten the names of the libraries.
* Change: In CRL::ApParser & CRL::ApDriver, more accurate translation between
    Alliance connectors (C record) and Hurricane::Pin objects. Pin are no
    longer made square but thin and oriented in the connecting direction.
      Use the new fused net for unnamed components.
* New: In CRL::GdsParser, implementation of SREF parsing, i.e. instances.
    Due to the unordered nature of the GDS stream, instances creation are
    delayed until the whole stream has been parsed and only then are they
    created.
      For the sake of reading back Alliance s2r GDS, we assume that any
    TEXT following a boundary is the Net name the boundary (component)
    belongs to.
      Create abutment box for Cells, computed from the bounding box, so
    the Hurricane QuadTree could work properly.
      Make use of the fused net for unnamed components.
* New: In Cumulus/plugins/chip, complete rewrite of the I/O pad management.
    Now we can mix real (foundry) pads and a symbolic core.
      To cleanly support the de-coupling between the real part and the
    symbolic one we introduce a new intermediary hierarchical level, the
    corona. We have now:
      Chip --> Pads + Corona --> Core.
      At chip level (and if we are using real pads) the layout is fully
    real (excepting the corona).
      The Corona contains everything that is symbolic. It has symbolic
    wires extending outward the abutment box to make contact with the
    real wires coming from the pads.
      In the pad ring we can use corners instances (or not), pad spacers
    or directly draw wires between connectors ring pads.
      Provide two flavors: placement only or full place & route.
    WARNING: If routing in a second step, *do not route* the *Chip* but
    the *Corona*.
* Change: In Cumulus/plugins/clocktree, give the modified Cell an
    additional extension of "_cts" (Clock Tree Synthesis) instead of
    "_clocked", to follow the common convention.
* New: In cumulus/plugins/S2R.py, encapsulate call to Alliance S2R and
    reload the translated Cell in the editor.
* New: In cumulus/plugins/core2chip, provide an utility to automatically
    create a chip from a core. To work this plugins must have a basic
    understanding of the pad functionalities which may differs from
    foundry to foundry. So a base class CoreToChip is created, then for
    each supported pad foundry a derived class is added. Currently we
    support AMS c35b4 and Alliance symbolic cmos.
* Bug: In Anabatic::Configuration, read the right configuration parameter
    "anabatic.topRoutinglayer" (Katana), and not the one for Katabatic...
* Change: In Unicorn/cgt.py, process the plugins in alphabetical order
    to ensure a reproductible ordering of the menus...
This commit is contained in:
Jean-Paul Chaput 2019-05-22 14:34:32 +02:00
parent 9bcc81eb7d
commit 3fb746fbef
70 changed files with 2073 additions and 765 deletions

View File

@ -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");

View File

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

View File

@ -14,13 +14,13 @@ from helpers.Technology import initTechno
# - <compositeLayersTable>
# - <symbolicLayersTable>
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)
)

View File

@ -1,6 +1,7 @@
# -*- Mode:Python; explicit-buffer-name: "plugins.conf<cmos45>" -*-
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')
)

View File

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

View File

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

View File

@ -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 = '<allianceFile has not been set>'
@ -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:<Alliance> at index %d.' % (allianceFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<Alliance> at index %d.' % (allianceFile,entryNo) )
print e
try:
env.validate()
env.validate()
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<Alliance>.' % (allianceFile))
sys.exit(1)
e = ErrorMessage( e )
e.addMessage( 'In %s:<Alliance>.' % (allianceFile) )
print e
sys.exit(1)
return
@ -159,7 +163,9 @@ def loadRoutingGaugesTable ( routingGaugesTable, fromFile ):
) )
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<routingGaugesTable> at index %d.' % (allianceFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<routingGaugesTable> 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:<cellGaugesTable> at index %d.' % (allianceFile,gaugeDatasNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<cellGaugesTable> at index %d.' % (allianceFile,gaugeDatasNo) )
print e
if gauge: af.addCellGauge(gauge)
return

View File

@ -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:<analogTechnologyTable> at index %d.' % (technoFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<analogTechnologyTable> at index %d.' % (technoFile,entryNo) )
print e
return

View File

@ -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 = '<confFile has not been set>'
@ -123,7 +123,9 @@ def loadParameters ( parametersData, fromFile ):
param.flags = options[key]
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<parametersTable> at index %d.' % (confFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<parametersTable> 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:<layoutTable> at index %d.' % (confFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<layoutTable> at index %d.' % (confFile,entryNo) )
print e
return

View File

@ -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 = '<devicesFile has not been set>'
@ -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:<devicesTable> at index %d.' % (devicesFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<devicesTable> at index %d.' % (devicesFile,entryNo) )
print e
return

View File

@ -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:<styleTable>:"%s" at index %d.' % (displayFile,style.getName(),entryNo)
else:
footer = 'In %s:<styleTable> 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:<styleTable>.' % displayFile
]
ErrorMessage.wrapPrint(e, styleTableExample)
e = ErrorMessage( e )
e.addMessage( styleTableExample )
print e
return

View File

@ -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 = '<confFile has not been set>'
@ -175,7 +175,9 @@ def loadPatterns ( patternsData, fromFile ):
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<patternsTable> at index %d.' % (confFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<patternsTable> at index %d.' % (confFile,entryNo) )
print e
return

View File

@ -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 = '<No technology file specified>'
@ -132,7 +132,9 @@ def loadRealLayers ( realLayersTable, confFile ):
routingLayer.setBlockageLayer(basicLayer)
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<realLayersTable> at entry %d.' % (technologyFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<realLayersTable> 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:<compositeLayersTable> at entry %d.' % (technologyFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<compositeLayersTable> at entry %d.' % (technologyFile,entryNo) )
print e
return
@ -270,7 +274,9 @@ def loadLayersExtensions ( layersExtensionsTable, confFile ):
])
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<layersExtensionsTable> at entry %d.' % (technologyFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<layersExtensionsTable> 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:<symbolicLayersTable> at entry %d.' % (technologyFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<symbolicLayersTable> 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:<gdsLayersTable> at entry %d.' % (technologyFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<gdsLayersTable> 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

View File

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

View File

@ -0,0 +1,256 @@
# -*- mode:Python; explicit-buffer-name: "io.py<crlcore/helpers>" -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2012-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | 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

View File

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

View File

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

View File

@ -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<char*> _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] );

View File

@ -16,6 +16,7 @@
#include <ctime>
#include <string>
#include <bitset>
#include <sstream>
#include <fstream>
#include <algorithm>
@ -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<uint16_t>& 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<uint16_t> _masks;
vector<int16_t> _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<uint16_t>& 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<uint16_t>();
_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<uint16_t>() ); }
@ -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<const Layer*> _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<const Layer*> _gdsLayerTable;
vector<DelayedInstance> _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<const Layer*> 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<int32_t> 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 ; i<points.size() ; ++i ) {
@ -1065,20 +1215,50 @@ namespace {
if (isRectilinear and (points.size() == 5)) {
Box boundingBox;
for ( Point p : points ) boundingBox.merge( p );
Pad::create( anonymousNet(), layer, boundingBox );
_component = Pad::create( net, layer, boundingBox );
cerr << _component << endl;
} else {
Rectilinear::create( anonymousNet(), layer, points );
_component = Rectilinear::create( net, layer, points );
}
if (not net->isAutomatic()) 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();

View File

@ -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:<Alliance> at index %d.' % (allianceFile,entryNo))
e = ErrorMessage( e )
e.addMessage( 'In %s:<Alliance> at index %d.' % (allianceFile,entryNo) )
print e
self.mbkEnv[ 'LD_LIBRARY_PATH' ] = self.mbkEnv[ 'ALLIANCE_TOP' ] + '/lib'
return

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

128
cumulus/src/plugins/S2R.py Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<name>[^(]*)\((?P<index>[\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

View File

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

View File

@ -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'):

View File

@ -136,7 +136,7 @@ namespace Etesian {
, "Place a block [<b>Etesian</b>]"
, std::bind(&GraphicEtesianEngine::_place,this)
, QIcon()
, "placeAndRoute.placeChip"
, "placeAndRoute.clockTree"
);
}

View File

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

View File

@ -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()
// ************************
{

View File

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

View File

@ -220,6 +220,9 @@ void UpdateSession::reset()
}
size_t UpdateSession::getStackSize ()
{ return (UPDATOR_STACK) ? UPDATOR_STACK->size() : 0; }
} // End of Hurricane namespace.

View File

@ -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<const Hurricane::Net::Type::Code*>
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";
}

View File

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

View File

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

View File

@ -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" );
}

View File

@ -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 */
};

View File

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

View File

@ -14,5 +14,8 @@
<file>images/gnome-gmush.png</file>
<file>images/gnome-core.png</file>
<file>images/i-core.png</file>
<file>images/angry-birds-red.png</file>
<file>images/angry-birds-chuck.png</file>
<file>images/angry-birds-bomb.png</file>
</qresource>
</RCC>

View File

@ -1070,7 +1070,7 @@ namespace Hurricane {
static const Name noCell = "None";
if ( !_cell ) return noCell;
return _cell->getName();
return _hierarchicalName;
}

View File

@ -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 }" );

View File

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

View File

@ -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<State>& );
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<State>&, bool >()
, _cellName(cellName)
, _cellHierName(cellHierName)
{ }
inline bool CellWidget::FindStateName::operator () ( const shared_ptr<State>& state )
{ return state->getName() == _cellName; }
{ return state->getName() == _cellHierName; }
inline void CellWidget::setActiveCommand ( Command* command )

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -203,7 +203,7 @@ if __name__ == '__main__':
setCgtBanner(unicorn.getBanner())
#print unicorn.getBanner()
#print credits()
if cell: unicorn.setCell(cell)
unicorn.show()
ha.qtExec()