From c5d8077730477be4aa6973851b4734020c158aea Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 9 Mar 2010 15:20:13 +0000 Subject: [PATCH] * ./hurricane/src/hviewer, ./coriolis/src/crlcore, ./coriolis/src/knik, ./coriolis/src/katabatic, ./coriolis/src/kite, ./coriolis/src/equinox, ./coriolis/src/solstice, ./coriolis/src/ispd: - SVN MOVE: Source tree simplification & uniformisation. Now all tools are at the same level, directly under the root of the repository. No more "coriolis/src". --- crlcore/CMakeLists.txt | 28 + crlcore/cmake_modules/CMakeLists.txt | 4 + crlcore/cmake_modules/FindCORIOLIS.cmake | 47 + crlcore/cmake_modules/FindLEFDEF.cmake | 119 ++ crlcore/cmake_modules/FindOPENACCESS.cmake | 188 +++ crlcore/etc/CMakeLists.txt | 6 + crlcore/etc/display.xml | 250 ++++ crlcore/etc/environment.alliance.xml | 50 + crlcore/etc/technology.cmos065.s2r.xml | 29 + crlcore/etc/technology.fake.s2r.xml | 29 + crlcore/etc/technology.hcmos9.s2r.xml | 29 + crlcore/etc/technology.symbolic.xml | 328 +++++ crlcore/src/CMakeLists.txt | 4 + crlcore/src/ccore/AllianceFramework.cpp | 498 +++++++ crlcore/src/ccore/AllianceLibrary.cpp | 118 ++ crlcore/src/ccore/Banner.cpp | 532 +++++++ crlcore/src/ccore/CConfig.h.cmake | 1 + crlcore/src/ccore/CConfig.h.in | 101 ++ crlcore/src/ccore/CMakeLists.txt | 237 +++ crlcore/src/ccore/COptions.cpp | 597 ++++++++ crlcore/src/ccore/Catalog.cpp | 307 ++++ crlcore/src/ccore/CellGauge.cpp | 141 ++ crlcore/src/ccore/CifDriver.cpp | 18 + crlcore/src/ccore/Environment.cpp | 716 +++++++++ crlcore/src/ccore/GdsDriver.cpp | 18 + crlcore/src/ccore/GraphicToolEngine.cpp | 77 + crlcore/src/ccore/GraphicsParser.cpp | 204 +++ crlcore/src/ccore/Memory.cpp | 229 +++ crlcore/src/ccore/ParsersDrivers.cpp | 388 +++++ crlcore/src/ccore/RealTechnologyParser.cpp | 225 +++ crlcore/src/ccore/RoutingGauge.cpp | 254 ++++ crlcore/src/ccore/RoutingLayerGauge.cpp | 306 ++++ crlcore/src/ccore/SearchPath.cpp | 83 ++ .../src/ccore/SymbolicTechnologyParser.cpp | 581 ++++++++ crlcore/src/ccore/ToolEngine.cpp | 313 ++++ crlcore/src/ccore/Utilities.cpp | 237 +++ crlcore/src/ccore/XmlParser.cpp | 193 +++ crlcore/src/ccore/agds/Agds.h | 17 + crlcore/src/ccore/agds/AgdsDriver.cpp | 111 ++ crlcore/src/ccore/alliance/CMakeLists.txt | 1 + crlcore/src/ccore/alliance/ap/Ap.h | 63 + crlcore/src/ccore/alliance/ap/ApDriver.cpp | 450 ++++++ crlcore/src/ccore/alliance/ap/ApParser.cpp | 826 +++++++++++ crlcore/src/ccore/alliance/vst/Vst.h | 63 + crlcore/src/ccore/alliance/vst/VstDriver.cpp | 674 +++++++++ .../ccore/alliance/vst/VstParserGrammar.hpp | 333 +++++ .../ccore/alliance/vst/VstParserGrammar.yy | 1310 +++++++++++++++++ .../ccore/alliance/vst/VstParserScanner.ll | 337 +++++ crlcore/src/ccore/bookshelf/Bookshelf.h | 67 + .../src/ccore/bookshelf/BookshelfDriver.cpp | 295 ++++ .../src/ccore/bookshelf/BookshelfParser.cpp | 1077 ++++++++++++++ crlcore/src/ccore/cif/Cif.h | 17 + crlcore/src/ccore/cif/CifDriver.cpp | 109 ++ crlcore/src/ccore/crlcore/AllianceFramework.h | 144 ++ crlcore/src/ccore/crlcore/AllianceLibrary.h | 121 ++ crlcore/src/ccore/crlcore/Banner.h | 235 +++ crlcore/src/ccore/crlcore/CConfig.h | 1 + crlcore/src/ccore/crlcore/CLayerConnexity.h | 192 +++ crlcore/src/ccore/crlcore/COptions.h | 188 +++ crlcore/src/ccore/crlcore/Catalog.h | 236 +++ crlcore/src/ccore/crlcore/CellGauge.h | 118 ++ crlcore/src/ccore/crlcore/CellPath.h | 140 ++ crlcore/src/ccore/crlcore/CellPaths.h | 84 ++ crlcore/src/ccore/crlcore/CifDriver.h | 41 + crlcore/src/ccore/crlcore/Environment.h | 144 ++ crlcore/src/ccore/crlcore/GdsDriver.h | 42 + crlcore/src/ccore/crlcore/GraphicToolEngine.h | 124 ++ crlcore/src/ccore/crlcore/GraphicsParser.h | 73 + crlcore/src/ccore/crlcore/Hierarchy.h | 53 + crlcore/src/ccore/crlcore/Ioc.h | 10 + crlcore/src/ccore/crlcore/LefDefExtension.h | 97 ++ crlcore/src/ccore/crlcore/Memory.h | 88 ++ crlcore/src/ccore/crlcore/NetExtension.h | 85 ++ crlcore/src/ccore/crlcore/ParsersDrivers.h | 226 +++ .../src/ccore/crlcore/RealTechnologyParser.h | 80 + crlcore/src/ccore/crlcore/RoutingGauge.h | 112 ++ crlcore/src/ccore/crlcore/RoutingLayerGauge.h | 232 +++ crlcore/src/ccore/crlcore/SearchPath.h | 81 + .../ccore/crlcore/SymbolicTechnologyParser.h | 119 ++ crlcore/src/ccore/crlcore/TimingEvent.h | 73 + crlcore/src/ccore/crlcore/ToolBox.h | 68 + crlcore/src/ccore/crlcore/ToolEngine.h | 106 ++ crlcore/src/ccore/crlcore/ToolEngines.h | 66 + crlcore/src/ccore/crlcore/Utilities.h | 339 +++++ crlcore/src/ccore/crlcore/XmlParser.h | 88 ++ crlcore/src/ccore/ioc/IocParserGrammar.yy | 201 +++ crlcore/src/ccore/ioc/IocParserScanner.ll | 35 + crlcore/src/ccore/lefdef/DefDriver.cpp | 673 +++++++++ crlcore/src/ccore/lefdef/DefParser.cpp | 712 +++++++++ crlcore/src/ccore/lefdef/LefDef.h | 87 ++ crlcore/src/ccore/lefdef/LefDefExtension.cpp | 169 +++ crlcore/src/ccore/lefdef/LefParser.cpp | 729 +++++++++ crlcore/src/ccore/liberty/CellPath.cpp | 335 +++++ .../src/ccore/liberty/LibertyParserGrammar.yy | 633 ++++++++ .../src/ccore/liberty/LibertyParserScanner.ll | 175 +++ .../src/ccore/liberty/LibertyTechnology.cpp | 204 +++ crlcore/src/ccore/liberty/LibertyTechnology.h | 129 ++ crlcore/src/ccore/liberty/LuTable.cpp | 304 ++++ crlcore/src/ccore/liberty/LuTable.h | 90 ++ crlcore/src/ccore/liberty/LuTableTemplate.cpp | 316 ++++ crlcore/src/ccore/liberty/LuTableTemplate.h | 167 +++ crlcore/src/ccore/liberty/TimingEvent.cpp | 111 ++ .../openaccess/COpenAccessBridgeLayer.cpp | 15 + .../ccore/openaccess/COpenAccessBridgeLayer.h | 19 + crlcore/src/ccore/openaccess/OAWrapper.cpp | 637 ++++++++ crlcore/src/ccore/openaccess/OAWrapper.h | 42 + .../ccore/openaccess/OpenAccessWrapper.cpp | 392 +++++ .../src/ccore/openaccess/OpenAccessWrapper.h | 25 + crlcore/src/ccore/properties/NetExtension.cpp | 115 ++ crlcore/src/ccore/spice/Spice.cpp | 72 + crlcore/src/ccore/spice/Spice.h | 38 + crlcore/src/ccore/spice/SpiceCommons.h | 23 + crlcore/src/ccore/spice/SpiceDriver.cpp | 147 ++ crlcore/src/ccore/spice/SpiceDriver.h | 71 + crlcore/src/ccore/spice/SpiceParser.cpp | 619 ++++++++ crlcore/src/ccore/spice/SpiceParser.h | 110 ++ .../ccore/toolbox/HyperNetPortOccurrences.cpp | 553 +++++++ .../ccore/toolbox/HyperNetPortOccurrences.h | 48 + crlcore/src/ccore/toolbox/RoutingPads.cpp | 269 ++++ crlcore/src/ccore/toolbox/ToolBox.cpp | 543 +++++++ .../ccore/toolbox/UniqueCellOccurrences.cpp | 300 ++++ crlcore/src/cyclop/CMakeLists.txt | 30 + crlcore/src/cyclop/COpenCellDialog.cpp | 198 +++ crlcore/src/cyclop/COpenCellDialog.h | 88 ++ crlcore/src/cyclop/Cyclop.cpp | 143 ++ crlcore/src/cyclop/Cyclop.h | 104 ++ crlcore/src/cyclop/CyclopMain.cpp | 225 +++ crlcore/src/cyclop/DemoGo.cpp | 94 ++ crlcore/src/cyclop/DemoGo.h | 88 ++ crlcore/src/fonts/UnknownBoldNormal14.h | 1059 +++++++++++++ crlcore/src/x2y/CMakeLists.txt | 19 + crlcore/src/x2y/x2y.cpp | 78 + 132 files changed, 28275 insertions(+) create mode 100644 crlcore/CMakeLists.txt create mode 100644 crlcore/cmake_modules/CMakeLists.txt create mode 100644 crlcore/cmake_modules/FindCORIOLIS.cmake create mode 100644 crlcore/cmake_modules/FindLEFDEF.cmake create mode 100644 crlcore/cmake_modules/FindOPENACCESS.cmake create mode 100644 crlcore/etc/CMakeLists.txt create mode 100644 crlcore/etc/display.xml create mode 100644 crlcore/etc/environment.alliance.xml create mode 100644 crlcore/etc/technology.cmos065.s2r.xml create mode 100644 crlcore/etc/technology.fake.s2r.xml create mode 100644 crlcore/etc/technology.hcmos9.s2r.xml create mode 100644 crlcore/etc/technology.symbolic.xml create mode 100644 crlcore/src/CMakeLists.txt create mode 100644 crlcore/src/ccore/AllianceFramework.cpp create mode 100644 crlcore/src/ccore/AllianceLibrary.cpp create mode 100644 crlcore/src/ccore/Banner.cpp create mode 100644 crlcore/src/ccore/CConfig.h.cmake create mode 100644 crlcore/src/ccore/CConfig.h.in create mode 100644 crlcore/src/ccore/CMakeLists.txt create mode 100644 crlcore/src/ccore/COptions.cpp create mode 100644 crlcore/src/ccore/Catalog.cpp create mode 100644 crlcore/src/ccore/CellGauge.cpp create mode 100644 crlcore/src/ccore/CifDriver.cpp create mode 100644 crlcore/src/ccore/Environment.cpp create mode 100644 crlcore/src/ccore/GdsDriver.cpp create mode 100644 crlcore/src/ccore/GraphicToolEngine.cpp create mode 100644 crlcore/src/ccore/GraphicsParser.cpp create mode 100644 crlcore/src/ccore/Memory.cpp create mode 100644 crlcore/src/ccore/ParsersDrivers.cpp create mode 100644 crlcore/src/ccore/RealTechnologyParser.cpp create mode 100644 crlcore/src/ccore/RoutingGauge.cpp create mode 100644 crlcore/src/ccore/RoutingLayerGauge.cpp create mode 100644 crlcore/src/ccore/SearchPath.cpp create mode 100644 crlcore/src/ccore/SymbolicTechnologyParser.cpp create mode 100644 crlcore/src/ccore/ToolEngine.cpp create mode 100644 crlcore/src/ccore/Utilities.cpp create mode 100644 crlcore/src/ccore/XmlParser.cpp create mode 100644 crlcore/src/ccore/agds/Agds.h create mode 100644 crlcore/src/ccore/agds/AgdsDriver.cpp create mode 100644 crlcore/src/ccore/alliance/CMakeLists.txt create mode 100644 crlcore/src/ccore/alliance/ap/Ap.h create mode 100644 crlcore/src/ccore/alliance/ap/ApDriver.cpp create mode 100644 crlcore/src/ccore/alliance/ap/ApParser.cpp create mode 100644 crlcore/src/ccore/alliance/vst/Vst.h create mode 100644 crlcore/src/ccore/alliance/vst/VstDriver.cpp create mode 100644 crlcore/src/ccore/alliance/vst/VstParserGrammar.hpp create mode 100644 crlcore/src/ccore/alliance/vst/VstParserGrammar.yy create mode 100644 crlcore/src/ccore/alliance/vst/VstParserScanner.ll create mode 100644 crlcore/src/ccore/bookshelf/Bookshelf.h create mode 100644 crlcore/src/ccore/bookshelf/BookshelfDriver.cpp create mode 100644 crlcore/src/ccore/bookshelf/BookshelfParser.cpp create mode 100644 crlcore/src/ccore/cif/Cif.h create mode 100644 crlcore/src/ccore/cif/CifDriver.cpp create mode 100644 crlcore/src/ccore/crlcore/AllianceFramework.h create mode 100644 crlcore/src/ccore/crlcore/AllianceLibrary.h create mode 100644 crlcore/src/ccore/crlcore/Banner.h create mode 100644 crlcore/src/ccore/crlcore/CConfig.h create mode 100644 crlcore/src/ccore/crlcore/CLayerConnexity.h create mode 100644 crlcore/src/ccore/crlcore/COptions.h create mode 100644 crlcore/src/ccore/crlcore/Catalog.h create mode 100644 crlcore/src/ccore/crlcore/CellGauge.h create mode 100644 crlcore/src/ccore/crlcore/CellPath.h create mode 100644 crlcore/src/ccore/crlcore/CellPaths.h create mode 100644 crlcore/src/ccore/crlcore/CifDriver.h create mode 100644 crlcore/src/ccore/crlcore/Environment.h create mode 100644 crlcore/src/ccore/crlcore/GdsDriver.h create mode 100644 crlcore/src/ccore/crlcore/GraphicToolEngine.h create mode 100644 crlcore/src/ccore/crlcore/GraphicsParser.h create mode 100644 crlcore/src/ccore/crlcore/Hierarchy.h create mode 100644 crlcore/src/ccore/crlcore/Ioc.h create mode 100644 crlcore/src/ccore/crlcore/LefDefExtension.h create mode 100644 crlcore/src/ccore/crlcore/Memory.h create mode 100644 crlcore/src/ccore/crlcore/NetExtension.h create mode 100644 crlcore/src/ccore/crlcore/ParsersDrivers.h create mode 100644 crlcore/src/ccore/crlcore/RealTechnologyParser.h create mode 100644 crlcore/src/ccore/crlcore/RoutingGauge.h create mode 100644 crlcore/src/ccore/crlcore/RoutingLayerGauge.h create mode 100644 crlcore/src/ccore/crlcore/SearchPath.h create mode 100644 crlcore/src/ccore/crlcore/SymbolicTechnologyParser.h create mode 100644 crlcore/src/ccore/crlcore/TimingEvent.h create mode 100644 crlcore/src/ccore/crlcore/ToolBox.h create mode 100644 crlcore/src/ccore/crlcore/ToolEngine.h create mode 100644 crlcore/src/ccore/crlcore/ToolEngines.h create mode 100644 crlcore/src/ccore/crlcore/Utilities.h create mode 100644 crlcore/src/ccore/crlcore/XmlParser.h create mode 100644 crlcore/src/ccore/ioc/IocParserGrammar.yy create mode 100644 crlcore/src/ccore/ioc/IocParserScanner.ll create mode 100644 crlcore/src/ccore/lefdef/DefDriver.cpp create mode 100644 crlcore/src/ccore/lefdef/DefParser.cpp create mode 100644 crlcore/src/ccore/lefdef/LefDef.h create mode 100644 crlcore/src/ccore/lefdef/LefDefExtension.cpp create mode 100644 crlcore/src/ccore/lefdef/LefParser.cpp create mode 100644 crlcore/src/ccore/liberty/CellPath.cpp create mode 100644 crlcore/src/ccore/liberty/LibertyParserGrammar.yy create mode 100644 crlcore/src/ccore/liberty/LibertyParserScanner.ll create mode 100644 crlcore/src/ccore/liberty/LibertyTechnology.cpp create mode 100644 crlcore/src/ccore/liberty/LibertyTechnology.h create mode 100644 crlcore/src/ccore/liberty/LuTable.cpp create mode 100644 crlcore/src/ccore/liberty/LuTable.h create mode 100644 crlcore/src/ccore/liberty/LuTableTemplate.cpp create mode 100644 crlcore/src/ccore/liberty/LuTableTemplate.h create mode 100644 crlcore/src/ccore/liberty/TimingEvent.cpp create mode 100644 crlcore/src/ccore/openaccess/COpenAccessBridgeLayer.cpp create mode 100644 crlcore/src/ccore/openaccess/COpenAccessBridgeLayer.h create mode 100644 crlcore/src/ccore/openaccess/OAWrapper.cpp create mode 100644 crlcore/src/ccore/openaccess/OAWrapper.h create mode 100644 crlcore/src/ccore/openaccess/OpenAccessWrapper.cpp create mode 100644 crlcore/src/ccore/openaccess/OpenAccessWrapper.h create mode 100644 crlcore/src/ccore/properties/NetExtension.cpp create mode 100644 crlcore/src/ccore/spice/Spice.cpp create mode 100644 crlcore/src/ccore/spice/Spice.h create mode 100644 crlcore/src/ccore/spice/SpiceCommons.h create mode 100644 crlcore/src/ccore/spice/SpiceDriver.cpp create mode 100644 crlcore/src/ccore/spice/SpiceDriver.h create mode 100644 crlcore/src/ccore/spice/SpiceParser.cpp create mode 100644 crlcore/src/ccore/spice/SpiceParser.h create mode 100644 crlcore/src/ccore/toolbox/HyperNetPortOccurrences.cpp create mode 100644 crlcore/src/ccore/toolbox/HyperNetPortOccurrences.h create mode 100644 crlcore/src/ccore/toolbox/RoutingPads.cpp create mode 100644 crlcore/src/ccore/toolbox/ToolBox.cpp create mode 100644 crlcore/src/ccore/toolbox/UniqueCellOccurrences.cpp create mode 100644 crlcore/src/cyclop/CMakeLists.txt create mode 100644 crlcore/src/cyclop/COpenCellDialog.cpp create mode 100644 crlcore/src/cyclop/COpenCellDialog.h create mode 100644 crlcore/src/cyclop/Cyclop.cpp create mode 100644 crlcore/src/cyclop/Cyclop.h create mode 100644 crlcore/src/cyclop/CyclopMain.cpp create mode 100644 crlcore/src/cyclop/DemoGo.cpp create mode 100644 crlcore/src/cyclop/DemoGo.h create mode 100644 crlcore/src/fonts/UnknownBoldNormal14.h create mode 100644 crlcore/src/x2y/CMakeLists.txt create mode 100644 crlcore/src/x2y/x2y.cpp diff --git a/crlcore/CMakeLists.txt b/crlcore/CMakeLists.txt new file mode 100644 index 00000000..2e9c7d34 --- /dev/null +++ b/crlcore/CMakeLists.txt @@ -0,0 +1,28 @@ +PROJECT(CRLCORE) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.4.0) + +IF(COMMAND CMAKE_POLICY) + CMAKE_POLICY(SET CMP0003 NEW) +ENDIF(COMMAND CMAKE_POLICY) + +SET(CMAKE_MODULE_PATH "${CRLCORE_SOURCE_DIR}/cmake_modules/" "$ENV{HURRICANE_TOP}/share/cmake_modules/" "$ENV{IO_TOP}/share/cmake_modules/" ) + + +SET(QT_USE_QTXML "true") +#SET(QT_USE_QTOPENGL "true") + +FIND_PACKAGE(Boost 1.33.1 COMPONENTS program_options REQUIRED) +FIND_PACKAGE(Qt4 REQUIRED) # find and setup Qt4 for this project +FIND_PACKAGE(BISON REQUIRED) +FIND_PACKAGE(FLEX REQUIRED) +FIND_PACKAGE(HURRICANE REQUIRED) +FIND_PACKAGE(IO REQUIRED) +FIND_PACKAGE(OPENACCESS) +FIND_PACKAGE(LEFDEF) + +SET_LIB_LINK_MODE() + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(etc) +ADD_SUBDIRECTORY(cmake_modules) diff --git a/crlcore/cmake_modules/CMakeLists.txt b/crlcore/cmake_modules/CMakeLists.txt new file mode 100644 index 00000000..17d7251d --- /dev/null +++ b/crlcore/cmake_modules/CMakeLists.txt @@ -0,0 +1,4 @@ +install ( FILES FindCORIOLIS.cmake + FindOPENACCESS.cmake + FindLEFDEF.cmake + DESTINATION /share/cmake_modules ) diff --git a/crlcore/cmake_modules/FindCORIOLIS.cmake b/crlcore/cmake_modules/FindCORIOLIS.cmake new file mode 100644 index 00000000..305286a8 --- /dev/null +++ b/crlcore/cmake_modules/FindCORIOLIS.cmake @@ -0,0 +1,47 @@ +# - Find the Coriolis includes and libraries. +# The following variables are set if Coriolis is found. If CORIOLIS is not +# found, CORIOLIS_FOUND is set to false. +# CORIOLIS_FOUND - True when the Coriolis include directory is found. +# CORIOLIS_INCLUDE_DIR - the path to where the Coriolis include files are. +# CORIOLIS_LIBRARIES - The path to where the Coriolis library files are. + + +SET(CORIOLIS_INCLUDE_PATH_DESCRIPTION "directory containing the Coriolis include files. E.g /usr/local/include/coriolis or /asim/coriolis/include/coriolis") + +SET(CORIOLIS_DIR_MESSAGE "Set the CORIOLIS_INCLUDE_DIR cmake cache entry to the ${CORIOLIS_INCLUDE_PATH_DESCRIPTION}") + +# don't even bother under WIN32 +IF(UNIX) + + SET(CORIOLIS_DIR_SEARCH $ENV{CORIOLIS_TOP} $ENV{HURRICANE_TOP}) + # + # Look for an installation. + # + FIND_PATH(CRLCORE_INCLUDE_PATH NAMES crlcore/ToolEngine.h PATHS + # Look in other places. + ${CORIOLIS_DIR_SEARCH} + PATH_SUFFIXES include/coriolis + # Help the user find it if we cannot. + DOC "The ${CORIOLIS_INCLUDE_PATH_DESCRIPTION}" + ) + + FIND_LIBRARY(CRLCORE_LIBRARY_PATH + NAMES crlcore + PATHS ${CORIOLIS_DIR_SEARCH} + PATH_SUFFIXES lib + # Help the user find it if we cannot. + DOC "The ${CORIOLIS_INCLUDE_PATH_DESCRIPTION}" + ) + + FIND_LIBRARY(CRLCORE_STATIC_LIBRARY_PATH + NAMES crlcore-static + PATHS ${CORIOLIS_DIR_SEARCH} + PATH_SUFFIXES lib + # Help the user find it if we cannot. + DOC "The ${CORIOLIS_INCLUDE_PATH_DESCRIPTION}" + ) + + SET_LIBRARIES_PATH(CORIOLIS CRLCORE) + HURRICANE_CHECK_LIBRARIES(CORIOLIS) + +ENDIF(UNIX) diff --git a/crlcore/cmake_modules/FindLEFDEF.cmake b/crlcore/cmake_modules/FindLEFDEF.cmake new file mode 100644 index 00000000..a4e04f63 --- /dev/null +++ b/crlcore/cmake_modules/FindLEFDEF.cmake @@ -0,0 +1,119 @@ +# - Find the LEF/DEF includes and libraries. +# The following variables are set if LEF/DEF is found. If LEF/DEF is not +# found, LEFDEF_FOUND is set to false. +# LEFDEF_FOUND - True when LEF/DEF is found. +# LEFDEF_INCLUDE_DIR - the path to where the LEF/DEF include files are. +# LEFDEF_LIBRARIES - The path to where the LEF/DEF library files are. +# +# The DEF C API library: LEFDEF_CDEF_LIBRARY +# LEFDEF_CDEF_LIBRARY_RELEASE +# LEFDEF_CDEF_LIBRARY_DEBUG +# +# The DEF C API library (zlib) : LEFDEF_ZCDEF_LIBRARY +# LEFDEF_ZCDEF_LIBRARY_RELEASE +# LEFDEF_ZCDEF_LIBRARY_DEBUG +# +# The DEF C++ API library: LEFDEF_DEF_LIBRARY +# LEFDEF_DEF_LIBRARY_RELEASE +# LEFDEF_DEF_LIBRARY_DEBUG +# +# The DEF C++ API library (zlib) : LEFDEF_ZDEF_LIBRARY +# LEFDEF_ZDEF_LIBRARY_RELEASE +# LEFDEF_ZDEF_LIBRARY_DEBUG +# +# The LEF C API library: LEFDEF_CLEF_LIBRARY +# LEFDEF_CLEF_LIBRARY_RELEASE +# LEFDEF_CLEF_LIBRARY_DEBUG +# +# The LEF C API library (zlib) : LEFDEF_ZCLEF_LIBRARY +# LEFDEF_ZCLEF_LIBRARY_RELEASE +# LEFDEF_ZCLEF_LIBRARY_DEBUG +# +# The LEF C++ API library: LEFDEF_LEF_LIBRARY +# LEFDEF_LEF_LIBRARY_RELEASE +# LEFDEF_LEF_LIBRARY_DEBUG +# +# The LEF C++ API library (zlib) : LEFDEF_ZLEF_LIBRARY +# LEFDEF_ZLEF_LIBRARY_RELEASE +# LEFDEF_ZLEF_LIBRARY_DEBUG + + +macro ( _find_lefdef_lib varname libname ) + find_library ( LEFDEF_${varname}_LIBRARY_RELEASE NAMES ${libname} PATHS ${LEFDEF_LIBRARY_DIR} ) + find_library ( LEFDEF_${varname}_LIBRARY_DEBUG NAMES ${libname}_Debug PATHS ${LEFDEF_LIBRARY_DIR} ) + + if ( LEFDEF_${varname}_LIBRARY_RELEASE AND NOT LEFDEF_${varname}_LIBRARY_DEBUG ) + set ( LEFDEF_${varname}_LIBRARY_DEBUG ${LEFDEF_${varname}_LIBRARY_RELEASE} + CACHE STRING "Path to a library" FORCE ) + endif ( LEFDEF_${varname}_LIBRARY_RELEASE AND NOT LEFDEF_${varname}_LIBRARY_DEBUG ) + + if ( LEFDEF_${varname}_LIBRARY_DEBUG AND NOT LEFDEF_${varname}_LIBRARY_RELEASE ) + set ( LEFDEF_${varname}_LIBRARY_RELEASE LEFDEF_${varname}_LIBRARY_DEBUG + CACHE STRING "Path to a library" FORCE ) + endif ( LEFDEF_${varname}_LIBRARY_DEBUG AND NOT LEFDEF_${varname}_LIBRARY_RELEASE ) + + if ( LEFDEF_${varname}_LIBRARY_RELEASE ) + list ( APPEND LEFDEF_LIBRARIES "optimized" ${LEFDEF_${varname}_LIBRARY_RELEASE} + "debug" ${LEFDEF_${varname}_LIBRARY_DEBUG} ) + set ( LEFDEF_${varname}_LIBRARY_FOUND 1 ) + mark_as_advanced ( LEFDEF_${varname}_LIBRARY_RELEASE + LEFDEF_${varname}_LIBRARY_DEBUG ) + else ( LEFDEF_${varname}_LIBRARY_RELEASE ) + set ( LEFDEF_FOUND "NO" ) + endif ( LEFDEF_${varname}_LIBRARY_RELEASE ) +endmacro ( _find_lefdef_lib ) + + +set ( LEFDEF_INCLUDE_DIR_DESCRIPTION "directory containing the LEF/DEF include files. E.g /opt/lefdef-5.6/include" ) +set ( LEFDEF_LIBRARY_DIR_DESCRIPTION "directory containing the LEF/DEF library files. E.g /opt/lefdef-5.6/lib" ) +set ( LEFDEF_DIR_MESSAGE "Set the LEFDEF_INCLUDE_DIR cmake cache entry to the ${LEFDEF_INCLUDE_DIR_DESCRIPTION}" ) + +# Don't even bother under Win32 +if ( UNIX ) + set ( LEFDEF_FOUND "YES" ) + set ( LEFDEF_SEARCH_PATH $ENV{LEFDEF_TOP} + "/opt/lefdef-5.6" + "/opt/lefdef-5.7" + "/opt/lefdef") + + set ( LEFDEF_LIBRARIES "" ) + set ( LEFDEF_LIBRARY_SEARCH_PATH "" ) + foreach ( element ${LEFDEF_SEARCH_PATH} ) + list ( APPEND LEFDEF_LIBRARY_SEARCH_PATH "${element}/lib" ) + endforeach ( element ${LEFDEF_SEARCH_PATH} ) + + find_path ( LEFDEF_INCLUDE_DIR NAMES "defiDefs.h" + PATHS ${LEFDEF_SEARCH_PATH} + PATH_SUFFIXES "include" + DOC "The ${LEFDEF_INCLUDE_DIR_DESCRIPTION}" ) + + find_path ( LEFDEF_LIBRARY_DIR NAMES "libdef.a" "libdef_Debug.a" + PATHS ${LEFDEF_LIBRARY_SEARCH_PATH} + DOC "The ${LEFDEF_LIBRARY_DIR_DESCRIPTION}" ) + + if ( LEFDEF_INCLUDE_DIR AND LEFDEF_LIBRARY_DIR ) + _find_lefdef_lib ( "CDEF" "cdef" ) + _find_lefdef_lib ( "ZCDEF" "cdefzlib" ) + _find_lefdef_lib ( "DEF" "def" ) + _find_lefdef_lib ( "ZDEF" "defzlib" ) + _find_lefdef_lib ( "CLEF" "clef" ) + _find_lefdef_lib ( "ZCLEF" "clefzlib" ) + _find_lefdef_lib ( "LEF" "lef" ) + _find_lefdef_lib ( "ZLEF" "lefzlib" ) + else ( LEFDEF_INCLUDE_DIR AND LEFDEF_LIBRARY_DIR ) + set ( LEFDEF_FOUND "NO" ) + endif ( LEFDEF_INCLUDE_DIR AND LEFDEF_LIBRARY_DIR ) + + mark_as_advanced ( LEFDEF_INCLUDE_DIR LEFDEF_LIBRARY_DIR LEFDEF_LIBRARIES ) + + if ( LEFDEF_FOUND ) + add_definitions ( -DHAVE_LEFDEF ) + if ( NOT LEFDEF_FIND_QUIETLY ) + message ( STATUS "Found LEF/DEF" ) + endif ( NOT LEFDEF_FIND_QUIETLY ) + else ( LEFDEF_FOUND ) + if ( LEFDEF_FIND_REQUIRED ) + message ( STATUS "LEF/DEF libraries and/or includes NOT found!" ) + endif ( LEFDEF_FIND_REQUIRED ) + endif ( LEFDEF_FOUND ) +endif ( UNIX ) diff --git a/crlcore/cmake_modules/FindOPENACCESS.cmake b/crlcore/cmake_modules/FindOPENACCESS.cmake new file mode 100644 index 00000000..f0413732 --- /dev/null +++ b/crlcore/cmake_modules/FindOPENACCESS.cmake @@ -0,0 +1,188 @@ +# - Find the OpenAccess includes and libraries. +# The following variables are set if OpenAccess is found. If OpenAccess is not +# found, OA_FOUND is set to false. +# OA_FOUND - True when OpenAccess is found. +# OA_INCLUDE_DIR - the path to where the OpenAccess include files are. +# OA_LIBRARIES - The path to where the OpenAccess library files are. +# +# The OpenAccess oaCommon library: OA_COMMON_LIBRARY +# OA_COMMON_LIBRARY_RELEASE +# OA_COMMON_DEBUG +# +# The OpenAccess oaBase library: OA_BASE_LIBRARY +# OA_BASE_LIBRARY_RELEASE +# OA_BASE_DEBUG +# +# The OpenAccess oaDM library: OA_DM_LIBRARY +# OA_DM_LIBRARY_RELEASE +# OA_DM_DEBUG +# +# The OpenAccess oaTech library: OA_TECH_LIBRARY +# OA_TECH_LIBRARY_RELEASE +# OA_TECH_DEBUG +# +# The OpenAccess oaDesign library: OA_DESIGN_LIBRARY +# OA_DESIGN_LIBRARY_RELEASE +# OA_DESIGN_DEBUG +# +# The OpenAccess oaWafer library: OA_WAFER_LIBRARY +# OA_WAFER_LIBRARY_RELEASE +# OA_WAFER_DEBUG +# +# The OpenAccess oaPlugin library: OA_PLUGIN_LIBRARY +# OA_PLUGIN_LIBRARY_RELEASE +# OA_PLUGIN_DEBUG + + +SET(OA_INCLUDE_PATH_DESCRIPTION "directory containing the OpenAccess include files. E.g /usr/local/include") + +SET(OA_DIR_MESSAGE "Set the OA_INCLUDE_DIR cmake cache entry to the ${OA_INCLUDE_PATH_DESCRIPTION}") + +# don't even bother under WIN32 +IF(UNIX) + + SET(OA_DIR_SEARCH $ENV{OPENACCESS_TOP}) + IF(OA_DIR_SEARCH) + FILE(TO_CMAKE_PATH ${OA_DIR_SEARCH} OA_DIR_SEARCH) + ENDIF(OA_DIR_SEARCH) + + # + # Look for an installation. + # + FIND_PATH(OA_INCLUDE_PATH NAMES oa/oaDesign.h PATHS + # Look in other places. + ${OA_DIR_SEARCH} + PATH_SUFFIXES include + # Help the user find it if we cannot. + DOC "The ${OA_INCLUDE_PATH_DESCRIPTION}" + ) + + + FIND_PROGRAM(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin ) + IF(CMAKE_UNAME) + EXEC_PROGRAM(uname ARGS -a OUTPUT_VARIABLE SYSTEM_TYPE) + ELSE(CMAKE_UNAME) + MESSAGE(FATAL_ERROR, "uname command was not found") + ENDIF(CMAKE_UNAME) + + IF($SYSTEM_TYPE MATCHES ".*x86_64.*") + SET(OA_LIBRARY_DIR ${OA_DIR_SEARCH}/lib/linux_rhel30_64/dbg) + ELSEIF($SYSTEM_TYPE MATCHES ".*i686.*") + SET(OA_LIBRARY_DIR ${OA_DIR_SEARCH}/lib/linux_rhel21_32/dbg) + ELSE($SYSTEM_TYPE MATCHES ".*x86_64.*") + SET(OA_LIBRARY_DIR "unknown") + ENDIF($SYSTEM_TYPE MATCHES ".*x86_64.*") + + # Set OA_OACOMMON_LIBRARY + FIND_LIBRARY(OA_OACOMMON_LIBRARY_RELEASE NAMES oaCommon PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH ) + FIND_LIBRARY(OA_OACOMMON_LIBRARY_DEBUG NAMES oaCommonD PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH) + + # Set OA_OABASE_LIBRARY + FIND_LIBRARY(OA_OABASE_LIBRARY_RELEASE NAMES oaBase PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH ) + FIND_LIBRARY(OA_OABASE_LIBRARY_DEBUG NAMES oaBaseD PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH) + + # Set OA_OADM_LIBRARY + FIND_LIBRARY(OA_OADM_LIBRARY_RELEASE NAMES oaDM PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH ) + FIND_LIBRARY(OA_OADM_LIBRARY_DEBUG NAMES oaDMD PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH) + + # Set OA_OATECH_LIBRARY + FIND_LIBRARY(OA_OATECH_LIBRARY_RELEASE NAMES oaTech PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH ) + FIND_LIBRARY(OA_OATECH_LIBRARY_DEBUG NAMES oaTechD PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH) + + # Set OA_OADESIGN_LIBRARY + FIND_LIBRARY(OA_OADESIGN_LIBRARY_RELEASE NAMES oaDesign PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH ) + FIND_LIBRARY(OA_OADESIGN_LIBRARY_DEBUG NAMES oaDesignD PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH) + + # Set OA_OAWAFER_LIBRARY + FIND_LIBRARY(OA_OAWAFER_LIBRARY_RELEASE NAMES oaWafer PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH ) + FIND_LIBRARY(OA_OAWAFER_LIBRARY_DEBUG NAMES oaWaferD PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH) + + # Set OA_OAPLUGIN_LIBRARY + FIND_LIBRARY(OA_OAPLUGIN_LIBRARY_RELEASE NAMES oaPlugIn PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH ) + FIND_LIBRARY(OA_OAPLUGIN_LIBRARY_DEBUG NAMES oaPlugInD PATHS ${OA_LIBRARY_DIR} NO_DEFAULT_PATH) + + ############################################ + # + # Check the existence of the libraries. + # + ############################################ + + MACRO (_OA_ADJUST_LIB_VARS basename) + # if only the release version was found, set the debug variable also to the release version + IF (OA_${basename}_LIBRARY_RELEASE AND NOT OA_${basename}_LIBRARY_DEBUG) + SET(OA_${basename}_LIBRARY_DEBUG ${OA_${basename}_LIBRARY_RELEASE}) + SET(OA_${basename}_LIBRARY ${OA_${basename}_LIBRARY_RELEASE}) + SET(OA_${basename}_LIBRARIES ${OA_${basename}_LIBRARY_RELEASE}) + ENDIF (OA_${basename}_LIBRARY_RELEASE AND NOT OA_${basename}_LIBRARY_DEBUG) + + # if only the debug version was found, set the release variable also to the debug version + IF (OA_${basename}_LIBRARY_DEBUG AND NOT OA_${basename}_LIBRARY_RELEASE) + SET(OA_${basename}_LIBRARY_RELEASE ${OA_${basename}_LIBRARY_DEBUG}) + SET(OA_${basename}_LIBRARY ${OA_${basename}_LIBRARY_DEBUG}) + SET(OA_${basename}_LIBRARIES ${OA_${basename}_LIBRARY_DEBUG}) + ENDIF (OA_${basename}_LIBRARY_DEBUG AND NOT OA_${basename}_LIBRARY_RELEASE) + IF (OA_${basename}_LIBRARY_DEBUG AND OA_${basename}_LIBRARY_RELEASE) + # if the generator supports configuration types then set + # optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value + IF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) + SET(OA_${basename}_LIBRARY optimized ${OA_${basename}_LIBRARY_RELEASE} debug ${OA_${basename}_LIBRARY_DEBUG}) + ELSE(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) + # if there are no configuration types and CMAKE_BUILD_TYPE has no value + # then just use the release libraries + SET(OA_${basename}_LIBRARY ${OA_${basename}_LIBRARY_RELEASE} ) + ENDIF(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) + SET(OA_${basename}_LIBRARIES optimized ${OA_${basename}_LIBRARY_RELEASE} debug ${OA_${basename}_LIBRARY_DEBUG}) + ENDIF (OA_${basename}_LIBRARY_DEBUG AND OA_${basename}_LIBRARY_RELEASE) + + SET(OA_${basename}_LIBRARY ${OA_${basename}_LIBRARY} CACHE FILEPATH "The OpenAccess ${basename} library") + + IF (OA_${basename}_LIBRARY) + SET(OA_${basename}_FOUND 1) + ENDIF (OA_${basename}_LIBRARY) + + # Make variables changeble to the advanced user + MARK_AS_ADVANCED(OA_${basename}_LIBRARY OA_${basename}_LIBRARY_RELEASE OA_${basename}_LIBRARY_DEBUG OA_${basename}_INCLUDE_DIR) + ENDMACRO (_OA_ADJUST_LIB_VARS) + + _OA_ADJUST_LIB_VARS(OACOMMON) + _OA_ADJUST_LIB_VARS(OABASE) + _OA_ADJUST_LIB_VARS(OADM) + _OA_ADJUST_LIB_VARS(OATECH) + _OA_ADJUST_LIB_VARS(OADESIGN) + _OA_ADJUST_LIB_VARS(OAWAFER) + _OA_ADJUST_LIB_VARS(OAPLUGIN) + + + IF (OA_INCLUDE_PATH AND OA_OACOMMON_LIBRARY AND OA_OABASE_LIBRARY + AND OA_OADM_LIBRARY AND OA_OATECH_LIBRARY AND OA_OADESIGN_LIBRARY + AND OA_OAWAFER_LIBRARY AND OA_OAPLUGIN_LIBRARY) + SET(OA_FOUND "YES") + IF (NOT OA_FIND_QUIETLY) + MESSAGE(STATUS "Found OpenAccess") + ENDIF( NOT OA_FIND_QUIETLY) + SET(OA_INCLUDE_DIR + ${OA_INCLUDE_PATH} + ) + SET(OA_LIBRARIES + ${OA_OACOMMON_LIBRARY} + ${OA_OABASE_LIBRARY} + ${OA_OADM_LIBRARY} + ${OA_OATECH_LIBRARY} + ${OA_OADESIGN_LIBRARY} + ${OA_OAWAFER_LIBRARY} + ${OA_OAPLUGIN_LIBRARY} + ) + ELSE (OA_INCLUDE_PATH AND OA_LIBRARY_PATH) + SET(OA_FOUND "NO") + IF(OA_FIND_REQUIRED) + MESSAGE( FATAL_ERROR "OpenAccess libraries, includes NOT found!") + ENDIF( OA_FIND_REQUIRED) + ENDIF (OA_INCLUDE_PATH AND OA_OACOMMON_LIBRARY AND OA_OABASE_LIBRARY + AND OA_OADM_LIBRARY AND OA_OATECH_LIBRARY AND OA_OADESIGN_LIBRARY + AND OA_OAWAFER_LIBRARY AND OA_OAPLUGIN_LIBRARY) + + IF(OA_FOUND) + ADD_DEFINITIONS(-DHAVE_OPENACCESS) + ENDIF(OA_FOUND) + +ENDIF(UNIX) diff --git a/crlcore/etc/CMakeLists.txt b/crlcore/etc/CMakeLists.txt new file mode 100644 index 00000000..721d286b --- /dev/null +++ b/crlcore/etc/CMakeLists.txt @@ -0,0 +1,6 @@ + install ( FILES environment.alliance.xml DESTINATION /share/etc ) + install ( FILES technology.symbolic.xml DESTINATION /share/etc ) + install ( FILES technology.hcmos9.s2r.xml DESTINATION /share/etc ) + install ( FILES technology.cmos065.s2r.xml DESTINATION /share/etc ) + install ( FILES technology.fake.s2r.xml DESTINATION /share/etc ) + install ( FILES display.xml DESTINATION /share/etc ) diff --git a/crlcore/etc/display.xml b/crlcore/etc/display.xml new file mode 100644 index 00000000..0bbef9a0 --- /dev/null +++ b/crlcore/etc/display.xml @@ -0,0 +1,250 @@ + + + + + true + Alliance Coriolis Look - black background + 3.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Alliance.Coriolis [black] + Alliance Coriolis Look - white background + 0.8 + + + + + + + + + + + + + + + + Alliance Standard Look - black background + 3.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Alliance.Classic [black] + Alliance Standard Look - white background + 3.0 + + + + + + + + + + + + + + + + Alliance.Coriolis [black] + Ispd Global Route Look - black background + 3.0 + + + + + + + + + + + + Alliance.Coriolis [black] + Useful for debugging layout - black background + 3.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + Layout Design + Useful for debugging layout - white background + 3.0 + + + + + + + + + + + + diff --git a/crlcore/etc/environment.alliance.xml b/crlcore/etc/environment.alliance.xml new file mode 100644 index 00000000..bcc062f7 --- /dev/null +++ b/crlcore/etc/environment.alliance.xml @@ -0,0 +1,50 @@ + + + + + + ${CORIOLIS_TOP}/share/etc/technology.symbolic.xml + + + ${CORIOLIS_TOP}/share/etc/technology.hcmos9.s2r.xml + + + ${CORIOLIS_TOP}/share/etc/cmos.lef + + + ${CORIOLIS_TOP}/share/etc/display.xml + + + + CATAL + + . + + + ${CELL_TOP}/cells/sxlib + ${CELL_TOP}/cells/dp_sxlib + ${CELL_TOP}/cells/ramlib + ${CELL_TOP}/cells/romlib + ${CELL_TOP}/cells/rflib + ${CELL_TOP}/cells/rf2lib + ${CELL_TOP}/cells/pxlib + ${CORIOLIS_TOP}/share/cells/stratus2sxlib + + + + 100 + + vst + ap + + + vst + ap + + + + vdd + vss + ^ck$ + + diff --git a/crlcore/etc/technology.cmos065.s2r.xml b/crlcore/etc/technology.cmos065.s2r.xml new file mode 100644 index 00000000..553df8e1 --- /dev/null +++ b/crlcore/etc/technology.cmos065.s2r.xml @@ -0,0 +1,29 @@ + + + + cmos065 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crlcore/etc/technology.fake.s2r.xml b/crlcore/etc/technology.fake.s2r.xml new file mode 100644 index 00000000..e3d2308d --- /dev/null +++ b/crlcore/etc/technology.fake.s2r.xml @@ -0,0 +1,29 @@ + + + + fake + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crlcore/etc/technology.hcmos9.s2r.xml b/crlcore/etc/technology.hcmos9.s2r.xml new file mode 100644 index 00000000..0a38882e --- /dev/null +++ b/crlcore/etc/technology.hcmos9.s2r.xml @@ -0,0 +1,29 @@ + + + + hcmos9 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crlcore/etc/technology.symbolic.xml b/crlcore/etc/technology.symbolic.xml new file mode 100644 index 00000000..92c0bd70 --- /dev/null +++ b/crlcore/etc/technology.symbolic.xml @@ -0,0 +1,328 @@ + + + Alliance + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crlcore/src/CMakeLists.txt b/crlcore/src/CMakeLists.txt new file mode 100644 index 00000000..af026ef9 --- /dev/null +++ b/crlcore/src/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(fonts) +add_subdirectory(ccore) +add_subdirectory(cyclop) +add_subdirectory(x2y) diff --git a/crlcore/src/ccore/AllianceFramework.cpp b/crlcore/src/ccore/AllianceFramework.cpp new file mode 100644 index 00000000..b3bca90a --- /dev/null +++ b/crlcore/src/ccore/AllianceFramework.cpp @@ -0,0 +1,498 @@ + +// -*- C++ -*- + +#include "hurricane/Warning.h" +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" +#include "hurricane/Library.h" +#include "hurricane/viewer/Graphics.h" + +#include "crlcore/Utilities.h" +#include "crlcore/GraphicsParser.h" +#include "crlcore/SymbolicTechnologyParser.h" +#include "crlcore/RealTechnologyParser.h" +#include "crlcore/CellGauge.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/RoutingLayerGauge.h" +#include "crlcore/AllianceFramework.h" + + +namespace CRL { + + + using Hurricane::Warning; + using Hurricane::tab; + using Hurricane::Graphics; + + + AllianceFramework* AllianceFramework::_singleton = NULL; + const Name AllianceFramework::_parentLibraryName = "AllianceFramework"; + + + AllianceFramework::AllianceFramework () + : _environment() + , _parsers() + , _drivers() + , _catalog() + , _parentLibrary(NULL) + , _routingGauges() + { + DataBase* db = DataBase::getDB (); + if ( !db ) + db = DataBase::create (); + + _environment.loadFromShell (); + _environment.loadFromXml (); + + string userEnvironment = Environment::getEnv ( "HOME", "" ); + _environment.loadFromXml ( userEnvironment+"/.environment.alliance.xml", false ); + + SymbolicTechnologyParser::load ( db, _environment.getSYMBOLIC_TECHNOLOGY() ); + RealTechnologyParser::load ( db, _environment.getREAL_TECHNOLOGY() ); + GraphicsParser::load ( _environment.getDISPLAY() ); + + if ( !_environment.getDisplayStyle().empty() ) + Graphics::setStyle ( _environment.getDisplayStyle() ); + + bool hasCatalog; + SearchPath& LIBRARIES = _environment.getLIBRARIES (); + Library* rootLibrary = db->getRootLibrary (); + + cmess2 << " o Creating Alliance Framework root library." << endl; + if ( !rootLibrary ) + rootLibrary = Library::create ( db, "RootLibrary" ); + + _parentLibrary = rootLibrary->getLibrary ( _parentLibraryName ); + if ( !_parentLibrary ) + _parentLibrary = Library::create ( rootLibrary, _parentLibraryName ); + + cmess2 << " o Loading libraries (working first)." << endl; + for ( unsigned i=0 ; igetTechnology(); + + RoutingGauge* sxlibRg = RoutingGauge::create ( "sxlib" ); + sxlibRg->addLayerGauge ( RoutingLayerGauge::create( technology->getLayer("METAL1") + , Constant::Vertical + , Constant::PinOnly + , 0 // Depth (?). + , 0 // Density. + , DbU::lambda(0) // Offset. + , DbU::lambda(5) // Pitch. + , DbU::lambda(2) // Wire width. + , DbU::lambda(3) // Via width. + ) ); + sxlibRg->addLayerGauge ( RoutingLayerGauge::create( technology->getLayer("METAL2") + , Constant::Horizontal + , Constant::Default + , 1 // Depth (?). + , 7.7 // Density. + , DbU::lambda(0) // Offset. + , DbU::lambda(5) // Pitch. + , DbU::lambda(2) // Wire width. + , DbU::lambda(3) // Via width. + ) ); + sxlibRg->addLayerGauge ( RoutingLayerGauge::create( technology->getLayer("METAL3") + , Constant::Vertical + , Constant::Default + , 2 // Depth (?). + , 0 // Density. + , DbU::lambda(0) // Offset. + , DbU::lambda(5) // Pitch. + , DbU::lambda(2) // Wire width. + , DbU::lambda(3) // Via width. + ) ); + sxlibRg->addLayerGauge ( RoutingLayerGauge::create( technology->getLayer("METAL4") + , Constant::Horizontal + , Constant::Default + , 3 // Depth (?). + , 0 // Density. + , DbU::lambda(0) // Offset. + , DbU::lambda(5) // Pitch. + , DbU::lambda(2) // Wire width. + , DbU::lambda(3) // Via width. + ) ); + sxlibRg->addLayerGauge ( RoutingLayerGauge::create( technology->getLayer("METAL5") + , Constant::Vertical + , Constant::Default + , 4 // Depth (?). + , 0 // Density. + , DbU::lambda(0) // Offset. + , DbU::lambda(5) // Pitch. + , DbU::lambda(2) // Wire width. + , DbU::lambda(3) // Via width. + ) ); + addRoutingGauge ( sxlibRg ); + + CellGauge* sxlibCg = CellGauge::create ( "sxlib" + , "metal2" // pinLayerName. + , DbU::lambda( 5.0) // pitch. + , DbU::lambda(50.0) // sliceHeight. + , DbU::lambda( 5.0) // sliceStep. + ); + addCellGauge ( sxlibCg ); + } + + + AllianceFramework::~AllianceFramework () + { + for ( size_t i=0 ; i<_libraries.size() ; i++ ) + delete _libraries[i]; + + while ( !_routingGauges.empty() ) { + _routingGauges.begin()->second->destroy(); + _routingGauges.erase ( _routingGauges.begin() ); + } + + while ( !_cellGauges.empty() ) { + _cellGauges.begin()->second->destroy(); + _cellGauges.erase ( _cellGauges.begin() ); + } + } + + + AllianceFramework* AllianceFramework::create () + { + if ( !_singleton ) + _singleton = new AllianceFramework (); + + return _singleton; + } + + + AllianceFramework* AllianceFramework::get () + { + return create (); + } + + + void AllianceFramework::destroy () + { + delete this; + } + + + string AllianceFramework::getPrint () const + { + return _environment.getPrint (); + } + + + AllianceLibrary* AllianceFramework::getAllianceLibrary ( const Name &path , bool &flag ) + { + string spath = getString ( path ); + size_t slash = spath.rfind ( '/' ); + string sname = spath.substr ( (slash!=string::npos)?slash+1:0 ); + + AllianceLibrary* library = new AllianceLibrary ( path, Library::create(getParentLibrary(),sname) ); + string catalog = spath + "/" + _environment.getCATALOG(); + + flag = false; + if ( _catalog.loadFromFile(catalog,library->getLibrary()) ) flag = true; + + ParserFormatSlot& parser = _parsers.getParserSlot ( spath, Catalog::State::Physical, _environment ); + + if ( !parser.loadByLib() ) return library; + + size_t base = spath.find_last_of ( '/' ); + if ( base == spath.npos ) return library; + + string file = spath.substr(base+1,spath.size()-base); + + // Load the whole library. + if ( ! _readLocate(file,Catalog::State::State::Logical,true) ) return library; + + // Call the parser function. + (parser.getParsLib())( _environment.getLIBRARIES().getSelected() , library->getLibrary() , _catalog ); + + return library; + } + + + Cell* AllianceFramework::getCell ( const string& name, unsigned int mode, unsigned int depth ) + { + bool createCell = false; + Catalog::State* state = _catalog.getState ( name ); + ParserFormatSlot* parser; + + // The cell is not even in the Catalog : add an entry. + if ( state == NULL ) state = _catalog.getState ( name, true ); + + if ( state->isFlattenLeaf() ) depth = 0; + state->setDepth ( depth ); + + // Do not try to load. + if ( mode & Catalog::State::InMemory ) return state->getCell(); + + unsigned int loadMode; + for ( int i=0 ; i<2 ; i++ ) { + // Check is the view is requested for loading or already loaded. + switch ( i ) { + case 0: loadMode = mode & Catalog::State::Logical; break; + case 1: loadMode = mode & Catalog::State::Physical; break; + } + if ( loadMode == 0 ) continue; + if ( state->getFlags(loadMode) != 0 ) continue; + + // Transmit all flags except thoses related to views. + loadMode |= (mode & (!Catalog::State::Views)); + + parser = & ( _parsers.getParserSlot ( name, loadMode, _environment ) ); + + // Try to open cell file (file extention is supplied by the parser). + if ( !_readLocate(name,loadMode) ) continue; + + if ( state->getCell() == NULL ) { + state->setCell ( Cell::create ( _libraries[ _environment.getLIBRARIES().getIndex() ]->getLibrary() , name ) ); + state->getCell ()->put ( CatalogProperty::create(state) ); + state->getCell ()->setFlattenLeaf ( false ); + createCell = true; + } + + try { + // Call the parser function. + (parser->getParsCell())( _environment.getLIBRARIES().getSelected() , state->getCell() ); + } catch ( ... ) { + if ( createCell ) + state->getCell()->destroy(); + throw; + } + } + + // At least one view must have been loaded. + if ( state->getFlags(Catalog::State::Views) != 0 ) return state->getCell(); + + // Delete the empty cell. + if ( state->getCell() ) state->getCell()->destroy (); + _catalog.deleteState ( name ); + + return NULL; + } + + + Cell* AllianceFramework::createCell ( const string& name ) + { + Catalog::State* state = _catalog.getState ( name ); + + // The cell is not in the CATAL : add an entry. + if ( state == NULL ) state = _catalog.getState ( name, true ); + + if ( !state->getCell() ) { + state->setPhysical ( true ); + state->setLogical ( true ); + state->setDepth ( 1 ); + + state->setCell ( Cell::create ( _libraries[0]->getLibrary() , name ) ); + state->getCell ()->put ( CatalogProperty::create(state) ); + state->getCell ()->setFlattenLeaf ( false ); + } + + return state->getCell (); + } + + + void AllianceFramework::saveCell ( Cell* cell , unsigned int mode ) + { + if ( !cell ) return; + + string name = getString(cell->getName()); + DriverSlot* driver; + unsigned int saveMode; + unsigned int savedViews = 0; + + for ( int i=0 ; i<2 ; i++ ) { + // Check is the view is requested for saving or already saved. + switch ( i ) { + case 0: saveMode = mode & Catalog::State::Logical; break; + case 1: saveMode = mode & Catalog::State::Physical; break; + } + if ( saveMode == 0 ) continue; + if ( ( savedViews & saveMode ) != 0 ) continue; + + // Transmit all flags except thoses related to views. + saveMode |= (mode & (!Catalog::State::Views)); + + driver = & ( _drivers.getDriverSlot ( name, saveMode, _environment ) ); + + // Try to open cell file (file extention is supplied by the parser). + if ( !_writeLocate(name,saveMode,false) ) continue; + + // Call the driver function. + (driver->getDrivCell())( _environment.getLIBRARIES().getSelected(), cell, savedViews ); + } + } + + + Library* AllianceFramework::getLibrary ( unsigned index ) + { + if ( index >= _libraries.size() ) + return NULL; + + return _libraries[ index ]->getLibrary(); + } + + + unsigned int AllianceFramework::loadLibraryCells ( Library *library ) + { + cmess2 << " " << tab++ << "+ Library: " << getString(library->getName()) << endl; + + map* states = _catalog.getStates (); + map::iterator istate = states->begin (); + + unsigned int count = 0; + for ( ; istate != states->end() ; istate++ ) { + if ( istate->second->getLibrary() == library ) { + getCell ( getString(istate->first), Catalog::State::Views ); + count++; + } + } + tab--; + + return count; + } + + + unsigned int AllianceFramework::loadLibraryCells ( const Name& name ) + { + for ( size_t i=0 ; i<_libraries.size() ; i++ ) { + string spath = getString ( _libraries[i]->getPath() ); + size_t slash = spath.rfind ('/'); + Name libraryName = spath.substr ( (slash!=string::npos)?slash+1:0 ); + if ( libraryName == name ) + return loadLibraryCells ( _libraries[i]->getLibrary() ); + } + + return 0; + } + + + bool AllianceFramework::_readLocate ( const string& file, unsigned int mode, bool isLib ) + { + string name; + + SearchPath& LIBRARIES = _environment.getLIBRARIES (); + ParserFormatSlot& format = _parsers.getParserSlot ( file, mode, _environment ); + + if ( isLib ) { + // Try to open using the library parsers. + for ( format.lbegin() ; !format.lend() ; format++ ) { + name = file + "." + getString(format.getExt()); + + LIBRARIES.locate ( name ); + if ( LIBRARIES.hasSelected() ) return true; + } + } else { + // Try to open using the cell parsers. + for ( format.cbegin() ; !format.cend() ; format++ ) { + name = file + "." + getString(format.getExt()); + + LIBRARIES.locate ( name ); + if ( LIBRARIES.hasSelected() ) return true; + } + } + + return false; + } + + + bool AllianceFramework::_writeLocate ( const string& file, unsigned int mode, bool isLib ) + { + SearchPath& LIBRARIES = _environment.getLIBRARIES (); + DriverSlot& format = _drivers.getDriverSlot ( file, mode, _environment ); + string name; + + if ( isLib ) { + if ( !format.getDrivLib() ) return false; + + // Try to open using the library driver. + name = file + "." + getString(format.getExtLib()); + + LIBRARIES.locate ( name, ios::out|ios::trunc, 0, 1 ); + if ( LIBRARIES.hasSelected() ) return true; + } else { + if ( !format.getDrivCell() ) return false; + + // Try to open using the cell driver. + name = file + "." + getString(format.getExtCell()); + + LIBRARIES.locate ( name, ios::out|ios::trunc, 0, 1 ); + if ( LIBRARIES.hasSelected() ) return true; + } + return false; + } + + + RoutingGauge* AllianceFramework::getRoutingGauge ( const Name& name ) + { + if ( name.isEmpty() ) return _defaultRoutingGauge; + + map::iterator igauge = _routingGauges.find ( name ); + if ( igauge != _routingGauges.end() ) + return igauge->second; + + return NULL; + } + + + void AllianceFramework::addRoutingGauge ( RoutingGauge* gauge ) + { + if ( !gauge ) { + cerr << Warning("AllianceFramework::addRoutingGauge(): NULL gauge argument.") << endl; + return; + } + + if ( getRoutingGauge(gauge->getName()) ) { + cerr << Warning("AllianceFramework::addRoutingGauge(): gauge %s already exists." + ,getString(gauge->getName()).c_str()) + << endl; + return; + } + + _routingGauges [ gauge->getName() ] = gauge; + _defaultRoutingGauge = gauge; + } + + + CellGauge* AllianceFramework::getCellGauge ( const Name& name ) + { + if ( name.isEmpty() ) return _defaultCellGauge; + + map::iterator igauge = _cellGauges.find ( name ); + if ( igauge != _cellGauges.end() ) + return igauge->second; + + return NULL; + } + + + void AllianceFramework::addCellGauge ( CellGauge* gauge ) + { + if ( !gauge ) { + cerr << Warning("AllianceFramework::addCellGauge(): NULL gauge argument.") << endl; + return; + } + + if ( getCellGauge(gauge->getName()) ) { + cerr << Warning("AllianceFramework::addCellGauge(): gauge %s already exists." + ,getString(gauge->getName()).c_str()) + << endl; + return; + } + + _cellGauges [ gauge->getName() ] = gauge; + _defaultCellGauge = gauge; + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/AllianceLibrary.cpp b/crlcore/src/ccore/AllianceLibrary.cpp new file mode 100644 index 00000000..2e468d3f --- /dev/null +++ b/crlcore/src/ccore/AllianceLibrary.cpp @@ -0,0 +1,118 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Rémy Escassut | +// | E-mail : Remy.Escassut@silvaco.com | +// | =============================================================== | +// | C++ Header : "./AllianceLibrary.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +# include "hurricane/Library.h" + +# include "crlcore/Utilities.h" +# include "crlcore/AllianceLibrary.h" + + + + +namespace CRL { + + +// ------------------------------------------------------------------- +// Class : "AllianceDirectory". + + AllianceLibrary::AllianceLibrary () + : _path("") + , _library(NULL) + { + } + + + AllianceLibrary::AllianceLibrary ( const Name& path, Library* library ) + : _path(path) + , _library(library) + { + if ( _path.isEmpty() ) + throw ( Error("Can't create "+_TName("AllianceLibrary")+" : empty path") ); + } + + + AllianceLibrary& AllianceLibrary::operator= ( const AllianceLibrary& d ) + { + _path = d._path; + _library = d._library; + return *this; + } + + + AllianceLibrary& AllianceLibrary::operator= ( const string& path ) + { + _path = path; + _library = NULL; + return *this; + } + + + string AllianceLibrary::_getString () const + { + return ( "<" + _TName("AllianceLibrary") + " " + getString(_library->getName()) + ">" ); + } + + + Record* AllianceLibrary::_getRecord() const + { + Record* record = new Record ( getString(this) ); + record->add ( getSlot("Path" ,&_path ) ); + record->add ( getSlot("Library", _library) ); + return ( record ); + } + + + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/Banner.cpp b/crlcore/src/ccore/Banner.cpp new file mode 100644 index 00000000..434de5f3 --- /dev/null +++ b/crlcore/src/ccore/Banner.cpp @@ -0,0 +1,532 @@ + + +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== + + +// -*- C++ -*- +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./Banner.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + +# include +# include +# include + +# include + +# include "crlcore/Banner.h" + + +namespace { + + + using std::make_pair; + using std::cerr; + using std::endl; + using std::setw; + + + const char* badChar = + "BannerFont::operator[](): Font \"%s\" doesn't has character \'%c\'.\n"; + const char* unevenCharWidth = + "BannerFont::BigChar::BigChar():\n" + " Character '%c' has an uneven width.\n" + " (line %d has a different width)\n\n"; + const char* nullCharLine = + "BannerFont::BigChar::BigChar():\n" + " Character '%c' has an unitialized line.\n" + " (line %d has NULL pointer)\n"; + const char* badHeight = + "BannerFont::addChar():\n" + " Character '%c' has not the same height as others in font \"%s\".\n" + " (font character height := %d)\n"; + const char* dupChar = + "BannerFont::addChar(): Attempt to redefine character \'%c\' in font \"%s\".\n"; + const char* badBannerWidth = + "Banner::_ReDraw() :\n\n" + " Banner \"%s\" doesnt't fit in screen width (%d characters).\n"; + + +# include "UnknownBoldNormal14.h" + + +} // End of anonymous namespace. + + +namespace CRL { + + + BannerFont::FontMap BannerFont::_fontMap; + + + +// ------------------------------------------------------------------- +// Class : "BannerFont::BigChar". + + + BannerFont::BigChar::BigChar ( char c + , int height + , const char* lines[] + , const BannerFont* font ) + : _character(c) + , _height(height) + , _lines(lines) + , _font(font) + { + if ( lines[0] == NULL ) + throw Error ( nullCharLine, _character, _height ); + + unsigned width = strlen ( lines[0] ); + + for ( int i=1 ; i<_height ; i++ ) { + if ( lines[i] == NULL ) + throw Error ( nullCharLine, _character, _height ); + + if ( strlen(lines[i]) != width ) + throw Error ( unevenCharWidth, _character, _height ); + } + } + + + BannerFont::BigChar::~BigChar () + { } + + + const char* BannerFont::BigChar::operator[] ( int line ) const + { + return _lines[line]; + } + + + string BannerFont::BigChar::_getPrint () const + { + string s; + for ( int line=0 ; line<_height ; line++ ) { + s += _lines[line]; + s += "\n"; + } + return s; + } + + +// ------------------------------------------------------------------- +// Class : "BannerFont::FontMap". + + + BannerFont::FontMap::FontMap (): map() + { +# define ADDCHAR(c,t) (font->addChar((c),sizeof(t)/sizeof(char*),(t))) + + BannerFont *font; + + try { + font = new BannerFont ( "Unknown_Bold_Normal_14" ); + // Digits. + ADDCHAR ( '0', Unknown_Bold_Normal_14_0 ); + ADDCHAR ( '1', Unknown_Bold_Normal_14_1 ); + ADDCHAR ( '2', Unknown_Bold_Normal_14_2 ); + ADDCHAR ( '3', Unknown_Bold_Normal_14_3 ); + ADDCHAR ( '4', Unknown_Bold_Normal_14_4 ); + ADDCHAR ( '5', Unknown_Bold_Normal_14_5 ); + ADDCHAR ( '6', Unknown_Bold_Normal_14_6 ); + ADDCHAR ( '7', Unknown_Bold_Normal_14_7 ); + ADDCHAR ( '8', Unknown_Bold_Normal_14_8 ); + ADDCHAR ( '9', Unknown_Bold_Normal_14_9 ); + + // Alphabetical caps. + ADDCHAR ( 'A', Unknown_Bold_Normal_14_A ); + ADDCHAR ( 'B', Unknown_Bold_Normal_14_B ); + ADDCHAR ( 'C', Unknown_Bold_Normal_14_C ); + ADDCHAR ( 'D', Unknown_Bold_Normal_14_D ); + ADDCHAR ( 'E', Unknown_Bold_Normal_14_E ); + ADDCHAR ( 'F', Unknown_Bold_Normal_14_F ); + ADDCHAR ( 'G', Unknown_Bold_Normal_14_G ); + ADDCHAR ( 'H', Unknown_Bold_Normal_14_H ); + ADDCHAR ( 'I', Unknown_Bold_Normal_14_I ); + ADDCHAR ( 'J', Unknown_Bold_Normal_14_J ); + ADDCHAR ( 'K', Unknown_Bold_Normal_14_K ); + ADDCHAR ( 'L', Unknown_Bold_Normal_14_L ); + ADDCHAR ( 'M', Unknown_Bold_Normal_14_M ); + ADDCHAR ( 'N', Unknown_Bold_Normal_14_N ); + ADDCHAR ( 'O', Unknown_Bold_Normal_14_O ); + ADDCHAR ( 'P', Unknown_Bold_Normal_14_P ); + ADDCHAR ( 'Q', Unknown_Bold_Normal_14_Q ); + ADDCHAR ( 'R', Unknown_Bold_Normal_14_R ); + ADDCHAR ( 'S', Unknown_Bold_Normal_14_S ); + ADDCHAR ( 'T', Unknown_Bold_Normal_14_T ); + ADDCHAR ( 'U', Unknown_Bold_Normal_14_U ); + ADDCHAR ( 'V', Unknown_Bold_Normal_14_V ); + ADDCHAR ( 'W', Unknown_Bold_Normal_14_W ); + ADDCHAR ( 'X', Unknown_Bold_Normal_14_X ); + ADDCHAR ( 'Y', Unknown_Bold_Normal_14_Y ); + ADDCHAR ( 'Z', Unknown_Bold_Normal_14_Z ); + + // Alphabetical. + ADDCHAR ( 'a', Unknown_Bold_Normal_14_a ); + ADDCHAR ( 'b', Unknown_Bold_Normal_14_b ); + ADDCHAR ( 'c', Unknown_Bold_Normal_14_c ); + ADDCHAR ( 'd', Unknown_Bold_Normal_14_d ); + ADDCHAR ( 'e', Unknown_Bold_Normal_14_e ); + ADDCHAR ( 'f', Unknown_Bold_Normal_14_f ); + ADDCHAR ( 'g', Unknown_Bold_Normal_14_g ); + ADDCHAR ( 'h', Unknown_Bold_Normal_14_h ); + ADDCHAR ( 'i', Unknown_Bold_Normal_14_i ); + ADDCHAR ( 'j', Unknown_Bold_Normal_14_j ); + ADDCHAR ( 'k', Unknown_Bold_Normal_14_k ); + ADDCHAR ( 'l', Unknown_Bold_Normal_14_l ); + ADDCHAR ( 'm', Unknown_Bold_Normal_14_m ); + ADDCHAR ( 'n', Unknown_Bold_Normal_14_n ); + ADDCHAR ( 'o', Unknown_Bold_Normal_14_o ); + ADDCHAR ( 'p', Unknown_Bold_Normal_14_p ); + ADDCHAR ( 'q', Unknown_Bold_Normal_14_q ); + ADDCHAR ( 'r', Unknown_Bold_Normal_14_r ); + ADDCHAR ( 's', Unknown_Bold_Normal_14_s ); + ADDCHAR ( 't', Unknown_Bold_Normal_14_t ); + ADDCHAR ( 'u', Unknown_Bold_Normal_14_u ); + ADDCHAR ( 'v', Unknown_Bold_Normal_14_v ); + ADDCHAR ( 'w', Unknown_Bold_Normal_14_w ); + ADDCHAR ( 'x', Unknown_Bold_Normal_14_x ); + ADDCHAR ( 'y', Unknown_Bold_Normal_14_y ); + ADDCHAR ( 'z', Unknown_Bold_Normal_14_z ); + + insert ( make_pair("Unknown_Bold_Normal_14",font) ); + } + catch ( Error &e ) { + cerr << e.what() << endl; + exit (1); + } + +# undef ADDCHAR + } + + + BannerFont::FontMap::~FontMap () + { + for ( iterator it=begin() ; it != end() ; it++ ) + delete it->second; + } + + + const BannerFont* BannerFont::FontMap::operator[] ( const string& name ) const + { + const_iterator it = find ( name ); + if ( it != end() ) + return it->second; + + return (*this)[ "Unknown_Bold_Normal_14" ]; + } + + +// ------------------------------------------------------------------- +// Class : "BannerFont". + + + BannerFont::~BannerFont () + { + CharMap::iterator ichar = _table.begin (); + for ( ; ichar != _table.end() ; ichar++ ) + delete ichar->second; + } + + + const BannerFont* BannerFont::getBannerFont ( const string& name ) + { + return _fontMap[name]; + } + + + void BannerFont::addChar ( char character, int height, const char* lines[] ) + { + CharMap::iterator it = _table.find ( character ); + CharMap::iterator begin = _table.begin (); + + if ( it != _table.end() ) + throw Error ( dupChar, _name.c_str(), character ); + + _table [ character ] = new BigChar ( character, height, lines, this ); + + if ( begin == _table.end() ) _height = height; + if ( _height != height ) + throw Error ( badHeight, _name.c_str(), _height, character ); + } + + + const BannerFont::BigChar& BannerFont::operator[] ( char character ) const + { + CharMap::const_iterator it = _table.find ( character ); + + if ( it == _table.end() ) + throw Error ( badChar, _name.c_str(), character ); + + return *(it->second); + } + + +// ------------------------------------------------------------------- +// Class : "FontMap". + + +// ------------------------------------------------------------------- +// Class : "Banner". + + + Banner::Banner ( string name + , string version + , string purpose + , string date + , string authors + , string contributors ) + : _name(name) + , _version(version) + , _purpose(purpose) + , _date(date) + , _authors(authors) + , _contributors(contributors) + , _screenWidth(80) + , _font(BannerFont::getBannerFont("Unknown_Bold_Normal_14")) + , _lines(NULL) + , _banner() + { + _redraw (); + } + + + Banner::~Banner() + { + if ( _lines ) delete [] _lines; + } + + + void Banner::_redraw () + { + if ( _lines ) delete [] _lines; + + _lines = new string [ _font->getHeight() ]; + _banner.str (""); + _banner << "\n"; + + // Concat all the caracters. + for ( unsigned i=0 ; i<_name.size() ; i++ ) { + for ( int line=0 ; line<_font->getHeight() ; line++ ) { + _lines[line] += ( *_font )[ _name[i] ][ line ]; + _lines[line] += ' '; + } + } + + // Check the banner width. + if ( _lines[0].size() > _screenWidth ) + throw Error ( badBannerWidth, _name.c_str(), _screenWidth ); + + int half = ( _screenWidth - _lines[0].size() ) / 2; + string head ( half, ' ' ); + + // Concat & center all the lines. + for ( int line=0 ; line<_font->getHeight() ; line++ ) { + if ( _lines[line].find_first_not_of(" ") != string::npos ) + _banner << head << _lines [ line ] << "\n"; + } + + // Draw the cartouche. + // Purpose. + if ( _purpose.size() ) { + half = ( _screenWidth - _purpose.size() ) / 2; + head.clear (); + head.append ( half, ' ' ); + + _banner << "\n" << head << _purpose << "\n"; + } + + half = ( _screenWidth - 44 ) / 2; + head.clear (); + head.append ( half, ' ' ); + + // Version. + if ( _version.size() ) { + string nameVersion = _name + " " + _version; + _banner << "\n" << head << "Coriolis CAD System 1.0," + << setw(19) << nameVersion; + } + + // Date. + if ( _date.size() ) { + time_t t; + time(&t); + _banner << "\n" << head << "Copyright (c) " << _date + << "-" << localtime(&t)->tm_year+1900 << ", ASIM/LIP6/UPMC"; + } + + // Authors. + if ( _authors.size() ) { + string author; + size_t end, token, tail, start; + + end = _authors.size(); + if ( end > 0 ) { + for ( token=0 ; token<=end ; token=tail ) { + tail = _authors.find ( ',' , token+1 ); + start = (token==0) ? 0 : token+1; + + author = _authors.substr ( start , tail-start ); + if ( !token ) + _banner << "\n" << head << "Author(s) :" << setw(32) << author; + else + _banner << "\n" << head << setw(43) << author; + } + } + } + + // Contributors. + if ( _contributors.size() ) { + string contributor; + size_t end, token, tail, start; + + end = _contributors.size(); + if ( end > 0 ) { + for ( token=0 ; token<=end ; token=tail ) { + tail = _contributors.find ( ',' , token+1 ); + start = (token==0) ? 0 : token+1; + + contributor = _contributors.substr ( start , tail-start ); + if ( !token ) + _banner << "\n" << head << "Contributors(s) :" << setw(26) << contributor; + else + _banner << "\n" << head << setw(43) << contributor; + } + } + } + + // E-mail. + _banner << "\n" << head << "E-mail : coriolis-cvs@asim.lip6.fr"; + + // Separate the banner from the following text. + _banner << "\n"; + } + + + void Banner::setFont ( BannerFont* font ) + { + if ( _font == font ) return; + + _font = font; + _redraw (); + } + + + void Banner::setName ( string name ) + { + if ( _name == name ) return; + + _name = name; + _redraw (); + } + + + void Banner::setVersion ( string version ) + { + if ( _version == version ) return; + + _version = version; + _redraw (); + } + + + void Banner::setPurpose ( string purpose ) + { + if ( _purpose == purpose ) return; + + _purpose = purpose; + _redraw (); + } + + + void Banner::setDate ( string date ) + { + if ( _date == date ) return; + + _date = date; + _redraw (); + } + + + void Banner::setAuthors ( string authors ) + { + if ( _authors == authors ) return; + + _authors = authors; + _redraw (); + } + + + void Banner::setContributors ( string contributors ) + { + if ( _contributors == contributors ) return; + + _contributors = contributors; + _redraw (); + } + + + void Banner::setScreenWidth ( unsigned int screenWidth ) + { + if ( _screenWidth == screenWidth ) return; + + _screenWidth = screenWidth; + _redraw (); + } + + + + +// x-----------------------------------------------------------------x +// | Functions Definitions | +// x-----------------------------------------------------------------x + + + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/CConfig.h.cmake b/crlcore/src/ccore/CConfig.h.cmake new file mode 100644 index 00000000..2682acca --- /dev/null +++ b/crlcore/src/ccore/CConfig.h.cmake @@ -0,0 +1 @@ +#cmakedefine CORIOLIS_TOP diff --git a/crlcore/src/ccore/CConfig.h.in b/crlcore/src/ccore/CConfig.h.in new file mode 100644 index 00000000..dd386f19 --- /dev/null +++ b/crlcore/src/ccore/CConfig.h.in @@ -0,0 +1,101 @@ +/* src/ccore/CConfig.h.in. Generated from configure.in by autoheader. */ + +// -*- C++ -*- +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./CConfig.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x +// + + + + +# ifndef __CCONFIG_H__ +# define __CCONFIG_H__ + + +/* The root directory where CORIOLIS is to be installed. */ +#undef CORIOLIS_TOP + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if LEF/DEF package has been found. */ +#undef HAVE_LEFDEF_LIB + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if OPENACCESS package has been found. */ +#undef HAVE_OPENACCESS_LIB + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define if using GNU regex */ +#undef WITH_REGEX + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#undef YYTEXT_POINTER + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +# endif + diff --git a/crlcore/src/ccore/CMakeLists.txt b/crlcore/src/ccore/CMakeLists.txt new file mode 100644 index 00000000..88b19f1b --- /dev/null +++ b/crlcore/src/ccore/CMakeLists.txt @@ -0,0 +1,237 @@ + + include ( ${QT_USE_FILE} ) + + include_directories ( ${HURRICANE_INCLUDE_DIR} ) + include_directories ( ${CRLCORE_SOURCE_DIR}/src/fonts + ${CRLCORE_SOURCE_DIR}/src/ccore + ${CRLCORE_SOURCE_DIR}/src/ccore/properties + ${CRLCORE_SOURCE_DIR}/src/ccore/bookshelf + ${CRLCORE_SOURCE_DIR}/src/ccore/cspice + ${CRLCORE_SOURCE_DIR}/src/ccore/lefdef + ${CRLCORE_SOURCE_DIR}/src/ccore/alliance/ap + ${CRLCORE_SOURCE_DIR}/src/ccore/alliance/vst + ${CRLCORE_SOURCE_DIR}/src/ccore/agds + ${CRLCORE_SOURCE_DIR}/src/ccore/cif + ${CRLCORE_SOURCE_DIR}/src/ccore/spice + ${CRLCORE_SOURCE_DIR}/src/ccore/liberty + ${CRLCORE_SOURCE_DIR}/src/ccore/toolbox + ) + + add_definitions ( -DCORIOLIS_TOP=\\"${PROJECT_BINARY_DIR}\\" ) + + set ( includes crlcore/Utilities.h + crlcore/Memory.h + crlcore/Banner.h + crlcore/COptions.h + crlcore/XmlParser.h + crlcore/GdsDriver.h + crlcore/CifDriver.h + crlcore/SearchPath.h + crlcore/Environment.h + crlcore/Catalog.h + crlcore/AllianceLibrary.h + crlcore/ParsersDrivers.h + crlcore/LefDefExtension.h + crlcore/Ioc.h + crlcore/NetExtension.h + crlcore/RoutingGauge.h + crlcore/RoutingLayerGauge.h + crlcore/CellGauge.h + crlcore/SymbolicTechnologyParser.h + crlcore/RealTechnologyParser.h + crlcore/GraphicsParser.h + crlcore/AllianceFramework.h + crlcore/ToolEngine.h + crlcore/ToolEngines.h + crlcore/ToolBox.h + crlcore/Hierarchy.h + crlcore/CellPath.h + crlcore/CellPaths.h + crlcore/TimingEvent.h + ) + set ( mocincludes crlcore/GraphicToolEngine.h ) + set ( ccore_cpps Utilities.cpp + Memory.cpp + Banner.cpp + COptions.cpp + XmlParser.cpp + GdsDriver.cpp + CifDriver.cpp + SearchPath.cpp + Environment.cpp + Catalog.cpp + AllianceLibrary.cpp + ParsersDrivers.cpp + RoutingGauge.cpp + CellGauge.cpp + RoutingLayerGauge.cpp + SymbolicTechnologyParser.cpp + RealTechnologyParser.cpp + GraphicsParser.cpp + AllianceFramework.cpp + ToolEngine.cpp + GraphicToolEngine.cpp + ) + set ( spice_cpps spice/SpiceParser.cpp + spice/SpiceDriver.cpp + spice/Spice.cpp + ) + set ( bookshelf_cpps bookshelf/BookshelfParser.cpp + bookshelf/BookshelfDriver.cpp + ) + set ( ap_cpps alliance/ap/ApParser.cpp + alliance/ap/ApDriver.cpp + ) + set ( agds_cpps agds/AgdsDriver.cpp + ) + set ( cif_cpps cif/CifDriver.cpp + ) + set ( toolbox_cpps toolbox/HyperNetPortOccurrences.cpp + toolbox/ToolBox.cpp + toolbox/UniqueCellOccurrences.cpp + toolbox/RoutingPads.cpp + ) + set ( vst_driver_cpps alliance/vst/VstDriver.cpp ) + set ( properties_cpps properties/NetExtension.cpp ) +# set ( liberty_cpps liberty/CellPath.cpp +# liberty/LuTableTemplate.cpp +# liberty/LibertyTechnology.cpp +# liberty/TimingEvent.cpp +# liberty/LuTable.cpp +# ) + set ( lefdef_cpps lefdef/LefDef.h + lefdef/LefDefExtension.cpp + lefdef/LefParser.cpp + lefdef/DefParser.cpp + lefdef/DefDriver.cpp + ) + + if ( OA_FOUND ) + include_directories ( ${OA_INCLUDE_DIR} ) + set( openaccess_cpps openaccess/COpenAccessBridgeLayer.cpp + openaccess/OAWrapper.cpp + ) + endif ( OA_FOUND ) + if ( LEFDEF_FOUND ) + include_directories ( ${LEFDEF_INCLUDE_DIR} ) + endif ( LEFDEF_FOUND ) + set (openaccess_cpps ${openaccess_cpps} + openaccess/OpenAccessWrapper.cpp ) + + set ( VstParserSourceDir ${CRLCORE_SOURCE_DIR}/src/ccore/alliance/vst ) + set ( VstParserBinaryDir ${CRLCORE_BINARY_DIR}/src/ccore/alliance/vst ) + set ( VstParserScanner ${VstParserSourceDir}/VstParserScanner.ll ) + set ( VstParserGrammar ${VstParserSourceDir}/VstParserGrammar.yy ) + set ( VstParserScannerCpp ${VstParserBinaryDir}/VstParserScanner.cpp ) + set ( VstParserGrammarCpp ${VstParserBinaryDir}/VstParserGrammar.cpp ) + add_subdirectory ( alliance ) + add_custom_target ( VstParser echo "Creating VST parser" ) + add_custom_command ( SOURCE ${VstParserScanner} + COMMAND ${FLEX_EXECUTABLE} + ARGS -PVST -o${VstParserScannerCpp} ${VstParserScanner} + TARGET VstParser + OUTPUTS ${VstParserScannerCpp} + ) + add_custom_command ( SOURCE ${VstParserGrammar} + COMMAND ${BISON_EXECUTABLE} + ARGS -d -v -p VST -y ${VstParserGrammar} -o ${VstParserGrammarCpp} + TARGET VstParser + DEPENDS ${VstParserScannerCpp} + OUTPUTS ${VstParserGrammarCpp} + ) + include_directories ( ${VstParserBinaryDir} ) + set ( vst_parser_cpps ${VstParserScannerCpp} + ${VstParserGrammarCpp} + ) + set_source_files_properties ( ${VstParserScannerCpp} GENERATED ) + set_source_files_properties ( ${VstParserGrammarCpp} GENERATED ) + + + set ( IocParserSourceDir ${CRLCORE_SOURCE_DIR}/src/ccore/ioc ) + set ( IocParserBinaryDir ${CRLCORE_BINARY_DIR}/src/ccore/ioc ) + set ( IocParserScanner ${IocParserSourceDir}/IocParserScanner.ll ) + set ( IocParserGrammar ${IocParserSourceDir}/IocParserGrammar.yy ) + set ( IocParserScannerCpp ${IocParserBinaryDir}/IocParserScanner.cpp ) + set ( IocParserGrammarCpp ${IocParserBinaryDir}/IocParserGrammar.cpp ) + add_subdirectory ( ioc ) + add_custom_target ( IocParser echo "Creating IOC parser" ) + add_custom_command ( SOURCE ${IocParserScanner} + COMMAND ${FLEX_EXECUTABLE} + ARGS -PIoc -o${IocParserScannerCpp} ${IocParserScanner} + TARGET IocParser + OUTPUTS ${IocParserScannerCpp} + ) + add_custom_command ( SOURCE ${IocParserGrammar} + COMMAND ${BISON_EXECUTABLE} + ARGS -d -v -p Ioc -y ${IocParserGrammar} -o ${IocParserGrammarCpp} + TARGET IocParser + DEPENDS ${IocParserScannerCpp} + OUTPUTS ${IocParserGrammarCpp} + ) + include_directories ( ${IocParserBinaryDir} ) + set ( ioc_parser_cpps ${IocParserScannerCpp} + ${IocParserGrammarCpp} + ) + set_source_files_properties ( ${IocParserScannerCpp} GENERATED ) + set_source_files_properties ( ${IocParserGrammarCpp} GENERATED ) + + +# # set ( LibertyParserSourceDir ${CRLCORE_SOURCE_DIR}/src/ccore/liberty ) +# # set ( LibertyParserBinaryDir ${CRLCORE_BINARY_DIR}/src/ccore/liberty ) +# # set ( LibertyParserScanner ${LibertyParserSourceDir}/LibertyParserScanner.ll ) +# # set ( LibertyParserGrammar ${LibertyParserSourceDir}/LibertyParserGrammar.yy ) +# # set ( LibertyParserScannerCpp ${LibertyParserBinaryDir}/LibertyParserScanner.cpp ) +# # set ( LibertyParserGrammarCpp ${LibertyParserBinaryDir}/LibertyParserGrammar.cpp ) +# # add_subdirectory ( liberty ) +# # add_custom_target ( LibertyParser echo "Creating LIBERTY parser" ) +# # add_custom_command ( SOURCE ${LibertyParserScanner} +# COMMAND ${FLEX_EXECUTABLE} +# ARGS -PLIBERTY -o${LibertyParserScannerCpp} ${LibertyParserScanner} +# TARGET LibertyParser +# OUTPUTS ${LibertyParserScannerCpp} +# ) +# add_custom_command ( SOURCE ${LibertyParserGrammar} +# COMMAND ${BISON_EXECUTABLE} +# ARGS -d -v -p LIBERTY -y ${LibertyParserGrammar} -o ${LibertyParserGrammarCpp} +# TARGET LibertyParser +# DEPENDS ${LibertyParserScannerCpp} +# OUTPUTS ${LibertyParserGrammarCpp} +# ) +# include_directories ( ${LibertyParserBinaryDir} ) +# set ( liberty_parser_cpps ${LibertyParserScannerCpp} +# ${LibertyParserGrammarCpp} +# ) +# set_source_files_properties ( ${LibertyParserScannerCpp} GENERATED ) +# set_source_files_properties ( ${LibertyParserGrammarCpp} GENERATED ) + + + qt4_wrap_cpp ( moc_cpps ${mocincludes} ) + install ( FILES ${includes} ${mocincludes} DESTINATION /include/coriolis/crlcore ) + + add_library ( crlcore ${ccore_cpps} + ${moc_cpps} + ${ap_cpps} + ${agds_cpps} + ${cif_cpps} + ${toolbox_cpps} + ${vst_parser_cpps} + ${vst_driver_cpps} + ${properties_cpps} + ${ioc_parser_cpps} + ${liberty_cpps} + ${liberty_parser_cpps} + ${bookshelf_cpps} + ${spice_cpps} + ${lefdef_cpps} + ${openaccess_cpps} + ) + target_link_libraries ( crlcore ${HURRICANE_LIBRARIES} + ${HURRICANE_GRAPHICAL_LIBRARIES} + ${QT_LIBRARIES} + ${IO_LIBRARIES} + ${LEFDEF_LIBRARIES} + ${OA_LIBRARIES} + ${AGDS_LIBRARY} + ${CIF_LIBRARY} + ) + install ( TARGETS crlcore DESTINATION /lib ) diff --git a/crlcore/src/ccore/COptions.cpp b/crlcore/src/ccore/COptions.cpp new file mode 100644 index 00000000..bc4d723d --- /dev/null +++ b/crlcore/src/ccore/COptions.cpp @@ -0,0 +1,597 @@ + + +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== + +// -*- C++ -*- +// +// $Id: COptions.cpp,v 1.7 2006/02/19 00:52:46 jpc Exp $ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./COptions.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +# include + +# include "crlcore/COptions.h" + + + + +namespace { + + using namespace std; + + // ----------------------------------------------------------------- + // Begin of local namespace (internal objects). + + +// ------------------------------------------------------------------- +// Class : "::_Frag()". + + class _Frag { + public: string _val; + public: int _order; + + public: _Frag ( string val, int order ) + : _val(val), _order(order) { }; + }; + + typedef vector<_Frag> _FragVect; + + + + + // --------------------------------------------------------------- + // Pre-defined objects. + + + +// ------------------------------------------------------------------- +// Function : "badShort()". + +inline string badShort ( const string &name ) +{ + string m; + + m += "COptions::Add() :"; + m += "\n\n"; + m += " Short options must have exactly one character \"" + name + "\".\n"; + + return ( m ); +} + + + +// ------------------------------------------------------------------- +// Function : "dupOption()". + +inline string dupOption ( const string &name ) +{ + string m; + + m += "COptions::Add() :"; + m += "\n\n"; + m += " Duplicate option \"" + name + "\".\n"; + + return ( m ); +} + + + + +// ------------------------------------------------------------------- +// Function : "unknownOption()". + +inline string unknownOption ( const string &name ) +{ + string m; + + m += "COptions::Parse() :"; + m += "\n\n"; + m += " Unknown option \"" + name + "\".\n"; + + return ( m ); +} + + + + +// ------------------------------------------------------------------- +// Function : "unknownKey()". + +inline string unknownKey ( const string &name ) +{ + string m; + + m += "COptions::Parse() :"; + m += "\n\n"; + m += " Unknown option key \"" + name + "\".\n"; + + return ( m ); +} + + + + +// ------------------------------------------------------------------- +// Function : "missingArg()". + +inline string missingArg ( const string &name ) +{ + string m; + + m += "COptions::Parse() :"; + m += "\n\n"; + m += " Missing mandatory argument of option \"" + name + "\"\n"; + + return ( m ); +} + + + + +// ------------------------------------------------------------------- +// Function : "reParse()". + +inline string reParse () +{ + string m; + + m += "COptions::Parse() :"; + m += "\n\n"; + m += " Attempt to re-parse options. You must explicitely clear\n"; + m += " the COptions object before calling another COptions::Parse().\n"; + + return ( m ); +} + + + // ----------------------------------------------------------------- + // End of local namespace (internal objects). + +} + + +namespace CRL { + + + + +// x-----------------------------------------------------------------x +// | Global Definitions | +// x-----------------------------------------------------------------x + + + const string COptions::_true = "__true"; + const string COptions::_false = "__false"; + const string COptions::_remains = "__remains"; + const string COptions::_argvzero = "__argv[0]"; + const string COptions::_missing = "__missing"; + + + + +// x-----------------------------------------------------------------x +// | Methods Definitions | +// x-----------------------------------------------------------------x + + +// ------------------------------------------------------------------- +// Conversion : "COptions::Option::operator string()". + +COptions::Option::operator string () +{ + if ( _times == 0 ) return ( COptions::_false ); + if ( _times <= _select ) return ( COptions::_false ); + if ( ! _hasArg ) return ( COptions::_true ); + + return ( _args[ _select ] ); +} + + + string& COptions::Option::getArg ( size_t i ) + { + return _args[i]; + } + + + + +// ------------------------------------------------------------------- +// Constructor : "COptions::COptions()". + +COptions::COptions () : _clear(true) + , _argHelp(false) + , _argVerbose(false) + , _argVeryVerbose(false) + , _argCatchCore(false) + , _missingBuiltin("",_missing) +{ + // Special option holding all remaining non options arguments. + Add ( "", _remains , true ); + Add ( "", _argvzero, true ); +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::Find()". + +COptions::OptionVect::iterator COptions::Find ( string name ) +{ + OptionVect::iterator it; + OptionVect::iterator end = _options.end (); + + if ( name.size() == 0 ) return ( end ); + if ( name.size() == 1 ) { + for ( it=_options.begin() ; it!=end ; it++ ) { + if ( it->getShort() == name ) break; + } + } else { + for ( it=_options.begin() ; it!=end ; it++ ) { + if ( it->getLong() == name ) break; + } + } + + return ( it ); +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::Add()". + +void COptions::Add ( string nameShort + , string nameLong + , bool hasArg + , string defaultArg ) +{ + OptionVect::iterator it; + OptionVect::iterator end = _options.end (); + + if ( nameShort.size() > 1 ) throw ( Error(badShort(nameShort)) ); + + if ( ( it=Find(nameShort) ) == end ) { + if ( ( it=Find(nameLong) ) == end ) { + _options.push_back ( Option(nameShort,nameLong,hasArg,defaultArg) ); + } else + throw ( Error (dupOption(nameLong)) ); + } else + throw ( Error (dupOption(nameShort)) ); +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::AddHelp()". + +void COptions::AddHelp () +{ + Add ( "h", "help" ); + _argHelp = true; +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::AddVerbose()". + +void COptions::AddVerbose () +{ + Add ( "v", "verbose" ); + _argVerbose = true; +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::AddVeryVerbose()". + +void COptions::AddVeryVerbose () +{ + Add ( "V", "very-verbose" ); + _argVeryVerbose = true; +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::AddVeryVerbose()". + +void COptions::AddCatchCore () +{ + Add ( "D", "core-dump" ); + _argCatchCore = true; +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::getHelp()". + +COptions::Option &COptions::getHelp () +{ + if ( ! _argHelp ) return ( _missingBuiltin ); + + return ( (*this)["help"] ); +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::getVerbose()". + +COptions::Option &COptions::getVerbose () +{ + if ( ! _argVerbose ) return ( _missingBuiltin ); + + return ( (*this)["verbose"] ); +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::getVeryVerbose()". + +COptions::Option &COptions::getVeryVerbose () +{ + if ( ! _argVeryVerbose ) return ( _missingBuiltin ); + + return ( (*this)["very-verbose"] ); +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::getCatchCore()". + +COptions::Option &COptions::getCatchCore () +{ + if ( ! _argCatchCore ) return ( _missingBuiltin ); + + return ( (*this)["core-dump"] ); +} + + + + + +// ------------------------------------------------------------------- +// Method : "COptions::Parse()". + +void COptions::Parse ( int argc, char *argv[] ) +{ + if ( ! _clear ) throw ( Error(reParse()) ); + _clear = false; + + _FragVect fragOpts; + _FragVect fragArgs; + string arg; + size_t equal; + int order = 0; + bool longOpt; + + + // First step : separate options from arguments in two + // indexed list (index is relative to the argv[] ordering. + for ( int i=1 ; iAddArg ( argv[0] ); + + // Storing all non-options remaining arguments. + opt = Find ( _remains ); + for ( ; itArg != endArg ; itArg++ ) + opt->AddArg ( itArg->_val ); +} + + + + + +// ------------------------------------------------------------------- +// Method : "COptions::Clear()". + +void COptions::Clear () +{ + OptionVect::iterator it; + OptionVect::iterator end = _options.end (); + + for ( it=_options.begin() ; it!=end ; it++ ) it->Clear (); + + _clear = true; +} + + + + +// ------------------------------------------------------------------- +// Operator : "COptions::operator[]()". + +COptions::Option &COptions::operator[] ( string key ) +{ + size_t separ = key.find ( '/' ); + int index = 0; + + if ( separ < key.size() ) { + istringstream sindex ( key.substr ( separ + 1 ) ); + sindex >> index; + } + + OptionVect::iterator opt = Find ( key.substr(0,separ) ); + if ( opt == _options.end () ) { + throw ( Error(unknownKey(key)) ); + } + + opt->SetSelect ( index ); + return ( *opt ); +} + + + + +// ------------------------------------------------------------------- +// Method : "COptions::_getPrint()". + +string COptions::_getPrint () +{ + ostringstream os; + ostringstream key; + OptionVect::iterator it; + OptionVect::iterator end = _options.end (); + string name; + string minus; + + + os << (string)(*this)[_argvzero]; + + for ( it=_options.begin() ; it!=end ; it++ ) { + if ( it->getLong() == _argvzero ) continue; + if ( it->getLong() == _remains ) continue; + if ( it->getLong().size() > 0 ) { + minus = "--"; + name = it->getLong(); + } else { + minus = "-"; + name = it->getShort(); + } + + for ( int i=0; i < it->getTimes(); i++ ) { + if ( it->getHasArg() ) { + key.str (""); + key << name << "/" << i; + os << " " << minus << name << "=" << (string)(*this)[ key.str() ]; + } else + os << " " << minus << name; + } + } + + it = Find ( _remains ); + for ( int i=0; i < it->getTimes(); i++ ) { + key.str (""); + key << _remains << "/" << i; + os << " " << (string)(*this)[ key.str() ]; + } + + return ( os.str() ); +} + + + + +} diff --git a/crlcore/src/ccore/Catalog.cpp b/crlcore/src/ccore/Catalog.cpp new file mode 100644 index 00000000..fe932ba2 --- /dev/null +++ b/crlcore/src/ccore/Catalog.cpp @@ -0,0 +1,307 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./Catalog.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +# include +using namespace std; + +#include "hurricane/Collection.h" +#include "hurricane/Library.h" +#include "hurricane/Name.h" + +#include "crlcore/Utilities.h" +#include "crlcore/Catalog.h" + + +namespace CRL { + + + const char* MissingStateProperty = "%s:\n\n Missing Catalog State Property in cell \"%s\".\n"; + + +// ------------------------------------------------------------------- +// Class : "Catalog::State". + + + Catalog::State::~State () + { + if ( _cell ) + _cell->removeProperty ( CatalogProperty::getPropertyName() ); + } + + + void Catalog::State::merge ( const State& other ) + { + if ( (_cell ==NULL) && other._cell ) _cell = other._cell; + if ( (_library==NULL) && other._library ) _library = other._library; + + _flags |= other._flags; + _depth = max ( _depth, other._depth ); + } + + + string Catalog::State::_getString () const + { + string s; + + if ( isFlattenLeaf() ) s += 'C'; + if ( isFeed() ) s += 'F'; + if ( isGds() ) s += 'G'; + if ( isDelete() ) s += 'D'; + + return s; + } + + + Record* Catalog::State::_getRecord () const + { + Record* record = new Record ( "" ); + if ( record != NULL ) { + record->add ( getSlot("_flags" , _flags ) ); + record->add ( getSlot("_depth" , _depth ) ); + record->add ( getSlot("_cell" , _cell ) ); + record->add ( getSlot("_library", _library) ); + } + return record; + } + + +// ------------------------------------------------------------------- +// Class : "Catalog". + + Catalog::~Catalog () + { + clear (); + } + + + Catalog::State* Catalog::getState ( const Name& name, bool add ) + { + map::iterator it; + + if ( (it=_states.find(name)) != _states.end() ) return it->second; + + State *state = NULL; + if ( add ) { + state = new State (); + _states [ name ] = state; + } + return ( state ); + } + + + void Catalog::mergeState ( const Name& name, const State& other ) + { + map::iterator it; + State* state; + + if ( (it=_states.find(name)) == _states.end() ) + state = getState ( name, true ); + else + state = it->second; + + state->merge ( other ); + } + + + bool Catalog::deleteState ( const Name& name ) + { + map::iterator it; + + if ( (it=_states.find(name)) == _states.end() ) return false; + + State *state = it->second; + + delete state; + _states.erase ( it ); + + return true; + } + + + void Catalog::clear () + { + map::const_iterator istate; + for ( istate=_states.begin() ; istate!=_states.end() ; istate++ ) { + delete istate->second; + } + _states.clear (); + } + + + bool Catalog::readLine ( const string& s, string& name, State* state ) + { + static string spaceChars = " "; + + size_t start = s.find_first_not_of ( spaceChars ); + size_t stop = s.find_first_of ( spaceChars, start ); + + if ( stop == string::npos ) return false; + + name = s.substr ( start, stop-start ); + + start = s.find_first_not_of ( spaceChars, stop ); + if ( start == string::npos ) return false; + + for ( ; startsetFlattenLeaf ( true ); break; + case 'F': state->setFeed ( true ); break; + case 'G': state->setGds ( true ); break; + case 'D': state->setDelete ( true ); break; + default: return false; + } + } + + return true; + } + + + bool Catalog::loadFromFile ( const string& path, Library* library ) + { + IoFile catalogFile ( path ); + + catalogFile.open ( "r" ); + if ( !catalogFile.isOpen() ) return false; + + string cellName; + char rawLine[1024]; + + while ( !catalogFile.eof() ) { + State cellState; + cellState.setLibrary ( library ); + + string line = catalogFile.readLine(rawLine,1023); + if ( !line.size() ) continue; + + if ( !readLine (line,cellName,&cellState) ) { + cerr << "[WARNING] Catalog::LoadFromFile() :\n" + << " Malformed catalog line \"" << line + << "\"\n (file: " << path << ", line: " << catalogFile.getLineNumber() << ")" << endl; + continue; + } + mergeState ( cellName, cellState ); + } + catalogFile.close (); + + return true; + } + + + string Catalog::_getPrint () const + { + map::const_iterator it; + ostringstream s; + + for ( it=_states.begin() ; it!=_states.end() ; it++ ) { + s << left << setw(30) << getString(it->first) << getString(it->second) << endl; + } + + return s.str(); + } + + + string Catalog::_getString () const + { + ostringstream s; + + s << ""; + return s.str(); + } + + + Record* Catalog::_getRecord () const + { + map::const_iterator it; + + Record* record = new Record ( "" ); + + record->add ( getSlot ( "States", &_states ) ); + + return record; + } + + +// ------------------------------------------------------------------- +// Class : "CatalogProperty" + + + Name CatalogProperty::_name = "Alliance Catalog State"; + + + CatalogProperty* CatalogProperty::create ( Catalog::State* state ) + { + CatalogProperty *property = new CatalogProperty ( state ); + + property->_postCreate (); + return property; + } + + + void CatalogProperty::onReleasedBy ( DBo* owner ) + { + _state->setCell ( NULL ); + PrivateProperty::onReleasedBy ( owner ); + } + + + Name CatalogProperty::getPropertyName () + { + return _name; + } + + + Name CatalogProperty::getName () const + { + return getPropertyName(); + } + + + string CatalogProperty::_getTypeName () const + { + return _TName ( "CatalogProperty" ); + } + + + string CatalogProperty::_getString () const + { + string s = PrivateProperty::_getString (); + s.insert ( s.length() - 1 , " " + getString(_state) ); + + return s; + } + + + Record* CatalogProperty::_getRecord () const + { + Record* record = PrivateProperty::_getRecord(); + if ( record ) { + record->add( getSlot("_name" ,_name ) ); + record->add( getSlot("_state",_state) ); + } + return record; + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/CellGauge.cpp b/crlcore/src/ccore/CellGauge.cpp new file mode 100644 index 00000000..1dc49891 --- /dev/null +++ b/crlcore/src/ccore/CellGauge.cpp @@ -0,0 +1,141 @@ + + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./CellGauge.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +#include + +#include "crlcore/CellGauge.h" + + + + +namespace { + + + const char *missingMandatoryAttr = + "CRoutingGauge::createFromXml () :\n\n" + " Can't found mandatory attribute \"%s\".\n"; + + const char *badAttrValue = + "CRoutingGauge::createFromXml () :\n\n" + " Invalid value \"%s\" for attribute \"%s\".\n"; + +// const char *missingCellGaugeTag = +// "::createCellGaugeFromXml () :\n\n" +// " Can't found \"cellgauge\" tag.\n" +// " (XML file := \"%s\").\n"; + +// const char *missingCellGaugeNameAttr = +// "::createCellGaugeFromXml () :\n\n" +// " Can't found cellgauge name tag attribute.\n"; + +// const char *emptyCellGaugeNameAttr = +// "::createCellGaugeFromXml () :\n\n" +// " cellgauge name tag attribute is empty.\n"; + + +} // End of Anonymous namespace. + + + + +namespace CRL { + + +// ------------------------------------------------------------------- +// Class : "CRL::CellGauge". + + + CellGauge::CellGauge ( const char* name + , const char* pinLayerName + , const DbU::Unit pitch + , const DbU::Unit sliceHeight + , const DbU::Unit sliceStep + ) : _name(name) + , _pinLayerName(pinLayerName) + , _pitch(pitch) + , _sliceHeight(sliceHeight) + , _sliceStep(sliceStep) + { } + + + CellGauge* CellGauge::create ( const char* name + , const char* pinLayerName + , const DbU::Unit pitch + , const DbU::Unit sliceHeight + , const DbU::Unit sliceStep + ) + { + if ( !name || (name[0] == '\0') ) + throw Error ( "CellGauge::create() : Empty name." ); + + CellGauge* gauge = new CellGauge ( name, pinLayerName, pitch, sliceHeight, sliceStep ); + + if ( gauge == NULL ) + throw Error ( BadCreate, "CRL::CellGauge::create()" ); + + return gauge; + } + + + CellGauge::~CellGauge() + { } + + + void CellGauge::destroy () + { delete this; } + + + string CellGauge::_getTypeName () const + { return _TName("CellGauge"); } + + + string CellGauge::_getString () const + { + return ( "<" + _TName("CellGauge ") + + getString(_name) + //+ " pinLayerName=" + getString(_pinLayerName) + //+ " pitch=" + getValueString(_pitch) + //+ " height=" + getValueString(_sliceHeight) + //+ " step=" + getValueString(_sliceStep) + + ">" ); + } + + + Record* CellGauge::_getRecord () const + { + Record* record = new Record ( getString(this) ); + record->add ( getSlot ( "Name" , &_name ) ); + record->add ( getSlot ( "PinLayerName" , &_pinLayerName) ); + record->add ( getSlot ( "pitch" , _pitch ) ); + record->add ( getSlot ( "sliceHeight" , _sliceHeight ) ); + record->add ( getSlot ( "sliceStep" , _sliceStep ) ); + return ( record ); + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/CifDriver.cpp b/crlcore/src/ccore/CifDriver.cpp new file mode 100644 index 00000000..03b71c96 --- /dev/null +++ b/crlcore/src/ccore/CifDriver.cpp @@ -0,0 +1,18 @@ +// author : Damien Dupuis +// date : 24.02.2010 +// -*- C++ -*- + +#include "hurricane/Cell.h" +using namespace Hurricane; + +#include "crlcore/CifDriver.h" +#include "cif/Cif.h" + +namespace CRL { + CifDriver::CifDriver(Cell* cell) : _cell(cell), _name(""), _units(""), _scale(0) {} + + bool CifDriver::save(const string& filePath) { + CRL::cifDriver(filePath, _cell, _name, _units, _scale); + return true; + } +}// namespace CRL diff --git a/crlcore/src/ccore/Environment.cpp b/crlcore/src/ccore/Environment.cpp new file mode 100644 index 00000000..921b647a --- /dev/null +++ b/crlcore/src/ccore/Environment.cpp @@ -0,0 +1,716 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./Environnment.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include +#include +#include + +#include + +#include "crlcore/Utilities.h" +#include "crlcore/XmlParser.h" +#include "crlcore/Environment.h" + + +#undef CORIOLIS_TOP +#define CORIOLIS_TOP "/dsk/l1/jpc/Linux.SLSoC5x/install" + + +namespace { + + + using namespace CRL; + + + const char* badRegex = + "Environment::Environment() :\n" + " Invalid regular expression for %s :\n" + " %s.\n"; + const char* badSCALE_X = + "Environment::Environment() :\n" + " Only three values are allowed for SCALE : 1, 10 & 100.\n" + " (current value := %ld)"; + const char* badEnvironment = + "Environment::Environment() :\n" + " %s logical format \"%s\" incoherent with physical format \"%s\".\n"; + + + class XmlEnvironmentParser : public XmlParser { + + // Methods. + public: + static XmlEnvironmentParser* create ( Environment& env + , QXmlStreamReader* reader ); + static bool load ( Environment& env + , const string& path + , bool warnNotFound=true ); + + // Internal - enum. + protected: + enum TagSet { TagsEnvironment = 2 + , TagsVariable + , TagsTechnologies + , TagsHurricane + , TagsReal + , TagsLEF + , TagsDisplay + , TagsConfig + , TagsLibraries + , TagsCatalog + , TagsWorking + , TagsSystem + , TagsLibrary + , TagsFormats + , TagsScale + , TagsInput + , TagsOutput + , TagsLogical + , TagsPhysical + , TagsSignals + , TagsPOWER + , TagsGROUND + , TagsClock + , TagsObstacle + , TagsTableSize + }; + enum State { HurricaneTechnology = 1 + , RealTechnology + , LEFTechnology + , Display + , WorkingLibrary + , SystemLibrary + , InputFormats + , OutputFormats + }; + + // Internal - Attributes. + Environment& _environment; + map _variables; + unsigned int _state; + + // Internal - Constructors. + XmlEnvironmentParser ( Environment& env + , QXmlStreamReader* reader=NULL ); + XmlEnvironmentParser ( const XmlEnvironmentParser& ); + XmlEnvironmentParser& operator= ( const XmlEnvironmentParser& ); + + // Internal - Methods. + const string& getVariable ( const string& name ); + void setVariable ( const string& name, const string& value ); + string& expandVariables ( string& value ); + void parseEnvironment (); + void parseVariable (); + void parseTechnologies (); + void parseHurricane (); + void parseReal (); + void parseLEF (); + void parseDisplay (); + void parseDisplayStyle (); + void parseConfig (); + void parseLibraries (); + void parseCatalog (); + void parseWorking (); + void parseSystem (); + void parseLibrary (); + void parseFormats (); + void parseScale (); + void parseInput (); + void parseOutput (); + void parseLogical (); + void parsePhysical (); + void parseSignals (); + void parsePOWER (); + void parseGROUND (); + void parseClock (); + void parseObstacle (); + virtual void _postLoad (); + virtual const char* _getMessage ( MessageId id ); + + }; + + + + XmlEnvironmentParser::XmlEnvironmentParser ( Environment& env, QXmlStreamReader* reader ) + : XmlParser(reader,TagsTableSize) + , _environment(env) + , _state(0) + { + addTagEntry ( TagsStandAlone , "environment" , (tagParser_t)&XmlEnvironmentParser::parseEnvironment ); + addTagEntry ( TagsEnvironment , "variable" , (tagParser_t)&XmlEnvironmentParser::parseVariable ); + + addTagEntry ( TagsEnvironment , "technologies", (tagParser_t)&XmlEnvironmentParser::parseTechnologies ); + addTagEntry ( TagsTechnologies, "hurricane" , (tagParser_t)&XmlEnvironmentParser::parseHurricane ); + addTagEntry ( TagsHurricane , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig ); + addTagEntry ( TagsTechnologies, "real" , (tagParser_t)&XmlEnvironmentParser::parseReal ); + addTagEntry ( TagsReal , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig ); + addTagEntry ( TagsTechnologies, "lef" , (tagParser_t)&XmlEnvironmentParser::parseLEF ); + addTagEntry ( TagsLEF , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig ); + addTagEntry ( TagsTechnologies, "display" , (tagParser_t)&XmlEnvironmentParser::parseDisplay ); + addTagEntry ( TagsDisplay , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig ); + addTagEntry ( TagsDisplay , "displaystyle", (tagParser_t)&XmlEnvironmentParser::parseDisplayStyle ); + + addTagEntry ( TagsEnvironment , "libraries" , (tagParser_t)&XmlEnvironmentParser::parseLibraries ); + addTagEntry ( TagsLibraries , "catalog" , (tagParser_t)&XmlEnvironmentParser::parseCatalog ); + addTagEntry ( TagsLibraries , "working" , (tagParser_t)&XmlEnvironmentParser::parseWorking ); + addTagEntry ( TagsWorking , "library" , (tagParser_t)&XmlEnvironmentParser::parseLibrary ); + addTagEntry ( TagsLibraries , "system" , (tagParser_t)&XmlEnvironmentParser::parseSystem ); + addTagEntry ( TagsSystem , "library" , (tagParser_t)&XmlEnvironmentParser::parseLibrary ); + + addTagEntry ( TagsEnvironment , "formats" , (tagParser_t)&XmlEnvironmentParser::parseFormats ); + addTagEntry ( TagsFormats , "scale" , (tagParser_t)&XmlEnvironmentParser::parseScale ); + addTagEntry ( TagsFormats , "input" , (tagParser_t)&XmlEnvironmentParser::parseInput ); + addTagEntry ( TagsInput , "logical" , (tagParser_t)&XmlEnvironmentParser::parseLogical ); + addTagEntry ( TagsInput , "physical" , (tagParser_t)&XmlEnvironmentParser::parsePhysical ); + addTagEntry ( TagsFormats , "output" , (tagParser_t)&XmlEnvironmentParser::parseOutput ); + addTagEntry ( TagsOutput , "logical" , (tagParser_t)&XmlEnvironmentParser::parseLogical ); + addTagEntry ( TagsOutput , "physical" , (tagParser_t)&XmlEnvironmentParser::parsePhysical ); + + addTagEntry ( TagsEnvironment , "signals" , (tagParser_t)&XmlEnvironmentParser::parseSignals ); + addTagEntry ( TagsSignals , "vdd" , (tagParser_t)&XmlEnvironmentParser::parsePOWER ); + addTagEntry ( TagsSignals , "vss" , (tagParser_t)&XmlEnvironmentParser::parseGROUND ); + addTagEntry ( TagsSignals , "clock" , (tagParser_t)&XmlEnvironmentParser::parseClock ); + addTagEntry ( TagsSignals , "obstacle" , (tagParser_t)&XmlEnvironmentParser::parseObstacle ); + + setVariable ( "CORIOLIS_TOP", _environment.getCORIOLIS_TOP() ); + } + + + XmlEnvironmentParser* XmlEnvironmentParser::create ( Environment& env + , QXmlStreamReader* reader ) + { + return new XmlEnvironmentParser ( env, reader ); + } + + + bool XmlEnvironmentParser::load ( Environment& env, const string& path, bool warnNotFound ) + { + XmlEnvironmentParser ep ( env ); + + string envPath = path; + if ( path.empty() ) + envPath = env.getCORIOLIS_TOP() + "/share/etc/environment.alliance.xml" ; + + return ep._load ( envPath, warnNotFound ); + } + + + const string& XmlEnvironmentParser::getVariable ( const string& name ) + { + static const string nullValue = ""; + + map::iterator it = _variables.find ( name ); + if ( it != _variables.end() ) + return it->second; + + return nullValue; + } + + + void XmlEnvironmentParser::setVariable ( const string& name, const string& value ) + { + if ( !getVariable(name).empty() ) + cerr << "[WARNING] Overriding variable \"" << name << "\".\n" << endl; + + _variables [ name ] = value; + } + + + string& XmlEnvironmentParser::expandVariables ( string& variable ) + { + size_t dollar; + size_t vbegin; + size_t vend; + bool braces = false; + + while ( (dollar = variable.find('$')) != string::npos ) { + if ( variable[dollar+1] == '{' ) { + braces = true; + vbegin = dollar+2; + vend = variable.find ( '}', vbegin ); + if ( vend == string::npos ) { + cerr << "[ERROR] Unmatched brace while expanding variables." << endl; + break; + } + } else { + vbegin = dollar+1; + for ( vend = vbegin ; vend < variable.size() ; vend++ ) + if ( !isalnum(variable[vend]) ) break; + } + + const string& substitute = getVariable ( variable.substr(vbegin,vend-vbegin) ); + if ( substitute.empty() ) { + cerr << "[ERROR] Reference to undefined variable \"" + << variable.substr(vbegin,vend-vbegin+(braces?1:0)) << "\"." << endl; + variable [ dollar ] = '_'; + continue; + } + + variable.replace ( dollar, vend-dollar+(braces?1:0), substitute ); + } + + return variable; + } + + + void XmlEnvironmentParser::parseEnvironment () + { + parseTags ( TagsEnvironment ); + } + + + void XmlEnvironmentParser::parseVariable () + { + QString value; + QString name; + + name = _reader->attributes().value("name").toString(); + if ( name.isEmpty() ) + cerr << "[ERROR] Unnamed variable." << endl; + else { + value = _reader->attributes().value("value").toString(); + if ( value.isEmpty() ) + cerr << "[ERROR] variable \"" << qPrintable(name) << "\" has no value." << endl; + else + setVariable ( name.toStdString(), value.toStdString() ); + } + + parseNoChilds (); + } + + + void XmlEnvironmentParser::parseTechnologies () + { + parseTags ( TagsTechnologies ); + } + + + void XmlEnvironmentParser::parseHurricane () + { + _state = HurricaneTechnology; + parseTags ( TagsHurricane ); + } + + + void XmlEnvironmentParser::parseReal () + { + _state = RealTechnology; + parseTags ( TagsReal ); + } + + + void XmlEnvironmentParser::parseLEF () + { + _state = LEFTechnology; + parseTags ( TagsLEF ); + } + + + void XmlEnvironmentParser::parseDisplay () + { + _state = Display; + parseTags ( TagsDisplay ); + } + + + void XmlEnvironmentParser::parseDisplayStyle () + { + QString value; + + value = _reader->attributes().value("name").toString(); + if ( !value.isEmpty() ) + _environment.setDisplayStyle ( value.toStdString().c_str() ); + else + cerr << "[ERROR] Unnamed display style." << endl; + + parseNoChilds (); + } + + + void XmlEnvironmentParser::parseConfig () + { + string config = readTextAsString().toStdString(); + expandVariables ( config ); + switch ( _state ) { + case HurricaneTechnology: _environment.setSYMBOLIC_TECHNOLOGY ( config.c_str() ); break; + case LEFTechnology: _environment.setLEF_TECHNOLOGY ( config.c_str() ); break; + case RealTechnology: _environment.setREAL_TECHNOLOGY ( config.c_str() ); break; + case Display: _environment.setDISPLAY ( config.c_str() ); break; + } + } + + + void XmlEnvironmentParser::parseLibraries () + { + parseTags ( TagsLibraries ); + } + + + void XmlEnvironmentParser::parseCatalog () + { + _environment.setCATALOG ( readTextAsString().toStdString().c_str() ); + } + + + void XmlEnvironmentParser::parseWorking () + { + _state = WorkingLibrary; + parseTags ( TagsWorking ); + } + + + void XmlEnvironmentParser::parseSystem () + { + _state = SystemLibrary; + + QString operation; + + operation = _reader->attributes().value("operation").toString(); + if ( operation.isEmpty() ) + _environment.getLIBRARIES().reset(); + else if ( operation != "append" ) + cerr << "[ERROR] Invalid value for attribute \"operation\" of : \"" + << qPrintable(operation) << "\"." << endl; + + parseTags ( TagsSystem ); + } + + + void XmlEnvironmentParser::parseLibrary () + { + string library = readTextAsString().toStdString(); + expandVariables ( library ); + switch ( _state ) { + case WorkingLibrary: _environment.setWORKING_LIBRARY ( library.c_str() ); break; + case SystemLibrary: _environment.addSYSTEM_LIBRARY ( library.c_str() ); break; + } + } + + + void XmlEnvironmentParser::parseFormats () + { + parseTags ( TagsFormats ); + } + + + void XmlEnvironmentParser::parseScale () + { + _environment.setSCALE_X ( readTextAsLong() ); + } + + + void XmlEnvironmentParser::parseInput () + { + _state = InputFormats; + parseTags ( TagsInput ); + } + + + void XmlEnvironmentParser::parseOutput () + { + _state = OutputFormats; + parseTags ( TagsOutput ); + } + + + void XmlEnvironmentParser::parseLogical () + { + string format = readTextAsString().toStdString(); + switch ( _state ) { + case InputFormats: _environment.setIN_LO ( format.c_str() ); break; + case OutputFormats: _environment.setOUT_LO ( format.c_str() ); break; + } + } + + + void XmlEnvironmentParser::parsePhysical () + { + string format = readTextAsString().toStdString(); + switch ( _state ) { + case InputFormats: _environment.setIN_PH ( format.c_str() ); break; + case OutputFormats: _environment.setOUT_PH ( format.c_str() ); break; + } + } + + + void XmlEnvironmentParser::parseSignals () + { + parseTags ( TagsSignals ); + } + + + void XmlEnvironmentParser::parsePOWER () + { + _environment.setPOWER ( readTextAsString().toStdString().c_str() ); + } + + + void XmlEnvironmentParser::parseGROUND () + { + _environment.setGROUND ( readTextAsString().toStdString().c_str() ); + } + + + void XmlEnvironmentParser::parseClock () + { + _environment.setCLOCK ( readTextAsString().toStdString().c_str() ); + } + + + void XmlEnvironmentParser::parseObstacle () + { + _environment.setOBSTACLE ( readTextAsString().toStdString().c_str() ); + } + + + void XmlEnvironmentParser::_postLoad () + { + } + + + const char* XmlEnvironmentParser::_getMessage ( MessageId id ) + { + const char* message = ""; + switch ( id ) { + case OpenFile: message = "environment"; break; + } + + return message; + } + + +} // End of anonymous namespace. + + + + +namespace CRL { + + + Environment::Environment () + : _CORIOLIS_TOP (CORIOLIS_TOP) + , _displayStyle () + , _SCALE_X (10) + , _SYMBOLIC_TECHNOLOGY(CORIOLIS_TOP "/share/etc/technology.symbolic.xml") + , _LEF_TECHNOLOGY ("") + , _DISPLAY (CORIOLIS_TOP "/share/etc/display.xml") + , _IN_LO ("vst") + , _IN_PH ("ap") + , _OUT_LO ("vst") + , _OUT_PH ("ap") + , _CATALOG ("CATAL") + , _inConstructor (true) + { + setPOWER ( "vdd" ); + setGROUND ( "vss" ); + setCLOCK ( "^ck$" ); + setOBSTACLE ( "^obs$" ); + + _LIBRARIES.append ( "." ); + + _inConstructor = false; + } + + + Environment::~Environment () + { + regfree ( &_PowerRegex ); + regfree ( &_GroundRegex ); + regfree ( &_ClockRegex ); + regfree ( &_ObstacleRegex ); + } + + + void Environment::loadFromXml ( const string& path, bool warnNotFound ) + { + XmlEnvironmentParser::load ( *this, path, warnNotFound ); + + check (); + } + + + void Environment::loadFromShell () + { + _CORIOLIS_TOP = getEnv ( "CORIOLIS_TOP", CORIOLIS_TOP ); + + check (); + } + + + bool Environment::isPOWER ( const char* name ) const + { + return regexec ( &_PowerRegex, name, 0, NULL, 0 ) == 0; + } + + + bool Environment::isGROUND ( const char* name ) const + { + return regexec ( &_GroundRegex, name, 0, NULL, 0 ) == 0; + } + + + bool Environment::isCLOCK ( const char* name ) const + { + return regexec ( &_ClockRegex, name, 0, NULL, 0 ) == 0; + } + + + bool Environment::isOBSTACLE ( const char* name ) const + { + return regexec ( &_ObstacleRegex, name, 0, NULL, 0 ) == 0; + } + + + void Environment::setPOWER ( const char* value ) + { + _POWER = value; + setRegex ( &_PowerRegex , _POWER , "Power" ); + } + + + void Environment::setGROUND ( const char* value ) + { + _GROUND = value; + setRegex ( &_GroundRegex , _GROUND , "Ground" ); + } + + + void Environment::setCLOCK ( const char* value ) + { + _CLOCK = value; + setRegex ( &_ClockRegex , _CLOCK , "Clock" ); + } + + + void Environment::setOBSTACLE ( const char* value ) + { + _OBSTACLE = value; + setRegex ( &_ObstacleRegex , _OBSTACLE , "Obstacle" ); + } + + + string Environment::getPrint () const + { + ostringstream s; + + s << "\n" + << " o Hurricane/Alliance environment.\n" + << " o Configuration files.\n" + << " - Coriolis directory:\n" + << " \"" << _CORIOLIS_TOP << "\"\n" + << " - Symbolic Technology:\n" + << " \"" << _SYMBOLIC_TECHNOLOGY << "\"\n" + << " - LEF Technology:\n" + << " \"" << _LEF_TECHNOLOGY << "\"\n" + << " - Display configuration:\n" + << " \"" << _DISPLAY << "\"\n"; + + s << " o Libraries.\n" + << " - Catalog := \"" << _CATALOG << "\"\n" + << " - Working Library:\n" + << " 0:\"" << _LIBRARIES[0] << "\"\n" + << " - System Libraries:\n"; + + if ( _LIBRARIES.getSize() <= 1 ) { + s << " .\n"; + } else { + for ( size_t i = 1; i < _LIBRARIES.getSize() ; i++ ) { + s << " " << setw(2) << i << ":\"" << _LIBRARIES[i] << "\"\n"; + } + } + + s << " o I/O Formats.\n" + << " - Scale := " << _SCALE_X << "\n" + << " - Input, logical := \"" << _IN_LO << "\"\n" + << " - Input, physical := \"" << _IN_PH << "\"\n" + << " - Output, logical := \"" << _OUT_LO << "\"\n" + << " - Output, physical := \"" << _OUT_PH << "\"\n" + << " o Special Signals.\n" + << " - Power Signal := \"" << _POWER << "\"\n" + << " - Ground Signal := \"" << _GROUND << "\"\n" + << " - Clock Signal := \"" << _CLOCK << "\"\n" + << " - Obstacles := \"" << _OBSTACLE << "\"\n\n"; + + return s.str(); + } + + + void Environment::setRegex ( regex_t* regex, const string& pattern, const char* name ) + { + char regexError[1024]; + int regexCode; + + if ( !_inConstructor ) regfree ( regex ); + + if ( ( regexCode = regcomp(regex,getString(pattern).c_str(),REG_EXTENDED|REG_NOSUB) ) ) { + regerror ( regexCode, regex, regexError, 1024 ); + throw Error ( badRegex, name, regexError ); + } + } + + + void Environment::check () const + { + switch ( _SCALE_X ) { + case 1: break; + case 10: break; + case 100: break; + default: + throw Error ( badSCALE_X , _SCALE_X ); + } + + bool coherency = false; + if ( ( _IN_LO == "vst" ) && ( _IN_PH == "ap" ) ) coherency = true; + else if ( ( _IN_LO == "spi" ) && ( _IN_PH == "ap" ) ) coherency = true; + else if ( ( _IN_LO == "def" ) && ( _IN_PH == "def") ) coherency = true; + else if ( ( _IN_LO == "aux" ) && ( _IN_PH == "aux") ) coherency = true; + else if ( ( _IN_LO == "oa" ) && ( _IN_PH == "oa" ) ) coherency = true; + if ( !coherency ) + throw Error ( badEnvironment, "Input", _IN_LO.c_str(), _IN_PH.c_str() ); + + coherency = false; + if ( ( _OUT_LO == "vst" ) && ( _OUT_PH == "ap" ) ) coherency = true; + else if ( ( _OUT_LO == "spi" ) && ( _OUT_PH == "ap" ) ) coherency = true; + else if ( ( _OUT_LO == "vst" ) && ( _OUT_PH == "gds") ) coherency = true; + else if ( ( _OUT_LO == "def" ) && ( _OUT_PH == "def") ) coherency = true; + else if ( ( _OUT_LO == "aux" ) && ( _OUT_PH == "aux") ) coherency = true; + else if ( ( _OUT_LO == "oa" ) && ( _OUT_PH == "oa" ) ) coherency = true; + if ( !coherency ) + throw Error ( badEnvironment, "Output", _OUT_LO.c_str(), _OUT_PH.c_str() ); + } + + + const char* Environment::getEnv ( const char* variable, const char* defaultValue ) + { + char *value; + + value = getenv ( variable ); + if ( value == NULL ) return defaultValue; + + return value; + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/GdsDriver.cpp b/crlcore/src/ccore/GdsDriver.cpp new file mode 100644 index 00000000..495c1495 --- /dev/null +++ b/crlcore/src/ccore/GdsDriver.cpp @@ -0,0 +1,18 @@ +// author : Damien Dupuis +// date : 08.12.2009 +// -*- C++ -*- + +#include "hurricane/Cell.h" +using namespace Hurricane; + +#include "crlcore/GdsDriver.h" +#include "agds/Agds.h" + +namespace CRL { + GdsDriver::GdsDriver(Cell* cell) : _cell(cell), _name(""), _lib(""), _uUnits(0), _pUnits(0) {} + + bool GdsDriver::save(const string& filePath) { + CRL::agdsDriver(filePath, _cell, _name, _lib, _uUnits, _pUnits); + return true; + } +}// namespace CRL diff --git a/crlcore/src/ccore/GraphicToolEngine.cpp b/crlcore/src/ccore/GraphicToolEngine.cpp new file mode 100644 index 00000000..0e2e312f --- /dev/null +++ b/crlcore/src/ccore/GraphicToolEngine.cpp @@ -0,0 +1,77 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./GraphicToolEngine.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include + +#include "hurricane/Warning.h" +#include "crlcore/GraphicToolEngine.h" + + +namespace CRL { + + + using namespace std; + + using Hurricane::Warning; + + +// ------------------------------------------------------------------- +// Class : "CRL::GraphicTool". + + + GraphicTool::GraphicTool () + : _drawGoMap() + { } + + + GraphicTool::~GraphicTool () + { } + + + void GraphicTool::addDrawGo ( const Name& name + , CellWidget::InitExtensionGo_t* initFunction + , CellWidget::DrawExtensionGo_t* drawFunction + ) + { + map::iterator idraw = _drawGoMap.find ( name ); + if ( idraw != _drawGoMap.end() ) + cerr << Warning("Overwriting %s DrawGo functions.",getString(name).c_str()) << endl; + + _drawGoMap.insert ( make_pair(name,DrawGoFunctions(initFunction,drawFunction)) ); + } + + + GraphicTool::DrawGoFunctions* GraphicTool::getDrawGo ( const Name& name ) + { + map::iterator idraw = _drawGoMap.find ( name ); + if ( idraw != _drawGoMap.end() ) + return &idraw->second; + + return NULL; + } + + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/GraphicsParser.cpp b/crlcore/src/ccore/GraphicsParser.cpp new file mode 100644 index 00000000..b238a395 --- /dev/null +++ b/crlcore/src/ccore/GraphicsParser.cpp @@ -0,0 +1,204 @@ + +// -*- C++ -*- + + +# include +# include + +# include + +# include "hurricane/viewer/DisplayStyle.h" +# include "hurricane/viewer/Graphics.h" + +# include "crlcore/GraphicsParser.h" + + + + +namespace CRL { + + + using Hurricane::Graphics; + + + void GraphicsParser::parseDefault () + { + QString state = readTextAsString (); + if ( state == "true" ) + _defaultDisplayStyle = _displayStyle; + } + + + void GraphicsParser::parseInherit () + { + Name name = readTextAsString().toStdString(); + + DisplayStyle* baseStyle = Graphics::getStyle ( name ); + if ( baseStyle ) + _displayStyle->inheritFrom ( baseStyle ); + else + cerr << "[ERROR] Base style \"" << getString(name) + << "\" of \"" << getString(_displayStyle->getName()) + << "\" doesn't exist (yet?)." << endl; + } + + + void GraphicsParser::parseDescription () + { + string description = readTextAsString().toStdString(); + + _displayStyle->setDescription ( description ); + } + + + void GraphicsParser::parseDarkening () + { + int darkening = (int)( readTextAsDouble() * 100 ); + + _displayStyle->setDarkening ( darkening ); + } + + + void GraphicsParser::parseDrawingStyle () + { + string pattern = "FFFFFFFFFFFFFFFF"; + int red = 255; + int green = 255; + int blue = 255; + int border = 0; + float threshold = 1.0; + Name drawingStyleName = "unnamed"; + QString value; + + value = _reader->attributes().value("name").toString(); + if ( !value.isEmpty() ) + drawingStyleName = value.toStdString (); + else + cerr << "[ERROR] Unnamed drawing style." << endl; + + value = _reader->attributes().value("color").toString(); + if ( !value.isEmpty() ) { + QStringList components = value.split ( "," ); + if ( components.size() == 3 ) { + red = components[0].toInt (); + green = components[1].toInt (); + blue = components[2].toInt (); + } else + cerr << "[ERROR] Malformed color attribute." << endl; + } else + cerr << "[ERROR] Missing madatory color attribute." << endl; + + value = _reader->attributes().value("pattern").toString(); + if ( !value.isEmpty() ) + pattern = value.toStdString (); + + value = _reader->attributes().value("border").toString(); + if ( !value.isEmpty() ) + border = value.toInt (); + + value = _reader->attributes().value("threshold").toString(); + if ( !value.isEmpty() ) + threshold = value.toFloat (); + + _displayStyle->addDrawingStyle ( _drawingGroupName + , drawingStyleName + , pattern + , red + , green + , blue + , border + , threshold + ); + + parseNoChilds (); + } + + + void GraphicsParser::parseDrawingGroup () + { + _drawingGroupName = _reader->attributes().value("name").toString().toStdString(); + if ( _drawingGroupName.isEmpty() ) + cerr << "[ERROR] Empty group name." << endl; + + parseTags ( TagsDrawingGroup ); + } + + + void GraphicsParser::parseDisplayStyle () + { + Name name = _reader->attributes().value("name").toString().toStdString(); + _displayStyle = new DisplayStyle ( name ); + Graphics::addStyle ( _displayStyle ); + + if ( !_defaultDisplayStyle ) + _defaultDisplayStyle = _displayStyle; + + parseTags ( TagsDisplayStyle ); + } + + + void GraphicsParser::parseDisplayStyles () + { + parseTags ( TagsDisplayStyles ); + } + + + void GraphicsParser::parseGraphics () + { + parseTags ( TagsGraphics ); + + if ( _defaultDisplayStyle ) + Graphics::setStyle ( _defaultDisplayStyle->getName() ); + } + + + GraphicsParser::GraphicsParser ( QXmlStreamReader* reader ) + : XmlParser(reader,6) + , _displayStyle(NULL) + , _defaultDisplayStyle(NULL) + , _drawingGroupName() + { + addTagEntry ( TagsStandAlone , "graphics" , (tagParser_t)&GraphicsParser::parseGraphics ); + addTagEntry ( TagsGraphics , "displaystyles", (tagParser_t)&GraphicsParser::parseDisplayStyles ); + addTagEntry ( TagsDisplayStyles, "displaystyle" , (tagParser_t)&GraphicsParser::parseDisplayStyle ); + addTagEntry ( TagsDisplayStyle , "group" , (tagParser_t)&GraphicsParser::parseDrawingGroup ); + addTagEntry ( TagsDisplayStyle , "default" , (tagParser_t)&GraphicsParser::parseDefault ); + addTagEntry ( TagsDisplayStyle , "inherit" , (tagParser_t)&GraphicsParser::parseInherit ); + addTagEntry ( TagsDisplayStyle , "description" , (tagParser_t)&GraphicsParser::parseDescription ); + addTagEntry ( TagsDisplayStyle , "darkening" , (tagParser_t)&GraphicsParser::parseDarkening ); + addTagEntry ( TagsDrawingGroup , "drawingstyle" , (tagParser_t)&GraphicsParser::parseDrawingStyle ); + } + + + GraphicsParser* GraphicsParser::create ( QXmlStreamReader* reader ) + { + return new GraphicsParser ( reader ); + } + + + bool GraphicsParser::load ( const string& path ) + { + GraphicsParser gp; + return gp._load ( path ); + } + + + void GraphicsParser::_postLoad () + { + if ( getDefaultDisplayStyle() ) + Graphics::setStyle ( getDefaultDisplayStyle()->getName() ); + } + + + const char* GraphicsParser::_getMessage ( MessageId id ) + { + const char* message = ""; + switch ( id ) { + case OpenFile: message = "graphics configuration"; break; + } + + return message; + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/Memory.cpp b/crlcore/src/ccore/Memory.cpp new file mode 100644 index 00000000..d9f4905c --- /dev/null +++ b/crlcore/src/ccore/Memory.cpp @@ -0,0 +1,229 @@ +/************************************************************************** +*** +*** Copyright (c) 1995-2000 Regents of the University of California, +*** Andrew E. Caldwell, Andrew B. Kahng and Igor L. Markov +*** Copyright (c) 2000-2002 Regents of the University of Michigan, +*** Saurabh N. Adya and Igor L. Markov +*** +*** Contact author(s): abk@cs.ucsd.edu, imarkov@umich.edu +*** Original Affiliation: UCLA, Computer Science Department, +*** Los Angeles, CA 90095-1596 USA +*** +*** Permission is hereby granted, free of charge, to any person obtaining +*** a copy of this software and associated documentation files (the +*** "Software"), to deal in the Software without restriction, including +*** without limitation +*** the rights to use, copy, modify, merge, publish, distribute, sublicense, +*** and/or sell copies of the Software, and to permit persons to whom the +*** Software is furnished to do so, subject to the following conditions: +*** +*** The above copyright notice and this permission notice shall be included +*** in all copies or substantial portions of the Software. +*** +*** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +*** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +*** OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +*** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +*** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +*** OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +*** THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*** +*** +***************************************************************************/ + + + + + + +// August 22, 1997 created by Igor Markov VLSI CAD UCLA ABKGROUP +// November 30, 1997 additions by Max Moroz, VLSI CAD UCLA ABKGROUP + +// note: not thread-safe + +// This file to be included into all projects in the group +// it contains platform-specific code portability of which relies +// on symbols defined by compilers + +// 970825 mro made corrections to conditional compilation in ctors for +// Platform and User: +// i) _MSC_VER not __MSC_VER (starts with single underscore) +// ii) allocated more space for _infoLines +// iii) changed nested #ifdefs to #if ... #elif ... #else +// 970923 ilm added abk_dump_stack() +// 971130 ilm added Max Moroz code for memory estimate and reworked +// class MemUsage() +// 980822 mm corrected MemUsage() to work with Solaris 2.6 + +#include +#include +using namespace std; + +#include "hurricane/Warning.h" +using Hurricane::Warning; + +#include "crlcore/Memory.h" + +#if defined(sun) || defined(__SUNPRO_CC) + #include +#endif + +#ifdef linux + #include +#endif + +#if defined(linux) || defined(sun) || defined(__SUNPRO_CC) + #include + #include + #include +#endif + +/* ======================== IMPLEMENTATIONS ======================== */ + +namespace { + +double getPeakMemoryUsage() +{ + +#if ! (defined(sun) || defined(linux) || defined(__SUNPRO_CC)) + return -1; +#endif + +#if defined(sun) || defined(__SUNPRO_CC) + char procFileName[20]; + unsigned pid=getpid(); + sprintf(procFileName,"/proc/%d/as",pid); + struct stat buf; + if (stat(procFileName,&buf)) // no such file on Solaris 2.5 and earlier + { // so we stat another file now + char procFileNameOld[20]; + sprintf(procFileNameOld,"/proc/%d",pid); + if (stat(procFileNameOld,&buf)) return -1.0; + } + return (1.0/(1024*1024)) * buf.st_size; +#elif defined(linux) + char buf[1000]; + sprintf(buf,"/proc/%d/stat", static_cast(getpid())); + ifstream ifs(buf); + for(unsigned k=0; k!=23; k++) ifs >> buf; + return (1.0/(1024*1024)) * atoi(buf); +#else + return -1; +#endif +} + +// code by Max Moroz + +const int kMegaByte=1024*1024; +const int kSmallChunks=1000; +const int kMaxAllocs=20000; +const double MemUsageEps=3; + +// everything in bytes + +inline int memused() +{ +// cout << " Peak memory " << getPeakMemoryUsage() << endl; + return static_cast(getPeakMemoryUsage()*kMegaByte); +} + +double getMemoryUsageEstimate() +{ +#if ! (defined(linux) || defined(sun) || defined(__SUNPRO_CC)) + return -1; +#endif + static int prevMem=0; + static int extra; + static int fail=0; + + if (fail) return -1; + +// new_handler oldHndl; +// oldHndl=set_new_handler(mH); + + void* ptr[kMaxAllocs]; + int numAllocs=0; + + int last=memused(); +// cout << "Memused : " << last << endl; + if (last<=0) return -1; +// cerr<<"memused()="<=kMaxAllocs) + { + throw Warning("too many allocs (may be okay for 64-bit builds)"); + // FIFO destruction + for (int i=0; i!=numAllocs; ++i) free(ptr[i]); + return -1.0; + } +// cerr<<"old: "<last+MemUsageEps) + break; + if (chunk<=kMegaByte && !countSmallChunks--) + { + chunk*=2; + countSmallChunks=kSmallChunks; + } + } + +// int result=memused()-allocated-prevMem; + +/* LIFO destruction + while (numAllocs) free(ptr[--numAllocs]); */ + + // FIFO destruction + for (int i=0; i!=numAllocs; ++i) free(ptr[i]); + + extra=memused()-last; +// handle extra correctly: +// in some cases we need to add its prev value to current, +// in some just store the new value + + prevMem=memused()-allocated; +// set_new_handler(oldHndl); + return prevMem/double(kMegaByte); +} + +} + +namespace CRL { + +MemUsage::MemUsage() +{ + _peak=getPeakMemoryUsage(); + _estimate=getMemoryUsageEstimate(); +} + +void MemChange::resetMark() +{ + _memUsageMark=getMemoryUsageEstimate(); +} + +MemChange::MemChange() +{ + resetMark(); +} + +MemChange::operator double() const +{ +#if defined(sun) || defined(linux) || defined(__SUNPRO_CC) + return getPeakMemoryUsage()-_memUsageMark; +#else + return -1.0; +#endif +} + +} diff --git a/crlcore/src/ccore/ParsersDrivers.cpp b/crlcore/src/ccore/ParsersDrivers.cpp new file mode 100644 index 00000000..03b65ffb --- /dev/null +++ b/crlcore/src/ccore/ParsersDrivers.cpp @@ -0,0 +1,388 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./ParserDriver.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + +# include "hurricane/DBo.h" + +# include "crlcore/Utilities.h" +# include "crlcore/Environment.h" +# include "crlcore/Catalog.h" +# include "crlcore/ParsersDrivers.h" +# include "Ap.h" +# include "Vst.h" +# include "Spice.h" +# include "Bookshelf.h" +# include "LefDef.h" +# include "openaccess/OpenAccessWrapper.h" + + +namespace { + + +// Error Messages. + const char* BadSlotIterator = "%s:\n\n" + " Attempt to use an unitialised iterator. Must be set up before\n" + " with either ::lbegin() or ::cbegin().\n"; + const char* DupParser = "%s:\n\n" + " Attempt to overwrite registered parser for format \"%s\"\n" + " and extention \"%s\".\n"; + +} // End of anonymous namespace. + + + + +namespace CRL { + + +// x-----------------------------------------------------------------x +// | Variables Definitions | +// x-----------------------------------------------------------------x + + const char* BadParserType = + "%s:\n\n" + " No registered parser avalaible to load cell \"%s\"\n" + " in format \"%s\".\n"; + const char* BadDriverType = + "%s:\n\n" + " No registered driver avalaible to save cell \"%s\"\n" + " in format \"%s\".\n"; + const char* BadInputMode = + "%s:\n\n" + " Invalid loading mode requested for cell \"%s\".\n" + " (neither logical or physical has been set)\n"; + const char* BadOutputMode = + "%s:\n\n" + " Invalid save mode requested for cell \"%s\".\n" + " (neither logical or physical has been set)\n"; + + +// x-----------------------------------------------------------------x +// | Methods of Class "ParserFormatSlot" | +// x-----------------------------------------------------------------x + + + bool ParserFormatSlot::cend () { + if ( !_itset ) + throw Error ( BadSlotIterator, "ParserFormatSlot::cend()" ); + + return _it == _cells.end(); + } + + + bool ParserFormatSlot::lend () + { + if ( !_itset ) + throw Error ( BadSlotIterator, "ParserFormatSlot::lend()" ); + + return _it == _libs.end(); + } + + + void ParserFormatSlot::operator++ (int) + { + if ( !_itset ) + throw Error ( BadSlotIterator, "ParserFormatSlot::operator++()" ); + + _it++; + } + + + void ParserFormatSlot::registerCell ( const string& tag, CellParser_t* p, const string& ext ) + { + ParserSlot slot ( tag, ext, (void*)p ); + ParserSlotIter it = _cells.begin(); + + for ( ; it != _cells.end() ; it++ ) { + if ( it->_ext == slot._ext ) + throw Error ( DupParser, "ParserFormatSlot::registerCell()", tag.c_str(), ext.c_str() ); + } + + _cells.push_back ( slot ); + cbegin(); + } + + + void ParserFormatSlot::registerLib ( const string& tag, LibraryParser_t* p, const string& ext ) + { + ParserSlot slot ( tag, ext, (void*)p ); + ParserSlotIter it = _libs.begin(); + + for ( ; it != _libs.end() ; it++ ) { + if ( it->_ext == slot._ext ) + throw Error ( DupParser, "ParserFormatSlot::registerLib()", tag.c_str(), ext.c_str() ); + } + + _libs.push_back ( slot ); + lbegin(); + + _loadByLib = true; + } + + + bool ParserFormatSlot::unRegisterCell ( const Name& ext ) + { + ParserSlotIter it = _cells.begin(); + + for ( ; it != _cells.end() ; it++ ) { + if ( it->_ext == ext ) { + _cells.erase ( it ); + cbegin (); + return true; + } + } + + cbegin (); + return false; + } + + + bool ParserFormatSlot::unRegisterLib ( const Name& ext ) + { + ParserSlotIter it = _libs.begin(); + + for ( ; it != _libs.end() ; it++ ) { + if ( it->_ext == ext ) { + _libs.erase ( it ); + if ( _libs.size() == 0 ) _loadByLib = false; + + lbegin (); + return true; + } + } + + lbegin (); + return false; + } + + +// x-----------------------------------------------------------------x +// | Methods of Class "ParsersMap" | +// x-----------------------------------------------------------------x + + + ParsersMap::ParsersMap (): map() + { + // Register the Alliance default parsers. + registerSlot ( "ap" , (CellParser_t*)apParser , "ap" ); + registerSlot ( "vst", (CellParser_t*)vstParser , "vst" ); + registerSlot ( "vst", (CellParser_t*)vstParser , "vbe" ); + registerSlot ( "spi", (CellParser_t*)spiceParser , "spi" ); + registerSlot ( "def", (CellParser_t*)defParser , "def" ); + registerSlot ( "def", (LibraryParser_t*)lefParser , "lef" ); + registerSlot ( "oa", (CellParser_t*)OpenAccessWrapper::oaDesignLoader , "oa" ); + registerSlot ( "oa", (LibraryParser_t*)OpenAccessWrapper::oaLibLoader , "oa" ); + registerSlot ( "aux", (CellParser_t*)bookshelfParser, "aux" ); + } + + + ParserFormatSlot& ParsersMap::getParserSlot ( const string& tag ) + { + ParserFormatSlot* slot; + iterator it; + + if ( ( it = find(Name(tag)) ) != end() ) { + slot = & ( it->second ); + } else { + (*this)[tag] = ParserFormatSlot (); + + // Needed as the slot is copied into the map. + // (a container own is elements) + slot = &( (*this)[tag] ); + } + + return *slot; + } + + + ParserFormatSlot &ParsersMap::getParserSlot ( const string& name + , unsigned int mode + , const Environment& environment ) + { + // Look for the parser tag (i.e. file extention). + Name format; + switch ( mode & (Catalog::State::Views) ) { + case Catalog::State::Physical: format = environment.getIN_PH(); break; + case Catalog::State::Logical: format = environment.getIN_LO(); break; + default: + throw Error ( BadInputMode, "ParserMap::getParserSlot()", getString(name).c_str() ); + } + + iterator it = find ( format ); + if ( it == end() ) + throw Error ( BadParserType + , "ParserMap::getParserSlot()" + , getString(name).c_str() + , getString(format).c_str() ); + + return it->second; + } + + + DriverSlot &DriversMap::getDriverSlot ( const string& name + , unsigned int mode + , const Environment& environment ) + { + // Look for the parser tag (i.e. file extention). + Name format; + switch ( mode & (Catalog::State::Views) ) { + case Catalog::State::Physical: format = environment.getOUT_PH(); break; + case Catalog::State::Logical: format = environment.getOUT_LO(); break; + default: + throw Error ( BadOutputMode, "DriverMap::getDriverSlot()", getString(name).c_str() ); + } + + iterator it = find ( format ); + if ( it == end() ) + throw Error ( BadDriverType + , "DriverMap::getDriverSlot()" + , getString(name).c_str() + , getString(format).c_str() ); + + return it->second; + } + + + void ParsersMap::registerSlot ( const string& tag, CellParser_t* p, const string& ext ) + { + ParserFormatSlot& slot = getParserSlot ( tag ); + + slot.registerCell ( tag, p, ext ); + } + + + void ParsersMap::registerSlot ( const string& tag, LibraryParser_t* p, const string& ext ) + { + ParserFormatSlot& slot = getParserSlot ( tag ); + + slot.registerLib ( tag, p, ext ); + } + + + void ParsersMap::unRegisterSlot ( const Name& tag, const Name& ext, bool lib ) + { + iterator it = find(tag); + + if ( it == end() ) return; + + if ( lib ) it->second.unRegisterLib ( ext ); + else it->second.unRegisterCell ( ext ); + } + + + + +// x-----------------------------------------------------------------x +// | Methods of Class "DriversMap" | +// x-----------------------------------------------------------------x + + + DriversMap::DriversMap () : map() + { + // Register the Alliance default drivers. + registerSlot ( "ap" , (CellDriver_t*)apDriver , "ap" ); + registerSlot ( "vst", (CellDriver_t*)vstDriver , "vst" ); + registerSlot ( "def", (CellDriver_t*)defDriver , "def" ); + registerSlot ( "aux", (CellDriver_t*)bookshelfDriver, "test.aux" ); + registerSlot ( "spi", (CellDriver_t*)spiceDriver , "spi" ); + registerSlot ( "oa" , (CellDriver_t*)OpenAccessWrapper::oaDriver, ""); + } + + + DriverSlot& DriversMap::getDriverSlot ( const string& tag ) + { + return (*this)[ tag ]; + } + + + void DriversMap::registerSlot ( const string& tag, LibraryDriver_t* d, const string& ext ) + { + iterator it = find ( tag ); + DriverSlot* p; + + if ( it == end() ) { + (*this)[ tag ] = DriverSlot ( tag ); + p = & ( (*this)[ tag ] ); + } else + p = & ( it->second ); + + p->setExtLib ( ext ); + p->setDrivLib ( d ); + } + + + void DriversMap::registerSlot ( const string& tag, CellDriver_t* d, const string& ext ) + { + iterator it = find ( tag ); + DriverSlot* p; + + if ( it == end() ) { + (*this)[ tag ] = DriverSlot ( tag ); + p = & ( (*this)[ tag ] ); + } else + p = & ( it->second ); + + p->setExtCell ( ext ); + p->setDrivCell ( d ); + } + + + void DriversMap::unRegisterSlot ( const Name& tag ) + { + iterator it = find ( tag ); + + if ( it == end() ) return; + erase ( it ); + } + + +} diff --git a/crlcore/src/ccore/RealTechnologyParser.cpp b/crlcore/src/ccore/RealTechnologyParser.cpp new file mode 100644 index 00000000..91963f00 --- /dev/null +++ b/crlcore/src/ccore/RealTechnologyParser.cpp @@ -0,0 +1,225 @@ + +// -*- C++ -*- + + +# include +# include + +# include +# include + +# include "hurricane/Error.h" +# include "hurricane/Warning.h" +# include "hurricane/DbU.h" +# include "hurricane/DataBase.h" +# include "hurricane/Technology.h" +# include "hurricane/BasicLayer.h" + +# include "crlcore/Utilities.h" +# include "crlcore/RealTechnologyParser.h" + + + + +namespace CRL { + + + using namespace std; + + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::DbU; + + + const QString RealTechnologyParser::MissingSymbolicNameError = "Missing symbolic layer name attribute"; + const QString RealTechnologyParser::MissingRealNameError = "Missing real layer name attribute"; + const QString RealTechnologyParser::InvalidSymbolicNameError = "Reference to unknown symbolic layer \"%1\""; + const QString RealTechnologyParser::MissingGridValueError = "Missing grid value attribute"; + const QString RealTechnologyParser::MissingGridsPerLambdaValueError = "Missing gridsperlambda value attribute"; + const QString RealTechnologyParser::MissingGridUnitError = "Missing grid unit attribute"; + const QString RealTechnologyParser::UnknownGridUnitError = "Unknown grid unit kind \"%1\""; + + + void RealTechnologyParser::parseTechnology () + { + parseTags ( TagsTechnology ); + } + + + void RealTechnologyParser::parseReal () + { + parseTags ( TagsReal ); + } + + + void RealTechnologyParser::parseName () + { + // May do something of the name here... + readTextAsString(); + } + + + void RealTechnologyParser::parseGrid () + { + QString value; + double gridValue; + DbU::UnitPower gridUnit; + + value = _reader->attributes().value("value").toString(); + if ( !value.isEmpty() ) + gridValue = value.toDouble (); + else + printError ( MissingGridValueError ); + + value = _reader->attributes().value("unit").toString(); + if ( !value.isEmpty() ) { + if ( value == "pico" ) gridUnit = DbU::Pico; + else if ( value == "nano" ) gridUnit = DbU::Nano; + else if ( value == "micron" ) gridUnit = DbU::Micro; + else if ( value == "milli" ) gridUnit = DbU::Milli; + else if ( value == "unity" ) gridUnit = DbU::Unity; + else if ( value == "kilo" ) gridUnit = DbU::Kilo; + else + printError ( UnknownGridUnitError.arg(value) ); + } + else + printError ( MissingGridUnitError ); + + DbU::setPhysicalsPerGrid ( gridValue, gridUnit ); + + parseNoChilds (); + } + + + void RealTechnologyParser::parseGridsPerLambda () + { + QString value; + double gridsPerLambda; + + value = _reader->attributes().value("value").toString(); + if ( !value.isEmpty() ) + gridsPerLambda = value.toInt (); + else + printError ( MissingGridsPerLambdaValueError ); + + DbU::setGridsPerLambda ( gridsPerLambda ); + + parseNoChilds (); + } + + + void RealTechnologyParser::parseLayers () + { + parseTags ( TagsLayers ); + } + + + void RealTechnologyParser::parseProcessLayer () + { + QString value; + string symbolicName; + string realName; + unsigned int gdsIInumber = (unsigned int)-1; + + value = _reader->attributes().value("symbolic").toString(); + if ( !value.isEmpty() ) + symbolicName = value.toStdString (); + else + printError ( MissingSymbolicNameError ); + + value = _reader->attributes().value("real").toString(); + if ( !value.isEmpty() ) + realName = value.toStdString (); + else + printError ( MissingRealNameError ); + + value = _reader->attributes().value("gdsII").toString(); + if ( !value.isEmpty() ) + gdsIInumber = value.toUInt (); + + if ( !symbolicName.empty() ) { + BasicLayer* basicLayer = _technology->getBasicLayer ( symbolicName ); + if ( basicLayer ) { + basicLayer->setRealName ( realName.c_str() ); + basicLayer->setExtractNumber ( gdsIInumber ); + } else + printError ( InvalidSymbolicNameError.arg(symbolicName.c_str()) ); + } + + parseNoChilds (); + } + + + RealTechnologyParser::RealTechnologyParser ( DataBase* db, QXmlStreamReader* reader ) + : XmlParser(reader,TagSetSize) + , _dataBase(db) + , _technology(NULL) + { + assert ( _dataBase != NULL ); + + _technology = db->getTechnology (); + assert ( _technology != NULL ); + + addTagEntry ( TagsStandAlone, "technology" , (tagParser_t)&RealTechnologyParser::parseTechnology ); + addTagEntry ( TagsTechnology, "real" , (tagParser_t)&RealTechnologyParser::parseReal ); + addTagEntry ( TagsReal , "name" , (tagParser_t)&RealTechnologyParser::parseName ); + addTagEntry ( TagsReal , "grid" , (tagParser_t)&RealTechnologyParser::parseGrid ); + addTagEntry ( TagsReal , "gridsperlambda", (tagParser_t)&RealTechnologyParser::parseGridsPerLambda ); + addTagEntry ( TagsReal , "layers" , (tagParser_t)&RealTechnologyParser::parseLayers ); + addTagEntry ( TagsLayers , "processlayer" , (tagParser_t)&RealTechnologyParser::parseProcessLayer ); + } + + + RealTechnologyParser* RealTechnologyParser::create ( DataBase* db, QXmlStreamReader* reader ) + { + return new RealTechnologyParser ( db, reader ); + } + + + bool RealTechnologyParser::load ( DataBase* db, const string& path ) + { + bool aborted = false; + + try { + RealTechnologyParser rtp ( db ); + return rtp._load ( path ); + } + catch ( Error& e ) { + cerr << e.what() << endl; + aborted = true; + } + catch ( ... ) { + cout << "[ERROR] Abnormal termination: unknown exception.\n" << endl; + exit ( 2 ); + } + + if ( aborted ) { + cerr << "[ERROR] Aborting & unloading S2R Technology." << endl; + + //Technology* technology = db->getTechnology (); + //if ( technology ) technology->destroy (); + + exit ( 1 ); + } + + return false; + } + + + void RealTechnologyParser::_postLoad () + { + } + + + const char* RealTechnologyParser::_getMessage ( MessageId id ) + { + const char* message = ""; + switch ( id ) { + case OpenFile: message = "S2R Technology configuration"; break; + } + + return message; + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/RoutingGauge.cpp b/crlcore/src/ccore/RoutingGauge.cpp new file mode 100644 index 00000000..7636a931 --- /dev/null +++ b/crlcore/src/ccore/RoutingGauge.cpp @@ -0,0 +1,254 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./RoutingGauge.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include +#include + +#include "hurricane/Commons.h" +#include "hurricane/Layer.h" +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" + +#include "crlcore/XmlParser.h" +#include "crlcore/RoutingLayerGauge.h" +#include "crlcore/RoutingGauge.h" + + +namespace { + + + const char* dupLayerGauge = + "RoutingGauge::AddLayerGauge() :\n\n" + " Attempt to re-define layer gauge %s in routing gauge %s.\n"; + + +} // End of anonymous namespace. + + + +namespace CRL { + + + using Hurricane::DataBase; + + +// ------------------------------------------------------------------- +// Class : "RoutingGauge". + + + RoutingGauge::RoutingGauge ( const char* name ) + : _name(name) + , _layerGauges() + , _viaLayers() + , _technology(DataBase::getDB()->getTechnology()) + { } + + + RoutingGauge::RoutingGauge ( const RoutingGauge& gauge ) + : _name (gauge._name) + , _layerGauges() + , _viaLayers () + , _technology (gauge._technology) + { + // Make a deep copy of the map. + for ( size_t i=0 ; igetLayer() + , gauge._layerGauges[i]->getDirection() + , gauge._layerGauges[i]->getType() + , gauge._layerGauges[i]->getDepth() + , gauge._layerGauges[i]->getDensity() + , gauge._layerGauges[i]->getOffset() + , gauge._layerGauges[i]->getPitch() + , gauge._layerGauges[i]->getWireWidth() + , gauge._layerGauges[i]->getViaWidth() ) + ); + } + + + RoutingGauge* RoutingGauge::create ( const char* name ) + { + RoutingGauge* gauge = new RoutingGauge ( name ); + + return gauge; + } + + + void RoutingGauge::_preDestroy () { + for ( size_t i=0 ; i<_layerGauges.size() ; i++ ) + _layerGauges[i]->destroy (); + } + + + void RoutingGauge::destroy() { + _preDestroy (); + + delete this; + } + + + RoutingGauge::~RoutingGauge () + { + } + + + RoutingGauge* RoutingGauge::getClone () const + { + return new RoutingGauge ( *this ); + } + + + RoutingLayerGauge* RoutingGauge::getLayerGauge ( const Layer* layer ) const + { + for ( size_t i=0 ; i < _layerGauges.size() ; i++ ) { + if ( _layerGauges[i]->getLayer() == layer ) + return _layerGauges[i]; + } + return NULL; + } + + + unsigned int RoutingGauge::getLayerDirection ( const Layer* layer ) const + { + RoutingLayerGauge* layerGauge = getLayerGauge(layer); + if ( !layerGauge ) return 0; + + return layerGauge->getDirection(); + } + + + size_t RoutingGauge::getLayerDepth ( const Layer* layer ) const + { + for ( size_t i=0 ; i < _layerGauges.size() ; i++ ) { + if ( _layerGauges[i]->getLayer()->getMask() == layer->getMask() ) + return i; + } + return UINT_MAX; + } + + + RoutingLayerGauge* RoutingGauge::getLayerGauge ( size_t depth ) const + { + if ( depth >= _layerGauges.size() ) return NULL; + return _layerGauges[depth]; + } + + + const Layer* RoutingGauge::getRoutingLayer ( size_t depth ) const + { + if ( depth >= _layerGauges.size() ) return NULL; + return _layerGauges[depth]->getLayer(); + } + + + Layer* RoutingGauge::getContactLayer ( size_t depth ) const + { + if ( depth >= _viaLayers.size() ) return NULL; + return _viaLayers[depth]; + } + + + unsigned int RoutingGauge::getLayerDirection ( size_t depth ) const + { return getLayerGauge(depth)->getDirection(); } + + + const vector& RoutingGauge::getLayerGauges () const + { + return _layerGauges; + } + + + void RoutingGauge::addLayerGauge ( RoutingLayerGauge* layerGauge ) + { + if ( getLayerGauge(layerGauge->getLayer()) != NULL ) + throw Error ( dupLayerGauge, getString(layerGauge->getLayer()->getName()).c_str() + , getString(_name).c_str() ); + + _layerGauges.push_back ( layerGauge ); + + size_t gaugeSize = _layerGauges.size(); + if ( gaugeSize > 1 ) { + Layer* viaLayer = _technology->getViaBetween(_layerGauges[gaugeSize-2]->getLayer() + ,_layerGauges[gaugeSize-1]->getLayer()); + if ( !viaLayer ) { + cerr << Error("Can't find a VIA between Gauge layers %s and %s." + ,getString(_layerGauges[gaugeSize-2]).c_str() + ,getString(_layerGauges[gaugeSize-1]).c_str()) << endl; + } + _viaLayers.push_back ( viaLayer ); + } + } + + + void RoutingGauge::checkConnexity () const + { + if ( _layerGauges.empty() ) return; + + for ( size_t i=0 ; i<_viaLayers.size() ; i++ ) { + if ( !_viaLayers[i] ) { + cerr << Error("Gap in %s: %s and %s are not contiguous." + ,getString(this).c_str() + ,getString(_layerGauges[i ]->getLayer()).c_str() + ,getString(_layerGauges[i+1]->getLayer()).c_str()) << endl; + } + if ( _layerGauges[i+1]->getType() == Constant::PinOnly ) { + cerr << Error("In %s: only first layer can be PinOnly.\n" + " (%s at depth %d)" + ,getString(this).c_str() + ,getString(_layerGauges[i+1]).c_str() + ,i+1 ) << endl; + } + } + } + + + string RoutingGauge::_getTypeName () const + { + return "CRL::RoutingGauge"; + } + + + string RoutingGauge::_getString () const + { + ostringstream os; + os << "<" << "RoutingGauge " << _name << ">"; + + return ( os.str() ); + } + + + Record* RoutingGauge::_getRecord ( Record* record ) const + { + if ( record == NULL ) + record = new Record ( getString(this) ); + + record->add ( getSlot("_name" , _name ) ); + record->add ( getSlot("_gauges" ,&_layerGauges) ); + return ( record ); + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/RoutingLayerGauge.cpp b/crlcore/src/ccore/RoutingLayerGauge.cpp new file mode 100644 index 00000000..ec7ddf8e --- /dev/null +++ b/crlcore/src/ccore/RoutingLayerGauge.cpp @@ -0,0 +1,306 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o r e L i b r a r y | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./RoutingLayerGauge.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +#include + +#include "hurricane/BasicLayer.h" + +#include "crlcore/RoutingLayerGauge.h" + + +namespace { + + + // --------------------------------------------------------------- + // Local Variables. + + const char* notBasicLayer = + "%s :\n\n" + " %s is not a .\n"; + + const char* notConductingLayer = + "%s :\n\n" + " %s is not a CONDUCTING .\n"; + + const char* negativeIndex = + "RoutingLayerGauge::getTrackIndex() :\n\n" + " In gauge %s :\n" + " Track position %s leads to a negative index [%s,%s].\n"; + + const char* overflowIndex = + "RoutingLayerGauge::getTrackIndex() :\n\n" + " In gauge %s :\n" + " Track position %s leads to an index out of bounds [%s,%s].\n"; + + const char* badExactPosition = + "RoutingLayerGauge::getTrackIndex() :\n\n" + " In gauge %s :\n" + " Track position %s do not exactly match a track.\n"; + + const char* badInterval = + "RoutingLayerGauge::getTrackNumber() :\n\n" + " In gauge %s :\n" + " Invalid interval [%s,%s] given for track number calculation.\n"; + + +} // End of anonymous namespace. + + + +namespace Constant { + + + Direction perpandicular ( unsigned int direction ) + { + switch ( direction ) { + case Horizontal: return Vertical; + case Vertical: + default: + break; + } + return Horizontal; + } + + +} // End of Constants namespace. + + + + +namespace CRL { + + + using namespace std; + + using Hurricane::Tabulation; + using Hurricane::BasicLayer; + using Hurricane::trace_in; + using Hurricane::trace_out; + using Hurricane::in_trace; + using Hurricane::tab; + + +// ------------------------------------------------------------------- +// Class : "RoutingLayerGauge" + + + RoutingLayerGauge::RoutingLayerGauge ( const Layer* layer + , unsigned int direction + , unsigned int type + , unsigned int depth + , double density + , DbU::Unit offset + , DbU::Unit pitch + , DbU::Unit wireWidth + , DbU::Unit viaWidth ) + : _layer (layer) + , _blockageLayer(layer->getBlockageLayer()) + , _direction (direction) + , _type (type) + , _depth (depth) + , _density (density) + , _offset (offset) + , _pitch (pitch) + , _wireWidth (wireWidth) + , _viaWidth (viaWidth) + { } + + + RoutingLayerGauge* RoutingLayerGauge::create ( const Layer* layer + , unsigned int direction + , unsigned int type + , unsigned int depth + , double density + , DbU::Unit offset + , DbU::Unit pitch + , DbU::Unit wireWidth + , DbU::Unit viaWidth ) + { +// Temporary: must write a more smart check. +// BasicLayer* basicLayer = dynamic_cast(layer); +// if ( basicLayer == NULL ) +// throw Error ( notBasicLayer, "CRL::RoutingLayerGauge::create()", getString(layer).c_str() ); + +// if ( basicLayer->getMaterial() != BasicLayer::Material::metal ) +// throw Error ( notConductingLayer, "CRL::RoutingLayerGauge::create()", getString(layer).c_str() ); + + RoutingLayerGauge* gauge = new RoutingLayerGauge ( layer + , direction + , type + , depth + , density + , offset + , pitch + , wireWidth + , viaWidth ); + + return gauge; + } + + + void RoutingLayerGauge::_preDestroy () + { } + + + void RoutingLayerGauge::destroy () + { + _preDestroy (); + + delete this; + } + + + RoutingLayerGauge::~RoutingLayerGauge () + { } + + + void RoutingLayerGauge::divide ( DbU::Unit dividend, long& quotient, long& modulo ) const + { + quotient = ( dividend - _offset ) / _pitch; + modulo = ( dividend - _offset ) % _pitch; + } + + + unsigned RoutingLayerGauge::getTrackNumber ( DbU::Unit start, DbU::Unit stop ) const + { + if ( start > stop ) + throw Error ( badInterval + , getString(this).c_str() + , DbU::getValueString(start).c_str() + , DbU::getValueString(stop).c_str() + ); + + long startModulo; + long startQuotient; + long stopModulo; + long stopQuotient; + long trackNumber; + + divide ( start, startQuotient, startModulo ); + divide ( stop , stopQuotient , stopModulo ); + + if ( startModulo != 0 ) startQuotient += 1; + + trackNumber = stopQuotient - startQuotient + 1; + + return ( (trackNumber>0) ? trackNumber : 0 ); + } + + + unsigned RoutingLayerGauge::getTrackIndex ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const + { + trace << "RoutingLayerGauge::getTrackIndex ( " << position << " )" << endl; + trace_in (); + + long modulo; + long depth; + + divide ( position-start, depth, modulo ); + + trace << "depth := " << depth << endl; + + if ( depth < 0 ) + throw Error ( negativeIndex + , getString(this).c_str() + , DbU::getValueString(position).c_str() + , DbU::getValueString(start).c_str() + , DbU::getValueString(stop).c_str() + ); + + if ( ( mode & Constant::Exact ) && ( modulo != 0 ) ) + throw Error ( badExactPosition, getString(this).c_str(), DbU::getValueString(position).c_str() ); + + if ( mode & Constant::Superior ) { + if ( modulo != 0 ) depth++; + } else if ( mode & Constant::Nearest ) { + if ( modulo > _pitch / 2 ) depth++; + } + + if ( (unsigned)depth >= getTrackNumber(start,stop) ) + throw Error ( overflowIndex + , getString(this).c_str() + , DbU::getValueString(position).c_str() + , DbU::getValueString(start).c_str() + , DbU::getValueString(stop).c_str() + ); + + trace_out (); + + return depth; + } + + + DbU::Unit RoutingLayerGauge::getTrackPosition ( DbU::Unit start, unsigned depth ) const + { + return depth * _pitch + _offset + start; + } + + + string RoutingLayerGauge::_getTypeName () const + { + return "CRL::RoutingLayerGauge"; + } + + + string RoutingLayerGauge::_getString () const + { + ostringstream os; + + os << "<" << "RoutingLayerGauge " << _layer->getName() << " "; + + if ( _direction == Constant::Horizontal ) os << "Horizontal "; + else os << "Vertical "; + + os << DbU::getValueString(_offset) << ",+" + << DbU::getValueString(_pitch) << " " + << _density << "% (" + << DbU::getValueString(_wireWidth) << "," + << DbU::getValueString(_viaWidth) << ")>"; + + return os.str(); + } + + + Record* RoutingLayerGauge::_getRecord () const + { + Record* record = new Record ( getString(this) ); + + record->add ( getSlot ( "_layer" , _layer ) ); + record->add ( getSlot ( "_direction", _direction ) ); + record->add ( getSlot ( "_type" , _type ) ); + record->add ( getSlot ( "_depth" , _depth ) ); + record->add ( getSlot ( "_density" , _density ) ); + record->add ( getSlot ( "_offset" , _offset ) ); + record->add ( getSlot ( "_pitch" , _pitch ) ); + record->add ( getSlot ( "_wireWidth", _wireWidth ) ); + record->add ( getSlot ( "_viaWidth" , _viaWidth ) ); + + return ( record ); + } + + +} // End of Coriolis namespace. diff --git a/crlcore/src/ccore/SearchPath.cpp b/crlcore/src/ccore/SearchPath.cpp new file mode 100644 index 00000000..8b952216 --- /dev/null +++ b/crlcore/src/ccore/SearchPath.cpp @@ -0,0 +1,83 @@ + +// -*- C++ -*- + + +# include "crlcore/SearchPath.h" + + +namespace CRL { + + + const size_t SearchPath::npos = (size_t)-1; + + + SearchPath::SearchPath () + : _paths() + , _index(npos) + , _selected("") + { + } + + + void SearchPath::replace ( const string& path, size_t index ) + { + if ( index < _paths.size() ) + _paths[index] = path; + } + + + size_t SearchPath ::locate ( const string& file, ios::openmode mode, int first, int last ) + { + for ( int i=max(0,first) ; i < min((int)_paths.size(),last) ; i++ ) { + string path = _paths[i] + "/" + file; + + fstream filestream ( path.c_str(), mode ); + if ( filestream.is_open() ) { + filestream.close (); + _selected = path; + return _index = i; + } + } + + _selected = ""; + return _index = npos; + } + + + bool SearchPath::hasPath ( const string& path ) const + { + for ( size_t i=0 ; i < _paths.size() ; i++ ) + if ( _paths[i] == path ) return true; + return false; + } + + + const string& SearchPath::operator[] ( size_t index ) const + { + static const string OutOfBound = ""; + + if ( index < _paths.size() ) return _paths[index]; + return OutOfBound; + } + + + string SearchPath::_getString () const + { + ostringstream s; + + s << ""; + return s.str(); + } + + + Record *SearchPath::_getRecord () const + { + Record* record = new Record ( "" ); + record->add ( getSlot ( "_paths" , &_paths ) ); + record->add ( getSlot ( "_selected", &_selected ) ); + record->add ( getSlot ( "_index" , _index ) ); + return record; + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/SymbolicTechnologyParser.cpp b/crlcore/src/ccore/SymbolicTechnologyParser.cpp new file mode 100644 index 00000000..efe91d60 --- /dev/null +++ b/crlcore/src/ccore/SymbolicTechnologyParser.cpp @@ -0,0 +1,581 @@ + +// -*- C++ -*- + + +#include +#include +#include + +#include +#include + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DbU.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/DiffusionLayer.h" +#include "hurricane/TransistorLayer.h" +#include "hurricane/ViaLayer.h" +#include "hurricane/ContactLayer.h" + +#include "crlcore/SymbolicTechnologyParser.h" +#include "crlcore/Utilities.h" + + + + +namespace CRL { + + + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::DbU; + using Hurricane::RegularLayer; + using Hurricane::DiffusionLayer; + using Hurricane::TransistorLayer; + using Hurricane::TransistorLayer; + using Hurricane::ContactLayer; + using Hurricane::ViaLayer; + + + const QString SymbolicTechnologyParser::UnnamedRuleError = "Rule has an empty name."; + const QString SymbolicTechnologyParser::UnnamedBasicLayerError = "Missing name attribute in ."; + const QString SymbolicTechnologyParser::UnnamedSymbolicLayerError = "Missing name attribute in <%1>."; + const QString SymbolicTechnologyParser::UnnamedLayerError = "Missing name attribute in ."; + const QString SymbolicTechnologyParser::InvalidRulePathError = "Invalid rule path \"%1\"."; + const QString SymbolicTechnologyParser::MissingValueError = "Rule \"%1\" has no attribute."; + const QString SymbolicTechnologyParser::UnknownRuleError = "Misspelled or unknown rule \"%1\"."; + const QString SymbolicTechnologyParser::UndefinedLayerError = "Reference to yet undefined layer \"%1\"."; + const QString SymbolicTechnologyParser::NotACompositeLayerError = "Rule layer \"%1\" is not a composite layer."; + const QString SymbolicTechnologyParser::NotABasicLayerError = "Rule sub-layer \"%1\" is not a basic layer."; + const QString SymbolicTechnologyParser::LayerOutnumber = "More than %1 sub-layers in <%2>."; + const QString SymbolicTechnologyParser::LayerMissingLayer = "Less than %1 sub-layers in <%2>."; + + + void SymbolicTechnologyParser::parseTechnology () + { + parseTags ( TagsTechnology ); + } + + + void SymbolicTechnologyParser::parseName () + { + _technology->setName ( readTextAsString().toStdString().c_str() ); + } + + + void SymbolicTechnologyParser::parseBasicLayer () + { + QString value; + string layerName; + BasicLayer::Material layerMaterial = BasicLayer::Material::other; + unsigned extractNumber = 0; + + value = _reader->attributes().value("name").toString(); + if ( !value.isEmpty() ) + layerName = value.toStdString (); + else + printError ( UnnamedBasicLayerError ); + + value = _reader->attributes().value("material").toString(); + if ( !value.isEmpty() ) { + if ( value == "nWell" ) layerMaterial = BasicLayer::Material::nWell; + else if ( value == "pWell" ) layerMaterial = BasicLayer::Material::pWell; + else if ( value == "nImplant" ) layerMaterial = BasicLayer::Material::nImplant; + else if ( value == "pImplant" ) layerMaterial = BasicLayer::Material::pImplant; + else if ( value == "active" ) layerMaterial = BasicLayer::Material::active; + else if ( value == "poly" ) layerMaterial = BasicLayer::Material::poly; + else if ( value == "cut" ) layerMaterial = BasicLayer::Material::cut; + else if ( value == "metal" ) layerMaterial = BasicLayer::Material::metal; + else if ( value == "blockage" ) layerMaterial = BasicLayer::Material::blockage; + else if ( value == "other" ) layerMaterial = BasicLayer::Material::other; + } + + if ( !layerName.empty() ) { + _basicLayer = BasicLayer::create ( _technology, layerName, layerMaterial, extractNumber ); + _layers [ _basicLayer->getName() ] = _basicLayer; + } + + value = _reader->attributes().value("basiclayer").toString(); + if ( not value.isEmpty() and (layerMaterial == BasicLayer::Material::blockage) ) { + layerName = value.toStdString (); + BasicLayer* routingLayer = _technology->getBasicLayer ( layerName.c_str() ); + if ( routingLayer and _basicLayer ) { + routingLayer->setBlockageLayer ( _basicLayer ); + } + } + + parseNoChilds (); + + _basicLayer = NULL; + } + + + void SymbolicTechnologyParser::parseRegularLayer () + { + QString value; + string layerName; + RegularLayer* regularLayer = NULL; + + value = _reader->attributes().value("name").toString(); + if ( !value.isEmpty() ) + layerName = value.toStdString (); + else + printError ( UnnamedSymbolicLayerError.arg("regularlayer") ); + + _layerComponents.clear (); + + parseTags ( TagsBasicLayers ); + + if ( !layerName.empty() ) { + if ( !_layerComponents.empty() ) { + if ( _layerComponents.size() > 1 ) + printError ( LayerOutnumber.arg("1","regularlayer") ); + + regularLayer = RegularLayer::create ( _technology, layerName ); + regularLayer->setBasicLayer ( _layerComponents[0] ); + _layers [ regularLayer->getName() ] = regularLayer; + _layerComponents.clear (); + } + } + } + + + void SymbolicTechnologyParser::parseDiffusionLayer () + { + QString value; + string layerName; + DiffusionLayer* layer = NULL; + + value = _reader->attributes().value("name").toString(); + if ( !value.isEmpty() ) + layerName = value.toStdString (); + else + printError ( UnnamedSymbolicLayerError.arg("diffusionlayer") ); + + _layerComponents.clear (); + + parseTags ( TagsBasicLayers ); + + if ( !layerName.empty() ) { + reverse ( _layerComponents.begin(), _layerComponents.end() ); + switch ( _layerComponents.size() ) { + case 0: + case 1: + printError ( LayerMissingLayer.arg("2","diffusionlayer") ); + break; + case 2: + _layerComponents.push_back ( NULL ); + default: + layer = DiffusionLayer::create ( _technology + , layerName + , _layerComponents[0] + , _layerComponents[1] + , _layerComponents[2] + ); + _layers [ layer->getName() ] = layer; + if ( _layerComponents.size() > 3 ) + printError ( LayerOutnumber.arg("3","diffusionlayer") ); + } + } + + _layerComponents.clear (); + } + + + void SymbolicTechnologyParser::parseTransistorLayer () + { + QString value; + string layerName; + TransistorLayer* layer = NULL; + + value = _reader->attributes().value("name").toString(); + if ( !value.isEmpty() ) + layerName = value.toStdString (); + else + printError ( UnnamedSymbolicLayerError.arg("transistorlayer") ); + + _layerComponents.clear (); + + parseTags ( TagsBasicLayers ); + + if ( !layerName.empty() ) { + reverse ( _layerComponents.begin(), _layerComponents.end() ); + switch ( _layerComponents.size() ) { + case 0: + case 1: + case 2: + printError ( LayerMissingLayer.arg("3","transistorlayer") ); + break; + case 3: + _layerComponents.push_back ( NULL ); + default: + layer = TransistorLayer::create ( _technology + , layerName + , _layerComponents[0] + , _layerComponents[1] + , _layerComponents[2] + , _layerComponents[3] + ); + _layers [ layer->getName() ] = layer; + if ( _layerComponents.size() > 4 ) + printError ( LayerOutnumber.arg("4","transistorlayer") ); + } + } + + _layerComponents.clear (); + } + + + void SymbolicTechnologyParser::parseContactLayer () + { + QString value; + string layerName; + ContactLayer* layer = NULL; + + value = _reader->attributes().value("name").toString(); + if ( !value.isEmpty() ) + layerName = value.toStdString (); + else + printError ( UnnamedSymbolicLayerError.arg("contactlayer") ); + + _layerComponents.clear (); + + parseTags ( TagsBasicLayers ); + + if ( !layerName.empty() ) { + reverse ( _layerComponents.begin(), _layerComponents.end() ); + switch ( _layerComponents.size() ) { + case 0: + case 1: + case 2: + case 3: + printError ( LayerMissingLayer.arg("3","contactlayer") ); + break; + case 4: + _layerComponents.push_back ( NULL ); + default: + layer = ContactLayer::create ( _technology + , layerName + , _layerComponents[0] + , _layerComponents[1] + , _layerComponents[2] + , _layerComponents[3] + , _layerComponents[4] + ); + _layers [ layer->getName() ] = layer; + if ( _layerComponents.size() > 5 ) + printError ( LayerOutnumber.arg("5","contactlayer") ); + } + } + + _layerComponents.clear (); + } + + + void SymbolicTechnologyParser::parseViaLayer () + { + QString value; + string layerName; + ViaLayer* layer = NULL; + + value = _reader->attributes().value("name").toString(); + if ( !value.isEmpty() ) + layerName = value.toStdString (); + else + printError ( UnnamedSymbolicLayerError.arg("vialayer") ); + + _layerComponents.clear (); + + parseTags ( TagsBasicLayers ); + + if ( !layerName.empty() ) { + reverse ( _layerComponents.begin(), _layerComponents.end() ); + switch ( _layerComponents.size() ) { + case 0: + case 1: + printError ( LayerMissingLayer.arg("3","vialayer") ); + break; + default: + layer = ViaLayer::create ( _technology + , layerName + , _layerComponents[0] + , _layerComponents[1] + , _layerComponents[2] + ); + _layers [ layer->getName() ] = layer; + if ( _layerComponents.size() > 3 ) + printError ( LayerOutnumber.arg("3","vialayer") ); + } + } + + _layerComponents.clear (); + } + + + void SymbolicTechnologyParser::parseLayer () + { + QString value; + string layerName; + + value = _reader->attributes().value("name").toString(); + if ( !value.isEmpty() ) + layerName = value.toStdString (); + else + printError ( UnnamedLayerError ); + + if ( !layerName.empty() ) { + BasicLayer* basicLayer = getBasicLayer ( QString(layerName.c_str()), false ); + if ( basicLayer ) + _layerComponents.push_back ( basicLayer ); + } + + parseNoChilds (); + } + + + void SymbolicTechnologyParser::parseSymbolic () + { + parseTags ( TagsSymbolic ); + } + + + void SymbolicTechnologyParser::parsePrecision () + { + DbU::setPrecision ( readTextAsUInt() ); + } + + + void SymbolicTechnologyParser::parseGridStep () + { + //DbU::setGridStep ( DbU::symbolic( readTextAsDouble()) ); + parseNoChilds (); + } + + + void SymbolicTechnologyParser::parseRules () + { + parseTags ( TagsRules ); + } + + + void SymbolicTechnologyParser::parseRule () + { + double doubleValue = 0.0; + Layer* ruleLayer = NULL; + BasicLayer* basicLayer = NULL; + QString ruleName; + unsigned int ruleType; + + ruleName = _reader->attributes().value("name").toString(); + if ( !ruleName.isEmpty() ) { + //cerr << qPrintable(ruleName) << endl; + ruleType = splitRulePath ( ruleName, ruleLayer, basicLayer ); + if ( ( ruleType != InvalidRule ) && ( ruleLayer ) ) { + QString ruleValue = _reader->attributes().value("value").toString(); + if ( !ruleValue.isEmpty() ) { + switch ( ruleType & ValueMask ) { + case DoubleValue: doubleValue = ruleValue.toDouble(); break; + } + switch ( ruleType ) { + case ExtentionCap: ruleLayer->setExtentionCap (basicLayer,DbU::lambda(doubleValue)); break; + case ExtentionWidth: ruleLayer->setExtentionWidth(basicLayer,DbU::lambda(doubleValue)); break; + case Enclosure: ruleLayer->setEnclosure (basicLayer,DbU::lambda(doubleValue)); break; + case MinimumWidth: ruleLayer->setMinimalSize (DbU::lambda(doubleValue)); break; + case MinimumSide: ruleLayer->setMinimalSize (DbU::lambda(doubleValue)); break; + } + } else + printError ( MissingValueError.arg(ruleName) ); + } else + if ( ruleLayer ) + printError ( UnknownRuleError.arg(ruleName) ); + } else + printError ( UnnamedRuleError ); + + parseNoChilds (); + } + + + unsigned int SymbolicTechnologyParser::splitRulePath ( const QString& path + , Layer*& ruleLayer + , BasicLayer*& basicLayer + ) + { + ruleLayer = NULL; + basicLayer = NULL; + + unsigned int ruleType = InvalidRule; + QStringList pathElements = path.split ( "." ); + + if ( pathElements.isEmpty() ) { + printError ( InvalidRulePathError.arg(path) ); + return ruleType; + } + + ruleLayer = getLayer ( pathElements[0], false ); + pathElements.pop_front (); + + basicLayer = getBasicLayer ( pathElements[0], true ); + if ( basicLayer ) pathElements.pop_front (); + + QString tailPath = pathElements.join ( "." ); + + if ( tailPath == "extention.cap" ) ruleType = ExtentionCap; + else if ( tailPath == "extention.width" ) ruleType = ExtentionWidth; + else if ( tailPath == "enclosure" ) ruleType = Enclosure; + else if ( tailPath == "minimum.width" ) ruleType = MinimumWidth; + else if ( tailPath == "minimum.side" ) ruleType = MinimumSide; + + return ruleType; + } + + + Layer* SymbolicTechnologyParser::getLayer ( const QString& name, bool ignoreError ) + { + Name layerName = name.toStdString(); + map::iterator it = _layers.find ( layerName ); + + if ( it == _layers.end() ) { + if ( !ignoreError ) + printError ( UndefinedLayerError.arg(name) ); + return NULL; + } + + return it->second; + } + + + BasicLayer* SymbolicTechnologyParser::getBasicLayer ( const QString& name, bool ignoreError ) + { + Name layerName = name.toStdString(); + map::iterator it = _layers.find ( layerName ); + + if ( it == _layers.end() ) { + if ( !ignoreError ) + printError ( UndefinedLayerError.arg(name) ); + return NULL; + } + + BasicLayer* basicLayer = dynamic_cast ( it->second ); + if ( !basicLayer ) + printError ( NotABasicLayerError.arg(name) ); + + return basicLayer; + } + + + SymbolicTechnologyParser::SymbolicTechnologyParser ( DataBase* db, QXmlStreamReader* reader ) + : XmlParser(reader,TagSetSize) + , _dataBase(db) + , _technology(NULL) + , _basicLayer(NULL) + , _layers() + , _layerComponents() + { + assert ( _dataBase != NULL ); + + _technology = db->getTechnology (); + if ( !_technology ) + _technology = Technology::create ( db, "" ); + + addTagEntry ( TagsStandAlone , "technology" , (tagParser_t)&SymbolicTechnologyParser::parseTechnology ); + addTagEntry ( TagsTechnology , "name" , (tagParser_t)&SymbolicTechnologyParser::parseName ); + addTagEntry ( TagsTechnology , "basiclayer" , (tagParser_t)&SymbolicTechnologyParser::parseBasicLayer ); + addTagEntry ( TagsTechnology , "regularlayer" , (tagParser_t)&SymbolicTechnologyParser::parseRegularLayer ); + addTagEntry ( TagsTechnology , "diffusionlayer" , (tagParser_t)&SymbolicTechnologyParser::parseDiffusionLayer ); + addTagEntry ( TagsTechnology , "transistorlayer", (tagParser_t)&SymbolicTechnologyParser::parseTransistorLayer ); + addTagEntry ( TagsTechnology , "vialayer" , (tagParser_t)&SymbolicTechnologyParser::parseViaLayer ); + addTagEntry ( TagsTechnology , "contactlayer" , (tagParser_t)&SymbolicTechnologyParser::parseContactLayer ); + addTagEntry ( TagsBasicLayers , "layer" , (tagParser_t)&SymbolicTechnologyParser::parseLayer ); + addTagEntry ( TagsTechnology , "symbolic" , (tagParser_t)&SymbolicTechnologyParser::parseSymbolic ); + addTagEntry ( TagsSymbolic , "precision" , (tagParser_t)&SymbolicTechnologyParser::parsePrecision ); + addTagEntry ( TagsSymbolic , "gridstep" , (tagParser_t)&SymbolicTechnologyParser::parseGridStep ); + addTagEntry ( TagsSymbolic , "rules" , (tagParser_t)&SymbolicTechnologyParser::parseRules ); + addTagEntry ( TagsRules , "rule" , (tagParser_t)&SymbolicTechnologyParser::parseRule ); + } + + + SymbolicTechnologyParser* SymbolicTechnologyParser::create ( DataBase* db, QXmlStreamReader* reader ) + { + return new SymbolicTechnologyParser ( db, reader ); + } + + + bool SymbolicTechnologyParser::load ( DataBase* db, const string& path ) + { + bool aborted = false; + + try { + SymbolicTechnologyParser tp ( db ); + return tp._load ( path ); + } + catch ( Error& e ) { + cerr << e.what() << endl; + aborted = true; + } + catch ( ... ) { + cout << "[ERROR] Abnormal termination: unknown exception.\n" << endl; + exit ( 2 ); + } + + if ( aborted ) { + cerr << "[ERROR] Aborting & unloading Technology." << endl; + + //Technology* technology = db->getTechnology (); + //if ( technology ) technology->destroy (); + + exit ( 1 ); + } + + return false; + } + + + void SymbolicTechnologyParser::_postLoad () + { + // Fixme. + _technology->setWorkingLayer ( "cut0" ); + _technology->setWorkingLayer ( "cut1" ); + _technology->setWorkingLayer ( "cut2" ); + _technology->setWorkingLayer ( "cut3" ); + _technology->setWorkingLayer ( "cut4" ); + _technology->setWorkingLayer ( "cut5" ); + _technology->setWorkingLayer ( "gcut" ); + _technology->setWorkingLayer ( "METAL1" ); + _technology->setWorkingLayer ( "METAL2" ); + _technology->setWorkingLayer ( "METAL3" ); + _technology->setWorkingLayer ( "METAL4" ); + _technology->setWorkingLayer ( "METAL5" ); + _technology->setWorkingLayer ( "METAL6" ); + _technology->setWorkingLayer ( "BLOCKAGE1" ); + _technology->setWorkingLayer ( "BLOCKAGE2" ); + _technology->setWorkingLayer ( "BLOCKAGE3" ); + _technology->setWorkingLayer ( "BLOCKAGE4" ); + _technology->setWorkingLayer ( "BLOCKAGE5" ); + _technology->setWorkingLayer ( "BLOCKAGE6" ); + _technology->setWorkingLayer ( "gmetalh" ); + _technology->setWorkingLayer ( "gmetalv" ); + _technology->setWorkingLayer ( "VIA12" ); + _technology->setWorkingLayer ( "VIA23" ); + _technology->setWorkingLayer ( "VIA34" ); + _technology->setWorkingLayer ( "VIA45" ); + _technology->setWorkingLayer ( "VIA56" ); + _technology->setWorkingLayer ( "gcontact" ); + } + + + const char* SymbolicTechnologyParser::_getMessage ( MessageId id ) + { + const char* message = ""; + switch ( id ) { + case OpenFile: message = "Technology configuration"; break; + } + + return message; + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/ToolEngine.cpp b/crlcore/src/ccore/ToolEngine.cpp new file mode 100644 index 00000000..a921ce62 --- /dev/null +++ b/crlcore/src/ccore/ToolEngine.cpp @@ -0,0 +1,313 @@ + + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ + + +#include "hurricane/Commons.h" +#include "hurricane/Error.h" +#include "hurricane/Cell.h" +#include "hurricane/Relation.h" + +#include "crlcore/Utilities.h" +#include "crlcore/ToolEngine.h" + + +namespace { + + + using std::cout; + using std::cerr; + using std::endl; + using std::string; + using Hurricane::ForEachIterator; + using Hurricane::_TName; + using Hurricane::Error; + using Hurricane::Name; + using Hurricane::Relation; + using Hurricane::Record; + using Hurricane::Cell; + using CRL::ToolEngine; + + + const Name ToolEnginesRelationName = "ToolEnginesRelationName"; + + +// ------------------------------------------------------------------- +// Class : "CRL::ToolEnginesRelation". + + + class ToolEnginesRelation : public Relation { + public: + // Static Methods. + static ToolEnginesRelation* getToolEnginesRelation ( const Cell* cell ); + // Constructor. + static ToolEnginesRelation* create ( Cell* masterOwner ); + // Methods. + virtual Name getName () const; + inline unsigned int getPlacementModificationFlag () const; + inline unsigned int updatePlacementModificationFlag (); + inline unsigned int getRoutingModificationFlag () const; + inline unsigned int updateRoutingModificationFlag (); + virtual string _getTypeName () const; + virtual Record* _getRecord () const; + + private: + // Internal: Attributes + unsigned int _placementModificationFlag; + unsigned int _routingModificationFlag; + + // Internal: Constructor. + ToolEnginesRelation ( Cell* masterOwner ); + protected: + virtual void _preDestroy (); + }; + + + ToolEnginesRelation::ToolEnginesRelation ( Cell* masterOwner ) + : Relation (masterOwner) + , _placementModificationFlag(0) + , _routingModificationFlag (0) + { } + + + ToolEnginesRelation* ToolEnginesRelation::create ( Cell* masterOwner ) + { + ToolEnginesRelation* enginesRelation = new ToolEnginesRelation(masterOwner); + + enginesRelation->_postCreate(); + + return enginesRelation; + } + + + void ToolEnginesRelation::_preDestroy () + { + ToolEngine* tool; + while ( (tool = getSlaveOwners().getSubSet().getFirst()) ) { + tool->setInRelationDestroy ( true ); + tool->destroy (); + } + Relation::_preDestroy (); + } + + + Name ToolEnginesRelation::getName () const + { return ToolEnginesRelationName; } + + + inline unsigned int ToolEnginesRelation::getPlacementModificationFlag () const + { return _placementModificationFlag; } + + + inline unsigned int ToolEnginesRelation::getRoutingModificationFlag () const + { return _routingModificationFlag; } + + + inline unsigned int ToolEnginesRelation::updatePlacementModificationFlag () + { return ++_placementModificationFlag; } + + + inline unsigned int ToolEnginesRelation::updateRoutingModificationFlag () + { return ++_routingModificationFlag; } + + + string ToolEnginesRelation::_getTypeName () const + { return _TName ( "ToolEnginesRelation" ); } + + + Record* ToolEnginesRelation::_getRecord () const + { + Record* record = Relation::_getRecord(); + if ( record ) { + record->add ( getSlot ( "placementModificationFlag", &_placementModificationFlag ) ); + record->add ( getSlot ( "routingModificationFlag" , &_routingModificationFlag ) ); + } + return record; + } + + + ToolEnginesRelation* ToolEnginesRelation::getToolEnginesRelation ( const Cell* cell ) + { + if ( !cell ) + throw Error ( "Can't get " + _TName("ToolEnginesRelation") + " : empty cell" ); + Property* property = cell->getProperty(ToolEnginesRelationName); + if ( !property ) + return NULL; + else { + ToolEnginesRelation* enginesRelation = dynamic_cast(property); + if ( !enginesRelation ) + throw Error ( "Bad Property type: Must be a ToolEnginesRelation" ); + return enginesRelation; + } + } + + +} // End of anonymous namespace. + + + + +namespace CRL { + + +// ------------------------------------------------------------------- +// Class : "CRL::ToolEngine". + + + ToolEngine::ToolEngine ( Cell* cell ) + : DBo() + , _cell (cell) + , _placementModificationFlag(0) + , _routingModificationFlag (0) + , _inRelationDestroy (false) + {} + + + void ToolEngine::_postCreate () + { + DBo::_postCreate(); + if ( !_cell ) + throw Error ( "Can't create " + _TName("ToolEngine") + " : empty _cell" ); + ToolEnginesRelation* enginesRelation = ToolEnginesRelation::getToolEnginesRelation(_cell); + if ( !enginesRelation ) + enginesRelation = ToolEnginesRelation::create ( _cell ); + else + forEach ( ToolEngine*, itool, enginesRelation->getSlaveOwners().getSubSet() ) { + if (itool->getName() == getName()) + throw Error ( "Can't create " + _TName("ToolEngine") + " : already exists !!" ); + } + put ( enginesRelation ); + cmess1 << " o Creating ToolEngine<" << getName() << "> for Cell <" + << _cell->getName() << ">" << endl; + } + + + void ToolEngine::_preDestroy () + { + ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell); + if ( !_inRelationDestroy ) { + if ( !relation ) + throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." ); + remove ( relation ); + } + DBo::_preDestroy(); + } + + + string ToolEngine::_getTypeName () const + { + return _TName ( "ToolEngine" ); + } + + + string ToolEngine::_getString () const + { + string s = DBo::_getString(); + s.insert(s.length() - 1, " " + getString(getName())); + return s; + } + + + Record* ToolEngine::_getRecord () const + { + Record* record = DBo::_getRecord(); + if ( record ) { + record->add ( getSlot ( "Cell" , _cell ) ); + record->add ( getSlot ( "Name" , getName() ) ); + record->add ( getSlot ( "placementModificationFlag", _placementModificationFlag ) ); + record->add ( getSlot ( "routingModificationFlag" , _routingModificationFlag ) ); + } + return record; + } + + + void ToolEngine::grabPlacementModificationFlag () + { + ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell); + if ( !relation ) + throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." ); + _placementModificationFlag = relation->updatePlacementModificationFlag(); + } + + + void ToolEngine::getPlacementModificationFlag () + { + ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell); + if ( !relation ) + throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." ); + _placementModificationFlag = relation->getPlacementModificationFlag(); + } + + + bool ToolEngine::placementModificationFlagHasChanged () + { + ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell); + if ( !relation ) + throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." ); + return ( _placementModificationFlag != relation->getPlacementModificationFlag() ); + } + + + void ToolEngine::grabRoutingModificationFlag () + { + ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell); + if ( !relation ) + throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." ); + _routingModificationFlag = relation->updateRoutingModificationFlag (); + } + + + void ToolEngine::getRoutingModificationFlag () + { + ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell); + if ( !relation ) + throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." ); + _routingModificationFlag = relation->getRoutingModificationFlag (); + } + + + bool ToolEngine::routingModificationFlagHasChanged () + { + ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell); + if ( !relation ) + throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." ); + return ( _routingModificationFlag != relation->getRoutingModificationFlag() ); + } + + + ToolEngines ToolEngine::get ( const Cell* cell ) + { + ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(cell); + + if ( relation ) + return relation->getSlaveOwners().getSubSet(); + else + return ToolEngines(); + } + + + ToolEngine* ToolEngine::get ( const Cell* cell, const Name& name ) + { + ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(cell); + if (!relation) + return NULL; + else + { + for_each_toolengine(toolengine, relation->getSlaveOwners().getSubSet()) { + if (toolengine->getName() == name) + return toolengine; + end_for; + } + return NULL; + } + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/Utilities.cpp b/crlcore/src/ccore/Utilities.cpp new file mode 100644 index 00000000..4dbc886e --- /dev/null +++ b/crlcore/src/ccore/Utilities.cpp @@ -0,0 +1,237 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./Utilities.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + +#include +#include +#include + +#include "crlcore/Utilities.h" + + +bool tty::_enabled = true; +unsigned int mstream::_activeMask = mstream::Verbose0; + +mstream cmess0 ( mstream::Verbose0, std::cout ); +mstream cmess1 ( mstream::Verbose1, std::cout ); +mstream cmess2 ( mstream::Verbose2, std::cout ); +mstream cinfo ( mstream::Info , std::cout ); + + + +namespace CRL { + + + using std::cout; + using std::cerr; + using std::endl; + using std::string; + using std::ostringstream; + + +# define SIGTFLT 1 + + + // Error messages. + const char* DupSystem = "\n Attempt to re-create Alliance System."; + const char* BadAllocProperty = "%s::create():\n Property allocation failed.\n"; + const char* BadCreate = "%s::create():\n Memory allocation failed.\n"; + const char* NullDataBase = "%s:\n\n The Hurricane DataBase have not been created yet.\n"; + const char* NullTechnology = "%s:\n\n The Hurricane DataBase do not contain any technology.\n"; + const char* NullLibrary = "%s:\n\n NULL Library given as argument.\n"; + const char* NullCell = "%s:\n\n NULL Cell given as argument.\n"; + const char* BadFopen = "%s:\n\n Unable to open %s file : \"%s\".\n"; + const char* BadColorValue = "%s() :\n\n" + " Invalid color value for color \"%s\" : \"%s\".\n"; + + System* System::_singleton = System::create (); + + +// ------------------------------------------------------------------- +// Class : "CRL::System". + + + System *System::create () + { + if ( _singleton != NULL ) { + cerr << "[WARNING] Attempt to re-create System() singleton." << endl; + return _singleton; + } + + _singleton = new System (); + + // Set the trap function for the SIGINT signal (CTRL-C). + //if ( signal(SIGINT,System::TrapSig) == SIG_ERR ) + // System::TrapSig ( SIGTFLT ); + + // Set the trap function for SIGFPE, SIGBUS, SIGABRT and SIGSEGV signals. + if ( ( signal(SIGFPE , System::trapSig) == SIG_ERR ) + || ( signal(SIGBUS , System::trapSig) == SIG_ERR ) + || ( signal(SIGABRT, System::trapSig) == SIG_ERR ) + || ( signal(SIGPIPE, System::trapSig) == SIG_ERR ) + || ( signal(SIGSEGV, System::trapSig) == SIG_ERR ) ) + System::trapSig ( SIGTFLT ); + + return _singleton; + } + + + void System::trapSig ( int sig ) + { + cerr << "\n\n[CRL ERROR] System::trapSig():\n" << endl; + + switch ( sig ) { + case SIGINT: + // User interrupt with CTRL-C. + //emergency (); + break; + + case SIGTERM: + case SIGFPE: + case SIGBUS: + case SIGSEGV: + case SIGABRT: + case SIGPIPE: + //emergency (); + + // Ouch!! This may result from a program bug. + cerr << " An program internal bug have occur "; + + if (sig == SIGFPE ) cerr << "(SIGFPE)."; + if (sig == SIGBUS ) cerr << "(SIGBUS)."; + if (sig == SIGSEGV) cerr << "(SIGSEGV)."; + if (sig == SIGPIPE) cerr << "(SIGPIPE)."; + + cerr << "\n Please e-mail to .\n" + << "\n program terminated "; + + if ( getSystem()->getCatchCore() ) { + cerr << "(core not dumped).\n"; + exit ( 1 ); + } else { + cerr << "(core will be dumped).\n"; + if ( ( signal(SIGFPE , SIG_DFL) == SIG_ERR ) + || ( signal(SIGBUS , SIG_DFL) == SIG_ERR ) + || ( signal(SIGABRT, SIG_DFL) == SIG_ERR ) + || ( signal(SIGSEGV, SIG_DFL) == SIG_ERR ) + || ( signal(SIGPIPE, SIG_DFL) == SIG_ERR ) ) + exit ( 1 ); + else { + kill ( getpid(), /*sig*/ SIGSEGV ); + return; + } + } + break; + + default: + /* Unexpected signal. */ + cerr << "\n Unexpected signal \'" << sig << "\' in trap function.\n"; + break; + } + + exit ( 1 ); + } + + + System *System::getSystem () { return _singleton; } + + +// ------------------------------------------------------------------- +// Class : "CRL::IoFile". + + + bool IoFile::open ( const string& mode ) + { + if ( isOpen() ) + throw Error ( "IoFile::Open():\n Attempt to reopen file %s\n", _path.c_str() ); + + _mode = mode; + _file = fopen ( _path.c_str(), mode.c_str() ); + _lineNumber = 0; + _eof = false; + + return _file; + } + + + void IoFile::close () + { + if ( isOpen() ) fclose ( _file ); + _file = NULL; + _lineNumber = 0; + _eof = false; + } + + + char* IoFile::readLine ( char* buffer, size_t length ) + { + assert ( buffer != NULL ); + + if ( eof() ) { + buffer[0] = '\0'; + } else { + char* result = fgets ( buffer, length-1, _file ); + if ( !result || feof(_file) ) { + _eof = true; + buffer[0] = '\0'; + } else { + _lineNumber++; + size_t readLength = strlen ( buffer ); + if ( buffer[readLength-1] == '\n' ) + buffer[readLength-1] = '\0'; + } + } + + return buffer; + } + + + string IoFile::_getString () const + { + ostringstream s; + + s << ""; + + return s.str(); + } + + + Record *IoFile::_getRecord () const + { + Record* record = new Record ( "" ); + record->add ( getSlot ( "_path", &_path ) ); + return record; + } + + +} // End of CRL namespace. + + +// ------------------------------------------------------------------- +// Class : "mstream". + + + void mstream::enable ( unsigned int mask ) { _activeMask |= mask; } + void mstream::disable ( unsigned int mask ) { _activeMask &= ~mask; } diff --git a/crlcore/src/ccore/XmlParser.cpp b/crlcore/src/ccore/XmlParser.cpp new file mode 100644 index 00000000..97e7135e --- /dev/null +++ b/crlcore/src/ccore/XmlParser.cpp @@ -0,0 +1,193 @@ + +// -*- C++ -*- + + +# include +# include + +# include + +# include + +# include "crlcore/XmlParser.h" + + + + +namespace CRL { + + + XmlParser::XmlParser ( QXmlStreamReader* reader, size_t tagsTablesSize ) + : _tagsTables(tagsTablesSize) + , _reader(reader) + { + } + + + XmlParser::~XmlParser () + { + } + + + bool XmlParser::_load ( const string& path, bool warnNotFound ) + { + QFile file ( path.c_str() ); + if ( !file.open(QFile::ReadOnly|QFile::Text) ) { + if ( warnNotFound ) { + cerr << "[ERROR] Cannot open " << _getMessage(OpenFile) << " file:" << endl; + cerr << " \"" << path << "\"." << endl; + } + return false; + } + + QXmlStreamReader reader ( &file ); + _reader = &reader; + + parseStandAlone (); + + file.close (); + if ( reader.hasError() ) { + cerr << "[ERROR] Syntax error " << _getMessage(OpenFile) << " in file:" << endl; + cerr << " \"" << path << "\"." << endl; + cerr << " (" << qPrintable(reader.errorString()) << ", line:" + << reader.lineNumber() << ")" << endl; + return false; + } + + _postLoad (); + + return true; + } + + + void XmlParser::addTagEntry ( int tagSet, const char* tag, tagParser_t tagParser ) + { + if ( (size_t)tagSet >= _tagsTables.size() ) { + cerr << "[ERROR] tagSet id " << tagSet << " is not within tag table range." << endl; + cerr << " (disabling management of tag: " << tag << ")" << endl; + return; + } + + _tagsTables[tagSet].push_back ( TagEntry(tag,tagParser) ); + } + + + void XmlParser::parseTags ( int tagSet ) + { + assert ( (size_t)tagSet < _tagsTables.size() ); + + TagsTable& tags = _tagsTables[tagSet]; + + _reader->readNext (); + while ( !_reader->atEnd() ) { + if ( _reader->isEndElement() ) { + _reader->readNext(); + break; + } + + if ( _reader->isStartElement() ) { + size_t entry = 0; + for ( ; entryname() == tags[entry]._name ) { + (this->*(tags[entry]._parser)) (); + break; + } + } + if ( entry >= tags.size() ) { +// if ( tags.size() == 1 ) { +// _reader->raiseError ( QString("missing <%1> tag").arg(tags[0]._name) ); +// } + parseUnknownTag (); + } + } else + _reader->readNext (); + } + } + + + void XmlParser::parseUnknownTag () + { + cerr << "[WARNING] Skipping unknown tag: <" + << qPrintable(_reader->name().toString()) << ">." << endl; + + _reader->readNext (); + while ( !_reader->atEnd() ) { + if ( _reader->isEndElement() ) { + _reader->readNext(); + break; + } + + if ( _reader->isStartElement() ) { + parseUnknownTag (); + } else + _reader->readNext (); + } + } + + + void XmlParser::parseStandAlone () + { + parseTags ( TagsStandAlone ); + } + + +// const char* XmlParser::readTextAsAscii () +// { +// const char* value = _reader->readElementText().toStdString().c_str(); +// if ( _reader->isEndElement() ) _reader->readNext (); + +// return value; +// } + + + QString XmlParser::readTextAsString () + { + QString value = _reader->readElementText(); + if ( _reader->isEndElement() ) _reader->readNext (); + + return value; + } + + + unsigned int XmlParser::readTextAsUInt () + { + unsigned int value = _reader->readElementText().toUInt(); + if ( _reader->isEndElement() ) _reader->readNext (); + + return value; + } + + + long XmlParser::readTextAsLong () + { + long value = _reader->readElementText().toLong(); + if ( _reader->isEndElement() ) _reader->readNext (); + + return value; + } + + + double XmlParser::readTextAsDouble () + { + double value = _reader->readElementText().toDouble(); + if ( _reader->isEndElement() ) _reader->readNext (); + + return value; + } + + + void XmlParser::printError ( const QString& error, ostream& o ) + { + o << "[ERROR] " << qPrintable(error) << endl; + + QFile* file = dynamic_cast ( _reader->device() ); + QString fileName = ""; + if ( file ) + fileName = file->fileName(); + + o << " (line: " << _reader->lineNumber() + << ", file: " << qPrintable(fileName) << ")" << endl; + } + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/agds/Agds.h b/crlcore/src/ccore/agds/Agds.h new file mode 100644 index 00000000..c6f98ff2 --- /dev/null +++ b/crlcore/src/ccore/agds/Agds.h @@ -0,0 +1,17 @@ +// author : Damien Dupuis +// date : 08.12.2009 +// -*- C++ -*- + +#ifndef __AGDS_H__ +#define __AGDS_H__ + +#include + +namespace Hurricane { + class Cell; +} + +namespace CRL { + void agdsDriver(const std::string& filePath, Hurricane::Cell* cell, std::string& name, std::string& lib, double& uUnits, double& pUnits); +} +# endif diff --git a/crlcore/src/ccore/agds/AgdsDriver.cpp b/crlcore/src/ccore/agds/AgdsDriver.cpp new file mode 100644 index 00000000..d44b724d --- /dev/null +++ b/crlcore/src/ccore/agds/AgdsDriver.cpp @@ -0,0 +1,111 @@ +// author : Damien Dupuis +// date : 08.12.2009 +// -*- C++ -*- + +#include +#include +#include +#include +using namespace std; + +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Library.h" +#include "hurricane/Go.h" +#include "hurricane/Cell.h" +#include "hurricane/Box.h" +#include "hurricane/Transformation.h" +#include "hurricane/Pad.h" +#include "hurricane/Segment.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Query.h" +using namespace Hurricane; + +#include "io/agds/GdsLibrary.h" +#include "io/agds/GdsStructure.h" +#include "io/agds/GdsRectangle.h" +using namespace IO; + +#include "Agds.h" + +namespace { +class AgdsQuery : public Query { + public: + AgdsQuery ( Cell* ); + + inline void setStructure(GdsStructure*); + + virtual bool hasGoCallback() const; + virtual void goCallback ( Go* ); + // not used but needed for compilation : + virtual void extensionGoCallback(Go*) {}; + virtual void masterCellCallback() {}; + + private: + Cell* _cell; + GdsStructure* _str; +}; + +AgdsQuery::AgdsQuery(Cell* cell) : Query(), _cell(cell), _str(NULL) { + Query::setQuery(_cell, _cell->getBoundingBox(), Transformation(), NULL, 0, Query::DoComponents); +} + +inline void AgdsQuery::setStructure(GdsStructure* str) { _str = str; } + +bool AgdsQuery::hasGoCallback() const { return true; } + +void AgdsQuery::goCallback(Go* go) { + Box b; + const BasicLayer* layer; + if (dynamic_cast(go)) { + const Pad* pad = static_cast(go); + b = pad->getBoundingBox(); + layer = dynamic_cast(pad->getLayer()); + } + else if (dynamic_cast(go)) { + const Contact* contact = static_cast(go); + b = contact->getBoundingBox(); + layer = dynamic_cast(contact->getLayer()); + } + else if (dynamic_cast(go)) { + const Segment* segment = static_cast(go); + b = segment->getBoundingBox(); + layer = dynamic_cast(segment->getLayer()); + } + else { + return; + } + GdsRectangle* rect = new GdsRectangle ( layer->getExtractNumber() + , DbU::getPhysical(b.getXMin(), DbU::Nano) + , DbU::getPhysical(b.getYMin(), DbU::Nano) + , DbU::getPhysical(b.getXMax(), DbU::Nano) + , DbU::getPhysical(b.getYMax(), DbU::Nano)); + _str->addElement(rect); +} +} // namespace + +namespace CRL { +void agdsDriver(const string& filePath, Cell* cell, string& name, string& lib, double& uUnits, double& pUnits) { + name = getString(cell->getName()); + replace(name.begin(), name.end(), ' ', '_'); + lib = getString(cell->getLibrary()->getName()); + replace(lib.begin(), lib.end(), ' ', '_'); + uUnits = 0.001; + pUnits = 1.0E-9; + GdsLibrary* gdsLib = new GdsLibrary(lib); + gdsLib->setUserUnits(uUnits); + gdsLib->setPhysUnits(pUnits); + AgdsQuery agdsQuery (cell); + + GdsStructure* str = new GdsStructure(getString(name)); + agdsQuery.setStructure(str); + + forEach ( BasicLayer*, basicLayer, DataBase::getDB()->getTechnology()->getBasicLayers() ) { + agdsQuery.setBasicLayer(*basicLayer); + agdsQuery.doQuery(); + } + + gdsLib->addStructure(str); + gdsLib->write(filePath); +} +} // namespace CRL diff --git a/crlcore/src/ccore/alliance/CMakeLists.txt b/crlcore/src/ccore/alliance/CMakeLists.txt new file mode 100644 index 00000000..9d6fe3b2 --- /dev/null +++ b/crlcore/src/ccore/alliance/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(vst) diff --git a/crlcore/src/ccore/alliance/ap/Ap.h b/crlcore/src/ccore/alliance/ap/Ap.h new file mode 100644 index 00000000..f75d6298 --- /dev/null +++ b/crlcore/src/ccore/alliance/ap/Ap.h @@ -0,0 +1,63 @@ + + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== + + + +#include +using namespace std; + +namespace Hurricane { + class Cell; +} + + +#ifndef __AP_H__ +#define __AP_H__ + + +namespace CRL { + + using namespace Hurricane; + +// ------------------------------------------------------------------- +// functions. + + void apParser ( const string& cellPath, Cell* cell ); + void apDriver ( const string& cellPath, Cell* cell, unsigned int& saveState); + +} + +# endif diff --git a/crlcore/src/ccore/alliance/ap/ApDriver.cpp b/crlcore/src/ccore/alliance/ap/ApDriver.cpp new file mode 100644 index 00000000..0a891fb5 --- /dev/null +++ b/crlcore/src/ccore/alliance/ap/ApDriver.cpp @@ -0,0 +1,450 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Christophe Alexandre | +// | E-mail : Christophe.Alexandre@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./ParsersDrivers.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +using namespace std; + +#include "hurricane/Pin.h" +#include "hurricane/Instance.h" +#include "hurricane/Net.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/Reference.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Cell.h" +#include "hurricane/Layer.h" +#include "hurricane/Warning.h" + +#include "Ap.h" + + +namespace { + +using namespace Hurricane; + +struct PinSort +{ + bool operator()(const Pin* pin1, const Pin* pin2) const { + if (pin1->getY() > pin2->getY()) + return true; + else if (pin2->getY() > pin1->getY()) + return false; + else if (pin1->getX() > pin2->getX()) + return true; + else + return false; + } +}; + + int toMBKlambda ( DbU::Unit u ) + { + return (int)( DbU::getLambda(u)*100.0 ); + } + +bool toMBKLayer ( const char*& mbkLayer + , const Name& layerName + , bool isContact =false + , bool isExternal=false + ) +{ + static bool firstCall = true; + static map tableLayer; + static map tableContact; + static map tableConnector; + static const char* untranslatable = "UNTRANSLATABLE"; + + if ( firstCall ) { + firstCall = false; + + tableLayer [ "NWELL" ] = "NWELL"; + tableLayer [ "PWELL" ] = "PWELL"; + tableLayer [ "NTIE" ] = "NTIE"; + tableLayer [ "PTIE" ] = "PTIE"; + tableLayer [ "NDIF" ] = "NDIF"; + tableLayer [ "PDIF" ] = "PDIF"; + tableLayer [ "NTRANS" ] = "NTRANS"; + tableLayer [ "PTRANS" ] = "PTRANS"; + tableLayer [ "POLY" ] = "POLY"; + + tableLayer [ "METAL1" ] = "ALU1"; + tableLayer [ "METAL2" ] = "ALU2"; + tableLayer [ "METAL3" ] = "ALU3"; + tableLayer [ "METAL4" ] = "ALU4"; + tableLayer [ "METAL5" ] = "ALU5"; + tableLayer [ "METAL6" ] = "ALU6"; + + tableLayer [ "OBSTACLE1" ] = "TALU1"; + tableLayer [ "OBSTACLE2" ] = "TALU2"; + tableLayer [ "OBSTACLE3" ] = "TALU3"; + tableLayer [ "OBSTACLE4" ] = "TALU4"; + tableLayer [ "OBSTACLE5" ] = "TALU5"; + tableLayer [ "OBSTACLE6" ] = "TALU6"; + + tableConnector [ "METAL1" ] = "CALU1"; + tableConnector [ "METAL2" ] = "CALU2"; + tableConnector [ "METAL3" ] = "CALU3"; + tableConnector [ "METAL4" ] = "CALU4"; + tableConnector [ "METAL5" ] = "CALU5"; + tableConnector [ "METAL6" ] = "CALU6"; + + tableContact [ "CONT_BODY_N" ] = "CONT_BODY_N"; + tableContact [ "CONT_BODY_P" ] = "CONT_BODY_P"; + tableContact [ "CONT_DIF_N" ] = "CONT_DIF_N"; + tableContact [ "CONT_DIF_P" ] = "CONT_DIF_P"; + tableContact [ "CONT_POLY" ] = "CONT_POLY"; + tableContact [ "VIA12" ] = "CONT_VIA"; + tableContact [ "VIA23" ] = "CONT_VIA2"; + tableContact [ "VIA34" ] = "CONT_VIA3"; + tableContact [ "VIA45" ] = "CONT_VIA4"; + tableContact [ "VIA56" ] = "CONT_VIA5"; + tableContact [ "METAL1" ] = "CONT_TURN1"; + tableContact [ "METAL2" ] = "CONT_TURN2"; + tableContact [ "METAL3" ] = "CONT_TURN3"; + tableContact [ "METAL4" ] = "CONT_TURN4"; + tableContact [ "METAL5" ] = "CONT_TURN5"; + tableContact [ "METAL6" ] = "CONT_TURN6"; + } + + map::iterator it; + if ( isContact ) { + it = tableContact.find ( layerName ); + if ( it != tableContact.end() ) { + mbkLayer = it->second; + return true; + } + } + if ( isExternal ) { + it = tableConnector.find ( layerName ); + if ( it != tableConnector.end() ) { + mbkLayer = it->second; + return true; + } + } + it = tableLayer.find ( layerName ); + if ( it != tableLayer.end() ) { + mbkLayer = it->second; + return true; + } + + mbkLayer = "UNTRANSLATED"; + return false; +} + + +string toMBKName ( const Name& name ) +{ + string mbkName = getString(name); + + if ( mbkName.size() && (mbkName[mbkName.size()-1] == ')') ) { + size_t i = mbkName.find_last_of ( '(' ); + if ( i != string::npos ) { + mbkName[i] = ' '; + mbkName.erase ( mbkName.size()-1 ); + } + } + + return mbkName; +} + + +void DumpReference(ofstream& ccell, Cell *cell) +{ + for_each_reference(reference, cell->getReferences()) { + ccell << "R " + << toMBKlambda(reference->getPoint().getX()) << "," + << toMBKlambda(reference->getPoint().getY()) << "," + << "ref_ref," + << toMBKName(reference->getName()) + << endl; + end_for; + } +} + +void DumpContacts(ofstream& ccell, Cell *cell) +{ + const char* mbkLayer; + + for_each_net(net, cell->getNets()) + { + for_each_component(component, net->getComponents()) + { + if (Contact* contact = dynamic_cast(component)) + { + if (dynamic_cast(contact)) + continue; + else + { + if ( (contact->getWidth () <= DbU::lambda(2.0)) + && (contact->getHeight() <= DbU::lambda(2.0))) + { + if (toMBKLayer(mbkLayer,contact->getLayer()->getName(),true)) + ccell << "V " + << toMBKlambda(contact->getX()) << "," + << toMBKlambda(contact->getY()) << "," + << mbkLayer << "," + << toMBKName(contact->getNet()->getName()) + << endl; + } + else + { + if (toMBKLayer(mbkLayer,contact->getLayer()->getName(),true)) + ccell << "B " + << toMBKlambda(contact->getX()) << "," + << toMBKlambda(contact->getY()) << "," + << toMBKlambda(contact->getWidth()) << "," + << toMBKlambda(contact->getHeight()) << "," + << mbkLayer << "," + << toMBKName(contact->getNet()->getName()) + << endl; + } + } + } + end_for; + } + end_for; + } +} + + + void DumpSegments ( ofstream& ccell, Cell* cell ) + { + const char* mbkLayer; + DbU::Unit x1, x2, y1, y2, width; + Segment* segment; + RoutingPad* rp; + bool external; + + forEach ( Net*, net, cell->getNets() ) { + forEach ( Component*, component, net->getComponents() ) { + if ( (rp = dynamic_cast(*component)) ) { + if ( !net->isExternal() ) continue; + + external = true; + segment = dynamic_cast(rp->getOccurrence().getEntity()); + if ( !segment ) continue; + + x1 = rp->getSourceX(); + x2 = rp->getTargetX(); + y1 = rp->getSourceY(); + y2 = rp->getTargetY(); + width = segment->getWidth(); + } else if ( (segment = dynamic_cast(*component)) ) { + external = NetExternalComponents::isExternal(*component); + x1 = segment->getSourceX(); + x2 = segment->getTargetX(); + y1 = segment->getSourceY(); + y2 = segment->getTargetY(); + width = segment->getWidth(); + } else + continue; + + if ( x1 > x2 ) swap ( x1, x2 ); + if ( y1 > y2 ) swap ( y1, y2 ); + + if ( toMBKLayer(mbkLayer,component->getLayer()->getName(),false,external) ) + ccell << "S " + << toMBKlambda(x1) << "," + << toMBKlambda(y1) << "," + << toMBKlambda(x2) << "," + << toMBKlambda(y2) << "," + << toMBKlambda(width) << "," + << toMBKName(component->getNet()->getName()) + << ",RIGHT," + << mbkLayer + << endl; + } + } + } + + +unsigned getPinIndex(Name& pinname) +{ + string pinNameString = getString(pinname); + string::size_type pointString = pinNameString.find('.'); + if (pointString == string::npos) + return 0; + else + { + string indexString(pinNameString, pointString + 1, pinNameString.size() - 1); + pinNameString = string(pinNameString, 0, pointString); + pinname = Name(pinNameString); + return atoi(indexString.c_str()); + } +} + +void DumpPins(ofstream &ccell, Cell* cell) +{ + const char* mbkLayer; + + for_each_net(net, cell->getExternalNets()) + { + typedef vector PinVector; + PinVector pinVector; + for_each_pin(pin, net->getPins()) + { + pinVector.push_back(pin); + end_for; + } + sort (pinVector.begin(), pinVector.end(), PinSort()); + set indexesSet; + for (PinVector::const_iterator pvit = pinVector.begin(); + pvit != pinVector.end(); + pvit++) + { + if ( !toMBKLayer(mbkLayer,(*pvit)->getLayer()->getName(),false) ) continue; + + Pin* pin = *pvit; + Name pinName(pin->getName()); + unsigned index = getPinIndex(pinName); + if (pinName != net->getName()) + { + throw Error("Pin name (" + getString(pinName) + + ") must look like " + + getString(net->getName()) + + "[.index] to be driven in AP format"); + } + if (indexesSet.find(index) != indexesSet.end()) + { + throw Error("Two pins on same net with same index for net : " + + getString(net->getName())); + } + indexesSet.insert(index); + if (pin->getWidth() != pin->getHeight()) + throw Warning(getString(pin->getName()) + " of " + + getString(net->getName()) + + " will be incompletely saved ... : AP format is only able to save square pins ..."); + ccell << "C " << toMBKlambda(pin->getX()) + << "," << toMBKlambda(pin->getY()) + << "," << toMBKlambda(pin->getWidth()) + << "," << toMBKName(pinName) + << "," << index + << ","; + switch (pin->getAccessDirection()) + { + case Pin::AccessDirection::NORTH: + ccell << "NORTH"; + break; + case Pin::AccessDirection::SOUTH: + ccell << "SOUTH"; + break; + case Pin::AccessDirection::EAST: + ccell << "EAST"; + break; + case Pin::AccessDirection::WEST: + ccell << "WEST"; + break; + case Pin::AccessDirection::UNDEFINED: + default: + throw Error("Pins must a have direction to generate a .ap"); + } + ccell << "," << mbkLayer << endl; + } + end_for; + } +} + +void DumpDate(ofstream &ccell) +{ + time_t tim; + time(&tim); + struct tm* rest = localtime(&tim); + ccell << rest->tm_mday + << "/" << rest->tm_mon+1 + << "/" << rest->tm_year+1900; +} + +void DumpInstances(ofstream &ccell, Cell* cell) +{ + for_each_instance(instance, cell->getNotUnplacedInstances()) + { + ccell << "I " << toMBKlambda(instance->getAbutmentBox().getXMin()) + << "," << toMBKlambda(instance->getAbutmentBox().getYMin()) + << "," << instance->getMasterCell()->getName() + << "," << instance->getName() + << ","; + + const Transformation& transformation = instance->getTransformation(); + switch (transformation.getOrientation()) { + case Transformation::Orientation::ID: + ccell << "NOSYM"; + break; + case Transformation::Orientation::R1: + ccell << "ROT_P"; + break; + case Transformation::Orientation::R2: + ccell << "SYMXY"; + break; + case Transformation::Orientation::R3: + ccell << "ROT_M"; + break; + case Transformation::Orientation::MX: + ccell << "SYM_X"; + break; + case Transformation::Orientation::XR: + ccell << "SY_RM"; + break; + case Transformation::Orientation::MY: + ccell << "SYM_Y"; + break; + case Transformation::Orientation::YR: + ccell << "SY_RP"; + break; + default: + throw Error("Unrecognized orientation in transformation"); + } + ccell << endl; + end_for; + } +} + +} + +namespace CRL { + +void apDriver( const string& cellPath, Cell *cell, unsigned int &saveState) { + ::std::ofstream ccell ( cellPath.c_str() ); + + ccell << "V ALLIANCE : 6" << endl; + unsigned scaleX = 100; + ccell << "H " << cell->getName() << ",P,"; + DumpDate(ccell); + ccell << "," << scaleX << endl; + const Box& abutmentBox = cell->getAbutmentBox(); + ccell << "A " << toMBKlambda(abutmentBox.getXMin()) + << "," << toMBKlambda(abutmentBox.getYMin()) + << "," << toMBKlambda(abutmentBox.getXMax()) + << "," << toMBKlambda(abutmentBox.getYMax()) + << endl; + DumpPins(ccell, cell); + DumpInstances(ccell, cell); + DumpSegments(ccell, cell); + DumpContacts(ccell, cell); + DumpReference(ccell, cell); + ccell << "EOF" << endl; + ccell.close (); +} + +} diff --git a/crlcore/src/ccore/alliance/ap/ApParser.cpp b/crlcore/src/ccore/alliance/ap/ApParser.cpp new file mode 100644 index 00000000..86000539 --- /dev/null +++ b/crlcore/src/ccore/alliance/ap/ApParser.cpp @@ -0,0 +1,826 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Christian Masson | +// | E-mail : Christian.Masson@lip6.fr | +// | =============================================================== | +// | C++ Module : "./ApParser.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// | 05/06/2008 - Jean-Paul Chaput | +// | Complete rewrite & simplification. | +// x-----------------------------------------------------------------x + + +#include +#include +#include +#include + +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Pin.h" +#include "hurricane/Contact.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/NetExternalComponents.h" + +#include "crlcore/Utilities.h" +#include "crlcore/AllianceFramework.h" +#include "crlcore/ToolBox.h" +#include "Ap.h" + + +namespace { + + +# define LINE_SIZE 4096 + + + using namespace Hurricane; + using namespace CRL; + + + class LayerInformation { + public: + Name _layerName; + bool _isConnector; + bool _isBlockage; + const Layer* _layer; + public: + LayerInformation (); + LayerInformation ( const Name& layerName + , const bool isConnector + , const bool isBlockage + , const Layer* layer + ); + bool isConnector () const; + bool isBlockage () const; + Name getName () const; + const Layer* getLayer () const; + }; + + + LayerInformation::LayerInformation () : _layerName() + , _isConnector(false) + , _isBlockage(false) + , _layer(NULL) + { } + + + LayerInformation::LayerInformation ( const Name& layerName + , const bool isConnector + , const bool isBlockage + , const Layer* layer + ) : _layerName(layerName) + , _isConnector(isConnector) + , _isBlockage(isBlockage) + , _layer(layer) + { } + + + bool LayerInformation::isConnector () const + { return _isConnector; } + + + bool LayerInformation::isBlockage () const + { return _isBlockage; } + + + Name LayerInformation::getName () const + { return _layerName; } + + + const Layer* LayerInformation::getLayer () const + { return _layer; } + + + class LayerInformations : public map { + public: + void setTechnology ( Technology* technology ); + void add ( const Name& apLayer + , const Name& hLayer + , bool isConnectorapLayer + , bool isBlockage + ); + private: + Technology* _technology; + }; + + + void LayerInformations::setTechnology ( Technology* technology ) + { _technology = technology; } + + + void LayerInformations::add ( const Name& apLayer + , const Name& hLayer + , bool isConnector + , bool isBlockage + ) + { + insert ( make_pair( apLayer + , LayerInformation(hLayer + ,isConnector + ,isBlockage + ,_technology->getLayer(hLayer)) + ) + ); + } + + + class ApParser { + public: + // Methods. + ApParser ( AllianceFramework* af ); + void loadFromFile ( const string& cellPath, Cell* cell ); + + private: + // Internal: enum. + enum ParserState { StateVersion + , StateHeader + , StateBody + , StateEOF + }; + // Internal: static Attributes. + static LayerInformations _layerInformations; + // Internal: Attributes. + AllianceFramework* _framework; + string _cellPath; + Cell* _cell; + double _scaleRatio; + unsigned int _anonymousId; + int _parserState; + size_t _lineNumber; + char _rawLine[LINE_SIZE]; + + protected: + // Internal: Methods. + static LayerInformation* _getLayerInformation ( const Name& layerName ); + inline DbU::Unit _getUnit ( long value ); + inline DbU::Unit _getUnit ( const char* value ); + vector _splitString ( char* s, char separator ); + Net* _getNet ( const char* apName ); + Net* _getAnonymousNet (); + Net* _safeGetNet ( const char* apName ); + void _parseVersion (); + void _parseHeader (); + void _parseAbutmentBox (); + void _parseReference (); + void _parseConnector (); + void _parseVia (); + void _parseBigVia (); + void _parseSegment (); + void _parseInstance (); + void _printWarning ( const char* format, ... ); + void _printError ( bool interrupt, const char* format, ... ); + }; + + + LayerInformations ApParser::_layerInformations; + + + ApParser::ApParser ( AllianceFramework* framework ) + : _framework(framework) + , _cellPath() + , _cell(NULL) + , _scaleRatio(100.0) + , _anonymousId(0) + , _parserState(StateVersion) + , _lineNumber(0) + { + if ( _layerInformations.empty() ) { + _layerInformations.setTechnology ( DataBase::getDB()->getTechnology() ); + + _layerInformations.add ( "NWELL" , "NWELL" , false, false ); + _layerInformations.add ( "PWELL" , "PWELL" , false, false ); + _layerInformations.add ( "NTIE" , "NTIE" , false, false ); + _layerInformations.add ( "PTIE" , "PTIE" , false, false ); + _layerInformations.add ( "NDIF" , "NDIF" , false, false ); + _layerInformations.add ( "PDIF" , "PDIF" , false, false ); + _layerInformations.add ( "NTRANS" , "NTRANS" , false, false ); + _layerInformations.add ( "PTRANS" , "PTRANS" , false, false ); + _layerInformations.add ( "POLY" , "POLY" , false, false ); + + _layerInformations.add ( "ALU1" , "METAL1" , false, false ); + _layerInformations.add ( "ALU2" , "METAL2" , false, false ); + _layerInformations.add ( "ALU3" , "METAL3" , false, false ); + _layerInformations.add ( "ALU4" , "METAL4" , false, false ); + _layerInformations.add ( "ALU5" , "METAL5" , false, false ); + _layerInformations.add ( "ALU6" , "METAL6" , false, false ); + + _layerInformations.add ( "CALU1" , "METAL1" , true, false ); + _layerInformations.add ( "CALU2" , "METAL2" , true, false ); + _layerInformations.add ( "CALU3" , "METAL3" , true, false ); + _layerInformations.add ( "CALU4" , "METAL4" , true, false ); + _layerInformations.add ( "CALU5" , "METAL5" , true, false ); + _layerInformations.add ( "CALU6" , "METAL6" , true, false ); + + _layerInformations.add ( "TALU1" , "BLOCKAGE1" , false, true ); + _layerInformations.add ( "TALU2" , "BLOCKAGE2" , false, true ); + _layerInformations.add ( "TALU3" , "BLOCKAGE3" , false, true ); + _layerInformations.add ( "TALU4" , "BLOCKAGE4" , false, true ); + _layerInformations.add ( "TALU5" , "BLOCKAGE5" , false, true ); + _layerInformations.add ( "TALU6" , "BLOCKAGE6" , false, true ); + + _layerInformations.add ( "CONT_BODY_N", "CONT_BODY_N", false, false ); + _layerInformations.add ( "CONT_BODY_P", "CONT_BODY_P", false, false ); + _layerInformations.add ( "CONT_DIF_N" , "CONT_DIF_N" , false, false ); + _layerInformations.add ( "CONT_DIF_P" , "CONT_DIF_P" , false, false ); + _layerInformations.add ( "CONT_POLY" , "CONT_POLY" , false, false ); + _layerInformations.add ( "CONT_VIA" , "VIA12" , false, false ); + _layerInformations.add ( "CONT_VIA2" , "VIA23" , false, false ); + _layerInformations.add ( "CONT_VIA3" , "VIA34" , false, false ); + _layerInformations.add ( "CONT_VIA4" , "VIA45" , false, false ); + _layerInformations.add ( "CONT_VIA5" , "VIA56" , false, false ); + _layerInformations.add ( "CONT_TURN1" , "METAL1" , false, false ); + _layerInformations.add ( "CONT_TURN2" , "METAL2" , false, false ); + _layerInformations.add ( "CONT_TURN3" , "METAL3" , false, false ); + _layerInformations.add ( "CONT_TURN4" , "METAL4" , false, false ); + _layerInformations.add ( "CONT_TURN5" , "METAL5" , false, false ); + _layerInformations.add ( "CONT_TURN6" , "METAL6" , false, false ); + } + } + + + LayerInformation* ApParser::_getLayerInformation ( const Name& layerName ) + { + map::iterator it = _layerInformations.find ( layerName ); + if ( it != _layerInformations.end() ) + return &(it->second); + + return NULL; + } + + + vector ApParser::_splitString ( char* s, char separator ) + { + vector fields; + + fields.push_back ( s ); + while ( *s != '\0' ) { + if ( *s == separator ) { + fields.push_back ( s+1 ); + *s = '\0'; + } + s++; + } + + return fields; + } + + + inline DbU::Unit ApParser::_getUnit ( long value ) + { + return DbU::lambda ( _scaleRatio*value ); + } + + + inline DbU::Unit ApParser::_getUnit ( const char* value ) + { + char* end; + long convert = strtol ( value, &end, 10 ); + + if ( *end != '\0' ) + _printError ( false + , "Incomplete string to integer conversion for \"%s\" (%ld)." + , value + , convert + ); + + return _getUnit ( convert ); + } + + + Net* ApParser::_getNet ( const char* apName ) + { + string hName = apName; + + size_t separator = hName.find ( ' ' ); + if ( separator != string::npos ) { + hName[separator] = '('; + hName += ')'; + } + + Net* net = _cell->getNet ( hName ); + if ( !net ) { + net = Net::create ( _cell, hName ); + if ( _framework->isPOWER(hName) ) { + net->setType ( Net::Type::POWER ); + net->setGlobal ( true ); + } + if ( _framework->isGROUND(hName) ) { + net->setType ( Net::Type::GROUND ); + net->setGlobal ( true ); + } + } + + return net; + } + + + Net* ApParser::_getAnonymousNet () + { + ostringstream anonymousName ( "anonymous_" ); + anonymousName << _anonymousId++; + + Net* net = Net::create ( _cell, anonymousName.str() ); + net->setAutomatic ( true ); + return net; + } + + + Net* ApParser::_safeGetNet ( const char* apName ) + { + if ( ( apName[0] == '\0' ) || !strcmp(apName,"*") ) + return _getAnonymousNet (); + + return _getNet ( apName ); + } + + + void ApParser::_parseVersion () + { + if ( strncmp(_rawLine,"V ALLIANCE : ",13) ) + _printError ( true, "Missing Alliance Version Header." ); + + int version = atoi ( _rawLine+13 ); + if ( version < 3 ) + _printError ( true, "AP version prior to 3 are not supporteds (version: %d).", version ); + } + + + void ApParser::_parseHeader () + { + if ( _rawLine[0] != 'H' ) _printError ( true, "Missing Cell Header." ); + + vector fields = _splitString ( _rawLine+2, ',' ); + + if ( fields.size() < 4 ) + _printError ( true, "Malformed header line." ); + + Name cellName = fields[0]; + _scaleRatio = 1 / strtod ( fields[3], NULL ); + + if ( cellName != _cell->getName() ) + _printError ( true + , "Cell name discrepency : file refers to %s." + , getString(_cell->getName()).c_str() + , getString(cellName).c_str() + ); + } + + + void ApParser::_parseAbutmentBox () + { + if ( _cell->getAbutmentBox().isEmpty() ) { + DbU::Unit XAB1 = 0; + DbU::Unit YAB1 = 0; + DbU::Unit XAB2 = 10; + DbU::Unit YAB2 = 10; + + vector fields = _splitString ( _rawLine+2, ',' ); + if ( fields.size() < 4 ) + _printError ( false, "Malformed Abutment Box line." ); + else { + XAB1 = _getUnit ( fields[0] ); + YAB1 = _getUnit ( fields[1] ); + XAB2 = _getUnit ( fields[2] ); + YAB2 = _getUnit ( fields[3] ); + } + + _cell->setAbutmentBox ( Box(XAB1, YAB1, XAB2, YAB2) ); + } else + _printWarning ( "Duplicated Abutment Box line (ignored)." ); + } + + + void ApParser::_parseReference () + { + static DbU::Unit XREF, YREF; + + vector fields = _splitString ( _rawLine+2, ',' ); + if ( fields.size() < 4 ) + _printError ( false, "Malformed Reference line." ); + else { + XREF = _getUnit ( fields[0] ); + YREF = _getUnit ( fields[1] ); + + if ( !strcmp(fields[2],"ref_ref") ) + Reference::create ( _cell, fields[3], XREF, YREF ); + } + } + + + void ApParser::_parseConnector () + { + static DbU::Unit XCON, YCON, WIDTH; + static unsigned int index; + static char pinName[1024]; + static Net* net; + static Pin* pin; + static LayerInformation* layerInfo; + static Pin::AccessDirection accessDirection; + static Name orientation; + static Name NORTH = "NORTH"; + static Name SOUTH = "SOUTH"; + static Name EAST = "EAST"; + static Name WEST = "WEST"; + + vector fields = _splitString ( _rawLine+2, ',' ); + if ( fields.size() < 7 ) + _printError ( false, "Malformed Connector line." ); + else { + XCON = _getUnit ( fields[0] ); + YCON = _getUnit ( fields[1] ); + WIDTH = _getUnit ( fields[2] ); + index = atoi(fields[4]); + orientation = fields[5]; + + size_t length = strlen ( fields[3] ); + if ( length > 1000 ) { + _printError ( false, "Connector name too long (exceed 1000 characters)." ); + return; + } + + strncpy ( pinName, fields[3], 1023 ); + if ( index > 0 ) { + pinName [ length ] = '.'; + strncpy ( pinName+length+1, fields[4], 1022-length ); + } + + net = _getNet ( fields[5] ); + layerInfo = _getLayerInformation ( fields[6] ); + + if ( orientation == NORTH ) accessDirection = Pin::AccessDirection::NORTH; + else if ( orientation == WEST ) accessDirection = Pin::AccessDirection::WEST; + else if ( orientation == SOUTH ) accessDirection = Pin::AccessDirection::SOUTH; + else if ( orientation == EAST ) accessDirection = Pin::AccessDirection::EAST; + else accessDirection = Pin::AccessDirection::UNDEFINED; + + if ( layerInfo && net ) { + net->setExternal ( true ); + pin = Pin::create ( net + , pinName + , accessDirection + , Pin::PlacementStatus::PLACED + , layerInfo->getLayer() + , XCON + , YCON + , WIDTH + , WIDTH + ); + //setExternal ( pin ); + } + if ( !layerInfo ) + _printError ( false, "Unknown layer name %s.", fields[6] ); + } + } + + + void ApParser::_parseVia () + { + static DbU::Unit XVIA, YVIA; + static Net* net; + static LayerInformation* layerInfo; + + vector fields = _splitString ( _rawLine+2, ',' ); + if ( fields.size() < 4 ) + _printError ( false, "Malformed VIA line." ); + else { + XVIA = _getUnit ( fields[0] ); + YVIA = _getUnit ( fields[1] ); + net = _safeGetNet ( fields[3] ); + layerInfo = _getLayerInformation ( fields[2] ); + + if ( layerInfo ) + Contact::create ( net, layerInfo->getLayer(), XVIA, YVIA ); + else + _printError ( false, "Unknown layer name %s.", fields[2] ); + } + } + + + void ApParser::_parseBigVia () + { + static DbU::Unit XVIA, YVIA, WIDTH, HEIGHT; + static Net* net; + static LayerInformation* layerInfo; + + vector fields = _splitString ( _rawLine+2, ',' ); + if ( fields.size() < 6 ) + _printError ( false, "Malformed big VIA line." ); + else { + XVIA = _getUnit ( fields[0] ); + YVIA = _getUnit ( fields[1] ); + WIDTH = _getUnit ( fields[2] ); + HEIGHT = _getUnit ( fields[3] ); + net = _safeGetNet ( fields[5] ); + layerInfo = _getLayerInformation ( fields[4] ); + + if ( layerInfo ) + Contact::create ( net, layerInfo->getLayer(), XVIA, YVIA, WIDTH, HEIGHT ); + else + _printError ( false, "Unknown layer name %s.", fields[4] ); + } + } + + + void ApParser::_parseSegment () + { + static DbU::Unit X1, Y1, X2, Y2, WIDTH; + static Net* net; + static LayerInformation* layerInfo; + + vector fields = _splitString ( _rawLine+2, ',' ); + if ( fields.size() < 8 ) + _printError ( false, "Malformed Segment line." ); + else { + X1 = _getUnit ( fields[0] ); + Y1 = _getUnit ( fields[1] ); + X2 = _getUnit ( fields[2] ); + Y2 = _getUnit ( fields[3] ); + WIDTH = _getUnit ( fields[4] ); + net = _safeGetNet ( fields[5] ); + layerInfo = _getLayerInformation ( fields[7] ); + + if ( layerInfo ) { + Segment* segment = NULL; + if ( X1 == X2 ) { + segment = Vertical::create ( net, layerInfo->getLayer(), X1, WIDTH, Y1, Y2 ); + } else if ( Y1 == Y2 ) { + segment = Horizontal::create ( net, layerInfo->getLayer(), Y1, WIDTH, X1, X2 ); + } else { + _printError ( false, "Segment neither horizontal nor vertical." ); + } + if ( layerInfo->isConnector()) { + NetExternalComponents::setExternal(segment); + } + } + else + _printError ( false, "Unknown layer name %s.", fields[7] ); + } + } + + + void ApParser::_parseInstance () + { + static DbU::Unit XINS, YINS; + static Name masterCellName; + static Name instanceName; + static Name orientName; + static Transformation::Orientation + orient = Transformation::Orientation::ID; + static Name NOSYM = "NOSYM"; + static Name SYM_X = "SYM_X"; + static Name SYM_Y = "SYM_Y"; + static Name SYMXY = "SYMXY"; + static Name ROT_P = "ROT_P"; + static Name ROT_M = "ROT_M"; + static Name SY_RM = "SY_RM"; + static Name SY_RP = "SY_RP"; + + vector fields = _splitString ( _rawLine+2, ',' ); + if ( fields.size() < 5 ) + _printError ( false, "Malformed instance line." ); + else { + XINS = _getUnit ( fields[0] ); + YINS = _getUnit ( fields[1] ); + masterCellName = fields[2]; + instanceName = fields[3]; + orientName = fields[4]; + + if (orientName == "NOSYM") orient = Transformation::Orientation::ID; + else if (orientName == "ROT_P") orient = Transformation::Orientation::R1; + else if (orientName == "SYMXY") orient = Transformation::Orientation::R2; + else if (orientName == "ROT_M") orient = Transformation::Orientation::R3; + else if (orientName == "SYM_X") orient = Transformation::Orientation::MX; + else if (orientName == "SY_RM") orient = Transformation::Orientation::XR; + else if (orientName == "SYM_Y") orient = Transformation::Orientation::MY; + else if (orientName == "SY_RP") orient = Transformation::Orientation::YR; + else + _printError ( false, "Unknown orientation (%s).", getString(orientName).c_str() ); + + Instance* instance = _cell->getInstance ( instanceName ); + if ( instance ) { + instance->setTransformation + ( getTransformation ( instance->getMasterCell()->getAbutmentBox() + , XINS + , YINS + , orient + ) + ); + instance->setPlacementStatus ( Instance::PlacementStatus::FIXED ); + } else { + Catalog::State* instanceState = _framework->getCatalog()->getState ( masterCellName ); + if ( !instanceState || (!instanceState->isFeed()) ) { + _printError ( false + , "No logical instance associated to physical instance %s." + , getString(instanceName).c_str() + ); + return; + } + + // Load a cell that is not in the logical view. Only feedthrough Cell + // could be in that case. + tab++; + Cell* masterCell = _framework->getCell ( getString(masterCellName) + , Catalog::State::Views + ); + tab--; + + if ( !masterCell ) { + _printError ( "Unable to load model %s.", getString(masterCellName).c_str() ); + return; + } + + instance = Instance::create ( _cell + , instanceName + , masterCell + , getTransformation ( masterCell->getAbutmentBox() + , XINS + , YINS + , orient + ) + , Instance::PlacementStatus::FIXED + , true // Checking of recursive calls + ); + _cell->setTerminal ( false ); + } + } + } + + + void ApParser::_printWarning ( const char* format, ... ) + { + static char formatted [ 8192 ]; + va_list args; + + va_start ( args, format ); + vsnprintf ( formatted, 8191, format, args ); + va_end ( args ); + + cerr << "[WARNING] ApParser(): " << formatted << "\n" + << " (file: " << _cellPath << ", line: " << _lineNumber << ")" << endl; + } + + + void ApParser::_printError ( bool interrupt, const char* format, ... ) + { + static char formatted [ 8192 ]; + va_list args; + + va_start ( args, format ); + vsnprintf ( formatted, 8191, format, args ); + va_end ( args ); + + cerr << "[ERROR] ApParser(): " << formatted << "\n" + << " (file: " << _cellPath << ", line: " << _lineNumber << ")" << endl; + + if ( interrupt ) + throw Error ( "ApParser processed" ); + } + + + void ApParser::loadFromFile ( const string& cellPath, Cell* cell ) + { + if ( !cell ) throw Error ( "ApParser::loadFromFile(): Cell argument is NULL." ); + + _cell = cell; + _cellPath = cellPath; + + CatalogProperty *catalogProperty + = (CatalogProperty*)cell->getProperty ( CatalogProperty::getPropertyName() ); + + if ( catalogProperty == NULL ) + throw Error ( "Missing CatalogProperty in cell %s.\n" , getString(cell->getName()).c_str() ); + + Catalog::State *state = catalogProperty->getState (); + + state->setPhysical ( true ); + if ( state->isFlattenLeaf() ) _cell->setFlattenLeaf ( true ); + + IoFile fileStream ( cellPath ); + fileStream.open ( "r" ); + + UpdateSession::open(); + + bool materializationState = Go::autoMaterializationIsDisabled (); + Go::disableAutoMaterialization (); + + _lineNumber = 0; + _parserState = StateVersion; + _scaleRatio = 100.0; + + try { + while ( !fileStream.eof() ) { + fileStream.readLine ( _rawLine, LINE_SIZE ); + _lineNumber++; + + if ( _rawLine[0] == '\0' ) { + if ( _parserState == StateEOF ) break; + + _printError ( true, "Premature end of file." ); + } else { + if ( _parserState == StateEOF ) + _printError ( true, "Garbage after EOF." ); + } + if ( !strcmp(_rawLine,"EOF") ) { _parserState = StateEOF; continue; } + + if ( _parserState == StateVersion ) { + _parseVersion (); + _parserState = StateHeader; + continue; + } + + if ( _parserState == StateHeader ) { + _parseHeader (); + _parserState = StateBody; + continue; + } + + if ( _parserState == StateBody ) { + switch ( _rawLine[0] ) { + case 'A': _parseAbutmentBox (); break; + case 'R': _parseReference (); break; + case 'V': _parseVia (); break; + case 'B': _parseBigVia (); break; + case 'S': _parseSegment (); break; + case 'I': _parseInstance (); break; + } + } + } + } catch ( Error& e ) { + if ( e.what() != "[ERROR] ApParser processed" ) + cerr << e.what() << endl; + } + + Go::enableAutoMaterialization(); + _cell->materialize(); + + UpdateSession::close (); + + if (materializationState) Go::disableAutoMaterialization (); + + fileStream.close (); + } + + +} // End of anonymous namespace. + + +namespace CRL { + + +void apParser ( const string& cellPath, Cell *cell ) +{ + cmess2 << " " << tab << "+ " << cellPath << endl; + + ApParser parser ( AllianceFramework::get() ); + + parser.loadFromFile ( cellPath, cell ); +} + + +} // End of CRL namespace. diff --git a/crlcore/src/ccore/alliance/vst/Vst.h b/crlcore/src/ccore/alliance/vst/Vst.h new file mode 100644 index 00000000..4e38ddde --- /dev/null +++ b/crlcore/src/ccore/alliance/vst/Vst.h @@ -0,0 +1,63 @@ + + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== + + + +# include + + +namespace Hurricane { + class Cell; +} + +#ifndef __VST_H__ +#define __VST_H__ + + +namespace CRL { + + using namespace std; + using namespace Hurricane; + +// ------------------------------------------------------------------- +// functions. + + void vstParser ( const string& cellPath, Cell* cell ); + void vstDriver ( const string& cellPath, Cell* cell, unsigned int& saveState); + +} + +# endif diff --git a/crlcore/src/ccore/alliance/vst/VstDriver.cpp b/crlcore/src/ccore/alliance/vst/VstDriver.cpp new file mode 100644 index 00000000..1be1add7 --- /dev/null +++ b/crlcore/src/ccore/alliance/vst/VstDriver.cpp @@ -0,0 +1,674 @@ +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// +// Date : 01/10/2004 +// Author : Christophe Alexandre +// +// Authors-Tag + +#include "hurricane/Cell.h" +#include "hurricane/Net.h" +#include "hurricane/Instance.h" +#include "hurricane/Plug.h" + +using namespace Hurricane; + +#include "crlcore/Catalog.h" +#include "crlcore/NetExtension.h" +#include "Vst.h" + +namespace { + + + using namespace CRL; + + +void FilterPointsInStrings(string& s) { + // Problem in VST... : the . which seems to represent hierachy paths + // in ap is not supported... + // So for the moment we just replace . by _ ... Hope this works + // If you are reading this message then maybe it does not!! + string::size_type iterator = s.find('.'); + while (iterator != string::npos) + { + s[iterator] = '_'; + iterator = s.find('.', iterator); + } +} + +struct StringSort +{ + + // Sorts signals taking into account parenthesis ... + // i(0) is before i(10) + bool operator()(const string* string1, const string* string2) const + { + string::size_type string1OpenPar = string1->find('('); + string::size_type string2OpenPar = string2->find('('); + if ((string1OpenPar == string::npos) || (string2OpenPar == string::npos)) + return (*string1 < *string2); + if ((string1->find('(', string1OpenPar + 1) != string::npos) + || (string2->find('(', string2OpenPar + 1) != string::npos)) + throw Error("malformed string, multi '('"); + string::size_type string1ClosePar = string1->rfind(')'); + string::size_type string2ClosePar = string2->rfind(')'); + if ((string1ClosePar == string::npos) || (string2ClosePar == string::npos)) + throw Error("malformed string, cannot find ')'"); + if ((string1ClosePar != string1->size()-1) || (string2ClosePar != string2->size()-1)) { + cerr << "string1 := \"" << *string1 << "\"" << endl; + cerr << "string2 := \"" << *string2 << "\"" << endl; + throw Error("malformed string"); + } + if ((string1->rfind(')', string1ClosePar - 1) != string::npos) + || (string2->rfind(')', string2ClosePar - 1) != string::npos)) + throw Error("malformed string, multi ')'"); + + if (string1->compare(0, string1OpenPar + 1, *string2, 0, string2OpenPar + 1)) + return (*string1 < *string2); + + string number1String = string(*string1, string1OpenPar + 1, string1->size()-string1OpenPar-2); + string number2String = string(*string2, string2OpenPar + 1, string2->size()-string2OpenPar-2); + + int number1 = atoi(number1String.c_str()); + int number2 = atoi(number2String.c_str()); + + return (number1 < number2); + } +}; + +unsigned FindIndex(const string& stringtosearch, string::size_type openpar) +{ + string numberString = string(stringtosearch, openpar+1, stringtosearch.size()-openpar-2); + return atoi(numberString.c_str()); +} + +string getNetDirection(const Net* net) { + switch (net->getDirection()) { + case Net::Direction::UNDEFINED: + return ("linkage"); + case Net::Direction::IN: + return ("in"); + case Net::Direction::OUT: + case Net::Direction::TRISTATE: + return ("out"); + case Net::Direction::INOUT: + return ("inout"); + default: + throw Error("Unrecognized direction"); + } +} + +typedef vector StringPtVector; +typedef vector StringVector; +typedef map StringNetMap; +typedef map StringPlugMap; +typedef set NetSet; +typedef vector PlugVector; + +unsigned FindBiggestName(StringPtVector& stringptvector) +{ + unsigned biggest = 0; + for (StringPtVector::const_iterator spvit = stringptvector.begin(); + spvit != stringptvector.end(); + spvit++) + { + string::size_type stringOpenPar = (*spvit)->find('('); + if (stringOpenPar != string::npos) + { + if (biggest < stringOpenPar) + biggest = stringOpenPar; + } + else + if (biggest < (*spvit)->size()) + biggest = (*spvit)->size(); + } + return biggest; +} + +void DumpPortList(ofstream &ccell, Cell* cell) +{ + ccell << " port (" << endl; + StringPtVector netsString; + StringNetMap stringNetMap; + for_each_net(net, cell->getExternalNets()) + { + const Name& name = NetExtension::getPort(net); + string* stringName; + if (!name.isEmpty()) + stringName = new string(getString(name)); + else + stringName = new string(getString(net->getName())); + netsString.push_back(stringName); + StringNetMap::iterator snmit = stringNetMap.find(stringName); + if (snmit != stringNetMap.end()) + { + throw Error("two times the same name"); + } + stringNetMap[stringName] = net; + end_for; + } + sort(netsString.begin(), netsString.end(), StringSort()); + + unsigned biggestName = FindBiggestName(netsString); + + StringVector vectorizedNetsString; + StringPtVector::const_iterator spvit = netsString.begin(); + while (spvit!=netsString.end()) + { + const string* string1 = *spvit; + string::size_type string1OpenPar = string1->find('('); + StringNetMap::iterator snmit = stringNetMap.find(string1); + if (snmit == stringNetMap.end()) + { + throw Error("Cannot find net named " + *string1); + } + Net* net1 = snmit->second; + string bitType; + if (net1->getDirection() == Net::Direction::TRISTATE) + bitType = " mux_bit bus"; + else + bitType = " bit"; + + if (string1OpenPar == string::npos) + { + vectorizedNetsString.push_back( + " " + + *string1 + + string(biggestName - string1->size() + 1, ' ') + + ": " + + getNetDirection(net1) + + bitType); + ++spvit; + continue; + } + + unsigned index1 = 0; + unsigned index2 = 0; + bool vectorFound = false; + + while (++spvit != netsString.end()) + { + if (!vectorFound) + { + index1 = index2 = FindIndex(*string1, string1OpenPar); + } + const string* string2 = *spvit; + StringNetMap::iterator snmit = stringNetMap.find(string2); + if (snmit == stringNetMap.end()) + { + throw Error("Cannot find net named " + *string2); + } + Net* net2 = snmit->second; + string::size_type string2OpenPar = string2->find('('); + if (string2OpenPar == string::npos) + break; + if (string1->compare(0, string1OpenPar + 1, *string2, 0, string2OpenPar + 1)) + break; + if (net1->getDirection() != net2->getDirection()) + break; + unsigned newIndex = FindIndex(*string2, string2OpenPar); + if (!vectorFound) + { + index1 = FindIndex(*string1, string1OpenPar); + if (newIndex != index1+1) + break; + index2 = newIndex; + vectorFound= true; + } + else + { + if (newIndex != index2+1) + break; + index2 = newIndex; + } + } + ostringstream index1StringStream; + index1StringStream << index1; + ostringstream index2StringStream; + index2StringStream << index2; + string name = string(*string1, 0, string1OpenPar); + string vectorType; + string busType; + if (net1->getDirection() == Net::Direction::TRISTATE) + { + vectorType = " mux_vector("; + busType = " bus"; + } + else + vectorType = " bit_vector("; + vectorizedNetsString.push_back( + " " + + name + + string(biggestName - name.size() + 1, ' ') + + ": " + + getNetDirection(net1) + + vectorType + + index1StringStream.str() + + " to " + + index2StringStream.str() + + ")" + + busType); + } + + StringVector::const_iterator svit = vectorizedNetsString.begin(); + while ((svit != vectorizedNetsString.end()) && (svit+1 != vectorizedNetsString.end())) + { + ccell << *(svit++) << ";" << endl; + } + if (svit != vectorizedNetsString.end()) + ccell << *svit << endl; + ccell << " );" << endl; + for (StringPtVector::iterator spvit = netsString.begin(); + spvit != netsString.end(); + spvit++) + { + delete(*spvit); + } +} + +void DumpSignalList(ofstream &ccell, Cell* cell) +{ + StringPtVector netsString; + NetSet netSet; + for_each_net(net, cell->getInternalNets()) + { + string* stringName = new string(net->getName()._getString()); + FilterPointsInStrings(*stringName); + netsString.push_back(stringName); + NetSet::iterator nsit = netSet.find(net); + if (nsit != netSet.end()) + { + throw Error("two times the same name"); + } + netSet.insert(net); + end_for; + } + sort(netsString.begin(), netsString.end(), StringSort()); + + unsigned biggestName = FindBiggestName(netsString); + + StringPtVector::const_iterator spvit = netsString.begin(); + while (spvit!=netsString.end()) + { + const string* string1 = *spvit; + string::size_type string1OpenPar = string1->find('('); + + if (string1OpenPar == string::npos) + { + ccell << "signal " + << *string1 + << string(biggestName - string1->size() + 1, ' ') + << ": bit;" + << endl; + ++spvit; + continue; + } + + unsigned index1 = FindIndex(*string1, string1OpenPar); + unsigned index2 = index1; + + while (++spvit != netsString.end()) + { + const string* string2 = *spvit; + string::size_type string2OpenPar = string2->find('('); + if (string2OpenPar == string::npos) + break; + if (string1->compare(0, string1OpenPar + 1, *string2, 0, string2OpenPar + 1)) + break; + unsigned newIndex = FindIndex(*string2, string2OpenPar); + //if (newIndex != index2+1) + // break; + index2 = newIndex; + } + ostringstream index1StringStream; + index1StringStream << index1; + ostringstream index2StringStream; + index2StringStream << index2; + string name = string(*string1, 0, string1OpenPar); + ccell << "signal " + << name + << string(biggestName - name.size() + 1, ' ') + << ": bit_vector(" + << index1StringStream.str() + << " to " + << index2StringStream.str() + << ");" + << endl; + } + + for (StringPtVector::iterator spvit = netsString.begin(); + spvit != netsString.end(); + spvit++) + { + delete(*spvit); + } +} + +void DumpConnectionList(ofstream &ccell, Instance*instance) +{ + ccell << " port map ( " << endl; + + StringPtVector netsString; + StringPlugMap stringPlugMap; + for_each_plug(plug, instance->getPlugs()) + { + Net* masterNet = plug->getMasterNet(); + const Name& name = NetExtension::getPort(masterNet); + string* netName; + if (!name.isEmpty()) + netName = new string(getString(name)); + else + netName = new string(getString(masterNet->getName())); + netsString.push_back(netName); + StringPlugMap::iterator spmit = stringPlugMap.find(netName); + if (spmit != stringPlugMap.end()) + { + throw Error("two times the same name"); + } + stringPlugMap[netName] = plug; + end_for; + } + + sort(netsString.begin(), netsString.end(), StringSort()); + + unsigned biggestName = FindBiggestName(netsString); + + StringVector connectionsString; + StringPtVector::const_iterator spvit = netsString.begin(); + while (spvit!=netsString.end()) + { + const string* string1 = *spvit; + string::size_type string1OpenPar = string1->find('('); + StringPlugMap::iterator spmit = stringPlugMap.find(string1); + if (spmit == stringPlugMap.end()) + { + throw Error("Cannot find net named " + *string1); + } + if (string1OpenPar == string::npos) + { + Plug* plug = spmit->second; + string connectedNetName; + if (plug->isConnected()) { + Net* net = plug->getNet(); + if (net->isExternal()) { + const Name& name = NetExtension::getPort(net); + if (!name.isEmpty()) + connectedNetName = getString(name); + else + connectedNetName = getString(net->getName()); + } + else + connectedNetName = getString(net->getName()); + } else { + Net* masterNet = plug->getMasterNet(); + if (masterNet->isGlobal()) // connection by name + { + for_each_net(globalnet, instance->getCell()->getGlobalNets()) + { + if (globalnet->getName() == masterNet->getName()) + { + connectedNetName = string(masterNet->getName()._getString()); + break; + } + end_for; + } + if (connectedNetName == string()) + { + throw Error("No global net " + masterNet->getName()._getString() + " in cell " + instance->getCell()->getName()._getString()); + } + + } + else + { + throw Error("Plug " + masterNet->getName()._getString() + " of instance " + instance->getName()._getString() + " must be connected"); + } + } + FilterPointsInStrings(connectedNetName); + + connectionsString.push_back( + " " + + *string1 + + string(biggestName - string1->size() + 1, ' ') + + " => " + + connectedNetName + ); + ++spvit; + continue; + } + + Plug* plug1 = spmit->second; + unsigned index1 = 0; + unsigned index2 = 0; + PlugVector plugConnectedVector; + plugConnectedVector.push_back(plug1); + bool vectorFound = false; + + while (++spvit != netsString.end()) + { + const string* string2 = *spvit; + StringPlugMap::iterator spmit = stringPlugMap.find(string2); + if (spmit == stringPlugMap.end()) + { + throw Error("Cannot find plug named " + *string2); + } + string::size_type string2OpenPar = string2->find('('); + if (string2OpenPar == string::npos) + break; + if (string1->compare(0, string1OpenPar + 1, *string2, 0, string2OpenPar + 1)) + break; + unsigned newIndex = FindIndex(*string2, string2OpenPar); + if (!vectorFound) + { + index1 = FindIndex(*string1, string1OpenPar); + if (newIndex != index1+1) + break; + index2 = newIndex; + Plug* plug2 = spmit->second; + plugConnectedVector.push_back(plug2); + vectorFound= true; + } + else + { + if (newIndex != index2+1) + break; + index2 = newIndex; + Plug* plug2 = spmit->second; + plugConnectedVector.push_back(plug2); + } + } + + if (vectorFound) + { + if (index2 < index1) + reverse(plugConnectedVector.begin(), plugConnectedVector.end()); + string connections; + PlugVector::const_iterator pvit = plugConnectedVector.begin(); + while (pvit != plugConnectedVector.end()) + { + Plug* plug = *pvit; + string connectedNetName; + if (plug->isConnected()) { + Net* net = plug->getNet(); + if (net->isExternal()) { + const Name& name = NetExtension::getPort(net); + if (!name.isEmpty()) + connectedNetName = getString(name); + else + connectedNetName = getString(net->getName()); + } + else + connectedNetName = getString(net->getName()); + } + else + if (plug->getMasterNet()->isGlobal()) + { + cerr << "Make all your connections" << endl; + exit(1); + } + FilterPointsInStrings(connectedNetName); + if (pvit+1 == plugConnectedVector.end()) + connections += connectedNetName; + else + connections += connectedNetName + "&"; + ++pvit; + } + string name = string(*string1, 0, string1OpenPar); + connectionsString.push_back( + " " + + name + + string(biggestName - name.size() + 1, ' ') + + " => " + + connections + ); + } + else + { + string name; + if (string1OpenPar != string::npos) + { + name = string(*string1, 0, string1OpenPar); + } + else + { + name = *string1; + } + + string connectedNetName; + if (plug1->isConnected()) + { + Net* net = plug1->getNet(); + if (net->isExternal()) + { + const Name& portName = NetExtension::getPort(net); + if (!portName.isEmpty()) + connectedNetName = getString(portName); + else + connectedNetName = getString(net->getName()); + } + } + else + if (plug1->getMasterNet()->isGlobal()) { + cerr << "Make all your connections" << endl; + exit(1); + } + + FilterPointsInStrings(connectedNetName); + connectionsString.push_back( + " " + + name + + string(biggestName - name.size() + 1, ' ') + + " => " + + connectedNetName + ); + } + } + + StringVector::const_iterator csit = connectionsString.begin(); + while (csit != connectionsString.end()) + { + if (csit+1 == connectionsString.end()) + ccell << *csit << endl; + else + ccell << *csit << "," << endl; + ++csit; + } + ccell << " );" << endl; + + for (StringPtVector::iterator spvit = netsString.begin(); + spvit != netsString.end(); + spvit++) + { + delete(*spvit); + } +} + +} + + +namespace CRL { + +void vstDriver ( const string &cellPath, Cell *cell, unsigned int &saveState ) +{ + ::std::ofstream ccell ( cellPath.c_str() ); + ccell << "entity " << cell->getName() << " is" << endl; + DumpPortList(ccell, cell); + ccell << "end " << cell->getName() << ";" << endl; + ccell << endl; + ccell << "architecture structural of " << cell->getName() << " is" << endl; + typedef set ModelSet; + ModelSet modelSet; + typedef list InstanceList; + InstanceList instanceList; + for_each_instance(instance, cell->getInstances()) + { + Cell* model = instance->getMasterCell(); + CatalogProperty *stateProp = + static_cast(model->getProperty(CatalogProperty::getPropertyName())); + + if (stateProp && (stateProp->getState()->isFeed())) + continue; + + modelSet.insert(model); + instanceList.push_back(instance); + end_for; + } + + for (ModelSet::const_iterator msit = modelSet.begin(); + msit != modelSet.end(); + msit++) + { + Cell* model = *msit; + ccell << "component " << model->getName() << endl; + DumpPortList(ccell, model); + ccell << "end component;" << endl; + ccell << endl; + } + + DumpSignalList(ccell, cell); + + ccell << endl << "begin" << endl << endl; + + for (InstanceList::const_iterator ilit = instanceList.begin(); + ilit != instanceList.end(); + ilit++) + { + Instance* instance = *ilit; + string insName(instance->getName()._getString()); + FilterPointsInStrings(insName); + ccell << insName << " : " << instance->getMasterCell()->getName() << endl; + + DumpConnectionList(ccell, instance); + ccell << endl; + } + ccell << "end structural;" << endl; + ccell.close (); +} + +} diff --git a/crlcore/src/ccore/alliance/vst/VstParserGrammar.hpp b/crlcore/src/ccore/alliance/vst/VstParserGrammar.hpp new file mode 100644 index 00000000..45e323c1 --- /dev/null +++ b/crlcore/src/ccore/alliance/vst/VstParserGrammar.hpp @@ -0,0 +1,333 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + Ampersand = 258, + Apostrophe = 259, + LeftParen = 260, + RightParen = 261, + DoubleStar = 262, + Star = 263, + Plus = 264, + Comma = 265, + Minus = 266, + VarAsgn = 267, + Colon = 268, + Semicolon = 269, + _LESym = 270, + _Box = 271, + _LTSym = 272, + Arrow = 273, + _EQSym = 274, + _GESym = 275, + _GTSym = 276, + Bar = 277, + _NESym = 278, + Dot = 279, + Slash = 280, + Identifier = 281, + DecimalInt = 282, + DecimalReal = 283, + AbstractLit = 284, + BasedInt = 285, + BasedReal = 286, + CharacterLit = 287, + StringLit = 288, + BitStringLit = 289, + ABS = 290, + ACCESS = 291, + AFTER = 292, + ALIAS = 293, + ALL = 294, + tok_AND = 295, + ARCHITECTURE = 296, + ARRAY = 297, + ARG = 298, + ASSERT = 299, + ATTRIBUTE = 300, + _BEGIN = 301, + BIT = 302, + BIT_VECTOR = 303, + BLOCK = 304, + BODY = 305, + BUFFER = 306, + BUS = 307, + CASE = 308, + Y_CLOCK = 309, + COMPONENT = 310, + CONFIGURATION = 311, + CONSTANT = 312, + CONVERT = 313, + DISCONNECT = 314, + DOWNTO = 315, + ELSE = 316, + ELSIF = 317, + _END = 318, + ENTITY = 319, + ERROR = 320, + _EXIT = 321, + _FILE = 322, + FOR = 323, + FUNCTION = 324, + GENERATE = 325, + GENERIC = 326, + GUARDED = 327, + IF = 328, + _IN = 329, + _INOUT = 330, + INTEGER = 331, + IS = 332, + _LABEL = 333, + LIBRARY = 334, + _LINKAGE = 335, + _LIST = 336, + LOOP = 337, + MAP = 338, + MOD = 339, + MUX_BIT = 340, + MUX_VECTOR = 341, + _NAND = 342, + NATURAL = 343, + NATURAL_VECTOR = 344, + NEW = 345, + _NEXT = 346, + _NOR = 347, + _NOT = 348, + tok_NULL = 349, + OF = 350, + ON = 351, + OPEN = 352, + _OR = 353, + OTHERS = 354, + _OUT = 355, + _PACKAGE = 356, + PORT = 357, + POSITIVE = 358, + PROCEDURE = 359, + PROCESS = 360, + RANGE = 361, + RECORD = 362, + REG_BIT = 363, + REG_VECTOR = 364, + REGISTER = 365, + REM = 366, + REPORT = 367, + RETURN = 368, + SELECT = 369, + SEVERITY = 370, + SIGNAL = 371, + _STABLE = 372, + STRING = 373, + SUBTYPE = 374, + THEN = 375, + TO = 376, + TRANSPORT = 377, + _TYPE = 378, + UNITS = 379, + UNTIL = 380, + USE = 381, + VARIABLE = 382, + WAIT = 383, + WARNING = 384, + WHEN = 385, + WHILE = 386, + WITH = 387, + WOR_BIT = 388, + WOR_VECTOR = 389, + _XOR = 390 + }; +#endif +/* Tokens. */ +#define Ampersand 258 +#define Apostrophe 259 +#define LeftParen 260 +#define RightParen 261 +#define DoubleStar 262 +#define Star 263 +#define Plus 264 +#define Comma 265 +#define Minus 266 +#define VarAsgn 267 +#define Colon 268 +#define Semicolon 269 +#define _LESym 270 +#define _Box 271 +#define _LTSym 272 +#define Arrow 273 +#define _EQSym 274 +#define _GESym 275 +#define _GTSym 276 +#define Bar 277 +#define _NESym 278 +#define Dot 279 +#define Slash 280 +#define Identifier 281 +#define DecimalInt 282 +#define DecimalReal 283 +#define AbstractLit 284 +#define BasedInt 285 +#define BasedReal 286 +#define CharacterLit 287 +#define StringLit 288 +#define BitStringLit 289 +#define ABS 290 +#define ACCESS 291 +#define AFTER 292 +#define ALIAS 293 +#define ALL 294 +#define tok_AND 295 +#define ARCHITECTURE 296 +#define ARRAY 297 +#define ARG 298 +#define ASSERT 299 +#define ATTRIBUTE 300 +#define _BEGIN 301 +#define BIT 302 +#define BIT_VECTOR 303 +#define BLOCK 304 +#define BODY 305 +#define BUFFER 306 +#define BUS 307 +#define CASE 308 +#define Y_CLOCK 309 +#define COMPONENT 310 +#define CONFIGURATION 311 +#define CONSTANT 312 +#define CONVERT 313 +#define DISCONNECT 314 +#define DOWNTO 315 +#define ELSE 316 +#define ELSIF 317 +#define _END 318 +#define ENTITY 319 +#define ERROR 320 +#define _EXIT 321 +#define _FILE 322 +#define FOR 323 +#define FUNCTION 324 +#define GENERATE 325 +#define GENERIC 326 +#define GUARDED 327 +#define IF 328 +#define _IN 329 +#define _INOUT 330 +#define INTEGER 331 +#define IS 332 +#define _LABEL 333 +#define LIBRARY 334 +#define _LINKAGE 335 +#define _LIST 336 +#define LOOP 337 +#define MAP 338 +#define MOD 339 +#define MUX_BIT 340 +#define MUX_VECTOR 341 +#define _NAND 342 +#define NATURAL 343 +#define NATURAL_VECTOR 344 +#define NEW 345 +#define _NEXT 346 +#define _NOR 347 +#define _NOT 348 +#define tok_NULL 349 +#define OF 350 +#define ON 351 +#define OPEN 352 +#define _OR 353 +#define OTHERS 354 +#define _OUT 355 +#define _PACKAGE 356 +#define PORT 357 +#define POSITIVE 358 +#define PROCEDURE 359 +#define PROCESS 360 +#define RANGE 361 +#define RECORD 362 +#define REG_BIT 363 +#define REG_VECTOR 364 +#define REGISTER 365 +#define REM 366 +#define REPORT 367 +#define RETURN 368 +#define SELECT 369 +#define SEVERITY 370 +#define SIGNAL 371 +#define _STABLE 372 +#define STRING 373 +#define SUBTYPE 374 +#define THEN 375 +#define TO 376 +#define TRANSPORT 377 +#define _TYPE 378 +#define UNITS 379 +#define UNTIL 380 +#define USE 381 +#define VARIABLE 382 +#define WAIT 383 +#define WARNING 384 +#define WHEN 385 +#define WHILE 386 +#define WITH 387 +#define WOR_BIT 388 +#define WOR_VECTOR 389 +#define _XOR 390 + + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 206 "/home/xtof/workspace/crlcore/src/calliance/vst/CParsVstGram.yy" +{ unsigned int _value; + string* _text; + char _flag; + string* _name; + string* _expr; + } +/* Line 1489 of yacc.c. */ +#line 326 "/home/xtof/workspace/crlcore/src/calliance/vst/CParsVstGram.hpp" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE VSTlval; + diff --git a/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy b/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy new file mode 100644 index 00000000..f19719e4 --- /dev/null +++ b/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy @@ -0,0 +1,1310 @@ +%{ + + +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== +// +// This file is based on the Alliance VHDL parser written by +// L.A. Tabusse, Vuong H.N., P. Bazargan-Sabet & D. Hommais. +// +// Yacc Rules for Alliance Structural VHDL. +// +// =================================================================== +// +// $Id$ + + +#include +#include + +#include +#include +#include +#include +#include +using namespace std; + +#include "hurricane/Net.h" +#include "hurricane/Cell.h" +#include "hurricane/Plug.h" +#include "hurricane/Instance.h" +#include "hurricane/UpdateSession.h" +using namespace Hurricane; + +#include "crlcore/Utilities.h" +#include "crlcore/Catalog.h" +#include "crlcore/AllianceFramework.h" +#include "crlcore/NetExtension.h" +#include "Vst.h" +using namespace CRL; + + +// Symbols from Flex which should be substituted. +# define yyrestart VSTrestart +# define yytext VSTtext +# define yywrap VSTwrap +# define yyin VSTin + + +extern void ClearVstIdentifiers (); +extern int yylex (); +extern int yywrap (); +extern void yyrestart ( FILE* ); +extern char* yytext; +extern FILE* yyin; + +int vhdLineNumber = 1; + + +namespace { + + + class Constraint { + private: + int _from; + int _to; + bool _set; + public: + Constraint () : _from(0), _to(0), _set(false) { }; + public: + int getFrom () const { return _from; } + int getTo () const { return _to; } + bool IsSet () const { return _set; } + void Set ( int from, int direction, int to ); + void UnSet () { _set = false; } + void Init ( int& index ) { index = _from; }; + void Next ( int& index ); + bool End ( int index ); + }; + + + void Constraint::Set ( int from, int direction, int to ) + { + _set = true; + _from = from; + _to = to; + } + + + void Constraint::Next ( int& index ) + { + if ( _from < _to ) index++; + else index--; + } + + + bool Constraint::End ( int index ) + { + if ( _from < _to ) return index <= _to; + + return index >= _to; + } + + + typedef vector PinVector; + typedef map VectorMap; + typedef map CellVectorMap; + + + AllianceFramework* __framework; + + + class YaccState { + public: + int _errorCount; + int _maxErrors; + queue _cellQueue; + Catalog::State* _state; + Cell* _cell; + Cell* _masterCell; + Instance* _instance; + Constraint _constraint; + vector _identifiersList; + CellVectorMap _cellVectorMap; + PinVector _instanceNets; + PinVector _masterNets; + bool _masterPort; + bool _firstPass; + bool _behavioral; + public: + YaccState () + : _errorCount(0) + , _maxErrors(10) + , _cellQueue() + , _state(NULL) + , _cell(NULL) + , _masterCell(NULL) + , _instance(NULL) + , _constraint() + , _identifiersList() + , _cellVectorMap() + , _instanceNets() + , _masterNets() + , _masterPort(true) + , _firstPass(true) + , _behavioral(false) + { } + }; + + + class YaccStateStack : public vector { + public: + YaccState* operator->() { return back(); }; + void pop_back () { delete back (); vector::pop_back (); } + }; + + + YaccStateStack __ys; + + + + + + int yyerror ( char* message ); + void VstError ( int code, const string& name ); + Net* getNet ( Cell* cell, const string& name ); + void SetNetType ( Net* net ); + +} + + +%} + + +%union { unsigned int _value; + string* _text; + char _flag; + string* _name; + string* _expr; + }; + +%token Ampersand +%token Apostrophe +%token LeftParen +%token RightParen +%token DoubleStar +%token Star +%token Plus +%token Comma +%token Minus +%token VarAsgn +%token Colon +%token Semicolon +%token _LESym +%token _Box +%token _LTSym +%token Arrow +%token _EQSym +%token _GESym +%token _GTSym +%token Bar +%token _NESym +%token Dot +%token Slash +%token <_text> Identifier +%token DecimalInt +%token DecimalReal +%token <_text> AbstractLit +%token BasedInt +%token BasedReal +%token <_text> CharacterLit +%token <_text> StringLit +%token <_text> BitStringLit +%token ABS +%token ACCESS +%token AFTER +%token ALIAS +%token ALL +%token tok_AND +%token ARCHITECTURE +%token ARRAY +%token ARG +%token ASSERT +%token ATTRIBUTE +%token _BEGIN +%token BIT +%token BIT_VECTOR +%token BLOCK +%token BODY +%token BUFFER +%token BUS +%token CASE +%token Y_CLOCK +%token COMPONENT +%token CONFIGURATION +%token CONSTANT +%token CONVERT +%token DISCONNECT +%token DOWNTO +%token ELSE +%token ELSIF +%token _END +%token ENTITY +%token ERROR +%token _EXIT +%token _FILE +%token FOR +%token FUNCTION +%token GENERATE +%token GENERIC +%token GUARDED +%token IF +%token _IN +%token _INOUT +%token INTEGER +%token IS +%token _LABEL +%token LIBRARY +%token _LINKAGE +%token _LIST +%token LOOP +%token MAP +%token MOD +%token MUX_BIT +%token MUX_VECTOR +%token _NAND +%token NATURAL +%token NATURAL_VECTOR +%token NEW +%token _NEXT +%token _NOR +%token _NOT +%token tok_NULL +%token OF +%token ON +%token OPEN +%token _OR +%token OTHERS +%token _OUT +%token _PACKAGE +%token PORT +%token POSITIVE +%token PROCEDURE +%token PROCESS +%token RANGE +%token RECORD +%token REG_BIT +%token REG_VECTOR +%token REGISTER +%token REM +%token REPORT +%token RETURN +%token SELECT +%token SEVERITY +%token SIGNAL +%token _STABLE +%token STRING +%token SUBTYPE +%token THEN +%token TO +%token TRANSPORT +%token _TYPE +%token UNITS +%token UNTIL +%token USE +%token VARIABLE +%token WAIT +%token WARNING +%token WHEN +%token WHILE +%token WITH +%token WOR_BIT +%token WOR_VECTOR +%token _XOR + +%type <_value> .mode. +%type <_value> .local_port_mode. +%type <_value> type_mark +%type <_value> .BUS. +%type <_text> .simple_name. +%type <_text> simple_name +%type <_text> a_label +%type <_name> formal_port_name +%type <_expr> actual_port_name +%type <_expr> expression +%type <_expr> relation +%type <_expr> simple_expression +%type <_expr> .sign.term..add_op__term.. +%type <_expr> term +%type <_expr> factor +%type <_expr> primary +%type <_expr> aggregate +%type <_expr> type_convertion +%type <_value> direction +%type <_value> abstractlit +%type <_name> name +%type <_name> slice_name +%type <_name> indexed_name + +%type <_text> formal_generic_name +%type <_text> generic_name +%type <_flag> .sign. + +%start design_file + + +%% +design_file + : entity_declaration + architecture_body + ; + +entity_declaration + : ENTITY + .simple_name. + IS + .generic_clause. + .port_clause. + END_ERR + .simple_name. + Semicolon_ERR + | ENTITY + error + { VstError ( 2, "" ); } + ; + +.generic_clause. + : /*empty*/ + | generic_clause + ; + +generic_clause + : GENERIC + LeftParen + formal_generic_list + RightParen_ERR + Semicolon_ERR + | GENERIC + error + Semicolon_ERR + ; + +formal_generic_list + : formal_generic_element + ...formal_generic_element.. + ; + +...formal_generic_element.. + : /*empty*/ + | ...formal_generic_element.. + Semicolon_ERR + formal_generic_element + ; + +formal_generic_element + : CONSTANT + identifier_list + Colon + type_mark + .constraint. + generic_VarAsgn__expression + { __ys->_constraint.UnSet (); + __ys->_identifiersList.clear (); + } + | error + ; + +generic_VarAsgn__expression + : VarAsgn + generic_expression + ; + +.constraint. + : /*empty*/ + | constraint + ; + +constraint + : LeftParen + range + RightParen_ERR + ; + +range + : abstractlit + direction + abstractlit { __ys->_constraint.Set ( $1, $2, $3 ); } + ; + +direction + : TO + | DOWNTO + ; + +.port_clause. + : /*empty*/ + | port_clause + ; + +port_clause + : PORT + LeftParen + formal_port_list + RightParen_ERR + Semicolon_ERR + | PORT + error + Semicolon_ERR + { VstError ( 3, "" ); } + ; + +formal_port_list + : formal_port_element + ...formal_port_element.. + ; + +...formal_port_element.. + : /*empty*/ + | ...formal_port_element.. + Semicolon_ERR + formal_port_element + ; + +formal_port_element + : .SIGNAL. + identifier_list + Colon + .mode. + type_mark + .constraint. + .BUS. + { if ( !__ys->_firstPass ) { + Net::Direction modeDirection = (Net::Direction::Code)$4; + Net::Direction typeDirection = (Net::Direction::Code)$5; + Net::Direction direction; + if ( typeDirection != Net::Direction::UNDEFINED ) + direction = typeDirection; + else + direction = modeDirection; + for ( unsigned int i=0 ; i < __ys->_identifiersList.size() ; i++ ) { + if ( __ys->_constraint.IsSet() ) { + int j; + for ( __ys->_constraint.Init(j) ; __ys->_constraint.End(j) ; __ys->_constraint.Next(j) ) { + ostringstream name; + name << *__ys->_identifiersList[i] << "(" << j << ")"; + Net* net = Net::create ( __ys->_cell, name.str() ); + net->setDirection ( direction ); + net->setExternal ( true ); + SetNetType ( net ); + __ys->_cellVectorMap[__ys->_cell][*__ys->_identifiersList[i]].push_back ( net ); + NetExtension::addPort ( net, name.str() ); + } + } else { + Net* net = Net::create ( __ys->_cell, *__ys->_identifiersList[i] ); + net->setDirection ( direction ); + net->setExternal ( true ); + SetNetType ( net ); + __ys->_cellVectorMap[__ys->_cell][*__ys->_identifiersList[i]].push_back ( net ); + NetExtension::addPort ( net, *__ys->_identifiersList[i] ); + } + } + } + + __ys->_constraint.UnSet (); + __ys->_identifiersList.clear (); + } + | error + { /* Reject tokens until the sync token Semicolon is found. */ + do { + yychar = yylex (); + } while ( (yychar != Semicolon) && (yychar != 0) ); + yyerrok; + + VstError ( 6, "" ); + } + ; + +architecture_body + : ARCHITECTURE + simple_name + { if ( ( __ys->_behavioral ) + || ( __ys->_state->isFlattenLeaf() ) + || ( __ys->_state->getDepth() <= 0 ) + ) YYACCEPT; + } + OF + simple_name + IS + { if ( __ys->_cell->getName() != *$5 ) VstError ( 1, *$5 ); } + architecture_declarative_part + _BEGIN + { if ( __ys->_firstPass ) YYACCEPT; } + architecture_statement_part + END_ERR + .simple_name. + Semicolon_ERR + { if ( ( $13 != NULL ) && ( *$13 != *$2 ) ) + VstError ( 7, *$13 ); + } + | ARCHITECTURE + error + { VstError ( 8, "" ); } + ; + +architecture_declarative_part + : ..block_declaration_item.. + ; + +..block_declaration_item.. + : /*empty*/ + | ..block_declaration_item.. + block_declaration_item + ; + +block_declaration_item + : signal_declaration + | component_declaration + | error + Semicolon_ERR + { VstError ( 9, "" ); } + ; + +signal_declaration + : SIGNAL + identifier_list + Colon + type_mark + .constraint. + .BUS. + Semicolon_ERR + { if ( !__ys->_firstPass ) { + Net::Direction direction = (Net::Direction::Code)$4; + for ( unsigned int i=0 ; i < __ys->_identifiersList.size() ; i++ ) { + if ( __ys->_constraint.IsSet() ) { + int j; + for ( __ys->_constraint.Init(j) ; __ys->_constraint.End(j) ; __ys->_constraint.Next(j) ) { + ostringstream name; + name << *__ys->_identifiersList[i] << "(" << j << ")"; + Net* net = Net::create ( __ys->_cell, name.str() ); + net->setDirection ( direction ); + net->setExternal ( false ); + SetNetType ( net ); + __ys->_cellVectorMap[__ys->_cell][*__ys->_identifiersList[i]].push_back ( net ); + } + } else { + Net* net = Net::create ( __ys->_cell, *__ys->_identifiersList[i] ); + net->setDirection ( direction ); + net->setExternal ( false ); + SetNetType ( net ); + __ys->_cellVectorMap[__ys->_cell][*__ys->_identifiersList[i]].push_back ( net ); + } + } + } + + __ys->_constraint.UnSet (); + __ys->_identifiersList.clear (); + } + ; + +component_declaration + : COMPONENT + Identifier + { if ( __ys->_firstPass ) { + if ( !__framework->getCell(*$2,Catalog::State::Views|Catalog::State::InMemory) ) + __ys->_cellQueue.push ( *$2 ); + } else { + __ys->_masterCell = __framework->getCell ( *$2, Catalog::State::Views ); + } + } + .generic_clause. + .PORT__local_port_list. + END_ERR + COMPONENT + Semicolon_ERR + ; + +.PORT__local_port_list. + : /*empty*/ + | PORT + LeftParen + local_port_list + RightParen_ERR + Semicolon_ERR + ; + +local_port_list + : local_port_element + ...local_port_element.. + ; + +...local_port_element.. + : /*empty*/ + | ...local_port_element.. + Semicolon_ERR + local_port_element + ; + +local_port_element + : .SIGNAL. + identifier_list + Colon + .local_port_mode. + type_mark + .constraint. + .BUS. + { if ( !__ys->_firstPass ) { + for ( unsigned int i=0 ; i < __ys->_identifiersList.size() ; i++ ) { + if ( __ys->_constraint.IsSet() ) { + int j; + for ( __ys->_constraint.Init(j) ; __ys->_constraint.End(j) ; __ys->_constraint.Next(j) ) { + ostringstream name; + name << *__ys->_identifiersList[i] << "(" << j << ")"; + Net* net = getNet ( __ys->_masterCell, name.str() ); + __ys->_cellVectorMap[__ys->_masterCell][*__ys->_identifiersList[i]].push_back ( net ); + } + } else { + Net* net = getNet ( __ys->_masterCell, *__ys->_identifiersList[i] ); + __ys->_cellVectorMap[__ys->_masterCell][*__ys->_identifiersList[i]].push_back ( net ); + } + } + } + + __ys->_constraint.UnSet (); + __ys->_identifiersList.clear (); + } + | error + { /* Reject tokens until the sync token Semicolon is found. */ + do { + yychar = yylex (); + } while ( (yychar != Semicolon) && (yychar != 0) ); + yyerrok; + + VstError ( 6, "" ); + } + ; + +architecture_statement_part + : ..concurrent_statement.. + ; + +..concurrent_statement.. + : /*empty*/ + | ..concurrent_statement.. + concurrent_statement + ; + +concurrent_statement + : component_instantiation_statement + | error + Semicolon_ERR + { VstError (18, ""); } + ; + +component_instantiation_statement + : a_label + simple_name + { __ys->_masterCell = __framework->getCell ( *$2, Catalog::State::Views|Catalog::State::InMemory ); + if ( !__ys->_masterCell ) + throw Error ( "CParsVst(), Line %d:\n" + " Model cell %s of instance %s has not been defined " + "in the compenent list." + , vhdLineNumber, *$2->c_str(), *$1->c_str() + ); + __ys->_instance = Instance::create ( __ys->_cell, *$1, __ys->_masterCell ); + __ys->_cell->setTerminal ( false ); + } + .generic_map_aspect. + .port_map_aspect. + Semicolon_ERR + ; + + +// ------------------------------------------------------------------- +// Generic Map. + +.generic_map_aspect. + : /*empty*/ + | generic_map_aspect + ; + +generic_map_aspect + : GENERIC + MAP + LeftParen + generic_association_list + RightParen_ERR + ; + +generic_association_list + : generic_association_element + ...generic_association_element.. + ; + +...generic_association_element.. + : /*empty*/ + | ...generic_association_element.. + Comma + generic_association_element + ; + +generic_association_element + : formal_generic_name + Arrow + actual_generic_name + | actual_generic_name + | error + ; + +formal_generic_name + : simple_name + ; + +actual_generic_name + : generic_expression + ; + +generic_expression + : generic_relation + ; + +generic_relation + : generic_simple_expression + ; + +generic_simple_expression + : .sign. + generic_term + ...generic_term.. + ; + +.sign. + : /*empty*/ + | Plus + | Minus + ; + +generic_term + : generic_factor + ; + +...generic_term.. + : /*empty*/ + /* | ...generic_term.. + generic_adding_operator + generic_term */ + ; + +generic_factor + : generic_primary + ; + +generic_primary + : generic_name + | generic_literal + | generic_aggregate + ; + +generic_aggregate + : LeftParen + generic_element_association + ...generic_element_association.. + RightParen_ERR + ; + +...generic_element_association.. + : /*empty*/ + | ...generic_element_association.. + Comma + generic_element_association + ; + +generic_element_association + : .generic_choices. + generic_expression + ; + +.generic_choices. + : /*empty*/ + ; + +/* +generic_adding_operator + : Ampersand + ; +*/ + +generic_name + : simple_name + ; + +generic_literal + : abstractlit + | StringLit + | CharacterLit + ; + + + + +// ------------------------------------------------------------------- +// Port Map. + +.port_map_aspect. + : /*empty*/ + | port_map_aspect + ; + +port_map_aspect + : PORT + MAP + LeftParen + association_list + RightParen_ERR + ; + +association_list + : association_element + ...association_element.. + ; + +...association_element.. + : /*empty*/ + | ...association_element.. + Comma + association_element + ; + +association_element + : formal_port_name + Arrow + { __ys->_masterPort = false; } + actual_port_name + { if ( __ys->_masterNets.size() != __ys->_instanceNets.size() ) + throw Error ( "CParsVst(), line %d:\n" + " Port map assignment discrepency." + , vhdLineNumber + ); + + for ( unsigned int i=0 ; i < __ys->_masterNets.size() ; i++ ) + if ( !__ys->_masterNets[i]->isGlobal() ) + __ys->_instance->getPlug ( __ys->_masterNets[i] )->setNet ( __ys->_instanceNets[i] ); + + __ys->_masterPort = true; + __ys->_masterNets.clear (); + __ys->_instanceNets.clear (); + } + | actual_port_name + { throw Error ( "CParsVst(), line %d:\n" + " While processing %s: implicit connexions are not allowed.\n" + , vhdLineNumber, getString(__ys->_instance->getName()).c_str() + ); + } + | error + { /* Reject tokens until the sync token Comma is found. */ + do { + yychar = yylex (); + } while ( (yychar != Comma) && (yychar != 0) ); + yyerrok; + + VstError ( 31, "" ); + } + ; + +formal_port_name + : name + ; + +actual_port_name + : expression + ; + +name + : simple_name + { if ( __ys->_masterPort ) { + PinVector& nets = __ys->_cellVectorMap[__ys->_masterCell][*$1]; + for ( unsigned int i=0 ; i < nets.size() ; i++ ) { + __ys->_masterNets.push_back ( nets[i] ); + } + } else { + PinVector& nets = __ys->_cellVectorMap[__ys->_cell][*$1]; + for ( unsigned int i=0 ; i < nets.size() ; i++ ) { + __ys->_instanceNets.push_back ( nets[i] ); + } + } + } + | indexed_name + | slice_name + ; + +indexed_name + : simple_name + LeftParen + abstractlit + RightParen_ERR + { ostringstream name; + name << *$1 << "(" << $3 << ")"; + if ( __ys->_masterPort ) + __ys->_masterNets.push_back ( getNet(__ys->_masterCell,name.str()) ); + else + __ys->_instanceNets.push_back ( getNet(__ys->_cell,name.str()) ); + } + ; + +slice_name + : simple_name + constraint + { int j; + for ( __ys->_constraint.Init(j) ; __ys->_constraint.End(j) ; __ys->_constraint.Next(j) ) { + ostringstream name; + name << *$1 << "(" << j << ")"; + if ( __ys->_masterPort ) + __ys->_masterNets.push_back ( getNet(__ys->_masterCell,name.str()) ); + else + __ys->_instanceNets.push_back ( getNet(__ys->_cell,name.str()) ); + } + } + ; + + +expression + : relation + ; + +relation + : simple_expression + ; + +simple_expression + : .sign.term..add_op__term.. + ; + +.sign.term..add_op__term.. + : term + | .sign.term..add_op__term.. + Ampersand + term + ; + +term + : factor + ; + + +factor + : primary + ; + +primary + : aggregate + | type_convertion + | name + ; + +aggregate + : LeftParen + expression + RightParen_ERR + ; + +type_convertion + : CONVERT + LeftParen + expression + RightParen_ERR + ; + + +.SIGNAL. + : /*empty*/ + | SIGNAL + ; + +.local_port_mode. + : /*empty*/ { $$ = Net::Direction::UNDEFINED; } + | _IN { $$ = Net::Direction::IN; } + | _OUT { $$ = Net::Direction::OUT; } + | _INOUT { $$ = Net::Direction::INOUT; } + | _LINKAGE { $$ = Net::Direction::UNDEFINED; } + ; + +.mode. + : /*empty*/ { $$ = Net::Direction::UNDEFINED; } + | _IN { $$ = Net::Direction::IN; } + | _OUT { $$ = Net::Direction::OUT; } + | _INOUT { $$ = Net::Direction::INOUT; } + | _LINKAGE { $$ = Net::Direction::UNDEFINED; } + ; + +type_mark + : BIT { $$ = Net::Direction::UNDEFINED; } + | WOR_BIT { $$ = Net::Direction::UNDEFINED; } + | MUX_BIT { $$ = Net::Direction::TRISTATE; } + | BIT_VECTOR { $$ = Net::Direction::UNDEFINED; } + | WOR_VECTOR { $$ = Net::Direction::UNDEFINED; } + | MUX_VECTOR { $$ = Net::Direction::TRISTATE; } + | INTEGER { $$ = Net::Direction::UNDEFINED; } + | NATURAL { $$ = Net::Direction::UNDEFINED; } + | NATURAL_VECTOR { $$ = Net::Direction::UNDEFINED; } + | POSITIVE { $$ = Net::Direction::UNDEFINED; } + | STRING { $$ = Net::Direction::UNDEFINED; } + | _LIST { $$ = Net::Direction::UNDEFINED; } + | ARG { $$ = Net::Direction::UNDEFINED; } + ; + +.BUS. + : /*empty*/ + | BUS + ; + +identifier_list + : Identifier { __ys->_identifiersList.push_back ( $1 ); } + ...identifier.. + ; + +...identifier.. + : /*empty*/ + | ...identifier.. + Comma + Identifier { __ys->_identifiersList.push_back ( $3 ); } + ; + +a_label + : Identifier + Colon { $$ = $1; } + ; + +.simple_name. + : /*empty*/ { $$ = NULL; } + | simple_name { $$ = $1; } + ; + +simple_name + : Identifier { $$ = $1; } + ; + +Semicolon_ERR + : Semicolon { yyerrok; } + ; + +abstractlit + : AbstractLit { $$ = atoi ( $1->c_str() ); } + ; + +RightParen_ERR + : RightParen { yyerrok; } + ; + +END_ERR + : _END { yyerrok; } + ; + + +%% + + +namespace { + + + // --------------------------------------------------------------- + // Function : "yyerror()". + // + // The Bison standard parser error (yyerror). + + int yyerror ( char* message ) + { + throw Error ( "CParsVst():\n %s before %s at line %d.\n" + , message, yytext, vhdLineNumber ); + return 0; + } + + + + + // --------------------------------------------------------------- + // Function : "VstError()". + // + // Manage errors from wich we can recover and continue a little + // while. + + void VstError ( int code, const string& name ) + { + __ys->_errorCount++; + + if ( __ys->_errorCount >= __ys->_maxErrors ) + throw Error ( "CParsVst(): Too many errors occured.\n" ); + + if ( code < 100 ) + cerr << "[ERROR] CParsVst(): Code " << code << " line " << vhdLineNumber << " :\n "; + else { + if (code < 200) + cerr << "[ERROR] CParsVst(): Code " << code << " :\n "; + } + + switch ( code ) { + case 1: cerr << "\"" << name << "\" is incompatible with the entity name." << endl; break; + case 2: cerr << "Bad entity declaration." << endl; break; + case 3: cerr << "Bad port clause declaration" << endl; break; + case 4: cerr << "Port \"" << name << "\" already declared." << endl; break; + case 5: cerr << "Illegal port declaration \"" << name << "\" (mode,type,guard mark)" << endl; break; + case 6: cerr << "Bad port declaration." << endl; break; + case 7: cerr << "\"" << name << "\" is incompatible with the architecture name." << endl; break; + case 8: cerr << "Bad architecture declaration." << endl; break; + case 9: cerr << "Illegal declaration" << endl; break; + case 10: cerr << "Signal \"" << name << "\" already declared." << endl; break; + case 11: cerr << "illegal signal declaration \"" << name << "\" (type,guard mark)." << endl; break; + case 12: cerr << "Component \"" << name << "\" already declared." << endl; break; + case 13: cerr << "Instance \"" << name << "\" already declared." << endl; break; + case 14: cerr << "Unknown component \"" << name << "\"." << endl; break; + case 15: cerr << "Illegal usage of implicit port map description" << endl; break; + case 16: cerr << "Unknown local port \"" << name << "\"." << endl; break; + case 17: cerr << "Unknown port or signal \"" << name << "\"." << endl; break; + case 18: cerr << "Illegal concurrent statement." << endl; break; + case 31: cerr << "Bad signal association." << endl; break; + case 32: cerr << "Null array not supported." << endl; break; + case 33: cerr << "Illegal constraint in declaration of type." << endl; break; + case 36: cerr << "Signal \"" << name << "\" used out of declared range." << endl; break; + case 38: cerr << "Width or/and type mismatch." << endl; break; + case 41: cerr << "Port \"" << name << "\" connected to more than one signal." << endl; break; + case 76: cerr << "Instance \"" << name << "\"mismatch with model." << endl; break; + default: cerr << "Syntax error." << endl; break; + case 200: + throw Error ( "Error(s) occured.\n" ); + } + } + + + + + // --------------------------------------------------------------- + // Function : "getNet()". + + Net* getNet ( Cell* cell, const string& name ) + { + Net* net = cell->getNet ( Name(name) ); + if ( !net ) { + throw Error ( "CParsVst(), line %d:\n" + " No net \"%s\" in cell \"%s\".\n" + , vhdLineNumber + , name.c_str() + , getString(cell->getName()).c_str() + ); + } + + return net; + } + + + + + // --------------------------------------------------------------- + // Function : "SetNetType()". + + void SetNetType ( Net* net ) + { + if ( __framework->isPOWER(net->getName()) ) { + net->setType ( Net::Type::POWER ); + net->setGlobal ( true ); + } else if ( __framework->isGROUND(net->getName()) ) { + net->setType ( Net::Type::GROUND ); + net->setGlobal ( true ); + } else if ( __framework->isCLOCK(net->getName()) ) { + net->setType ( Net::Type::CLOCK ); + } else + net->setType ( Net::Type::LOGICAL ); + } + + +} + + + + +namespace CRL { + + +// ------------------------------------------------------------------- +// Function : "vstParser()". + +void vstParser ( const string& cellPath, Cell *cell ) +{ + cmess2 << " " << tab << "+ " << cellPath << endl; tab++; + + static bool firstCall = true; + if ( firstCall ) { + firstCall = false; + __framework = AllianceFramework::get (); + } + + __ys.push_back ( new YaccState() ); + + if ( ( cellPath.size() > 4 ) && ( !cellPath.compare(cellPath.size()-4,4,".vbe") ) ) + __ys->_behavioral = true; + + CatalogProperty *sprop = + (CatalogProperty*)cell->getProperty ( CatalogProperty::getPropertyName() ); + if ( sprop == NULL ) + throw Error ( "Missing CatalogProperty in cell %s.\n" , getString(cell->getName()).c_str() ); + + __ys->_state = sprop->getState (); + __ys->_state->setLogical ( true ); + __ys->_cell = cell; + + IoFile ccell ( cellPath ); + ccell.open ( "r" ); + yyin = ccell.getFile (); + if ( !firstCall ) yyrestart ( VSTin ); + yyparse (); + + bool hasInstances = false; + while ( !__ys->_cellQueue.empty() ) { + hasInstances = true; + if ( !__framework->getCell ( getString(__ys->_cellQueue.front()) + , Catalog::State::Views + , __ys->_state->getDepth()-1) ) { + throw Error ( "CParsVst():\n" + " Unable to find cell \"%s\", please check your CRL_CATA_LIB.\n" + , getString(__ys->_cellQueue.front()).c_str() + ); + } + __ys->_cellQueue.pop (); + } + + if ( hasInstances ) cmess2 << " " << --tab << "+ " << cellPath << endl; + else --tab; + + __ys->_firstPass = false; + ccell.close (); + ccell.open ( "r" ); + yyin = ccell.getFile (); + yyrestart ( VSTin ); + UpdateSession::open (); + yyparse (); + UpdateSession::close (); + ClearVstIdentifiers (); + + __ys.pop_back(); + + ccell.close (); +} + + +} diff --git a/crlcore/src/ccore/alliance/vst/VstParserScanner.ll b/crlcore/src/ccore/alliance/vst/VstParserScanner.ll new file mode 100644 index 00000000..d64a56be --- /dev/null +++ b/crlcore/src/ccore/alliance/vst/VstParserScanner.ll @@ -0,0 +1,337 @@ +%{ + + +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== +// +// This file is based on the Alliance VHDL parser written by +// L.A. Tabusse & Vuong H.N. (1992) +// +// Lexical VHDL Analyser. Please refer to the IEEE Standard VHDL LRM +// Chapter 13 : Lexical Elements. +// +// =================================================================== +// +// $Id: CParsVstScan.ll,v 1.2 2006/02/19 00:52:44 jpc Exp $ + +# include + +# include +# include +# include +# include + +using namespace std; + +# include "VstParserGrammar.hpp" + +extern int vhdLineNumber; +extern void ClearVstIdentifiers (); + + +namespace { + + class VHDLKeywords : public map { + public: + VHDLKeywords (); + }; + + + VHDLKeywords::VHDLKeywords () { + (*this)[ "abs" ] = ABS; + (*this)[ "access" ] = ACCESS; + (*this)[ "after" ] = AFTER; + (*this)[ "alias" ] = ALIAS; + (*this)[ "all" ] = ALL; + (*this)[ "and" ] = tok_AND; + (*this)[ "architecture" ] = ARCHITECTURE; + (*this)[ "arg" ] = ARG; + (*this)[ "array" ] = ARRAY; + (*this)[ "assert" ] = ASSERT; + (*this)[ "attribute" ] = ATTRIBUTE; + + (*this)[ "begin" ] = _BEGIN; + (*this)[ "bit" ] = BIT; + (*this)[ "bit_vector" ] = BIT_VECTOR; + (*this)[ "block" ] = BLOCK; + (*this)[ "body" ] = BODY; + (*this)[ "buffer" ] = BUFFER; + (*this)[ "bus" ] = BUS; + + (*this)[ "case" ] = CASE; + (*this)[ "component" ] = COMPONENT; + (*this)[ "configuration" ] = CONFIGURATION; + (*this)[ "constant" ] = CONSTANT; + + (*this)[ "disconnect" ] = DISCONNECT; + (*this)[ "downto" ] = DOWNTO; + + (*this)[ "else" ] = ELSE; + (*this)[ "elsif" ] = ELSIF; + (*this)[ "end" ] = _END; + (*this)[ "entity" ] = ENTITY; + (*this)[ "error" ] = ERROR; + (*this)[ "exit" ] = _EXIT; + + (*this)[ "file" ] = _FILE; + (*this)[ "for" ] = FOR; + (*this)[ "function" ] = FUNCTION; + + (*this)[ "generate" ] = GENERATE; + (*this)[ "generic" ] = GENERIC; + (*this)[ "guarded" ] = GUARDED; + + (*this)[ "if" ] = IF; + (*this)[ "in" ] = _IN; + (*this)[ "inout" ] = _INOUT; + (*this)[ "integer" ] = INTEGER; + (*this)[ "is" ] = IS; + + (*this)[ "label" ] = _LABEL; + (*this)[ "library" ] = LIBRARY; + (*this)[ "linkage" ] = _LINKAGE; + (*this)[ "list" ] = _LIST; + (*this)[ "loop" ] = LOOP; + + (*this)[ "map" ] = MAP; + (*this)[ "mod" ] = MOD; + (*this)[ "mux_bit" ] = MUX_BIT; + (*this)[ "mux_vector" ] = MUX_VECTOR; + + (*this)[ "nand" ] = _NAND; + (*this)[ "natural" ] = NATURAL; + (*this)[ "new" ] = NEW; + (*this)[ "next" ] = _NEXT; + (*this)[ "nor" ] = _NOR; + (*this)[ "not" ] = _NOT; + (*this)[ "null" ] = tok_NULL; + + (*this)[ "of" ] = OF; + (*this)[ "on" ] = ON; + (*this)[ "open" ] = OPEN; + (*this)[ "or" ] = _OR; + (*this)[ "others" ] = OTHERS; + (*this)[ "out" ] = _OUT; + + (*this)[ "package" ] = _PACKAGE; + (*this)[ "port" ] = PORT; + (*this)[ "positive" ] = POSITIVE; + (*this)[ "procedure" ] = PROCEDURE; + (*this)[ "process" ] = PROCESS; + + (*this)[ "range" ] = RANGE; + (*this)[ "record" ] = RECORD; + (*this)[ "reg_bit" ] = REG_BIT; + (*this)[ "reg_vector" ] = REG_VECTOR; + (*this)[ "register" ] = REGISTER; + (*this)[ "rem" ] = REM; + (*this)[ "report" ] = REPORT; + (*this)[ "return" ] = RETURN; + + (*this)[ "select" ] = SELECT; + (*this)[ "severity" ] = SEVERITY; + (*this)[ "signal" ] = SIGNAL; + (*this)[ "stable" ] = _STABLE; + (*this)[ "string" ] = STRING; + (*this)[ "subtype" ] = SUBTYPE; + + (*this)[ "then" ] = THEN; + (*this)[ "to" ] = TO; + (*this)[ "transport" ] = TRANSPORT; + (*this)[ "type" ] = _TYPE; + + (*this)[ "units" ] = UNITS; + (*this)[ "until" ] = UNTIL; + (*this)[ "use" ] = USE; + + (*this)[ "variable" ] = VARIABLE; + + (*this)[ "wait" ] = WAIT; + (*this)[ "warning" ] = WARNING; + (*this)[ "when" ] = WHEN; + (*this)[ "while" ] = WHILE; + (*this)[ "with" ] = WITH; + (*this)[ "wor_bit" ] = WOR_BIT; + (*this)[ "wor_vector" ] = WOR_VECTOR; + + (*this)[ "xor" ] = _XOR; + } + + + class Identifiers : public vector { + public: + ~Identifiers (); + void clear (); + }; + + + Identifiers::~Identifiers () { + for ( unsigned int i=0 ; i < size() ; i++ ) + delete (*this)[i]; + } + + + void Identifiers::clear () { + for ( unsigned int i=0 ; i < size() ; i++ ) + delete (*this)[i]; + + vector::clear (); + } + + + VHDLKeywords vhdlKeywords; + Identifiers identifiers; + + char* lower ( char* str ); + +} + + +%} + + +upper_case_letter [A-Z] +digit [0-9] +special_character [\#\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\_\|] +space_character [ \t] +format_effector [\t\v\r\l\f] +end_of_line \n +lower_case_letter [a-z] +other_special_character [\!\$\@\?\[\\\]\^\`\{\}\~] + +graphic_character ({basic_graphic_character}|{lower_case_letter}|{other_special_character}) +basic_graphic_character ({upper_case_letter}|{digit}|{special_character}|{space_character}) +letter ({upper_case_letter}|{lower_case_letter}) +letter_or_digit ({letter}|{digit}) +decimal_literal {integer}(\.{integer})?({exponent})? +integer {digit}(_?{digit})* +exponent ([eE][-+]?{integer}) +base {integer} +based_integer {extended_digit}(_?{extended_digit})* +extended_digit ({digit}|[a-fA-F]) +base_specifier (B|b|O|o|X|x) + + +%% + + +{space_character} { /* separators : skip them. */ } +\& { return Ampersand; } +\' { return Apostrophe; } +\( { return LeftParen; } +\) { return RightParen; } +"**" { return DoubleStar; } +\* { return Star; } +\+ { return Plus; } +\, { return Comma; } +\- { return Minus; } +":=" { return VarAsgn; } +\: { return Colon; } +\; { return Semicolon; } +"<=" { return _LESym; } +">=" { return _GESym; } +\< { return _LTSym; } +\> { return _GTSym; } += { return _EQSym; } +\/= { return _NESym; } +"=>" { return Arrow; } +"<>" { return _Box; } +\| { return Bar; } +! { return Bar; } +\. { return Dot; } +\/ { return Slash; } + +{letter}(_?{letter_or_digit})* { + VHDLKeywords::iterator it = vhdlKeywords.find ( lower(yytext) ); + + if ( it != vhdlKeywords.end() ) { return it->second; } + + VSTlval._text = new string ( yytext ); + identifiers.push_back ( VSTlval._text ); + + return Identifier; + } + +({decimal_literal})|({base}#{based_integer}(\.{based_integer})?#({exponent})?)|({base}:{based_integer}(\.{based_integer})?:({exponent})?) { + VSTlval._text = new string ( yytext ); + identifiers.push_back ( VSTlval._text ); + return AbstractLit; + } + +'({graphic_character}|\"|\%)' { + VSTlval._text = new string ( yytext ); + identifiers.push_back ( VSTlval._text ); + return CharacterLit; + } + +(\"({graphic_character}|(\"\")|\%)*\")|(\%({graphic_character}|(\%\%)|\")*\%) { + VSTlval._text = new string ( yytext ); + identifiers.push_back ( VSTlval._text ); + return StringLit; + } + +{base_specifier}(\"{extended_digit}(_?{extended_digit})*\"|\%{extended_digit}(_?{extended_digit})*\%) { + VSTlval._text = new string ( yytext ); + identifiers.push_back ( VSTlval._text ); + return BitStringLit; + } + +\n { /* end of line */ vhdLineNumber++; } +\-\-.*$ { /* comment : skip them */ vhdLineNumber++; } +. { return *yytext; } + + +%% + + +int yywrap () { return 1; } + + +void ClearVstIdentifiers () +{ + identifiers.clear (); +} + + +namespace { + + +char* lower ( char* str ) +{ + for ( char* ptr = str; *ptr != '\0' ; ptr++ ) + *ptr = (char)tolower ( *ptr ); + + return str; +} + + +} diff --git a/crlcore/src/ccore/bookshelf/Bookshelf.h b/crlcore/src/ccore/bookshelf/Bookshelf.h new file mode 100644 index 00000000..4fa1c250 --- /dev/null +++ b/crlcore/src/ccore/bookshelf/Bookshelf.h @@ -0,0 +1,67 @@ + + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// +// +// Date : 25/10/2005 +// Author : Damien Dupuis +// +// Authors-Tag + +// ************************************************************************************ +// File: BK.h +// ************************************************************************************ + + + +#include +using namespace std; + +#include "hurricane/Cell.h" +using namespace Hurricane; + +#ifndef __BOOKSHELF_H__ +#define __BOOKSHELF_H__ + + +namespace CRL { + +// ------------------------------------------------------------------- +// functions. + +void bookshelfParser ( const string& cellPath, Cell* cell ); +void bookshelfDriver ( const string& cellPath, Cell* cell, unsigned int& saveState); + +} + +# endif diff --git a/crlcore/src/ccore/bookshelf/BookshelfDriver.cpp b/crlcore/src/ccore/bookshelf/BookshelfDriver.cpp new file mode 100644 index 00000000..1db4b427 --- /dev/null +++ b/crlcore/src/ccore/bookshelf/BookshelfDriver.cpp @@ -0,0 +1,295 @@ +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// +// Date : 08/11/2005 +// Author : Damien Dupuis +// +// Authors-Tag + +#include +using namespace std; + +#include "hurricane/Pin.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/Net.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/Warning.h" +using namespace Hurricane; + + +namespace { + +struct PinSort { + bool operator()(const Pin* pin1, const Pin* pin2) const + { + if (pin1->getY() > pin2->getY()) + return true; + else if (pin2->getY() > pin1->getY()) + return false; + else if (pin1->getX() > pin2->getX()) + return true; + else + return false; + } +}; + +void DumpMasters ( ofstream& ccell, Cell *cell ) +{ + unsigned i = 0; + for_each_cell ( masterCell, cell->getSubCells() ) + { + cerr << "found : " << masterCell << endl; + i++; + end_for; + } + + cerr << "Dumped " << i << " masterCell" << endl; +} + +void DumpSegments(ofstream& ccell, Cell* cell) +{ + for_each_net(net, cell->getNets()) + { + for_each_component(component, net->getComponents()) + { + if (Horizontal* horizontal = dynamic_cast(component)) + { + DbU::Unit minX = (horizontal->getSourceX() < horizontal->getTargetX())? + horizontal->getSourceX() : horizontal->getTargetX(); + DbU::Unit maxX = (horizontal->getSourceX() > horizontal->getTargetX())? + horizontal->getSourceX() : horizontal->getTargetX(); + DbU::Unit y = horizontal->getY(); + DbU::Unit width = horizontal->getWidth(); + + ccell << "S " + << minX << "," + << y << "," + << maxX << "," + << y << "," + << width << "," + << horizontal->getNet()->getName() << ",RIGHT," + << horizontal->getLayer()->getName() + << endl; + } + else if (Vertical* vertical = dynamic_cast(component)) + { + DbU::Unit minY = (vertical->getSourceY() < vertical->getTargetY())? + vertical->getSourceY() : vertical->getTargetY(); + DbU::Unit maxY = (vertical->getSourceY() > vertical->getTargetY())? + vertical->getSourceY() : vertical->getTargetY(); + DbU::Unit x = vertical->getX(); + DbU::Unit width = vertical->getWidth(); + + ccell << "S " + << x << "," + << minY << "," + << x << "," + << maxY << "," + << width << "," + << vertical->getNet()->getName() << ",LEFT," + << vertical->getLayer()->getName() + << endl; + } + end_for; + } + end_for; + } +} + +unsigned getPinIndex(Name& pinname) { + string pinNameString = getString(pinname); + string::size_type pointString = pinNameString.find('.'); + if (pointString == string::npos) { + return 0; + } else { + string indexString(pinNameString, pointString + 1, pinNameString.size() - 1); + pinNameString = string(pinNameString, 0, pointString); + pinname = Name(pinNameString); + return atoi(indexString.c_str()); + } +} + +void DumpPins(ofstream &ccell, Cell* cell) { + for_each_net(net, cell->getExternalNets()) { + typedef vector PinVector; + PinVector pinVector; + for_each_pin(pin, net->getPins()) { + pinVector.push_back(pin); + end_for; + } + sort (pinVector.begin(), pinVector.end(), PinSort()); + set indexesSet; + for (PinVector::const_iterator pvit = pinVector.begin(); + pvit != pinVector.end(); + pvit++) { + Pin* pin = *pvit; + Name pinName(pin->getName()); + unsigned index = getPinIndex(pinName); + if (pinName != net->getName()) { + throw Error("Pin name (" + getString(pinName) + + ") must look like " + + getString(net->getName()) + + "[.index] to be driven in AP format"); + } + if (indexesSet.find(index) != indexesSet.end()) { + throw Error("Two pins on same net with same index for net : " + + getString(net->getName())); + } + indexesSet.insert(index); + if (pin->getWidth() != pin->getHeight()) { + throw Warning(getString(pin->getName()) + " of " + + getString(net->getName()) + + " will be incompletely saved ... : AP format is only able to save square pins ..."); + ccell << "C " + << pin->getX() + << "," << pin->getY() + << "," << pin->getWidth() + << "," << pinName + << "," << index + << ","; + } + switch (pin->getAccessDirection()) { + case Pin::AccessDirection::NORTH: + ccell << "NORTH"; + break; + case Pin::AccessDirection::SOUTH: + ccell << "SOUTH"; + break; + case Pin::AccessDirection::EAST: + ccell << "EAST"; + break; + case Pin::AccessDirection::WEST: + ccell << "WEST"; + break; + case Pin::AccessDirection::UNDEFINED: + default: + throw Error("Pins must a have direction to generate a .ap"); + } + ccell << ","; + ccell << pin->getLayer()->getName(); + ccell << endl; + } + end_for; + } +} + +void DumpDate(ofstream &ccell) +{ + time_t tim; + time(&tim); + struct tm* rest = localtime(&tim); + ccell << rest->tm_mday + << "/" << rest->tm_mon+1 + << "/" << rest->tm_year+1900; +} + +void DumpInstances(ofstream &ccell, Cell* cell) { + for_each_instance(instance, cell->getNotUnplacedInstances()) { + ccell << "I " + << instance->getAbutmentBox().getXMin() + << "," << instance->getAbutmentBox().getYMin() + << "," << instance->getMasterCell()->getName() + << "," << instance->getName() + << ","; + + const Transformation& transformation = instance->getTransformation(); + switch (transformation.getOrientation()) { + case Transformation::Orientation::ID: + ccell << "NOSYM"; + break; + case Transformation::Orientation::R1: + ccell << "ROT_P"; + break; + case Transformation::Orientation::R2: + ccell << "SYMXY"; + break; + case Transformation::Orientation::R3: + ccell << "ROT_M"; + break; + case Transformation::Orientation::MX: + ccell << "SYM_X"; + break; + case Transformation::Orientation::XR: + ccell << "SY_RM"; + break; + case Transformation::Orientation::MY: + ccell << "SYM_Y"; + break; + case Transformation::Orientation::YR: + ccell << "SY_RP"; + break; + default: + throw Error("Unrecognized orientation in transformation"); + } + ccell << endl; + end_for; + } +} + +} + +namespace CRL { + +void bookshelfDriver( const string& cellPath, Cell *cell, unsigned int &saveState) +{ + ::std::ofstream auxFile ( cellPath.c_str() ); + + // .aux file generation : + string str_name = getString ( cell->getName() ) + ".test"; + auxFile << "STDCellPlacement : " + << str_name << ".masters " + << str_name << ".nodes " + << str_name << ".nets " + << str_name << ".pl" << endl; + + //DumpMasters ( ccell, cell ); + + //ccell << "UCLA nodes 1.0" << endl; + + //DumpDate(ccell); + //ccell << "," << scaleX << endl; + //const Box& abutmentBox = cell->getAbutmentBox(); + //ccell << "A " + // << abutmentBox.getXMin() + // << "," << abutmentBox.getYMin() + // << "," << abutmentBox.getXMax() + // << "," << abutmentBox.getYMax() + // << endl; + //DumpPins(ccell, cell); + //DumpInstances(ccell, cell); + //DumpSegments(ccell, cell); + //DumpContacts(ccell, cell); + //ccell << "EOF" << endl; + auxFile.close (); +} + +} diff --git a/crlcore/src/ccore/bookshelf/BookshelfParser.cpp b/crlcore/src/ccore/bookshelf/BookshelfParser.cpp new file mode 100644 index 00000000..71fc2389 --- /dev/null +++ b/crlcore/src/ccore/bookshelf/BookshelfParser.cpp @@ -0,0 +1,1077 @@ + + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// Damien Dupuis +// +// The Coriolis Project is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// +// License-Tag +// +// +// Date : 25/10/2005 +// Author : Damien Dupuis +// +// Authors-Tag + +// ************************************************************************************ +// File: CParsBK.cpp +// ************************************************************************************ + + +#include + +#include + +#include + +#include "hurricane/DataBase.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/UpdateSession.h" +using namespace Hurricane; + + +#include "crlcore/Utilities.h" +#include "crlcore/AllianceFramework.h" + +#include "Bookshelf.h" + + +const char* badRegex = + "CParsBK::CParsBK () :\n\n" + " Invalid regular expression for %s :\n" + " %s.\n"; + +namespace { + + + using namespace Hurricane; + using namespace CRL; + + + + + char* lower ( char* str ) + { + for ( char* ptr = str; *ptr != '\0' ; ptr++ ) + *ptr = (char)tolower ( *ptr ); + + return str; + } + +// CParsAP should read this code : +// ******************************* +// inline char * __passDelim ( char* s, const char* delims ) { +// if ( s == NULL ) +// return NULL; +// +// char* newS = NULL; +// while ( *s != (char)0 ) { +// for ( unsigned i = 0 ; i < strlen ( delims ) ; i++ ) { +// if ( *s == delims[i] ) { +// if ( delims[i] == ' ' ) cerr << "Vive moi j'ai lu un espace !!!" << endl; +// if ( delims[i] == '\t' ) cerr << "Vive moi j'ai lu une tabulation !!!" << endl; +// if ( delims[i] == '\n' ) cerr << "Vive moi j'ai lu un saut de ligne !!!" << endl; +// *s = (char)0; +// break; +// } +// } +// if ( *s != (char)0 ) { // si on a trouvé un vrai token différent de fin de chaine et delims +// newS = s; +// break; +// } +// s++; +// } +// return newS; +// } +// +// inline char * __chrDelim ( char* s, const char* delims ) { +// if ( s == NULL ) +// return NULL; +// } +// +// char* __strtok ( char* s, const char* delims ) +// { +// static char* _start = NULL; +// static const char* _delims = NULL; +// +// if ( delims ) _delims = delims; +// if ( s ) _start = __passDelim ( s, _delims ); +// +// char* token = _start; +// +// if ( token && _delims ) { +// char* nextToken = NULL; +// for ( unsigned i = 0 ; i < strlen ( _delims ) ; i++ ) { // pass les delimiteurs +// if ( ( nextToken = strchr ( token, _delims[i] ) ) != NULL ) { +// _start = __passDelim ( nextToken, _delims ); +// return token; +// } +// } +// } +// +// return NULL; +// } + + + +// ************************************************************************************** +// The Class BKParser +// ************************************************************************************** + +class BKParser { +// ************* + +// BKParser Types +// ************** + enum BKState { AUX, NODES, NETS, WTS, PL, SCL, END }; + +// BKParser Attributes +// ******************* + + + public: AllianceFramework* _framework; + public: Technology* _technology; + public: Layer::Mask _mask; + public: FILE * _file; + public: unsigned _bufferSize; + public: char _buffer[256]; + public: unsigned _lineNumber; + public: bool _done; + public: Cell * _cell; + public: long _scale; // Scale factor for coordinates + public: int _version; // BK Format Version + public: int _warningNumber; + public: int _errorNumber; + public: unsigned _anonymousNetId; + public: string _fileStringTab [6]; + public: regex_t _regex [6]; + public: unsigned _nbNets; // For genertating automatic NetNames + +// Constructors & Destructor +// ************************* + + public: BKParser ( AllianceFramework* framework ); + public: ~BKParser(); + +// Others +// ****** + + public: void OnAbort ( const string& message, unsigned state ); + public: void OnWarning ( const string& message, unsigned state ); + public: void OnError ( const string& message, unsigned state ); + + public: bool ScanAux (); // to read different FileNames + public: bool ScanNodes ( Name& name, DbU::Unit& width, DbU::Unit& height, bool& isPad ); // to read Instances + public: bool ScanNets ( Name& insName, Net::Direction& dir, DbU::Unit& dx, DbU::Unit& dy ); // to read Nets + public: bool ScanWts ( Name& name, unsigned& weight ); // to read instances Weights + public: bool ScanPl ( Name& name, DbU::Unit& x, DbU::Unit& y, Transformation::Orientation& orient, bool& isFixed );// to read Placement + //public: bool ScanScl ( DbU::Unit& coordinate, ....to be completed ); // to read Rows + public: bool ScanNum ( unsigned& num ); + public: bool ScanDegree ( unsigned& degree, Name& netName ); + + public: bool isNumber ( char* token ); + public: bool isFloat ( char* token ); + public: bool isName ( char* token ); + public: bool isSymetry ( char* token ); + public: bool isDirection ( char* token ); + + public: void LoadFromFile(const string& cellPath, Cell* cell); + + private: Name getNewNetName (); +}; + + + + +// ************************************************************************************ +// Implementation of Class BKParser +// ************************************************************************************ + +BKParser::BKParser ( AllianceFramework* framework ) +// ************************************************ + : _framework ( framework ), + _technology ( NULL ), + _mask ( ~0 ), + _file ( NULL ), + _bufferSize ( 256 ), + _buffer(), + _lineNumber ( 0 ), + _done ( false ), + _cell ( NULL ), + _scale ( 1 ), + _version ( 0 ), + _warningNumber ( 0 ), + _errorNumber ( 0 ), + _anonymousNetId ( 0 ), + _fileStringTab (), + _regex (), + _nbNets ( 0 ) +{ + _buffer[0]='\0'; + _technology = DataBase::getDB()->getTechnology (); +} + + +BKParser::~BKParser() +// ****************** +{ +} + + +void BKParser::OnAbort ( const string& message, unsigned state ) +// ************************************************************* +{ + string reason = message; + if ( ! _fileStringTab[state].empty() ) { + reason += " in File: " + _fileStringTab[state]; + if ( _lineNumber ) + reason += " (line " + getString ( _lineNumber ) + ")"; + } + throw Error(reason); +} + + +void BKParser::OnError ( const string& message, unsigned state ) +// ************************************************************* +{ + _errorNumber++; + string reason = "[ERROR] "; + if ( ! _fileStringTab[state].empty() ) { + reason += _fileStringTab[state]; + if ( _lineNumber ) + reason += "," + getString ( _lineNumber ) + " : "; + } + reason += message; + cout << reason << endl; +} + + +void BKParser::OnWarning ( const string& message, unsigned state ) +// *************************************************************** +{ + _warningNumber++; + string reason = message; + if ( ! _fileStringTab[state].empty() ) { + reason += " in File: " + _fileStringTab[state]; + if ( _lineNumber ) + reason += " (line " + getString ( _lineNumber ) + ")"; + } + cout << tab << "[WARNING] " << reason << endl; +} + + +Name BKParser::getNewNetName() +// *************************** +{ + ostringstream name ( "anonymous_net_" ); + name << _anonymousNetId++; + + return name.str(); +} + + +Net* MergeNets ( Net* net1, Net* net2 ) +// ************************************ +{ + if ( net2->getName()[0] != '~' ) { + if ( ( net1->getName()[0] == '~' ) || + ( net2->isGlobal() && !net1->isGlobal() ) || + ( net2->isExternal() && !net1->isExternal() ) ) { + Net* tmpNet = net1; + net1 = net2; + net2 = tmpNet; + } + } + net1->setExternal ( net1->isExternal() || net2->isExternal() ); + net1->setGlobal ( net1->isGlobal() || net2->isGlobal() ); + + net1->merge ( net2 ); // Caution : net2 will be deleted + return net1; +} + + +// ************************************************************************************ +// BK Record Scanning methods +// ************************************************************************************ + + +bool BKParser::isNumber ( char* token ) { + trace << "isNumber = " << token; + + unsigned i = 0; + char tok; + while ( ( tok = token[i++] ) != char(0) ) { + if ( ( tok < '0' ) || ( tok > '9' ) ) + return false; + } + return true; +} + +bool BKParser::isFloat ( char* token ) { + trace << "isFloat = " << token; + + unsigned i = 0; + char tok; + while ( ( tok = token[i++] ) != char(0) ) { + if ( ( tok != '-' ) && ( tok != '+' ) && ( tok != '.' ) + && ( ( tok < '0' ) || ( tok > '9' ) ) ) + return false; + } + return true; +} + +bool BKParser::isName ( char* token ) { + trace << "isName = " << token; + + unsigned i = 0; + char tok; + while ( ( tok = token[i++] ) != char(0) ) { + if ( ( tok != '_' ) && ( tok != '-' ) && ( tok != '+' ) && ( tok != '.' ) + && ( ( tok < '0' ) || ( tok > '9' ) ) + && ( ( tok < 'a' ) || ( tok > 'z' ) ) + && ( ( tok < 'A' ) || ( tok > 'Z' ) ) ) + return false; + } + return true; +} + +bool BKParser::isSymetry ( char* token ) { + trace << "isSymetry = " << token; + if ( ( ( token[0] == 'X' ) && ( token[1] == char(0) ) ) + || ( ( token[0] == 'Y' ) && ( token[1] == char(0) ) ) + || ( ( token[0] == 'R' ) && ( token[1] == '9' ) && ( token[2] == '0' ) && ( token[3] == char(0) ) ) ) + return true; + return false; +} +bool BKParser::isDirection ( char* token ) { + trace << "isDirection = " << token; + + if ( ( ( token[0] == 'I' ) || ( token[0] == 'O' ) || ( token[0] == 'B' ) ) && ( token[1] == char(0) ) ) + return true; + return false; +} + + +bool BKParser::ScanAux () +// ********************** +{ + // ********************************************************************************************************** + // The Aux record looks like : + // RowBasedPlacement : .nodes .nets .wts .pl .scl + // ********************************************************************************************************** + trace << "ScanAux = " << _buffer; + + // *********************** + // Patterns initialization + // *********************** + const char* regexPattern [6]; + regexPattern[NODES] = "([-_\\.[:alnum:]]+\\.nodes)"; + regexPattern[NETS] = "([-_\\.[:alnum:]]+\\.nets)"; + regexPattern[WTS] = "([-_\\.[:alnum:]]+\\.wts)"; + regexPattern[PL] = "([-_\\.[:alnum:]]+\\.pl)"; + regexPattern[SCL] = "([-_\\.[:alnum:]]+\\.scl)"; + + char regexError[1024]; + int regexCode; + + + UpdateSession::open(); + + size_t nmatch = 0; + regmatch_t* pmatch; + for ( unsigned state = NODES ; state < END ; state++ ) { + // Patterns Compilation : + // ********************** + if ( ( regexCode = regcomp ( &_regex[state], regexPattern[state], REG_EXTENDED ) ) ) { + regerror ( regexCode, &_regex[state], regexError, 1024 ); + throw Error ( badRegex, "state", regexError ); + } + + // Pattern recognition and fileStringTab initialization : + // ****************************************************** + nmatch = _regex[state].re_nsub; + pmatch = ( regmatch_t* ) malloc ( sizeof (*pmatch) * nmatch ); + if ( !pmatch ) + throw Error ( "Big malloc problem : I hate malloc ;-)" ); + regexCode = regexec ( &_regex[state], _buffer, nmatch, pmatch, 0 ); + if ( regexCode == 0 ) { + unsigned start = pmatch[0].rm_so; + unsigned end = pmatch[0].rm_eo; + unsigned size = end - start; + + char subString[size+1]; + strncpy ( subString, &_buffer[start], size ); + subString[size] = '\0'; + _fileStringTab[state] = string ( subString ); + } + + free ( pmatch ); + regfree ( &_regex[state] ); + } + + return ( _fileStringTab[NODES] != "" ) && ( _fileStringTab[NETS] != "" ); +} + +bool BKParser::ScanNum ( unsigned& num ) +// ************************************* +{ + // ******************************* + // The NodeNum record looks like : + // NumNodes : + // ******************************* + trace << "ScanNum = " << _buffer; + + char *p_type, *p_num; + if ( ( ( p_type = strtok ( _buffer, "\t \n:" ) ) != NULL ) && + ( ( p_num = strtok ( NULL , "\t \n:" ) ) != NULL ) ) { + num = atol ( p_num ); + return true; + } + + return false; +} + +bool BKParser::ScanDegree ( unsigned& degree, Name& netName ) +// ********************************************************** +{ + // ********************************** + // The NetDregree record looks like : + // NetDegree : [netName] + // ********************************** + trace << "ScanDegree = " << _buffer; + + bool mDegree = false; + bool mName = false; + char *p_type, *p_token; + if ( ( p_type = strtok ( _buffer, "\t \n:" ) ) == NULL ) { + return false; + } + while ( ( p_token = strtok ( NULL, "\t \n:" ) ) != NULL ) { + if ( isNumber ( p_token ) ) { + degree = atol ( p_token ); + mDegree = true; + _nbNets++; + } + else if ( isName ( p_token ) ) { + netName = p_token; + mName = true; + } + } + if ( mDegree && !mName ) { + netName = Name ( "NET" + getString ( _nbNets ) ); + + char ext = 'a'; + while ( ( _cell->getNet ( netName ) != NULL ) && ( ext <= 'z' ) ) { + netName = Name ( getString ( netName ) + getString ( ext++ ) ); + } + if ( ext > 'z' ) { + OnError ( "Can't create automatic netName :" + getString ( netName ), NETS ); + return false; + } + } + + return mDegree; +} + +bool BKParser::ScanNodes ( Name& name, DbU::Unit& width, DbU::Unit& height, bool& isPad ) +// **************************************************************************** +{ + // ************************************** + // The Node record looks like : + // [terminal] + // ************************************** + trace << "ScanNodes = " << _buffer; + + char *p_name, *p_width, *p_height, *p_term; + if ( ( ( p_name = strtok ( _buffer, "\t \n" ) ) != NULL ) && + ( ( p_width = strtok ( NULL , "\t \n" ) ) != NULL ) && + ( ( p_height = strtok ( NULL , "\t \n" ) ) != NULL ) ) { + name = p_name; + width = DbU::lambda ( atol ( p_width ) ); + height = DbU::lambda ( atol ( p_height ) ); + if ( ( p_term = strtok ( NULL, "\n" ) ) != NULL ) { + isPad = ( p_term[0] != (char)0 ); + } + + return true; + } + + return false; +} + +bool BKParser::ScanNets ( Name& insName, Net::Direction& dir, DbU::Unit& dx, DbU::Unit& dy ) +// ******************************************************************************* +{ + // ********************************* + // The Net record looks like : + // NetDegree : + // ********************************* + trace << "ScanNets = " << _buffer; + + bool mName = false; + bool mDirection = false; + bool mOffset = false; + char *p_name, *p_token; + if ( ( p_name = strtok ( _buffer, "\t \n:" ) ) == NULL ) { + return false; + } + insName = p_name; + mName = true; + while ( ( p_token = strtok ( NULL, "\t \n:" ) ) != NULL ) { + if ( isDirection ( p_token ) ) { + if ( string ( p_token ) == "I" ) + dir = Net::Direction::IN; + else if ( string ( p_token ) == "O" ) + dir = Net::Direction::OUT; + else if ( string ( p_token ) == "B" ) + dir = Net::Direction::INOUT; + else + throw Error ( "Unknown net direction read !!" ); + mDirection = true; + } + else if ( isFloat ( p_token ) ) { + dx = DbU::lambda ( atof ( p_token ) ); + if ( ( p_token = strtok ( NULL, "\t \n:" ) ) == NULL ) + OnError ( "Wrong syntax :offset misreading", NETS ); + if ( !isFloat ( p_token ) ) + OnError ( "Wrong syntax :offset misreading", NETS ); + dy = DbU::lambda ( atof ( p_token ) ); + mOffset = true; + _nbNets++; + } + } + if ( !mDirection ) + dir = Net::Direction::IN; // Default Direction + if ( !mOffset ) { + dx = 0; + dy = 0; + } + + return mName; +} + + +bool BKParser::ScanWts ( Name& name, unsigned& weight ) +// **************************************************** +{ + // ****************************** + // The Weight record looks like : + // + // ****************************** + trace << "ScanWts = " << _buffer; + + //char *p_x, *p_y, *p_model, *p_name, *p_transf; + + //if (((p_x = __strtok (_buffer + 2, ",")) != NULL) && + // ((p_y = __strtok (NULL, ",")) != NULL) && + // ((p_model = __strtok (NULL, ",")) != NULL) && + // ((p_name = __strtok (NULL, ",")) != NULL) && + // ((p_transf = __strtok (NULL, "\n")) != NULL) ) { + + // x = getUnit(atol(p_x) / _scale); + // y = getUnit(atol(p_y) / _scale); + // masterCellName = Name(lower(p_model)); + // instName = Name(lower(p_name)); + + // string transfo = p_transf; + // // Conversion to Hurricane orientation code + // if (transfo == "NOSYM") orientation=Transformation::Orientation::ID; + // else if (transfo == "ROT_P") orientation=Transformation::Orientation::R1; + // else if (transfo == "SYMXY") orientation=Transformation::Orientation::R2; + // else if (transfo == "ROT_M") orientation=Transformation::Orientation::R3; + // else if (transfo == "SYM_X") orientation=Transformation::Orientation::MX; + // else if (transfo == "SY_RM") orientation=Transformation::Orientation::XR; + // else if (transfo == "SYM_Y") orientation=Transformation::Orientation::MY; + // else if (transfo == "SY_RP") orientation=Transformation::Orientation::YR; + // else { + // OnError("Unknown Orientation code " + transfo); + // orientation=Transformation::Orientation::ID; + // } + // return true; + //} + return false; +} + + +bool BKParser::ScanPl ( Name& name, DbU::Unit& x, DbU::Unit& y, Transformation::Orientation& orient, bool& isFixed ) +// ******************************************************************************************************* +{ + // ************************************* + // The Placement record looks like : + // : [FIXED] + // ************************************* + trace << "ScanPl = " << _buffer; + + char *p_name, *p_x, *p_y, *p_orient, *p_fixed; + if ( ( ( p_name = strtok ( _buffer, "\t \n" ) ) != NULL ) && + ( ( p_x = strtok ( NULL , "\t \n" ) ) != NULL ) && + ( ( p_y = strtok ( NULL , "\t \n:" ) ) != NULL ) && + ( ( p_orient = strtok ( NULL , "\t \n:" ) ) != NULL ) ) { + name = p_name; + x = DbU::lambda ( atol ( p_x ) ); + y = DbU::lambda ( atol ( p_y ) ); + if ( string ( p_orient ) == "N" ) + orient = Transformation::Orientation::ID; + else if ( string ( p_orient ) == "E" ) + orient = Transformation::Orientation::R3; + else if ( string ( p_orient ) == "S" ) + orient = Transformation::Orientation::R2; + else if ( string ( p_orient ) == "W" ) + orient = Transformation::Orientation::R1; + else if ( string ( p_orient ) == "FN" ) + orient = Transformation::Orientation::MX; + else if ( string ( p_orient ) == "FE" ) + orient = Transformation::Orientation::YR; + else if ( string ( p_orient ) == "FS" ) + orient = Transformation::Orientation::MY; + else if ( string ( p_orient ) == "FW" ) + orient = Transformation::Orientation::XR; + else + throw Error ( "Unknown transformation read !!" ); + + if ( ( p_fixed = strtok ( NULL, "\n" ) ) != NULL ) { + isFixed = ( p_fixed[0] != (char)0 ); + } + + return true; + } + + return false; +} + + +//bool BKParser::ScanScl ( Name& name ) +//// ********************************** +//{ +// // ******************************* +// // The Big Via record looks like : +// // B ,,,,, +// // Ex : +// // ******************************* +// trace << "ScanScl = " << _buffer; +// //char *p_x, *p_y, *p_dx, *p_dy, *p_viaType, *p_name; +// //if (((p_x = __strtok (_buffer + 2, ",")) != NULL) && +// // ((p_y = __strtok (NULL, ",")) != NULL) && +// // ((p_dx = __strtok (NULL, ",")) != NULL) && +// // ((p_dy = __strtok (NULL, ",")) != NULL) && +// // ((p_viaType = __strtok (NULL, ",")) != NULL) && +// // ((p_name = __strtok (NULL, "\n")) != NULL)) { +// +// // x = getUnit(atol(p_x) / _scale); +// // y = getUnit(atol(p_y) / _scale); +// // w = getUnit(atol(p_dx) / _scale); +// // h = getUnit(atol(p_dy) / _scale); +// // layerName = Name(p_viaType); +// // if ((p_name[ 0 ] == '\0') || (! strcmp(p_name, "*" ))) +// // netName = Name(""); +// // else +// // netName = Name(lower(p_name)); +// +// // return true; +// //} +// return false; +//} +// + +// *************************************************************************************** +// Miscellaneous utilitarians +// *************************************************************************************** + +Transformation getTransformation ( const Box& abox, const DbU::Unit& x, const DbU::Unit& y, const Transformation::Orientation& orientation ) +// ******************************************************************************************************************************* +{ + // Creates the Hurricane Transformation record for an Instance, from : + // * the Instance Abutment Box + // * the x, y location of the lower left corner + // * the Hurricane orientation code. + + switch ( orientation ) { + case Transformation::Orientation::ID : + return Transformation ( x - abox.getXMin(), y - abox.getYMin(), orientation); + case Transformation::Orientation::R1 : + return Transformation ( x + abox.getYMax(), y - abox.getXMin(), orientation); + case Transformation::Orientation::R2 : + return Transformation ( x + abox.getXMax(), y + abox.getYMax(), orientation); + case Transformation::Orientation::R3 : + return Transformation ( x - abox.getYMin(), y + abox.getXMax(), orientation); + case Transformation::Orientation::MX : + return Transformation ( x + abox.getXMax(), y - abox.getYMin(), orientation); + case Transformation::Orientation::XR : + return Transformation ( x + abox.getYMax(), y + abox.getXMax(), orientation); + case Transformation::Orientation::MY : + return Transformation ( x - abox.getXMin(), y + abox.getYMax(), orientation); + case Transformation::Orientation::YR : + return Transformation ( x - abox.getYMin(), y - abox.getXMin(), orientation); + } + return Transformation(); +} + + +void UpdateSizes ( Contact* contact ) +// ********************************** +{ + DbU::Unit width = 0; + DbU::Unit height = 0; + const Layer* layer = contact->getLayer(); + //if ( layer->getType() == CompositeLayer::Type::VIA ) { + width = max ( contact->getWidth(), layer->getMinimalSize() ); + height = max ( contact->getHeight(), layer->getMinimalSize() ); + //} + + for_each_hook ( hook, contact->getBodyHook()->getSlaveHooks() ) { + Component* component = hook->getComponent(); + if ( Vertical* vertical = dynamic_cast ( component ) ) { + width = max ( width, vertical->getWidth() ); + } else if ( Horizontal* horizontal = dynamic_cast ( component ) ) { + height = max ( height, horizontal->getWidth() ); + } + end_for; + } + contact->setSizes ( width, height ); +} + + +// *************************************************************************************** +// BK Loader +// *************************************************************************************** + + +void BKParser::LoadFromFile ( const string& cellPath, Cell* cell ) +// **************************************************************** +{ + bool disabledFlag = Go::autoMaterializationIsDisabled(); + Go::disableAutoMaterialization(); // We force the mode + + CatalogProperty *sprop = ( CatalogProperty* ) cell->getProperty ( CatalogProperty::getPropertyName() ); + if ( sprop == NULL ) + throw Error ( "Missing CatalogProperty in cell %s.\n" , getString ( cell->getName() ).c_str() ); + + Catalog::State *state = sprop->getState (); + + state->setPhysical ( true ); + + IoFile filestream ( cellPath ); + filestream.open ( "r" ); + _file = filestream.getFile (); + + _cell = cell; + + string _pathString = cellPath.substr ( 0, cellPath.rfind ( "/" ) ); + + unsigned int pstate = AUX; + + string fileString; + _fileStringTab[0] = cellPath; + fileString = _pathString + "/" + _fileStringTab[pstate]; + + bool noError = true; + bool scanOk; + + unsigned int nodes_count = 0; + unsigned int nets_count = 0; + unsigned int netsall_count = 0; + unsigned int lines_done = 0; + unsigned int lines_progress_count = 0; + + const char* attente = "\\|/-"; + unsigned int att_idx = 0; + + try { + while ( noError ) { + _buffer[0] = fgetc ( _file ); + if ( _buffer[0] == '\n' ) { + _lineNumber++; + continue; + } + char* result = fgets ( &_buffer[1], sizeof ( _buffer ) - 1, _file ); + _lineNumber++; + + if ( _buffer[0] == '#' ) continue; + + + if ( ! strncmp ( _buffer, "UCLA", 4 ) ) continue; + + if ( _buffer[0] != ( char ) EOF ) { + switch ( pstate ) { + case AUX: + cerr << " " << tab << "Charging aux...\r"; + scanOk = ScanAux (); + if ( !scanOk ) { + noError = false; + OnAbort ( "Problem while parsing : missing .nodes or .nets file", pstate ); + } + break; + case NODES: + { + cerr << " " << tab << "Charging... \r"; cerr.flush(); + if ( ! strncmp ( _buffer, "NumNodes", 8 ) ) { + unsigned num = 0; + scanOk = ScanNum ( num ); + if ( !scanOk ) { + noError = false; + OnError ( "\nProblem while parsing NumNodes", pstate ); + } + nodes_count = num; + continue; + } + if ( ! strncmp ( _buffer, "NumTerminals", 12 ) ) + continue; + Name name; + DbU::Unit width, height; + bool isPad = false; + scanOk = ScanNodes ( name, width, height, isPad ); + if ( !scanOk ) { + noError = false; + OnError ( "\nProblem while parsing a node", pstate ); + } + if ( nodes_count == 0 ) + OnAbort ( "\nWrong declaration of NumNodes", pstate ); + lines_progress_count++; + lines_done = 100 * lines_progress_count / nodes_count; + cerr << " " << tab << "Charging... [" << lines_done << "%] " + << attente[att_idx] << " \r"; cerr.flush(); + att_idx = (att_idx+1) % 4; + Cell* masterCell = Cell::create ( _cell->getLibrary(), Name ( getString ( name ) + "_model" ) ); + masterCell->setAbutmentBox ( Box ( 0, 0, width, height ) ); + if ( isPad ) masterCell->setPad ( true ); + Instance::create ( _cell, name, masterCell ); + break; + } + case NETS: + cerr << " " << tab << "Charging... \r"; cerr.flush(); + if ( ! strncmp ( _buffer, "NumNets", 7 ) ) { + unsigned num = 0; + scanOk = ScanNum ( num ); + if ( !scanOk ) { + noError = false; + OnError ( "\nProblem while parsing NumNets", pstate ); + } + nets_count += num; + netsall_count += num; + continue; + } + if ( ! strncmp ( _buffer, "NumPins", 7 ) ) { + unsigned num = 0; + scanOk = ScanNum ( num ); + if ( !scanOk ) { + noError = false; + OnError ( "\nProblem while parsing NumPins", pstate ); + } + netsall_count += num; + continue; + } + if ( nets_count == 0 ) + OnAbort ( "\nWrong declaration of NumNets", pstate ); + if ( netsall_count == nets_count ) + OnAbort ( "\nWrong declaration of NumPins", pstate ); + + if ( ! strncmp ( _buffer, "NetDegree", 9 ) ) { + unsigned degree = 0; + Name netName; + scanOk = ScanDegree ( degree, netName ); + if ( !scanOk ) { + noError = false; + OnError ( "\nProblem while parsing a net", pstate ); + } + lines_progress_count++; + Net* net = Net::create ( _cell, netName ); + if ( !net ) throw Error ( "Can't create net " + getString ( netName ) ); + for ( unsigned i = 0 ; i < degree ; i++ ) { + // Now reading next line + _buffer[0] = fgetc ( _file ); + if ( _buffer[0] == '\n' ) { + _lineNumber++; + continue; + } + char* result = fgets ( &_buffer[1], sizeof ( _buffer ) - 1, _file ); + _lineNumber++; + + if ( _buffer[0] == '#' ) continue; + + Name insName; + Net::Direction dir; + DbU::Unit dx; + DbU::Unit dy; + scanOk = ScanNets ( insName, dir, dx, dy ); + if ( !scanOk ) { + noError = false; + string message = "\nProblem while parsing net " + getString ( netName ) + + " with degree " + getString ( degree ); + OnAbort ( message, pstate ); + } + Instance* instance = _cell->getInstance ( insName ); + if ( !instance ) throw Error ( "Can't get instance " + getString ( insName ) ); + Cell* model = instance->getMasterCell(); + if ( !model ) throw Error ( "Can't get model of instance " + getString ( insName ) ); + unsigned index = 0; + Name tempName = netName; + while ( model->getNet ( tempName ) ) + tempName = Name ( getString ( netName ) + "_" + getString ( index++ ) ); + //cerr << endl << " Trying to create masterNet " << getString ( tempName ) << " in masterCell " << model << endl; + Net* masterNet = Net::create ( model, tempName ); + if ( !masterNet ) throw Error ( "Can't create master net " + getString ( tempName ) + " on instance " + getString ( insName ) ); + masterNet->setDirection ( dir ); + masterNet->setPosition ( Point ( dx, dy ) ); + masterNet->setExternal ( true ); // To create plug + Plug* plug = instance->getPlug ( masterNet ); + if ( !plug ) throw Error ( "Can't get plug of net " + getString ( netName ) + " on instance " + getString ( insName ) ); + plug->setNet ( net ); + lines_progress_count++; + lines_done = 100 * lines_progress_count / netsall_count; + cerr << " " << tab << "Charging... [" << lines_done << "%] " + << attente[att_idx] << " \r"; cerr.flush(); + att_idx = (att_idx+1) % 4; + } + } + + break; + case WTS: + cerr << " " << tab << "Charging... \r"; cerr.flush(); + break; + case PL: + { + Name name; + DbU::Unit x, y; + Transformation::Orientation orient; + bool isFixed = false; + scanOk = ScanPl ( name, x, y, orient, isFixed ); + if ( !scanOk ) { + noError = false; + OnError ( "\nProblem while parsing", pstate ); + } + if ( nodes_count == 0 ) + OnAbort ( "\nWrong declaration of NumNodes or NumTerminals", pstate ); + lines_progress_count++; + lines_done = 100 * lines_progress_count / nodes_count; + cerr << " " << tab << "Charging... [" << lines_done << "%] " + << attente[att_idx] << " \r"; cerr.flush(); + att_idx = (att_idx+1) % 4; + Instance * instance = _cell->getInstance ( name ); + if ( instance ) { + Box abox = instance->getAbutmentBox(); + instance->setTransformation ( getTransformation ( abox, x, y, orient ) ); + if ( isFixed ) + instance->setPlacementStatus ( Instance::PlacementStatus::FIXED ); + } + else { + OnError ( "\nCouldn't find instance : " + getString ( name ) + " : not in .nodes file", pstate ); + } + break; + } + case SCL: + cerr << " " << tab << "Charging... \r"; + break; + default: + break; + } + } + else { + pstate++; + if ( pstate == END ) + break; + + if ( ! _fileStringTab[pstate].empty() ) { + fclose ( _file ); + _lineNumber = 0; + att_idx = 0; + lines_done = 0; + fileString = _pathString + "/" + _fileStringTab[pstate]; + _file = fopen ( fileString.c_str(), "r" ); + if ( pstate != NODES ) { + cerr << endl; + if ( !lines_progress_count ) + cerr << " " << tab << "Warning : Nothing parsed !!" << endl; + lines_progress_count = 0; + } + cerr << " " << tab << "+ " << fileString << endl; + if ( ! _file ) + OnError ( "Unable to find file : " + fileString, pstate ); + } + } + } // End of while + cerr << endl; + } // End of try + catch (Exception& exception) { + fclose(_file); + if (_cell) _cell->destroy(); + tab--; + cout << tab << exception.what() << endl; + OnAbort("Can't load cell " + getString ( _cell->getName() ), AUX); + } + catch (...) { + fclose(_file); + if (_cell) _cell->destroy(); + tab--; + cout << tab << Error("Can't load cell " + getString(_cell->getName()))._getString() << endl; + OnAbort("Can't load cell " + getString ( _cell->getName() ), AUX ); + } + + //filestream.close (); + + if (!_cell) OnAbort("Cell Was Not Created", AUX); + + UpdateSession::close(); + + Go::enableAutoMaterialization(); + _cell->materialize(); + + if (disabledFlag) // We restore the initial state if needed + Go::disableAutoMaterialization(); + + // Resizing AbutmentBox !! + _cell->setAbutmentBox ( _cell->getBoundingBox() ); + + //trace_off(); +} + +} // End of anonymous namespace. + + + + +namespace CRL { + + +void bookshelfParser ( const string& cellPath, Cell *cell ) +{ + cmess2 << " " << tab << "+ " << cellPath << endl; + + BKParser parser ( AllianceFramework::get() ); + + parser.LoadFromFile ( cellPath, cell ); +} + + +} + + +// ************************************************************************************** +// Copyright (C) LIP6 & BULL S.A. 2003-2005 All rights reserved +// ************************************************************************************** diff --git a/crlcore/src/ccore/cif/Cif.h b/crlcore/src/ccore/cif/Cif.h new file mode 100644 index 00000000..bf249b65 --- /dev/null +++ b/crlcore/src/ccore/cif/Cif.h @@ -0,0 +1,17 @@ +// author : Damien Dupuis +// date : 24.02.2010 +// -*- C++ -*- + +#ifndef __CIF_H__ +#define __CIF_H__ + +#include + +namespace Hurricane { + class Cell; +} + +namespace CRL { + void cifDriver(const std::string& file, Hurricane::Cell*, std::string& name, std::string& units, double& scale ); +} +# endif diff --git a/crlcore/src/ccore/cif/CifDriver.cpp b/crlcore/src/ccore/cif/CifDriver.cpp new file mode 100644 index 00000000..e83ee796 --- /dev/null +++ b/crlcore/src/ccore/cif/CifDriver.cpp @@ -0,0 +1,109 @@ +// author : Damien Dupuis +// date : 24.02.2010 +// -*- C++ -*- + +#include +#include +#include +#include +#include +using namespace std; + +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Go.h" +#include "hurricane/Cell.h" +#include "hurricane/Box.h" +#include "hurricane/Transformation.h" +#include "hurricane/Pad.h" +#include "hurricane/Segment.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Query.h" +using namespace Hurricane; + +#include "io/cif/CifCircuit.h" +#include "io/cif/CifPolygon.h" +using namespace IO; + +#include "Cif.h" + +namespace { +class CifQuery : public Query { + public: + CifQuery ( Cell* ); + + inline void setCircuit(CifCircuit*); + + virtual bool hasGoCallback() const; + virtual void goCallback ( Go* ); + // not used but needed for compilation : + virtual void extensionGoCallback(Go*) {}; + virtual void masterCellCallback() {}; + + private: + Cell* _cell; + CifCircuit* _circuit; +}; + +CifQuery::CifQuery(Cell* cell) : Query(), _cell(cell), _circuit(NULL) { + Query::setQuery(_cell, _cell->getBoundingBox(), Transformation(), NULL, 0, Query::DoComponents); +} + +inline void CifQuery::setCircuit(CifCircuit* circuit) { _circuit = circuit; } + +bool CifQuery::hasGoCallback() const { return true; } + +void CifQuery::goCallback(Go* go) { + Box b; + const BasicLayer* layer; + if (dynamic_cast(go)) { + const Pad* pad = static_cast(go); + b = pad->getBoundingBox(); + layer = dynamic_cast(pad->getLayer()); + } + else if (dynamic_cast(go)) { + const Contact* contact = static_cast(go); + b = contact->getBoundingBox(); + layer = dynamic_cast(contact->getLayer()); + } + else if (dynamic_cast(go)) { + const Segment* segment = static_cast(go); + b = segment->getBoundingBox(); + layer = dynamic_cast(segment->getLayer()); + } + else { + return; + } + CifPolygon* poly = new CifPolygon ( layer->getExtractNumber() ); + long xMin = round(DbU::getPhysical(b.getXMin(), DbU::Nano)); + long yMin = round(DbU::getPhysical(b.getYMin(), DbU::Nano)); + long xMax = round(DbU::getPhysical(b.getXMax(), DbU::Nano)); + long yMax = round(DbU::getPhysical(b.getYMax(), DbU::Nano)); + poly->addPoint(xMin, yMin); + poly->addPoint(xMax, yMin); + poly->addPoint(xMax, yMax); + poly->addPoint(xMin, yMax); + + _circuit->addPolygon(poly); +} +} // namespace + +namespace CRL { +void cifDriver(const string& filePath, Cell* cell, string& name, string& units, double& scale) { + name = getString(cell->getName()); + replace(name.begin(), name.end(), ' ', '_'); + units = "micro"; + scale = 0.001; + CifCircuit* circuit = new CifCircuit(name, units, scale); + CifQuery cifQuery (cell); + + cifQuery.setCircuit(circuit); + + forEach ( BasicLayer*, basicLayer, DataBase::getDB()->getTechnology()->getBasicLayers() ) { + cifQuery.setBasicLayer(*basicLayer); + cifQuery.doQuery(); + } + + circuit->write(filePath); +} +} // namespace CRL diff --git a/crlcore/src/ccore/crlcore/AllianceFramework.h b/crlcore/src/ccore/crlcore/AllianceFramework.h new file mode 100644 index 00000000..89e927bc --- /dev/null +++ b/crlcore/src/ccore/crlcore/AllianceFramework.h @@ -0,0 +1,144 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./AllianceFramework.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __CRL_ALLIANCE_FRAMEWORK__ +#define __CRL_ALLIANCE_FRAMEWORK__ + + +#include + +#include "crlcore/Environment.h" +#include "crlcore/AllianceLibrary.h" +#include "crlcore/Catalog.h" +#include "crlcore/ParsersDrivers.h" + + +namespace CRL { + + + class RoutingGauge; + class CellGauge; + + + class AllianceFramework { + + public: + // Constructors. + static AllianceFramework* create (); + // Destructors. + void destroy (); + // Accessors. + static AllianceFramework* get (); + string getPrint () const; + // Predicates. + inline bool isPOWER ( const char* name ); + inline bool isPOWER ( const string& name ); + inline bool isPOWER ( const Name& name ); + inline bool isGROUND ( const char* name ); + inline bool isGROUND ( const string& name ); + inline bool isGROUND ( const Name& name ); + inline bool isCLOCK ( const char* name ); + inline bool isCLOCK ( const string& name ); + inline bool isCLOCK ( const Name& name ); + inline bool isOBSTACLE ( const char* name ); + inline bool isOBSTACLE ( const string& name ); + inline bool isOBSTACLE ( const Name& name ); + // Accessors. + inline Environment* getEnvironment (); + inline Catalog* getCatalog (); + inline const Name& getParentLibraryName () const; + inline Library* getParentLibrary (); + Library* getLibrary ( unsigned index ); + AllianceLibrary* getAllianceLibrary ( const Name& path, bool& flag ); + RoutingGauge* getRoutingGauge ( const Name& name="" ); + CellGauge* getCellGauge ( const Name& name="" ); + inline const Name getDefaultCGPinLayerName () const; + // Modifiers. + void addRoutingGauge ( RoutingGauge* ); + void addCellGauge ( CellGauge* ); + // Cell Management. + Cell* getCell ( const string& name + , unsigned int mode + , unsigned int depth=(unsigned int)-1 ); + Cell* createCell ( const string& name ); + void saveCell ( Cell* cell , unsigned int mode ); + unsigned int loadLibraryCells ( Library* library ); + unsigned int loadLibraryCells ( const Name& name ); + + // Internals - Attributes. + protected: + static const Name _parentLibraryName; + static AllianceFramework* _singleton; + Environment _environment; + ParsersMap _parsers; + DriversMap _drivers; + Catalog _catalog; + AllianceLibraries _libraries; + Library* _parentLibrary; + RoutingGauge* _defaultRoutingGauge; + map + _routingGauges; + map + _cellGauges; + CellGauge* _defaultCellGauge; + + // Internals - Constructors. + AllianceFramework (); + AllianceFramework ( const AllianceFramework& ); + AllianceFramework& operator= ( const AllianceFramework& ); + // Internals - Destructors. + ~AllianceFramework (); + // Internals - Methods. + bool _readLocate ( const string& file, unsigned int mode, bool isLib=false ); + bool _writeLocate ( const string& file, unsigned int mode, bool isLib=false ); + + }; + + inline bool AllianceFramework::isPOWER ( const char* name ) { return _environment.isPOWER(name); } + inline bool AllianceFramework::isPOWER ( const string& name ) { return isPOWER(name.c_str()); } + inline bool AllianceFramework::isPOWER ( const Name& name ) { return isPOWER(getString(name)); } + inline bool AllianceFramework::isGROUND ( const char* name ) { return _environment.isGROUND(name); } + inline bool AllianceFramework::isGROUND ( const string& name ) { return isGROUND(name.c_str()); } + inline bool AllianceFramework::isGROUND ( const Name& name ) { return isGROUND(getString(name)); } + inline bool AllianceFramework::isCLOCK ( const char* name ) { return _environment.isCLOCK(name); } + inline bool AllianceFramework::isCLOCK ( const string& name ) { return isCLOCK(name.c_str()); } + inline bool AllianceFramework::isCLOCK ( const Name& name ) { return isCLOCK(getString(name)); } + inline bool AllianceFramework::isOBSTACLE ( const char* name ) { return _environment.isOBSTACLE(name); } + inline bool AllianceFramework::isOBSTACLE ( const string& name ) { return isOBSTACLE(name.c_str()); } + inline bool AllianceFramework::isOBSTACLE ( const Name& name ) { return isOBSTACLE(getString(name)); } + inline Environment* AllianceFramework::getEnvironment () { return &_environment; } + inline Catalog* AllianceFramework::getCatalog () { return &_catalog; } + inline const Name& AllianceFramework::getParentLibraryName + () const { return _parentLibraryName; } + inline Library* AllianceFramework::getParentLibrary () { return _parentLibrary; } +// TEMPORARY. + inline const Name AllianceFramework::getDefaultCGPinLayerName + () const { return "CALU1"; } + + +} // End of CRL namespace. + + +#endif // __CRL_ALLIANCE_FRAMEWORK__ diff --git a/crlcore/src/ccore/crlcore/AllianceLibrary.h b/crlcore/src/ccore/crlcore/AllianceLibrary.h new file mode 100644 index 00000000..0bbff49f --- /dev/null +++ b/crlcore/src/ccore/crlcore/AllianceLibrary.h @@ -0,0 +1,121 @@ + + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Rémy Escassut | +// | E-mail : Remy.Escassut@silvaco.com | +// | =============================================================== | +// | C++ Header : "./AllianceLibrary.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +# ifndef __CRL_ALLIANCE_LIBRARY_H__ +# define __CRL_ALLIANCE_LIBRARY_H__ + +# include +# include + +# include "hurricane/Name.h" +# include "hurricane/Slot.h" + +namespace Hurricane { + class Library; +} + + +namespace CRL { + + + using std::vector; + + using Hurricane::Name; + using Hurricane::Library; + using Hurricane::Record; + using Hurricane::_TName; + + +// ------------------------------------------------------------------- +// Class : "CRL::AllianceLibrary". + + class AllianceLibrary { + + public: + // Constructors. + AllianceLibrary (); + AllianceLibrary ( const Name& path, Library* library=NULL ); + // Operators + AllianceLibrary& operator= ( const AllianceLibrary& directory ); + AllianceLibrary& operator= ( const string& path ); + // Accessors + inline const Name& getPath () const; + inline Library* getLibrary () const; + // Hurricane management. + inline string _getTypeName () const; + string _getString () const; + Record* _getRecord () const; + + protected: + // Internal - Attributes. + Name _path; + Library* _library; + + }; + + + typedef vector AllianceLibraries; + + +// Inline Functions. + inline const Name& AllianceLibrary::getPath () const { return _path; } + inline Library* AllianceLibrary::getLibrary () const { return _library; } + inline string AllianceLibrary::_getTypeName () const { return _TName("AllianceLibrary"); } + + +} // End of CRL namespace. + + +#endif diff --git a/crlcore/src/ccore/crlcore/Banner.h b/crlcore/src/ccore/crlcore/Banner.h new file mode 100644 index 00000000..15818ebc --- /dev/null +++ b/crlcore/src/ccore/crlcore/Banner.h @@ -0,0 +1,235 @@ + + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./Banner.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + + + +# ifndef __CRL_BANNER_H__ +# define __CRL_BANNER_H__ + +# include +# include +# include +# include +# include + +# ifdef __CCORE_INTERNAL__ +# include "hurricane/CConfig.h" +# endif +# include "crlcore/Utilities.h" + + +namespace CRL { + + + using std::map; + using std::vector; + using std::ostream; + using std::ostringstream; + + +// ------------------------------------------------------------------- +// Class : "CRL::BannerFont". + + + class BannerFont { + + public: + // BigChar subclass. + class BigChar { + public: + // Constructor & Destructor. + BigChar ( char c, int height, const char* lines[], const BannerFont* font ); + ~BigChar (); + // Methods. + inline int getHeight () const; + inline const BannerFont* getFont () const; + string _getPrint () const; + const char* operator[] ( int line ) const; + + private: + // Internal: Attributes. + char _character; + int _height; + const char** _lines; + const BannerFont* _font; + + // Internal: Constructors. + BigChar& operator= ( const BigChar& ); + BigChar ( const BigChar& ); + }; + + // Static Methods. + static const BannerFont* getBannerFont ( const string& name ); + // Constructor & Destructor. + inline BannerFont ( const string& name ); + // Methods. + inline void addChar ( char character, int height, const char *lines[] ); + inline int getHeight () const; + inline const BigChar& operator[] ( char character ) const; + + private: + // Internal: FontMap subclass. + class FontMap : public map { + public: + FontMap (); + ~FontMap (); + const BannerFont* operator[] ( const string& name ) const; + }; + + // Internal: Types. + typedef map CharMap; + + // Internal: Static Attributes. + static FontMap _fontMap; + // Internal: Attributes. + CharMap _table; + string _name; + int _height; + + // Internal: Constructors. + BannerFont ( const BannerFont& ); + ~BannerFont (); + inline BannerFont& operator= ( const BannerFont& ); + + }; + + + + +// ------------------------------------------------------------------- +// Class : "CRL::Banner". + + + class Banner { + public: + // Constructor & Destructor. + Banner ( string name="" + , string version="" + , string purpose="" + , string date="" + , string authors="" + , string contributors="" ); + virtual ~Banner (); + // Accessors. + inline const BannerFont* getFont () const; + inline const string& getName () const; + inline const string& getVersion () const; + inline const string& getPurpose () const; + inline const string& getDate () const; + inline const string& getAuthors () const; + inline const string& getContributors () const; + inline unsigned int getScreenWidth () const; + // Modifiers. + void setFont ( BannerFont* font ); + void setName ( string name ); + void setVersion ( string version ); + void setPurpose ( string purpose ); + void setDate ( string date ); + void setAuthors ( string authors ); + void setContributors ( string contributors ); + void setScreenWidth ( unsigned screenWidth ); + // Hurricane Management. + virtual const string _getPrint () const { return ( _banner.str() ); }; + + // Internal: Attributes. + private: + string _name; + string _version; + string _purpose; + string _date; + string _authors; + string _contributors; + unsigned int _screenWidth; + const BannerFont* _font; + string* _lines; + ostringstream _banner; + + // Internal: Constructors. + Banner ( const Banner & ); + Banner& operator= ( const Banner & ); + // Internal: Methods. + void _redraw (); + }; + + +// Inline Functions. + inline int BannerFont::BigChar::getHeight () const { return _height; } + inline const BannerFont* BannerFont::BigChar::getFont () const { return _font; } + inline BannerFont::BannerFont ( const string& name ): _table(), _name(name) {} + inline int BannerFont::getHeight () const { return _height; } + inline const BannerFont* Banner::getFont () const { return _font; } + inline const string& Banner::getName () const { return _name; } + inline const string& Banner::getVersion () const { return _version; } + inline const string& Banner::getPurpose () const { return _purpose; } + inline const string& Banner::getDate () const { return _date; } + inline const string& Banner::getAuthors () const { return _authors; } + inline const string& Banner::getContributors () const { return _contributors; } + inline unsigned int Banner::getScreenWidth () const { return _screenWidth; } + + +} // End of CRL namespace. + + +// Hurricane Management. + +inline std::string getPrint ( const CRL::BannerFont::BigChar& c ) { return c._getPrint(); } +inline std::string getPrint ( const CRL::Banner& b ) { return b._getPrint(); } +inline std::ostream& operator<< ( std::ostream& o, const CRL::BannerFont::BigChar& c ) { return o << getPrint(c); } +inline std::ostream& operator<< ( std::ostream& o, const CRL::Banner& b ) { return o << getPrint(b); } + +MSTREAM_R_SUPPORT(CRL::Banner); + + +# endif diff --git a/crlcore/src/ccore/crlcore/CConfig.h b/crlcore/src/ccore/crlcore/CConfig.h new file mode 100644 index 00000000..8899b736 --- /dev/null +++ b/crlcore/src/ccore/crlcore/CConfig.h @@ -0,0 +1 @@ +/* #undef CORIOLIS_TOP */ diff --git a/crlcore/src/ccore/crlcore/CLayerConnexity.h b/crlcore/src/ccore/crlcore/CLayerConnexity.h new file mode 100644 index 00000000..9d0d9dba --- /dev/null +++ b/crlcore/src/ccore/crlcore/CLayerConnexity.h @@ -0,0 +1,192 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== +// +// $Id: CLayerConnexity.h,v 1.7 2007/07/29 15:27:22 jpc Exp $ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o r e L i b r a r y | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./CLayerConnexity.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +# ifndef __CRL_LAYER_CONNEXITY_H__ +# define __CRL_LAYER_CONNEXITY_H__ + + +# include + +# include "hurricane/Layer.h" +# include "hurricane/BasicLayer.h" +# include "hurricane/Contact.h" + +# include "hurricane/Utilities.h" +# include "hurricane/CXML.h" +# include "hurricane/Slot.h" + + + +namespace CRL { + + +// ------------------------------------------------------------------- +// Forward Declarations. + + class CDataBase; + + + +// ------------------------------------------------------------------- +// Class : "Eolienne::CLayerConnexity". + + class CLayerConnexity { + + // Types. + protected: + typedef vector LayerTable; + typedef map MaskLayerMap; + typedef map LayerMap; + + // Attributes. + protected: + Layer::Mask _cutMask; + LayerTable _layerTable; + MaskLayerMap _contactMap; + MaskLayerMap _oppositeMap; + MaskLayerMap _contactTopMap; + MaskLayerMap _contactBottomMap; + LayerMap _topMap; + LayerMap _bottomMap; + LayerMap _connectorMap; + + // Constructors. + protected: + CLayerConnexity (); + void _postCreate (); + private: + CLayerConnexity ( const CLayerConnexity& ); + CLayerConnexity& operator= ( const CLayerConnexity& ); + + // Destructors. + protected: + virtual ~CLayerConnexity (); + virtual void _preDestroy (); + public: + virtual void destroy(); + + // Accessors. + public: + Layer* getContactLayer ( Layer* layer1, Layer* layer2 ) const; + Layer* getContactTopLayer ( Layer* layer ) const; + Layer* getContactBottomLayer ( Layer* layer ) const; + Layer* getOppositeLayer ( Contact* contact, Layer* layer ) const; + Layer* getTopLayer ( Layer* layer ) const; + Layer* getBottomLayer ( Layer* layer ) const; + bool IsOnTop ( Layer* layer1, Layer* layer2 ) const; + bool IsConnectorLayer ( Layer* layer ) const; + Layer* getNonConnectorLayer ( Layer* layer ) const; + Layer* getLayer ( unsigned index ) const; + unsigned getIndex ( Layer* layer ) const; + unsigned getLayerTableSize () const { return _layerTable.size(); }; + + // Modifiers. + public: + void AddContact ( Layer* bottomLayer, Layer* topLayer, Layer* contact ); + void SortLayers (); + + // XML related constructors. + public: + static void createFromXml ( CLayerConnexity* lc, CXmlNode& tree ); + + // Hurricane Managment. + public: + Record* _getRecord () const; + string _getString () const; + string _getTypeName() const { return ( "CRL::CLayerConnexity" ); }; + + // Friends. + friend class CDataBase; + }; + + + + +// x-----------------------------------------------------------------x +// | Functions Declarations | +// x-----------------------------------------------------------------x + + + // Global CLayerConnexity access. + CLayerConnexity* getCLayerConnexity (); + + unsigned getLayerTableSize (); + unsigned getIndex ( Layer* layer ); + Layer* getLayer ( unsigned index ); + Layer* getContactLayer ( Layer* layer1, Layer* layer2 ); + inline Layer* getContactLayer ( unsigned index1, unsigned index2 ) + { return getContactLayer(getLayer(index1),getLayer(index2)); }; + Layer* getContactTopLayer ( Layer* layer ); + Layer* getContactBottomLayer ( Layer* layer ); + Layer* getOppositeLayer ( Contact* contact, Layer* layer ); + Layer* getTopLayer ( Layer* layer ); + Layer* getBottomLayer ( Layer* layer ); + bool IsOnTop ( Layer* layer1, Layer* layer2 ); + bool IsConnectorLayer ( Layer* layer ); + Layer* getNonConnectorLayer ( Layer* layer ); + + + + +} // End of namespace CRL. + + + + +// x-----------------------------------------------------------------x +// | Functions Overload for Hurricane Managment | +// x-----------------------------------------------------------------x + + +# endif diff --git a/crlcore/src/ccore/crlcore/COptions.h b/crlcore/src/ccore/crlcore/COptions.h new file mode 100644 index 00000000..8d57e66f --- /dev/null +++ b/crlcore/src/ccore/crlcore/COptions.h @@ -0,0 +1,188 @@ + + +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== + + +// -*- C++ -*- +// +// $Id: COptions.h,v 1.5 2006/02/19 00:52:46 jpc Exp $ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./Options.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + + +#include "crlcore/Utilities.h" + + + + +#ifndef __CRL_OPTIONS_H__ +#define __CRL_OPTIONS_H__ + + + + +namespace CRL { + + + using std::vector; + + + +// ------------------------------------------------------------------- +// Class : "CRL::COptions()". + + class COptions { + + private: class Option { + private: string _nameShort; + private: string _nameLong; + private: bool _hasArg; + private: string _defaultArg; + private: vector _args; + private: int _times; + private: int _select; + + public: Option ( string nameShort + , string nameLong + , bool hasArg=false + , string defaultArg="" ) + : _nameShort(nameShort) + , _nameLong(nameLong) + , _hasArg(hasArg) + , _defaultArg(defaultArg) + , _args() + , _times(0) + , _select(0) + { }; + + public: string getShort () { return ( _nameShort ); }; + public: string getLong () { return ( _nameLong ); }; + public: bool getHasArg () { return ( _hasArg ); }; + public: string getDefault () { return ( _defaultArg ); }; + public: int getTimes () { return ( _times ); }; + public: string& getArg ( size_t i ); + + public: void SetSelect ( int select ) { _select = select; }; + public: int AddArg ( string val ) + { _args.push_back (val); return ( _times++ ); }; + public: void Clear () + { _args.clear (); _times = 0; _select = 0; } + + public: operator string (); + public: operator bool () { return ( _times > 0 ); }; + public: operator int () { return ( _times ); }; + }; + + typedef vector