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:
parent
9bcc81eb7d
commit
3fb746fbef
|
@ -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");
|
||||
|
|
|
@ -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')
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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')
|
||||
)
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ):
|
||||
|
|
|
@ -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
|
|
@ -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 )
|
||||
|
|
|
@ -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() ) {
|
||||
|
|
|
@ -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] );
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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'):
|
||||
|
|
|
@ -136,7 +136,7 @@ namespace Etesian {
|
|||
, "Place a block [<b>Etesian</b>]"
|
||||
, std::bind(&GraphicEtesianEngine::_place,this)
|
||||
, QIcon()
|
||||
, "placeAndRoute.placeChip"
|
||||
, "placeAndRoute.clockTree"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
// ************************
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -220,6 +220,9 @@ void UpdateSession::reset()
|
|||
}
|
||||
|
||||
|
||||
size_t UpdateSession::getStackSize ()
|
||||
{ return (UPDATOR_STACK) ? UPDATOR_STACK->size() : 0; }
|
||||
|
||||
|
||||
} // End of Hurricane namespace.
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1070,7 +1070,7 @@ namespace Hurricane {
|
|||
static const Name noCell = "None";
|
||||
|
||||
if ( !_cell ) return noCell;
|
||||
return _cell->getName();
|
||||
return _hierarchicalName;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 }" );
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 |
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -203,7 +203,7 @@ if __name__ == '__main__':
|
|||
setCgtBanner(unicorn.getBanner())
|
||||
#print unicorn.getBanner()
|
||||
#print credits()
|
||||
|
||||
|
||||
if cell: unicorn.setCell(cell)
|
||||
unicorn.show()
|
||||
ha.qtExec()
|
||||
|
|
Loading…
Reference in New Issue