From b18219d807e71341d678a7ad50c537581f73719b Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sun, 1 Feb 2015 23:24:13 +0100 Subject: [PATCH] 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). --- bootstrap/build.conf | 4 +- bootstrap/builder/Configuration.py | 2 +- bootstrap/cmake_modules/FindBootstrap.cmake | 24 +- bootstrap/cmake_modules/FindQwt.cmake | 1 + bootstrap/coriolisEnv.py | 1 + crlcore/etc/CMakeLists.txt | 1 + crlcore/etc/cmos/display.conf | 1 + crlcore/etc/cmos/plugins.conf | 1 + crlcore/etc/common/display.conf | 286 ++++----- crlcore/etc/ispd05/alliance.conf | 68 +++ crlcore/etc/ispd05/display.conf | 10 + crlcore/etc/ispd05/hMetis.conf | 5 + crlcore/etc/ispd05/kite.conf | 23 + crlcore/etc/ispd05/mauka.conf | 5 + crlcore/etc/ispd05/misc.conf | 9 + crlcore/etc/ispd05/nimbus.conf | 5 + crlcore/etc/ispd05/patterns.conf | 5 + crlcore/etc/ispd05/plugins.conf | 23 + crlcore/etc/ispd05/stratus1.conf | 15 + crlcore/etc/ispd05/technology.conf | 162 ++++++ crlcore/etc/scmos_deep_018/display.conf | 2 + crlcore/etc/scmos_deep_018/plugins.conf | 3 +- crlcore/etc/vsc200/display.conf | 2 + crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp | 2 + cumulus/src/plugins/ClockTreePlugin.py | 14 +- etesian/CMakeLists.txt | 4 +- etesian/src/AddFeeds.cpp | 371 ++++++++++++ etesian/src/CMakeLists.txt | 52 +- etesian/src/Configuration.cpp | 41 +- etesian/src/EtesianEngine.cpp | 547 +++++++++++++----- etesian/src/FeedCells.cpp | 94 +++ etesian/src/GraphicEtesianEngine.cpp | 1 + etesian/src/PyEtesian.cpp | 6 +- etesian/src/PyEtesianEngine.cpp | 26 +- etesian/src/etesian/Configuration.h | 23 +- etesian/src/etesian/EtesianEngine.h | 86 ++- etesian/src/etesian/FeedCells.h | 55 ++ etesian/src/etesian/PyEtesianEngine.h | 5 +- hurricane/src/hurricane/Cell.cpp | 5 +- hurricane/src/hurricane/hurricane/Cell.h | 4 + .../hurricane/hurricane/NetRoutingProperty.h | 15 +- hurricane/src/viewer/CellViewer.cpp | 17 + .../src/viewer/hurricane/viewer/CellViewer.h | 1 + kite/src/BuildPowerRails.cpp | 12 +- kite/src/BuildPreRouteds.cpp | 3 + kite/src/KiteEngine.cpp | 2 +- knik/src/KnikEngine.cpp | 5 +- 47 files changed, 1605 insertions(+), 444 deletions(-) create mode 100644 crlcore/etc/ispd05/alliance.conf create mode 100644 crlcore/etc/ispd05/display.conf create mode 100644 crlcore/etc/ispd05/hMetis.conf create mode 100644 crlcore/etc/ispd05/kite.conf create mode 100644 crlcore/etc/ispd05/mauka.conf create mode 100644 crlcore/etc/ispd05/misc.conf create mode 100644 crlcore/etc/ispd05/nimbus.conf create mode 100644 crlcore/etc/ispd05/patterns.conf create mode 100644 crlcore/etc/ispd05/plugins.conf create mode 100644 crlcore/etc/ispd05/stratus1.conf create mode 100644 crlcore/etc/ispd05/technology.conf create mode 100644 etesian/src/AddFeeds.cpp create mode 100644 etesian/src/FeedCells.cpp create mode 100644 etesian/src/etesian/FeedCells.h diff --git a/bootstrap/build.conf b/bootstrap/build.conf index b7167d1e..1641c3a4 100644 --- a/bootstrap/build.conf +++ b/bootstrap/build.conf @@ -36,11 +36,11 @@ projects = [ { 'name' : "coloquinte" , 'tools' : [ "hurricaneAMS" , "amsCore" , "opSim" - , "scribe" + #, "scribe" , "graph" , "pharos" , "isis" - , "schematic" + #, "schematic" , "solver" , "autoDTR" ] diff --git a/bootstrap/builder/Configuration.py b/bootstrap/builder/Configuration.py index 3dac25df..a3d251d8 100644 --- a/bootstrap/builder/Configuration.py +++ b/bootstrap/builder/Configuration.py @@ -141,7 +141,7 @@ class Configuration ( object ): lines = uname.stdout.readlines() if self._osSlsoc7x_64.match(lines[0]): - self._osType = "Linux.el7" + self._osType = "Linux.el7_64" self._libSuffix = "64" elif self._osSlsoc6x_64.match(lines[0]): self._osType = "Linux.slsoc6x_64" diff --git a/bootstrap/cmake_modules/FindBootstrap.cmake b/bootstrap/cmake_modules/FindBootstrap.cmake index 9d8b7b7d..37a98847 100644 --- a/bootstrap/cmake_modules/FindBootstrap.cmake +++ b/bootstrap/cmake_modules/FindBootstrap.cmake @@ -212,25 +212,33 @@ # macro(setup_qt) if(WITH_QT5) + message(STATUS "Attempt to find Qt 5...") # For Qt5 - find_package(Qt5Core REQUIRED) - find_package(Qt5Gui REQUIRED) - find_package(Qt5Widgets REQUIRED) - find_package(Qt5PrintSupport REQUIRED) + find_package(Qt5Core REQUIRED) + find_package(Qt5Gui REQUIRED) + find_package(Qt5Widgets REQUIRED) + find_package(Qt5Svg REQUIRED) + find_package(Qt5PrintSupport REQUIRED) set(CMAKE_AUTOMOC ON) - set(QtX_INCLUDE_DIR ${Qt5PrintSupport_INCLUDE_DIR} - ${Qt5Widgets_INCLUDE_DIR} - ${Qt5Gui_INCLUDE_DIR} - ${Qt5Core_INCLUDE_DIR} ) + set(QtX_INCLUDE_DIR ${Qt5PrintSupport_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} + ${Qt5Svg_INCLUDE_DIRS} + ${Qt5Gui_INCLUDE_DIRS} + ${Qt5Core_INCLUDE_DIRS} ) set(QtX_LIBRARIES ${Qt5PrintSupport_LIBRARIES} ${Qt5Widgets_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Core_LIBRARIES} ) + #message(STATUS "QtX_INCLUDE_DIR: ${QtX_INCLUDE_DIR}") + #message(STATUS "QtX_LIBRARIES: ${QtX_LIBRARIES}") else() + message(STATUS "Attempt to find Qt 4...") # For Qt4. #set(QT_USE_QTXML "true") + set(QT_USE_QTSVG "true") find_package(Qt4 REQUIRED) include(${QT_USE_FILE}) + # ${QT_QTSVG_LIBRARY} set(QtX_LIBRARIES ${QT_LIBRARIES}) endif() endmacro() diff --git a/bootstrap/cmake_modules/FindQwt.cmake b/bootstrap/cmake_modules/FindQwt.cmake index b64011f9..4e30db80 100644 --- a/bootstrap/cmake_modules/FindQwt.cmake +++ b/bootstrap/cmake_modules/FindQwt.cmake @@ -14,6 +14,7 @@ FIND_PATH(QWT_INCLUDE_DIR NAMES qwt.h PATHS /usr/include + /usr/include/qt5 /usr/local/include "$ENV{LIB_DIR}/include" "$ENV{INCLUDE}" diff --git a/bootstrap/coriolisEnv.py b/bootstrap/coriolisEnv.py index 293c7b9b..879eb8a2 100755 --- a/bootstrap/coriolisEnv.py +++ b/bootstrap/coriolisEnv.py @@ -191,6 +191,7 @@ if __name__ == "__main__": version = "%d.%d" % (pyVersion[0],pyVersion[1]) if osType.startswith("Linux.SL") \ or osType.startswith("Linux.sl") \ + or osType.startswith("Linux.el") \ or osType.startswith("Darwin") \ or osType.startswith("Cygwin"): sitePackagesDir = "%s/python%s/site-packages" % (absLibDir,version) diff --git a/crlcore/etc/CMakeLists.txt b/crlcore/etc/CMakeLists.txt index 68cc8b71..c0e29afe 100644 --- a/crlcore/etc/CMakeLists.txt +++ b/crlcore/etc/CMakeLists.txt @@ -1,6 +1,7 @@ install ( FILES techno.conf 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 vsc200 DESTINATION ${SYS_CONF_DIR}/coriolis2 ) install ( DIRECTORY scmos_deep_018 DESTINATION ${SYS_CONF_DIR}/coriolis2 ) diff --git a/crlcore/etc/cmos/display.conf b/crlcore/etc/cmos/display.conf index e8c64d57..f6cc3311 100644 --- a/crlcore/etc/cmos/display.conf +++ b/crlcore/etc/cmos/display.conf @@ -6,4 +6,5 @@ import helpers # - # - +scale = 1.0 execfile( helpers.sysConfDir+'/common/display.conf' ) diff --git a/crlcore/etc/cmos/plugins.conf b/crlcore/etc/cmos/plugins.conf index 8d6928eb..06e87847 100644 --- a/crlcore/etc/cmos/plugins.conf +++ b/crlcore/etc/cmos/plugins.conf @@ -20,4 +20,5 @@ parametersTable = \ , ('chip.pad.pvsseck' , TypeString, 'pvsseck_px') , ('clockTree.minimumSide' , TypeInt , 300) , ('clockTree.buffer' , TypeString, 'buf_x2') + , ('clockTree.placerEngine' , TypeString, 'Mauka') ) diff --git a/crlcore/etc/common/display.conf b/crlcore/etc/common/display.conf index 3cef5f98..d77430a1 100644 --- a/crlcore/etc/common/display.conf +++ b/crlcore/etc/common/display.conf @@ -19,63 +19,63 @@ stylesTable = \ , (Drawing, 'fallback' , { 'color':'Gray238' , 'border':1, 'pattern':'55AA55AA55AA55AA' }) , (Drawing, 'background' , { 'color':'Gray50' , '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, 'boundaries' , { 'color':'208,199,192', 'border':1, 'pattern':'0000000000000000', 'threshold':0 }) , (Drawing, 'marker' , { 'color':'80,250,80' , 'border':1 }) , (Drawing, 'selectionDraw' , { 'color':'White' , 'border':1 }) , (Drawing, 'selectionFill' , { 'color':'White' , 'border':1 }) - , (Drawing, 'grid' , { 'color':'White' , 'border':1, 'threshold':2.0 }) - , (Drawing, 'spot' , { 'color':'White' , 'border':2, 'threshold':6.0 }) + , (Drawing, 'grid' , { 'color':'White' , 'border':1, 'threshold':2.0*scale }) + , (Drawing, 'spot' , { 'color':'White' , 'border':2, 'threshold':6.0*scale }) , (Drawing, 'ghost' , { 'color':'White' , 'border':1 }) - , (Drawing, 'text.ruler' , { 'color':'White' , 'border':1, 'threshold':0.0 }) - , (Drawing, 'text.instance' , { 'color':'Black' , 'border':1, 'threshold':4.0 }) - , (Drawing, 'text.reference' , { 'color':'White' , 'border':1, 'threshold':20.0 }) + , (Drawing, 'text.ruler' , { 'color':'White' , 'border':1, 'threshold':0.0*scale }) + , (Drawing, 'text.instance' , { 'color':'Black' , 'border':1, 'threshold':4.0*scale }) + , (Drawing, 'text.reference' , { 'color':'White' , 'border':1, 'threshold':20.0*scale }) , (Drawing, 'undef' , { 'color':'Violet' , 'border':0, 'pattern':'2244118822441188' }) , (Drawing, 'mauka.container', { 'color':'Magenta4' , 'border':4, 'pattern':'0000000000000000', 'goMatched':False }) # Group: Active Layer. , (Group , 'Active Layer') - , (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.5 }) - , (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'55AA55AA55AA55AA', 'threshold':1.50 }) - , (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50 }) - , (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50 }) - , (Drawing, 'active' , { 'color':'White' , 'pattern':'antihash1.8' , 'threshold':1.50 }) - , (Drawing, 'poly' , { 'color':'Red' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50 }) + , (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.5 *scale }) + , (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'55AA55AA55AA55AA', 'threshold':1.50*scale }) + , (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50*scale }) + , (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50*scale }) + , (Drawing, 'active' , { 'color':'White' , 'pattern':'antihash1.8' , 'threshold':1.50*scale }) + , (Drawing, 'poly' , { 'color':'Red' , 'pattern':'55AA55AA55AA55AA', 'threshold':1.50*scale }) # Group: Routing Layer. , (Group , 'Routing Layer') - , (Drawing, 'metal1' , { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80 }) - , (Drawing, 'metal2' , { 'color':'Aqua' , 'pattern':'light_antihash0.8' , 'threshold':0.02 }) - , (Drawing, 'metal3' , { 'color':'LightPink', 'pattern':'light_antihash1.8' , 'threshold':0.02 }) - , (Drawing, 'metal4' , { 'color':'Green' , 'pattern':'light_antihash2.8' , 'threshold':0.02 }) - , (Drawing, 'metal5' , { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.02 }) - , (Drawing, 'metal6' , { 'color':'Violet' , 'pattern':'light_antihash0.8' , 'threshold':0.02 }) + , (Drawing, 'metal1' , { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80*scale }) + , (Drawing, 'metal2' , { 'color':'Aqua' , 'pattern':'light_antihash0.8' , 'threshold':0.02*scale }) + , (Drawing, 'metal3' , { 'color':'LightPink', 'pattern':'light_antihash1.8' , 'threshold':0.02*scale }) + , (Drawing, 'metal4' , { 'color':'Green' , 'pattern':'light_antihash2.8' , 'threshold':0.02*scale }) + , (Drawing, 'metal5' , { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.02*scale }) + , (Drawing, 'metal6' , { 'color':'Violet' , 'pattern':'light_antihash0.8' , 'threshold':0.02*scale }) # Group: Cuts (VIA holes). , (Group , 'Cuts (VIA Holes)') - , (Drawing, 'cut0', { 'color':'0,150,150', 'threshold':1.50 }) - , (Drawing, 'cut1', { 'color':'Aqua' , 'threshold':0.80 }) - , (Drawing, 'cut2', { 'color':'LightPink', 'threshold':0.80 }) - , (Drawing, 'cut3', { 'color':'Green' , 'threshold':0.80 }) - , (Drawing, 'cut4', { 'color':'Yellow' , 'threshold':0.80 }) - , (Drawing, 'cut5', { 'color':'Violet' , 'threshold':0.80 }) + , (Drawing, 'cut0', { 'color':'0,150,150', 'threshold':1.50*scale }) + , (Drawing, 'cut1', { 'color':'Aqua' , 'threshold':0.80*scale }) + , (Drawing, 'cut2', { 'color':'LightPink', 'threshold':0.80*scale }) + , (Drawing, 'cut3', { 'color':'Green' , 'threshold':0.80*scale }) + , (Drawing, 'cut4', { 'color':'Yellow' , 'threshold':0.80*scale }) + , (Drawing, 'cut5', { 'color':'Violet' , 'threshold':0.80*scale }) # Group: MIM6. , (Group , 'MIM6') - , (Drawing, 'topmim6', { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80 }) - , (Drawing, 'botmim6', { 'color':'Aqua' , 'pattern':'light_antihash0.8', 'threshold':0.80 }) - , (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8', 'threshold':0.80 }) - , (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.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*scale }) + , (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8', 'threshold':0.80*scale }) + , (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80*scale }) # Group: Blockages. , (Group , 'Blockages') - , (Drawing, 'blockage1', { 'color':'Blue' , 'pattern':'006070381c0e0703' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage2', { 'color':'Aqua' , 'pattern':'8103060c183060c0' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage3', { 'color':'LightPink', 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage4', { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage5', { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage6', { 'color':'Violet' , 'pattern':'light_antihash0.8', '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*scale, '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*scale, '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*scale, 'border':2 }) # Group: Knik & Kite. , (Group , 'Knik & Kite') @@ -98,11 +98,11 @@ stylesTable = \ , (Drawing, 'foreground' , { 'color':'Black', 'border':1 }) , (Drawing, 'selectionDraw', { 'color':'Black', 'border':1 }) , (Drawing, 'selectionFill', { 'color':'Black', 'border':1 }) - , (Drawing, 'grid' , { 'color':'Black', 'border':1, 'threshold':6.0 }) - , (Drawing, 'spot' , { '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*scale }) , (Drawing, 'ghost' , { 'color':'Black', 'border':1 }) - , (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0 }) - , (Drawing, 'text.instance', { 'color':'Black', 'border':1, 'threshold':4.0 }) + , (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0*scale }) + , (Drawing, 'text.instance', { 'color':'Black', 'border':1, 'threshold':4.0*scale }) , (Drawing, 'undef' , { 'color':'Black', 'border':0, 'pattern':'2244118822441188' }) ) @@ -116,70 +116,70 @@ stylesTable = \ , (Drawing, 'fallback' , { 'color':'Gray238' , 'border':1, 'pattern':'55AA55AA55AA55AA' }) , (Drawing, 'background' , { 'color':'Gray50' , '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, 'boundaries' , { 'color':'208,199,192', 'border':1, 'pattern':'0000000000000000', 'threshold':0 }) , (Drawing, 'marker' , { 'color':'80,250,80' , 'border':1 }) , (Drawing, 'selectionDraw' , { 'color':'White' , 'border':1 }) , (Drawing, 'selectionFill' , { 'color':'White' , 'border':1 }) - , (Drawing, 'grid' , { 'color':'White' , 'border':1, 'threshold':2.0 }) - , (Drawing, 'spot' , { 'color':'White' , 'border':2, 'threshold':6.0 }) + , (Drawing, 'grid' , { 'color':'White' , 'border':1, 'threshold':2.0*scale }) + , (Drawing, 'spot' , { 'color':'White' , 'border':2, 'threshold':6.0*scale }) , (Drawing, 'ghost' , { 'color':'White' , 'border':1 }) - , (Drawing, 'text.ruler' , { 'color':'White' , 'border':1, 'threshold':0.0 }) - , (Drawing, 'text.instance' , { 'color':'White' , 'border':1, 'threshold':4.0 }) - , (Drawing, 'text.reference', { 'color':'White' , 'border':1, 'threshold':20.0 }) + , (Drawing, 'text.ruler' , { 'color':'White' , 'border':1, 'threshold':0.0 *scale }) + , (Drawing, 'text.instance' , { 'color':'White' , 'border':1, 'threshold':4.0 *scale }) + , (Drawing, 'text.reference', { 'color':'White' , 'border':1, 'threshold':20.0*scale }) , (Drawing, 'undef' , { 'color':'Violet' , 'border':0, 'pattern':'2244118822441188' }) # Active Layers. , (Group , 'Active Layers') - , (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'urgo.8' , 'border':1, 'threshold':1.50 }) - , (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'urgo.8' , 'border':1, 'threshold':1.50 }) - , (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'antihash0.8' , 'border':1, 'threshold':1.50 }) - , (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'antihash0.8' , 'border':1, 'threshold':1.50 }) - , (Drawing, 'active' , { 'color':'White' , 'pattern':'antihash1.8' , 'border':1, 'threshold':1.50 }) - , (Drawing, 'poly' , { 'color':'Red' , 'pattern':'poids2.8' , 'border':1, 'threshold':1.50 }) - , (Drawing, 'poly2' , { 'color':poly2Color , 'pattern':'poids2.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*scale }) + , (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*scale }) + , (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*scale }) + , (Drawing, 'poly2' , { 'color':poly2Color , 'pattern':'poids2.8' , 'border':1, 'threshold':1.50*scale }) # Routing Layers. , (Group , 'Routing Layers') - #, (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'light_antislash0.8', 'border':1, 'threshold':0.80 }) - , (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'slash.8' , 'border':1, 'threshold':0.80 }) - , (Drawing, 'metal2', { 'color':'Aqua' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal3', { 'color':'LightPink', 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal4', { 'color':'Green' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal5', { 'color':'Yellow' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal6', { 'color':'Violet' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal7', { 'color':'Red' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal8', { 'color':'Blue' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) + #, (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*scale }) + , (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*scale }) + , (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*scale }) + , (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*scale }) + , (Drawing, 'metal8', { 'color':'Blue' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02*scale }) # Cuts (VIA holes). , (Group , 'Cuts (VIA holes)') - , (Drawing, 'cut0', { 'color':'0,150,150', 'threshold':1.50 }) - , (Drawing, 'cut1', { 'color':'Aqua' , 'threshold':0.80 }) - , (Drawing, 'cut2', { 'color':'LightPink', 'threshold':0.80 }) - , (Drawing, 'cut3', { 'color':'Green' , 'threshold':0.80 }) - , (Drawing, 'cut4', { 'color':'Yellow' , 'threshold':0.80 }) - , (Drawing, 'cut5', { 'color':'Violet' , 'threshold':0.80 }) - , (Drawing, 'cut6', { 'color':'Red' , 'threshold':0.80 }) - , (Drawing, 'cut7', { 'color':'Blue' , 'threshold':0.80 }) + , (Drawing, 'cut0', { 'color':'0,150,150', 'threshold':1.50*scale }) + , (Drawing, 'cut1', { 'color':'Aqua' , 'threshold':0.80*scale }) + , (Drawing, 'cut2', { 'color':'LightPink', 'threshold':0.80*scale }) + , (Drawing, 'cut3', { 'color':'Green' , 'threshold':0.80*scale }) + , (Drawing, 'cut4', { 'color':'Yellow' , 'threshold':0.80*scale }) + , (Drawing, 'cut5', { 'color':'Violet' , 'threshold':0.80*scale }) + , (Drawing, 'cut6', { 'color':'Red' , 'threshold':0.80*scale }) + , (Drawing, 'cut7', { 'color':'Blue' , 'threshold':0.80*scale }) # MIM6. , (Group , 'MIM6') - , (Drawing, 'topmim6', { 'color':'Blue' , 'pattern':'poids2.32' , 'threshold':0.80 }) - , (Drawing, 'botmim6', { 'color':'Aqua' , 'pattern':'light_antihash0.8' , 'threshold':0.80 }) - , (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8' , 'threshold':0.80 }) - , (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.8' , '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*scale }) + , (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8' , 'threshold':0.80*scale }) + , (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.8' , 'threshold':0.80*scale }) # Blockages. , (Group , 'Blockages') - , (Drawing, 'blockage1', { 'color':'Blue' , 'pattern':'light_antislash0.8', 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage2', { 'color':'Aqua' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage3', { 'color':'LightPink', 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage4', { 'color':'Green' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage5', { 'color':'Yellow' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage6', { 'color':'Violet' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage7', { 'color':'Red' , 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage8', { 'color':'Blue' , 'pattern':'poids4.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*scale, '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*scale, '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*scale, '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*scale, 'border':2 }) # Knick & Kite. , (Group , 'Knick & Kite') @@ -203,12 +203,12 @@ stylesTable = \ , (Drawing, 'foreground' , { 'color':'Black', 'border':1 }) , (Drawing, 'selectionDraw' , { 'color':'Black', 'border':1 }) , (Drawing, 'selectionFill' , { 'color':'Black', 'border':1 }) - , (Drawing, 'grid' , { 'color':'Black', 'border':1, 'threshold':6.0 }) - , (Drawing, 'spot' , { '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*scale }) , (Drawing, 'ghost' , { 'color':'Black', 'border':1 }) - , (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0 }) - , (Drawing, 'text.instance' , { 'color':'Black', 'border':1, 'threshold':4.0 }) - , (Drawing, 'text.reference', { 'color':'Black', 'border':1, 'threshold':20.0 }) + , (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0 *scale }) + , (Drawing, 'text.instance' , { 'color':'Black', 'border':1, 'threshold':4.0 *scale }) + , (Drawing, 'text.reference', { 'color':'Black', 'border':1, 'threshold':20.0*scale }) , (Drawing, 'undef' , { 'color':'Black', 'border':0, 'pattern':'2244118822441188' }) ) @@ -238,30 +238,30 @@ stylesTable = \ # Active Layers. , (Group , 'Active Layers') - , (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) - , (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) - , (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) - , (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) - , (Drawing, 'active' , { 'color':'White' , 'pattern':'0000000000000000', 'threshold':1.50, 'border':2 }) - , (Drawing, 'poly' , { 'color':'Red' , '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*scale, 'border':2 }) + , (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 }) + , (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 }) + , (Drawing, 'active' , { 'color':'White' , 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 }) + , (Drawing, 'poly' , { 'color':'Red' , 'pattern':'0000000000000000', 'threshold':1.50*scale, 'border':2 }) # Routing Layers. , (Group , 'Routing Layers') - , (Drawing, 'metal1' , { 'color':'Blue' , 'pattern':'0000000000000000', 'threshold':0.80, 'border':2 }) - , (Drawing, 'metal2' , { 'color':'Aqua' , 'pattern':'0000000000000000', 'threshold':0.40, 'border':2 }) - , (Drawing, 'metal3' , { 'color':'LightPink', 'pattern':'0000000000000000', 'threshold':0.02, 'border':2 }) - , (Drawing, 'metal4' , { 'color':'Green' , 'pattern':'0000000000000000', 'threshold':0.02, 'border':2 }) - , (Drawing, 'metal5' , { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':0.02, 'border':2 }) - , (Drawing, 'metal6' , { 'color':'Violet' , 'pattern':'0000000000000000', 'threshold':0.02, 'border':2 }) + , (Drawing, 'metal1' , { 'color':'Blue' , 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':2 }) + , (Drawing, 'metal2' , { 'color':'Aqua' , 'pattern':'0000000000000000', 'threshold':0.40*scale, 'border':2 }) + , (Drawing, 'metal3' , { 'color':'LightPink', 'pattern':'0000000000000000', 'threshold':0.02*scale, 'border':2 }) + , (Drawing, 'metal4' , { 'color':'Green' , 'pattern':'0000000000000000', 'threshold':0.02*scale, 'border':2 }) + , (Drawing, 'metal5' , { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':0.02*scale, 'border':2 }) + , (Drawing, 'metal6' , { 'color':'Violet' , 'pattern':'0000000000000000', 'threshold':0.02*scale, 'border':2 }) # Cuts (VIA holes). , (Group , 'Cuts (VIA holes)') - , (Drawing, 'cut0' , { 'color':'0,150,150', 'pattern':'poids4.8' , 'threshold':1.50, 'border':1 }) - , (Drawing, 'cut1' , { 'color':'Aqua' , 'pattern':'0000000000000000', 'threshold':0.80, 'border':1 }) - , (Drawing, 'cut2' , { 'color':'LightPink', 'pattern':'0000000000000000', 'threshold':0.80, 'border':1 }) - , (Drawing, 'cut3' , { 'color':'Green' , 'pattern':'0000000000000000', 'threshold':0.80, 'border':1 }) - , (Drawing, 'cut4' , { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':0.80, 'border':1 }) - , (Drawing, 'cut5' , { 'color':'Violet' , 'pattern':'0000000000000000', 'threshold':0.80, '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*scale, 'border':1 }) + , (Drawing, 'cut2' , { 'color':'LightPink', 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':1 }) + , (Drawing, 'cut3' , { 'color':'Green' , 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':1 }) + , (Drawing, 'cut4' , { 'color':'Yellow' , 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':1 }) + , (Drawing, 'cut5' , { 'color':'Violet' , 'pattern':'0000000000000000', 'threshold':0.80*scale, 'border':1 }) ) # ---------------------------------------------------------------------- @@ -273,14 +273,14 @@ stylesTable = \ # Group: Viewer. , (Group , 'Viewer') , (Drawing, 'background' , { 'color':'White', 'border':1 }) - , (Drawing, 'grid' , { 'color':'Black', 'border':1, 'threshold':2.0 }) - , (Drawing, 'spot' , { 'color':'Black', 'border':1, 'threshold':2.0 }) - , (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0 }) - , (Drawing, 'text.reference', { 'color':'Black', 'border':1, 'threshold':20.0 }) + , (Drawing, 'grid' , { 'color':'Black', 'border':1, 'threshold':2.0 *scale }) + , (Drawing, 'spot' , { 'color':'Black', 'border':1, 'threshold':2.0 *scale }) + , (Drawing, 'text.ruler' , { 'color':'Black', 'border':1, 'threshold':0.0 *scale }) + , (Drawing, 'text.reference', { 'color':'Black', 'border':1, 'threshold':20.0*scale }) # 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, 'background' , { 'color':'White' , '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, 'boundaries' , { 'color':'Black' , 'border':1, 'pattern':'0000000000000000', 'threshold':0 }) , (Drawing, 'marker' , { 'color':'80,250,80', 'border':1 }) , (Drawing, 'selectionDraw' , { 'color':'Black' , 'border':1 }) , (Drawing, 'selectionFill' , { 'color':'Black' , 'border':1 }) - , (Drawing, 'grid' , { 'color':'Black' , 'border':1, 'threshold':2.0 }) - , (Drawing, 'spot' , { 'color':'Black' , 'border':2, 'threshold':6.0 }) + , (Drawing, 'grid' , { 'color':'Black' , 'border':1, 'threshold':2.0*scale }) + , (Drawing, 'spot' , { 'color':'Black' , 'border':2, 'threshold':6.0*scale }) , (Drawing, 'ghost' , { 'color':'Black' , 'border':1 }) - , (Drawing, 'text.ruler' , { 'color':'Black' , 'border':1, 'threshold':0.0 }) - , (Drawing, 'text.instance' , { 'color':'Black' , 'border':1, 'threshold':4.0 }) - , (Drawing, 'text.reference' , { 'color':'Black' , 'border':1, 'threshold':20.0 }) + , (Drawing, 'text.ruler' , { 'color':'Black' , 'border':1, 'threshold':0.0 *scale }) + , (Drawing, 'text.instance' , { 'color':'Black' , 'border':1, 'threshold':4.0 *scale }) + , (Drawing, 'text.reference' , { 'color':'Black' , 'border':1, 'threshold':20.0*scale }) , (Drawing, 'undef' , { 'color':'Violet' , 'border':0, 'pattern':'2244118822441188' }) , (Drawing, 'mauka.container', { 'color':'Magenta4' , 'border':4, 'pattern':'0000000000000000', 'goMatched':False }) # Group: Active Layers. , (Group , 'Active Layers') - , (Drawing, 'nWell' , { 'color':'Tan' , 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50 }) - , (Drawing, 'pWell' , { 'color':'LightYellow', 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50 }) - , (Drawing, 'nImplant', { 'color':'LawnGreen' , 'pattern':'diffusion.32' , 'border':0, 'threshold':1.50 }) - , (Drawing, 'pImplant', { 'color':'Yellow' , 'pattern':'diffusion.32' , 'border':0, 'threshold':1.50 }) - , (Drawing, 'active' , { 'color':'White' , 'pattern':'active.32' , 'border':0, 'threshold':1.50 }) - , (Drawing, 'poly' , { 'color':'Red' , 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50 }) - , (Drawing, 'poly2' , { 'color':poly2Color , '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*scale }) + , (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*scale }) + , (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*scale }) + , (Drawing, 'poly2' , { 'color':poly2Color , 'pattern':'antipoids2.32', 'border':1, 'threshold':1.50*scale }) # Group: Routing Layers. , (Group , 'Routing Layers') - , (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'slash.32' , 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal2', { 'color':'Aqua' , 'pattern':'antislash2.32', 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal3', { 'color':'LightPink', 'pattern':'antislash3.32', 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal4', { 'color':'Green' , 'pattern':'antislash4.32', 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal5', { 'color':'Yellow' , 'pattern':'antislash5.32', 'border':1, 'threshold':0.02 }) - , (Drawing, 'metal6', { 'color':'Violet' , 'pattern':'antislash2.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*scale }) + , (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*scale }) + , (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*scale }) # Group: Cuts (VIA holes) , (Group , 'Cuts (VIA holes)') - , (Drawing, 'cut0', { 'color':'Blue' , 'pattern':'poids2.8' , 'border':2, 'threshold':1.50 }) - , (Drawing, 'cut1', { 'color':'Aqua' , 'pattern':'antipoids2.8', 'border':2, 'threshold':0.80 }) - , (Drawing, 'cut2', { 'color':'LightPink', 'pattern':'poids2.8' , 'border':2, 'threshold':0.80 }) - , (Drawing, 'cut3', { 'color':'Green' , 'pattern':'antipoids2.8', 'border':2, 'threshold':0.80 }) - , (Drawing, 'cut4', { 'color':'Yellow' , 'pattern':'poids2.8' , 'border':2, 'threshold':0.80 }) - , (Drawing, 'cut5', { 'color':'Violet' , 'pattern':'antipoids2.8', 'border':2, 'threshold':0.80 }) + , (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*scale }) + , (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*scale }) + , (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*scale }) # Group: MIM6. , (Group , 'MIM6') - , (Drawing, 'topmim6', { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80 }) - , (Drawing, 'botmim6', { 'color':'Aqua' , 'pattern':'light_antihash0.8', 'threshold':0.80 }) - , (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8', 'threshold':0.80 }) - , (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.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*scale }) + , (Drawing, 'padopen', { 'color':'LightPink', 'pattern':'light_antihash1.8', 'threshold':0.80*scale }) + , (Drawing, 'alucap' , { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80*scale }) # Group: Blockages. , (Group , 'Blockages') - , (Drawing, 'blockage1', { 'color':'Blue' , 'pattern':'006070381c0e0703' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage2', { 'color':'Aqua' , 'pattern':'8103060c183060c0' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage3', { 'color':'LightPink', 'pattern':'poids4.8' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage4', { 'color':'Green' , 'pattern':'light_antihash2.8', 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage5', { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.80, 'border':2 }) - , (Drawing, 'blockage6', { 'color':'Violet' , 'pattern':'light_antihash0.8', '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*scale, '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*scale, '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*scale, 'border':2 }) # Group: Knik & Kite. , (Group , 'Knik & Kite') diff --git a/crlcore/etc/ispd05/alliance.conf b/crlcore/etc/ispd05/alliance.conf new file mode 100644 index 00000000..da646820 --- /dev/null +++ b/crlcore/etc/ispd05/alliance.conf @@ -0,0 +1,68 @@ +# -*- Mode:Python; explicit-buffer-name: "alliance.conf" -*- + +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) + diff --git a/crlcore/etc/ispd05/display.conf b/crlcore/etc/ispd05/display.conf new file mode 100644 index 00000000..f6cc3311 --- /dev/null +++ b/crlcore/etc/ispd05/display.conf @@ -0,0 +1,10 @@ +# -*- Mode:Python; explicit-buffer-name: "display.conf" -*- + +import helpers + +# Provides standard settings for: +# - +# - + +scale = 1.0 +execfile( helpers.sysConfDir+'/common/display.conf' ) diff --git a/crlcore/etc/ispd05/hMetis.conf b/crlcore/etc/ispd05/hMetis.conf new file mode 100644 index 00000000..98586ae8 --- /dev/null +++ b/crlcore/etc/ispd05/hMetis.conf @@ -0,0 +1,5 @@ +# -*- Mode:Python; explicit-buffer-name: "hMetis.conf" -*- + +import helpers + +execfile( helpers.sysConfDir+'/common/hMetis.conf' ) diff --git a/crlcore/etc/ispd05/kite.conf b/crlcore/etc/ispd05/kite.conf new file mode 100644 index 00000000..6deac6e4 --- /dev/null +++ b/crlcore/etc/ispd05/kite.conf @@ -0,0 +1,23 @@ +# -*- Mode:Python; explicit-buffer-name: "kite.conf" -*- + +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 } ) + ) diff --git a/crlcore/etc/ispd05/mauka.conf b/crlcore/etc/ispd05/mauka.conf new file mode 100644 index 00000000..481b0b6a --- /dev/null +++ b/crlcore/etc/ispd05/mauka.conf @@ -0,0 +1,5 @@ +# -*- Mode:Python; explicit-buffer-name: "mauka.conf" -*- + +import helpers + +execfile( helpers.sysConfDir+'/common/mauka.conf' ) diff --git a/crlcore/etc/ispd05/misc.conf b/crlcore/etc/ispd05/misc.conf new file mode 100644 index 00000000..6d5ac0f6 --- /dev/null +++ b/crlcore/etc/ispd05/misc.conf @@ -0,0 +1,9 @@ +# -*- Mode:Python; explicit-buffer-name: "misc.conf" -*- + +import helpers + +# Provides standard settings for: +# # - +# # - +# +execfile( helpers.sysConfDir+'/common/misc.conf' ) diff --git a/crlcore/etc/ispd05/nimbus.conf b/crlcore/etc/ispd05/nimbus.conf new file mode 100644 index 00000000..10d9fc4a --- /dev/null +++ b/crlcore/etc/ispd05/nimbus.conf @@ -0,0 +1,5 @@ +# -*- Mode:Python; explicit-buffer-name: "nimbus.conf" -*- + +import helpers + +execfile( helpers.sysConfDir+'/common/nimbus.conf' ) diff --git a/crlcore/etc/ispd05/patterns.conf b/crlcore/etc/ispd05/patterns.conf new file mode 100644 index 00000000..8c511b77 --- /dev/null +++ b/crlcore/etc/ispd05/patterns.conf @@ -0,0 +1,5 @@ +# -*- Mode:Python; explicit-buffer-name: "patterns.conf" -*- + +import helpers + +execfile( helpers.sysConfDir+'/common/patterns.conf' ) diff --git a/crlcore/etc/ispd05/plugins.conf b/crlcore/etc/ispd05/plugins.conf new file mode 100644 index 00000000..8d6928eb --- /dev/null +++ b/crlcore/etc/ispd05/plugins.conf @@ -0,0 +1,23 @@ +# -*- Mode:Python; explicit-buffer-name: "plugins.conf" -*- + +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') + ) diff --git a/crlcore/etc/ispd05/stratus1.conf b/crlcore/etc/ispd05/stratus1.conf new file mode 100644 index 00000000..8b434647 --- /dev/null +++ b/crlcore/etc/ispd05/stratus1.conf @@ -0,0 +1,15 @@ +# -*- Mode:Python; explicit-buffer-name: "stratus1.conf" -*- + +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' ) diff --git a/crlcore/etc/ispd05/technology.conf b/crlcore/etc/ispd05/technology.conf new file mode 100644 index 00000000..1371a43d --- /dev/null +++ b/crlcore/etc/ispd05/technology.conf @@ -0,0 +1,162 @@ +# -*- Mode:Python; explicit-buffer-name: "technology.conf" -*- + +import helpers + +# The informations here are extracted from the Alliance ".rds" file, +# and must be coherent with it. +# +# Provides standard settings for: +# - +# - +# - +# - + +execfile( helpers.sysConfDir+'/common/technology.conf' ) + + +# Format of : +# 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) + ) diff --git a/crlcore/etc/scmos_deep_018/display.conf b/crlcore/etc/scmos_deep_018/display.conf index a9e4bc45..a61db995 100644 --- a/crlcore/etc/scmos_deep_018/display.conf +++ b/crlcore/etc/scmos_deep_018/display.conf @@ -6,4 +6,6 @@ import helpers # - # - +scale = 0.5 + execfile( helpers.sysConfDir+'/common/display.conf' ) diff --git a/crlcore/etc/scmos_deep_018/plugins.conf b/crlcore/etc/scmos_deep_018/plugins.conf index 745b5dcc..5b16ad52 100644 --- a/crlcore/etc/scmos_deep_018/plugins.conf +++ b/crlcore/etc/scmos_deep_018/plugins.conf @@ -21,6 +21,7 @@ parametersTable = \ , ('chip.pad.pvssick' , TypeString, 'pvssick_mpx') , ('chip.pad.pvddeck' , TypeString, 'pvddeck_mpx') , ('chip.pad.pvsseck' , TypeString, 'pvsseck_mpx') - , ('clockTree.minimumSide' , TypeInt , 700) + , ('clockTree.minimumSide' , TypeInt , 1000) , ('clockTree.buffer' , TypeString, 'bf1_x4') + , ('clockTree.placerEngine' , TypeString, 'Etesian') ) diff --git a/crlcore/etc/vsc200/display.conf b/crlcore/etc/vsc200/display.conf index 23fe7ada..db8ca9ab 100644 --- a/crlcore/etc/vsc200/display.conf +++ b/crlcore/etc/vsc200/display.conf @@ -6,4 +6,6 @@ import helpers # - # - +scale = 0.5 + execfile( helpers.sysConfDir+'/common/display.conf' ) diff --git a/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp b/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp index e5d63777..62f126f5 100644 --- a/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp +++ b/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp @@ -36,6 +36,7 @@ #include "hurricane/UpdateSession.h" #include "crlcore/Utilities.h" #include "crlcore/AllianceFramework.h" +#include "crlcore/CellGauge.h" #include "crlcore/ToolBox.h" #include "crlcore/Ispd05Bookshelf.h" @@ -151,6 +152,7 @@ namespace CRL { Cell* Ispd05::load ( string benchmark ) { AllianceFramework* af = AllianceFramework::get(); + pitch = af->getCellGauge()->getPitch(); UpdateSession::open (); diff --git a/cumulus/src/plugins/ClockTreePlugin.py b/cumulus/src/plugins/ClockTreePlugin.py index 5327e15b..ba83c0c6 100755 --- a/cumulus/src/plugins/ClockTreePlugin.py +++ b/cumulus/src/plugins/ClockTreePlugin.py @@ -27,6 +27,7 @@ try: from helpers import trace from helpers import ErrorMessage import Mauka + import Etesian import Unicorn import plugins import clocktree.ClockTree @@ -101,9 +102,16 @@ def ScriptMain ( **kw ): ht = clocktree.ClockTree.HTree.create( chip.Configuration.GaugeConfWrapper(chip.Configuration.GaugeConf()) , cell, None, cell.getAbutmentBox() ) if editor: editor.refresh() - mauka = Mauka.MaukaEngine.create( cell ) - mauka.run() - mauka.destroy() + + if Cfg.getParamString('clockTree.placerEngine').asString() != 'Etesian': + 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.prune() ht.route() diff --git a/etesian/CMakeLists.txt b/etesian/CMakeLists.txt index 85c1af97..ef071b7f 100644 --- a/etesian/CMakeLists.txt +++ b/etesian/CMakeLists.txt @@ -8,8 +8,8 @@ cmake_minimum_required(VERSION 2.8.9) list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/") - find_package(COLOQUINTE) - find_package(Bootstrap REQUIRED) + find_package(Coloquinte REQUIRED) + find_package(Bootstrap REQUIRED) setup_project_paths(CORIOLIS) setup_project_paths(COLOQUINTE) setup_qt() diff --git a/etesian/src/AddFeeds.cpp b/etesian/src/AddFeeds.cpp new file mode 100644 index 00000000..29700de5 --- /dev/null +++ b/etesian/src/AddFeeds.cpp @@ -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 +#include +#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 _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 _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::iterator imerge = _chunks.end(); + list::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::iterator ichunk = _chunks.begin(); + list::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 << "::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 ; islicemerge( 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((*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. diff --git a/etesian/src/CMakeLists.txt b/etesian/src/CMakeLists.txt index cc70c261..d67555df 100644 --- a/etesian/src/CMakeLists.txt +++ b/etesian/src/CMakeLists.txt @@ -4,7 +4,6 @@ include_directories ( ${ETESIAN_SOURCE_DIR}/src ${COLOQUINTE_INCLUDE_DIR} - ${EIGEN3_INCLUDE_DIR} ${CORIOLIS_INCLUDE_DIR} ${HURRICANE_INCLUDE_DIR} ${CONFIGURATION_INCLUDE_DIR} @@ -12,27 +11,8 @@ ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_PATH} ) - set ( includes #etesian/Constants.h - #etesian/TrackCost.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 + set ( includes etesian/Configuration.h + etesian/FeedCells.h etesian/EtesianEngine.h etesian/GraphicEtesianEngine.h ) @@ -40,30 +20,9 @@ etesian/PyGraphicEtesianEngine.h ) set ( mocIncludes etesian/GraphicEtesianEngine.h ) - set ( cpps #TrackCost.cpp - #DataNegociate.cpp - #TrackElement.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 + set ( cpps Configuration.cpp + AddFeeds.cpp + FeedCells.cpp EtesianEngine.cpp GraphicEtesianEngine.cpp ) @@ -71,7 +30,6 @@ PyEtesianEngine.cpp PyGraphicEtesianEngine.cpp ) -# set ( etesiancpps EtesianMain.cpp ) qtX_wrap_cpp ( mocCpps ${mocIncludes} ) add_library ( etesian ${cpps} ${mocCpps} ${pyCpps} ) diff --git a/etesian/src/Configuration.cpp b/etesian/src/Configuration.cpp index 7d4d6eb8..0341e9c8 100644 --- a/etesian/src/Configuration.cpp +++ b/etesian/src/Configuration.cpp @@ -24,9 +24,10 @@ #include "hurricane/DataBase.h" #include "hurricane/Cell.h" #include "crlcore/Utilities.h" -#include "crlcore/RoutingLayerGauge.h" +#include "crlcore/CellGauge.h" #include "crlcore/AllianceFramework.h" #include "etesian/Configuration.h" +#include "etesian/EtesianEngine.h" @@ -45,8 +46,7 @@ namespace Etesian { using Hurricane::Technology; using Hurricane::DataBase; using CRL::AllianceFramework; - using CRL::RoutingGauge; - using CRL::RoutingLayerGauge; + using CRL::CellGauge; // ------------------------------------------------------------------- @@ -61,43 +61,44 @@ namespace Etesian { // Class : "Etesian::ConfigurationConcrete". - ConfigurationConcrete::ConfigurationConcrete ( const RoutingGauge* rg ) + ConfigurationConcrete::ConfigurationConcrete ( const CellGauge* cg ) : 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 ) : Configuration() - , _rg (NULL) + , _cg (NULL) + , _flags (other._flags) { - if ( other._rg ) _rg = other._rg->getClone(); + if ( other._cg ) _cg = other._cg->getClone(); } ConfigurationConcrete::~ConfigurationConcrete () { - ltrace(89) << "About to delete attribute _rg (RoutingGauge)." << endl; - _rg->destroy (); + ltrace(89) << "About to delete attribute _cg (CellGauge)." << endl; + _cg->destroy (); } - ConfigurationConcrete* ConfigurationConcrete::clone () const - { return new ConfigurationConcrete(*this); } - - - RoutingGauge* ConfigurationConcrete::getRoutingGauge () const - { return _rg; } + ConfigurationConcrete* ConfigurationConcrete::clone () const { 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; } + void ConfigurationConcrete::unsetFlags ( unsigned int flags ) { _flags &= ~flags; } void ConfigurationConcrete::print ( Cell* cell ) const { cout << " o Configuration of ToolEngine 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; - os << "<" << _getTypeName() << " " << _rg->getName() << ">"; + os << "<" << _getTypeName() << " " << _cg->getName() << ">"; return os.str(); } @@ -118,7 +119,7 @@ namespace Etesian { Record* ConfigurationConcrete::_getRecord () const { Record* record = new Record ( _getString() ); - record->add ( getSlot ( "_rg" , _rg ) ); + record->add ( getSlot ( "_cg" , _cg ) ); return ( record ); } diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index fe2b2bfb..4c192b6d 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -18,7 +18,8 @@ #include #include #if HAVE_COLOQUINTE -#include "coloquinte/circuit_graph.hxx" +#include "Coloquinte/circuit.hxx" +#include "Coloquinte/legalizer.hxx" #endif #include "vlsisapd/utilities/Dots.h" #include "hurricane/DebugSession.h" @@ -42,15 +43,23 @@ #include "crlcore/Measures.h" #include "crlcore/AllianceFramework.h" #include "etesian/EtesianEngine.h" +#include "etesian/FeedCells.h" namespace { using namespace std; using namespace Hurricane; + using coloquinte::float_t; + using coloquinte::point; + + #if HAVE_COLOQUINTE + inline bool isNan( const float_t& f ) { return (f != f); } + + string extractInstanceName ( const RoutingPad* rp ) { ostringstream name; @@ -102,6 +111,7 @@ namespace { } +#if 0 Coloquinte::cell::pin::pin_dir extractDirection ( const RoutingPad* rp ) { switch ( rp->_getEntityAsComponent()->getNet()->getDirection() ) { @@ -114,6 +124,7 @@ namespace { return Coloquinte::cell::pin::O; } +#endif Point extractRpOffset ( const RoutingPad* rp ) @@ -129,6 +140,38 @@ namespace { return offset; } + + + Transformation toTransformation ( point position + , point 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 @@ -172,11 +215,31 @@ namespace Etesian { using Hurricane::CellWidget; using CRL::ToolEngine; using CRL::AllianceFramework; + using CRL::Catalog; using CRL::addMeasure; using CRL::Measures; using CRL::MeasuresSet; 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 = "%s :\n\n" @@ -199,16 +262,27 @@ namespace Etesian { EtesianEngine::EtesianEngine ( Cell* cell ) : ToolEngine (cell) - , _configuration(NULL) + , _configuration(new ConfigurationConcrete()) , _flags (0) - , _circuit (NULL) + , _timer () + , _surface () + , _circuit () + , _placementLB () + , _placementUB () , _cellsToIds () + , _idsToInsts () , _cellWidget (NULL) + , _feedCells (this) { } 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 ) @@ -234,9 +308,6 @@ namespace Etesian { EtesianEngine::~EtesianEngine () { -#if HAVE_COLOQUINTE - if (_circuit) delete _circuit; -#endif delete _configuration; } @@ -245,10 +316,41 @@ namespace Etesian { { return _toolName; } + const Configuration* EtesianEngine::getConfiguration () const + { return _configuration; } + + Configuration* EtesianEngine::getConfiguration () { 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 () { //cerr << "EtesianEngine::resetPlacement()" << endl; @@ -293,31 +395,46 @@ namespace Etesian { } - void EtesianEngine::place ( unsigned int slowMotion ) + void EtesianEngine::toColoquinte () { #if HAVE_COLOQUINTE cmess1 << " o Converting <" << getCell()->getName() << "> into Coloquinte." << endl; resetPlacement(); - Dots dots ( cmess2, " ", 80, 1000 ); - AllianceFramework* af = AllianceFramework::get(); + Dots dots ( cmess2, " ", 80, 1000 ); + AllianceFramework* af = AllianceFramework::get(); + DbU::Unit pitch = getPitch(); cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; getCell()->flattenNets( Cell::BuildRings ); // Coloquinte circuit description data-structures. size_t instancesNb = getCell()->getLeafInstanceOccurrences().getSize(); - vector idsToTransf ( instancesNb ); + vector idsToTransf ( instancesNb ); + vector instances ( instancesNb ); + vector< point > positions ( instancesNb ); + vector< point > orientations( instancesNb, point(1.0,1.0) ); - _circuit = new Coloquinte::circuit(); - _circuit->cells .resize( instancesNb ); - _circuit->hypernets.resize( getCell()->getNets().getSize() ); - - cmess1 << " - Converting Instances (Bookshelf nodes)" << endl; + cmess1 << " - Converting " << instancesNb << " instances" << endl; cout.flush(); - Coloquinte::cell_id cellId = 0; + Box topAb = getCell()->getAbutmentBox(); + + UpdateSession::open(); + forEach ( Occurrence, ioccurrence, getCell()->getNonLeafInstanceOccurrences() ) + { + Instance* instance = static_cast((*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() ) { Instance* instance = static_cast((*ioccurrence).getEntity()); @@ -327,32 +444,48 @@ namespace Etesian { instanceName.erase( 0, 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(); (*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( xsize, ysize ); + instances[instanceId].list_index = instanceId; + instances[instanceId].area = static_cast(xsize) * static_cast(ysize); + positions[instanceId] = point( 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(); - //cerr << instanceName << " " << (int)instance->getPlacementStatus().getCode() - // << " area:" << cellSize.cast().prod() << endl; - - _circuit->cells[cellId].name = instanceName; - _circuit->cells[cellId].sizes = cellSize; - _circuit->cells[cellId].area = cellSize.cast().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 ); - cmess1 << " - Converting Nets (Bookshelf nets)" << endl; + size_t netsNb = getCell()->getNets().getSize(); + cmess1 << " - Converting " << netsNb << " nets" << endl; + + vector nets ( netsNb ); + vector pins; unsigned int netId = 0; forEach ( Net*, inet, getCell()->getNets() ) @@ -369,32 +502,20 @@ namespace Etesian { if (af->isBLOCKAGE((*inet)->getName())) continue; dots.dot(); - //cerr << (*inet)->getName() << endl; + + nets[netId] = temporary_net( netId, 1.0 ); forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) { - //cerr << " " << (*irp)->getOccurrence().getCompactString() << endl; string insName = extractInstanceName( *irp ); Point offset = extractRpOffset ( *irp ); - - //cerr << " Master Cell: " << (*irp)->getOccurrence().getMasterCell() << endl; - //cerr << " Rebuilt instance name: " << insName << " " << offset << endl; + double xpin = offset.getX() / pitch; + double ypin = offset.getY() / pitch; auto iid = _cellsToIds.find( insName ); if (iid == _cellsToIds.end() ) { cerr << Error( "Unable to lookup instance <%s>.", insName.c_str() ) << endl; } else { - Coloquinte::cell_id cellId = (*iid).second; - 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 ); + pins.push_back( temporary_pin( point(xpin,ypin), (*iid).second, netId ) ); } } @@ -402,110 +523,186 @@ namespace Etesian { } dots.finish( Dots::Reset ); - _circuit->position_overlays.resize(1); - _circuit->position_overlays[0].x_pos = Coloquinte::circuit_vector( _cellsToIds.size() ); - _circuit->position_overlays[0].y_pos = Coloquinte::circuit_vector( _cellsToIds.size() ); + _surface = box( (int_t)(getCell()->getAbutmentBox().getXMin() / pitch) + , (int_t)(getCell()->getAbutmentBox().getXMax() / pitch) + , (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 ) { - 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(); +#endif // HAVE_COLOQUINTE + } - // if (not _circuit->cells[ipair.second].movable) { - // cerr << " Fixed cell @" << position.x() << "x" << position.y() << endl; - // } - } + void EtesianEngine::place ( unsigned int flags ) + { +#if HAVE_COLOQUINTE + if (flags & SlowMotion) getConfiguration()-> setFlags( SlowMotion ); + else getConfiguration()->unsetFlags( SlowMotion ); - // Temporarily force the circuit size. - // 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(); + toColoquinte(); cmess1 << " o Running Coloquinte." << endl; cmess1 << " - Computing initial placement..." << endl; 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++ ) { - _circuit->position_overlays[0] - = Coloquinte::solve_quadratic_model( *_circuit - , _circuit->position_overlays[0] - , _circuit->position_overlays[0] - ); + double sliceHeight = getSliceHeight() / getPitch(); + time_t startTime = time(NULL); + time_t timeDelta; + ostringstream label; - timeDelta = time(NULL) - startTime; - lowerBound = B2B_wirelength( *_circuit, _circuit->position_overlays[0] ); - cmess2 << " Iteration " << setw( 4) << (j+1) - << " Elapsed time:" << setw( 5) << timeDelta << "s" - << " Lower bound:" << setw(10) - << lowerBound << endl; + cmess2 << " o Initial wirelength " << get_HPWL_wirelength(_circuit, _placementLB) << "." << endl; + startMeasures(); - _updatePlacement( 0 ); - } - - float strength = 0.000001; - float strength_incr = 0.000002; + auto first_legalizer = get_rough_legalizer( _circuit, _placementLB, _surface); + first_legalizer.selfcheck(); - cmess1 << " - Optimizing placement..." << endl; + cmess1 << " o Simple legalization." << endl; + get_result( _circuit, _placementUB, first_legalizer); - _circuit->position_overlays.resize(2); - for ( int j = 0; j < 200; j++, strength = strength * 1.02 + strength_incr) { - _circuit->position_overlays[1] - = Coloquinte::legalize( *_circuit - , 1.0 - , _circuit->position_overlays[0] - , 1 - , false - ); - - 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; + timeDelta = time(NULL) - startTime; + cmess2 << " - Elapsed time:" << timeDelta + << " HPWL:" << get_HPWL_wirelength( _circuit, _placementUB ) + << "\n " + << "- Linear Disrupt.:" << get_mean_linear_disruption ( _circuit, _placementLB, _placementLB ) + << " Quad. Disrupt.:" << get_mean_quadratic_disruption( _circuit, _placementLB, _placementLB ) + << endl; + _placementLB = _placementUB; + _placementLB.selfcheck(); - _circuit->position_overlays[0] - = Coloquinte::solve_quadratic_model( *_circuit - , _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; + zero_orientations( _circuit, _placementLB ); + _updatePlacement( _placementUB ); - _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; igetLeafInstanceOccurrences() ) @@ -532,14 +776,26 @@ namespace Etesian { if (iid == _cellsToIds.end() ) { cerr << Error( "Unable to lookup instance <%s>.", instanceName.c_str() ) << endl; } else { - instancePosition.setX( _circuit->position_overlays[placementId].x_pos[(*iid).second] * DbU::fromLambda(5.0) ); - instancePosition.setY( _circuit->position_overlays[placementId].y_pos[(*iid).second] * DbU::fromLambda(5.0) ); + point position = placement.positions_[(*iid).second]; + + 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; // This is temporary as it's not trans-hierarchic: we ignore the posutions // of all the intermediary instances. - instance->setTransformation( instancePosition ); + instance->setTransformation( trans ); instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); } } @@ -568,7 +824,6 @@ namespace Etesian { Record* record = ToolEngine::_getRecord (); if (record) { - //record->add( getSlot( "_routingPlanes", &_routingPlanes ) ); record->add( getSlot( "_configuration", _configuration ) ); } return record; diff --git a/etesian/src/FeedCells.cpp b/etesian/src/FeedCells.cpp new file mode 100644 index 00000000..d6d0b371 --- /dev/null +++ b/etesian/src/FeedCells.cpp @@ -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 +#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(): <%s> 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(): <%s> 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::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. diff --git a/etesian/src/GraphicEtesianEngine.cpp b/etesian/src/GraphicEtesianEngine.cpp index 2c889b7f..bbb96e29 100644 --- a/etesian/src/GraphicEtesianEngine.cpp +++ b/etesian/src/GraphicEtesianEngine.cpp @@ -99,6 +99,7 @@ namespace Etesian { _viewer->clearToolInterrupt(); EtesianEngine* etesian = getForFramework( CreateEngine ); + etesian->getConfiguration()->setFlags( EtesianEngine::SlowMotion ); etesian->resetPlacement(); etesian->place(); } diff --git a/etesian/src/PyEtesian.cpp b/etesian/src/PyEtesian.cpp index c0143e6d..074ebe41 100644 --- a/etesian/src/PyEtesian.cpp +++ b/etesian/src/PyEtesian.cpp @@ -87,11 +87,7 @@ extern "C" { Py_INCREF( &PyTypeGraphicEtesianEngine ); PyModule_AddObject( module, "GraphicEtesianEngine", (PyObject*)&PyTypeGraphicEtesianEngine ); - //PyObject* dictionnary = PyModule_GetDict( module ); - //PyObject* constant; - - //LoadObjectConstant( dictionnary, KtBuildGlobalRouting, "KtBuildGlobalRouting" ); - //LoadObjectConstant( dictionnary, KtLoadGlobalRouting , "KtLoadGlobalRouting" ); + PyEtesianEngine_postModuleInit(); } diff --git a/etesian/src/PyEtesianEngine.cpp b/etesian/src/PyEtesianEngine.cpp index 9414e79d..d06e74ad 100644 --- a/etesian/src/PyEtesianEngine.cpp +++ b/etesian/src/PyEtesianEngine.cpp @@ -109,7 +109,7 @@ extern "C" { METHOD_HEAD("EtesianEngine.place()") unsigned int flags = 0; if (PyArg_ParseTuple(args,"I:EtesianEngine.place", &flags)) { - etesian->place(/*flags*/); + etesian->place( flags ); } else { PyErr_SetString(ConstructorError, "EtesianEngine.place(): Invalid number/bad type of parameter."); return NULL; @@ -137,24 +137,8 @@ extern "C" { , "Returns the Etesian engine attached to the Cell, None if there isnt't." } , { "create" , (PyCFunction)PyEtesianEngine_create , METH_VARARGS|METH_STATIC , "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 , "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 the associated hurricane object. The python object remains." } , {NULL, NULL, 0, NULL} /* sentinel */ @@ -178,6 +162,14 @@ extern "C" { DBoLinkCreateMethod(EtesianEngine) + extern void PyEtesianEngine_postModuleInit () + { + PyObject* constant; + + LoadObjectConstant(PyTypeEtesianEngine.tp_dict,EtesianEngine::SlowMotion,"SlowMotion"); + } + + #endif // Shared Library Code Part. } // extern "C". diff --git a/etesian/src/etesian/Configuration.h b/etesian/src/etesian/Configuration.h index 0d37320d..8fb0e20c 100644 --- a/etesian/src/etesian/Configuration.h +++ b/etesian/src/etesian/Configuration.h @@ -25,10 +25,7 @@ namespace Hurricane { class Cell; } -#include "crlcore/RoutingGauge.h" -namespace CRL { - class RoutingLayerGauge; -} +#include "crlcore/CellGauge.h" namespace Etesian { @@ -39,8 +36,7 @@ namespace Etesian { using Hurricane::Layer; using Hurricane::DbU; using Hurricane::Cell; - using CRL::RoutingGauge; - using CRL::RoutingLayerGauge; + using CRL::CellGauge; // ------------------------------------------------------------------- @@ -53,7 +49,10 @@ namespace Etesian { virtual ~Configuration (); virtual Configuration* clone () const = 0; // 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 Record* _getRecord () const = 0; virtual string _getString () const = 0; @@ -76,18 +75,22 @@ namespace Etesian { friend class Configuration; public: // Constructor & Destructor. - ConfigurationConcrete ( const RoutingGauge* rg=NULL ); + ConfigurationConcrete ( const CellGauge* cg=NULL ); virtual ~ConfigurationConcrete (); virtual ConfigurationConcrete* clone () const; // 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 Record* _getRecord () const; virtual string _getString () const; virtual string _getTypeName () const; protected: // Attributes. - RoutingGauge* _rg; + CellGauge* _cg; + unsigned int _flags; private: ConfigurationConcrete ( const ConfigurationConcrete& ); ConfigurationConcrete& operator= ( const ConfigurationConcrete& ); diff --git a/etesian/src/etesian/EtesianEngine.h b/etesian/src/etesian/EtesianEngine.h index be17f72c..77d59e79 100644 --- a/etesian/src/etesian/EtesianEngine.h +++ b/etesian/src/etesian/EtesianEngine.h @@ -19,31 +19,32 @@ #include #include +#include "Coloquinte/circuit.hxx" -//#include "coloquinte/circuit_graph.hxx" -namespace Coloquinte { - struct circuit; -} - +#include "hurricane/Timer.h" #include "hurricane/Name.h" namespace Hurricane { class Layer; class Net; class Cell; class CellWidget; + class Instance; } #include "crlcore/ToolEngine.h" #include "etesian/Configuration.h" +#include "etesian/FeedCells.h" namespace Etesian { + using Hurricane::Timer; using Hurricane::Name; using Hurricane::Layer; using Hurricane::Net; using Hurricane::Cell; using Hurricane::Record; + using Hurricane::Instance; // ------------------------------------------------------------------- @@ -51,21 +52,36 @@ namespace Etesian { class EtesianEngine : public CRL::ToolEngine { public: - enum Flag { NoPlacement=0x0001, FlatDesign=0x0002 }; + enum Flag { NoPlacement=0x0001 + , FlatDesign =0x0002 + , ForceUpdate=0x0004 + , SlowMotion =0x0008 + }; public: - static const Name& staticGetName (); - static EtesianEngine* create ( Cell* ); - static EtesianEngine* get ( const Cell* ); - public: - virtual Configuration* getConfiguration (); - virtual const Name& getName () const; - inline void setCellWidget ( Hurricane::CellWidget* ); - void resetPlacement (); - void place ( unsigned int slowMotion=0 ); - void _updatePlacement ( unsigned int placementId ); - virtual Record* _getRecord () const; - virtual std::string _getString () const; - virtual std::string _getTypeName () const; + static const Name& staticGetName (); + static EtesianEngine* create ( Cell* ); + static EtesianEngine* get ( const Cell* ); + public: + inline bool isSlowMotion () const; + virtual Configuration* getConfiguration (); + virtual const Configuration* getConfiguration () const; + virtual const Name& getName () const; + inline CellGauge* getCellGauge () const; + inline DbU::Unit getPitch () const; + inline DbU::Unit getSliceHeight () const; + inline const FeedCells& getFeedCells () 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: // Attributes. @@ -73,24 +89,40 @@ namespace Etesian { protected: Configuration* _configuration; unsigned int _flags; - Coloquinte::circuit* _circuit; + Timer _timer; + coloquinte::box _surface; + coloquinte::netlist _circuit; + coloquinte::gp::placement_t _placementLB; + coloquinte::gp::placement_t _placementUB; std::unordered_map _cellsToIds; + std::vector _idsToInsts; Hurricane::CellWidget* _cellWidget; + FeedCells _feedCells; protected: // Constructors & Destructors. - EtesianEngine ( Cell* ); - virtual ~EtesianEngine (); - virtual void _postCreate (); - virtual void _preDestroy (); + EtesianEngine ( Cell* ); + virtual ~EtesianEngine (); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + EtesianEngine ( const EtesianEngine& ); + EtesianEngine& operator= ( const EtesianEngine& ); private: - EtesianEngine ( const EtesianEngine& ); - EtesianEngine& operator= ( const EtesianEngine& ); + void _updatePlacement ( const coloquinte::gp::placement_t&, unsigned int flags=0 ); + void _progressReport1 ( time_t startTime, string label ) const; + void _progressReport2 ( time_t startTime, string label ) const; }; // 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. diff --git a/etesian/src/etesian/FeedCells.h b/etesian/src/etesian/FeedCells.h new file mode 100644 index 00000000..d99b3a4a --- /dev/null +++ b/etesian/src/etesian/FeedCells.h @@ -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 +#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 _feedCells; + mutable unsigned int _feedCount; + }; + + +// Inline Methods. + inline FeedCells::FeedCells ( EtesianEngine* etesian ) + : _etesian (etesian) + , _feedCells() + , _feedCount(0) + { } + + +} // Etesian namespace. + +#endif // ETESIAN_FEEDCELLS_H diff --git a/etesian/src/etesian/PyEtesianEngine.h b/etesian/src/etesian/PyEtesianEngine.h index 89f30378..19eeea3e 100644 --- a/etesian/src/etesian/PyEtesianEngine.h +++ b/etesian/src/etesian/PyEtesianEngine.h @@ -42,8 +42,9 @@ extern "C" { extern PyTypeObject PyTypeEtesianEngine; extern PyMethodDef PyEtesianEngine_Methods[]; - extern PyObject* PyEtesianEngine_Link ( Etesian::EtesianEngine* ); - extern void PyEtesianEngine_LinkPyType (); + extern PyObject* PyEtesianEngine_Link ( Etesian::EtesianEngine* ); + extern void PyEtesianEngine_LinkPyType (); + extern void PyEtesianEngine_postModuleInit (); #define IsPyEtesianEngine(v) ( (v)->ob_type == &PyTypeEtesianEngine ) diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index abcccd32..c305fad9 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -104,7 +104,8 @@ Cell::Cell(Library* library, const Name& name) _nextOfLibraryCellMap(NULL), _nextOfSymbolCellSet(NULL), _slaveEntityMap(), - _observers() + _observers(), + _flags(0) { if (!_library) throw Error("Can't create " + _TName("Cell") + " : null library"); @@ -193,6 +194,8 @@ void Cell::flattenNets(unsigned int flags) { UpdateSession::open(); + _flags |= FlattenedNets; + forEach ( Occurrence, ioccurrence, getHyperNetRootNetOccurrences() ) { Net* net = static_cast((*ioccurrence).getEntity()); diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index 53ce1478..b2d51eed 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -72,6 +72,8 @@ class Cell : public Entity { // Flags set for Observers. , CellAboutToChange = 0x0001 , CellChanged = 0x0002 + // Cell states + , FlattenedNets = 0x0001 }; public: typedef Entity Inherit; public: typedef map ExtensionSliceMap; @@ -180,6 +182,7 @@ class Cell : public Entity { private: Cell* _nextOfSymbolCellSet; private: SlaveEntityMap _slaveEntityMap; private: Observable _observers; + private: unsigned int _flags; // Constructors // ************ @@ -303,6 +306,7 @@ class Cell : public Entity { public: bool isFlattenLeaf() const {return _isFlattenLeaf;}; public: bool isLeaf() const; public: bool isPad() const {return _isPad;}; + public: bool isFlattenedNets() const {return _flags & FlattenedNets;}; // Updators // ******** diff --git a/hurricane/src/hurricane/hurricane/NetRoutingProperty.h b/hurricane/src/hurricane/hurricane/NetRoutingProperty.h index 7e1ccb90..c05f7a97 100644 --- a/hurricane/src/hurricane/hurricane/NetRoutingProperty.h +++ b/hurricane/src/hurricane/hurricane/NetRoutingProperty.h @@ -40,11 +40,13 @@ namespace Hurricane { public: enum State { Excluded = 0x0001 , Fixed = 0x0002 - , ManualGlobalRoute = 0x0004 - , AutomaticGlobalRoute = 0x0008 + , Unconnected = 0x0004 + , ManualGlobalRoute = 0x0008 + , AutomaticGlobalRoute = 0x0010 , MixedPreRoute = Fixed|ManualGlobalRoute }; public: + inline bool isUnconnected () const; inline bool isFixed () const; inline bool isManualGlobalRoute () const; inline bool isAutomaticGlobalRoute () const; @@ -67,6 +69,7 @@ namespace Hurricane { 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::isManualGlobalRoute () const { return _flags & ManualGlobalRoute; }; inline bool NetRoutingState::isAutomaticGlobalRoute () const { return _flags & AutomaticGlobalRoute; }; @@ -113,6 +116,7 @@ namespace Hurricane { class NetRoutingExtension { public: + static inline bool isUnconnected ( const Net* ); static inline bool isFixed ( const Net* ); static inline bool isManualGlobalRoute ( 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 ) { NetRoutingState* state = get( net ); diff --git a/hurricane/src/viewer/CellViewer.cpp b/hurricane/src/viewer/CellViewer.cpp index 99d49d00..22860116 100644 --- a/hurricane/src/viewer/CellViewer.cpp +++ b/hurricane/src/viewer/CellViewer.cpp @@ -502,6 +502,14 @@ namespace Hurricane { , QIcon(":/images/python-logo-v3.png") ); 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 ) ); } + 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 () { ScriptWidget::runScript( this, getCell() ); } diff --git a/hurricane/src/viewer/hurricane/viewer/CellViewer.h b/hurricane/src/viewer/hurricane/viewer/CellViewer.h index 2efca82d..7c35d3c3 100644 --- a/hurricane/src/viewer/hurricane/viewer/CellViewer.h +++ b/hurricane/src/viewer/hurricane/viewer/CellViewer.h @@ -141,6 +141,7 @@ namespace Hurricane { void raiseToolInterrupt (); void clearToolInterrupt (); void runScriptWidget (); + void runStressScript (); inline void emitCellAboutToChange (); inline void emitCellChanged (); signals: diff --git a/kite/src/BuildPowerRails.cpp b/kite/src/BuildPowerRails.cpp index 12e81db2..ae608040 100644 --- a/kite/src/BuildPowerRails.cpp +++ b/kite/src/BuildPowerRails.cpp @@ -381,12 +381,14 @@ namespace { } } - ltrace(300) << " Check againts top clocks ck:" << _ck->getName() - << " cki:" << _cki->getName() << " cko:" << _cko->getName() << endl; + ltrace(300) << " Check againts top clocks ck:" << ((_ck) ? _ck->getName() : "NULL") + << " cki:" << ((_cki) ? _cki->getName() : "NULL") + << " cko:" << ((_cko) ? _cko->getName() : "NULL") + << endl; - if (upNet->getName() == _ck->getName() ) return _ck; - if (upNet->getName() == _cki->getName()) return _cki; - if (upNet->getName() == _cko->getName()) return _cko; + if ( _ck and (upNet->getName() == _ck->getName() ) ) return _ck; + if ( _cki and (upNet->getName() == _cki->getName()) ) return _cki; + if ( _cko and (upNet->getName() == _cko->getName()) ) return _cko; return NULL; } diff --git a/kite/src/BuildPreRouteds.cpp b/kite/src/BuildPreRouteds.cpp index 7323e7b6..6c20f70b 100644 --- a/kite/src/BuildPreRouteds.cpp +++ b/kite/src/BuildPreRouteds.cpp @@ -164,9 +164,12 @@ namespace Kite { } if (isFixed or isPreRouted or (rpCount < 2)) { + NetRoutingState* state = getRoutingState( *inet, Katabatic::KbCreate ); state->unsetFlags( NetRoutingState::AutomaticGlobalRoute ); state->setFlags ( NetRoutingState::ManualGlobalRoute ); + if (rpCount < 2) + state->setFlags ( NetRoutingState::Unconnected ); if (isFixed) { cmess2 << " - <" << (*inet)->getName() << "> is fixed." << endl; diff --git a/kite/src/KiteEngine.cpp b/kite/src/KiteEngine.cpp index f4ae9824..7bc873a8 100644 --- a/kite/src/KiteEngine.cpp +++ b/kite/src/KiteEngine.cpp @@ -278,7 +278,7 @@ namespace Kite { if (not _knik) { unsigned int flags = Cell::WarnOnUnplacedInstances; flags |= (mode & KtBuildGlobalRouting) ? Cell::BuildRings : 0; - cell->flattenNets( flags ); + if (not cell->isFlattenedNets()) cell->flattenNets( flags ); // Test signals from . //DebugSession::addToTrace( getCell(), "core.snx_inst.a2_x2_8_sig" ); diff --git a/knik/src/KnikEngine.cpp b/knik/src/KnikEngine.cpp index b7c35730..21baee21 100644 --- a/knik/src/KnikEngine.cpp +++ b/knik/src/KnikEngine.cpp @@ -228,7 +228,10 @@ void KnikEngine::initGlobalRouting( const map& excludedNets ) forEach ( Net*, inet, getCell()->getNets() ) { 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; }