Integration of the latest Coloquinte in Etesian & misc modifs.

* New: In Bootstrap, in Builder & coriolisEnv.py support for RHEL7/SL7.
    The sub-directory name is 'el7_64'.
      In qt_setup() add QtSvg to list of Qt5 & Qt4 used libraries.
* New: In Hurricane, In Cell add a placeholder for flags. First use to
    store whether the Nets have been transhierarchically flatteneds.
* New: In Hurricane, In NetRoutingState add an Unconnected flag for
    more accurate diagnosis.
* New: Hurricane, in CellViewer add an entry menu for stress tests.
    The script must be named "stressScript.py" in the cwd.
* Change: In CRL Core, in display.conf add a scaling parameter for the
    display threhold of the layer. This way we can adapt to different
    standard cells height.
* Change: In CRL Core, in ISPD05 bookshelf loader, use the pitch of the
    cell gauge instead of a hard-wired 5.0.
* Change: In Cumulus, in ClockTreePlugin, add support for Etesian placer
    and a new configuration parameter to choose between Mauka/Etesian.
* New: In Etesian, support for the latest Coloquinte.
    Add feed insertion stage.
* Bug: In Kite, In BuildPowerRails, check that _ck is not NULL before
    tring to access it's name...
* Change: In Kite, check if the Cell has it's Nets flattened before
    doing it (or not).
This commit is contained in:
Jean-Paul Chaput 2015-02-01 23:24:13 +01:00
parent 56bd484429
commit b18219d807
47 changed files with 1605 additions and 444 deletions

View File

@ -36,11 +36,11 @@ projects = [ { 'name' : "coloquinte"
, 'tools' : [ "hurricaneAMS" , 'tools' : [ "hurricaneAMS"
, "amsCore" , "amsCore"
, "opSim" , "opSim"
, "scribe" #, "scribe"
, "graph" , "graph"
, "pharos" , "pharos"
, "isis" , "isis"
, "schematic" #, "schematic"
, "solver" , "solver"
, "autoDTR" , "autoDTR"
] ]

View File

@ -141,7 +141,7 @@ class Configuration ( object ):
lines = uname.stdout.readlines() lines = uname.stdout.readlines()
if self._osSlsoc7x_64.match(lines[0]): if self._osSlsoc7x_64.match(lines[0]):
self._osType = "Linux.el7" self._osType = "Linux.el7_64"
self._libSuffix = "64" self._libSuffix = "64"
elif self._osSlsoc6x_64.match(lines[0]): elif self._osSlsoc6x_64.match(lines[0]):
self._osType = "Linux.slsoc6x_64" self._osType = "Linux.slsoc6x_64"

View File

@ -212,25 +212,33 @@
# #
macro(setup_qt) macro(setup_qt)
if(WITH_QT5) if(WITH_QT5)
message(STATUS "Attempt to find Qt 5...")
# For Qt5 # For Qt5
find_package(Qt5Core REQUIRED) find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED) find_package(Qt5Gui REQUIRED)
find_package(Qt5Widgets REQUIRED) find_package(Qt5Widgets REQUIRED)
find_package(Qt5PrintSupport REQUIRED) find_package(Qt5Svg REQUIRED)
find_package(Qt5PrintSupport REQUIRED)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(QtX_INCLUDE_DIR ${Qt5PrintSupport_INCLUDE_DIR} set(QtX_INCLUDE_DIR ${Qt5PrintSupport_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIR} ${Qt5Widgets_INCLUDE_DIRS}
${Qt5Gui_INCLUDE_DIR} ${Qt5Svg_INCLUDE_DIRS}
${Qt5Core_INCLUDE_DIR} ) ${Qt5Gui_INCLUDE_DIRS}
${Qt5Core_INCLUDE_DIRS} )
set(QtX_LIBRARIES ${Qt5PrintSupport_LIBRARIES} set(QtX_LIBRARIES ${Qt5PrintSupport_LIBRARIES}
${Qt5Widgets_LIBRARIES} ${Qt5Widgets_LIBRARIES}
${Qt5Gui_LIBRARIES} ${Qt5Gui_LIBRARIES}
${Qt5Core_LIBRARIES} ) ${Qt5Core_LIBRARIES} )
#message(STATUS "QtX_INCLUDE_DIR: ${QtX_INCLUDE_DIR}")
#message(STATUS "QtX_LIBRARIES: ${QtX_LIBRARIES}")
else() else()
message(STATUS "Attempt to find Qt 4...")
# For Qt4. # For Qt4.
#set(QT_USE_QTXML "true") #set(QT_USE_QTXML "true")
set(QT_USE_QTSVG "true")
find_package(Qt4 REQUIRED) find_package(Qt4 REQUIRED)
include(${QT_USE_FILE}) include(${QT_USE_FILE})
# ${QT_QTSVG_LIBRARY}
set(QtX_LIBRARIES ${QT_LIBRARIES}) set(QtX_LIBRARIES ${QT_LIBRARIES})
endif() endif()
endmacro() endmacro()

View File

@ -14,6 +14,7 @@
FIND_PATH(QWT_INCLUDE_DIR NAMES qwt.h PATHS FIND_PATH(QWT_INCLUDE_DIR NAMES qwt.h PATHS
/usr/include /usr/include
/usr/include/qt5
/usr/local/include /usr/local/include
"$ENV{LIB_DIR}/include" "$ENV{LIB_DIR}/include"
"$ENV{INCLUDE}" "$ENV{INCLUDE}"

View File

@ -191,6 +191,7 @@ if __name__ == "__main__":
version = "%d.%d" % (pyVersion[0],pyVersion[1]) version = "%d.%d" % (pyVersion[0],pyVersion[1])
if osType.startswith("Linux.SL") \ if osType.startswith("Linux.SL") \
or osType.startswith("Linux.sl") \ or osType.startswith("Linux.sl") \
or osType.startswith("Linux.el") \
or osType.startswith("Darwin") \ or osType.startswith("Darwin") \
or osType.startswith("Cygwin"): or osType.startswith("Cygwin"):
sitePackagesDir = "%s/python%s/site-packages" % (absLibDir,version) sitePackagesDir = "%s/python%s/site-packages" % (absLibDir,version)

View File

@ -1,6 +1,7 @@
install ( FILES techno.conf DESTINATION ${SYS_CONF_DIR}/coriolis2 ) install ( FILES techno.conf DESTINATION ${SYS_CONF_DIR}/coriolis2 )
install ( DIRECTORY common DESTINATION ${SYS_CONF_DIR}/coriolis2 ) install ( DIRECTORY common DESTINATION ${SYS_CONF_DIR}/coriolis2 )
install ( DIRECTORY ispd05 DESTINATION ${SYS_CONF_DIR}/coriolis2 )
install ( DIRECTORY cmos DESTINATION ${SYS_CONF_DIR}/coriolis2 ) install ( DIRECTORY cmos DESTINATION ${SYS_CONF_DIR}/coriolis2 )
install ( DIRECTORY vsc200 DESTINATION ${SYS_CONF_DIR}/coriolis2 ) install ( DIRECTORY vsc200 DESTINATION ${SYS_CONF_DIR}/coriolis2 )
install ( DIRECTORY scmos_deep_018 DESTINATION ${SYS_CONF_DIR}/coriolis2 ) install ( DIRECTORY scmos_deep_018 DESTINATION ${SYS_CONF_DIR}/coriolis2 )

View File

@ -6,4 +6,5 @@ import helpers
# - <defaultStyle> # - <defaultStyle>
# - <stylesTable> # - <stylesTable>
scale = 1.0
execfile( helpers.sysConfDir+'/common/display.conf' ) execfile( helpers.sysConfDir+'/common/display.conf' )

View File

@ -20,4 +20,5 @@ parametersTable = \
, ('chip.pad.pvsseck' , TypeString, 'pvsseck_px') , ('chip.pad.pvsseck' , TypeString, 'pvsseck_px')
, ('clockTree.minimumSide' , TypeInt , 300) , ('clockTree.minimumSide' , TypeInt , 300)
, ('clockTree.buffer' , TypeString, 'buf_x2') , ('clockTree.buffer' , TypeString, 'buf_x2')
, ('clockTree.placerEngine' , TypeString, 'Mauka')
) )

View File

@ -19,63 +19,63 @@ stylesTable = \
, (Drawing, 'fallback' , { 'color':'Gray238' , 'border':1, 'pattern':'55AA55AA55AA55AA' }) , (Drawing, 'fallback' , { 'color':'Gray238' , 'border':1, 'pattern':'55AA55AA55AA55AA' })
, (Drawing, 'background' , { 'color':'Gray50' , 'border':1 }) , (Drawing, 'background' , { 'color':'Gray50' , 'border':1 })
, (Drawing, 'foreground' , { 'color':'White' , 'border':1 }) , (Drawing, 'foreground' , { 'color':'White' , 'border':1 })
, (Drawing, 'rubber' , { 'color':'192,0,192' , 'border':2, 'threshold':0.02 }) , (Drawing, 'rubber' , { 'color':'192,0,192' , 'border':2, 'threshold':0.02*scale })
, (Drawing, 'phantom' , { 'color':'Seashell4' , 'border':1 }) , (Drawing, 'phantom' , { 'color':'Seashell4' , 'border':1 })
, (Drawing, 'boundaries' , { 'color':'208,199,192', 'border':1, 'pattern':'0000000000000000', 'threshold':0 }) , (Drawing, 'boundaries' , { 'color':'208,199,192', 'border':1, 'pattern':'0000000000000000', 'threshold':0 })
, (Drawing, 'marker' , { 'color':'80,250,80' , 'border':1 }) , (Drawing, 'marker' , { 'color':'80,250,80' , 'border':1 })
, (Drawing, 'selectionDraw' , { 'color':'White' , 'border':1 }) , (Drawing, 'selectionDraw' , { 'color':'White' , 'border':1 })
, (Drawing, 'selectionFill' , { 'color':'White' , 'border':1 }) , (Drawing, 'selectionFill' , { 'color':'White' , 'border':1 })
, (Drawing, 'grid' , { 'color':'White' , 'border':1, 'threshold':2.0 }) , (Drawing, 'grid' , { 'color':'White' , 'border':1, 'threshold':2.0*scale })
, (Drawing, 'spot' , { 'color':'White' , 'border':2, 'threshold':6.0 }) , (Drawing, 'spot' , { 'color':'White' , 'border':2, 'threshold':6.0*scale })
, (Drawing, 'ghost' , { 'color':'White' , 'border':1 }) , (Drawing, 'ghost' , { 'color':'White' , 'border':1 })
, (Drawing, 'text.ruler' , { 'color':'White' , 'border':1, 'threshold':0.0 }) , (Drawing, 'text.ruler' , { 'color':'White' , 'border':1, 'threshold':0.0*scale })
, (Drawing, 'text.instance' , { 'color':'Black' , 'border':1, 'threshold':4.0 }) , (Drawing, 'text.instance' , { 'color':'Black' , 'border':1, 'threshold':4.0*scale })
, (Drawing, 'text.reference' , { 'color':'White' , 'border':1, 'threshold':20.0 }) , (Drawing, 'text.reference' , { 'color':'White' , 'border':1, 'threshold':20.0*scale })
, (Drawing, 'undef' , { 'color':'Violet' , 'border':0, 'pattern':'2244118822441188' }) , (Drawing, 'undef' , { 'color':'Violet' , 'border':0, 'pattern':'2244118822441188' })
, (Drawing, 'mauka.container', { 'color':'Magenta4' , 'border':4, 'pattern':'0000000000000000', 'goMatched':False }) , (Drawing, 'mauka.container', { 'color':'Magenta4' , 'border':4, 'pattern':'0000000000000000', 'goMatched':False })
# Group: Active Layer. # Group: Active Layer.
, (Group , 'Active Layer') , (Group , 'Active Layer')
, (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.5 }) , (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.5 *scale })
, (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'55AA55AA55AA55AA', 'threshold':1.50 }) , (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'55AA55AA55AA55AA', 'threshold':1.50*scale })
, (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50 }) , (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50*scale })
, (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50 }) , (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50*scale })
, (Drawing, 'active' , { 'color':'White' , 'pattern':'antihash1.8' , 'threshold':1.50 }) , (Drawing, 'active' , { 'color':'White' , 'pattern':'antihash1.8' , 'threshold':1.50*scale })
, (Drawing, 'poly' , { 'color':'Red' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50 }) , (Drawing, 'poly' , { 'color':'Red' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50*scale })
# Group: Routing Layer. # Group: Routing Layer.
, (Group , 'Routing Layer') , (Group , 'Routing Layer')
, (Drawing, 'metal1' , { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80 }) , (Drawing, 'metal1' , { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80*scale })
, (Drawing, 'metal2' , { 'color':'Aqua' , 'pattern':'light_antihash0.8' , 'threshold':0.02 }) , (Drawing, 'metal2' , { 'color':'Aqua' , 'pattern':'light_antihash0.8' , 'threshold':0.02*scale })
, (Drawing, 'metal3' , { 'color':'LightPink', 'pattern':'light_antihash1.8' , 'threshold':0.02 }) , (Drawing, 'metal3' , { 'color':'LightPink', 'pattern':'light_antihash1.8' , 'threshold':0.02*scale })
, (Drawing, 'metal4' , { 'color':'Green' , 'pattern':'light_antihash2.8' , 'threshold':0.02 }) , (Drawing, 'metal4' , { 'color':'Green' , 'pattern':'light_antihash2.8' , 'threshold':0.02*scale })
, (Drawing, 'metal5' , { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.02 }) , (Drawing, 'metal5' , { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.02*scale })
, (Drawing, 'metal6' , { 'color':'Violet' , 'pattern':'light_antihash0.8' , 'threshold':0.02 }) , (Drawing, 'metal6' , { 'color':'Violet' , 'pattern':'light_antihash0.8' , 'threshold':0.02*scale })
# Group: Cuts (VIA holes). # Group: Cuts (VIA holes).
, (Group , 'Cuts (VIA Holes)') , (Group , 'Cuts (VIA Holes)')
, (Drawing, 'cut0', { 'color':'0,150,150', 'threshold':1.50 }) , (Drawing, 'cut0', { 'color':'0,150,150', 'threshold':1.50*scale })
, (Drawing, 'cut1', { 'color':'Aqua' , 'threshold':0.80 }) , (Drawing, 'cut1', { 'color':'Aqua' , 'threshold':0.80*scale })
, (Drawing, 'cut2', { 'color':'LightPink', 'threshold':0.80 }) , (Drawing, 'cut2', { 'color':'LightPink', 'threshold':0.80*scale })
, (Drawing, 'cut3', { 'color':'Green' , 'threshold':0.80 }) , (Drawing, 'cut3', { 'color':'Green' , 'threshold':0.80*scale })
, (Drawing, 'cut4', { 'color':'Yellow' , 'threshold':0.80 }) , (Drawing, 'cut4', { 'color':'Yellow' , 'threshold':0.80*scale })
, (Drawing, 'cut5', { 'color':'Violet' , 'threshold':0.80 }) , (Drawing, 'cut5', { 'color':'Violet' , 'threshold':0.80*scale })
# Group: MIM6. # Group: MIM6.
, (Group , 'MIM6') , (Group , 'MIM6')
, (Drawing, 'topmim6', { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80 }) , (Drawing, 'topmim6', { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80*scale })
, (Drawing, 'botmim6', { 'color':'Aqua' , 'pattern':'light_antihash0.8', 'threshold':0.80 }) , (Drawing, 'botmim6', { 'color':'Aqua' , 'pattern':'light_antihash0.8', 'threshold':0.80*scale })
, (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8', 'threshold':0.80 }) , (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8', 'threshold':0.80*scale })
, (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80 }) , (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80*scale })
# Group: Blockages. # Group: Blockages.
, (Group , 'Blockages') , (Group , 'Blockages')
, (Drawing, 'blockage1', { 'color':'Blue' , 'pattern':'006070381c0e0703' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage1', { 'color':'Blue' , 'pattern':'006070381c0e0703' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage2', { 'color':'Aqua' , 'pattern':'8103060c183060c0' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage2', { 'color':'Aqua' , 'pattern':'8103060c183060c0' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage3', { 'color':'LightPink', 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage3', { 'color':'LightPink', 'pattern':'poids4.8' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage4', { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage4', { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage5', { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage5', { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage6', { 'color':'Violet' , 'pattern':'light_antihash0.8', 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage6', { 'color':'Violet' , 'pattern':'light_antihash0.8', 'threshold':0.80*scale, 'border':2 })
# Group: Knik & Kite. # Group: Knik & Kite.
, (Group , 'Knik & Kite') , (Group , 'Knik & Kite')
@ -98,11 +98,11 @@ stylesTable = \
, (Drawing, 'foreground' , { 'color':'Black', 'border':1 }) , (Drawing, 'foreground' , { 'color':'Black', 'border':1 })
, (Drawing, 'selectionDraw', { 'color':'Black', 'border':1 }) , (Drawing, 'selectionDraw', { 'color':'Black', 'border':1 })
, (Drawing, 'selectionFill', { 'color':'Black', 'border':1 }) , (Drawing, 'selectionFill', { 'color':'Black', 'border':1 })
, (Drawing, 'grid' , { 'color':'Black', 'border':1, 'threshold':6.0 }) , (Drawing, 'grid' , { 'color':'Black', 'border':1, 'threshold':6.0*scale })
, (Drawing, 'spot' , { 'color':'Black', 'border':1, 'threshold':6.0 }) , (Drawing, 'spot' , { 'color':'Black', 'border':1, 'threshold':6.0*scale })
, (Drawing, 'ghost' , { 'color':'Black', 'border':1 }) , (Drawing, 'ghost' , { 'color':'Black', 'border':1 })
, (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0 }) , (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0*scale })
, (Drawing, 'text.instance', { 'color':'Black', 'border':1, 'threshold':4.0 }) , (Drawing, 'text.instance', { 'color':'Black', 'border':1, 'threshold':4.0*scale })
, (Drawing, 'undef' , { 'color':'Black', 'border':0, 'pattern':'2244118822441188' }) , (Drawing, 'undef' , { 'color':'Black', 'border':0, 'pattern':'2244118822441188' })
) )
@ -116,70 +116,70 @@ stylesTable = \
, (Drawing, 'fallback' , { 'color':'Gray238' , 'border':1, 'pattern':'55AA55AA55AA55AA' }) , (Drawing, 'fallback' , { 'color':'Gray238' , 'border':1, 'pattern':'55AA55AA55AA55AA' })
, (Drawing, 'background' , { 'color':'Gray50' , 'border':1 }) , (Drawing, 'background' , { 'color':'Gray50' , 'border':1 })
, (Drawing, 'foreground' , { 'color':'White' , 'border':1 }) , (Drawing, 'foreground' , { 'color':'White' , 'border':1 })
, (Drawing, 'rubber' , { 'color':'192,0,192' , 'border':4, 'threshold':0.02 }) , (Drawing, 'rubber' , { 'color':'192,0,192' , 'border':4, 'threshold':0.02*scale })
, (Drawing, 'phantom' , { 'color':'Seashell4' , 'border':1 }) , (Drawing, 'phantom' , { 'color':'Seashell4' , 'border':1 })
, (Drawing, 'boundaries' , { 'color':'208,199,192', 'border':1, 'pattern':'0000000000000000', 'threshold':0 }) , (Drawing, 'boundaries' , { 'color':'208,199,192', 'border':1, 'pattern':'0000000000000000', 'threshold':0 })
, (Drawing, 'marker' , { 'color':'80,250,80' , 'border':1 }) , (Drawing, 'marker' , { 'color':'80,250,80' , 'border':1 })
, (Drawing, 'selectionDraw' , { 'color':'White' , 'border':1 }) , (Drawing, 'selectionDraw' , { 'color':'White' , 'border':1 })
, (Drawing, 'selectionFill' , { 'color':'White' , 'border':1 }) , (Drawing, 'selectionFill' , { 'color':'White' , 'border':1 })
, (Drawing, 'grid' , { 'color':'White' , 'border':1, 'threshold':2.0 }) , (Drawing, 'grid' , { 'color':'White' , 'border':1, 'threshold':2.0*scale })
, (Drawing, 'spot' , { 'color':'White' , 'border':2, 'threshold':6.0 }) , (Drawing, 'spot' , { 'color':'White' , 'border':2, 'threshold':6.0*scale })
, (Drawing, 'ghost' , { 'color':'White' , 'border':1 }) , (Drawing, 'ghost' , { 'color':'White' , 'border':1 })
, (Drawing, 'text.ruler' , { 'color':'White' , 'border':1, 'threshold':0.0 }) , (Drawing, 'text.ruler' , { 'color':'White' , 'border':1, 'threshold':0.0 *scale })
, (Drawing, 'text.instance' , { 'color':'White' , 'border':1, 'threshold':4.0 }) , (Drawing, 'text.instance' , { 'color':'White' , 'border':1, 'threshold':4.0 *scale })
, (Drawing, 'text.reference', { 'color':'White' , 'border':1, 'threshold':20.0 }) , (Drawing, 'text.reference', { 'color':'White' , 'border':1, 'threshold':20.0*scale })
, (Drawing, 'undef' , { 'color':'Violet' , 'border':0, 'pattern':'2244118822441188' }) , (Drawing, 'undef' , { 'color':'Violet' , 'border':0, 'pattern':'2244118822441188' })
# Active Layers. # Active Layers.
, (Group , 'Active Layers') , (Group , 'Active Layers')
, (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'urgo.8' , 'border':1, 'threshold':1.50 }) , (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'urgo.8' , 'border':1, 'threshold':1.50*scale })
, (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'urgo.8' , 'border':1, 'threshold':1.50 }) , (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'urgo.8' , 'border':1, 'threshold':1.50*scale })
, (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'antihash0.8' , 'border':1, 'threshold':1.50 }) , (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'antihash0.8' , 'border':1, 'threshold':1.50*scale })
, (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'antihash0.8' , 'border':1, 'threshold':1.50 }) , (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'antihash0.8' , 'border':1, 'threshold':1.50*scale })
, (Drawing, 'active' , { 'color':'White' , 'pattern':'antihash1.8' , 'border':1, 'threshold':1.50 }) , (Drawing, 'active' , { 'color':'White' , 'pattern':'antihash1.8' , 'border':1, 'threshold':1.50*scale })
, (Drawing, 'poly' , { 'color':'Red' , 'pattern':'poids2.8' , 'border':1, 'threshold':1.50 }) , (Drawing, 'poly' , { 'color':'Red' , 'pattern':'poids2.8' , 'border':1, 'threshold':1.50*scale })
, (Drawing, 'poly2' , { 'color':poly2Color , 'pattern':'poids2.8' , 'border':1, 'threshold':1.50 }) , (Drawing, 'poly2' , { 'color':poly2Color , 'pattern':'poids2.8' , 'border':1, 'threshold':1.50*scale })
# Routing Layers. # Routing Layers.
, (Group , 'Routing Layers') , (Group , 'Routing Layers')
#, (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'light_antislash0.8', 'border':1, 'threshold':0.80 }) #, (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'light_antislash0.8', 'border':1, 'threshold':0.80*scale })
, (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'slash.8' , 'border':1, 'threshold':0.80 }) , (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'slash.8' , 'border':1, 'threshold':0.80*scale })
, (Drawing, 'metal2', { 'color':'Aqua' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal2', { 'color':'Aqua' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal3', { 'color':'LightPink', 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal3', { 'color':'LightPink', 'pattern':'poids4.8' , 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal4', { 'color':'Green' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal4', { 'color':'Green' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal5', { 'color':'Yellow' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal5', { 'color':'Yellow' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal6', { 'color':'Violet' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal6', { 'color':'Violet' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal7', { 'color':'Red' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal7', { 'color':'Red' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal8', { 'color':'Blue' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal8', { 'color':'Blue' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02*scale })
# Cuts (VIA holes). # Cuts (VIA holes).
, (Group , 'Cuts (VIA holes)') , (Group , 'Cuts (VIA holes)')
, (Drawing, 'cut0', { 'color':'0,150,150', 'threshold':1.50 }) , (Drawing, 'cut0', { 'color':'0,150,150', 'threshold':1.50*scale })
, (Drawing, 'cut1', { 'color':'Aqua' , 'threshold':0.80 }) , (Drawing, 'cut1', { 'color':'Aqua' , 'threshold':0.80*scale })
, (Drawing, 'cut2', { 'color':'LightPink', 'threshold':0.80 }) , (Drawing, 'cut2', { 'color':'LightPink', 'threshold':0.80*scale })
, (Drawing, 'cut3', { 'color':'Green' , 'threshold':0.80 }) , (Drawing, 'cut3', { 'color':'Green' , 'threshold':0.80*scale })
, (Drawing, 'cut4', { 'color':'Yellow' , 'threshold':0.80 }) , (Drawing, 'cut4', { 'color':'Yellow' , 'threshold':0.80*scale })
, (Drawing, 'cut5', { 'color':'Violet' , 'threshold':0.80 }) , (Drawing, 'cut5', { 'color':'Violet' , 'threshold':0.80*scale })
, (Drawing, 'cut6', { 'color':'Red' , 'threshold':0.80 }) , (Drawing, 'cut6', { 'color':'Red' , 'threshold':0.80*scale })
, (Drawing, 'cut7', { 'color':'Blue' , 'threshold':0.80 }) , (Drawing, 'cut7', { 'color':'Blue' , 'threshold':0.80*scale })
# MIM6. # MIM6.
, (Group , 'MIM6') , (Group , 'MIM6')
, (Drawing, 'topmim6', { 'color':'Blue' , 'pattern':'poids2.32' , 'threshold':0.80 }) , (Drawing, 'topmim6', { 'color':'Blue' , 'pattern':'poids2.32' , 'threshold':0.80*scale })
, (Drawing, 'botmim6', { 'color':'Aqua' , 'pattern':'light_antihash0.8' , 'threshold':0.80 }) , (Drawing, 'botmim6', { 'color':'Aqua' , 'pattern':'light_antihash0.8' , 'threshold':0.80*scale })
, (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8' , 'threshold':0.80 }) , (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8' , 'threshold':0.80*scale })
, (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.8' , 'threshold':0.80 }) , (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.8' , 'threshold':0.80*scale })
# Blockages. # Blockages.
, (Group , 'Blockages') , (Group , 'Blockages')
, (Drawing, 'blockage1', { 'color':'Blue' , 'pattern':'light_antislash0.8', 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage1', { 'color':'Blue' , 'pattern':'light_antislash0.8', 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage2', { 'color':'Aqua' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage2', { 'color':'Aqua' , 'pattern':'poids4.8' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage3', { 'color':'LightPink', 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage3', { 'color':'LightPink', 'pattern':'poids4.8' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage4', { 'color':'Green' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage4', { 'color':'Green' , 'pattern':'poids4.8' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage5', { 'color':'Yellow' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage5', { 'color':'Yellow' , 'pattern':'poids4.8' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage6', { 'color':'Violet' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage6', { 'color':'Violet' , 'pattern':'poids4.8' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage7', { 'color':'Red' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage7', { 'color':'Red' , 'pattern':'poids4.8' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage8', { 'color':'Blue' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage8', { 'color':'Blue' , 'pattern':'poids4.8' , 'threshold':0.80*scale, 'border':2 })
# Knick & Kite. # Knick & Kite.
, (Group , 'Knick & Kite') , (Group , 'Knick & Kite')
@ -203,12 +203,12 @@ stylesTable = \
, (Drawing, 'foreground' , { 'color':'Black', 'border':1 }) , (Drawing, 'foreground' , { 'color':'Black', 'border':1 })
, (Drawing, 'selectionDraw' , { 'color':'Black', 'border':1 }) , (Drawing, 'selectionDraw' , { 'color':'Black', 'border':1 })
, (Drawing, 'selectionFill' , { 'color':'Black', 'border':1 }) , (Drawing, 'selectionFill' , { 'color':'Black', 'border':1 })
, (Drawing, 'grid' , { 'color':'Black', 'border':1, 'threshold':6.0 }) , (Drawing, 'grid' , { 'color':'Black', 'border':1, 'threshold':6.0*scale })
, (Drawing, 'spot' , { 'color':'Black', 'border':1, 'threshold':6.0 }) , (Drawing, 'spot' , { 'color':'Black', 'border':1, 'threshold':6.0*scale })
, (Drawing, 'ghost' , { 'color':'Black', 'border':1 }) , (Drawing, 'ghost' , { 'color':'Black', 'border':1 })
, (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0 }) , (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0 *scale })
, (Drawing, 'text.instance' , { 'color':'Black', 'border':1, 'threshold':4.0 }) , (Drawing, 'text.instance' , { 'color':'Black', 'border':1, 'threshold':4.0 *scale })
, (Drawing, 'text.reference', { 'color':'Black', 'border':1, 'threshold':20.0 }) , (Drawing, 'text.reference', { 'color':'Black', 'border':1, 'threshold':20.0*scale })
, (Drawing, 'undef' , { 'color':'Black', 'border':0, 'pattern':'2244118822441188' }) , (Drawing, 'undef' , { 'color':'Black', 'border':0, 'pattern':'2244118822441188' })
) )
@ -238,30 +238,30 @@ stylesTable = \
# Active Layers. # Active Layers.
, (Group , 'Active Layers') , (Group , 'Active Layers')
, (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) , (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 })
, (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) , (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 })
, (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) , (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 })
, (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) , (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 })
, (Drawing, 'active' , { 'color':'White' , 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) , (Drawing, 'active' , { 'color':'White' , 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 })
, (Drawing, 'poly' , { 'color':'Red' , 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) , (Drawing, 'poly' , { 'color':'Red' , 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 })
# Routing Layers. # Routing Layers.
, (Group , 'Routing Layers') , (Group , 'Routing Layers')
, (Drawing, 'metal1' , { 'color':'Blue' , 'pattern':'0000000000000000', 'threshold':0.80, 'border':2 }) , (Drawing, 'metal1' , { 'color':'Blue' , 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'metal2' , { 'color':'Aqua' , 'pattern':'0000000000000000', 'threshold':0.40, 'border':2 }) , (Drawing, 'metal2' , { 'color':'Aqua' , 'pattern':'0000000000000000', 'threshold':0.40*scale, 'border':2 })
, (Drawing, 'metal3' , { 'color':'LightPink', 'pattern':'0000000000000000', 'threshold':0.02, 'border':2 }) , (Drawing, 'metal3' , { 'color':'LightPink', 'pattern':'0000000000000000', 'threshold':0.02*scale, 'border':2 })
, (Drawing, 'metal4' , { 'color':'Green' , 'pattern':'0000000000000000', 'threshold':0.02, 'border':2 }) , (Drawing, 'metal4' , { 'color':'Green' , 'pattern':'0000000000000000', 'threshold':0.02*scale, 'border':2 })
, (Drawing, 'metal5' , { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':0.02, 'border':2 }) , (Drawing, 'metal5' , { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':0.02*scale, 'border':2 })
, (Drawing, 'metal6' , { 'color':'Violet' , 'pattern':'0000000000000000', 'threshold':0.02, 'border':2 }) , (Drawing, 'metal6' , { 'color':'Violet' , 'pattern':'0000000000000000', 'threshold':0.02*scale, 'border':2 })
# Cuts (VIA holes). # Cuts (VIA holes).
, (Group , 'Cuts (VIA holes)') , (Group , 'Cuts (VIA holes)')
, (Drawing, 'cut0' , { 'color':'0,150,150', 'pattern':'poids4.8' , 'threshold':1.50, 'border':1 }) , (Drawing, 'cut0' , { 'color':'0,150,150', 'pattern':'poids4.8' , 'threshold':1.50*scale, 'border':1 })
, (Drawing, 'cut1' , { 'color':'Aqua' , 'pattern':'0000000000000000', 'threshold':0.80, 'border':1 }) , (Drawing, 'cut1' , { 'color':'Aqua' , 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':1 })
, (Drawing, 'cut2' , { 'color':'LightPink', 'pattern':'0000000000000000', 'threshold':0.80, 'border':1 }) , (Drawing, 'cut2' , { 'color':'LightPink', 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':1 })
, (Drawing, 'cut3' , { 'color':'Green' , 'pattern':'0000000000000000', 'threshold':0.80, 'border':1 }) , (Drawing, 'cut3' , { 'color':'Green' , 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':1 })
, (Drawing, 'cut4' , { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':0.80, 'border':1 }) , (Drawing, 'cut4' , { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':1 })
, (Drawing, 'cut5' , { 'color':'Violet' , 'pattern':'0000000000000000', 'threshold':0.80, 'border':1 }) , (Drawing, 'cut5' , { 'color':'Violet' , 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':1 })
) )
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
@ -273,14 +273,14 @@ stylesTable = \
# Group: Viewer. # Group: Viewer.
, (Group , 'Viewer') , (Group , 'Viewer')
, (Drawing, 'background' , { 'color':'White', 'border':1 }) , (Drawing, 'background' , { 'color':'White', 'border':1 })
, (Drawing, 'grid' , { 'color':'Black', 'border':1, 'threshold':2.0 }) , (Drawing, 'grid' , { 'color':'Black', 'border':1, 'threshold':2.0 *scale })
, (Drawing, 'spot' , { 'color':'Black', 'border':1, 'threshold':2.0 }) , (Drawing, 'spot' , { 'color':'Black', 'border':1, 'threshold':2.0 *scale })
, (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0 }) , (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0 *scale })
, (Drawing, 'text.reference', { 'color':'Black', 'border':1, 'threshold':20.0 }) , (Drawing, 'text.reference', { 'color':'Black', 'border':1, 'threshold':20.0*scale })
# Group: Active Layers. # Group: Active Layers.
, (Group , 'Active Layers') , (Group , 'Active Layers')
, (Drawing, 'active', { 'color':'175,175,175', 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) , (Drawing, 'active', { 'color':'175,175,175', 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 })
) )
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
@ -293,64 +293,64 @@ stylesTable = \
, (Drawing, 'fallback' , { 'color':'Gray238' , 'border':1, 'pattern':'55AA55AA55AA55AA' }) , (Drawing, 'fallback' , { 'color':'Gray238' , 'border':1, 'pattern':'55AA55AA55AA55AA' })
, (Drawing, 'background' , { 'color':'White' , 'border':1 }) , (Drawing, 'background' , { 'color':'White' , 'border':1 })
, (Drawing, 'foreground' , { 'color':'Black' , 'border':1 }) , (Drawing, 'foreground' , { 'color':'Black' , 'border':1 })
, (Drawing, 'rubber' , { 'color':'192,0,192', 'border':4, 'threshold':0.02 }) , (Drawing, 'rubber' , { 'color':'192,0,192', 'border':4, 'threshold':0.02*scale })
, (Drawing, 'phantom' , { 'color':'Seashell4', 'border':1 }) , (Drawing, 'phantom' , { 'color':'Seashell4', 'border':1 })
, (Drawing, 'boundaries' , { 'color':'Black' , 'border':1, 'pattern':'0000000000000000', 'threshold':0 }) , (Drawing, 'boundaries' , { 'color':'Black' , 'border':1, 'pattern':'0000000000000000', 'threshold':0 })
, (Drawing, 'marker' , { 'color':'80,250,80', 'border':1 }) , (Drawing, 'marker' , { 'color':'80,250,80', 'border':1 })
, (Drawing, 'selectionDraw' , { 'color':'Black' , 'border':1 }) , (Drawing, 'selectionDraw' , { 'color':'Black' , 'border':1 })
, (Drawing, 'selectionFill' , { 'color':'Black' , 'border':1 }) , (Drawing, 'selectionFill' , { 'color':'Black' , 'border':1 })
, (Drawing, 'grid' , { 'color':'Black' , 'border':1, 'threshold':2.0 }) , (Drawing, 'grid' , { 'color':'Black' , 'border':1, 'threshold':2.0*scale })
, (Drawing, 'spot' , { 'color':'Black' , 'border':2, 'threshold':6.0 }) , (Drawing, 'spot' , { 'color':'Black' , 'border':2, 'threshold':6.0*scale })
, (Drawing, 'ghost' , { 'color':'Black' , 'border':1 }) , (Drawing, 'ghost' , { 'color':'Black' , 'border':1 })
, (Drawing, 'text.ruler' , { 'color':'Black' , 'border':1, 'threshold':0.0 }) , (Drawing, 'text.ruler' , { 'color':'Black' , 'border':1, 'threshold':0.0 *scale })
, (Drawing, 'text.instance' , { 'color':'Black' , 'border':1, 'threshold':4.0 }) , (Drawing, 'text.instance' , { 'color':'Black' , 'border':1, 'threshold':4.0 *scale })
, (Drawing, 'text.reference' , { 'color':'Black' , 'border':1, 'threshold':20.0 }) , (Drawing, 'text.reference' , { 'color':'Black' , 'border':1, 'threshold':20.0*scale })
, (Drawing, 'undef' , { 'color':'Violet' , 'border':0, 'pattern':'2244118822441188' }) , (Drawing, 'undef' , { 'color':'Violet' , 'border':0, 'pattern':'2244118822441188' })
, (Drawing, 'mauka.container', { 'color':'Magenta4' , 'border':4, 'pattern':'0000000000000000', 'goMatched':False }) , (Drawing, 'mauka.container', { 'color':'Magenta4' , 'border':4, 'pattern':'0000000000000000', 'goMatched':False })
# Group: Active Layers. # Group: Active Layers.
, (Group , 'Active Layers') , (Group , 'Active Layers')
, (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50 }) , (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50*scale })
, (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50 }) , (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50*scale })
, (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'diffusion.32' , 'border':0, 'threshold':1.50 }) , (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'diffusion.32' , 'border':0, 'threshold':1.50*scale })
, (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'diffusion.32' , 'border':0, 'threshold':1.50 }) , (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'diffusion.32' , 'border':0, 'threshold':1.50*scale })
, (Drawing, 'active' , { 'color':'White' , 'pattern':'active.32' , 'border':0, 'threshold':1.50 }) , (Drawing, 'active' , { 'color':'White' , 'pattern':'active.32' , 'border':0, 'threshold':1.50*scale })
, (Drawing, 'poly' , { 'color':'Red' , 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50 }) , (Drawing, 'poly' , { 'color':'Red' , 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50*scale })
, (Drawing, 'poly2' , { 'color':poly2Color , 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50 }) , (Drawing, 'poly2' , { 'color':poly2Color , 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50*scale })
# Group: Routing Layers. # Group: Routing Layers.
, (Group , 'Routing Layers') , (Group , 'Routing Layers')
, (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'slash.32' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'slash.32' , 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal2', { 'color':'Aqua' , 'pattern':'antislash2.32', 'border':1, 'threshold':0.02 }) , (Drawing, 'metal2', { 'color':'Aqua' , 'pattern':'antislash2.32', 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal3', { 'color':'LightPink', 'pattern':'antislash3.32', 'border':1, 'threshold':0.02 }) , (Drawing, 'metal3', { 'color':'LightPink', 'pattern':'antislash3.32', 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal4', { 'color':'Green' , 'pattern':'antislash4.32', 'border':1, 'threshold':0.02 }) , (Drawing, 'metal4', { 'color':'Green' , 'pattern':'antislash4.32', 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal5', { 'color':'Yellow' , 'pattern':'antislash5.32', 'border':1, 'threshold':0.02 }) , (Drawing, 'metal5', { 'color':'Yellow' , 'pattern':'antislash5.32', 'border':1, 'threshold':0.02*scale })
, (Drawing, 'metal6', { 'color':'Violet' , 'pattern':'antislash2.32', 'border':1, 'threshold':0.02 }) , (Drawing, 'metal6', { 'color':'Violet' , 'pattern':'antislash2.32', 'border':1, 'threshold':0.02*scale })
# Group: Cuts (VIA holes) # Group: Cuts (VIA holes)
, (Group , 'Cuts (VIA holes)') , (Group , 'Cuts (VIA holes)')
, (Drawing, 'cut0', { 'color':'Blue' , 'pattern':'poids2.8' , 'border':2, 'threshold':1.50 }) , (Drawing, 'cut0', { 'color':'Blue' , 'pattern':'poids2.8' , 'border':2, 'threshold':1.50*scale })
, (Drawing, 'cut1', { 'color':'Aqua' , 'pattern':'antipoids2.8', 'border':2, 'threshold':0.80 }) , (Drawing, 'cut1', { 'color':'Aqua' , 'pattern':'antipoids2.8', 'border':2, 'threshold':0.80*scale })
, (Drawing, 'cut2', { 'color':'LightPink', 'pattern':'poids2.8' , 'border':2, 'threshold':0.80 }) , (Drawing, 'cut2', { 'color':'LightPink', 'pattern':'poids2.8' , 'border':2, 'threshold':0.80*scale })
, (Drawing, 'cut3', { 'color':'Green' , 'pattern':'antipoids2.8', 'border':2, 'threshold':0.80 }) , (Drawing, 'cut3', { 'color':'Green' , 'pattern':'antipoids2.8', 'border':2, 'threshold':0.80*scale })
, (Drawing, 'cut4', { 'color':'Yellow' , 'pattern':'poids2.8' , 'border':2, 'threshold':0.80 }) , (Drawing, 'cut4', { 'color':'Yellow' , 'pattern':'poids2.8' , 'border':2, 'threshold':0.80*scale })
, (Drawing, 'cut5', { 'color':'Violet' , 'pattern':'antipoids2.8', 'border':2, 'threshold':0.80 }) , (Drawing, 'cut5', { 'color':'Violet' , 'pattern':'antipoids2.8', 'border':2, 'threshold':0.80*scale })
# Group: MIM6. # Group: MIM6.
, (Group , 'MIM6') , (Group , 'MIM6')
, (Drawing, 'topmim6', { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80 }) , (Drawing, 'topmim6', { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80*scale })
, (Drawing, 'botmim6', { 'color':'Aqua' , 'pattern':'light_antihash0.8', 'threshold':0.80 }) , (Drawing, 'botmim6', { 'color':'Aqua' , 'pattern':'light_antihash0.8', 'threshold':0.80*scale })
, (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8', 'threshold':0.80 }) , (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8', 'threshold':0.80*scale })
, (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80 }) , (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80*scale })
# Group: Blockages. # Group: Blockages.
, (Group , 'Blockages') , (Group , 'Blockages')
, (Drawing, 'blockage1', { 'color':'Blue' , 'pattern':'006070381c0e0703' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage1', { 'color':'Blue' , 'pattern':'006070381c0e0703' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage2', { 'color':'Aqua' , 'pattern':'8103060c183060c0' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage2', { 'color':'Aqua' , 'pattern':'8103060c183060c0' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage3', { 'color':'LightPink', 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage3', { 'color':'LightPink', 'pattern':'poids4.8' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage4', { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage4', { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage5', { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage5', { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.80*scale, 'border':2 })
, (Drawing, 'blockage6', { 'color':'Violet' , 'pattern':'light_antihash0.8', 'threshold':0.80, 'border':2 }) , (Drawing, 'blockage6', { 'color':'Violet' , 'pattern':'light_antihash0.8', 'threshold':0.80*scale, 'border':2 })
# Group: Knik & Kite. # Group: Knik & Kite.
, (Group , 'Knik & Kite') , (Group , 'Knik & Kite')

View File

@ -0,0 +1,68 @@
# -*- Mode:Python; explicit-buffer-name: "alliance.conf<cmos>" -*-
from helpers.Alliance import AddMode
from helpers.Alliance import Gauge
allianceTop = '/soc/alliance'
cellsTop = allianceTop+'/cells/'
allianceConfig = \
( ( 'SYMB_TECHNO_NAME' , helpers.symbolicTechno )
, ( 'REAL_TECHNO_NAME' , helpers.realTechno )
, ( 'SYMBOLIC_TECHNOLOGY', helpers.symbolicDir+'/technology.conf' )
, ( 'REAL_TECHNOLOGY' , helpers.realDir +'/technology.conf' )
, ( 'DISPLAY' , helpers.sysConfDir +'/display.xml' )
, ( 'CATALOG' , 'CATAL')
, ( 'WORKING_LIBRARY' , '.')
, ( 'SYSTEM_LIBRARY' , ( (cellsTop+'sxlib' , AddMode.Append)
, (cellsTop+'dp_sxlib', AddMode.Append)
, (cellsTop+'ramlib' , AddMode.Append)
, (cellsTop+'romlib' , AddMode.Append)
, (cellsTop+'rflib' , AddMode.Append)
, (cellsTop+'rf2lib' , AddMode.Append)
, (cellsTop+'pxlib' , AddMode.Append)
, (cellsTop+'padlib' , AddMode.Append) ) )
, ( 'SCALE_X' , 100)
, ( 'IN_LO' , 'vst')
, ( 'IN_PH' , 'ap')
, ( 'OUT_LO' , 'vst')
, ( 'OUT_PH' , 'ap')
, ( 'POWER' , 'vdd')
, ( 'GROUND' , 'vss')
, ( 'CLOCK' , '^ck.*')
, ( 'BLOCKAGE' , '^blockage[Nn]et*')
, ( 'PAD' , '.*_px$')
# The following are only read by the Alliance tool wrappers.
, ( 'ALLIANCE_TOP' , allianceTop)
, ( 'MBK_TARGET_LIB' , cellsTop+'sxlib')
, ( 'RDS_TECHNO_NAME' , allianceTop+'/etc/cmos.rds')
, ( 'GRAAL_TECHNO_NAME' , allianceTop+'/etc/graal.rds')
)
# Format of routingGaugesTable (dictionary):
# A list of entry of the form:
# ( METAL_NAME, (Direction, Type, depth, density, offset, pitch, wire_width, via_width) )
routingGaugesTable = {}
routingGaugesTable['sxlib'] = \
( ( 'METAL1', ( Gauge.Vertical , Gauge.PinOnly, 0, 0.0, 0, 5, 2, 1 ) )
, ( 'METAL2', ( Gauge.Horizontal, Gauge.Default, 1, 7.0, 0, 5, 2, 1 ) )
, ( 'METAL3', ( Gauge.Vertical , Gauge.Default, 2, 0.0, 0, 5, 2, 1 ) )
, ( 'METAL4', ( Gauge.Horizontal, Gauge.Default, 3, 0.0, 0, 5, 2, 1 ) )
, ( 'METAL5', ( Gauge.Vertical , Gauge.Default, 4, 0.0, 0, 5, 2, 1 ) )
#, ( 'METAL6', ( Gauge.Horizontal, Gauge.Default, 5, 0.0, 0, 5, 2, 1 ) )
#, ( 'METAL7', ( Gauge.Vertical , Gauge.Default, 6, 0.0, 0, 5, 2, 1 ) )
)
# Format of cellGaugesTable (dictionary):
# A list of entry of the form:
# ( METAL_PIN, xy_common_pitch, slice_height, slice_step )
cellGaugesTable = {}
cellGaugesTable['ispd05'] = ('metal2', 5.0, 60.0, 5.0)

View File

@ -0,0 +1,10 @@
# -*- Mode:Python; explicit-buffer-name: "display.conf<cmos>" -*-
import helpers
# Provides standard settings for:
# - <defaultStyle>
# - <stylesTable>
scale = 1.0
execfile( helpers.sysConfDir+'/common/display.conf' )

View File

@ -0,0 +1,5 @@
# -*- Mode:Python; explicit-buffer-name: "hMetis.conf<cmos>" -*-
import helpers
execfile( helpers.sysConfDir+'/common/hMetis.conf' )

View File

@ -0,0 +1,23 @@
# -*- Mode:Python; explicit-buffer-name: "kite.conf<cmos>" -*-
import helpers
# Contains the layout (shared by all technologies).
execfile( helpers.sysConfDir+'/common/kite.conf' )
parametersTable = \
( ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters.
, ("katabatic.saturateRatio" ,TypePercentage,80 )
, ("katabatic.saturateRp" ,TypeInt ,8 )
, ('katabatic.topRoutingLayer' ,TypeString , 'METAL5')
# Kite parameters.
, ("kite.hTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } )
, ("kite.vTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } )
, ("kite.eventsLimit" ,TypeInt ,4000002 )
, ("kite.ripupCost" ,TypeInt ,3 , { 'min':0 } )
, ("kite.strapRipupLimit" ,TypeInt ,16 , { 'min':1 } )
, ("kite.localRipupLimit" ,TypeInt ,9 , { 'min':1 } )
, ("kite.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } )
, ("kite.longGlobalRipupLimit" ,TypeInt ,5 , { 'min':1 } )
)

View File

@ -0,0 +1,5 @@
# -*- Mode:Python; explicit-buffer-name: "mauka.conf<cmos>" -*-
import helpers
execfile( helpers.sysConfDir+'/common/mauka.conf' )

View File

@ -0,0 +1,9 @@
# -*- Mode:Python; explicit-buffer-name: "misc.conf<cmos>" -*-
import helpers
# Provides standard settings for:
# # - <defaultStyle>
# # - <stylesTable>
#
execfile( helpers.sysConfDir+'/common/misc.conf' )

View File

@ -0,0 +1,5 @@
# -*- Mode:Python; explicit-buffer-name: "nimbus.conf<cmos>" -*-
import helpers
execfile( helpers.sysConfDir+'/common/nimbus.conf' )

View File

@ -0,0 +1,5 @@
# -*- Mode:Python; explicit-buffer-name: "patterns.conf<cmos>" -*-
import helpers
execfile( helpers.sysConfDir+'/common/patterns.conf' )

View File

@ -0,0 +1,23 @@
# -*- Mode:Python; explicit-buffer-name: "plugins.conf<cmos>" -*-
import helpers
# Contains the layout (shared by all technologies).
#execfile( helpers.sysConfDir+'/common/plugins.conf' )
# Parameters for chip plugin.
parametersTable = \
( ("chip.block.rails.count" , TypeInt , 5 )
, ("chip.block.rails.hWidth" , TypeInt , 12 )
, ("chip.block.rails.vWidth" , TypeInt , 12 )
, ("chip.block.rails.hSpacing" , TypeInt , 6 )
, ("chip.block.rails.vSpacing" , TypeInt , 6 )
, ('chip.pad.pck' , TypeString, 'pck_px')
, ('chip.pad.pvddick' , TypeString, 'pvddick_px')
, ('chip.pad.pvssick' , TypeString, 'pvssick_px')
, ('chip.pad.pvddeck' , TypeString, 'pvddeck_px')
, ('chip.pad.pvsseck' , TypeString, 'pvsseck_px')
, ('clockTree.minimumSide' , TypeInt , 300)
, ('clockTree.buffer' , TypeString, 'buf_x2')
)

View File

@ -0,0 +1,15 @@
# -*- Mode:Python; explicit-buffer-name: "stratus1.conf<cmos>" -*-
import helpers
# Status1 parameters.
parametersTable = \
( ("stratus1.mappingName", TypeString, helpers.sysConfDir+"/stratus2sxlib.xml",
{ 'flags':Cfg.Parameter.Flags.NeedRestart|Cfg.Parameter.Flags.MustExist } )
, ("stratus1.format" , TypeString, "vst")
, ("stratus1.simulator" , TypeString, "asimut")
,)
execfile( helpers.sysConfDir+'/common/stratus1.conf' )

View File

@ -0,0 +1,162 @@
# -*- Mode:Python; explicit-buffer-name: "technology.conf<cmos>" -*-
import helpers
# The informations here are extracted from the Alliance ".rds" file,
# and must be coherent with it.
#
# Provides standard settings for:
# - <viewerConfig>
# - <realLayersTable>
# - <symbolicLayersTable>
# - <workingLayersTable>
execfile( helpers.sysConfDir+'/common/technology.conf' )
# Format of <symbolicRulesTable>:
# Each entry is a pair of (string, value).
# * string: a synthetic way to designate the symbolic layer on which
# it applies, an optional real layer in case where there is
# more than one, and the dimension name.
# * value : the rule (dimension) value expressed in lambda.
symbolicRulesTable = \
( ('NWELL.nWell.extention.cap' , 0.0)
, ('PWELL.pWell.extention.cap' , 0.0)
, ('NTIE.minimum.width' , 3.0)
, ('NTIE.nWell.extention.cap' , 1.5)
, ('NTIE.nWell.extention.width' , 0.5)
, ('NTIE.nImplant.extention.cap' , 1.0)
, ('NTIE.nImplant.extention.width' , 0.5)
, ('NTIE.active.extention.cap' , 0.5)
, ('NTIE.active.extention.width' , 0.0)
, ('PTIE.minimum.width' , 3.0)
, ('PTIE.pWell.extention.cap' , 1.5)
, ('PTIE.pWell.extention.width' , 0.5)
, ('PTIE.pImplant.extention.cap' , 1.0)
, ('PTIE.pImplant.extention.width' , 0.5)
, ('PTIE.active.extention.cap' , 0.5)
, ('PTIE.active.extention.width' , 0.0)
, ('NDIF.minimum.width' , 3.0)
, ('NDIF.nImplant.extention.cap' , 1.0)
, ('NDIF.nImplant.extention.width' , 0.5)
, ('NDIF.active.extention.cap' , 0.5)
, ('NDIF.active.extention.width' , 0.0)
, ('PDIF.minimum.width' , 3.0)
, ('PDIF.pImplant.extention.cap' , 1.0)
, ('PDIF.pImplant.extention.width' , 0.5)
, ('PDIF.active.extention.cap' , 0.5)
, ('PDIF.active.extention.width' , 0.0)
, ('GATE.minimum.width' , 1.0)
, ('GATE.poly.extention.cap' , 1.5)
, ('NTRANS.minimum.width' , 1.0)
, ('NTRANS.nImplant.extention.cap' , -1.0)
, ('NTRANS.nImplant.extention.width' , 2.5)
, ('NTRANS.active.extention.cap' , -1.5)
, ('NTRANS.active.extention.width' , 2.0)
, ('PTRANS.minimum.width' , 1.0)
, ('PTRANS.nWell.extention.cap' , -1.0)
, ('PTRANS.nWell.extention.width' , 4.5)
, ('PTRANS.pImplant.extention.cap' , -1.0)
, ('PTRANS.pImplant.extention.width' , 4.0)
, ('PTRANS.active.extention.cap' , -1.5)
, ('PTRANS.active.extention.width' , 3.0)
, ('POLY.minimum.width' , 1.0)
, ('POLY.poly.extention.cap' , 0.5)
, ('POLY2.minimum.width' , 1.0)
, ('POLY2.poly.extention.cap' , 0.5)
# Routing Layers.
, ('METAL1.minimum.width' , 1.0)
, ('METAL1.metal1.extention.cap' , 0.5)
, ('METAL2.minimum.width' , 1.0)
, ('METAL2.metal2.extention.cap' , 1.0)
, ('METAL3.minimum.width' , 1.0)
, ('METAL3.metal3.extention.cap' , 1.0)
, ('METAL4.minimum.width' , 1.0)
, ('METAL4.metal4.extention.cap' , 1.0)
, ('METAL5.minimum.width' , 2.0)
, ('METAL5.metal5.extention.cap' , 1.0)
, ('METAL6.minimum.width' , 2.0)
, ('METAL6.metal6.extention.cap' , 1.0)
, ('METAL7.minimum.width' , 2.0)
, ('METAL7.metal6.extention.cap' , 1.0)
, ('METAL8.minimum.width' , 2.0)
, ('METAL8.metal6.extention.cap' , 1.0)
# Contacts (i.e. Active <--> Metal).
, ('CONT_BODY_N.minimum.side' , 1.0)
, ('CONT_BODY_N.nWell.enclosure' , 1.5)
, ('CONT_BODY_N.nImplant.enclosure' , 1.5)
, ('CONT_BODY_N.active.enclosure' , 1.0)
, ('CONT_BODY_N.metal1.enclosure' , 0.5)
, ('CONT_BODY_P.minimum.side' , 1.0)
, ('CONT_BODY_P.pWell.enclosure' , 1.5)
, ('CONT_BODY_P.pImplant.enclosure' , 1.5)
, ('CONT_BODY_P.active.enclosure' , 1.0)
, ('CONT_BODY_P.metal1.enclosure' , 0.5)
, ('CONT_DIF_N.minimum.side' , 1.0)
, ('CONT_DIF_N.nImplant.enclosure' , 1.0)
, ('CONT_DIF_N.active.enclosure' , 0.5)
, ('CONT_DIF_N.metal1.enclosure' , 0.5)
, ('CONT_DIF_P.minimum.side' , 1.0)
, ('CONT_DIF_P.pImplant.enclosure' , 1.0)
, ('CONT_DIF_P.active.enclosure' , 0.5)
, ('CONT_DIF_P.metal1.enclosure' , 0.5)
, ('CONT_POLY.minimum.width' , 1.0)
, ('CONT_POLY.poly.enclosure' , 0.5)
, ('CONT_POLY.metal1.enclosure' , 0.5)
# VIAs (i.e. Metal <--> Metal).
, ('VIA12.minimum.side' , 1.0)
, ('VIA12.metal1.enclosure' , 0.5)
, ('VIA12.metal2.enclosure' , 0.5)
, ('VIA23.minimum.side' , 1.0)
, ('VIA23.metal2.enclosure' , 0.5)
, ('VIA23.metal3.enclosure' , 0.5)
, ('VIA34.minimum.side' , 1.0)
, ('VIA34.metal3.enclosure' , 0.5)
, ('VIA34.metal4.enclosure' , 0.5)
, ('VIA45.minimum.side' , 1.0)
, ('VIA45.metal4.enclosure' , 0.5)
, ('VIA45.metal5.enclosure' , 0.5)
, ('VIA56.minimum.side' , 1.0)
, ('VIA56.metal5.enclosure' , 0.5)
, ('VIA56.metal6.enclosure' , 0.5)
, ('VIA67.minimum.side' , 1.0)
, ('VIA67.metal6.enclosure' , 0.5)
, ('VIA67.metal7.enclosure' , 0.5)
, ('VIA78.minimum.side' , 1.0)
, ('VIA78.metal7.enclosure' , 0.5)
, ('VIA78.metal8.enclosure' , 0.5)
# Blockages.
, ('BLOCKAGE1.minimum.width' , 1.0)
, ('BLOCKAGE1.blockage1.extention.cap' , 0.5)
, ('BLOCKAGE2.minimum.width' , 2.0)
, ('BLOCKAGE2.blockage2.extention.cap' , 0.5)
, ('BLOCKAGE3.minimum.width' , 2.0)
, ('BLOCKAGE3.blockage3.extention.cap' , 0.5)
, ('BLOCKAGE4.minimum.width' , 2.0)
, ('BLOCKAGE4.blockage4.extention.cap' , 0.5)
, ('BLOCKAGE5.minimum.width' , 2.0)
, ('BLOCKAGE5.blockage5.extention.cap' , 1.0)
, ('BLOCKAGE6.minimum.width' , 2.0)
, ('BLOCKAGE6.blockage6.extention.cap' , 1.0)
, ('BLOCKAGE7.minimum.width' , 2.0)
, ('BLOCKAGE7.blockage6.extention.cap' , 1.0)
, ('BLOCKAGE8.minimum.width' , 2.0)
, ('BLOCKAGE8.blockage6.extention.cap' , 1.0)
)

View File

@ -6,4 +6,6 @@ import helpers
# - <defaultStyle> # - <defaultStyle>
# - <stylesTable> # - <stylesTable>
scale = 0.5
execfile( helpers.sysConfDir+'/common/display.conf' ) execfile( helpers.sysConfDir+'/common/display.conf' )

View File

@ -21,6 +21,7 @@ parametersTable = \
, ('chip.pad.pvssick' , TypeString, 'pvssick_mpx') , ('chip.pad.pvssick' , TypeString, 'pvssick_mpx')
, ('chip.pad.pvddeck' , TypeString, 'pvddeck_mpx') , ('chip.pad.pvddeck' , TypeString, 'pvddeck_mpx')
, ('chip.pad.pvsseck' , TypeString, 'pvsseck_mpx') , ('chip.pad.pvsseck' , TypeString, 'pvsseck_mpx')
, ('clockTree.minimumSide' , TypeInt , 700) , ('clockTree.minimumSide' , TypeInt , 1000)
, ('clockTree.buffer' , TypeString, 'bf1_x4') , ('clockTree.buffer' , TypeString, 'bf1_x4')
, ('clockTree.placerEngine' , TypeString, 'Etesian')
) )

View File

@ -6,4 +6,6 @@ import helpers
# - <defaultStyle> # - <defaultStyle>
# - <stylesTable> # - <stylesTable>
scale = 0.5
execfile( helpers.sysConfDir+'/common/display.conf' ) execfile( helpers.sysConfDir+'/common/display.conf' )

View File

@ -36,6 +36,7 @@
#include "hurricane/UpdateSession.h" #include "hurricane/UpdateSession.h"
#include "crlcore/Utilities.h" #include "crlcore/Utilities.h"
#include "crlcore/AllianceFramework.h" #include "crlcore/AllianceFramework.h"
#include "crlcore/CellGauge.h"
#include "crlcore/ToolBox.h" #include "crlcore/ToolBox.h"
#include "crlcore/Ispd05Bookshelf.h" #include "crlcore/Ispd05Bookshelf.h"
@ -151,6 +152,7 @@ namespace CRL {
Cell* Ispd05::load ( string benchmark ) Cell* Ispd05::load ( string benchmark )
{ {
AllianceFramework* af = AllianceFramework::get(); AllianceFramework* af = AllianceFramework::get();
pitch = af->getCellGauge()->getPitch();
UpdateSession::open (); UpdateSession::open ();

View File

@ -27,6 +27,7 @@ try:
from helpers import trace from helpers import trace
from helpers import ErrorMessage from helpers import ErrorMessage
import Mauka import Mauka
import Etesian
import Unicorn import Unicorn
import plugins import plugins
import clocktree.ClockTree import clocktree.ClockTree
@ -101,9 +102,16 @@ def ScriptMain ( **kw ):
ht = clocktree.ClockTree.HTree.create( chip.Configuration.GaugeConfWrapper(chip.Configuration.GaugeConf()) ht = clocktree.ClockTree.HTree.create( chip.Configuration.GaugeConfWrapper(chip.Configuration.GaugeConf())
, cell, None, cell.getAbutmentBox() ) , cell, None, cell.getAbutmentBox() )
if editor: editor.refresh() if editor: editor.refresh()
mauka = Mauka.MaukaEngine.create( cell )
mauka.run() if Cfg.getParamString('clockTree.placerEngine').asString() != 'Etesian':
mauka.destroy() mauka = Mauka.MaukaEngine.create( cell )
mauka.run()
mauka.destroy()
else:
etesian = Etesian.EtesianEngine.create( cell )
etesian.place( Etesian.EtesianEngine.SlowMotion )
etesian.destroy()
ht.connectLeaf() ht.connectLeaf()
ht.prune() ht.prune()
ht.route() ht.route()

View File

@ -8,8 +8,8 @@
cmake_minimum_required(VERSION 2.8.9) cmake_minimum_required(VERSION 2.8.9)
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/") list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
find_package(COLOQUINTE) find_package(Coloquinte REQUIRED)
find_package(Bootstrap REQUIRED) find_package(Bootstrap REQUIRED)
setup_project_paths(CORIOLIS) setup_project_paths(CORIOLIS)
setup_project_paths(COLOQUINTE) setup_project_paths(COLOQUINTE)
setup_qt() setup_qt()

371
etesian/src/AddFeeds.cpp Normal file
View File

@ -0,0 +1,371 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | E t e s i a n - A n a l y t i c P l a c e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./AddFeeds.cpp" |
// +-----------------------------------------------------------------+
#include <map>
#include <list>
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
#include "hurricane/UpdateSession.h"
#include "hurricane/Instance.h"
#include "hurricane/Plug.h"
#include "hurricane/Path.h"
#include "hurricane/viewer/CellWidget.h"
#include "crlcore/AllianceFramework.h"
#include "crlcore/ToolBox.h"
#include "etesian/EtesianEngine.h"
namespace {
using namespace std;
using Hurricane::tab;
using Hurricane::inltrace;
using Hurricane::ltracein;
using Hurricane::ltraceout;
using Hurricane::ForEachIterator;
using Hurricane::Warning;
using Hurricane::Error;
using Hurricane::DbU;
using Hurricane::Box;
using Hurricane::Interval;
using Hurricane::Instance;
using Hurricane::Path;
using Hurricane::Transformation;
using Hurricane::DataBase;
using Hurricane::Cell;
using CRL::AllianceFramework;
using CRL::CatalogExtension;
using CRL::getTransformation;
using Etesian::EtesianEngine;
// -------------------------------------------------------------------
// Class : "::SliceHoles".
class SliceHoles;
class Slice {
public:
Slice ( SliceHoles*, DbU::Unit ybottom, Interval xspan );
inline DbU::Unit getYBottom () const;
inline const Interval& getXSpan () const;
inline DbU::Unit getXMin () const;
inline DbU::Unit getXMax () const;
inline SliceHoles* getSliceHoles () const;
inline EtesianEngine* getEtesian () const;
inline size_t getSpinSlice0 () const;
void merge ( DbU::Unit source, DbU::Unit target );
void addFeeds ( size_t islice );
void fillHole ( DbU::Unit xmin, DbU::Unit xmax, DbU::Unit ybottom, size_t yspin );
string _getString () const;
private:
SliceHoles* _sliceHoles;
DbU::Unit _ybottom;
Interval _xspan;
list<Interval> _chunks;
};
class SliceHoles {
public:
SliceHoles ( EtesianEngine* );
~SliceHoles ();
inline EtesianEngine* getEtesian () const;
inline size_t getSpinSlice0 () const;
inline void setSpinSlice0 ( size_t );
void merge ( const Box& );
void addFeeds ();
private:
EtesianEngine* _etesian;
Box _cellAb;
DbU::Unit _sliceHeight;
vector<Slice*> _slices;
size_t _spinSlice0;
};
Slice::Slice ( SliceHoles* sliceHoles, DbU::Unit ybottom, Interval xspan )
: _sliceHoles(sliceHoles)
, _ybottom (ybottom)
, _xspan (xspan)
, _chunks ()
{ }
inline DbU::Unit Slice::getYBottom () const { return _ybottom; }
inline DbU::Unit Slice::getXMin () const { return _xspan.getVMin(); }
inline DbU::Unit Slice::getXMax () const { return _xspan.getVMax(); }
inline const Interval& Slice::getXSpan () const { return _xspan; }
inline SliceHoles* Slice::getSliceHoles () const { return _sliceHoles; }
inline EtesianEngine* Slice::getEtesian () const { return getSliceHoles()->getEtesian(); }
inline size_t Slice::getSpinSlice0 () const { return getSliceHoles()->getSpinSlice0(); }
void Slice::merge ( DbU::Unit source, DbU::Unit target )
{
Interval chunkToMerge = _xspan.getIntersection( Interval(source,target) );
ltrace(300) << " Slice::merge() " << " " << chunkToMerge << endl;
ltrace(300) << " | " << _getString() << endl;
if (chunkToMerge.isEmpty()) return;
list<Interval>::iterator imerge = _chunks.end();
list<Interval>::iterator ichunk = _chunks.begin();
while ( ichunk != _chunks.end() ) {
if (imerge == _chunks.end()) {
if (chunkToMerge.getVMax() < (*ichunk).getVMin()) {
ltrace(300) << " | Insert before " << *ichunk << endl;
imerge = _chunks.insert( ichunk, chunkToMerge );
break;
}
if (chunkToMerge.intersect(*ichunk)) {
ltrace(300) << " | Merge with " << *ichunk << endl;
imerge = ichunk;
(*imerge).merge( chunkToMerge );
}
} else {
if (chunkToMerge.getVMax() >= (*ichunk).getVMin()) {
(*imerge).merge( *ichunk );
ltrace(300) << " | Absorb (erase) " << *ichunk << endl;
ichunk = _chunks.erase( ichunk );
continue;
} else
break;
}
++ichunk;
}
if (imerge == _chunks.end()) {
_chunks.insert( ichunk, chunkToMerge );
ltrace(300) << " | Insert at end " << DbU::getValueString(_ybottom) << " " << chunkToMerge << endl;
ltrace(300) << " | " << _getString() << endl;
}
}
void Slice::addFeeds ( size_t islice )
{
if (_chunks.empty()) {
fillHole( getXMin(), getXMax(), getYBottom(), islice%2 );
return;
}
list<Interval>::iterator ichunk = _chunks.begin();
list<Interval>::iterator ichunknext = ichunk;
++ichunknext;
// Hole before the first chunk.
if ((*ichunk).getVMin() > getXMin()) {
fillHole( getXMin(), (*ichunk).getVMin(), getYBottom(), (islice+getSpinSlice0())%2 );
}
for ( ; ichunknext != _chunks.end() ; ++ichunk, ++ichunknext ) {
fillHole( (*ichunk).getVMax(), (*ichunknext).getVMin(), getYBottom(), (islice+getSpinSlice0())%2 );
}
// Hole after the last chunk.
if ((*ichunk).getVMax() < getXMax()) {
fillHole( (*ichunk).getVMax(), getXMax(), getYBottom(), (islice+getSpinSlice0())%2 );
}
}
void Slice::fillHole ( DbU::Unit xmin, DbU::Unit xmax, DbU::Unit ybottom, size_t yspin )
{
Cell* feed = getEtesian()->getFeedCells().getBiggestFeed();
if (feed == NULL) {
cerr << Error("EtesianEngine: No feed has been registered, ignoring.") << endl;
return;
}
DbU::Unit feedWidth = feed->getAbutmentBox().getWidth();
DbU::Unit xtie = xmin;
while ( true ) {
if (xtie >= xmax) break;
if (xtie+feedWidth > xmax) {
// Feed is too big, try to find a smaller one.
int pitch = (int)((xmax-xtie) / getEtesian()->getPitch());
for ( ; pitch > 0 ; --pitch ) {
feed = getEtesian()->getFeedCells().getFeed( pitch );
feedWidth = feed->getAbutmentBox().getWidth();
if (feed != NULL) break;
}
if (feed == NULL) break;
}
Instance::create ( getEtesian()->getCell()
, getEtesian()->getFeedCells().getUniqueInstanceName().c_str()
, feed
, getTransformation( feed->getAbutmentBox()
, xtie
, _ybottom
, (yspin)?Transformation::Orientation::MY
:Transformation::Orientation::ID
)
, Instance::PlacementStatus::PLACED
);
xtie += feedWidth;
}
}
string Slice::_getString () const
{
ostringstream os;
os << "<Slice " << " @" << DbU::getValueString(_ybottom) << " ";
list<Interval>::const_iterator ichunk = _chunks.begin();
for ( ; ichunk != _chunks.end() ; ++ichunk ) {
if (ichunk != _chunks.begin()) os << " ";
os << "[" << DbU::getValueString((*ichunk).getVMin())
<< " " << DbU::getValueString((*ichunk).getVMax()) << "]";
}
os << ">";
return os.str();
}
SliceHoles::SliceHoles ( EtesianEngine* etesian )
: _etesian (etesian)
, _cellAb (etesian->getCell()->getAbutmentBox())
, _sliceHeight(_etesian->getSliceHeight())
, _slices ()
{
size_t slicesNb = _cellAb.getHeight() / _sliceHeight;
for ( size_t islice=0 ; islice<slicesNb ; ++islice )
_slices.push_back( new Slice( this
, _cellAb.getYMin()+islice*_sliceHeight
, Interval(_cellAb.getXMin(),_cellAb.getXMax()) ) );
}
SliceHoles::~SliceHoles ()
{
for ( size_t islice=0 ; islice<_slices.size() ; ++islice )
delete _slices[islice];
}
inline EtesianEngine* SliceHoles::getEtesian () const { return _etesian; }
inline size_t SliceHoles::getSpinSlice0 () const { return _spinSlice0; }
inline void SliceHoles::setSpinSlice0 ( size_t spinSlice0 ) { _spinSlice0 = spinSlice0; }
void SliceHoles::merge ( const Box& bb )
{
if (bb.getYMin() < _cellAb.getYMin()) {
cerr << Warning("Attempt to merge instance outside the Cell abutment box.") << endl;
return;
}
size_t ibegin = (bb.getYMin()-_cellAb.getYMin()) / _sliceHeight;
size_t iend = (bb.getYMax()-_cellAb.getYMin()) / _sliceHeight;
for ( size_t islice=ibegin ; islice<iend ; ++islice ) {
_slices[islice]->merge( bb.getXMin(), bb.getXMax() );
}
}
void SliceHoles::addFeeds ()
{
for ( size_t islice=0 ; islice<_slices.size() ; islice++ )
_slices[islice]->addFeeds( islice );
}
} // End of anonymous namespace.
namespace Etesian {
using Hurricane::ForEachIterator;
using Hurricane::DataBase;
using Hurricane::UpdateSession;
using Hurricane::Occurrence;
void EtesianEngine::addFeeds ()
{
UpdateSession::open();
bool yspinSet = false;
size_t yspinSlice0 = 0;
SliceHoles sliceHoles ( this );
forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() )
{
Instance* instance = static_cast<Instance*>((*ioccurrence).getEntity());
Cell* masterCell = instance->getMasterCell();
if (CatalogExtension::isFeed(masterCell)) {
cerr << Warning( "Feed instance %s already present."
, getString(instance->getName()).c_str() ) << endl;
}
Box instanceAb = masterCell->getAbutmentBox();
Transformation instanceTransf = instance->getTransformation();
(*ioccurrence).getPath().getTransformation().applyOn( instanceTransf );
instanceTransf.applyOn( instanceAb );
if (not yspinSet) {
yspinSet = true;
int islice = (instanceAb.getYMin() - getCell()->getAbutmentBox().getYMin()) / getSliceHeight();
switch ( instanceTransf.getOrientation() ) {
case Transformation::Orientation::ID:
case Transformation::Orientation::MX:
yspinSlice0 = (islice % 2);
break;
case Transformation::Orientation::R2:
case Transformation::Orientation::MY:
yspinSlice0 = ((islice+1) % 2);
break;
case Transformation::Orientation::R1:
case Transformation::Orientation::R3:
case Transformation::Orientation::XR:
case Transformation::Orientation::YR:
cerr << Warning( "Instance %s has invalid transformation %s."
, getString(instance->getName()).c_str()
, getString(instanceTransf.getOrientation()).c_str()
) << endl;
yspinSet = false;
break;
}
sliceHoles.setSpinSlice0( yspinSlice0 );
}
sliceHoles.merge( instanceAb );
}
sliceHoles.addFeeds();
UpdateSession::close();
if (_cellWidget) _cellWidget->refresh();
}
} // Kite namespace.

View File

@ -4,7 +4,6 @@
include_directories ( ${ETESIAN_SOURCE_DIR}/src include_directories ( ${ETESIAN_SOURCE_DIR}/src
${COLOQUINTE_INCLUDE_DIR} ${COLOQUINTE_INCLUDE_DIR}
${EIGEN3_INCLUDE_DIR}
${CORIOLIS_INCLUDE_DIR} ${CORIOLIS_INCLUDE_DIR}
${HURRICANE_INCLUDE_DIR} ${HURRICANE_INCLUDE_DIR}
${CONFIGURATION_INCLUDE_DIR} ${CONFIGURATION_INCLUDE_DIR}
@ -12,27 +11,8 @@
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
${PYTHON_INCLUDE_PATH} ${PYTHON_INCLUDE_PATH}
) )
set ( includes #etesian/Constants.h set ( includes etesian/Configuration.h
#etesian/TrackCost.h etesian/FeedCells.h
#etesian/DataNegociate.h
#etesian/TrackElement.h etesian/TrackElements.h
#etesian/TrackSegment.h
#etesian/TrackFixedSegment.h
#etesian/TrackMarker.h
#etesian/Track.h
#etesian/Tracks.h
#etesian/HorizontalTrack.h
#etesian/VerticalTrack.h
#etesian/RoutingPlane.h
#etesian/Session.h
#etesian/Manipulator.h
#etesian/SegmentFsm.h
#etesian/RoutingEvent.h
#etesian/RoutingEventQueue.h
#etesian/RoutingEventHistory.h
#etesian/RoutingEventLoop.h
#etesian/NegociateWindow.h
etesian/Configuration.h
etesian/EtesianEngine.h etesian/EtesianEngine.h
etesian/GraphicEtesianEngine.h etesian/GraphicEtesianEngine.h
) )
@ -40,30 +20,9 @@
etesian/PyGraphicEtesianEngine.h etesian/PyGraphicEtesianEngine.h
) )
set ( mocIncludes etesian/GraphicEtesianEngine.h ) set ( mocIncludes etesian/GraphicEtesianEngine.h )
set ( cpps #TrackCost.cpp set ( cpps Configuration.cpp
#DataNegociate.cpp AddFeeds.cpp
#TrackElement.cpp FeedCells.cpp
#TrackElements.cpp
#TrackSegment.cpp
#TrackFixedSegment.cpp
#TrackMarker.cpp
#Track.cpp
#Tracks.cpp
#HorizontalTrack.cpp
#VerticalTrack.cpp
#RoutingPlane.cpp
#Session.cpp
#Manipulator.cpp
#SegmentFsm.cpp
#RoutingEvent.cpp
#RoutingEventQueue.cpp
#RoutingEventHistory.cpp
#RoutingEventLoop.cpp
#NegociateWindow.cpp
#BuildPowerRails.cpp
#ProtectRoutingPads.cpp
#PreProcess.cpp
Configuration.cpp
EtesianEngine.cpp EtesianEngine.cpp
GraphicEtesianEngine.cpp GraphicEtesianEngine.cpp
) )
@ -71,7 +30,6 @@
PyEtesianEngine.cpp PyEtesianEngine.cpp
PyGraphicEtesianEngine.cpp PyGraphicEtesianEngine.cpp
) )
# set ( etesiancpps EtesianMain.cpp )
qtX_wrap_cpp ( mocCpps ${mocIncludes} ) qtX_wrap_cpp ( mocCpps ${mocIncludes} )
add_library ( etesian ${cpps} ${mocCpps} ${pyCpps} ) add_library ( etesian ${cpps} ${mocCpps} ${pyCpps} )

View File

@ -24,9 +24,10 @@
#include "hurricane/DataBase.h" #include "hurricane/DataBase.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "crlcore/Utilities.h" #include "crlcore/Utilities.h"
#include "crlcore/RoutingLayerGauge.h" #include "crlcore/CellGauge.h"
#include "crlcore/AllianceFramework.h" #include "crlcore/AllianceFramework.h"
#include "etesian/Configuration.h" #include "etesian/Configuration.h"
#include "etesian/EtesianEngine.h"
@ -45,8 +46,7 @@ namespace Etesian {
using Hurricane::Technology; using Hurricane::Technology;
using Hurricane::DataBase; using Hurricane::DataBase;
using CRL::AllianceFramework; using CRL::AllianceFramework;
using CRL::RoutingGauge; using CRL::CellGauge;
using CRL::RoutingLayerGauge;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -61,43 +61,44 @@ namespace Etesian {
// Class : "Etesian::ConfigurationConcrete". // Class : "Etesian::ConfigurationConcrete".
ConfigurationConcrete::ConfigurationConcrete ( const RoutingGauge* rg ) ConfigurationConcrete::ConfigurationConcrete ( const CellGauge* cg )
: Configuration() : Configuration()
, _rg (NULL) , _cg (NULL)
, _flags (0)
{ {
if ( rg == NULL ) rg = AllianceFramework::get()->getRoutingGauge(); if ( cg == NULL ) cg = AllianceFramework::get()->getCellGauge();
_rg = rg->getClone(); _cg = cg->getClone();
} }
ConfigurationConcrete::ConfigurationConcrete ( const ConfigurationConcrete& other ) ConfigurationConcrete::ConfigurationConcrete ( const ConfigurationConcrete& other )
: Configuration() : Configuration()
, _rg (NULL) , _cg (NULL)
, _flags (other._flags)
{ {
if ( other._rg ) _rg = other._rg->getClone(); if ( other._cg ) _cg = other._cg->getClone();
} }
ConfigurationConcrete::~ConfigurationConcrete () ConfigurationConcrete::~ConfigurationConcrete ()
{ {
ltrace(89) << "About to delete attribute _rg (RoutingGauge)." << endl; ltrace(89) << "About to delete attribute _cg (CellGauge)." << endl;
_rg->destroy (); _cg->destroy ();
} }
ConfigurationConcrete* ConfigurationConcrete::clone () const ConfigurationConcrete* ConfigurationConcrete::clone () const { return new ConfigurationConcrete(*this); }
{ return new ConfigurationConcrete(*this); } CellGauge* ConfigurationConcrete::getCellGauge () const { return _cg; }
bool ConfigurationConcrete::isSlowMotion () const { return _flags & EtesianEngine::SlowMotion; }
void ConfigurationConcrete::setFlags ( unsigned int flags ) { _flags |= flags; }
RoutingGauge* ConfigurationConcrete::getRoutingGauge () const void ConfigurationConcrete::unsetFlags ( unsigned int flags ) { _flags &= ~flags; }
{ return _rg; }
void ConfigurationConcrete::print ( Cell* cell ) const void ConfigurationConcrete::print ( Cell* cell ) const
{ {
cout << " o Configuration of ToolEngine<Etesian> for Cell <" << cell->getName() << ">" << endl; cout << " o Configuration of ToolEngine<Etesian> for Cell <" << cell->getName() << ">" << endl;
cout << Dots::asIdentifier(" - Routing Gauge" ,getString(_rg->getName())) << endl; cout << Dots::asIdentifier(" - Cell Gauge",getString(_cg->getName())) << endl;
} }
@ -109,7 +110,7 @@ namespace Etesian {
{ {
ostringstream os; ostringstream os;
os << "<" << _getTypeName() << " " << _rg->getName() << ">"; os << "<" << _getTypeName() << " " << _cg->getName() << ">";
return os.str(); return os.str();
} }
@ -118,7 +119,7 @@ namespace Etesian {
Record* ConfigurationConcrete::_getRecord () const Record* ConfigurationConcrete::_getRecord () const
{ {
Record* record = new Record ( _getString() ); Record* record = new Record ( _getString() );
record->add ( getSlot ( "_rg" , _rg ) ); record->add ( getSlot ( "_cg" , _cg ) );
return ( record ); return ( record );
} }

View File

@ -18,7 +18,8 @@
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#if HAVE_COLOQUINTE #if HAVE_COLOQUINTE
#include "coloquinte/circuit_graph.hxx" #include "Coloquinte/circuit.hxx"
#include "Coloquinte/legalizer.hxx"
#endif #endif
#include "vlsisapd/utilities/Dots.h" #include "vlsisapd/utilities/Dots.h"
#include "hurricane/DebugSession.h" #include "hurricane/DebugSession.h"
@ -42,15 +43,23 @@
#include "crlcore/Measures.h" #include "crlcore/Measures.h"
#include "crlcore/AllianceFramework.h" #include "crlcore/AllianceFramework.h"
#include "etesian/EtesianEngine.h" #include "etesian/EtesianEngine.h"
#include "etesian/FeedCells.h"
namespace { namespace {
using namespace std; using namespace std;
using namespace Hurricane; using namespace Hurricane;
using coloquinte::float_t;
using coloquinte::point;
#if HAVE_COLOQUINTE #if HAVE_COLOQUINTE
inline bool isNan( const float_t& f ) { return (f != f); }
string extractInstanceName ( const RoutingPad* rp ) string extractInstanceName ( const RoutingPad* rp )
{ {
ostringstream name; ostringstream name;
@ -102,6 +111,7 @@ namespace {
} }
#if 0
Coloquinte::cell::pin::pin_dir extractDirection ( const RoutingPad* rp ) Coloquinte::cell::pin::pin_dir extractDirection ( const RoutingPad* rp )
{ {
switch ( rp->_getEntityAsComponent()->getNet()->getDirection() ) { switch ( rp->_getEntityAsComponent()->getNet()->getDirection() ) {
@ -114,6 +124,7 @@ namespace {
return Coloquinte::cell::pin::O; return Coloquinte::cell::pin::O;
} }
#endif
Point extractRpOffset ( const RoutingPad* rp ) Point extractRpOffset ( const RoutingPad* rp )
@ -129,6 +140,38 @@ namespace {
return offset; return offset;
} }
Transformation toTransformation ( point<float_t> position
, point<float_t> orientation
, Cell* model
, DbU::Unit pitch
)
{
DbU::Unit tx = position.x_ * pitch;
DbU::Unit ty = position.y_ * pitch;
Point center = model->getAbutmentBox().getCenter();
Transformation::Orientation orient = Transformation::Orientation::ID;
if ( (orientation.x_ >= 0) and (orientation.y_ >= 0) ) {
tx += - center.getX();
ty += - center.getY();
} else if ( (orientation.x_ < 0) and (orientation.y_ >= 0) ) {
tx += center.getX();
ty += - center.getY();
orient = Transformation::Orientation::MX;
} else if ( (orientation.x_ >= 0) and (orientation.y_ < 0) ) {
tx += - center.getX();
ty += center.getY();
orient = Transformation::Orientation::MY;
} else if ( (orientation.x_ < 0) and (orientation.y_ < 0) ) {
tx += center.getX();
ty += center.getY();
orient = Transformation::Orientation::R2;
}
return Transformation( tx, ty, orient );
}
#endif #endif
@ -172,11 +215,31 @@ namespace Etesian {
using Hurricane::CellWidget; using Hurricane::CellWidget;
using CRL::ToolEngine; using CRL::ToolEngine;
using CRL::AllianceFramework; using CRL::AllianceFramework;
using CRL::Catalog;
using CRL::addMeasure; using CRL::addMeasure;
using CRL::Measures; using CRL::Measures;
using CRL::MeasuresSet; using CRL::MeasuresSet;
using CRL::CatalogExtension; using CRL::CatalogExtension;
using coloquinte::index_t;
using coloquinte::capacity_t;
using coloquinte::int_t;
using coloquinte::float_t;
using coloquinte::point;
using coloquinte::box;
using coloquinte::Movability;
using coloquinte::temporary_cell;
using coloquinte::temporary_net;
using coloquinte::temporary_pin;
using coloquinte::netlist;
using coloquinte::gp::placement_t;
using coloquinte::gp::get_rough_legalizer;
using coloquinte::gp::get_star_linear_system;
using coloquinte::gp::get_result;
using coloquinte::dp::legalize;
using coloquinte::dp::swaps_global;
using coloquinte::dp::swaps_row;
using coloquinte::dp::OSRP_convex;
using coloquinte::dp::row_compatible_orientation;
const char* missingEtesian = const char* missingEtesian =
"%s :\n\n" "%s :\n\n"
@ -199,16 +262,27 @@ namespace Etesian {
EtesianEngine::EtesianEngine ( Cell* cell ) EtesianEngine::EtesianEngine ( Cell* cell )
: ToolEngine (cell) : ToolEngine (cell)
, _configuration(NULL) , _configuration(new ConfigurationConcrete())
, _flags (0) , _flags (0)
, _circuit (NULL) , _timer ()
, _surface ()
, _circuit ()
, _placementLB ()
, _placementUB ()
, _cellsToIds () , _cellsToIds ()
, _idsToInsts ()
, _cellWidget (NULL) , _cellWidget (NULL)
, _feedCells (this)
{ } { }
void EtesianEngine::_postCreate () void EtesianEngine::_postCreate ()
{ } {
// Ugly. Direct uses of Alliance Framework.
// Must change toward something in the settings.
_feedCells.useFeed( AllianceFramework::get()->getCell("tie_x0" ,Catalog::State::Views) );
_feedCells.useFeed( AllianceFramework::get()->getCell("rowend_x0",Catalog::State::Views) );
}
EtesianEngine* EtesianEngine::create ( Cell* cell ) EtesianEngine* EtesianEngine::create ( Cell* cell )
@ -234,9 +308,6 @@ namespace Etesian {
EtesianEngine::~EtesianEngine () EtesianEngine::~EtesianEngine ()
{ {
#if HAVE_COLOQUINTE
if (_circuit) delete _circuit;
#endif
delete _configuration; delete _configuration;
} }
@ -245,10 +316,41 @@ namespace Etesian {
{ return _toolName; } { return _toolName; }
const Configuration* EtesianEngine::getConfiguration () const
{ return _configuration; }
Configuration* EtesianEngine::getConfiguration () Configuration* EtesianEngine::getConfiguration ()
{ return _configuration; } { return _configuration; }
void EtesianEngine::startMeasures ()
{
_timer.resetIncrease();
_timer.start();
}
void EtesianEngine::stopMeasures ()
{ _timer.stop(); }
void EtesianEngine::printMeasures ( string tag ) const
{
ostringstream result;
result << Timer::getStringTime(_timer.getCombTime()) << ", "
<< Timer::getStringMemory(_timer.getIncrease());
cmess1 << ::Dots::asString( " - Done in", result.str() ) << endl;
result.str("");
result << _timer.getCombTime()
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
<< (_timer.getMemorySize()>>10) << "Kb";
cmess2 << ::Dots::asString( " - Raw measurements", result.str() ) << endl;
}
void EtesianEngine::resetPlacement () void EtesianEngine::resetPlacement ()
{ {
//cerr << "EtesianEngine::resetPlacement()" << endl; //cerr << "EtesianEngine::resetPlacement()" << endl;
@ -293,31 +395,46 @@ namespace Etesian {
} }
void EtesianEngine::place ( unsigned int slowMotion ) void EtesianEngine::toColoquinte ()
{ {
#if HAVE_COLOQUINTE #if HAVE_COLOQUINTE
cmess1 << " o Converting <" << getCell()->getName() << "> into Coloquinte." << endl; cmess1 << " o Converting <" << getCell()->getName() << "> into Coloquinte." << endl;
resetPlacement(); resetPlacement();
Dots dots ( cmess2, " ", 80, 1000 ); Dots dots ( cmess2, " ", 80, 1000 );
AllianceFramework* af = AllianceFramework::get(); AllianceFramework* af = AllianceFramework::get();
DbU::Unit pitch = getPitch();
cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl;
getCell()->flattenNets( Cell::BuildRings ); getCell()->flattenNets( Cell::BuildRings );
// Coloquinte circuit description data-structures. // Coloquinte circuit description data-structures.
size_t instancesNb = getCell()->getLeafInstanceOccurrences().getSize(); size_t instancesNb = getCell()->getLeafInstanceOccurrences().getSize();
vector<Transformation> idsToTransf ( instancesNb ); vector<Transformation> idsToTransf ( instancesNb );
vector<temporary_cell> instances ( instancesNb );
vector< point<float_t> > positions ( instancesNb );
vector< point<float_t> > orientations( instancesNb, point<float_t>(1.0,1.0) );
_circuit = new Coloquinte::circuit(); cmess1 << " - Converting " << instancesNb << " instances" << endl;
_circuit->cells .resize( instancesNb );
_circuit->hypernets.resize( getCell()->getNets().getSize() );
cmess1 << " - Converting Instances (Bookshelf nodes)" << endl;
cout.flush(); cout.flush();
Coloquinte::cell_id cellId = 0; Box topAb = getCell()->getAbutmentBox();
UpdateSession::open();
forEach ( Occurrence, ioccurrence, getCell()->getNonLeafInstanceOccurrences() )
{
Instance* instance = static_cast<Instance*>((*ioccurrence).getEntity());
Cell* masterCell = instance->getMasterCell();
// Have to check here if the model is fully placed or not.
masterCell->setAbutmentBox( topAb );
instance->setTransformation( Transformation() ); // (0,0,ID).
instance->setPlacementStatus( Instance::PlacementStatus::PLACED );
}
UpdateSession::close();
index_t instanceId = 0;
forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() ) forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() )
{ {
Instance* instance = static_cast<Instance*>((*ioccurrence).getEntity()); Instance* instance = static_cast<Instance*>((*ioccurrence).getEntity());
@ -327,32 +444,48 @@ namespace Etesian {
instanceName.erase( 0, 1 ); instanceName.erase( 0, 1 );
instanceName.erase( instanceName.size()-1 ); instanceName.erase( instanceName.size()-1 );
if (CatalogExtension::isFeed(masterCell)) continue; if (CatalogExtension::isFeed(masterCell)) {
cerr << Warning("Feed instance found and skipped.") << endl;
continue;
}
Box instanceAb = masterCell->getAbutmentBox();
Coloquinte::circuit_coordinate cellSize ( masterCell->getAbutmentBox().getWidth () / DbU::fromLambda(5.0)
, masterCell->getAbutmentBox().getHeight() / DbU::fromLambda(5.0) );
_cellsToIds.insert( make_pair(instanceName,cellId) );
Transformation instanceTransf = instance->getTransformation(); Transformation instanceTransf = instance->getTransformation();
(*ioccurrence).getPath().getTransformation().applyOn( instanceTransf ); (*ioccurrence).getPath().getTransformation().applyOn( instanceTransf );
idsToTransf[cellId] = instanceTransf; instanceTransf.applyOn( instanceAb );
double xsize = instanceAb.getWidth () / pitch;
double ysize = instanceAb.getHeight() / pitch;
double xpos = instanceAb.getCenter().getX() / pitch;
double ypos = instanceAb.getCenter().getY() / pitch;
instances[instanceId].size = point<int_t>( xsize, ysize );
instances[instanceId].list_index = instanceId;
instances[instanceId].area = static_cast<capacity_t>(xsize) * static_cast<capacity_t>(ysize);
positions[instanceId] = point<float_t>( xpos, ypos );
if ( not instance->isFixed() and instance->isTerminal() ) {
instances[instanceId].attributes = coloquinte::XMovable
|coloquinte::YMovable
|coloquinte::XFlippable
|coloquinte::YFlippable;
} else {
instances[instanceId].attributes = 0;
}
_cellsToIds.insert( make_pair(instanceName,instanceId) );
_idsToInsts.push_back( instance );
++instanceId;
dots.dot(); dots.dot();
//cerr << instanceName << " " << (int)instance->getPlacementStatus().getCode()
// << " area:" << cellSize.cast<Coloquinte::cell_area>().prod() << endl;
_circuit->cells[cellId].name = instanceName;
_circuit->cells[cellId].sizes = cellSize;
_circuit->cells[cellId].area = cellSize.cast<Coloquinte::cell_area>().prod();
_circuit->cells[cellId].movable = not instance->isFixed() and instance->isTerminal();
//if (not _circuit->cells[cellId].movable)
// cerr << "FIXED (movable=false):" << instance << endl;
//_circuit->cells[cellId].movable = (instance->getPlacementStatus() == Instance::PlacementStatus::UNPLACED);
cellId++;
} }
dots.finish( Dots::Reset|Dots::FirstDot ); dots.finish( Dots::Reset|Dots::FirstDot );
cmess1 << " - Converting Nets (Bookshelf nets)" << endl; size_t netsNb = getCell()->getNets().getSize();
cmess1 << " - Converting " << netsNb << " nets" << endl;
vector<temporary_net> nets ( netsNb );
vector<temporary_pin> pins;
unsigned int netId = 0; unsigned int netId = 0;
forEach ( Net*, inet, getCell()->getNets() ) forEach ( Net*, inet, getCell()->getNets() )
@ -369,32 +502,20 @@ namespace Etesian {
if (af->isBLOCKAGE((*inet)->getName())) continue; if (af->isBLOCKAGE((*inet)->getName())) continue;
dots.dot(); dots.dot();
//cerr << (*inet)->getName() << endl;
nets[netId] = temporary_net( netId, 1.0 );
forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) { forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) {
//cerr << " " << (*irp)->getOccurrence().getCompactString() << endl;
string insName = extractInstanceName( *irp ); string insName = extractInstanceName( *irp );
Point offset = extractRpOffset ( *irp ); Point offset = extractRpOffset ( *irp );
double xpin = offset.getX() / pitch;
//cerr << " Master Cell: " << (*irp)->getOccurrence().getMasterCell() << endl; double ypin = offset.getY() / pitch;
//cerr << " Rebuilt instance name: " << insName << " " << offset << endl;
auto iid = _cellsToIds.find( insName ); auto iid = _cellsToIds.find( insName );
if (iid == _cellsToIds.end() ) { if (iid == _cellsToIds.end() ) {
cerr << Error( "Unable to lookup instance <%s>.", insName.c_str() ) << endl; cerr << Error( "Unable to lookup instance <%s>.", insName.c_str() ) << endl;
} else { } else {
Coloquinte::cell_id cellId = (*iid).second; pins.push_back( temporary_pin( point<float_t>(xpin,ypin), (*iid).second, netId ) );
Coloquinte::hypernet::pin_id netPinId ( cellId, _circuit->cells [cellId].pins.size() );
Coloquinte::cell::pin_id cellPinId ( netId , _circuit->hypernets[netId ].pins.size() );
_circuit->hypernets[netId].pins.push_back( netPinId );
Coloquinte::cell::pin cellPin;
//cellPin.name = extractTerminalName( *irp );
cellPin.d = extractDirection ( *irp );
cellPin.offs.x() = offset.getX() / DbU::fromLambda(5.0);
cellPin.offs.y() = offset.getY() / DbU::fromLambda(5.0);
cellPin.ind = cellPinId;
_circuit->cells[cellId].pins.push_back( cellPin );
} }
} }
@ -402,110 +523,186 @@ namespace Etesian {
} }
dots.finish( Dots::Reset ); dots.finish( Dots::Reset );
_circuit->position_overlays.resize(1); _surface = box<int_t>( (int_t)(getCell()->getAbutmentBox().getXMin() / pitch)
_circuit->position_overlays[0].x_pos = Coloquinte::circuit_vector( _cellsToIds.size() ); , (int_t)(getCell()->getAbutmentBox().getXMax() / pitch)
_circuit->position_overlays[0].y_pos = Coloquinte::circuit_vector( _cellsToIds.size() ); , (int_t)(getCell()->getAbutmentBox().getYMin() / pitch)
, (int_t)(getCell()->getAbutmentBox().getYMax() / pitch)
);
_circuit = netlist( instances, nets, pins );
_placementLB.positions_ = positions;
_placementLB.orientations_ = orientations;
_placementUB = _placementLB;
cerr << "Coloquinte cell height: " << _circuit.get_cell(0).size.y_ << endl;
for ( auto ipair : _cellsToIds ) { #endif // HAVE_COLOQUINTE
Coloquinte::circuit_coordinate position ( idsToTransf[ipair.second].getTx() / DbU::fromLambda(5.0) }
, idsToTransf[ipair.second].getTy() / DbU::fromLambda(5.0) );
// if (not _circuit->cells[ipair.second].movable) {
// cerr << _circuit->cells[ipair.second].name << endl;
// cerr << " " << idsToTransf[ipair.second] << endl;
// cerr << " Fixed cell BEFORE @" << position.x() << "x" << position.y() << endl;
// }
//position += _circuit->cells[ipair.second].get_sizes() / 2;
_circuit->position_overlays[0].x_pos[ipair.second] = position.x();
_circuit->position_overlays[0].y_pos[ipair.second] = position.y();
// if (not _circuit->cells[ipair.second].movable) { void EtesianEngine::place ( unsigned int flags )
// cerr << " Fixed cell @" << position.x() << "x" << position.y() << endl; {
// } #if HAVE_COLOQUINTE
} if (flags & SlowMotion) getConfiguration()-> setFlags( SlowMotion );
else getConfiguration()->unsetFlags( SlowMotion );
// Temporarily force the circuit size. toColoquinte();
// getCell()->setAbutmentBox( Box( DbU::fromLambda(0.0)
// , DbU::fromLambda(0.0)
// , DbU::fromLambda(5.0)*12000
// , DbU::fromLambda(5.0)*12000
// ) );
// _circuit->bounds = Coloquinte::circuit_box( Coloquinte::circuit_coordinate::Zero()
// , Coloquinte::circuit_coordinate({12000, 12000}) );
_circuit->bounds = Coloquinte::circuit_box
( Coloquinte::circuit_coordinate( { getCell()->getAbutmentBox().getXMin() / DbU::fromLambda(5.0)
, getCell()->getAbutmentBox().getYMin() / DbU::fromLambda(5.0) } )
, Coloquinte::circuit_coordinate( { getCell()->getAbutmentBox().getXMax() / DbU::fromLambda(5.0)
, getCell()->getAbutmentBox().getYMax() / DbU::fromLambda(5.0) } ));
_circuit->selfcheck();
cmess1 << " o Running Coloquinte." << endl; cmess1 << " o Running Coloquinte." << endl;
cmess1 << " - Computing initial placement..." << endl; cmess1 << " - Computing initial placement..." << endl;
cmess2 << setfill('0') << right; cmess2 << setfill('0') << right;
time_t startTime = time(NULL);
time_t timeDelta;
Coloquinte::circuit_scalar upperBound;
Coloquinte::circuit_scalar lowerBound;
for ( int j = 0; j < 3; j++ ) { double sliceHeight = getSliceHeight() / getPitch();
_circuit->position_overlays[0] time_t startTime = time(NULL);
= Coloquinte::solve_quadratic_model( *_circuit time_t timeDelta;
, _circuit->position_overlays[0] ostringstream label;
, _circuit->position_overlays[0]
);
timeDelta = time(NULL) - startTime; cmess2 << " o Initial wirelength " << get_HPWL_wirelength(_circuit, _placementLB) << "." << endl;
lowerBound = B2B_wirelength( *_circuit, _circuit->position_overlays[0] ); startMeasures();
cmess2 << " Iteration " << setw( 4) << (j+1)
<< " Elapsed time:" << setw( 5) << timeDelta << "s"
<< " Lower bound:" << setw(10)
<< lowerBound << endl;
_updatePlacement( 0 ); auto first_legalizer = get_rough_legalizer( _circuit, _placementLB, _surface);
} first_legalizer.selfcheck();
float strength = 0.000001;
float strength_incr = 0.000002;
cmess1 << " - Optimizing placement..." << endl; cmess1 << " o Simple legalization." << endl;
get_result( _circuit, _placementUB, first_legalizer);
_circuit->position_overlays.resize(2); timeDelta = time(NULL) - startTime;
for ( int j = 0; j < 200; j++, strength = strength * 1.02 + strength_incr) { cmess2 << " - Elapsed time:" << timeDelta
_circuit->position_overlays[1] << " HPWL:" << get_HPWL_wirelength( _circuit, _placementUB )
= Coloquinte::legalize( *_circuit << "\n "
, 1.0 << "- Linear Disrupt.:" << get_mean_linear_disruption ( _circuit, _placementLB, _placementLB )
, _circuit->position_overlays[0] << " Quad. Disrupt.:" << get_mean_quadratic_disruption( _circuit, _placementLB, _placementLB )
, 1 << endl;
, false _placementLB = _placementUB;
); _placementLB.selfcheck();
timeDelta = time(NULL) - startTime;
upperBound = B2B_wirelength( *_circuit, _circuit->position_overlays[1] );
cmess2 << " Iteration " << setw( 4) << (j+1)
<< " Elapsed time:" << setw( 5) << timeDelta << "s"
<< " UPPER bound:" << setw(10)
<< upperBound << endl;
_circuit->position_overlays[0] zero_orientations( _circuit, _placementLB );
= Coloquinte::solve_quadratic_model( *_circuit _updatePlacement( _placementUB );
, _circuit->position_overlays[0]
, _circuit->position_overlays[1]
, strength
);
timeDelta = time(NULL) - startTime;
lowerBound = B2B_wirelength( *_circuit, _circuit->position_overlays[0] );
cmess2 << " "
<< " Elapsed time:" << setw( 5) << timeDelta << "s"
<< " Lower bound:" << setw(10)
<< lowerBound << endl;
cmess2 << " Spreading ratio: "
<< ((((double)upperBound-(double)lowerBound)*100) / (double)lowerBound) << "%" << endl;
_updatePlacement( 0 ); // cerr << _idsToInsts[1266]
} // << " x:" << _placementLB.positions_[1095].x_
// << " y:" << _placementLB.positions_[1095].y_
// << endl;
// Breakpoint::get()->stop( 0, "After " );
// Early topology-independent solution
cmess1 << " o Star (*) Optimization." << endl;
auto solv = get_star_linear_system( _circuit, _placementLB, 1.0, 0, 10000);
get_result( _circuit, _placementLB, solv, 200 );
_progressReport2( startTime, " [--]" );
for ( int i=0; i<10; ++i ) {
auto solv = get_HPWLF_linear_system( _circuit, _placementLB, 1.0, 2, 100000 );
get_result( _circuit, _placementLB, solv, 300 ); // number of iterations
label.str("");
label << " [" << setw(2) << setfill('0') << i << "]";
_progressReport2( startTime, label.str() );
_updatePlacement( _placementLB );
}
float_t pulling_force = 0.03;
cmess2 << " o Simple legalization." << endl;
for ( int i=0; i<50; ++i, pulling_force += 0.03 ) {
// Create a legalizer and bipartition it until we have sufficient precision
// (~2 to 10 standard cell widths).
auto legalizer = get_rough_legalizer( _circuit, _placementLB, _surface );
for ( int quad_part=0 ; quad_part<8 ; quad_part++ ) {
legalizer.x_bipartition();
legalizer.y_bipartition();
legalizer.redo_line_partitions();
legalizer.redo_diagonal_bipartitions();
legalizer.redo_line_partitions();
legalizer.redo_diagonal_bipartitions();
legalizer.selfcheck();
}
if (i < 10) {
spread_orientations( _circuit, _placementLB );
}
// Keep the orientation between LB and UB
_placementUB = _placementLB;
get_result( _circuit, _placementUB, legalizer );
label.str("");
label << " [" << setw(2) << setfill('0') << i << "] Bipart.";
_progressReport1( startTime, label.str() );
_updatePlacement( _placementUB );
if (i >= 30) {
auto legalizer = legalize( _circuit, _placementUB, _surface, sliceHeight );
coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
_progressReport1( startTime, " Legal. " );
_updatePlacement( _placementUB );
}
// Get the system to optimize (tolerance, maximum and minimum pin counts)
// and the pulling forces (threshold distance)
auto solv = get_HPWLF_linear_system ( _circuit, _placementLB, 0.01, 2, 100000 )
+ get_linear_pulling_forces( _circuit, _placementUB, _placementLB, pulling_force, 40.0 );
get_result( _circuit, _placementLB, solv, 400 ); // number of iterations
_progressReport2( startTime, " Linear." );
_updatePlacement( _placementLB );
// Optimize orientation sometimes
// if (i>=10 and i%5 == 0) {
// optimize_exact_orientations( _circuit, _placementLB );
// std::cout << "Oriented" << std::endl;
// //output_progressReport(circuit, LB_pl);
// _updatePlacement( _placementLB );
// }
}
cmess1 << " o Detailed Placement." << endl;
index_t legalizeIterations = 10;
for ( index_t i=0; i<legalizeIterations; ++i ){
ostringstream label;
label.str("");
label << " [" << setw(2) << setfill('0') << i << "]";
optimize_exact_orientations( _circuit, _placementUB );
_progressReport1( startTime, label.str()+" Oriented ......." );
_updatePlacement( _placementUB );
auto legalizer = legalize( _circuit, _placementLB, _surface, sliceHeight );
coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
_progressReport1( startTime, " Legalized ......" );
_updatePlacement( _placementUB );
swaps_global( _circuit, legalizer, 3, 4 );
coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
_progressReport1( startTime, " Global Swaps ..." );
_updatePlacement( _placementUB );
OSRP_convex( _circuit, legalizer );
coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
_progressReport1( startTime, " Row Optimization" );
_updatePlacement( _placementUB );
swaps_row( _circuit, legalizer, 4 );
coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
_progressReport1( startTime, " Local Swaps ...." );
if (i == legalizeIterations-1) {
row_compatible_orientation( _circuit, legalizer, true );
coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
_progressReport1( startTime, " Final Legalize ." );
}
_updatePlacement( _placementUB, (i==legalizeIterations-1) ? ForceUpdate : 0 );
}
cmess1 << " o Adding feed cells." << endl;
addFeeds();
cmess1 << " o Placement finished." << endl;
stopMeasures();
printMeasures( "total" );
cmess1 << ::Dots::asString
(" - HPWL", DbU::getValueString(get_HPWL_wirelength(_circuit,_placementUB )*getPitch()) ) << endl;
cmess1 << ::Dots::asString
(" - RMST", DbU::getValueString(get_RSMT_wirelength(_circuit,_placementUB )*getPitch()) ) << endl;
_updatePlacement( 1 );
_flags &= ~NoPlacement; _flags &= ~NoPlacement;
#else #else
cerr << Warning("Coloquinte library wasn't found, Etesian is disabled.") << endl; cerr << Warning("Coloquinte library wasn't found, Etesian is disabled.") << endl;
@ -513,9 +710,56 @@ namespace Etesian {
} }
void EtesianEngine::_updatePlacement ( unsigned int placementId ) void EtesianEngine::_progressReport1 ( time_t startTime, string label ) const
{ {
#if HAVE_COLOQUINTE #if HAVE_COLOQUINTE
size_t w = label.size();
string indent ( w, ' ' );
if (not w) {
label = string( 5, ' ' );
indent = label;
}
ostringstream elapsed;
elapsed << " dTime:" << setw(5) << (time(NULL) - startTime) << "s ";
cmess2 << label << elapsed.str()
<< " HPWL:" << get_HPWL_wirelength ( _circuit, _placementUB )
<< " RMST:" << get_RSMT_wirelength ( _circuit, _placementUB )
<< "\n" << indent
<< " Linear Disrupt.:" << get_mean_linear_disruption ( _circuit, _placementLB, _placementUB )
<< " Quad Disrupt.:" << get_mean_quadratic_disruption( _circuit, _placementLB, _placementUB )
<< endl;
#endif
}
void EtesianEngine::_progressReport2 ( time_t startTime, string label ) const
{
#if HAVE_COLOQUINTE
size_t w = label.size();
string indent ( w, ' ' );
if (not w) {
label = string( 5, ' ' );
indent = label;
}
ostringstream elapsed;
elapsed << " dTime:" << setw(5) << (time(NULL) - startTime) << "s ";
cmess2 << label << elapsed.str()
<< " HPWL:" << get_HPWL_wirelength( _circuit, _placementLB )
<< " RMST:" << get_RSMT_wirelength( _circuit, _placementLB )
<< endl;
#endif
}
void EtesianEngine::_updatePlacement ( const coloquinte::gp::placement_t& placement, unsigned int flags )
{
#if HAVE_COLOQUINTE
if ((not isSlowMotion()) and not (flags & ForceUpdate)) return;
UpdateSession::open(); UpdateSession::open();
forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() ) forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() )
@ -532,14 +776,26 @@ namespace Etesian {
if (iid == _cellsToIds.end() ) { if (iid == _cellsToIds.end() ) {
cerr << Error( "Unable to lookup instance <%s>.", instanceName.c_str() ) << endl; cerr << Error( "Unable to lookup instance <%s>.", instanceName.c_str() ) << endl;
} else { } else {
instancePosition.setX( _circuit->position_overlays[placementId].x_pos[(*iid).second] * DbU::fromLambda(5.0) ); point<float_t> position = placement.positions_[(*iid).second];
instancePosition.setY( _circuit->position_overlays[placementId].y_pos[(*iid).second] * DbU::fromLambda(5.0) );
if ( isNan(position.x_) or isNan(position.y_) ) {
cerr << Error( "Instance <%s> is not placed yet (position == NaN)."
, instanceName.c_str() ) << endl;
instance->setPlacementStatus( Instance::PlacementStatus::UNPLACED );
continue;
}
Transformation trans = toTransformation( position
, placement.orientations_[(*iid).second]
, instance->getMasterCell()
, getPitch()
);
//cerr << "Setting <" << instanceName << " @" << instancePosition << endl; //cerr << "Setting <" << instanceName << " @" << instancePosition << endl;
// This is temporary as it's not trans-hierarchic: we ignore the posutions // This is temporary as it's not trans-hierarchic: we ignore the posutions
// of all the intermediary instances. // of all the intermediary instances.
instance->setTransformation( instancePosition ); instance->setTransformation( trans );
instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); instance->setPlacementStatus( Instance::PlacementStatus::PLACED );
} }
} }
@ -568,7 +824,6 @@ namespace Etesian {
Record* record = ToolEngine::_getRecord (); Record* record = ToolEngine::_getRecord ();
if (record) { if (record) {
//record->add( getSlot( "_routingPlanes", &_routingPlanes ) );
record->add( getSlot( "_configuration", _configuration ) ); record->add( getSlot( "_configuration", _configuration ) );
} }
return record; return record;

94
etesian/src/FeedCells.cpp Normal file
View File

@ -0,0 +1,94 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | E t e s i a n - A n a l y t i c P l a c e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./FeedCells.cpp" |
// +-----------------------------------------------------------------+
#include <sstream>
#include "hurricane/Warning.h"
#include "etesian/FeedCells.h"
#include "etesian/EtesianEngine.h"
namespace Etesian {
using std::cerr;
using std::endl;
using std::map;
using std::string;
using std::ostringstream;
using std::make_pair;
using Hurricane::Warning;
using Hurricane::DbU;
void FeedCells::useFeed ( Cell* cell )
{
if ( cell == NULL ) return;
DbU::Unit pitch = _etesian->getPitch();
if (cell->getAbutmentBox().getWidth() % pitch != 0)
cerr << Warning( "FeedCells::addFeed(): &lt;%s&gt; has not a width (%s) multiple of pitch (%s)."
, getString(cell->getName()).c_str()
, DbU::getValueString(cell->getAbutmentBox().getWidth()).c_str()
, DbU::getValueString(pitch).c_str()
) << endl;
int pitchNb = (int)( cell->getAbutmentBox().getWidth() / pitch );
if (getFeed(pitchNb) != NULL) {
cerr << Warning( "FeedCells::addFeed(): &lt;%s&gt; duplicate feed for width %d."
, getString(cell->getName()).c_str()
, pitchNb
) << endl;
return;
}
_feedCells.insert( make_pair(pitchNb,cell) );
}
Cell* FeedCells::getBiggestFeed () const
{
if (_feedCells.empty()) return NULL;
return (*(--_feedCells.end())).second;
}
Cell* FeedCells::getSmallestFeed () const
{
if (_feedCells.empty()) return NULL;
return (*(_feedCells.begin())).second;
}
Cell* FeedCells::getFeed ( int pitches ) const
{
map<int,Cell*>::const_iterator ifeed = _feedCells.find( pitches );
if (ifeed == _feedCells.end()) return NULL;
return (*ifeed).second;
}
string FeedCells::getUniqueInstanceName () const
{
ostringstream name;
name << "feed_" << _feedCount++;
return name.str();
}
} // Etesian namespace.

View File

@ -99,6 +99,7 @@ namespace Etesian {
_viewer->clearToolInterrupt(); _viewer->clearToolInterrupt();
EtesianEngine* etesian = getForFramework( CreateEngine ); EtesianEngine* etesian = getForFramework( CreateEngine );
etesian->getConfiguration()->setFlags( EtesianEngine::SlowMotion );
etesian->resetPlacement(); etesian->resetPlacement();
etesian->place(); etesian->place();
} }

View File

@ -87,11 +87,7 @@ extern "C" {
Py_INCREF( &PyTypeGraphicEtesianEngine ); Py_INCREF( &PyTypeGraphicEtesianEngine );
PyModule_AddObject( module, "GraphicEtesianEngine", (PyObject*)&PyTypeGraphicEtesianEngine ); PyModule_AddObject( module, "GraphicEtesianEngine", (PyObject*)&PyTypeGraphicEtesianEngine );
//PyObject* dictionnary = PyModule_GetDict( module ); PyEtesianEngine_postModuleInit();
//PyObject* constant;
//LoadObjectConstant( dictionnary, KtBuildGlobalRouting, "KtBuildGlobalRouting" );
//LoadObjectConstant( dictionnary, KtLoadGlobalRouting , "KtLoadGlobalRouting" );
} }

View File

@ -109,7 +109,7 @@ extern "C" {
METHOD_HEAD("EtesianEngine.place()") METHOD_HEAD("EtesianEngine.place()")
unsigned int flags = 0; unsigned int flags = 0;
if (PyArg_ParseTuple(args,"I:EtesianEngine.place", &flags)) { if (PyArg_ParseTuple(args,"I:EtesianEngine.place", &flags)) {
etesian->place(/*flags*/); etesian->place( flags );
} else { } else {
PyErr_SetString(ConstructorError, "EtesianEngine.place(): Invalid number/bad type of parameter."); PyErr_SetString(ConstructorError, "EtesianEngine.place(): Invalid number/bad type of parameter.");
return NULL; return NULL;
@ -137,24 +137,8 @@ extern "C" {
, "Returns the Etesian engine attached to the Cell, None if there isnt't." } , "Returns the Etesian engine attached to the Cell, None if there isnt't." }
, { "create" , (PyCFunction)PyEtesianEngine_create , METH_VARARGS|METH_STATIC , { "create" , (PyCFunction)PyEtesianEngine_create , METH_VARARGS|METH_STATIC
, "Create a Etesian engine on this cell." } , "Create a Etesian engine on this cell." }
// , { "printConfiguration", (PyCFunction)PyEtesianEngine_printConfiguration, METH_NOARGS
// , "Display on the console the configuration of Etesian." }
// , { "saveGlobalSolution", (PyCFunction)PyEtesianEngine_saveGlobalSolution, METH_NOARGS
// , "Save the global routing solution on disk." }
// , { "getToolSuccess" , (PyCFunction)PyEtesianEngine_getToolSuccess , METH_NOARGS
// , "Returns True if the detailed routing has been successful." }
// , { "loadGlobalRouting" , (PyCFunction)PyEtesianEngine_loadGlobalRouting , METH_VARARGS
// , "Read/load the global routing and build topologies for Etesian." }
, { "place" , (PyCFunction)PyEtesianEngine_place , METH_VARARGS , { "place" , (PyCFunction)PyEtesianEngine_place , METH_VARARGS
, "Run the global router (Knik)." } , "Run the global router (Knik)." }
// , { "layerAssign" , (PyCFunction)PyEtesianEngine_layerAssign , METH_VARARGS
// , "Run the layer assigment stage." }
// , { "runNegociate" , (PyCFunction)PyEtesianEngine_runNegociate , METH_NOARGS
// , "Run the negociation stage of the detailed router." }
// , { "finalizeLayout" , (PyCFunction)PyEtesianEngine_finalizeLayout , METH_NOARGS
// , "Revert to a pure Hurricane database, remove router's additionnal data structures." }
// , { "dumpMeasures" , (PyCFunction)PyEtesianEngine_dumpMeasures , METH_NOARGS
// , "Dump to disk lots of statistical informations about the routing." }
, { "destroy" , (PyCFunction)PyEtesianEngine_destroy , METH_NOARGS , { "destroy" , (PyCFunction)PyEtesianEngine_destroy , METH_NOARGS
, "Destroy the associated hurricane object. The python object remains." } , "Destroy the associated hurricane object. The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */ , {NULL, NULL, 0, NULL} /* sentinel */
@ -178,6 +162,14 @@ extern "C" {
DBoLinkCreateMethod(EtesianEngine) DBoLinkCreateMethod(EtesianEngine)
extern void PyEtesianEngine_postModuleInit ()
{
PyObject* constant;
LoadObjectConstant(PyTypeEtesianEngine.tp_dict,EtesianEngine::SlowMotion,"SlowMotion");
}
#endif // Shared Library Code Part. #endif // Shared Library Code Part.
} // extern "C". } // extern "C".

View File

@ -25,10 +25,7 @@ namespace Hurricane {
class Cell; class Cell;
} }
#include "crlcore/RoutingGauge.h" #include "crlcore/CellGauge.h"
namespace CRL {
class RoutingLayerGauge;
}
namespace Etesian { namespace Etesian {
@ -39,8 +36,7 @@ namespace Etesian {
using Hurricane::Layer; using Hurricane::Layer;
using Hurricane::DbU; using Hurricane::DbU;
using Hurricane::Cell; using Hurricane::Cell;
using CRL::RoutingGauge; using CRL::CellGauge;
using CRL::RoutingLayerGauge;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -53,7 +49,10 @@ namespace Etesian {
virtual ~Configuration (); virtual ~Configuration ();
virtual Configuration* clone () const = 0; virtual Configuration* clone () const = 0;
// Methods. // Methods.
virtual RoutingGauge* getRoutingGauge () const = 0; virtual CellGauge* getCellGauge () const = 0;
virtual bool isSlowMotion () const = 0;
virtual void setFlags ( unsigned int ) = 0;
virtual void unsetFlags ( unsigned int ) = 0;
virtual void print ( Cell* ) const = 0; virtual void print ( Cell* ) const = 0;
virtual Record* _getRecord () const = 0; virtual Record* _getRecord () const = 0;
virtual string _getString () const = 0; virtual string _getString () const = 0;
@ -76,18 +75,22 @@ namespace Etesian {
friend class Configuration; friend class Configuration;
public: public:
// Constructor & Destructor. // Constructor & Destructor.
ConfigurationConcrete ( const RoutingGauge* rg=NULL ); ConfigurationConcrete ( const CellGauge* cg=NULL );
virtual ~ConfigurationConcrete (); virtual ~ConfigurationConcrete ();
virtual ConfigurationConcrete* clone () const; virtual ConfigurationConcrete* clone () const;
// Methods. // Methods.
virtual RoutingGauge* getRoutingGauge () const; virtual CellGauge* getCellGauge () const;
virtual bool isSlowMotion () const;
virtual void setFlags ( unsigned int );
virtual void unsetFlags ( unsigned int );
virtual void print ( Cell* ) const; virtual void print ( Cell* ) const;
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
virtual string _getString () const; virtual string _getString () const;
virtual string _getTypeName () const; virtual string _getTypeName () const;
protected: protected:
// Attributes. // Attributes.
RoutingGauge* _rg; CellGauge* _cg;
unsigned int _flags;
private: private:
ConfigurationConcrete ( const ConfigurationConcrete& ); ConfigurationConcrete ( const ConfigurationConcrete& );
ConfigurationConcrete& operator= ( const ConfigurationConcrete& ); ConfigurationConcrete& operator= ( const ConfigurationConcrete& );

View File

@ -19,31 +19,32 @@
#include <iostream> #include <iostream>
#include <unordered_map> #include <unordered_map>
#include "Coloquinte/circuit.hxx"
//#include "coloquinte/circuit_graph.hxx" #include "hurricane/Timer.h"
namespace Coloquinte {
struct circuit;
}
#include "hurricane/Name.h" #include "hurricane/Name.h"
namespace Hurricane { namespace Hurricane {
class Layer; class Layer;
class Net; class Net;
class Cell; class Cell;
class CellWidget; class CellWidget;
class Instance;
} }
#include "crlcore/ToolEngine.h" #include "crlcore/ToolEngine.h"
#include "etesian/Configuration.h" #include "etesian/Configuration.h"
#include "etesian/FeedCells.h"
namespace Etesian { namespace Etesian {
using Hurricane::Timer;
using Hurricane::Name; using Hurricane::Name;
using Hurricane::Layer; using Hurricane::Layer;
using Hurricane::Net; using Hurricane::Net;
using Hurricane::Cell; using Hurricane::Cell;
using Hurricane::Record; using Hurricane::Record;
using Hurricane::Instance;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -51,21 +52,36 @@ namespace Etesian {
class EtesianEngine : public CRL::ToolEngine { class EtesianEngine : public CRL::ToolEngine {
public: public:
enum Flag { NoPlacement=0x0001, FlatDesign=0x0002 }; enum Flag { NoPlacement=0x0001
, FlatDesign =0x0002
, ForceUpdate=0x0004
, SlowMotion =0x0008
};
public: public:
static const Name& staticGetName (); static const Name& staticGetName ();
static EtesianEngine* create ( Cell* ); static EtesianEngine* create ( Cell* );
static EtesianEngine* get ( const Cell* ); static EtesianEngine* get ( const Cell* );
public: public:
virtual Configuration* getConfiguration (); inline bool isSlowMotion () const;
virtual const Name& getName () const; virtual Configuration* getConfiguration ();
inline void setCellWidget ( Hurricane::CellWidget* ); virtual const Configuration* getConfiguration () const;
void resetPlacement (); virtual const Name& getName () const;
void place ( unsigned int slowMotion=0 ); inline CellGauge* getCellGauge () const;
void _updatePlacement ( unsigned int placementId ); inline DbU::Unit getPitch () const;
virtual Record* _getRecord () const; inline DbU::Unit getSliceHeight () const;
virtual std::string _getString () const; inline const FeedCells& getFeedCells () const;
virtual std::string _getTypeName () const; inline void setCellWidget ( Hurricane::CellWidget* );
void startMeasures ();
void stopMeasures ();
void printMeasures ( std::string ) const;
void resetPlacement ();
void toColoquinte ();
void place ( unsigned int flags=SlowMotion );
inline void useFeed ( Cell* );
void addFeeds ();
virtual Record* _getRecord () const;
virtual std::string _getString () const;
virtual std::string _getTypeName () const;
private: private:
// Attributes. // Attributes.
@ -73,24 +89,40 @@ namespace Etesian {
protected: protected:
Configuration* _configuration; Configuration* _configuration;
unsigned int _flags; unsigned int _flags;
Coloquinte::circuit* _circuit; Timer _timer;
coloquinte::box<coloquinte::int_t> _surface;
coloquinte::netlist _circuit;
coloquinte::gp::placement_t _placementLB;
coloquinte::gp::placement_t _placementUB;
std::unordered_map<string,unsigned int> _cellsToIds; std::unordered_map<string,unsigned int> _cellsToIds;
std::vector<Instance*> _idsToInsts;
Hurricane::CellWidget* _cellWidget; Hurricane::CellWidget* _cellWidget;
FeedCells _feedCells;
protected: protected:
// Constructors & Destructors. // Constructors & Destructors.
EtesianEngine ( Cell* ); EtesianEngine ( Cell* );
virtual ~EtesianEngine (); virtual ~EtesianEngine ();
virtual void _postCreate (); virtual void _postCreate ();
virtual void _preDestroy (); virtual void _preDestroy ();
private:
EtesianEngine ( const EtesianEngine& );
EtesianEngine& operator= ( const EtesianEngine& );
private: private:
EtesianEngine ( const EtesianEngine& ); void _updatePlacement ( const coloquinte::gp::placement_t&, unsigned int flags=0 );
EtesianEngine& operator= ( const EtesianEngine& ); void _progressReport1 ( time_t startTime, string label ) const;
void _progressReport2 ( time_t startTime, string label ) const;
}; };
// Inline Functions. // Inline Functions.
inline void EtesianEngine::setCellWidget ( Hurricane::CellWidget* cw ) { _cellWidget = cw; } inline bool EtesianEngine::isSlowMotion () const { return getConfiguration()->isSlowMotion(); }
inline void EtesianEngine::setCellWidget ( Hurricane::CellWidget* cw ) { _cellWidget = cw; }
inline CellGauge* EtesianEngine::getCellGauge () const { return getConfiguration()->getCellGauge(); }
inline DbU::Unit EtesianEngine::getPitch () const { return getCellGauge()->getPitch(); }
inline DbU::Unit EtesianEngine::getSliceHeight () const { return getCellGauge()->getSliceHeight(); }
inline void EtesianEngine::useFeed ( Cell* cell ) { _feedCells.useFeed(cell); }
inline const FeedCells& EtesianEngine::getFeedCells () const { return _feedCells; }
// Variables. // Variables.

View File

@ -0,0 +1,55 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | E t e s i a n - A n a l y t i c P l a c e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./FeedCells.h" |
// +-----------------------------------------------------------------+
#ifndef ETESIAN_FEEDCELLS_H
#define ETESIAN_FEEDCELLS_H
#include <map>
#include "hurricane/Cell.h"
namespace Etesian {
using Hurricane::Cell;
class EtesianEngine;
class FeedCells {
public:
inline FeedCells ( EtesianEngine* );
void useFeed ( Cell* );
Cell* getBiggestFeed () const;
Cell* getSmallestFeed () const;
Cell* getFeed ( int pitches ) const;
std::string getUniqueInstanceName () const;
private:
EtesianEngine* _etesian;
std::map<int,Cell*> _feedCells;
mutable unsigned int _feedCount;
};
// Inline Methods.
inline FeedCells::FeedCells ( EtesianEngine* etesian )
: _etesian (etesian)
, _feedCells()
, _feedCount(0)
{ }
} // Etesian namespace.
#endif // ETESIAN_FEEDCELLS_H

View File

@ -42,8 +42,9 @@ extern "C" {
extern PyTypeObject PyTypeEtesianEngine; extern PyTypeObject PyTypeEtesianEngine;
extern PyMethodDef PyEtesianEngine_Methods[]; extern PyMethodDef PyEtesianEngine_Methods[];
extern PyObject* PyEtesianEngine_Link ( Etesian::EtesianEngine* ); extern PyObject* PyEtesianEngine_Link ( Etesian::EtesianEngine* );
extern void PyEtesianEngine_LinkPyType (); extern void PyEtesianEngine_LinkPyType ();
extern void PyEtesianEngine_postModuleInit ();
#define IsPyEtesianEngine(v) ( (v)->ob_type == &PyTypeEtesianEngine ) #define IsPyEtesianEngine(v) ( (v)->ob_type == &PyTypeEtesianEngine )

View File

@ -104,7 +104,8 @@ Cell::Cell(Library* library, const Name& name)
_nextOfLibraryCellMap(NULL), _nextOfLibraryCellMap(NULL),
_nextOfSymbolCellSet(NULL), _nextOfSymbolCellSet(NULL),
_slaveEntityMap(), _slaveEntityMap(),
_observers() _observers(),
_flags(0)
{ {
if (!_library) if (!_library)
throw Error("Can't create " + _TName("Cell") + " : null library"); throw Error("Can't create " + _TName("Cell") + " : null library");
@ -193,6 +194,8 @@ void Cell::flattenNets(unsigned int flags)
{ {
UpdateSession::open(); UpdateSession::open();
_flags |= FlattenedNets;
forEach ( Occurrence, ioccurrence, getHyperNetRootNetOccurrences() ) { forEach ( Occurrence, ioccurrence, getHyperNetRootNetOccurrences() ) {
Net* net = static_cast<Net*>((*ioccurrence).getEntity()); Net* net = static_cast<Net*>((*ioccurrence).getEntity());

View File

@ -72,6 +72,8 @@ class Cell : public Entity {
// Flags set for Observers. // Flags set for Observers.
, CellAboutToChange = 0x0001 , CellAboutToChange = 0x0001
, CellChanged = 0x0002 , CellChanged = 0x0002
// Cell states
, FlattenedNets = 0x0001
}; };
public: typedef Entity Inherit; public: typedef Entity Inherit;
public: typedef map<Name,ExtensionSlice*> ExtensionSliceMap; public: typedef map<Name,ExtensionSlice*> ExtensionSliceMap;
@ -180,6 +182,7 @@ class Cell : public Entity {
private: Cell* _nextOfSymbolCellSet; private: Cell* _nextOfSymbolCellSet;
private: SlaveEntityMap _slaveEntityMap; private: SlaveEntityMap _slaveEntityMap;
private: Observable _observers; private: Observable _observers;
private: unsigned int _flags;
// Constructors // Constructors
// ************ // ************
@ -303,6 +306,7 @@ class Cell : public Entity {
public: bool isFlattenLeaf() const {return _isFlattenLeaf;}; public: bool isFlattenLeaf() const {return _isFlattenLeaf;};
public: bool isLeaf() const; public: bool isLeaf() const;
public: bool isPad() const {return _isPad;}; public: bool isPad() const {return _isPad;};
public: bool isFlattenedNets() const {return _flags & FlattenedNets;};
// Updators // Updators
// ******** // ********

View File

@ -40,11 +40,13 @@ namespace Hurricane {
public: public:
enum State { Excluded = 0x0001 enum State { Excluded = 0x0001
, Fixed = 0x0002 , Fixed = 0x0002
, ManualGlobalRoute = 0x0004 , Unconnected = 0x0004
, AutomaticGlobalRoute = 0x0008 , ManualGlobalRoute = 0x0008
, AutomaticGlobalRoute = 0x0010
, MixedPreRoute = Fixed|ManualGlobalRoute , MixedPreRoute = Fixed|ManualGlobalRoute
}; };
public: public:
inline bool isUnconnected () const;
inline bool isFixed () const; inline bool isFixed () const;
inline bool isManualGlobalRoute () const; inline bool isManualGlobalRoute () const;
inline bool isAutomaticGlobalRoute () const; inline bool isAutomaticGlobalRoute () const;
@ -67,6 +69,7 @@ namespace Hurricane {
inline NetRoutingState::NetRoutingState ( Net* net, unsigned int flags ) : _net(net), _flags(flags) { } inline NetRoutingState::NetRoutingState ( Net* net, unsigned int flags ) : _net(net), _flags(flags) { }
inline bool NetRoutingState::isUnconnected () const { return _flags & Unconnected; };
inline bool NetRoutingState::isFixed () const { return _flags & Fixed; }; inline bool NetRoutingState::isFixed () const { return _flags & Fixed; };
inline bool NetRoutingState::isManualGlobalRoute () const { return _flags & ManualGlobalRoute; }; inline bool NetRoutingState::isManualGlobalRoute () const { return _flags & ManualGlobalRoute; };
inline bool NetRoutingState::isAutomaticGlobalRoute () const { return _flags & AutomaticGlobalRoute; }; inline bool NetRoutingState::isAutomaticGlobalRoute () const { return _flags & AutomaticGlobalRoute; };
@ -113,6 +116,7 @@ namespace Hurricane {
class NetRoutingExtension { class NetRoutingExtension {
public: public:
static inline bool isUnconnected ( const Net* );
static inline bool isFixed ( const Net* ); static inline bool isFixed ( const Net* );
static inline bool isManualGlobalRoute ( const Net* ); static inline bool isManualGlobalRoute ( const Net* );
static inline bool isAutomaticGlobalRoute ( const Net* ); static inline bool isAutomaticGlobalRoute ( const Net* );
@ -128,6 +132,13 @@ namespace Hurricane {
}; };
inline bool NetRoutingExtension::isUnconnected ( const Net* net )
{
NetRoutingState* state = get( net );
return (state == NULL) ? false : state->isUnconnected();
}
inline bool NetRoutingExtension::isFixed ( const Net* net ) inline bool NetRoutingExtension::isFixed ( const Net* net )
{ {
NetRoutingState* state = get( net ); NetRoutingState* state = get( net );

View File

@ -502,6 +502,14 @@ namespace Hurricane {
, QIcon(":/images/python-logo-v3.png") , QIcon(":/images/python-logo-v3.png")
); );
connect( action, SIGNAL(triggered()), this, SLOT(runScriptWidget()) ); connect( action, SIGNAL(triggered()), this, SLOT(runScriptWidget()) );
action = addToMenu( "tools.stressScript"
, tr("Python Stress Script")
, tr("Run Python Stress Script (50 times...).")
, QKeySequence()
, QIcon(":/images/python-logo-v3.png")
);
connect( action, SIGNAL(triggered()), this, SLOT(runStressScript()) );
} }
@ -783,6 +791,15 @@ namespace Hurricane {
{ ExceptionWidget::catchAllWrapper( std::bind( &CellViewer::_runScript, this, scriptPath ) ); } { ExceptionWidget::catchAllWrapper( std::bind( &CellViewer::_runScript, this, scriptPath ) ); }
void CellViewer::runStressScript ()
{
for ( size_t i=0 ; i<1000 ; ++i ) {
cerr << "Calling ./stressScript [" << setw(3) << right << setfill('0') << i << "]" << endl;
ExceptionWidget::catchAllWrapper( std::bind( &CellViewer::_runScript, this, "stressScript.py" ) );
}
}
void CellViewer::runScriptWidget () void CellViewer::runScriptWidget ()
{ ScriptWidget::runScript( this, getCell() ); } { ScriptWidget::runScript( this, getCell() ); }

View File

@ -141,6 +141,7 @@ namespace Hurricane {
void raiseToolInterrupt (); void raiseToolInterrupt ();
void clearToolInterrupt (); void clearToolInterrupt ();
void runScriptWidget (); void runScriptWidget ();
void runStressScript ();
inline void emitCellAboutToChange (); inline void emitCellAboutToChange ();
inline void emitCellChanged (); inline void emitCellChanged ();
signals: signals:

View File

@ -381,12 +381,14 @@ namespace {
} }
} }
ltrace(300) << " Check againts top clocks ck:" << _ck->getName() ltrace(300) << " Check againts top clocks ck:" << ((_ck) ? _ck->getName() : "NULL")
<< " cki:" << _cki->getName() << " cko:" << _cko->getName() << endl; << " cki:" << ((_cki) ? _cki->getName() : "NULL")
<< " cko:" << ((_cko) ? _cko->getName() : "NULL")
<< endl;
if (upNet->getName() == _ck->getName() ) return _ck; if ( _ck and (upNet->getName() == _ck->getName() ) ) return _ck;
if (upNet->getName() == _cki->getName()) return _cki; if ( _cki and (upNet->getName() == _cki->getName()) ) return _cki;
if (upNet->getName() == _cko->getName()) return _cko; if ( _cko and (upNet->getName() == _cko->getName()) ) return _cko;
return NULL; return NULL;
} }

View File

@ -164,9 +164,12 @@ namespace Kite {
} }
if (isFixed or isPreRouted or (rpCount < 2)) { if (isFixed or isPreRouted or (rpCount < 2)) {
NetRoutingState* state = getRoutingState( *inet, Katabatic::KbCreate ); NetRoutingState* state = getRoutingState( *inet, Katabatic::KbCreate );
state->unsetFlags( NetRoutingState::AutomaticGlobalRoute ); state->unsetFlags( NetRoutingState::AutomaticGlobalRoute );
state->setFlags ( NetRoutingState::ManualGlobalRoute ); state->setFlags ( NetRoutingState::ManualGlobalRoute );
if (rpCount < 2)
state->setFlags ( NetRoutingState::Unconnected );
if (isFixed) { if (isFixed) {
cmess2 << " - <" << (*inet)->getName() << "> is fixed." << endl; cmess2 << " - <" << (*inet)->getName() << "> is fixed." << endl;

View File

@ -278,7 +278,7 @@ namespace Kite {
if (not _knik) { if (not _knik) {
unsigned int flags = Cell::WarnOnUnplacedInstances; unsigned int flags = Cell::WarnOnUnplacedInstances;
flags |= (mode & KtBuildGlobalRouting) ? Cell::BuildRings : 0; flags |= (mode & KtBuildGlobalRouting) ? Cell::BuildRings : 0;
cell->flattenNets( flags ); if (not cell->isFlattenedNets()) cell->flattenNets( flags );
// Test signals from <snx2013>. // Test signals from <snx2013>.
//DebugSession::addToTrace( getCell(), "core.snx_inst.a2_x2_8_sig" ); //DebugSession::addToTrace( getCell(), "core.snx_inst.a2_x2_8_sig" );

View File

@ -228,7 +228,10 @@ void KnikEngine::initGlobalRouting( const map<Name,Net*>& excludedNets )
forEach ( Net*, inet, getCell()->getNets() ) { forEach ( Net*, inet, getCell()->getNets() ) {
if (excludedNets.find(inet->getName()) != excludedNets.end()) { if (excludedNets.find(inet->getName()) != excludedNets.end()) {
cparanoid << " - <" << inet->getName() << "> not routed (pre-routing found)." << endl; if (NetRoutingExtension::isUnconnected(*inet))
cparanoid << " - <" << inet->getName() << "> not routed (unconnected)." << endl;
else
cparanoid << " - <" << inet->getName() << "> not routed (pre-routing found)." << endl;
continue; continue;
} }