* ./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".
This commit is contained in:
parent
905c7b4960
commit
c5d8077730
|
@ -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)
|
|
@ -0,0 +1,4 @@
|
|||
install ( FILES FindCORIOLIS.cmake
|
||||
FindOPENACCESS.cmake
|
||||
FindLEFDEF.cmake
|
||||
DESTINATION /share/cmake_modules )
|
|
@ -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)
|
|
@ -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 )
|
|
@ -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)
|
|
@ -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 )
|
|
@ -0,0 +1,250 @@
|
|||
<?xml version="1.0"?>
|
||||
<graphics>
|
||||
<displaystyles>
|
||||
<displaystyle name="Alliance.Coriolis [black]">
|
||||
<default>true</default>
|
||||
<description>Alliance Coriolis Look - black background</description>
|
||||
<darkening>3.0</darkening>
|
||||
<!-- Patterns:
|
||||
Poids 01010101 aa55aa55aa55aa55 nImplant
|
||||
10101010 pImplant
|
||||
01010101 poly
|
||||
10101010
|
||||
01010101
|
||||
10101010
|
||||
01010101
|
||||
10101010
|
||||
|
||||
10111011 bbddee77bbddee77 active
|
||||
11011101
|
||||
11101110
|
||||
01110111
|
||||
10111011
|
||||
11011101
|
||||
11101110
|
||||
11110111
|
||||
-->
|
||||
<group name="Viewer">
|
||||
<drawingstyle name="fallback" color="238,238,238" border="1" pattern="55AA55AA55AA55AA"/>
|
||||
<drawingstyle name="background" color="50,50,50" border="1"/>
|
||||
<drawingstyle name="foreground" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="rubber" color="192,0,192" border="4" threshold="0.02"/>
|
||||
<drawingstyle name="phantom" color="139,134,130" border="1"/>
|
||||
<drawingstyle name="boundaries" color="208,199,192" border="1" pattern="0000000000000000" threshold="0"/>
|
||||
<drawingstyle name="marker" color="80,250,80" border="1"/>
|
||||
<drawingstyle name="selectionDraw" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="selectionFill" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="grid" color="255,255,255" border="1" threshold="2.0"/>
|
||||
<drawingstyle name="spot" color="255,255,255" border="2" threshold="6.0"/>
|
||||
<drawingstyle name="ghost" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="text.ruler" color="255,255,255" border="1" threshold="0.0"/>
|
||||
<drawingstyle name="text.instance" color="0,0,0" border="1" threshold="4.0"/>
|
||||
<drawingstyle name="undef" color="238,130,238" border="0" pattern="2244118822441188"/>
|
||||
</group>
|
||||
<group name="Active Layers">
|
||||
<drawingstyle name="nWell" color="210,180,140" pattern="55AA55AA55AA55AA" threshold="1.50"/>
|
||||
<drawingstyle name="pWell" color="255,255,224" pattern="55AA55AA55AA55AA" threshold="1.50"/>
|
||||
<drawingstyle name="nImplant" color="124,252,0" pattern="55AA55AA55AA55AA" threshold="1.50"/>
|
||||
<drawingstyle name="pImplant" color="255,255,0" pattern="55AA55AA55AA55AA" threshold="1.50"/>
|
||||
<drawingstyle name="active" color="255,255,255" pattern="bbddee77bbddee77" threshold="1.50"/>
|
||||
<drawingstyle name="poly" color="255,0,0" pattern="55AA55AA55AA55AA" threshold="1.50"/>
|
||||
</group>
|
||||
<group name="Routing Layers">
|
||||
<drawingstyle name="metal1" color="0,0,255" pattern="AA55AA55AA55AA55" threshold="0.80"/>
|
||||
<drawingstyle name="metal2" color="0,255,255" pattern="8822882288228822" threshold="0.40"/>
|
||||
<drawingstyle name="metal3" color="255,182,193" pattern="4411441144114411" threshold="0.02"/>
|
||||
<drawingstyle name="metal4" color="0,255,0" pattern="2288228822882288" threshold="0.02"/>
|
||||
<drawingstyle name="metal5" color="255,255,0" pattern="1144114411441144" threshold="0.02"/>
|
||||
<drawingstyle name="metal6" color="238,130,238" pattern="8822882288228822" threshold="0.02"/>
|
||||
</group>
|
||||
<group name="Cuts (VIA holes)">
|
||||
<drawingstyle name="cut0" color="0,150,150" threshold="1.50"/>
|
||||
<drawingstyle name="cut1" color="0,255,255" threshold="0.80"/>
|
||||
<drawingstyle name="cut2" color="255,182,193" threshold="0.80"/>
|
||||
<drawingstyle name="cut3" color="0,255,0" threshold="0.80"/>
|
||||
<drawingstyle name="cut4" color="255,255,0" threshold="0.80"/>
|
||||
<drawingstyle name="cut5" color="238,130,238" threshold="0.80"/>
|
||||
</group>
|
||||
<group name="MIM6">
|
||||
<drawingstyle name="topmim6" color="0,0,255" pattern="AA55AA55AA55AA55" threshold="0.80"/>
|
||||
<drawingstyle name="botmim6" color="0,255,255" pattern="8822882288228822" threshold="0.80"/>
|
||||
<drawingstyle name="padopen" color="255,182,193" pattern="4411441144114411" threshold="0.80"/>
|
||||
<drawingstyle name="alucap" color="0,255,0" pattern="2288228822882288" threshold="0.80"/>
|
||||
</group>
|
||||
<group name="Blockages">
|
||||
<drawingstyle name="blockage1" color="0,0,255" pattern="006070381c0e0703" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="blockage2" color="0,255,255" pattern="8103060c183060c0" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="blockage3" color="255,182,193" pattern="8800220088002200" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="blockage4" color="0,255,0" pattern="2288228822882288" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="blockage5" color="255,255,0" pattern="1144114411441144" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="blockage6" color="238,130,238" pattern="8822882288228822" threshold="0.80" border="2"/>
|
||||
</group>
|
||||
<group name="Knick & Kite">
|
||||
<drawingstyle name="SPL1" color="255,0,0"/>
|
||||
<drawingstyle name="AutoLayer" color="255,0,255"/>
|
||||
<drawingstyle name="gmetalh" color="128,255,200" pattern="8822882288228822" border="1"/>
|
||||
<drawingstyle name="gmetalv" color="200,200,255" pattern="4411441144114411" border="1"/>
|
||||
<drawingstyle name="gcut" color="255,255,190" border="1"/>
|
||||
</group>
|
||||
</displaystyle>
|
||||
<displaystyle name="Alliance.Coriolis [white]">
|
||||
<inherit>Alliance.Coriolis [black]</inherit>
|
||||
<description>Alliance Coriolis Look - white background</description>
|
||||
<darkening>0.8</darkening>
|
||||
<group name="Viewer">
|
||||
<drawingstyle name="fallback" color="0,0,0" border="1" pattern="55AA55AA55AA55AA"/>
|
||||
<drawingstyle name="background" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="foreground" color="0,0,0" border="1"/>
|
||||
<drawingstyle name="selectionDraw" color="0,0,0" border="1"/>
|
||||
<drawingstyle name="selectionFill" color="0,0,0" border="1"/>
|
||||
<drawingstyle name="grid" color="0,0,0" border="1" threshold="6.0"/>
|
||||
<drawingstyle name="spot" color="0,0,0" border="1" threshold="6.0"/>
|
||||
<drawingstyle name="ghost" color="0,0,0" border="1"/>
|
||||
<drawingstyle name="text.ruler" color="0,0,0" border="1" threshold="0.0"/>
|
||||
<drawingstyle name="text.instance" color="0,0,0" border="1" threshold="4.0"/>
|
||||
<drawingstyle name="undef" color="0,0,0" border="0" pattern="2244118822441188"/>
|
||||
</group>
|
||||
</displaystyle>
|
||||
<displaystyle name="Alliance.Classic [black]">
|
||||
<description>Alliance Standard Look - black background</description>
|
||||
<darkening>3.0</darkening>
|
||||
<group name="Viewer">
|
||||
<drawingstyle name="fallback" color="238,238,238" border="1" pattern="55AA55AA55AA55AA"/>
|
||||
<drawingstyle name="background" color="50,50,50" border="1"/>
|
||||
<drawingstyle name="foreground" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="rubber" color="192,0,192" border="4" threshold="0.02"/>
|
||||
<drawingstyle name="phantom" color="139,134,130" border="1"/>
|
||||
<drawingstyle name="boundaries" color="208,199,192" border="1" pattern="0000000000000000" threshold="0"/>
|
||||
<drawingstyle name="marker" color="80,250,80" border="1"/>
|
||||
<drawingstyle name="selectionDraw" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="selectionFill" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="grid" color="255,255,255" border="1" threshold="2.0"/>
|
||||
<drawingstyle name="spot" color="255,255,255" border="2" threshold="6.0"/>
|
||||
<drawingstyle name="ghost" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="text.ruler" color="255,255,255" border="1" threshold="0.0"/>
|
||||
<drawingstyle name="text.instance" color="255,255,255" border="1" threshold="4.0"/>
|
||||
<drawingstyle name="undef" color="238,130,238" border="0" pattern="2244118822441188"/>
|
||||
</group>
|
||||
<group name="Active Layers">
|
||||
<drawingstyle name="nWell" color="210,180,140" pattern="feffffffefffffff" border="1" threshold="1.50"/>
|
||||
<drawingstyle name="pWell" color="255,255,224" pattern="feffffffefffffff" border="1" threshold="1.50"/>
|
||||
<drawingstyle name="nImplant" color="124,252,0" pattern="77bbddee77bbddee" border="1" threshold="1.50"/>
|
||||
<drawingstyle name="pImplant" color="255,255,0" pattern="77bbddee77bbddee" border="1" threshold="1.50"/>
|
||||
<drawingstyle name="active" color="255,255,255" pattern="bbddee77bbddee77" border="1" threshold="1.50"/>
|
||||
<drawingstyle name="poly" color="255,0,0" pattern="aa55aa55aa55aa55" border="1" threshold="1.50"/>
|
||||
</group>
|
||||
<group name="Routing Layers">
|
||||
<drawingstyle name="metal1" color="0,0,255" pattern="8844221188442211" border="1" threshold="0.80"/>
|
||||
<drawingstyle name="metal2" color="0,255,255" pattern="8800220088002200" border="1" threshold="0.40"/>
|
||||
<drawingstyle name="metal3" color="255,182,193" pattern="8800220088002200" border="1" threshold="0.02"/>
|
||||
<drawingstyle name="metal4" color="0,255,0" pattern="8800220088002200" border="1" threshold="0.02"/>
|
||||
<drawingstyle name="metal5" color="255,255,0" pattern="8800220088002200" border="1" threshold="0.02"/>
|
||||
<drawingstyle name="metal6" color="238,130,238" pattern="8800220088002200" border="1" threshold="0.02"/>
|
||||
</group>
|
||||
<group name="Cuts (VIA holes)">
|
||||
<drawingstyle name="cut0" color="0,150,150" threshold="1.50"/>
|
||||
<drawingstyle name="cut1" color="0,255,255" threshold="0.80"/>
|
||||
<drawingstyle name="cut2" color="255,182,193" threshold="0.80"/>
|
||||
<drawingstyle name="cut3" color="0,255,0" threshold="0.80"/>
|
||||
<drawingstyle name="cut4" color="255,255,0" threshold="0.80"/>
|
||||
<drawingstyle name="cut5" color="238,130,238" threshold="0.80"/>
|
||||
</group>
|
||||
<group name="MIM6">
|
||||
<drawingstyle name="topmim6" color="0,0,255" pattern="AA55AA55AA55AA55" threshold="0.80"/>
|
||||
<drawingstyle name="botmim6" color="0,255,255" pattern="8822882288228822" threshold="0.80"/>
|
||||
<drawingstyle name="padopen" color="255,182,193" pattern="4411441144114411" threshold="0.80"/>
|
||||
<drawingstyle name="alucap" color="0,255,0" pattern="2288228822882288" threshold="0.80"/>
|
||||
</group>
|
||||
<group name="Blockages">
|
||||
<drawingstyle name="blockage1" color="0,0,255" pattern="8844221188442211" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="blockage2" color="0,255,255" pattern="8800220088002200" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="blockage3" color="255,182,193" pattern="8800220088002200" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="blockage4" color="0,255,0" pattern="8800220088002200" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="blockage5" color="255,255,0" pattern="8800220088002200" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="blockage6" color="238,130,238" pattern="8800220088002200" threshold="0.80" border="2"/>
|
||||
</group>
|
||||
<group name="Knick & Kite">
|
||||
<drawingstyle name="SPL1" color="255,0,0"/>
|
||||
<drawingstyle name="AutoLayer" color="255,0,255"/>
|
||||
<drawingstyle name="gmetalh" color="128,255,200" pattern="8822882288228822" border="1"/>
|
||||
<drawingstyle name="gmetalv" color="200,200,255" pattern="4411441144114411" border="1"/>
|
||||
<drawingstyle name="gcontact" color="255,255,190" border="1"/>
|
||||
</group>
|
||||
</displaystyle>
|
||||
<displaystyle name="Alliance.Classic [white]">
|
||||
<inherit>Alliance.Classic [black]</inherit>
|
||||
<description>Alliance Standard Look - white background</description>
|
||||
<darkening>3.0</darkening>
|
||||
<group name="Viewer">
|
||||
<drawingstyle name="fallback" color="0,0,0" border="1" pattern="55AA55AA55AA55AA"/>
|
||||
<drawingstyle name="background" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="foreground" color="0,0,0" border="1"/>
|
||||
<drawingstyle name="selectionDraw" color="0,0,0" border="1"/>
|
||||
<drawingstyle name="selectionFill" color="0,0,0" border="1"/>
|
||||
<drawingstyle name="grid" color="0,0,0" border="1" threshold="6.0"/>
|
||||
<drawingstyle name="spot" color="0,0,0" border="1" threshold="6.0"/>
|
||||
<drawingstyle name="ghost" color="0,0,0" border="1"/>
|
||||
<drawingstyle name="text.ruler" color="0,0,0" border="1" threshold="0.0"/>
|
||||
<drawingstyle name="text.instance" color="0,0,0" border="1" threshold="4.0"/>
|
||||
<drawingstyle name="undef" color="0,0,0" border="0" pattern="2244118822441188"/>
|
||||
</group>
|
||||
</displaystyle>
|
||||
<displaystyle name="Ispd Global Route">
|
||||
<inherit>Alliance.Coriolis [black]</inherit>
|
||||
<description>Ispd Global Route Look - black background</description>
|
||||
<darkening>3.0</darkening>
|
||||
<group name="Viewer">
|
||||
<drawingstyle name="background" color="0,0,0" border="1"/>
|
||||
<drawingstyle name="rubber" color="192,0,192" border="1" threshold="0"/>
|
||||
</group>
|
||||
<group name="Knick & Kite">
|
||||
<drawingstyle name="gmetalh" color="128,255,200" pattern="8822882288228822" border="1" threshold="0"/>
|
||||
<drawingstyle name="gmetalv" color="200,200,255" pattern="4411441144114411" border="1" threshold="0"/>
|
||||
<drawingstyle name="gcontact" color="255,255,190" border="1" threshold="0"/>
|
||||
</group>
|
||||
</displaystyle>
|
||||
<displaystyle name="Layout Design">
|
||||
<inherit>Alliance.Coriolis [black]</inherit>
|
||||
<description>Useful for debugging layout - black background</description>
|
||||
<darkening>3.0</darkening>
|
||||
<group name="Active Layers">
|
||||
<drawingstyle name="nWell" color="210,180,140" pattern="0000000000000000" threshold="1.50" border="2"/>
|
||||
<drawingstyle name="pWell" color="255,255,224" pattern="0000000000000000" threshold="1.50" border="2"/>
|
||||
<drawingstyle name="nImplant" color="124,252,0" pattern="0000000000000000" threshold="1.50" border="2"/>
|
||||
<drawingstyle name="pImplant" color="255,255,0" pattern="0000000000000000" threshold="1.50" border="2"/>
|
||||
<drawingstyle name="active" color="255,255,255" pattern="0000000000000000" threshold="1.50" border="2"/>
|
||||
<drawingstyle name="poly" color="255,0,0" pattern="0000000000000000" threshold="1.50" border="2"/>
|
||||
</group>
|
||||
<group name="Routing Layers">
|
||||
<drawingstyle name="metal1" color="0,0,255" pattern="0000000000000000" threshold="0.80" border="2"/>
|
||||
<drawingstyle name="metal2" color="0,255,255" pattern="0000000000000000" threshold="0.40" border="2"/>
|
||||
<drawingstyle name="metal3" color="255,182,193" pattern="0000000000000000" threshold="0.02" border="2"/>
|
||||
<drawingstyle name="metal4" color="0,255,0" pattern="0000000000000000" threshold="0.02" border="2"/>
|
||||
<drawingstyle name="metal5" color="255,255,0" pattern="0000000000000000" threshold="0.02" border="2"/>
|
||||
<drawingstyle name="metal6" color="238,130,238" pattern="0000000000000000" threshold="0.02" border="2"/>
|
||||
</group>
|
||||
<group name="Cuts (VIA holes)">
|
||||
<drawingstyle name="cut0" color="0,150,150" pattern="8800220088002200" threshold="1.50" border="1"/>
|
||||
<drawingstyle name="cut1" color="0,255,255" pattern="0000000000000000" threshold="0.80" border="1"/>
|
||||
<drawingstyle name="cut2" color="255,182,193" pattern="0000000000000000" threshold="0.80" border="1"/>
|
||||
<drawingstyle name="cut3" color="0,255,0" pattern="0000000000000000" threshold="0.80" border="1"/>
|
||||
<drawingstyle name="cut4" color="255,255,0" pattern="0000000000000000" threshold="0.80" border="1"/>
|
||||
<drawingstyle name="cut5" color="238,130,238" pattern="0000000000000000" threshold="0.80" border="1"/>
|
||||
</group>
|
||||
</displaystyle>
|
||||
<displaystyle name="Layout Design White">
|
||||
<inherit>Layout Design</inherit>
|
||||
<description>Useful for debugging layout - white background</description>
|
||||
<darkening>3.0</darkening>
|
||||
<group name="Viewer">
|
||||
<drawingstyle name="background" color="255,255,255" border="1"/>
|
||||
<drawingstyle name="grid" color="0,0,0" border="1" threshold="2.0"/>
|
||||
<drawingstyle name="spot" color="0,0,0" border="1" threshold="2.0"/>
|
||||
<drawingstyle name="text.ruler" color="0,0,0" border="1" threshold="0.0"/>
|
||||
</group>
|
||||
<group name="Active Layers">
|
||||
<drawingstyle name="active" color="175,175,175" pattern="0000000000000000" threshold="1.50" border="2"/>
|
||||
</group>
|
||||
</displaystyle>
|
||||
</displaystyles>
|
||||
</graphics>
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0"?>
|
||||
<environment>
|
||||
<variable name="CELL_TOP" value="/opt/alliance-5.0"/>
|
||||
<technologies>
|
||||
<hurricane>
|
||||
<config>${CORIOLIS_TOP}/share/etc/technology.symbolic.xml</config>
|
||||
</hurricane>
|
||||
<real>
|
||||
<config>${CORIOLIS_TOP}/share/etc/technology.hcmos9.s2r.xml</config>
|
||||
</real>
|
||||
<lef>
|
||||
<config>${CORIOLIS_TOP}/share/etc/cmos.lef</config>
|
||||
</lef>
|
||||
<display>
|
||||
<config>${CORIOLIS_TOP}/share/etc/display.xml</config>
|
||||
</display>
|
||||
</technologies>
|
||||
<libraries>
|
||||
<catalog>CATAL</catalog>
|
||||
<working>
|
||||
<library>.</library>
|
||||
</working>
|
||||
<system operation="append">
|
||||
<library>${CELL_TOP}/cells/sxlib</library>
|
||||
<library>${CELL_TOP}/cells/dp_sxlib</library>
|
||||
<library>${CELL_TOP}/cells/ramlib</library>
|
||||
<library>${CELL_TOP}/cells/romlib</library>
|
||||
<library>${CELL_TOP}/cells/rflib</library>
|
||||
<library>${CELL_TOP}/cells/rf2lib</library>
|
||||
<library>${CELL_TOP}/cells/pxlib</library>
|
||||
<library>${CORIOLIS_TOP}/share/cells/stratus2sxlib</library>
|
||||
</system>
|
||||
</libraries>
|
||||
<formats>
|
||||
<scale>100</scale>
|
||||
<input>
|
||||
<logical>vst</logical>
|
||||
<physical>ap</physical>
|
||||
</input>
|
||||
<output>
|
||||
<logical>vst</logical>
|
||||
<physical>ap</physical>
|
||||
</output>
|
||||
</formats>
|
||||
<signals>
|
||||
<vdd>vdd</vdd>
|
||||
<vss>vss</vss>
|
||||
<clock>^ck$</clock>
|
||||
</signals>
|
||||
</environment>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0"?>
|
||||
<technology>
|
||||
<real>
|
||||
<name>cmos065</name>
|
||||
<grid value="0.005" unit="micron"/>
|
||||
<gridsperlambda value="24"/>
|
||||
<layers>
|
||||
<!-- Non routing layers -->
|
||||
<processlayer symbolic="nWell" real="NW" gdsII="3" />
|
||||
<processlayer symbolic="nImplant" real="NP" gdsII="26"/>
|
||||
<processlayer symbolic="pImplant" real="PP" gdsII="25"/>
|
||||
<processlayer symbolic="active" real="OD" gdsII="6" />
|
||||
<processlayer symbolic="poly" real="PO" gdsII="17"/>
|
||||
<!-- Routing layers -->
|
||||
<processlayer symbolic="cut0" real="CO" gdsII="30"/>
|
||||
<processlayer symbolic="metal1" real="M1" gdsII="31"/>
|
||||
<processlayer symbolic="cut1" real="VIA1X" gdsII="51"/>
|
||||
<processlayer symbolic="metal2" real="M2X" gdsII="32"/>
|
||||
<processlayer symbolic="cut2" real="VIA2X" gdsII="52"/>
|
||||
<processlayer symbolic="metal3" real="M3X" gdsII="33"/>
|
||||
<processlayer symbolic="cut3" real="VIA3X" gdsII="53"/>
|
||||
<processlayer symbolic="metal4" real="M4X" gdsII="34"/>
|
||||
<processlayer symbolic="cut4" real="VIA4X" gdsII="54"/>
|
||||
<processlayer symbolic="metal5" real="M5X" gdsII="35"/>
|
||||
<processlayer symbolic="cut5" real="VIA5X" gdsII="55"/>
|
||||
<processlayer symbolic="metal6" real="M6X" gdsII="36"/>
|
||||
</layers>
|
||||
</real>
|
||||
</technology>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0"?>
|
||||
<technology>
|
||||
<real>
|
||||
<name>fake</name>
|
||||
<grid value="0.005" unit="micron"/>
|
||||
<gridsperlambda value="24"/>
|
||||
<layers>
|
||||
<!-- Non routing layers -->
|
||||
<processlayer symbolic="nWell" real="NW" gdsII="3" />
|
||||
<processlayer symbolic="nImplant" real="NP" gdsII="26"/>
|
||||
<processlayer symbolic="pImplant" real="PP" gdsII="25"/>
|
||||
<processlayer symbolic="active" real="AC" gdsII="6" />
|
||||
<processlayer symbolic="poly" real="PO" gdsII="17"/>
|
||||
<!-- Routing layers -->
|
||||
<processlayer symbolic="cut0" real="C0" gdsII="30"/>
|
||||
<processlayer symbolic="metal1" real="M1" gdsII="31"/>
|
||||
<processlayer symbolic="cut1" real="C1" gdsII="51"/>
|
||||
<processlayer symbolic="metal2" real="M2" gdsII="32"/>
|
||||
<processlayer symbolic="cut2" real="C2" gdsII="52"/>
|
||||
<processlayer symbolic="metal3" real="M3" gdsII="33"/>
|
||||
<processlayer symbolic="cut3" real="C3" gdsII="53"/>
|
||||
<processlayer symbolic="metal4" real="M4" gdsII="34"/>
|
||||
<processlayer symbolic="cut4" real="C4" gdsII="54"/>
|
||||
<processlayer symbolic="metal5" real="M5" gdsII="35"/>
|
||||
<processlayer symbolic="cut5" real="C5" gdsII="55"/>
|
||||
<processlayer symbolic="metal6" real="M6" gdsII="36"/>
|
||||
</layers>
|
||||
</real>
|
||||
</technology>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0"?>
|
||||
<technology>
|
||||
<real>
|
||||
<name>hcmos9</name>
|
||||
<grid value="0.005" unit="micron"/>
|
||||
<gridsperlambda value="24"/>
|
||||
<layers>
|
||||
<!-- Non routing layers -->
|
||||
<processlayer symbolic="nWell" real="NWELL" gdsII="3" />
|
||||
<processlayer symbolic="nImplant" real="NPLUS" gdsII="26"/>
|
||||
<processlayer symbolic="pImplant" real="PPLUS" gdsII="25"/>
|
||||
<processlayer symbolic="active" real="ACTIVE" gdsII="6" />
|
||||
<processlayer symbolic="poly" real="POLY" gdsII="17"/>
|
||||
<!-- Routing layers -->
|
||||
<processlayer symbolic="cut0" real="CONTACT" gdsII="30"/>
|
||||
<processlayer symbolic="metal1" real="METAL1" gdsII="31"/>
|
||||
<processlayer symbolic="cut1" real="VIA1" gdsII="51"/>
|
||||
<processlayer symbolic="metal2" real="METAL2" gdsII="32"/>
|
||||
<processlayer symbolic="cut2" real="VIA2" gdsII="52"/>
|
||||
<processlayer symbolic="metal3" real="METAL3" gdsII="33"/>
|
||||
<processlayer symbolic="cut3" real="VIA3" gdsII="53"/>
|
||||
<processlayer symbolic="metal4" real="METAL4" gdsII="34"/>
|
||||
<processlayer symbolic="cut4" real="VIA4" gdsII="54"/>
|
||||
<processlayer symbolic="metal5" real="METAL5" gdsII="35"/>
|
||||
<processlayer symbolic="cut5" real="VIA5" gdsII="55"/>
|
||||
<processlayer symbolic="metal6" real="METAL6" gdsII="36"/>
|
||||
</layers>
|
||||
</real>
|
||||
</technology>
|
|
@ -0,0 +1,328 @@
|
|||
<?xml version="1.0"?>
|
||||
<technology>
|
||||
<name>Alliance</name>
|
||||
|
||||
<!-- Non-Routing Layers -->
|
||||
<basiclayer name="nWell" material="nWell"/>
|
||||
<basiclayer name="pWell" material="pWell"/>
|
||||
<basiclayer name="nImplant" material="nImplant"/>
|
||||
<basiclayer name="pImplant" material="pImplant"/>
|
||||
<basiclayer name="active" material="active"/>
|
||||
<basiclayer name="poly" material="poly"/>
|
||||
|
||||
<!-- Routing Layers & VIA Cuts -->
|
||||
<!-- NB: order *is* meaningful -->
|
||||
<basiclayer name="cut0" material="cut"/>
|
||||
<basiclayer name="metal1" material="metal"/>
|
||||
<basiclayer name="cut1" material="cut"/>
|
||||
<basiclayer name="metal2" material="metal"/>
|
||||
<basiclayer name="cut2" material="cut"/>
|
||||
<basiclayer name="metal3" material="metal"/>
|
||||
<basiclayer name="cut3" material="cut"/>
|
||||
<basiclayer name="metal4" material="metal"/>
|
||||
<basiclayer name="cut4" material="cut"/>
|
||||
<basiclayer name="metal5" material="metal"/>
|
||||
<basiclayer name="cut5" material="cut"/>
|
||||
<basiclayer name="metal6" material="metal"/>
|
||||
<basiclayer name="topmim6"/>
|
||||
<basiclayer name="botmim6"/>
|
||||
<basiclayer name="padopen"/>
|
||||
<basiclayer name="alucap"/>
|
||||
|
||||
<!-- Obstacles -->
|
||||
<basiclayer name="blockage1" material="blockage" basiclayer="metal1"/>
|
||||
<basiclayer name="blockage2" material="blockage" basiclayer="metal2"/>
|
||||
<basiclayer name="blockage3" material="blockage" basiclayer="metal3"/>
|
||||
<basiclayer name="blockage4" material="blockage" basiclayer="metal4"/>
|
||||
<basiclayer name="blockage5" material="blockage" basiclayer="metal5"/>
|
||||
<basiclayer name="blockage6" material="blockage" basiclayer="metal6"/>
|
||||
|
||||
<!-- Miscellaneous: -->
|
||||
<basiclayer name="text.cell" material="other"/>
|
||||
<basiclayer name="text.instance" material="other"/>
|
||||
<basiclayer name="undef" material="other"/>
|
||||
<basiclayer name="SPL1" material="other"/>
|
||||
<basiclayer name="AutoLayer" material="other"/>
|
||||
|
||||
<!-- Symbolic Layers: Non-Routing Layers -->
|
||||
<regularlayer name="NWELL" type="UNDEFINED">
|
||||
<layer name="nWell"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="PWELL" type="UNDEFINED">
|
||||
<layer name="pWell"/>
|
||||
</regularlayer>
|
||||
<diffusionlayer name="NTIE" type="UNDEFINED">
|
||||
<layer name="nWell"/>
|
||||
<layer name="nImplant"/>
|
||||
<layer name="active"/>
|
||||
</diffusionlayer>
|
||||
<diffusionlayer name="PTIE" type="UNDEFINED">
|
||||
<layer name="pWell"/>
|
||||
<layer name="pImplant"/>
|
||||
<layer name="active"/>
|
||||
</diffusionlayer>
|
||||
<diffusionlayer name="NDIF" type="UNDEFINED">
|
||||
<layer name="nImplant"/>
|
||||
<layer name="active"/>
|
||||
</diffusionlayer>
|
||||
<diffusionlayer name="PDIF" type="UNDEFINED">
|
||||
<layer name="pImplant"/>
|
||||
<layer name="active"/>
|
||||
</diffusionlayer>
|
||||
<diffusionlayer name="GATE" type="UNDEFINED">
|
||||
<layer name="poly"/>
|
||||
<layer name="active"/>
|
||||
</diffusionlayer>
|
||||
<transistorlayer name="NTRANS" type="UNDEFINED">
|
||||
<layer name="nImplant"/>
|
||||
<layer name="active"/>
|
||||
<layer name="poly"/>
|
||||
</transistorlayer>
|
||||
<transistorlayer name="PTRANS" type="UNDEFINED">
|
||||
<layer name="nWell"/>
|
||||
<layer name="pImplant"/>
|
||||
<layer name="active"/>
|
||||
<layer name="poly"/>
|
||||
</transistorlayer>
|
||||
<regularlayer name="POLY" type="UNDEFINED">
|
||||
<layer name="poly"/>
|
||||
</regularlayer>
|
||||
|
||||
<!-- Symbolic Layers: Routing Layers -->
|
||||
<regularlayer name="METAL1" type="METAL">
|
||||
<layer name="metal1"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="METAL2" type="METAL">
|
||||
<layer name="metal2"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="METAL3" type="METAL">
|
||||
<layer name="metal3"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="METAL4" type="METAL">
|
||||
<layer name="metal4"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="METAL5" type="METAL">
|
||||
<layer name="metal5"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="METAL6" type="METAL">
|
||||
<layer name="metal6"/>
|
||||
</regularlayer>
|
||||
|
||||
<!-- Symbolic Layers: Contacts Layers -->
|
||||
<contactlayer name="CONT_BODY_N" type="VIA">
|
||||
<layer name="nWell"/>
|
||||
<layer name="nImplant"/>
|
||||
<layer name="active"/>
|
||||
<layer name="cut0"/>
|
||||
<layer name="metal1"/>
|
||||
</contactlayer>
|
||||
<contactlayer name="CONT_BODY_P" type="VIA">
|
||||
<layer name="pWell"/>
|
||||
<layer name="pImplant"/>
|
||||
<layer name="active"/>
|
||||
<layer name="cut0"/>
|
||||
<layer name="metal1"/>
|
||||
</contactlayer>
|
||||
<contactlayer name="CONT_DIF_N" type="VIA">
|
||||
<layer name="nImplant"/>
|
||||
<layer name="active"/>
|
||||
<layer name="cut0"/>
|
||||
<layer name="metal1"/>
|
||||
</contactlayer>
|
||||
<contactlayer name="CONT_DIF_P" type="VIA">
|
||||
<layer name="pImplant"/>
|
||||
<layer name="active"/>
|
||||
<layer name="cut0"/>
|
||||
<layer name="metal1"/>
|
||||
</contactlayer>
|
||||
<vialayer name="CONT_POLY" type="VIA">
|
||||
<layer name="poly"/>
|
||||
<layer name="cut0"/>
|
||||
<layer name="metal1"/>
|
||||
</vialayer>
|
||||
<vialayer name="VIA12" type="VIA">
|
||||
<layer name="metal1"/>
|
||||
<layer name="cut1"/>
|
||||
<layer name="metal2"/>
|
||||
</vialayer>
|
||||
<vialayer name="VIA23" type="VIA">
|
||||
<layer name="metal2"/>
|
||||
<layer name="cut2"/>
|
||||
<layer name="metal3"/>
|
||||
</vialayer>
|
||||
<vialayer name="VIA34" type="VIA">
|
||||
<layer name="metal3"/>
|
||||
<layer name="cut3"/>
|
||||
<layer name="metal4"/>
|
||||
</vialayer>
|
||||
<vialayer name="VIA45" type="VIA">
|
||||
<layer name="metal4"/>
|
||||
<layer name="cut4"/>
|
||||
<layer name="metal5"/>
|
||||
</vialayer>
|
||||
<vialayer name="VIA56" type="VIA">
|
||||
<layer name="metal5"/>
|
||||
<layer name="cut5"/>
|
||||
<layer name="metal6"/>
|
||||
</vialayer>
|
||||
|
||||
<!-- Symbolic Layers: Obstacle Layers -->
|
||||
<regularlayer name="BLOCKAGE1" type="UNDEFINED">
|
||||
<layer name="blockage1"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="BLOCKAGE2" type="UNDEFINED">
|
||||
<layer name="blockage2"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="BLOCKAGE3" type="UNDEFINED">
|
||||
<layer name="blockage3"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="BLOCKAGE4" type="UNDEFINED">
|
||||
<layer name="blockage4"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="BLOCKAGE5" type="UNDEFINED">
|
||||
<layer name="blockage5"/>
|
||||
</regularlayer>
|
||||
<regularlayer name="BLOCKAGE6" type="UNDEFINED">
|
||||
<layer name="metal6"/>
|
||||
</regularlayer>
|
||||
|
||||
<!-- Special BasicLayers for Knik/Kite routers -->
|
||||
<!-- *Must be after all others* -->
|
||||
<basiclayer name="gmetalh" material="metal"/>
|
||||
<basiclayer name="gcut" material="cut"/>
|
||||
<basiclayer name="gmetalv" material="metal"/>
|
||||
<vialayer name="gcontact" type="VIA">
|
||||
<layer name="gmetalh"/>
|
||||
<layer name="gcut"/>
|
||||
<layer name="gmetalv"/>
|
||||
</vialayer>
|
||||
|
||||
<symbolic>
|
||||
<precision>2</precision>
|
||||
<gridstep>1.0</gridstep>
|
||||
<rules>
|
||||
<!-- Active Layers -->
|
||||
<rule name="NWELL.nWell.extention.cap" value="0.0"/>
|
||||
<rule name="PWELL.pWell.extention.cap" value="0.0"/>
|
||||
|
||||
<rule name="NTIE.minimum.width" value="3.0"/>
|
||||
<rule name="NTIE.nWell.extention.cap" value="1.5"/>
|
||||
<rule name="NTIE.nWell.extention.width" value="0.5"/>
|
||||
<rule name="NTIE.nImplant.extention.cap" value="1.0"/>
|
||||
<rule name="NTIE.nImplant.extention.width" value="0.5"/>
|
||||
<rule name="NTIE.active.extention.cap" value="0.5"/>
|
||||
<rule name="NTIE.active.extention.width" value="0.0"/>
|
||||
|
||||
<rule name="PTIE.minimum.width" value="3.0"/>
|
||||
<rule name="PTIE.pWell.extention.cap" value="1.5"/>
|
||||
<rule name="PTIE.pWell.extention.width" value="0.5"/>
|
||||
<rule name="PTIE.pImplant.extention.cap" value="1.0"/>
|
||||
<rule name="PTIE.pImplant.extention.width" value="0.5"/>
|
||||
<rule name="PTIE.active.extention.cap" value="0.5"/>
|
||||
<rule name="PTIE.active.extention.width" value="0.0"/>
|
||||
|
||||
<rule name="NDIF.minimum.width" value="3.0"/>
|
||||
<rule name="NDIF.nImplant.extention.cap" value="1.0"/>
|
||||
<rule name="NDIF.nImplant.extention.width" value="0.5"/>
|
||||
<rule name="NDIF.active.extention.cap" value="0.5"/>
|
||||
<rule name="NDIF.active.extention.width" value="0.0"/>
|
||||
|
||||
<rule name="PDIF.minimum.width" value="3.0"/>
|
||||
<rule name="PDIF.pImplant.extention.cap" value="1.0"/>
|
||||
<rule name="PDIF.pImplant.extention.width" value="0.5"/>
|
||||
<rule name="PDIF.active.extention.cap" value="0.5"/>
|
||||
<rule name="PDIF.active.extention.width" value="0.0"/>
|
||||
|
||||
<rule name="GATE.minimum.width" value="1.0"/>
|
||||
<rule name="GATE.poly.extention.cap" value="1.5"/>
|
||||
|
||||
<rule name="NTRANS.minimum.width" value="1.0"/>
|
||||
<rule name="NTRANS.nImplant.extention.cap" value="-1.0"/>
|
||||
<rule name="NTRANS.nImplant.extention.width" value="2.5"/>
|
||||
<rule name="NTRANS.active.extention.cap" value="-1.5"/>
|
||||
<rule name="NTRANS.active.extention.width" value="2.0"/>
|
||||
|
||||
<rule name="PTRANS.minimum.width" value="1.0"/>
|
||||
<rule name="PTRANS.nWell.extention.cap" value="-1.0"/>
|
||||
<rule name="PTRANS.nWell.extention.width" value="4.5"/>
|
||||
<rule name="PTRANS.pImplant.extention.cap" value="-1.0"/>
|
||||
<rule name="PTRANS.pImplant.extention.width" value="4.0"/>
|
||||
<rule name="PTRANS.active.extention.cap" value="-1.5"/>
|
||||
<rule name="PTRANS.active.extention.width" value="3.0"/>
|
||||
|
||||
<rule name="POLY.minimum.width" value="1.0"/>
|
||||
<rule name="POLY.poly.extention.cap" value="0.5"/>
|
||||
|
||||
<!-- Routing Layers -->
|
||||
<rule name="METAL1.minimum.width" value="1.0"/>
|
||||
<rule name="METAL1.metal1.extention.cap" value="0.5"/>
|
||||
<rule name="METAL2.minimum.width" value="1.0"/>
|
||||
<rule name="METAL2.metal2.extention.cap" value="0.5"/>
|
||||
<rule name="METAL3.minimum.width" value="1.0"/>
|
||||
<rule name="METAL3.metal3.extention.cap" value="0.5"/>
|
||||
<rule name="METAL4.minimum.width" value="1.0"/>
|
||||
<rule name="METAL4.metal4.extention.cap" value="0.5"/>
|
||||
<rule name="METAL5.minimum.width" value="2.0"/>
|
||||
<rule name="METAL5.metal5.extention.cap" value="1.0"/>
|
||||
<rule name="METAL6.minimum.width" value="2.0"/>
|
||||
<rule name="METAL6.metal6.extention.cap" value="1.0"/>
|
||||
|
||||
<!-- VIAs -->
|
||||
<rule name="CONT_BODY_N.minimum.side" value="1.0"/>
|
||||
<rule name="CONT_BODY_N.nWell.enclosure" value="1.5"/>
|
||||
<rule name="CONT_BODY_N.nImplant.enclosure" value="1.5"/>
|
||||
<rule name="CONT_BODY_N.active.enclosure" value="1.0"/>
|
||||
<rule name="CONT_BODY_N.metal1.enclosure" value="0.5"/>
|
||||
|
||||
<rule name="CONT_BODY_P.minimum.side" value="1.0"/>
|
||||
<rule name="CONT_BODY_P.pWell.enclosure" value="1.5"/>
|
||||
<rule name="CONT_BODY_P.pImplant.enclosure" value="1.5"/>
|
||||
<rule name="CONT_BODY_P.active.enclosure" value="1.0"/>
|
||||
<rule name="CONT_BODY_P.metal1.enclosure" value="0.5"/>
|
||||
|
||||
<rule name="CONT_DIF_N.minimum.side" value="1.0"/>
|
||||
<rule name="CONT_DIF_N.nImplant.enclosure" value="1.0"/>
|
||||
<rule name="CONT_DIF_N.active.enclosure" value="0.5"/>
|
||||
<rule name="CONT_DIF_N.metal1.enclosure" value="0.5"/>
|
||||
|
||||
<rule name="CONT_DIF_P.minimum.side" value="1.0"/>
|
||||
<rule name="CONT_DIF_P.pImplant.enclosure" value="1.0"/>
|
||||
<rule name="CONT_DIF_P.active.enclosure" value="0.5"/>
|
||||
<rule name="CONT_DIF_P.metal1.enclosure" value="0.5"/>
|
||||
|
||||
<rule name="CONT_POLY.minimum.width" value="1.0"/>
|
||||
<rule name="CONT_POLY.poly.enclosure" value="0.5"/>
|
||||
<rule name="CONT_POLY.metal1.enclosure" value="0.5"/>
|
||||
|
||||
<rule name="VIA12.minimum.side" value="1.0"/>
|
||||
<rule name="VIA12.metal1.enclosure" value="0.5"/>
|
||||
<rule name="VIA12.metal2.enclosure" value="0.5"/>
|
||||
<rule name="VIA23.minimum.side" value="1.0"/>
|
||||
<rule name="VIA23.metal2.enclosure" value="0.5"/>
|
||||
<rule name="VIA23.metal3.enclosure" value="0.5"/>
|
||||
<rule name="VIA34.minimum.side" value="1.0"/>
|
||||
<rule name="VIA34.metal3.enclosure" value="0.5"/>
|
||||
<rule name="VIA34.metal4.enclosure" value="0.5"/>
|
||||
<rule name="VIA45.minimum.side" value="1.0"/>
|
||||
<rule name="VIA45.metal4.enclosure" value="0.5"/>
|
||||
<rule name="VIA45.metal5.enclosure" value="0.5"/>
|
||||
<rule name="VIA56.minimum.side" value="1.0"/>
|
||||
<rule name="VIA56.metal5.enclosure" value="0.5"/>
|
||||
<rule name="VIA56.metal6.enclosure" value="0.5"/>
|
||||
|
||||
<!-- Blockage Layers -->
|
||||
<rule name="BLOCKAGE1.minimum.width" value="1.0"/>
|
||||
<rule name="BLOCKAGE1.blockage1.extention.cap" value="0.5"/>
|
||||
<rule name="BLOCKAGE2.minimum.width" value="2.0"/>
|
||||
<rule name="BLOCKAGE2.blockage2.extention.cap" value="0.5"/>
|
||||
<rule name="BLOCKAGE3.minimum.width" value="2.0"/>
|
||||
<rule name="BLOCKAGE3.blockage3.extention.cap" value="0.5"/>
|
||||
<rule name="BLOCKAGE4.minimum.width" value="2.0"/>
|
||||
<rule name="BLOCKAGE4.blockage4.extention.cap" value="0.5"/>
|
||||
<rule name="BLOCKAGE5.minimum.width" value="2.0"/>
|
||||
<rule name="BLOCKAGE5.blockage5.extention.cap" value="1.0"/>
|
||||
<rule name="BLOCKAGE6.minimum.width" value="2.0"/>
|
||||
<rule name="BLOCKAGE6.blockage6.extention.cap" value="1.0"/>
|
||||
</rules>
|
||||
</symbolic>
|
||||
</technology>
|
|
@ -0,0 +1,4 @@
|
|||
add_subdirectory(fonts)
|
||||
add_subdirectory(ccore)
|
||||
add_subdirectory(cyclop)
|
||||
add_subdirectory(x2y)
|
|
@ -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", "<HomeDirectory>" );
|
||||
_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 ; i<LIBRARIES.getSize() ; i++ ) {
|
||||
Name libraryName = LIBRARIES[i];
|
||||
|
||||
_libraries.push_back ( getAllianceLibrary(libraryName,hasCatalog) );
|
||||
|
||||
cmess2 << " - \"" << libraryName._getString() << "\"";
|
||||
cmess2.flush();
|
||||
|
||||
if ( hasCatalog ) cmess2 << " [have CATAL]." << endl;
|
||||
else cmess2 << " [no CATAL]" << endl;
|
||||
}
|
||||
|
||||
// Temporary: create the SxLib routing gauge.
|
||||
Technology* technology = db->getTechnology();
|
||||
|
||||
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<Name,Catalog::State*>* states = _catalog.getStates ();
|
||||
map<Name,Catalog::State*>::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<const Name,RoutingGauge*>::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<const Name,CellGauge*>::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.
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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.
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <time.h>
|
||||
# include <cstring>
|
||||
# include <cstdlib>
|
||||
|
||||
# include <iomanip>
|
||||
|
||||
# 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<const string,const BannerFont*>()
|
||||
{
|
||||
# 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.
|
|
@ -0,0 +1 @@
|
|||
#cmakedefine CORIOLIS_TOP
|
|
@ -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 <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> 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 <memory.h> 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 <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> 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
|
||||
|
|
@ -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 )
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <sstream>
|
||||
|
||||
# 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 ; i<argc ; i++ ) {
|
||||
arg = argv[i];
|
||||
|
||||
if ( arg.empty() ) continue;
|
||||
if ( arg[0] == '-' ) {
|
||||
( arg[1] == '-' ) ? longOpt = true : longOpt = false;
|
||||
|
||||
equal = arg.find ( '=' );
|
||||
if ( equal < arg.size() ) {
|
||||
if ( longOpt )
|
||||
fragOpts.push_back ( _Frag( arg.substr(2,equal-2), order++) );
|
||||
else {
|
||||
for ( unsigned j=1 ; j<equal ; j++ )
|
||||
fragOpts.push_back ( _Frag( arg.substr(j,1), order++) );
|
||||
}
|
||||
fragArgs.push_back ( _Frag( arg.substr(equal+1), order++) );
|
||||
} else {
|
||||
if ( longOpt )
|
||||
fragOpts.push_back ( _Frag( arg.substr(2), order++) );
|
||||
else {
|
||||
for ( unsigned j=1 ; j<arg.size() ; j++ )
|
||||
fragOpts.push_back ( _Frag( arg.substr(j,1), order++) );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fragArgs.push_back ( _Frag( arg, order++) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Second step : try to match options.
|
||||
_FragVect::iterator itOpt = fragOpts.begin ();
|
||||
_FragVect::iterator endOpt = fragOpts.end ();
|
||||
_FragVect::iterator itArg = fragArgs.begin ();
|
||||
_FragVect::iterator endArg = fragArgs.end ();
|
||||
OptionVect::iterator opt;
|
||||
|
||||
for ( ; itOpt!=endOpt ; itOpt++ ) {
|
||||
opt = Find ( itOpt->_val );
|
||||
|
||||
if ( opt == _options.end() ) throw ( Error(unknownOption(itOpt->_val)) );
|
||||
|
||||
if ( opt->getHasArg() ) {
|
||||
if ( (itArg != endArg ) && ( itArg->_order == itOpt->_order+1 ) )
|
||||
{ opt->AddArg ( itArg->_val ); itArg++; continue; }
|
||||
|
||||
if ( opt->getDefault().size() > 0 )
|
||||
{ opt->AddArg ( opt->getDefault() ); continue; }
|
||||
|
||||
throw ( Error(missingArg(itOpt->_val)) );
|
||||
}
|
||||
|
||||
opt->AddArg ( "__true" );
|
||||
}
|
||||
|
||||
|
||||
// Third step : set default arguments (if not found on
|
||||
// the command line).
|
||||
for ( opt=_options.begin() ; opt!=_options.end() ; opt++ ) {
|
||||
if ( ( opt->getDefault().size() > 0 ) && ( opt->getTimes() == 0 ) )
|
||||
opt->AddArg ( opt->getDefault() );
|
||||
}
|
||||
|
||||
|
||||
// Storing argv[0] (program's name).
|
||||
Find ( _argvzero )->AddArg ( 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() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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 <iomanip>
|
||||
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 ( "<State " + _getString() + " >" );
|
||||
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<Name,State*>::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<Name,State*>::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<Name,State*>::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<Name,State*>::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 ( ; start<s.size() ; start++ ) {
|
||||
switch ( s[start] ) {
|
||||
case 'C': state->setFlattenLeaf ( 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<Name,State*>::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 << "<StateMap " << _states.size() << ">";
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
Record* Catalog::_getRecord () const
|
||||
{
|
||||
map<Name,State*>::const_iterator it;
|
||||
|
||||
Record* record = new Record ( "<Catalog>" );
|
||||
|
||||
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.
|
|
@ -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 <sstream>
|
||||
|
||||
#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.
|
|
@ -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
|
|
@ -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 <cctype>
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <iomanip>
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#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<string,string> _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<string,string>::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 <system>: \""
|
||||
<< 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 = "<unknwown message id>";
|
||||
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 << " <not set or empty>.\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.
|
|
@ -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
|
|
@ -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 <iostream>
|
||||
|
||||
#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<Name,DrawGoFunctions>::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<Name,DrawGoFunctions>::iterator idraw = _drawGoMap.find ( name );
|
||||
if ( idraw != _drawGoMap.end() )
|
||||
return &idraw->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
|
@ -0,0 +1,204 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
# include <cassert>
|
||||
# include <string>
|
||||
|
||||
# include <QXmlStreamReader>
|
||||
|
||||
# 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 = "<unknwown message id>";
|
||||
switch ( id ) {
|
||||
case OpenFile: message = "graphics configuration"; break;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
|
@ -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 <cstdlib>
|
||||
#include <fstream>
|
||||
using namespace std;
|
||||
|
||||
#include "hurricane/Warning.h"
|
||||
using Hurricane::Warning;
|
||||
|
||||
#include "crlcore/Memory.h"
|
||||
|
||||
#if defined(sun) || defined(__SUNPRO_CC)
|
||||
#include <sys/systeminfo.h>
|
||||
#endif
|
||||
|
||||
#ifdef linux
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#if defined(linux) || defined(sun) || defined(__SUNPRO_CC)
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/stat.h>
|
||||
#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<unsigned>(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<int>(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()="<<memused()<<endl;
|
||||
int chunk=8192; // system allocates 8K chunks
|
||||
int allocated=0;
|
||||
int countSmallChunks=kSmallChunks;
|
||||
// if we allocate <8K, we'd get memused()+=8K, and allocated<8K - error
|
||||
while (1)
|
||||
{
|
||||
// abkfatal(numAllocs<kMaxAllocs, "too many allocs");
|
||||
if (numAllocs>=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: "<<memused()<<"; allocating "<<chunk<<"; now: ";
|
||||
if (!(ptr[numAllocs++]=malloc(chunk)))
|
||||
{
|
||||
fail=1;
|
||||
return -1;
|
||||
}
|
||||
// cerr<<memused()<<endl;
|
||||
allocated+=chunk;
|
||||
if (memused()>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
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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<Name,ParserFormatSlot>()
|
||||
{
|
||||
// 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<Name,DriverSlot>()
|
||||
{
|
||||
// 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 );
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,225 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
# include <cassert>
|
||||
# include <string>
|
||||
|
||||
# include <QStringList>
|
||||
# include <QXmlStreamReader>
|
||||
|
||||
# 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 = "<unknwown message id>";
|
||||
switch ( id ) {
|
||||
case OpenFile: message = "S2R Technology configuration"; break;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
|
@ -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 <climits>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#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 ; i<gauge._layerGauges.size() ; i++ )
|
||||
addLayerGauge ( RoutingLayerGauge::create
|
||||
( gauge._layerGauges[i]->getLayer()
|
||||
, 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<RoutingLayerGauge*>& 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.
|
|
@ -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 <sstream>
|
||||
|
||||
#include "hurricane/BasicLayer.h"
|
||||
|
||||
#include "crlcore/RoutingLayerGauge.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Local Variables.
|
||||
|
||||
const char* notBasicLayer =
|
||||
"%s :\n\n"
|
||||
" %s is not a <BasicLayer>.\n";
|
||||
|
||||
const char* notConductingLayer =
|
||||
"%s :\n\n"
|
||||
" %s is not a CONDUCTING <BasicLayer>.\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<BasicLayer*>(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.
|
|
@ -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 = "<File not found>";
|
||||
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 = "<index out of bound>";
|
||||
|
||||
if ( index < _paths.size() ) return _paths[index];
|
||||
return OutOfBound;
|
||||
}
|
||||
|
||||
|
||||
string SearchPath::_getString () const
|
||||
{
|
||||
ostringstream s;
|
||||
|
||||
s << "<SearchPath " << _paths.size()+1 << " directories>";
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
Record *SearchPath::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( "<SearchPath>" );
|
||||
record->add ( getSlot ( "_paths" , &_paths ) );
|
||||
record->add ( getSlot ( "_selected", &_selected ) );
|
||||
record->add ( getSlot ( "_index" , _index ) );
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
|
@ -0,0 +1,581 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include <QStringList>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#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 <basiclayer>.";
|
||||
const QString SymbolicTechnologyParser::UnnamedSymbolicLayerError = "Missing name attribute in <%1>.";
|
||||
const QString SymbolicTechnologyParser::UnnamedLayerError = "Missing name attribute in <layer>.";
|
||||
const QString SymbolicTechnologyParser::InvalidRulePathError = "Invalid rule path \"%1\".";
|
||||
const QString SymbolicTechnologyParser::MissingValueError = "Rule \"%1\" has no <value> 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<const Name,Layer*>::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<const Name,Layer*>::iterator it = _layers.find ( layerName );
|
||||
|
||||
if ( it == _layers.end() ) {
|
||||
if ( !ignoreError )
|
||||
printError ( UndefinedLayerError.arg(name) );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BasicLayer* basicLayer = dynamic_cast<BasicLayer*> ( 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, "<SymbolicTechnologyParser>" );
|
||||
|
||||
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 = "<unknwown message id>";
|
||||
switch ( id ) {
|
||||
case OpenFile: message = "Technology configuration"; break;
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
|
@ -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<ToolEngine*>().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<ToolEnginesRelation*>(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<ToolEngine*>() ) {
|
||||
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<ToolEngine*>();
|
||||
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<ToolEngine*>()) {
|
||||
if (toolengine->getName() == name)
|
||||
return toolengine;
|
||||
end_for;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
|
@ -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 <csignal>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#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 <coriolis-sav@asim.lip6.fr>.\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 << "<IoFile " << _path << ">";
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
Record *IoFile::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( "<IoFile>" );
|
||||
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; }
|
|
@ -0,0 +1,193 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
# include <cassert>
|
||||
# include <string>
|
||||
|
||||
# include <QFile>
|
||||
|
||||
# include <QXmlStreamReader>
|
||||
|
||||
# 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 ( ; entry<tags.size() ; entry++ ) {
|
||||
if ( _reader->name() == 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<QFile*> ( _reader->device() );
|
||||
QString fileName = "<not a file>";
|
||||
if ( file )
|
||||
fileName = file->fileName();
|
||||
|
||||
o << " (line: " << _reader->lineNumber()
|
||||
<< ", file: " << qPrintable(fileName) << ")" << endl;
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
|
@ -0,0 +1,17 @@
|
|||
// author : Damien Dupuis
|
||||
// date : 08.12.2009
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef __AGDS_H__
|
||||
#define __AGDS_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
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
|
|
@ -0,0 +1,111 @@
|
|||
// author : Damien Dupuis
|
||||
// date : 08.12.2009
|
||||
// -*- C++ -*-
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
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<const Pad*>(go)) {
|
||||
const Pad* pad = static_cast<const Pad*>(go);
|
||||
b = pad->getBoundingBox();
|
||||
layer = dynamic_cast<const BasicLayer*>(pad->getLayer());
|
||||
}
|
||||
else if (dynamic_cast<const Contact*>(go)) {
|
||||
const Contact* contact = static_cast<const Contact*>(go);
|
||||
b = contact->getBoundingBox();
|
||||
layer = dynamic_cast<const BasicLayer*>(contact->getLayer());
|
||||
}
|
||||
else if (dynamic_cast<const Segment*>(go)) {
|
||||
const Segment* segment = static_cast<const Segment*>(go);
|
||||
b = segment->getBoundingBox();
|
||||
layer = dynamic_cast<const BasicLayer*>(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
|
|
@ -0,0 +1 @@
|
|||
add_subdirectory(vst)
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <string>
|
||||
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
|
|
@ -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 <time.h>
|
||||
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<const Name,const char*> tableLayer;
|
||||
static map<const Name,const char*> tableContact;
|
||||
static map<const Name,const char*> 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<const Name,const char*>::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<Contact*>(component))
|
||||
{
|
||||
if (dynamic_cast<Pin*>(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<RoutingPad*>(*component)) ) {
|
||||
if ( !net->isExternal() ) continue;
|
||||
|
||||
external = true;
|
||||
segment = dynamic_cast<Segment*>(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<Segment*>(*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<Pin*> PinVector;
|
||||
PinVector pinVector;
|
||||
for_each_pin(pin, net->getPins())
|
||||
{
|
||||
pinVector.push_back(pin);
|
||||
end_for;
|
||||
}
|
||||
sort (pinVector.begin(), pinVector.end(), PinSort());
|
||||
set<unsigned> 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 ();
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdarg>
|
||||
|
||||
#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<const Name,LayerInformation> {
|
||||
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<char*> _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<const Name, LayerInformation>::iterator it = _layerInformations.find ( layerName );
|
||||
if ( it != _layerInformations.end() )
|
||||
return &(it->second);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
vector<char*> ApParser::_splitString ( char* s, char separator )
|
||||
{
|
||||
vector<char*> 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<char*> 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 <Cell %s>: 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<char*> 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<char*> 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<char*> 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<char*> 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<char*> 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<char*> 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<char*> 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.
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <string>
|
||||
|
||||
|
||||
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
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <Christophe.Alexandre@lip6.fr>
|
||||
//
|
||||
// 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<string*> StringPtVector;
|
||||
typedef vector<string> StringVector;
|
||||
typedef map<const string*, Net*> StringNetMap;
|
||||
typedef map<const string*, Plug*> StringPlugMap;
|
||||
typedef set<Net*> NetSet;
|
||||
typedef vector<Plug*> 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<Cell*> ModelSet;
|
||||
ModelSet modelSet;
|
||||
typedef list<Instance*> InstanceList;
|
||||
InstanceList instanceList;
|
||||
for_each_instance(instance, cell->getInstances())
|
||||
{
|
||||
Cell* model = instance->getMasterCell();
|
||||
CatalogProperty *stateProp =
|
||||
static_cast<CatalogProperty*>(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 ();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <string.h>
|
||||
|
||||
# include <iostream>
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
# include "VstParserGrammar.hpp"
|
||||
|
||||
extern int vhdLineNumber;
|
||||
extern void ClearVstIdentifiers ();
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class VHDLKeywords : public map<string,int> {
|
||||
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<string*> {
|
||||
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<string*>::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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <Damien.Dupuis@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
|
||||
// ************************************************************************************
|
||||
// File: BK.h
|
||||
// ************************************************************************************
|
||||
|
||||
|
||||
|
||||
#include <fstream>
|
||||
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
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <Damien.Dupuis@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
|
||||
#include <time.h>
|
||||
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<Horizontal*>(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<Vertical*>(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<Pin*> PinVector;
|
||||
PinVector pinVector;
|
||||
for_each_pin(pin, net->getPins()) {
|
||||
pinVector.push_back(pin);
|
||||
end_for;
|
||||
}
|
||||
sort (pinVector.begin(), pinVector.end(), PinSort());
|
||||
set<unsigned> 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 ();
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
|||
// author : Damien Dupuis
|
||||
// date : 24.02.2010
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef __CIF_H__
|
||||
#define __CIF_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Hurricane {
|
||||
class Cell;
|
||||
}
|
||||
|
||||
namespace CRL {
|
||||
void cifDriver(const std::string& file, Hurricane::Cell*, std::string& name, std::string& units, double& scale );
|
||||
}
|
||||
# endif
|
|
@ -0,0 +1,109 @@
|
|||
// author : Damien Dupuis
|
||||
// date : 24.02.2010
|
||||
// -*- C++ -*-
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
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<const Pad*>(go)) {
|
||||
const Pad* pad = static_cast<const Pad*>(go);
|
||||
b = pad->getBoundingBox();
|
||||
layer = dynamic_cast<const BasicLayer*>(pad->getLayer());
|
||||
}
|
||||
else if (dynamic_cast<const Contact*>(go)) {
|
||||
const Contact* contact = static_cast<const Contact*>(go);
|
||||
b = contact->getBoundingBox();
|
||||
layer = dynamic_cast<const BasicLayer*>(contact->getLayer());
|
||||
}
|
||||
else if (dynamic_cast<const Segment*>(go)) {
|
||||
const Segment* segment = static_cast<const Segment*>(go);
|
||||
b = segment->getBoundingBox();
|
||||
layer = dynamic_cast<const BasicLayer*>(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
|
|
@ -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 <map>
|
||||
|
||||
#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<const Name,RoutingGauge*>
|
||||
_routingGauges;
|
||||
map<const Name,CellGauge*>
|
||||
_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__
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <string>
|
||||
# include <vector>
|
||||
|
||||
# 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<AllianceLibrary*> 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
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <map>
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include <ostream>
|
||||
# include <sstream>
|
||||
|
||||
# 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<const string,const BannerFont*> {
|
||||
public:
|
||||
FontMap ();
|
||||
~FontMap ();
|
||||
const BannerFont* operator[] ( const string& name ) const;
|
||||
};
|
||||
|
||||
// Internal: Types.
|
||||
typedef map<char,BigChar*> 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
|
|
@ -0,0 +1 @@
|
|||
/* #undef CORIOLIS_TOP */
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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 <map>
|
||||
|
||||
# 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<Layer*> LayerTable;
|
||||
typedef map<Layer::Mask,Layer*> MaskLayerMap;
|
||||
typedef map<Layer*,Layer*> 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
|
|
@ -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 <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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<string> _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<Option> OptionVect;
|
||||
|
||||
|
||||
// Constants.
|
||||
public: static const string _true;
|
||||
public: static const string _false;
|
||||
public: static const string _remains;
|
||||
public: static const string _argvzero;
|
||||
public: static const string _missing;
|
||||
|
||||
// Attributes.
|
||||
private: bool _clear;
|
||||
private: bool _argHelp;
|
||||
private: bool _argVerbose;
|
||||
private: bool _argVeryVerbose;
|
||||
private: bool _argCatchCore;
|
||||
private: Option _missingBuiltin;
|
||||
private: OptionVect _options;
|
||||
|
||||
// Constructor.
|
||||
public: COptions ();
|
||||
|
||||
// Private methods.
|
||||
private: OptionVect::iterator Find ( string name );
|
||||
|
||||
// Accessors.
|
||||
public: bool getClear () { return ( _clear ); };
|
||||
public: Option &getHelp ();
|
||||
public: Option &getVerbose ();
|
||||
public: Option &getVeryVerbose ();
|
||||
public: Option &getCatchCore ();
|
||||
|
||||
// Mofifiers.
|
||||
public: void Clear ();
|
||||
public: void Parse ( int argc, char *argv[] );
|
||||
public: void Add ( string nameShort
|
||||
, string nameLong
|
||||
, bool hasArg=false
|
||||
, string defaultArg="" );
|
||||
public: void AddHelp ();
|
||||
public: void AddVerbose ();
|
||||
public: void AddVeryVerbose ();
|
||||
public: void AddCatchCore ();
|
||||
|
||||
// Operators.
|
||||
public: Option &operator[] ( string key );
|
||||
|
||||
// Hurricane managment.
|
||||
public: string _getPrint ();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
|
||||
|
||||
// x-----------------------------------------------------------------x
|
||||
// | Functions Overload for Hurricane Managment |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
inline std::string getPrint ( CRL::COptions &opts ) { return ( opts._getPrint() ); }
|
||||
inline std::ostream& operator<< ( std::ostream &o, CRL::COptions& opts ) { return ( o << getPrint(opts) ); }
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,236 @@
|
|||
|
||||
// -*- 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 : "./Catalog.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#ifndef __CRL_CATALOG_H__
|
||||
#define __CRL_CATALOG_H__
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "hurricane/Name.h"
|
||||
#include "hurricane/Property.h"
|
||||
#include "hurricane/Slot.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class Cell;
|
||||
class Library;
|
||||
}
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using std::string;
|
||||
using std::map;
|
||||
using Hurricane::_TName;
|
||||
using Hurricane::Name;
|
||||
using Hurricane::Record;
|
||||
using Hurricane::PrivateProperty;
|
||||
using Hurricane::DBo;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Library;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::Catalog".
|
||||
|
||||
|
||||
class Catalog {
|
||||
|
||||
public:
|
||||
class State;
|
||||
public:
|
||||
inline Catalog ();
|
||||
~Catalog ();
|
||||
State* getState ( const Name& name, bool add=false );
|
||||
void mergeState ( const Name& name, const State& other );
|
||||
bool deleteState ( const Name& name );
|
||||
void clear ();
|
||||
bool loadFromFile ( const string& path, Library* library );
|
||||
inline map<Name,State*>* getStates ();
|
||||
string _getPrint () const;
|
||||
inline string _getTypeName () const;
|
||||
string _getString () const;
|
||||
Record* _getRecord () const;
|
||||
|
||||
public:
|
||||
// Sub-Class: State.
|
||||
class State {
|
||||
public:
|
||||
// Flags Constants.
|
||||
enum Flags { FlattenLeaf = 1 << 0
|
||||
, Feed = 1 << 1
|
||||
, GDS = 1 << 2
|
||||
, Delete = 1 << 3
|
||||
, Logical = 1 << 4
|
||||
, Physical = 1 << 5
|
||||
, InMemory = 1 << 6
|
||||
, Views = Physical|Logical
|
||||
};
|
||||
// Constructors.
|
||||
inline State ();
|
||||
~State ();
|
||||
// Predicates.
|
||||
inline bool isFlattenLeaf () const;
|
||||
inline bool isFeed () const;
|
||||
inline bool isGds () const;
|
||||
inline bool isDelete () const;
|
||||
inline bool isPhysical () const;
|
||||
inline bool isLogical () const;
|
||||
// Flags management.
|
||||
inline unsigned int getFlags ( unsigned int mask=(unsigned int)-1 ) const;
|
||||
inline bool setFlags ( unsigned int mask, bool value );
|
||||
inline bool setFlattenLeaf ( bool value );
|
||||
inline bool setFeed ( bool value );
|
||||
inline bool setGds ( bool value );
|
||||
inline bool setDelete ( bool value );
|
||||
inline bool setPhysical ( bool value );
|
||||
inline bool setLogical ( bool value );
|
||||
// Accessors.
|
||||
inline Cell* getCell () const;
|
||||
inline Library* getLibrary () const;
|
||||
inline unsigned int getDepth () const;
|
||||
// Modifiers.
|
||||
inline void merge ( const State& other );
|
||||
inline Cell* setCell ( Cell* cell );
|
||||
inline Library* setLibrary ( Library* library );
|
||||
inline void setDepth ( unsigned int depth );
|
||||
// Hurricane Management.
|
||||
inline string _getTypeName () const;
|
||||
inline string _getString () const;
|
||||
inline Record* _getRecord () const;
|
||||
|
||||
private:
|
||||
// Internal - Attributes.
|
||||
unsigned int _flags;
|
||||
unsigned int _depth;
|
||||
Cell* _cell;
|
||||
Library* _library;
|
||||
};
|
||||
|
||||
private:
|
||||
// Attributes.
|
||||
map<Name,State*> _states;
|
||||
|
||||
private:
|
||||
Catalog ( const Catalog& );
|
||||
static bool readLine ( const string& s, string& name, State* state );
|
||||
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::CatalogProperty".
|
||||
|
||||
|
||||
class CatalogProperty : public PrivateProperty {
|
||||
|
||||
public:
|
||||
static Name _name;
|
||||
public:
|
||||
static CatalogProperty* create ( Catalog::State* state );
|
||||
static Name getPropertyName ();
|
||||
virtual Name getName () const;
|
||||
inline Catalog::State* getState () const;
|
||||
inline void setState ( Catalog::State* state );
|
||||
virtual void onReleasedBy ( DBo* owner );
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
|
||||
protected:
|
||||
// Attributes.
|
||||
Catalog::State* _state;
|
||||
|
||||
protected:
|
||||
// Constructor.
|
||||
inline CatalogProperty ( Catalog::State* state );
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Error Strings.
|
||||
|
||||
extern const char* MissingStateProperty;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Inline Functions.
|
||||
|
||||
inline Catalog::State::State () : _flags(0), _depth(1), _cell(NULL), _library(NULL) { }
|
||||
inline bool Catalog::State::isFlattenLeaf () const { return (_flags&FlattenLeaf)?1:0; }
|
||||
inline bool Catalog::State::isFeed () const { return (_flags&Feed )?1:0; }
|
||||
inline bool Catalog::State::isGds () const { return (_flags&GDS )?1:0; }
|
||||
inline bool Catalog::State::isDelete () const { return (_flags&Delete )?1:0; }
|
||||
inline bool Catalog::State::isPhysical () const { return (_flags&Physical )?1:0; }
|
||||
inline bool Catalog::State::isLogical () const { return (_flags&Logical )?1:0; }
|
||||
inline unsigned int Catalog::State::getFlags ( unsigned int mask ) const { return ( _flags & mask ); }
|
||||
inline bool Catalog::State::setFlags ( unsigned int mask, bool value ) {
|
||||
switch ( value ) {
|
||||
case true: _flags |= mask; break;
|
||||
case false: _flags &= ~mask; break;
|
||||
}
|
||||
return ( (_flags&mask) ? true : false );
|
||||
}
|
||||
inline bool Catalog::State::setFlattenLeaf ( bool value ) { return setFlags(FlattenLeaf,value); }
|
||||
inline bool Catalog::State::setFeed ( bool value ) { return setFlags(Feed ,value); }
|
||||
inline bool Catalog::State::setGds ( bool value ) { return setFlags(GDS ,value); }
|
||||
inline bool Catalog::State::setDelete ( bool value ) { return setFlags(Delete ,value); }
|
||||
inline bool Catalog::State::setPhysical ( bool value ) { return setFlags(Physical ,value); }
|
||||
inline bool Catalog::State::setLogical ( bool value ) { return setFlags(Logical ,value); }
|
||||
inline Cell* Catalog::State::setCell ( Cell* cell ) { return _cell = cell; }
|
||||
inline Library* Catalog::State::setLibrary ( Library* library ) { return _library = library; }
|
||||
inline void Catalog::State::setDepth ( unsigned int depth ) { _depth = depth; }
|
||||
inline Cell* Catalog::State::getCell () const { return _cell; }
|
||||
inline Library* Catalog::State::getLibrary () const { return _library; }
|
||||
inline unsigned int Catalog::State::getDepth () const { return _depth; }
|
||||
inline string Catalog::State::_getTypeName () const { return _TName("Catalog::State"); }
|
||||
|
||||
inline Catalog::Catalog () : _states() {}
|
||||
inline map<Name,Catalog::State*>*
|
||||
Catalog::getStates () { return &_states; }
|
||||
inline string Catalog::_getTypeName () const { return _TName("Catalog"); }
|
||||
|
||||
inline CatalogProperty::CatalogProperty ( Catalog::State* state ) : PrivateProperty(), _state(state) {}
|
||||
inline Catalog::State* CatalogProperty::getState () const { return _state; }
|
||||
inline void CatalogProperty::setState ( Catalog::State* state ) { _state = state; }
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
|
||||
|
||||
// x-----------------------------------------------------------------x
|
||||
// | Functions Overload for Hurricane Management |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
inline std::string getPrint ( const CRL::Catalog &CATAL ) { return CATAL._getPrint(); }
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
// -*- 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.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef __CRL_CELL_GAUGE_H__
|
||||
#define __CRL_CELL_GAUGE_H__
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "hurricane/Commons.h"
|
||||
#include "hurricane/DbU.h"
|
||||
#include "hurricane/Name.h"
|
||||
|
||||
#include "crlcore/Utilities.h"
|
||||
#include "crlcore/XmlParser.h"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using std::string;
|
||||
using std::map;
|
||||
|
||||
using Hurricane::Record;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Name;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::CellGauge".
|
||||
|
||||
|
||||
class CellGauge {
|
||||
|
||||
public:
|
||||
// Constructors & Destructor.
|
||||
static CellGauge* create ( const char* name
|
||||
, const char* pinLayerName
|
||||
, const DbU::Unit pitch=0
|
||||
, const DbU::Unit sliceHeight=0
|
||||
, const DbU::Unit sliceStep=0 );
|
||||
virtual void destroy ();
|
||||
// Accessors
|
||||
inline const Name& getName () const;
|
||||
inline const Name& getPinLayerName () const;
|
||||
inline const DbU::Unit getPitch () const;
|
||||
inline const DbU::Unit getSliceHeight () const;
|
||||
inline const DbU::Unit getSliceStep () const;
|
||||
// Hurricane management.
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
|
||||
protected:
|
||||
// Internal: Attributes.
|
||||
Name _name;
|
||||
Name _pinLayerName;
|
||||
DbU::Unit _pitch;
|
||||
DbU::Unit _sliceHeight;
|
||||
DbU::Unit _sliceStep;
|
||||
|
||||
protected:
|
||||
// Internal: Constructors & Destructors.
|
||||
CellGauge ( const char* name
|
||||
, const char* pinLayerName
|
||||
, const DbU::Unit pitch
|
||||
, const DbU::Unit sliceHeight
|
||||
, const DbU::Unit sliceStep );
|
||||
protected:
|
||||
virtual ~CellGauge ();
|
||||
private:
|
||||
CellGauge ( const CellGauge& );
|
||||
CellGauge& operator= ( const CellGauge& );
|
||||
};
|
||||
|
||||
|
||||
// New Types.
|
||||
typedef map<Name,CellGauge*> CellGaugeMap;
|
||||
|
||||
|
||||
// Inline Functions.
|
||||
inline const Name& CellGauge::getName () const { return _name; }
|
||||
inline const Name& CellGauge::getPinLayerName () const { return _pinLayerName; }
|
||||
inline const DbU::Unit CellGauge::getPitch () const { return _pitch; }
|
||||
inline const DbU::Unit CellGauge::getSliceHeight () const { return _sliceHeight; }
|
||||
inline const DbU::Unit CellGauge::getSliceStep () const { return _sliceStep; }
|
||||
|
||||
|
||||
} // End of namespace CRL.
|
||||
|
||||
|
||||
#endif // __CRL_CELL_GAUGE_H__
|
|
@ -0,0 +1,140 @@
|
|||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
//
|
||||
// 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 : 15/05/2007
|
||||
// Author : Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
#ifndef CRL_CCELLPATH_H
|
||||
#define CRL_CCELLPATH_H
|
||||
|
||||
#include "hurricane/Net.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
#include "TimingEvent.h"
|
||||
# include "hurricane/Slot.h"
|
||||
|
||||
namespace CRL {
|
||||
|
||||
class CLuTable;
|
||||
class CLuTableTemplate;
|
||||
|
||||
class CCellPath : public DBo {
|
||||
|
||||
// Types
|
||||
// *****
|
||||
|
||||
public: typedef DBo Inherit;
|
||||
|
||||
public: class Type {
|
||||
// ***************
|
||||
|
||||
public: enum Code {UNDEFINED=0, POSITIVE_UNATE=1, NEGATIVE_UNATE=2, LATCH_ACCESS=3, LATCH_SETUP=4, LATCH_HOLD=5};
|
||||
|
||||
private: Code _code;
|
||||
|
||||
public: Type(const Code& code = UNDEFINED);
|
||||
public: Type(const Type& type);
|
||||
|
||||
public: Type& operator=(const Type& type);
|
||||
|
||||
public: operator const Code&() const {return _code;};
|
||||
|
||||
public: const Code& getCode() const {return _code;};
|
||||
|
||||
public: string _getTypeName() const { return _TName("CRL::CCellPath::Type"); };
|
||||
public: string _getString() const;
|
||||
public: Record* _getRecord() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Attributes
|
||||
// **********
|
||||
|
||||
private: Net* _net;
|
||||
private: Net* _relatedNet;
|
||||
|
||||
private: Type _type;
|
||||
|
||||
private: CLuTable* _riseDelay;
|
||||
private: CLuTable* _fallDelay;
|
||||
|
||||
private: CLuTable* _riseTransition;
|
||||
private: CLuTable* _fallTransition;
|
||||
|
||||
// Constructor
|
||||
// ***********
|
||||
|
||||
protected: CCellPath (Net* target);
|
||||
|
||||
public: static CCellPath* create(Net* target);
|
||||
|
||||
// Accessors
|
||||
// *********
|
||||
|
||||
public: Net* getNet() const { return _net; }
|
||||
public: Net* getRelatedNet() const { return _relatedNet; }
|
||||
public: Type getType() const { return _type; }
|
||||
|
||||
public: CLuTable* getRiseDelayTable() const { return _riseDelay; }
|
||||
public: CLuTable* getFallDelayTable() const { return _fallDelay; }
|
||||
public: CLuTable* getDelayTable(CTimingEvent event) const;
|
||||
|
||||
public: CLuTable* getRiseTransitionTable() const { return _riseTransition; }
|
||||
public: CLuTable* getFallTransitionTable() const { return _fallTransition; }
|
||||
public: CLuTable* getTransitionTable(CTimingEvent event) const;
|
||||
|
||||
|
||||
// Updators
|
||||
// ********
|
||||
|
||||
public: void _setRelatedNet(Net* relatedNet) { _relatedNet=relatedNet; }
|
||||
public: void _setType(Type type) { _type=type; }
|
||||
|
||||
public: CLuTable* _createRiseDelayTable(CLuTableTemplate* luTemplate);
|
||||
public: CLuTable* _createFallDelayTable(CLuTableTemplate* luTemplate);
|
||||
|
||||
public: CLuTable* _createRiseTransitionTable(CLuTableTemplate* luTemplate);
|
||||
public: CLuTable* _createFallTransitionTable(CLuTableTemplate* luTemplate);
|
||||
|
||||
// Others
|
||||
// ******
|
||||
|
||||
public: string _getString() const;
|
||||
public: virtual string _getTypeName() const {return _TName("CCellPath");};
|
||||
public: virtual Record* _getRecord() const;
|
||||
|
||||
protected: virtual void _postCreate();
|
||||
};
|
||||
|
||||
|
||||
} //namespace CRL
|
||||
|
||||
|
||||
#endif // CRL_CCELLPATH_H
|
|
@ -0,0 +1,84 @@
|
|||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
//
|
||||
// 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 : 15/05/2007
|
||||
// Author : Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
#ifndef CRL_CCELLPATHS_H
|
||||
#define CRL_CCELLPATHS_H
|
||||
|
||||
#include "hurricane/Collection.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
namespace CRL {
|
||||
|
||||
class CCellPath;
|
||||
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
// CCellPaths declaration
|
||||
// ****************************************************************************************************
|
||||
|
||||
typedef GenericCollection<CCellPath*> CCellPaths;
|
||||
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
// CCellPathLocator declaration
|
||||
// ****************************************************************************************************
|
||||
|
||||
typedef GenericLocator<CCellPath*> CCellPathLocator;
|
||||
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
// CCellPathFilter declaration
|
||||
// ****************************************************************************************************
|
||||
|
||||
typedef GenericFilter<CCellPath*> CCellPathFilter;
|
||||
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
// for_each_ccellpath declaration
|
||||
// ****************************************************************************************************
|
||||
|
||||
#define for_each_ccellpath(ccellpath, ccellpaths)\
|
||||
/************************************************/\
|
||||
{\
|
||||
CCellPathLocator _locator = ccellpaths.getLocator();\
|
||||
while (_locator.isValid()) {\
|
||||
CCellPath* ccellpath = _locator.getElement();\
|
||||
_locator.progress();
|
||||
|
||||
} //namespace CRL
|
||||
|
||||
|
||||
#endif // CRL_CCELLPATHS_H
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
// author : Damien Dupuis
|
||||
// date : 24.02.2010
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef __CIF_DRIVER_H__
|
||||
#define __CIF_DRIVER_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Hurricane {
|
||||
class Cell;
|
||||
}
|
||||
|
||||
namespace CRL {
|
||||
|
||||
class CifDriver {
|
||||
public:
|
||||
CifDriver(Cell*);
|
||||
|
||||
bool save(const std::string&);
|
||||
|
||||
inline std::string getName();
|
||||
inline std::string getUnits();
|
||||
inline double getScale();
|
||||
|
||||
private:
|
||||
Hurricane::Cell* _cell;
|
||||
std::string _name;
|
||||
std::string _units;
|
||||
double _scale;
|
||||
};
|
||||
|
||||
inline std::string CifDriver::getName() { return _name; };
|
||||
inline std::string CifDriver::getUnits() { return _units; };
|
||||
inline double CifDriver::getScale() { return _scale; };
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
# endif
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
#ifndef __CRL_ENVIRONMENT__
|
||||
#define __CRL_ENVIRONMENT__
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <crlcore/SearchPath.h>
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
class Environment {
|
||||
|
||||
public:
|
||||
// Internal: Static Methods.
|
||||
static const char* getEnv ( const char* variable, const char* defaultValue );
|
||||
// Constructors & destructors.
|
||||
Environment ();
|
||||
~Environment ();
|
||||
|
||||
// Accessors.
|
||||
inline const string& getCORIOLIS_TOP () const;
|
||||
inline const string& getDisplayStyle () const;
|
||||
inline long getSCALE_X () const;
|
||||
inline const string& getSYMBOLIC_TECHNOLOGY () const;
|
||||
inline const string& getREAL_TECHNOLOGY () const;
|
||||
inline const string& getLEF_TECHNOLOGY () const;
|
||||
inline const string& getDISPLAY () const;
|
||||
inline const string& getIN_LO () const;
|
||||
inline const string& getIN_PH () const;
|
||||
inline const string& getOUT_LO () const;
|
||||
inline const string& getOUT_PH () const;
|
||||
inline const string& getPOWER () const;
|
||||
inline const string& getGROUND () const;
|
||||
inline const string& getCLOCK () const;
|
||||
inline const string& getOBSTACLE () const;
|
||||
inline const string& getCATALOG () const;
|
||||
inline SearchPath& getLIBRARIES ();
|
||||
|
||||
// Predicates.
|
||||
bool isPOWER ( const char* name ) const;
|
||||
bool isGROUND ( const char* name ) const;
|
||||
bool isCLOCK ( const char* name ) const;
|
||||
bool isOBSTACLE ( const char* name ) const;
|
||||
|
||||
// Modifiers.
|
||||
void loadFromXml ( const string& path="", bool warnNotFound=true );
|
||||
void loadFromShell ();
|
||||
inline void setDisplayStyle ( const char* );
|
||||
inline void setSCALE_X ( long value );
|
||||
inline void setSYMBOLIC_TECHNOLOGY ( const char* value );
|
||||
inline void setREAL_TECHNOLOGY ( const char* value );
|
||||
inline void setLEF_TECHNOLOGY ( const char* value );
|
||||
inline void setDISPLAY ( const char* value );
|
||||
inline void setIN_LO ( const char* value );
|
||||
inline void setIN_PH ( const char* value );
|
||||
inline void setOUT_LO ( const char* value );
|
||||
inline void setOUT_PH ( const char* value );
|
||||
void setPOWER ( const char* value );
|
||||
void setGROUND ( const char* value );
|
||||
void setCLOCK ( const char* value );
|
||||
void setOBSTACLE ( const char* value );
|
||||
inline void setCATALOG ( const char* value );
|
||||
inline void setWORKING_LIBRARY ( const char* value );
|
||||
inline void addSYSTEM_LIBRARY ( const char* value );
|
||||
|
||||
// Methods.
|
||||
string getPrint () const;
|
||||
|
||||
protected:
|
||||
// Internal: Attributes.
|
||||
string _CORIOLIS_TOP;
|
||||
string _displayStyle;
|
||||
long _SCALE_X;
|
||||
string _SYMBOLIC_TECHNOLOGY;
|
||||
string _LEF_TECHNOLOGY;
|
||||
string _REAL_TECHNOLOGY;
|
||||
string _DISPLAY;
|
||||
string _IN_LO;
|
||||
string _IN_PH;
|
||||
string _OUT_LO;
|
||||
string _OUT_PH;
|
||||
string _POWER;
|
||||
string _GROUND;
|
||||
string _CLOCK;
|
||||
string _OBSTACLE;
|
||||
string _CATALOG;
|
||||
SearchPath _LIBRARIES;
|
||||
regex_t _PowerRegex;
|
||||
regex_t _GroundRegex;
|
||||
regex_t _ClockRegex;
|
||||
regex_t _ObstacleRegex;
|
||||
bool _inConstructor;
|
||||
|
||||
// Internal: Modifiers.
|
||||
void setRegex ( regex_t* regex, const string& pattern, const char* name );
|
||||
void check () const;
|
||||
};
|
||||
|
||||
|
||||
// Inline Member Functions.
|
||||
inline const string& Environment::getCORIOLIS_TOP () const { return _CORIOLIS_TOP; }
|
||||
inline const string& Environment::getDisplayStyle () const { return _displayStyle; }
|
||||
inline long Environment::getSCALE_X () const { return _SCALE_X; }
|
||||
inline const string& Environment::getSYMBOLIC_TECHNOLOGY () const { return _SYMBOLIC_TECHNOLOGY; }
|
||||
inline const string& Environment::getREAL_TECHNOLOGY () const { return _REAL_TECHNOLOGY; }
|
||||
inline const string& Environment::getLEF_TECHNOLOGY () const { return _LEF_TECHNOLOGY; }
|
||||
inline const string& Environment::getDISPLAY () const { return _DISPLAY; }
|
||||
inline const string& Environment::getIN_LO () const { return _IN_LO; }
|
||||
inline const string& Environment::getIN_PH () const { return _IN_PH; }
|
||||
inline const string& Environment::getOUT_LO () const { return _OUT_LO; }
|
||||
inline const string& Environment::getOUT_PH () const { return _OUT_PH; }
|
||||
inline const string& Environment::getPOWER () const { return _POWER; }
|
||||
inline const string& Environment::getGROUND () const { return _GROUND; }
|
||||
inline const string& Environment::getCLOCK () const { return _CLOCK; }
|
||||
inline const string& Environment::getOBSTACLE () const { return _OBSTACLE; }
|
||||
inline const string& Environment::getCATALOG () const { return _CATALOG; }
|
||||
inline SearchPath& Environment::getLIBRARIES () { return _LIBRARIES; }
|
||||
|
||||
inline void Environment::setDisplayStyle ( const char* value ) { _displayStyle = value; }
|
||||
inline void Environment::setSCALE_X ( long value ) { _SCALE_X = value; }
|
||||
inline void Environment::setSYMBOLIC_TECHNOLOGY ( const char* value ) { _SYMBOLIC_TECHNOLOGY = value; }
|
||||
inline void Environment::setREAL_TECHNOLOGY ( const char* value ) { _REAL_TECHNOLOGY = value; }
|
||||
inline void Environment::setLEF_TECHNOLOGY ( const char* value ) { _LEF_TECHNOLOGY = value; }
|
||||
inline void Environment::setDISPLAY ( const char* value ) { _DISPLAY = value; }
|
||||
inline void Environment::setIN_LO ( const char* value ) { _IN_LO = value; }
|
||||
inline void Environment::setIN_PH ( const char* value ) { _IN_PH = value; }
|
||||
inline void Environment::setOUT_LO ( const char* value ) { _OUT_LO = value; }
|
||||
inline void Environment::setOUT_PH ( const char* value ) { _OUT_PH = value; }
|
||||
inline void Environment::setCATALOG ( const char* value ) { _CATALOG = value; }
|
||||
inline void Environment::setWORKING_LIBRARY ( const char* value ) { _LIBRARIES.replace(value,0); }
|
||||
inline void Environment::addSYSTEM_LIBRARY ( const char* value ) { _LIBRARIES.append(value); }
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
# endif
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
// author : Damien Dupuis
|
||||
// date : 08.12.2009
|
||||
// -*- C++ -*-
|
||||
|
||||
#ifndef __GDS_DRIVER_H__
|
||||
#define __GDS_DRIVER_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Hurricane {
|
||||
class Cell;
|
||||
}
|
||||
|
||||
namespace CRL {
|
||||
class GdsDriver {
|
||||
public:
|
||||
GdsDriver(Hurricane::Cell*);
|
||||
|
||||
bool save(const std::string& filePath);
|
||||
inline std::string getName();
|
||||
inline std::string getLib();
|
||||
inline double getUUnits();
|
||||
inline double getPUnits();
|
||||
|
||||
private:
|
||||
Hurricane::Cell* _cell;
|
||||
std::string _name;
|
||||
std::string _lib;
|
||||
double _uUnits;
|
||||
double _pUnits;
|
||||
};
|
||||
|
||||
inline std::string GdsDriver::getName() { return _name; };
|
||||
inline std::string GdsDriver::getLib() { return _lib; };
|
||||
inline double GdsDriver::getUUnits() { return _uUnits; };
|
||||
inline double GdsDriver::getPUnits() { return _pUnits; };
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
# endif
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
|
||||
// -*- 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++ Header : "./GraphicTool.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
#ifndef __CRL_GRAPHIC_TOOL__
|
||||
#define __CRL_GRAPHIC_TOOL__
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <QObject>
|
||||
|
||||
class QMenu;
|
||||
|
||||
#include "hurricane/viewer/CellWidget.h"
|
||||
|
||||
|
||||
namespace Hurricane {
|
||||
class Name;
|
||||
class Cell;
|
||||
class CellViewer;
|
||||
}
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using std::string;
|
||||
using std::map;
|
||||
using Hurricane::Name;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::CellWidget;
|
||||
using Hurricane::CellViewer;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::GraphicTool".
|
||||
|
||||
|
||||
class GraphicTool : public QObject {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
class DrawGoFunctions {
|
||||
private:
|
||||
CellWidget::InitExtensionGo_t* _init;
|
||||
CellWidget::DrawExtensionGo_t* _draw;
|
||||
public:
|
||||
inline DrawGoFunctions ( CellWidget::InitExtensionGo_t*
|
||||
, CellWidget::DrawExtensionGo_t*
|
||||
);
|
||||
inline CellWidget::DrawExtensionGo_t* getDraw () const;
|
||||
inline CellWidget::InitExtensionGo_t* getInit () const;
|
||||
};
|
||||
public:
|
||||
typedef map<Name,DrawGoFunctions> DrawGoMap;
|
||||
|
||||
public:
|
||||
void addDrawGo ( const Name&
|
||||
, CellWidget::InitExtensionGo_t*
|
||||
, CellWidget::DrawExtensionGo_t*
|
||||
);
|
||||
DrawGoFunctions* getDrawGo ( const Name& );
|
||||
inline const DrawGoMap& getDrawGos () const;
|
||||
virtual void addToMenu ( CellViewer* ) = 0;
|
||||
virtual const Name& getName () const = 0;
|
||||
virtual size_t release () = 0;
|
||||
signals:
|
||||
void cellPreModificated ();
|
||||
void cellPostModificated ();
|
||||
|
||||
protected:
|
||||
map<Name,DrawGoFunctions> _drawGoMap;
|
||||
|
||||
protected:
|
||||
GraphicTool ();
|
||||
virtual ~GraphicTool ();
|
||||
};
|
||||
|
||||
|
||||
// Inline Functions.
|
||||
inline GraphicTool::DrawGoFunctions::DrawGoFunctions ( CellWidget::InitExtensionGo_t* init
|
||||
, CellWidget::DrawExtensionGo_t* draw
|
||||
)
|
||||
: _init(init)
|
||||
, _draw(draw)
|
||||
{ }
|
||||
|
||||
inline CellWidget::DrawExtensionGo_t* GraphicTool::DrawGoFunctions::getDraw () const
|
||||
{ return _draw; }
|
||||
|
||||
inline CellWidget::InitExtensionGo_t* GraphicTool::DrawGoFunctions::getInit () const
|
||||
{ return _init; }
|
||||
|
||||
inline const GraphicTool::DrawGoMap& GraphicTool::getDrawGos () const
|
||||
{ return _drawGoMap; }
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
#endif // __CRL_GRAPHIC_TOOL__
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
# ifndef __CRL_GRAPHICS_PARSER_H__
|
||||
# define __CRL_GRAPHICS_PARSER_H__
|
||||
|
||||
|
||||
# include "hurricane/Name.h"
|
||||
# include "crlcore/XmlParser.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class DisplayStyle;
|
||||
}
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using Hurricane::Name;
|
||||
using Hurricane::DisplayStyle;
|
||||
|
||||
|
||||
class GraphicsParser : public XmlParser {
|
||||
|
||||
// Methods.
|
||||
public:
|
||||
static GraphicsParser* create ( QXmlStreamReader* reader );
|
||||
static bool load ( const string& path );
|
||||
inline DisplayStyle* getDefaultDisplayStyle () const;
|
||||
|
||||
// Internal - enum.
|
||||
protected:
|
||||
enum TagSet { TagsGraphics = 2
|
||||
, TagsDisplayStyles = 3
|
||||
, TagsDisplayStyle = 4
|
||||
, TagsDrawingGroup = 5
|
||||
};
|
||||
|
||||
// Internal - Attributes.
|
||||
DisplayStyle* _displayStyle;
|
||||
DisplayStyle* _defaultDisplayStyle;
|
||||
Name _drawingGroupName;
|
||||
|
||||
// Internal - Constructors.
|
||||
GraphicsParser ( QXmlStreamReader* reader=NULL );
|
||||
GraphicsParser ( const GraphicsParser& );
|
||||
GraphicsParser& operator= ( const GraphicsParser& );
|
||||
|
||||
// Internal - Methods.
|
||||
void parseDefault ();
|
||||
void parseDescription ();
|
||||
void parseDarkening ();
|
||||
void parseInherit ();
|
||||
void parseDrawingStyle ();
|
||||
void parseDrawingGroup ();
|
||||
void parseDisplayStyle ();
|
||||
void parseDisplayStyles ();
|
||||
void parseGraphics ();
|
||||
virtual void _postLoad ();
|
||||
virtual const char* _getMessage ( MessageId id );
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline DisplayStyle* GraphicsParser::getDefaultDisplayStyle () const
|
||||
{ return _defaultDisplayStyle; }
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
# endif
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
// -*- 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 : "./Hierarchy.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#ifndef __CRL_HIERARCHY__
|
||||
#define __CRL_HIERARCHY__
|
||||
|
||||
#include "hurricane/Occurrences.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class Cell;
|
||||
}
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Occurrences;
|
||||
|
||||
|
||||
Occurrences getAllUniqueCellOccurrencesFrom ( Cell* cell );
|
||||
|
||||
void createRoutingPadsRing ( Cell* cell );
|
||||
void createRoutingPadsAndPinsRing ( Cell* cell );
|
||||
void createPlacedRoutingPadsAndPinsRing ( Cell* cell );
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
#endif // __CRL_HIERARCHY__
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __CRL_IOC_H
|
||||
#define __CRL_IOC_H
|
||||
|
||||
#include "hurricane/Cell.h"
|
||||
|
||||
using Hurricane::Cell;
|
||||
|
||||
extern void IocParser(Cell* cell, const char* file);
|
||||
|
||||
#endif /* __CIOC_H */
|
|
@ -0,0 +1,97 @@
|
|||
|
||||
// -*- 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++ Header : "./LefDefExtension.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#ifndef __LEFDEF_EXTENSION__
|
||||
#define __LEFDEF_EXTENSION__
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "hurricane/Box.h"
|
||||
#include "hurricane/Property.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class Cell;
|
||||
}
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using std::list;
|
||||
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Name;
|
||||
using Hurricane::StandardPrivateProperty;
|
||||
using Hurricane::Cell;
|
||||
|
||||
|
||||
typedef list<Name> PinIocOrder;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::LefDefExtensionDatas".
|
||||
|
||||
|
||||
class LefDefExtensionDatas {
|
||||
public:
|
||||
LefDefExtensionDatas ();
|
||||
public:
|
||||
unsigned int _lefDbuPerMicron;
|
||||
unsigned int _defDbuPerMicron;
|
||||
Box _rowsBox;
|
||||
PinIocOrder _northOrder;
|
||||
PinIocOrder _southOrder;
|
||||
PinIocOrder _eastOrder;
|
||||
PinIocOrder _westOrder;
|
||||
PinIocOrder _undefined;
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::LefDefExtension".
|
||||
|
||||
|
||||
class LefDefExtension {
|
||||
public:
|
||||
typedef StandardPrivateProperty<LefDefExtensionDatas> Extension;
|
||||
public:
|
||||
static Box getRowsBox ( const Cell* );
|
||||
static unsigned int getLefDbuPerMicron ( const Cell* );
|
||||
static unsigned int getDefDbuPerMicron ( const Cell* );
|
||||
static const Box& addRowsBox ( Cell*, Box );
|
||||
static void setLefDbuPerMicron ( Cell*, unsigned int );
|
||||
static void setDefDbuPerMicron ( Cell*, unsigned int );
|
||||
static PinIocOrder& getNorthPinIocOrder ( Cell*, bool create=false );
|
||||
static PinIocOrder& getSouthPinIocOrder ( Cell*, bool create=false );
|
||||
static PinIocOrder& getEastPinIocOrder ( Cell*, bool create=false );
|
||||
static PinIocOrder& getWestPinIocOrder ( Cell*, bool create=false );
|
||||
static PinIocOrder& getUndefinedPinIoc ( Cell*, bool create=false );
|
||||
};
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
#endif // __LEFDEF_EXTENSION__
|
|
@ -0,0 +1,88 @@
|
|||
/**************************************************************************
|
||||
***
|
||||
*** 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.
|
||||
***
|
||||
***
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
//! author="Igor Markov, June 15, 1997"
|
||||
// freely inspired from infolines.h from UCLApack.
|
||||
|
||||
|
||||
# ifndef __CRL_MEMORY_H__
|
||||
# define __CRL_MEMORY_H__
|
||||
|
||||
# include <iostream>
|
||||
|
||||
using std::ostream;
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::MemUsage".
|
||||
//
|
||||
// Prints information about the memory usage of the process in Mbytes.
|
||||
|
||||
|
||||
class MemUsage {
|
||||
public:
|
||||
MemUsage ();
|
||||
inline double getPeakMem () const { return _peak; }
|
||||
inline double getEstimate () const { return _estimate; }
|
||||
inline operator double () const { return _estimate; };
|
||||
protected:
|
||||
double _peak;
|
||||
double _estimate;
|
||||
};
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream&, const MemUsage&);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::MemUsage".
|
||||
|
||||
|
||||
class MemChange {
|
||||
public:
|
||||
MemChange ();
|
||||
void resetMark (); // does the same as ctor.
|
||||
operator double () const; // returns the change wrt the stored value.
|
||||
protected:
|
||||
double _memUsageMark; // in Mbytes.
|
||||
};
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
# endif // __CRL_MEMORY_H__
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
// -*- 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++ Header : "./NetExtension.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#ifndef __NET_EXTENSION__
|
||||
#define __NET_EXTENSION__
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "hurricane/Property.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class Net;
|
||||
class Cell;
|
||||
}
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using std::set;
|
||||
|
||||
using Hurricane::Name;
|
||||
using Hurricane::StandardPrivateProperty;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Net;
|
||||
|
||||
|
||||
typedef set<Name> PortSet;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::NetExtensionDatas".
|
||||
|
||||
|
||||
class NetExtensionDatas {
|
||||
public:
|
||||
NetExtensionDatas ();
|
||||
public:
|
||||
PortSet _ports;
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::NetExtension".
|
||||
|
||||
|
||||
class NetExtension {
|
||||
public:
|
||||
typedef StandardPrivateProperty<NetExtensionDatas> Extension;
|
||||
public:
|
||||
static void addPort ( Net* , const Name& );
|
||||
static const Name& getPort ( const Net* );
|
||||
static const PortSet* getPorts ( const Net* );
|
||||
static const Net* getNetByPort ( const Cell* , const Name& );
|
||||
protected:
|
||||
static Extension* _getOrCreate ( Net* );
|
||||
};
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
#endif // __NET_EXTENSION__
|
|
@ -0,0 +1,226 @@
|
|||
|
||||
// -*- 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 : "./ParsersDrivers.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
# ifndef __CRL_PARSERS_DRIVERS_H__
|
||||
# define __CRL_PARSERS_DRIVERS_H__
|
||||
|
||||
|
||||
# include <string>
|
||||
# include <map>
|
||||
|
||||
# include "hurricane/Name.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class Library;
|
||||
class Cell;
|
||||
}
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using Hurricane::Name;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Library;
|
||||
|
||||
|
||||
class Environment;
|
||||
class Catalog;
|
||||
class ParsersMap;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Typedefs.
|
||||
|
||||
typedef void ( LibraryParser_t )( const string& , Library*, Catalog& );
|
||||
typedef void ( CellParser_t )( const string& , Cell* );
|
||||
typedef void ( LibraryDriver_t )( const string& , Library *, Catalog& );
|
||||
typedef void ( CellDriver_t )( const string& , Cell*, unsigned int& );
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Struct : "CRL::ParserSlot".
|
||||
|
||||
struct ParserSlot {
|
||||
Name _tag;
|
||||
Name _ext;
|
||||
void* _parser;
|
||||
|
||||
ParserSlot ( const string& t, const string& e, void* p ): _tag(t),_ext(e),_parser(p) {};
|
||||
};
|
||||
|
||||
|
||||
typedef list<ParserSlot> ParserSlots;
|
||||
typedef list<ParserSlot>::iterator ParserSlotIter;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::ParserFormatSlot".
|
||||
|
||||
class ParserFormatSlot {
|
||||
|
||||
public:
|
||||
// Constructors.
|
||||
inline ParserFormatSlot ();
|
||||
// Accessors.
|
||||
inline bool loadByLib ();
|
||||
inline const Name& getTag ();
|
||||
inline const Name& getExt ();
|
||||
inline LibraryParser_t* getParsLib ();
|
||||
inline CellParser_t* getParsCell ();
|
||||
// Modifiers.
|
||||
void registerCell ( const string& tag, CellParser_t* p, const string& ext );
|
||||
void registerLib ( const string& tag, LibraryParser_t* p, const string& ext );
|
||||
bool unRegisterCell ( const Name& ext );
|
||||
bool unRegisterLib ( const Name& ext );
|
||||
// Iterators handling.
|
||||
inline void cbegin ();
|
||||
inline void lbegin ();
|
||||
bool cend ();
|
||||
bool lend ();
|
||||
void operator++ (int);
|
||||
|
||||
private:
|
||||
// Internal - Attributes.
|
||||
bool _loadByLib;
|
||||
bool _itset;
|
||||
ParserSlots _cells;
|
||||
ParserSlots _libs;
|
||||
ParserSlotIter _it;
|
||||
};
|
||||
|
||||
|
||||
inline ParserFormatSlot::ParserFormatSlot () : _loadByLib(false), _itset(false) { };
|
||||
inline bool ParserFormatSlot::loadByLib () { return ( _loadByLib ); }
|
||||
inline const Name& ParserFormatSlot::getTag () { return ( _it->_tag ); }
|
||||
inline const Name& ParserFormatSlot::getExt () { return ( _it->_ext ); }
|
||||
inline LibraryParser_t* ParserFormatSlot::getParsLib () { return ( (LibraryParser_t*)_it->_parser ); }
|
||||
inline CellParser_t* ParserFormatSlot::getParsCell () { return ( (CellParser_t* )_it->_parser ); }
|
||||
inline void ParserFormatSlot::cbegin () { _it = _cells.begin(); _itset = true; }
|
||||
inline void ParserFormatSlot::lbegin () { _it = _libs.begin(); _itset = true; }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::ParsersMap".
|
||||
|
||||
class ParsersMap : public map<Name,ParserFormatSlot> {
|
||||
|
||||
public:
|
||||
// Constructor.
|
||||
ParsersMap ();
|
||||
// Methods.
|
||||
ParserFormatSlot& getParserSlot ( const string& tag );
|
||||
ParserFormatSlot& getParserSlot ( const string& tag, unsigned int mode, const Environment& env );
|
||||
void registerSlot ( const string& tag, LibraryParser_t* p, const string& ext );
|
||||
void registerSlot ( const string& tag, CellParser_t* p, const string& ext );
|
||||
void unRegisterSlot ( const Name& tag, const Name& ext, bool lib );
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::DriverSlot".
|
||||
|
||||
class DriverSlot {
|
||||
|
||||
public:
|
||||
// Constructor.
|
||||
inline DriverSlot ( string tag="unknown" );
|
||||
// Accessors.
|
||||
inline const Name& getTag ();
|
||||
inline const Name& getExtLib ();
|
||||
inline const Name& getExtCell ();
|
||||
inline LibraryDriver_t* getDrivLib ();
|
||||
inline CellDriver_t* getDrivCell ();
|
||||
|
||||
// Modifiers.
|
||||
inline void setExtLib ( const string &ext );
|
||||
inline void setExtCell ( const string &ext );
|
||||
inline void setDrivLib ( LibraryDriver_t *driv );
|
||||
inline void setDrivCell ( CellDriver_t *driv );
|
||||
|
||||
private:
|
||||
// Internal - Attributes.
|
||||
Name _tag;
|
||||
Name _extLib;
|
||||
Name _extCell;
|
||||
LibraryDriver_t* _drivLib;
|
||||
CellDriver_t* _drivCell;
|
||||
};
|
||||
|
||||
|
||||
inline DriverSlot::DriverSlot ( string tag )
|
||||
: _tag(tag)
|
||||
, _extLib("unknown")
|
||||
, _extCell("unknown")
|
||||
, _drivLib(NULL)
|
||||
, _drivCell(NULL)
|
||||
{ }
|
||||
inline const Name& DriverSlot::getTag () { return ( _tag ); }
|
||||
inline const Name& DriverSlot::getExtLib () { return ( _extLib ); }
|
||||
inline const Name& DriverSlot::getExtCell () { return ( _extCell ); }
|
||||
inline LibraryDriver_t* DriverSlot::getDrivLib () { return ( _drivLib ); }
|
||||
inline CellDriver_t* DriverSlot::getDrivCell () { return ( _drivCell ); }
|
||||
inline void DriverSlot::setExtLib ( const string& ext ) { _extLib = ext; }
|
||||
inline void DriverSlot::setExtCell ( const string& ext ) { _extCell = ext; }
|
||||
inline void DriverSlot::setDrivLib ( LibraryDriver_t* driv ) { _drivLib = driv; }
|
||||
inline void DriverSlot::setDrivCell ( CellDriver_t* driv ) { _drivCell = driv; }
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::DriversMap".
|
||||
|
||||
class DriversMap : public map<Name,DriverSlot> {
|
||||
|
||||
public:
|
||||
// Constructor.
|
||||
DriversMap ();
|
||||
// Methods.
|
||||
DriverSlot& getDriverSlot ( const string& tag );
|
||||
DriverSlot& getDriverSlot ( const string& tag, unsigned int mode, const Environment& env );
|
||||
void registerSlot ( const string& tag, CellDriver_t *d, const string& ext );
|
||||
void registerSlot ( const string& tag, LibraryDriver_t *d, const string& ext );
|
||||
void unRegisterSlot ( const Name& tag );
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Error Messages.
|
||||
|
||||
extern const char* BadParserType;
|
||||
extern const char* BadDriverType;
|
||||
extern const char* BadInputMode;
|
||||
extern const char* BadOutputMode;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
# endif
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
#ifndef __CRL_REAL_TECHNOLOGY_PARSER_H__
|
||||
#define __CRL_REAL_TECHNOLOGY_PARSER_H__
|
||||
|
||||
|
||||
class QString;
|
||||
|
||||
#include "crlcore/XmlParser.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class DataBase;
|
||||
class Technology;
|
||||
class Layer;
|
||||
class BasicLayer;
|
||||
}
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::BasicLayer;
|
||||
|
||||
|
||||
class RealTechnologyParser : public XmlParser {
|
||||
|
||||
// Methods.
|
||||
public:
|
||||
static RealTechnologyParser* create ( DataBase* db, QXmlStreamReader* reader );
|
||||
static bool load ( DataBase* db, const string& path );
|
||||
|
||||
// Internal - enum.
|
||||
protected:
|
||||
enum TagSet { TagsTechnology = 2
|
||||
, TagsReal
|
||||
, TagsName
|
||||
, TagsLayers
|
||||
, TagsProcessLayer
|
||||
, TagSetSize
|
||||
};
|
||||
|
||||
// Internal - Attributes.
|
||||
static const QString MissingSymbolicNameError;
|
||||
static const QString MissingRealNameError;
|
||||
static const QString InvalidSymbolicNameError;
|
||||
static const QString MissingGridValueError;
|
||||
static const QString MissingGridsPerLambdaValueError;
|
||||
static const QString MissingGridUnitError;
|
||||
static const QString UnknownGridUnitError;
|
||||
DataBase* _dataBase;
|
||||
Technology* _technology;
|
||||
|
||||
// Internal - Constructors.
|
||||
RealTechnologyParser ( DataBase* db, QXmlStreamReader* reader=NULL );
|
||||
RealTechnologyParser ( const RealTechnologyParser& );
|
||||
RealTechnologyParser& operator= ( const RealTechnologyParser& );
|
||||
|
||||
// Internal - Methods.
|
||||
void parseTechnology ();
|
||||
void parseReal ();
|
||||
void parseName ();
|
||||
void parseGrid ();
|
||||
void parseGridsPerLambda ();
|
||||
void parseLayers ();
|
||||
void parseProcessLayer ();
|
||||
virtual void _postLoad ();
|
||||
virtual const char* _getMessage ( MessageId id );
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,112 @@
|
|||
|
||||
// -*- 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 : "./RoutingGauge.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#ifndef __CRL_ROUTING_GAUGE_H__
|
||||
#define __CRL_ROUTING_GAUGE_H__
|
||||
|
||||
|
||||
class QXmlSteamReader;
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "hurricane/Name.h"
|
||||
#include "hurricane/Slot.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class Layer;
|
||||
class Technology;
|
||||
}
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
using Hurricane::Name;
|
||||
using Hurricane::Record;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Technology;
|
||||
|
||||
class RoutingLayerGauge;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "RoutingGauge".
|
||||
|
||||
class RoutingGauge {
|
||||
|
||||
public:
|
||||
// Constructors & Destructors.
|
||||
static RoutingGauge* create ( const char* name );
|
||||
virtual void destroy ();
|
||||
// Accessors.
|
||||
RoutingGauge* getClone () const;
|
||||
inline const Name getName () const;
|
||||
inline Technology* getTechnology () const;
|
||||
inline size_t getDepth () const;
|
||||
size_t getLayerDepth ( const Layer* ) const;
|
||||
RoutingLayerGauge* getLayerGauge ( const Layer* ) const;
|
||||
unsigned int getLayerDirection ( const Layer* ) const;
|
||||
RoutingLayerGauge* getLayerGauge ( size_t depth ) const;
|
||||
unsigned int getLayerDirection ( size_t depth ) const;
|
||||
const Layer* getRoutingLayer ( size_t depth ) const;
|
||||
Layer* getContactLayer ( size_t depth ) const;
|
||||
const vector<RoutingLayerGauge*>&
|
||||
getLayerGauges () const;
|
||||
// Methods.
|
||||
void addLayerGauge ( RoutingLayerGauge* layerGauge );
|
||||
void checkConnexity () const;
|
||||
// Hurricane Managment.
|
||||
virtual Record* _getRecord ( Record* record=NULL ) const;
|
||||
virtual string _getString () const;
|
||||
virtual string _getTypeName () const;
|
||||
|
||||
protected:
|
||||
// Internal - Attributes.
|
||||
Name _name;
|
||||
vector<RoutingLayerGauge*> _layerGauges;
|
||||
vector<Layer*> _viaLayers;
|
||||
Technology* _technology;
|
||||
|
||||
// Internal - Constructors & Destructors.
|
||||
RoutingGauge ( const char* name );
|
||||
RoutingGauge ( const RoutingGauge& );
|
||||
virtual ~RoutingGauge ();
|
||||
virtual void _preDestroy ();
|
||||
RoutingGauge& operator= ( const RoutingGauge& );
|
||||
};
|
||||
|
||||
|
||||
inline const Name RoutingGauge::getName () const { return _name; }
|
||||
inline size_t RoutingGauge::getDepth () const { return _layerGauges.size(); }
|
||||
inline Technology* RoutingGauge::getTechnology () const { return _technology; }
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,232 @@
|
|||
|
||||
// -*- 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++ Header : "./RoutingLayerGauge.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef __CRL_ROUTING_LAYER_GAUGE_H__
|
||||
#define __CRL_ROUTING_LAYER_GAUGE_H__
|
||||
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "hurricane/Commons.h"
|
||||
#include "hurricane/DbU.h"
|
||||
#include "hurricane/Collection.h"
|
||||
#include "hurricane/Slot.h"
|
||||
|
||||
#include "crlcore/Utilities.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class Layer;
|
||||
}
|
||||
|
||||
|
||||
namespace Constant {
|
||||
|
||||
enum Direction { Horizontal = (1<<0)
|
||||
, Vertical = (1<<1)
|
||||
};
|
||||
|
||||
enum LayerGaugeType { Default = (1<<0)
|
||||
, PinOnly = (1<<1)
|
||||
};
|
||||
|
||||
enum Round { Superior = (1<<2)
|
||||
, Inferior = (1<<3)
|
||||
, Nearest = (1<<4)
|
||||
, Exact = (1<<5)
|
||||
};
|
||||
|
||||
Direction perpandicular ( unsigned int );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using std::map;
|
||||
|
||||
using Hurricane::GenericCollection;
|
||||
using Hurricane::GenericLocator;
|
||||
using Hurricane::GenericFilter;
|
||||
using Hurricane::Record;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Layer;
|
||||
|
||||
|
||||
class RoutingGauge;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "RoutingLayerGauge".
|
||||
|
||||
|
||||
class RoutingLayerGauge {
|
||||
|
||||
public:
|
||||
// Constructors & Destructors.
|
||||
static 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 );
|
||||
virtual void destroy ();
|
||||
// Accessors.
|
||||
inline const Layer* getLayer () const;
|
||||
inline const Layer* getBlockageLayer () const;
|
||||
inline unsigned int getDepth () const;
|
||||
inline unsigned int getDirection () const;
|
||||
inline unsigned int getType () const;
|
||||
inline double getDensity () const;
|
||||
inline DbU::Unit getOffset () const;
|
||||
inline DbU::Unit getPitch () const;
|
||||
inline DbU::Unit getHalfPitch () const;
|
||||
inline DbU::Unit getWireWidth () const;
|
||||
inline DbU::Unit getHalfWireWidth () const;
|
||||
inline DbU::Unit getViaWidth () const;
|
||||
inline DbU::Unit getHalfViaWidth () const;
|
||||
void divide ( DbU::Unit dividend, long& quotient, long& modulo ) const;
|
||||
unsigned int getTrackNumber ( DbU::Unit start, DbU::Unit stop ) const;
|
||||
unsigned int getTrackIndex ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const;
|
||||
DbU::Unit getTrackPosition ( DbU::Unit start, unsigned depth ) const;
|
||||
// Hurricane Managment.
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
|
||||
protected:
|
||||
// Internal - Attributes.
|
||||
const Layer* _layer;
|
||||
const Layer* _blockageLayer;
|
||||
unsigned int _direction;
|
||||
unsigned int _type;
|
||||
unsigned int _depth;
|
||||
double _density;
|
||||
DbU::Unit _offset;
|
||||
DbU::Unit _pitch;
|
||||
DbU::Unit _wireWidth;
|
||||
DbU::Unit _viaWidth;
|
||||
|
||||
// Internal - Constructors & Destructors.
|
||||
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 );
|
||||
virtual ~RoutingLayerGauge ();
|
||||
virtual void _preDestroy();
|
||||
RoutingLayerGauge& operator= ( const RoutingLayerGauge& );
|
||||
|
||||
// Friends.
|
||||
friend class RoutingGauge;
|
||||
};
|
||||
|
||||
|
||||
// New Types.
|
||||
typedef map<Layer*,RoutingLayerGauge*> RoutingLayerGaugeMap;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Collection : "RoutingLayerGauges".
|
||||
|
||||
typedef GenericCollection<RoutingLayerGauge*> RoutingLayerGauges;
|
||||
typedef GenericLocator<RoutingLayerGauge*> RoutingLayerGaugeLocator;
|
||||
typedef GenericFilter<RoutingLayerGauge*> RoutingLayerGaugeFilter;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Inline Functions.
|
||||
|
||||
inline const Layer* RoutingLayerGauge::getLayer () const { return ( _layer ); }
|
||||
inline const Layer* RoutingLayerGauge::getBlockageLayer () const { return ( _blockageLayer ); }
|
||||
inline unsigned int RoutingLayerGauge::getDirection () const { return ( _direction ); }
|
||||
inline unsigned int RoutingLayerGauge::getType () const { return ( _type ); }
|
||||
inline unsigned int RoutingLayerGauge::getDepth () const { return ( _depth ); }
|
||||
inline double RoutingLayerGauge::getDensity () const { return ( _density ); }
|
||||
inline DbU::Unit RoutingLayerGauge::getOffset () const { return ( _offset ); }
|
||||
inline DbU::Unit RoutingLayerGauge::getPitch () const { return ( _pitch ); }
|
||||
inline DbU::Unit RoutingLayerGauge::getHalfPitch () const { return ( _pitch>>1 ); }
|
||||
inline DbU::Unit RoutingLayerGauge::getWireWidth () const { return ( _wireWidth ); }
|
||||
inline DbU::Unit RoutingLayerGauge::getHalfWireWidth () const { return ( _wireWidth>>1 ); }
|
||||
inline DbU::Unit RoutingLayerGauge::getViaWidth () const { return ( _viaWidth ); }
|
||||
inline DbU::Unit RoutingLayerGauge::getHalfViaWidth () const { return ( _viaWidth>>1 ); }
|
||||
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
INSPECTOR_P_SUPPORT(CRL::RoutingLayerGauge);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Inspector Support for : "const ::Constant::Direction*".
|
||||
|
||||
|
||||
template<>
|
||||
inline std::string getString<const Constant::Direction*>
|
||||
( const Constant::Direction* direction )
|
||||
{
|
||||
switch ( *direction ) {
|
||||
case Constant::Horizontal: return "Horizontal";
|
||||
case Constant::Vertical: return "Vertical";
|
||||
}
|
||||
return ( "Unknown Constant::Direction" );
|
||||
}
|
||||
|
||||
|
||||
IOSTREAM_POINTER_SUPPORT(Constant::Direction);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Inspector Support for : "const Constant::LayerGaugeType*".
|
||||
|
||||
|
||||
template<>
|
||||
inline std::string getString<const Constant::LayerGaugeType*>
|
||||
( const Constant::LayerGaugeType* layerGaugeType )
|
||||
{
|
||||
switch ( *layerGaugeType ) {
|
||||
case Constant::Horizontal: return "Horizontal";
|
||||
case Constant::Vertical: return "Vertical";
|
||||
}
|
||||
return ( "Unknown Constant::LayerGaugeType" );
|
||||
}
|
||||
|
||||
|
||||
IOSTREAM_POINTER_SUPPORT(Constant::LayerGaugeType);
|
||||
|
||||
|
||||
# endif // __CRL_ROUTING_LAYER_GAUGE_H__
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
# ifndef __CRL_SEARCH_PATH__
|
||||
# define __CRL_SEARCH_PATH__
|
||||
|
||||
|
||||
# include <string>
|
||||
# include <vector>
|
||||
|
||||
# include "hurricane/Commons.h"
|
||||
# include "hurricane/Slot.h"
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
using Hurricane::Record;
|
||||
using Hurricane::_TName;
|
||||
|
||||
|
||||
class SearchPath {
|
||||
|
||||
public:
|
||||
// Constants.
|
||||
static const size_t npos;
|
||||
|
||||
// Constructors.
|
||||
SearchPath ();
|
||||
|
||||
// Methods.
|
||||
inline void reset ();
|
||||
inline void append ( const string& path );
|
||||
void replace ( const string& path, size_t index );
|
||||
size_t locate ( const string& file
|
||||
, ios::openmode mode =ios::in
|
||||
, int first=0
|
||||
, int last =64 );
|
||||
inline size_t getSize () const;
|
||||
inline const string& getSelected () const;
|
||||
inline size_t getIndex () const;
|
||||
bool hasSelected () const;
|
||||
bool hasPath ( const string& path ) const;
|
||||
const string& operator[] ( size_t index ) const;
|
||||
|
||||
// Internal - Attributes.
|
||||
private:
|
||||
vector<string> _paths;
|
||||
size_t _index;
|
||||
string _selected;
|
||||
|
||||
// Internal - Constructors.
|
||||
private:
|
||||
SearchPath ( const SearchPath& );
|
||||
|
||||
// Hurricane management.
|
||||
public:
|
||||
inline string _getTypeName () const;
|
||||
string _getString () const;
|
||||
Record* _getRecord () const;
|
||||
};
|
||||
|
||||
|
||||
// Inline Functions.
|
||||
inline void SearchPath::reset () { _paths.resize(1); }
|
||||
inline void SearchPath::append ( const string& path ) { _paths.push_back(path); }
|
||||
inline size_t SearchPath::getSize () const { return _paths.size(); }
|
||||
inline const string& SearchPath::getSelected () const { return _selected; }
|
||||
inline size_t SearchPath::getIndex () const { return _index; }
|
||||
inline bool SearchPath::hasSelected () const { return _index != npos; }
|
||||
inline string SearchPath::_getTypeName () const { return _TName("SearchPath"); }
|
||||
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
# endif
|
|
@ -0,0 +1,119 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
# ifndef __CRL_SYMBOLIC_TECHNOLOGY_PARSER_H__
|
||||
# define __CRL_SYMBOLIC_TECHNOLOGY_PARSER_H__
|
||||
|
||||
|
||||
class QString;
|
||||
|
||||
# include "crlcore/XmlParser.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class DataBase;
|
||||
class Technology;
|
||||
class Layer;
|
||||
class BasicLayer;
|
||||
}
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
using Hurricane::Name;
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::BasicLayer;
|
||||
|
||||
|
||||
class SymbolicTechnologyParser : public XmlParser {
|
||||
|
||||
public:
|
||||
// Methods.
|
||||
static SymbolicTechnologyParser* create ( DataBase* db, QXmlStreamReader* reader );
|
||||
static bool load ( DataBase* db, const string& path );
|
||||
|
||||
// Internal - enum.
|
||||
protected:
|
||||
enum TagSet { TagsTechnology = 2
|
||||
, TagsName
|
||||
, TagsBasicLayer
|
||||
, TagsBasicLayers
|
||||
, TagsLayer
|
||||
, TagsSymbolic
|
||||
, TagsPrecision
|
||||
, TagsGridStep
|
||||
, TagsRules
|
||||
, TagsRule
|
||||
, TagSetSize
|
||||
};
|
||||
|
||||
enum RuleType { DoubleValue = (1<<0)
|
||||
, ValueMask = DoubleValue
|
||||
, ExtentionCap = (1<<4) | DoubleValue
|
||||
, ExtentionWidth = (1<<5) | DoubleValue
|
||||
, Enclosure = (1<<6) | DoubleValue
|
||||
, MinimumWidth = (1<<7) | DoubleValue
|
||||
, MinimumSide = (1<<8) | DoubleValue
|
||||
, InvalidRule = (unsigned int)-1
|
||||
};
|
||||
|
||||
// Internal - Attributes.
|
||||
static const QString UnnamedRuleError;
|
||||
static const QString UnnamedBasicLayerError;
|
||||
static const QString UnnamedSymbolicLayerError;
|
||||
static const QString UnnamedLayerError;
|
||||
static const QString InvalidRulePathError;
|
||||
static const QString MissingValueError;
|
||||
static const QString UnknownRuleError;
|
||||
static const QString UndefinedLayerError;
|
||||
static const QString NotACompositeLayerError;
|
||||
static const QString NotABasicLayerError;
|
||||
static const QString LayerOutnumber;
|
||||
static const QString LayerMissingLayer;
|
||||
DataBase* _dataBase;
|
||||
Technology* _technology;
|
||||
BasicLayer* _basicLayer;
|
||||
map<const Name,Layer*> _layers;
|
||||
vector<BasicLayer*> _layerComponents;
|
||||
|
||||
// Internal - Constructors.
|
||||
SymbolicTechnologyParser ( DataBase* db, QXmlStreamReader* reader=NULL );
|
||||
SymbolicTechnologyParser ( const SymbolicTechnologyParser& );
|
||||
SymbolicTechnologyParser& operator= ( const SymbolicTechnologyParser& );
|
||||
|
||||
// Internal - Methods.
|
||||
void parseTechnology ();
|
||||
void parseName ();
|
||||
void parseBasicLayer ();
|
||||
void parseRegularLayer ();
|
||||
void parseDiffusionLayer ();
|
||||
void parseTransistorLayer ();
|
||||
void parseViaLayer ();
|
||||
void parseContactLayer ();
|
||||
void parseLayer ();
|
||||
void parseSymbolic ();
|
||||
void parsePrecision ();
|
||||
void parseGridStep ();
|
||||
void parseRules ();
|
||||
void parseRule ();
|
||||
unsigned int splitRulePath ( const QString& path
|
||||
, Layer*& ruleLayer
|
||||
, BasicLayer*& basicLayer
|
||||
);
|
||||
BasicLayer* getBasicLayer ( const QString& name, bool ignoreError );
|
||||
Layer* getLayer ( const QString& name, bool ignoreError );
|
||||
virtual void _postLoad ();
|
||||
virtual const char* _getMessage ( MessageId id );
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
# endif
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
//
|
||||
// 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 : 15/05/2007
|
||||
// Author : Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
#ifndef CRL_CTIMINGEVENT_H
|
||||
#define CRL_CTIMINGEVENT_H
|
||||
|
||||
#include "hurricane/Commons.h"
|
||||
# include "hurricane/Slot.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
namespace CRL {
|
||||
|
||||
//! Description des evenements temporels : front montant ou front descendant
|
||||
class CTimingEvent {
|
||||
public:enum Code { UNDEFINED=0, FALLING_EDGE=1, RISING_EDGE=2 } ;
|
||||
private: Code _code;
|
||||
|
||||
public: CTimingEvent(const Code& code = UNDEFINED);
|
||||
public: CTimingEvent(const CTimingEvent& event);
|
||||
|
||||
public: CTimingEvent& operator=(const CTimingEvent& event);
|
||||
|
||||
public: operator const Code&() const {return _code;}
|
||||
//public: operator bool() const { return _code != UNDEFINED; } //creates ambiguities
|
||||
|
||||
public: const Code& getCode() const {return _code;}
|
||||
|
||||
public: string getName() const;
|
||||
public: string _getTypeName() const { return _TName("CTimingEvent"); };
|
||||
public: string _getString() const;
|
||||
public: Record* _getRecord() const;
|
||||
};
|
||||
|
||||
CTimingEvent getCTimingEvent(const string &s);
|
||||
|
||||
} //namespace CRL
|
||||
|
||||
CRL::CTimingEvent operator-(CRL::CTimingEvent event);
|
||||
|
||||
#define for_each_ctimingevent(event) \
|
||||
for(CRL::CTimingEvent event= CRL::CTimingEvent::FALLING_EDGE ; event != CRL::CTimingEvent::UNDEFINED ; \
|
||||
event= (event == CRL::CTimingEvent::FALLING_EDGE)?CRL::CTimingEvent::RISING_EDGE:CRL::CTimingEvent::UNDEFINED )
|
||||
|
||||
#endif // CRL_CTIMINGEVENT_H
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
|
||||
// -*- 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 |
|
||||
// | K i t e - D e t a i l e d R o u t e r |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./ToolBox.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#ifndef __CRL_TOOLBOX_H__
|
||||
#define __CRL_TOOLBOX_H__
|
||||
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Component.h"
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
using Hurricane::Name;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Library;
|
||||
using Hurricane::Occurrence;
|
||||
|
||||
Component* getBestExternalComponent ( Net* );
|
||||
void PlaceNet ( Net* );
|
||||
void PlaceNets ( Cell* );
|
||||
void PlaceMasterNets ( const Library* );
|
||||
void PlacePlug ( Plug* );
|
||||
void PlacePlugs ( Cell* );
|
||||
void createPartRing2 ( Net& );
|
||||
void createPartRing ( Cell*, Name nom );
|
||||
void createPlugsRing ( Net& );
|
||||
void createPlugsRing ( Cell* );
|
||||
void createPlugsAndPinsRing ( Cell* );
|
||||
void createContactsRing ( Cell* );
|
||||
void deleteEmptyNets ( Cell* );
|
||||
Transformation getTransformation ( const Box& abox, const DbU::Unit& x, const DbU::Unit& y, const Transformation::Orientation& orientation );
|
||||
bool isNoInstancePlacedOrFixed ( Cell* );
|
||||
Occurrence getRootNetOccurrence ( const Occurrence& netoccurrence );
|
||||
void ConnectPlugHooks ( Cell* );
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
#endif // __CRL_TOOLBOX_H__
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
// -*- 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++ Header : "./ToolEngine.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
#ifndef __CRL_TOOL_ENGINE__
|
||||
#define __CRL_TOOL_ENGINE__
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "hurricane/Commons.h"
|
||||
#include "hurricane/DBo.h"
|
||||
#include "hurricane/Slot.h"
|
||||
|
||||
namespace Hurricane {
|
||||
class Name;
|
||||
class Cell;
|
||||
}
|
||||
|
||||
#include "crlcore/ToolEngines.h"
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using std::string;
|
||||
using Hurricane::Record;
|
||||
using Hurricane::Name;
|
||||
using Hurricane::DBo;
|
||||
using Hurricane::Cell;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::ToolEngine".
|
||||
|
||||
|
||||
class ToolEngine : public DBo {
|
||||
public:
|
||||
// Static Methods.
|
||||
static ToolEngines get ( const Cell* cell );
|
||||
static ToolEngine* get ( const Cell* cell, const Name& name );
|
||||
// Methods.
|
||||
virtual const Name& getName () const = 0;
|
||||
inline Cell* getCell () const;
|
||||
bool placementModificationFlagHasChanged ();
|
||||
bool routingModificationFlagHasChanged ();
|
||||
inline void setInRelationDestroy ( bool );
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
|
||||
protected:
|
||||
// Internal: Attributes
|
||||
Cell* _cell;
|
||||
private:
|
||||
unsigned int _placementModificationFlag;
|
||||
unsigned int _routingModificationFlag;
|
||||
bool _inRelationDestroy;
|
||||
|
||||
// Internal: Constructors & Destructors.
|
||||
protected:
|
||||
ToolEngine ( Cell* cell );
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
// Internal: Methods.
|
||||
void grabPlacementModificationFlag ();
|
||||
void getPlacementModificationFlag ();
|
||||
void grabRoutingModificationFlag ();
|
||||
void getRoutingModificationFlag ();
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Inline Functions.
|
||||
|
||||
|
||||
inline Cell* ToolEngine::getCell () const { return _cell; }
|
||||
inline void ToolEngine::setInRelationDestroy ( bool state ) { _inRelationDestroy = state; }
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
#endif // __CRL_TOOL_ENGINE__
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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
|
||||
// ===================================================================
|
||||
|
||||
|
||||
# ifndef __CRL_TOOL_ENGINES_H__
|
||||
# define __CRL_TOOL_ENGINES_H__
|
||||
|
||||
# include "hurricane/Collection.h"
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using Hurricane::GenericCollection;
|
||||
using Hurricane::GenericLocator;
|
||||
using Hurricane::GenericFilter;
|
||||
|
||||
|
||||
class ToolEngine;
|
||||
|
||||
|
||||
typedef GenericCollection<ToolEngine*> ToolEngines;
|
||||
typedef GenericLocator<ToolEngine*> ToolEngineLocator;
|
||||
typedef GenericFilter<ToolEngine*> ToolEngineFilter;
|
||||
|
||||
# define for_each_toolengine(toolEngine, toolEngines) { \
|
||||
ToolEngineLocator _locator = toolEngines.getLocator(); \
|
||||
while ( _locator.isValid() ) { \
|
||||
ToolEngine* toolEngine = _locator.getElement(); \
|
||||
_locator.progress();
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // __CENGINES_H
|
|
@ -0,0 +1,339 @@
|
|||
|
||||
// -*- 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 : "./Utilities.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#ifndef __CRL_UTILITIES_H__
|
||||
#define __CRL_UTILITIES_H__
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
|
||||
#include <ostream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "hurricane/Commons.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Slot.h"
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using Hurricane::_TName;
|
||||
using Hurricane::Record;
|
||||
using Hurricane::Error;
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::System".
|
||||
|
||||
|
||||
class System {
|
||||
public:
|
||||
// Constructor & Destructor.
|
||||
static System* create ();
|
||||
// Methods.
|
||||
static System* getSystem ();
|
||||
static void trapSig ( int sig );
|
||||
inline bool getCatchCore ();
|
||||
inline bool setCatchCore ( bool catchCore );
|
||||
|
||||
private:
|
||||
// Internal: Attributes.
|
||||
static System* _singleton;
|
||||
bool _catchCore;
|
||||
|
||||
// Constructors & Destructors.
|
||||
inline System ();
|
||||
System ( const System &other );
|
||||
System& operator= ( const System &other );
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::IoFile ()".
|
||||
//
|
||||
// Class wrapper for the C FILE* stream.
|
||||
|
||||
|
||||
class IoFile {
|
||||
public:
|
||||
// Constructors.
|
||||
inline IoFile ( string path="<unbound>" );
|
||||
// Methods
|
||||
inline bool isOpen () const;
|
||||
inline bool eof () const;
|
||||
char* readLine ( char* buffer, size_t length );
|
||||
inline FILE* getFile ();
|
||||
inline size_t getLineNumber () const;
|
||||
bool open ( const string& mode );
|
||||
void close ();
|
||||
inline void rewind ();
|
||||
// Hurricane management.
|
||||
inline string _getTypeName () const;
|
||||
string _getString () const;
|
||||
Record* _getRecord () const;
|
||||
|
||||
private:
|
||||
// Internal - Attributes.
|
||||
FILE* _file;
|
||||
string _path;
|
||||
string _mode;
|
||||
size_t _lineNumber;
|
||||
bool _eof;
|
||||
|
||||
// Internal - Constructor.
|
||||
IoFile ( const IoFile& );
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Function : "CRL::_PName()".
|
||||
//
|
||||
// Generate strings with prefixes.
|
||||
|
||||
inline string _PName ( const string& s ) { return ( "CRL::" + s ); }
|
||||
|
||||
|
||||
// Inline Methods.
|
||||
inline System::System (): _catchCore(true) { }
|
||||
inline bool System::getCatchCore () { return _catchCore; }
|
||||
inline bool System::setCatchCore ( bool catchCore ) { return _catchCore = catchCore; }
|
||||
|
||||
inline IoFile::IoFile ( string path ): _file(NULL)
|
||||
, _path(path)
|
||||
, _mode("")
|
||||
, _lineNumber(0)
|
||||
, _eof(false) {}
|
||||
inline bool IoFile::isOpen () const { return _file!=NULL; }
|
||||
inline bool IoFile::eof () const { return _eof; }
|
||||
inline FILE* IoFile::getFile () { return _file; }
|
||||
inline size_t IoFile::getLineNumber () const { return _lineNumber; }
|
||||
inline void IoFile::rewind () { if (_file) std::rewind(_file); _lineNumber=0; }
|
||||
inline string IoFile::_getTypeName () const { return _TName("IoFile"); }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Error Messages.
|
||||
|
||||
extern const char* BadAllocProperty;
|
||||
extern const char* BadCreate;
|
||||
extern const char* NullDataBase;
|
||||
extern const char* NullTechnology;
|
||||
extern const char* NullLibrary;
|
||||
extern const char* NullCell;
|
||||
extern const char* BadFopen;
|
||||
extern const char* BadColorValue;
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "::tty()".
|
||||
|
||||
|
||||
class tty {
|
||||
public:
|
||||
enum Flags { Black = 0
|
||||
, Red = 1
|
||||
, Green = 2
|
||||
, Yellow = 3
|
||||
, Blue = 4
|
||||
, Magenta = 5
|
||||
, Cyan = 6
|
||||
, White = 7
|
||||
, Reset = 9
|
||||
, Normal = 0
|
||||
, Bright = (1<<4)
|
||||
, ColorMask = 0x0F
|
||||
, TypeMask = 0xF0
|
||||
};
|
||||
public:
|
||||
inline static void enable ();
|
||||
inline static void disable ();
|
||||
inline static bool enabled ();
|
||||
inline static std::ostream& cr ( std::ostream& );
|
||||
inline static std::ostream& reset ( std::ostream& );
|
||||
inline static std::ostream& bold ( std::ostream& );
|
||||
inline static std::ostream& faint ( std::ostream& );
|
||||
inline static std::ostream& italic ( std::ostream& );
|
||||
inline static std::ostream& underline ( std::ostream& );
|
||||
inline static std::ostream& slowBlink ( std::ostream& );
|
||||
inline static std::ostream& rapidBlink ( std::ostream& );
|
||||
inline static std::ostream& negative ( std::ostream& );
|
||||
inline static std::ostream& conceal ( std::ostream& );
|
||||
inline static std::ostream& underline2 ( std::ostream& );
|
||||
inline static std::ostream& normal ( std::ostream& );
|
||||
inline static std::ostream& underlineOff ( std::ostream& );
|
||||
inline static std::ostream& blinkOff ( std::ostream& );
|
||||
inline static std::ostream& positive ( std::ostream& );
|
||||
inline static std::ostream& reveal ( std::ostream& );
|
||||
inline static std::string fgcolor ( unsigned int );
|
||||
inline static std::string bgcolor ( unsigned int );
|
||||
private:
|
||||
static bool _enabled;
|
||||
static const char* _intensity[4];
|
||||
};
|
||||
|
||||
|
||||
inline void tty::enable () { _enabled=true; }
|
||||
inline void tty::disable () { _enabled=false; }
|
||||
inline bool tty::enabled () { return _enabled; }
|
||||
inline std::ostream& tty::cr ( std::ostream& o ) { if (_enabled) o<<"\r" ; return o; }
|
||||
inline std::ostream& tty::reset ( std::ostream& o ) { if (_enabled) o<<"\x1b[0m" ; return o; }
|
||||
inline std::ostream& tty::bold ( std::ostream& o ) { if (_enabled) o<<"\x1b[1m" ; return o; }
|
||||
inline std::ostream& tty::faint ( std::ostream& o ) { if (_enabled) o<<"\x1b[2m" ; return o; }
|
||||
inline std::ostream& tty::italic ( std::ostream& o ) { if (_enabled) o<<"\x1b[3m" ; return o; }
|
||||
inline std::ostream& tty::underline ( std::ostream& o ) { if (_enabled) o<<"\x1b[4m" ; return o; }
|
||||
inline std::ostream& tty::slowBlink ( std::ostream& o ) { if (_enabled) o<<"\x1b[5m" ; return o; }
|
||||
inline std::ostream& tty::rapidBlink ( std::ostream& o ) { if (_enabled) o<<"\x1b[6m" ; return o; }
|
||||
inline std::ostream& tty::negative ( std::ostream& o ) { if (_enabled) o<<"\x1b[7m" ; return o; }
|
||||
inline std::ostream& tty::conceal ( std::ostream& o ) { if (_enabled) o<<"\x1b[8m" ; return o; }
|
||||
inline std::ostream& tty::underline2 ( std::ostream& o ) { if (_enabled) o<<"\x1b[21m"; return o; }
|
||||
inline std::ostream& tty::normal ( std::ostream& o ) { if (_enabled) o<<"\x1b[22m"; return o; }
|
||||
inline std::ostream& tty::underlineOff ( std::ostream& o ) { if (_enabled) o<<"\x1b[24m"; return o; }
|
||||
inline std::ostream& tty::blinkOff ( std::ostream& o ) { if (_enabled) o<<"\x1b[25m"; return o; }
|
||||
inline std::ostream& tty::positive ( std::ostream& o ) { if (_enabled) o<<"\x1b[27m"; return o; }
|
||||
inline std::ostream& tty::reveal ( std::ostream& o ) { if (_enabled) o<<"\x1b[28m"; return o; }
|
||||
|
||||
inline std::string tty::fgcolor ( unsigned int mask )
|
||||
{
|
||||
if ( not _enabled ) return "";
|
||||
std::string sequence ("\x1b[");
|
||||
sequence += ((mask&Bright)?"4":"3");
|
||||
sequence += ('0'+(mask&ColorMask));
|
||||
sequence += "m";
|
||||
return sequence;
|
||||
}
|
||||
|
||||
inline std::string tty::bgcolor ( unsigned int mask )
|
||||
{
|
||||
if ( not _enabled ) return "";
|
||||
std::string sequence ("\x1b[");
|
||||
sequence += ((mask&Bright)?"10":"9");
|
||||
sequence += ('0'+(mask&ColorMask));
|
||||
sequence += "m";
|
||||
return sequence;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "::mstream()".
|
||||
//
|
||||
// Wrapper around the STL ostream which uses a verbose level to choose
|
||||
// wether to print or not.
|
||||
|
||||
|
||||
class mstream : public std::ostream {
|
||||
public:
|
||||
enum StreamMasks { Verbose0 = (1<<0)
|
||||
, Verbose1 = (1<<1)
|
||||
, Verbose2 = (1<<2)
|
||||
, Info = (1<<3)
|
||||
, VerboseLevel0 = Verbose0
|
||||
, VerboseLevel1 = Verbose0|Verbose1
|
||||
, VerboseLevel2 = Verbose0|Verbose1|Verbose2
|
||||
};
|
||||
public:
|
||||
static void enable ( unsigned int mask );
|
||||
static void disable ( unsigned int mask );
|
||||
inline mstream ( unsigned int mask, std::ostream &s );
|
||||
inline unsigned int getStreamMask() const;
|
||||
inline bool enabled () const;
|
||||
// Overload for formatted outputs.
|
||||
template<typename T> inline mstream& operator<< ( T& t );
|
||||
template<typename T> inline mstream& operator<< ( T* t );
|
||||
template<typename T> inline mstream& operator<< ( const T& t );
|
||||
template<typename T> inline mstream& operator<< ( const T* t );
|
||||
inline mstream& flush ();
|
||||
// Overload for manipulators.
|
||||
inline mstream &operator<< ( std::ostream &(*pf)(std::ostream &) );
|
||||
|
||||
// Internal: Attributes.
|
||||
private:
|
||||
static unsigned int _activeMask;
|
||||
unsigned int _streamMask;
|
||||
};
|
||||
|
||||
|
||||
inline mstream::mstream ( unsigned int mask, std::ostream& s ): std::ostream(s.rdbuf()) , _streamMask(mask) {}
|
||||
inline unsigned int mstream::getStreamMask() const { return _streamMask; }
|
||||
inline bool mstream::enabled () const { return (_streamMask & _activeMask); }
|
||||
inline mstream& mstream::flush () { if (enabled()) static_cast<std::ostream*>(this)->flush(); return *this; }
|
||||
inline mstream& mstream::operator<< ( std::ostream& (*pf)(std::ostream&) ) { if (enabled()) (*pf)(*this); return *this; }
|
||||
|
||||
template<typename T>
|
||||
inline mstream& mstream::operator<< ( T& t )
|
||||
{ if (enabled()) { *(static_cast<std::ostream*>(this)) << t; } return *this; };
|
||||
|
||||
template<typename T>
|
||||
inline mstream& mstream::operator<< ( T* t )
|
||||
{ if (enabled()) { *(static_cast<std::ostream*>(this)) << t; } return *this; };
|
||||
|
||||
template<typename T>
|
||||
inline mstream& mstream::operator<< ( const T& t )
|
||||
{ if (enabled()) { *(static_cast<std::ostream*>(this)) << t; } return *this; };
|
||||
|
||||
template<typename T>
|
||||
inline mstream& mstream::operator<< ( const T* t )
|
||||
{ if (enabled()) { *(static_cast<std::ostream*>(this)) << t; } return *this; };
|
||||
|
||||
// Specific non-member operator overload. Must be one for each type.
|
||||
#define MSTREAM_V_SUPPORT(Type) \
|
||||
inline mstream& operator<< ( mstream& o, const Type s ) \
|
||||
{ if (o.enabled()) { static_cast<std::ostream&>(o) << s; } return o; };
|
||||
|
||||
#define MSTREAM_R_SUPPORT(Type) \
|
||||
inline mstream& operator<< ( mstream& o, const Type& s ) \
|
||||
{ if (o.enabled()) { static_cast<std::ostream&>(o) << s; } return o; };
|
||||
|
||||
#define MSTREAM_P_SUPPORT(Type) \
|
||||
inline mstream& operator<< ( mstream& o, const Type* s ) \
|
||||
{ if (o.enabled()) { static_cast<std::ostream&>(o) << s; } return o; };
|
||||
|
||||
#define MSTREAM_PR_SUPPORT(Type) \
|
||||
MSTREAM_P_SUPPORT(Type) \
|
||||
MSTREAM_R_SUPPORT(Type)
|
||||
|
||||
MSTREAM_PR_SUPPORT(std::string);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Shared objects.
|
||||
|
||||
extern mstream cmess0;
|
||||
extern mstream cmess1;
|
||||
extern mstream cmess2;
|
||||
extern mstream cinfo;
|
||||
|
||||
|
||||
# endif
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
# ifndef __CRL_XML_PARSER_H__
|
||||
# define __CRL_XML_PARSER_H__
|
||||
|
||||
|
||||
# include <iostream>
|
||||
# include <vector>
|
||||
|
||||
# include <QString>
|
||||
|
||||
class QXmlStreamReader;
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
class XmlParser {
|
||||
|
||||
// Internal - Subclass: TagEntry.
|
||||
protected:
|
||||
typedef void (XmlParser::* tagParser_t)();
|
||||
|
||||
struct TagEntry {
|
||||
const char* _name;
|
||||
tagParser_t _parser;
|
||||
|
||||
inline TagEntry ( const char* name, tagParser_t parser );
|
||||
};
|
||||
|
||||
// Internal - Subclass: TagTable.
|
||||
enum BasicTagSet { TagsNoChilds = 0
|
||||
, TagsStandAlone = 1
|
||||
};
|
||||
class TagsTable : public vector<TagEntry> { };
|
||||
|
||||
// Internal - MessageId.
|
||||
enum MessageId { OpenFile = 0 };
|
||||
|
||||
// Internal - Attributes.
|
||||
vector<TagsTable> _tagsTables;
|
||||
QXmlStreamReader* _reader;
|
||||
|
||||
// Internal - Constructors & destructors.
|
||||
XmlParser ( QXmlStreamReader* reader, size_t tagsTablesSize );
|
||||
XmlParser ( const XmlParser& );
|
||||
virtual ~XmlParser ();
|
||||
XmlParser& operator= ( const XmlParser& );
|
||||
|
||||
// Internal - Methods.
|
||||
void addTagEntry ( int tagSet, const char* tag, tagParser_t tagParser );
|
||||
void parseTags ( int tagSet );
|
||||
void parseUnknownTag ();
|
||||
void parseStandAlone ();
|
||||
inline void parseNoChilds ();
|
||||
// const char* readTextAsAscii ();
|
||||
QString readTextAsString ();
|
||||
unsigned int readTextAsUInt ();
|
||||
long readTextAsLong ();
|
||||
double readTextAsDouble ();
|
||||
bool _load ( const string& path, bool warnNotFound=true );
|
||||
virtual void _postLoad () = 0;
|
||||
virtual const char* _getMessage ( MessageId id ) = 0;
|
||||
virtual void printError ( const QString& error, ostream& o=cerr );
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Inline Functions.
|
||||
inline XmlParser::TagEntry::TagEntry ( const char* name
|
||||
, XmlParser::tagParser_t parser
|
||||
) : _name(name)
|
||||
, _parser(parser)
|
||||
{ }
|
||||
|
||||
|
||||
inline void XmlParser::parseNoChilds () { parseTags(TagsNoChilds); }
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
# endif
|
|
@ -0,0 +1,201 @@
|
|||
%{
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
using namespace std;
|
||||
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Pin.h"
|
||||
#include "hurricane/Names.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
#include "crlcore/LefDefExtension.h"
|
||||
#include "crlcore/NetExtension.h"
|
||||
using namespace CRL;
|
||||
#include "crlcore/Ioc.h"
|
||||
|
||||
#define yyin Iocin
|
||||
#define yytext Ioctext
|
||||
|
||||
extern char *yytext;
|
||||
|
||||
extern int yyerror(char *str);
|
||||
extern int yylex();
|
||||
|
||||
enum Orientation {T=0, B=1, R=2, L=3, I=4};
|
||||
static Orientation orientation;
|
||||
static bool topUsed = false, bottomUsed = false, rightUsed = false, leftUsed = false, ignoreUsed = false;
|
||||
static map<Name, Net*> pinsMap;
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char *text;
|
||||
unsigned value;
|
||||
}
|
||||
|
||||
%token IGNORE TOP BOTTOM LEFT RIGHT IOPIN SPACE PAROUV PARFER PTVIRG
|
||||
%token <text> IOCID1
|
||||
%token <text> IOCID2
|
||||
%token <value> IOCVALUE
|
||||
%start file
|
||||
|
||||
%%
|
||||
file :
|
||||
| orientation PAROUV expr PARFER file
|
||||
;
|
||||
|
||||
orientation : TOP {
|
||||
if (topUsed)
|
||||
yyerror("on ioc file : TOP declared twice");
|
||||
else
|
||||
{
|
||||
orientation = T;
|
||||
topUsed = true;
|
||||
}
|
||||
}
|
||||
| BOTTOM {
|
||||
if (bottomUsed)
|
||||
yyerror("on ioc file : BOTTOM declared twice");
|
||||
else
|
||||
{
|
||||
orientation = B;
|
||||
bottomUsed = true;
|
||||
}
|
||||
}
|
||||
| RIGHT {
|
||||
if (rightUsed)
|
||||
yyerror("on ioc file : RIGHT declared twice");
|
||||
else
|
||||
{
|
||||
orientation = R;
|
||||
rightUsed = true;
|
||||
}
|
||||
}
|
||||
| LEFT {
|
||||
if (leftUsed)
|
||||
yyerror("on ioc file : LEFT declared twice");
|
||||
else
|
||||
{
|
||||
orientation = L;
|
||||
leftUsed = true;
|
||||
}
|
||||
}
|
||||
| IGNORE {
|
||||
if (ignoreUsed)
|
||||
yyerror("on ioc file : IGNORE declared twice");
|
||||
else
|
||||
{
|
||||
orientation = I;
|
||||
ignoreUsed = true;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
expr :
|
||||
| iopin expr
|
||||
| space expr
|
||||
;
|
||||
|
||||
|
||||
iopin : PAROUV IOPIN iopin1 PARFER PTVIRG
|
||||
;
|
||||
|
||||
space : SPACE IOCVALUE PTVIRG { throw Error("SPACES are not implemented");}
|
||||
;
|
||||
|
||||
iopin1 : IOCID1{
|
||||
string stringName ($1);
|
||||
if ((stringName.size() > 2) && (stringName.substr(stringName.size()-2) == ".0")) {
|
||||
stringName.erase(stringName.size()-2);
|
||||
}
|
||||
map<Name, Net*>::iterator pmit = pinsMap.find(Name(stringName));
|
||||
if (pmit == pinsMap.end())
|
||||
{
|
||||
cerr << stringName << " " << endl;
|
||||
throw Error("Unknown Pin Name");
|
||||
}
|
||||
Layer* layer = DataBase::getDB()->getTechnology()->getLayer(AllianceFramework::get()->getDefaultCGPinLayerName());
|
||||
Pin::AccessDirection accessDirection;
|
||||
Name pinName = Name(stringName);
|
||||
Net* net = pmit->second;
|
||||
Cell* cell = net->getCell();
|
||||
switch (orientation)
|
||||
{
|
||||
case T: accessDirection = Pin::AccessDirection::NORTH; LefDefExtension::getNorthPinIocOrder(cell,true).push_back(pinName); break;
|
||||
case B: accessDirection = Pin::AccessDirection::SOUTH; LefDefExtension::getSouthPinIocOrder(cell,true).push_back(pinName); break;
|
||||
case R: accessDirection = Pin::AccessDirection::EAST; LefDefExtension::getEastPinIocOrder(cell,true).push_back(pinName); break;
|
||||
case L: accessDirection = Pin::AccessDirection::WEST; LefDefExtension::getWestPinIocOrder(cell,true).push_back(pinName); break;
|
||||
case I: accessDirection = Pin::AccessDirection::UNDEFINED; LefDefExtension::getUndefinedPinIoc(cell,true).push_back(pinName); break;
|
||||
default: throw Error("Unrecognized Orientation while parsing ioc file...");
|
||||
}
|
||||
(void)Pin::create(net, pinName, accessDirection,Pin::PlacementStatus::PLACED, layer, 0, 0);
|
||||
}
|
||||
| IOCID2 {
|
||||
string stringName ($1);
|
||||
if ((stringName.size() > 2) && (stringName.substr(stringName.size()-2) == ".0")) {
|
||||
stringName.erase(stringName.size()-2);
|
||||
}
|
||||
map<Name, Net*>::iterator pmit = pinsMap.find(stringName);
|
||||
if (pmit == pinsMap.end())
|
||||
{
|
||||
cerr << stringName << " " << endl;
|
||||
throw Error("Unknown Pin Name");
|
||||
}
|
||||
Layer* layer = DataBase::getDB()->getTechnology()->getLayer("CALU2");
|
||||
Pin::AccessDirection accessDirection;
|
||||
Name pinName = Name(stringName);
|
||||
Net* net = pmit->second;
|
||||
Cell* cell = net->getCell();
|
||||
switch (orientation)
|
||||
{
|
||||
case T: accessDirection = Pin::AccessDirection::NORTH; LefDefExtension::getNorthPinIocOrder(cell,true).push_back(pinName); break;
|
||||
case B: accessDirection = Pin::AccessDirection::SOUTH; LefDefExtension::getSouthPinIocOrder(cell,true).push_back(pinName); break;
|
||||
case R: accessDirection = Pin::AccessDirection::EAST; LefDefExtension::getEastPinIocOrder(cell,true).push_back(pinName); break;
|
||||
case L: accessDirection = Pin::AccessDirection::WEST; LefDefExtension::getWestPinIocOrder(cell,true).push_back(pinName); break;
|
||||
case I: accessDirection = Pin::AccessDirection::UNDEFINED; LefDefExtension::getUndefinedPinIoc(cell,true).push_back(pinName); break;
|
||||
default: throw Error("Unrecognized Orientation while parsing ioc file...");
|
||||
}
|
||||
(void)Pin::create(net, pinName, accessDirection, Pin::PlacementStatus::PLACED, layer, 0, 0);
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
||||
int yyerror (char *str)
|
||||
{
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "error parsing the ioc file: %s before %s\n", str, yytext);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void IocParser(Cell* cell, const char* file)
|
||||
{
|
||||
extern FILE *yyin;
|
||||
if (!cell)
|
||||
throw Error("NULL cell in IOC parser");
|
||||
if ( (yyin=fopen(file,"r")) )
|
||||
{
|
||||
for_each_net(net, cell->getExternalNets())
|
||||
{
|
||||
if (net->isGlobal())
|
||||
continue;
|
||||
const Name& pinNamePt = NetExtension::getPort(net);
|
||||
Name pinName;
|
||||
if (!pinNamePt.isEmpty())
|
||||
pinName = Name(pinNamePt);
|
||||
else
|
||||
pinName = net->getName();
|
||||
if (pinsMap.find(pinName) != pinsMap.end())
|
||||
throw Error("two connectors with the same name");
|
||||
pinsMap[pinName] = net;
|
||||
end_for;
|
||||
}
|
||||
yyparse();
|
||||
fclose(yyin);
|
||||
}
|
||||
else
|
||||
throw Error("IOC file not present");
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
%{
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "IocParserGrammar.hpp"
|
||||
|
||||
#define YY_NO_UNPUT /* Avoids warning */
|
||||
|
||||
|
||||
%}
|
||||
|
||||
%%
|
||||
#.* {}
|
||||
\n {}
|
||||
[Ii][Gg][Nn][Oo][Rr][Ee] {return IGNORE; }
|
||||
[Tt][Oo][Pp] {return TOP; }
|
||||
[Bb][Oo][Tt][Tt][Oo][Mm] {return BOTTOM; }
|
||||
[Ll][Ee][Ff][Tt] {return LEFT; }
|
||||
[Rr][Ii][Gg][Hh][Tt] {return RIGHT; }
|
||||
[Ii][Oo][Pp][Ii][Nn] {return IOPIN; }
|
||||
[Ss][Pp][Aa][Cc][Ee] {return SPACE; }
|
||||
"(" {return PAROUV; }
|
||||
")" {return PARFER; }
|
||||
; {return PTVIRG; }
|
||||
[a-zA-Z][a-zA-Z0-9_]*"\."[0-9]+ {Ioclval.text = strdup(yytext); return IOCID1; }
|
||||
[a-zA-Z][a-zA-Z0-9_]*"\("[0-9]+"\)""\."[0-9]+ {Ioclval.text = strdup(yytext); return IOCID2; }
|
||||
[0-9]+ {Ioclval.value = atoi(yytext); return IOCVALUE; }
|
||||
[ \t]+ {}
|
||||
. {return *yytext;}
|
||||
|
||||
%%
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,673 @@
|
|||
|
||||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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: CDrivDEF.cpp,v 1.15 2006/02/23 14:13:53 xtof Exp $
|
||||
//
|
||||
// x-----------------------------------------------------------------x
|
||||
// | |
|
||||
// | C O R I O L I S |
|
||||
// | Alliance / Hurricane Interface |
|
||||
// | |
|
||||
// | Author : Christophe Alexandre |
|
||||
// | E-mail : Christophe.Alexandre@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./CDrivDEF.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
# include <iostream>
|
||||
# include <functional>
|
||||
|
||||
# include "hurricane/SharedName.h"
|
||||
# include "hurricane/DataBase.h"
|
||||
# include "hurricane/Technology.h"
|
||||
# include "hurricane/Warning.h"
|
||||
# include "hurricane/Cell.h"
|
||||
# include "hurricane/Instance.h"
|
||||
# include "hurricane/Net.h"
|
||||
# include "hurricane/Plug.h"
|
||||
# include "hurricane/Segment.h"
|
||||
# include "hurricane/Segments.h"
|
||||
# include "hurricane/Vertical.h"
|
||||
# include "hurricane/Verticals.h"
|
||||
# include "hurricane/Horizontal.h"
|
||||
# include "hurricane/Horizontals.h"
|
||||
|
||||
# include "hurricane/DataBase.h"
|
||||
# include "LefDef.h"
|
||||
|
||||
# if HAVE_LEDEF
|
||||
# include "hurricane/defwWriter.hpp"
|
||||
# endif
|
||||
|
||||
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
// x-----------------------------------------------------------------x
|
||||
// | Local Definitions |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
# if HAVE_LEFDEF && defined(LEF_ENABLED)
|
||||
#define CHECK_STATUS(status) \
|
||||
if (status) { \
|
||||
defwPrintError(status); \
|
||||
exit(status); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef list<Net*> NetList;
|
||||
|
||||
|
||||
struct LessNet : public binary_function<Net*,Net*,bool> {
|
||||
bool operator () ( Net* net1, Net* net2 );
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// Painstakingly slow, but quick to write.
|
||||
// Implement net1 < net2 (strictly inferior).
|
||||
bool LessNet::operator () ( Net* net1, Net* net2 ) {
|
||||
if ( net1->GetName() == net2->GetName() ) return false;
|
||||
|
||||
const string& name1 = (net1->GetName()._GetSharedName())->_GetSString ();
|
||||
const string& name2 = (net2->GetName()._GetSharedName())->_GetSString ();
|
||||
|
||||
size_t length1 = name1.size ();
|
||||
size_t length2 = name2.size ();
|
||||
size_t index1 = 0;
|
||||
size_t index2 = 0;
|
||||
int number1 = 0;
|
||||
int number2 = 0;
|
||||
|
||||
while ( true ) {
|
||||
if ( isdigit(name1[index1]) ) {
|
||||
for ( number1 = 0 ; isdigit(name1[index1]) && (index1<length1) ; index1++ )
|
||||
number1 = ( number1 * 10 ) + (int)( name1[index1] - '0' );
|
||||
|
||||
if ( isdigit(name2[index2]) ) {
|
||||
for ( number2 = 0 ; isdigit(name2[index2]) && (index2<length2) ; index2++ )
|
||||
number2 = ( number2 * 10 ) + (int)( name2[index2] - '0' );
|
||||
} else
|
||||
return true;
|
||||
|
||||
if ( number1 == number2 ) continue;
|
||||
if ( number1 < number2 ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isdigit(name2[index2]) ) return true;
|
||||
|
||||
if ( name1[index1] == name2[index2] ) {
|
||||
index1++;
|
||||
index2++;
|
||||
if ( (index1<length1) && (index2<length2) )
|
||||
continue;
|
||||
|
||||
if (index1>=length1) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( name1[index1] < name2[index2] ) return true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
# endif // HAVE_LEFDEF
|
||||
|
||||
|
||||
|
||||
|
||||
void defDriver ( const string& cellPath, Cell *cell, unsigned int &saveState )
|
||||
{
|
||||
# if HAVE_LEFDEF && defined(LEF_ENABLED)
|
||||
CDataBase* dataBase = GetCDataBase();
|
||||
if ( dataBase == NULL )
|
||||
throw CError ( NullDataBase, "CDrivDEF()" );
|
||||
|
||||
saveState |= CCatal::State::VIEWS;
|
||||
|
||||
|
||||
int status;
|
||||
IOFILE ccell ( cellPath );
|
||||
ccell.Open ( "w" );
|
||||
FILE* fileDefOut = ccell.GetFile ();
|
||||
|
||||
unsigned defConvertFactor = GetDefConvertFactor(*cell);
|
||||
unsigned lefConvertFactor = GetLefConvertFactor(*(dataBase->GetTechnology()));
|
||||
status = defwInit(fileDefOut, 5, 2, "ON", ":", "[]"
|
||||
, GetString ( cell->GetName() ).c_str ()
|
||||
, GetString(dataBase->GetTechnology()->GetName()).c_str()
|
||||
, NULL, NULL,
|
||||
defConvertFactor);
|
||||
CHECK_STATUS(status);
|
||||
Box abutmentBox(cell->GetAbutmentBox());
|
||||
if (!abutmentBox.IsEmpty())
|
||||
{
|
||||
int xMin = (int)GetValue(abutmentBox.GetXMin()) * defConvertFactor / lefConvertFactor;
|
||||
int yMin = (int)GetValue(abutmentBox.GetYMin()) * defConvertFactor / lefConvertFactor;
|
||||
int xMax = (int)GetValue(abutmentBox.GetXMax()) * defConvertFactor / lefConvertFactor;
|
||||
int yMax = (int)GetValue(abutmentBox.GetYMax()) * defConvertFactor / lefConvertFactor;
|
||||
status = defwDieArea(xMin, yMin, xMax, yMax);
|
||||
CHECK_STATUS(status);
|
||||
}
|
||||
status = defwStartComponents(cell->GetInstances().GetSize());
|
||||
CHECK_STATUS(status);
|
||||
|
||||
for_each_instance(instance, cell->GetInstances())
|
||||
{
|
||||
int x = (int)GetValue(instance->GetAbutmentBox().GetXMin()) * defConvertFactor / lefConvertFactor;
|
||||
int y = (int)GetValue(instance->GetAbutmentBox().GetYMin()) * defConvertFactor / lefConvertFactor;
|
||||
char componentStatus[128];
|
||||
|
||||
|
||||
switch (instance->GetPlacementStatus())
|
||||
{
|
||||
case Instance::PlacementStatus::UNPLACED:
|
||||
strcpy(componentStatus, "UNPLACED");
|
||||
break;
|
||||
case Instance::PlacementStatus::PLACED:
|
||||
strcpy(componentStatus, "PLACED");
|
||||
break;
|
||||
case Instance::PlacementStatus::FIXED:
|
||||
strcpy(componentStatus, "FIXED");
|
||||
break;
|
||||
default:
|
||||
throw Error ("Unknown instance placement status");
|
||||
}
|
||||
status = defwComponent(GetString(instance->GetName()).c_str(),
|
||||
GetString(instance->GetMasterCell()->GetName()).c_str(),
|
||||
0, NULL, NULL, NULL, NULL, NULL,
|
||||
0, NULL, NULL, NULL, NULL,
|
||||
componentStatus,
|
||||
x, y, 0, 0.0, NULL,
|
||||
0, 0, 0, 0);
|
||||
CHECK_STATUS(status);
|
||||
end_for;
|
||||
}
|
||||
status = defwEndComponents();
|
||||
CHECK_STATUS(status);
|
||||
|
||||
//PINS
|
||||
// le nombre de pins est egal au nombre de pins de la cellule
|
||||
unsigned numPins = cell->GetPins().GetSize();
|
||||
// + le nombre de nets externes et les nets POWER/GROUND/CLOCK sans pins :
|
||||
for_each_net ( net, cell->GetNets() )
|
||||
{
|
||||
if ( ( ( net->GetType() == Net::Type::POWER ) || ( net->GetType() == Net::Type::GROUND ) || ( net->IsExternal() ) )
|
||||
&& ( net->GetPins().GetSize() == 0 ) )
|
||||
numPins++;
|
||||
end_for
|
||||
}
|
||||
status = defwStartPins(numPins);
|
||||
CHECK_STATUS(status);
|
||||
|
||||
for_each_pin( pin, cell->GetPins() )
|
||||
{
|
||||
Net *net = pin->GetNet();
|
||||
if ( ! net->IsGlobal() && ! net->IsExternal() )
|
||||
throw Warning ( "Pin on non global and non external net : " + GetString ( net) );
|
||||
string dir;
|
||||
string use;
|
||||
string place;
|
||||
string layer;
|
||||
const char* pinName = GetString ( pin->GetName() ).c_str();
|
||||
const char* netName = GetString ( net->GetName() ).c_str();
|
||||
|
||||
switch ( net->GetDirection() )
|
||||
{
|
||||
case Net::Direction::UNDEFINED:
|
||||
break;
|
||||
case Net::Direction::IN:
|
||||
dir = string ( "INPUT" );
|
||||
break;
|
||||
case Net::Direction::OUT:
|
||||
dir = string ( "OUTPUT" );
|
||||
break;
|
||||
case Net::Direction::INOUT:
|
||||
dir = string ( "INOUT" );
|
||||
break;
|
||||
default:
|
||||
throw Error ( "Wrong net Direction" );
|
||||
}
|
||||
|
||||
switch ( net->GetType() )
|
||||
{
|
||||
case Net::Type::UNDEFINED:
|
||||
break;
|
||||
case Net::Type::LOGICAL:
|
||||
use = string ( "SIGNAL" );
|
||||
break;
|
||||
case Net::Type::POWER:
|
||||
use = string ( "POWER" );
|
||||
break;
|
||||
case Net::Type::GROUND:
|
||||
use = string ( "GROUND" );
|
||||
break;
|
||||
case Net::Type::CLOCK:
|
||||
use = string ( "CLOCK" );
|
||||
break;
|
||||
default:
|
||||
throw Error ( "Wrong net Type" );
|
||||
}
|
||||
|
||||
switch ( pin->GetPlacementStatus() )
|
||||
{
|
||||
case Pin::PlacementStatus::UNPLACED:
|
||||
break;
|
||||
case Pin::PlacementStatus::PLACED:
|
||||
place = string ( "PLACED" );
|
||||
layer = GetString ( pin->GetLayer()->GetName() );
|
||||
break;
|
||||
case Pin::PlacementStatus::FIXED:
|
||||
place = string ( "FIXED" );
|
||||
layer = GetString ( pin->GetLayer()->GetName() );
|
||||
break;
|
||||
default:
|
||||
throw Error ( "Wrong pin PlacementStatus" );
|
||||
}
|
||||
|
||||
status = defwPin ( pinName, netName,
|
||||
( net->IsGlobal() ) ? 1 : 0,
|
||||
( net->GetDirection() == Net::Direction::UNDEFINED ) ? NULL : dir.c_str(),
|
||||
( net->GetType() == Net::Type::UNDEFINED ) ? NULL : use.c_str(),
|
||||
( pin->GetPlacementStatus() == Pin::PlacementStatus::UNPLACED ) ? NULL : place.c_str(),
|
||||
( pin->GetPlacementStatus() == Pin::PlacementStatus::UNPLACED ) ? 0 : (int) pin->GetX(),
|
||||
( pin->GetPlacementStatus() == Pin::PlacementStatus::UNPLACED ) ? 0 : (int) pin->GetY(),
|
||||
0,
|
||||
( pin->GetPlacementStatus() == Pin::PlacementStatus::UNPLACED ) ? NULL : layer.c_str(),
|
||||
( pin->GetPlacementStatus() == Pin::PlacementStatus::UNPLACED ) ? 0 : - (int) pin->GetHalfWidth(),
|
||||
( pin->GetPlacementStatus() == Pin::PlacementStatus::UNPLACED ) ? 0 : - (int) pin->GetHalfHeight(),
|
||||
( pin->GetPlacementStatus() == Pin::PlacementStatus::UNPLACED ) ? 0 : (int) pin->GetHalfWidth(),
|
||||
( pin->GetPlacementStatus() == Pin::PlacementStatus::UNPLACED ) ? 0 : (int) pin->GetHalfHeight()
|
||||
);
|
||||
CHECK_STATUS(status);
|
||||
|
||||
end_for
|
||||
}
|
||||
|
||||
for_each_net ( net, cell->GetNets() )
|
||||
{
|
||||
if ( ( net->GetType() == Net::Type::POWER ) && ( net->GetPins().GetSize() == 0 ) )
|
||||
{
|
||||
string dir;
|
||||
string use;
|
||||
const char* pinName = GetString ( GetPort(*net) ).c_str();
|
||||
const char* netName = GetString ( net->GetName() ).c_str();
|
||||
switch ( net->GetDirection() )
|
||||
{
|
||||
case Net::Direction::UNDEFINED:
|
||||
break;
|
||||
case Net::Direction::IN:
|
||||
dir = string ( "INPUT" );
|
||||
break;
|
||||
case Net::Direction::OUT:
|
||||
dir = string ( "OUTPUT" );
|
||||
break;
|
||||
case Net::Direction::INOUT:
|
||||
dir = string ( "INOUT" );
|
||||
break;
|
||||
default:
|
||||
throw Error ( "Wrong net direction" );
|
||||
}
|
||||
use = string ( "POWER" );
|
||||
status = defwPin ( pinName, netName,
|
||||
net->IsGlobal() ? 1 : 0, ( net->GetDirection() == Net::Direction::UNDEFINED ) ? NULL : dir.c_str(),
|
||||
use.c_str(), NULL, 0, 0, 0, NULL, 0, 0, 0, 0);
|
||||
CHECK_STATUS(status);
|
||||
}
|
||||
else if ( ( net->GetType() == Net::Type::GROUND ) && ( net->GetPins().GetSize() == 0 ) )
|
||||
{
|
||||
string dir;
|
||||
string use;
|
||||
const char* pinName = GetString ( GetPort(*net) ).c_str();
|
||||
const char* netName = GetString ( net->GetName() ).c_str();
|
||||
switch ( net->GetDirection() )
|
||||
{
|
||||
case Net::Direction::UNDEFINED:
|
||||
break;
|
||||
case Net::Direction::IN:
|
||||
dir = string ( "INPUT" );
|
||||
break;
|
||||
case Net::Direction::OUT:
|
||||
dir = string ( "OUTPUT" );
|
||||
break;
|
||||
case Net::Direction::INOUT:
|
||||
dir = string ( "INOUT" );
|
||||
break;
|
||||
default:
|
||||
throw Error ( "Wrong net direction" );
|
||||
}
|
||||
use = string ( "GROUND" );
|
||||
status = defwPin ( pinName, netName,
|
||||
net->IsGlobal() ? 1 : 0, ( net->GetDirection() == Net::Direction::UNDEFINED ) ? NULL : dir.c_str(),
|
||||
use.c_str(), NULL, 0, 0, 0, NULL, 0, 0, 0, 0);
|
||||
CHECK_STATUS(status);
|
||||
}
|
||||
else if ( net->IsExternal() && ( net->GetPins().GetSize() == 0 ) )
|
||||
{
|
||||
string dir;
|
||||
string use;
|
||||
const char* pinName = GetString ( GetPort(*net) ).c_str();
|
||||
const char* netName = GetString ( net->GetName() ).c_str();
|
||||
switch ( net->GetDirection() )
|
||||
{
|
||||
case Net::Direction::UNDEFINED:
|
||||
break;
|
||||
case Net::Direction::IN:
|
||||
dir = string ( "INPUT" );
|
||||
break;
|
||||
case Net::Direction::OUT:
|
||||
dir = string ( "OUTPUT" );
|
||||
break;
|
||||
case Net::Direction::INOUT:
|
||||
dir = string ( "INOUT" );
|
||||
break;
|
||||
default:
|
||||
throw Error ( "Wrong net direction" );
|
||||
}
|
||||
switch ( net->GetType() )
|
||||
{
|
||||
case Net::Type::UNDEFINED:
|
||||
break;
|
||||
case Net::Type::LOGICAL:
|
||||
use = string ( "SIGNAL" );
|
||||
break;
|
||||
case Net::Type::CLOCK:
|
||||
use = string ( "CLOCK" );
|
||||
break;
|
||||
default:
|
||||
throw Error ( "Wrong type or shouldn't be that type" );
|
||||
}
|
||||
status = defwPin ( pinName, netName,
|
||||
net->IsGlobal() ? 1 : 0, ( net->GetDirection() == Net::Direction::UNDEFINED ) ? NULL : dir.c_str(),
|
||||
( net->GetType() == Net::Type::UNDEFINED ) ? NULL : use.c_str(), NULL, 0, 0, 0, NULL, 0, 0, 0, 0);
|
||||
CHECK_STATUS(status);
|
||||
}
|
||||
end_for
|
||||
}
|
||||
|
||||
status = defwEndPins();
|
||||
CHECK_STATUS(status);
|
||||
|
||||
unsigned netCpt = 0;
|
||||
unsigned specialNetCpt = 0;
|
||||
for_each_net(net, cell->GetNets())
|
||||
{
|
||||
if (net->IsGlobal())
|
||||
{
|
||||
if (net->IsSupply())
|
||||
++specialNetCpt;
|
||||
else
|
||||
{
|
||||
cerr << "Strange Net:" << net
|
||||
<< "Global net but no type ...."
|
||||
<< endl;
|
||||
cerr << net->GetType() << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (net->IsClock())
|
||||
++specialNetCpt;
|
||||
else
|
||||
++netCpt;
|
||||
}
|
||||
end_for;
|
||||
}
|
||||
|
||||
if (specialNetCpt > 0)
|
||||
{
|
||||
status = defwStartSpecialNets(specialNetCpt);
|
||||
CHECK_STATUS(status);
|
||||
for_each_net(net, cell->GetNets())
|
||||
{
|
||||
if (net->IsClock())
|
||||
{
|
||||
status = defwSpecialNet(GetString(net->GetName()).c_str());
|
||||
CHECK_STATUS(status);
|
||||
for_each_plug(plug, net->GetPlugs())
|
||||
{
|
||||
Instance* instance = plug->GetInstance();
|
||||
Net* masterNet = plug->GetMasterNet();
|
||||
const char* instanceName = GetString(instance->GetName()).c_str();
|
||||
status = defwSpecialNetConnection(instanceName,
|
||||
GetString(masterNet->GetName()).c_str(), 0);
|
||||
CHECK_STATUS(status);
|
||||
end_for;
|
||||
}
|
||||
if (!net->GetSegments().IsEmpty())
|
||||
{
|
||||
status = defwSpecialNetPathStart("ROUTED");
|
||||
CHECK_STATUS(status);
|
||||
Segments segments = net->GetSegments();
|
||||
SegmentLocator segmentLocator = segments.GetLocator();
|
||||
Segment* segment = segmentLocator.GetElement();
|
||||
status =
|
||||
defwSpecialNetPathLayer(GetString(segment->GetLayer()->GetName()).c_str());
|
||||
CHECK_STATUS(status);
|
||||
const char* coorX[2];
|
||||
const char* coorY[2];
|
||||
coorX[0] = strdup((GetString(segment->GetSourceX())).c_str());
|
||||
coorY[0] = strdup((GetString(segment->GetSourceY())).c_str());
|
||||
coorX[1] = strdup((GetString(segment->GetTargetX())).c_str());
|
||||
coorY[1] = strdup((GetString(segment->GetTargetY())).c_str());
|
||||
status = defwSpecialNetPathPoint(2, coorX, coorY);
|
||||
CHECK_STATUS(status);
|
||||
free((char*)coorX[0]);
|
||||
free((char*)coorX[1]);
|
||||
free((char*)coorY[0]);
|
||||
free((char*)coorY[1]);
|
||||
status = defwSpecialNetPathEnd();
|
||||
CHECK_STATUS(status);
|
||||
segmentLocator.Progress();
|
||||
while (segmentLocator.IsValid())
|
||||
{
|
||||
status = defwSpecialNetPathStart("ROUTED");
|
||||
CHECK_STATUS(status);
|
||||
Segment* segment = segmentLocator.GetElement();
|
||||
status =
|
||||
defwSpecialNetPathLayer(GetString(segment->GetLayer()->GetName()).c_str());
|
||||
const char* coorX[2];
|
||||
const char* coorY[2];
|
||||
coorX[0] = strdup((GetString(segment->GetSourceX())).c_str());
|
||||
coorY[0] = strdup((GetString(segment->GetSourceY())).c_str());
|
||||
coorX[1] = strdup((GetString(segment->GetTargetX())).c_str());
|
||||
coorY[1] = strdup((GetString(segment->GetTargetY())).c_str());
|
||||
status = defwSpecialNetPathPoint(2, coorX, coorY);
|
||||
CHECK_STATUS(status);
|
||||
free((char*)coorX[0]);
|
||||
free((char*)coorX[1]);
|
||||
free((char*)coorY[0]);
|
||||
free((char*)coorY[1]);
|
||||
status = defwSpecialNetPathEnd();
|
||||
CHECK_STATUS(status);
|
||||
segmentLocator.Progress();
|
||||
}
|
||||
}
|
||||
status = defwSpecialNetUse("CLOCK");
|
||||
CHECK_STATUS(status);
|
||||
status = defwSpecialNetEndOneNet();
|
||||
CHECK_STATUS(status);
|
||||
}
|
||||
if (net->IsGlobal() && (net->IsSupply()))
|
||||
{
|
||||
status = defwSpecialNet(GetString(net->GetName()).c_str());
|
||||
CHECK_STATUS(status);
|
||||
for_each_instance(instance, cell->GetInstances())
|
||||
{
|
||||
Cell* model = instance->GetMasterCell();
|
||||
for_each_net(modelnet, model->GetExternalNets())
|
||||
{
|
||||
if (modelnet->IsGlobal() &&
|
||||
((modelnet->IsGround() && net->IsGround())
|
||||
|| (modelnet->IsPower() && net->IsPower()))
|
||||
)
|
||||
{
|
||||
status = defwSpecialNetConnection(
|
||||
GetString(instance->GetName()).c_str(),
|
||||
GetString(modelnet->GetName()).c_str(),
|
||||
0);
|
||||
CHECK_STATUS(status);
|
||||
}
|
||||
end_for;
|
||||
}
|
||||
end_for;
|
||||
}
|
||||
if (net->IsGround())
|
||||
status = defwSpecialNetUse("GROUND");
|
||||
else if (net->IsPower())
|
||||
status = defwSpecialNetUse("POWER");
|
||||
else
|
||||
throw Error("No Supply type");
|
||||
CHECK_STATUS(status);
|
||||
status = defwSpecialNetEndOneNet();
|
||||
CHECK_STATUS(status);
|
||||
}
|
||||
end_for;
|
||||
}
|
||||
status = defwEndSpecialNets();
|
||||
CHECK_STATUS(status);
|
||||
}
|
||||
status = defwStartNets(netCpt);
|
||||
CHECK_STATUS(status);
|
||||
for_each_net(net, cell->GetNets())
|
||||
{
|
||||
if (!net->IsGlobal() && !net->IsClock())
|
||||
{
|
||||
status = defwNet(GetString(net->GetName()).c_str());
|
||||
CHECK_STATUS(status);
|
||||
for_each_plug(plug, net->GetPlugs())
|
||||
{
|
||||
Instance* instance = plug->GetInstance();
|
||||
Net* masterNet = plug->GetMasterNet();
|
||||
const char* instanceName = GetString(instance->GetName()).c_str();
|
||||
status = defwNetConnection(instanceName,
|
||||
GetString(masterNet->GetName()).c_str(), 0);
|
||||
CHECK_STATUS(status);
|
||||
end_for;
|
||||
}
|
||||
if (!net->GetSegments().IsEmpty())
|
||||
{
|
||||
status = defwNetPathStart("ROUTED");
|
||||
CHECK_STATUS(status);
|
||||
Segments segments = net->GetSegments();
|
||||
SegmentLocator segmentLocator = segments.GetLocator();
|
||||
Segment* segment = segmentLocator.GetElement();
|
||||
status =
|
||||
defwNetPathLayer(GetString(segment->GetLayer()->GetName()).c_str(), 1, NULL);
|
||||
CHECK_STATUS(status);
|
||||
const char* coorX[2];
|
||||
const char* coorY[2];
|
||||
const char* coorValue[2];
|
||||
coorX[0] = strdup((GetString(segment->GetSourceX())).c_str());
|
||||
coorY[0] = strdup((GetString(segment->GetSourceY())).c_str());
|
||||
coorValue[0] = NULL;
|
||||
coorX[1] = strdup((GetString(segment->GetTargetX())).c_str());
|
||||
coorY[1] = strdup((GetString(segment->GetTargetY())).c_str());
|
||||
coorValue[1] = NULL;
|
||||
status = defwNetPathPoint(2, coorX, coorY, coorValue);
|
||||
CHECK_STATUS(status);
|
||||
free((char*)coorX[0]);
|
||||
free((char*)coorX[1]);
|
||||
free((char*)coorY[0]);
|
||||
free((char*)coorY[1]);
|
||||
status = defwNetPathEnd();
|
||||
CHECK_STATUS(status);
|
||||
segmentLocator.Progress();
|
||||
while (segmentLocator.IsValid())
|
||||
{
|
||||
status = defwNetPathStart("ROUTED");
|
||||
CHECK_STATUS(status);
|
||||
Segment* segment = segmentLocator.GetElement();
|
||||
status =
|
||||
defwNetPathLayer(GetString(segment->GetLayer()->GetName()).c_str(), 1, NULL);
|
||||
const char* coorX[2];
|
||||
const char* coorY[2];
|
||||
const char* coorValue[2];
|
||||
coorX[0] = strdup((GetString(segment->GetSourceX())).c_str());
|
||||
coorY[0] = strdup((GetString(segment->GetSourceY())).c_str());
|
||||
coorValue[0] = NULL;
|
||||
coorX[1] = strdup((GetString(segment->GetTargetX())).c_str());
|
||||
coorY[1] = strdup((GetString(segment->GetTargetY())).c_str());
|
||||
coorValue[1] = NULL;
|
||||
status = defwNetPathPoint(2, coorX, coorY, coorValue);
|
||||
CHECK_STATUS(status);
|
||||
free((char*)coorX[0]);
|
||||
free((char*)coorX[1]);
|
||||
free((char*)coorY[0]);
|
||||
free((char*)coorY[1]);
|
||||
status = defwNetPathEnd();
|
||||
CHECK_STATUS(status);
|
||||
segmentLocator.Progress();
|
||||
}
|
||||
}
|
||||
status = defwNetEndOneNet();
|
||||
CHECK_STATUS(status);
|
||||
}
|
||||
end_for;
|
||||
}
|
||||
status = defwEndNets();
|
||||
CHECK_STATUS(status);
|
||||
|
||||
status = defwEnd();
|
||||
CHECK_STATUS(status);
|
||||
|
||||
ccell.Close ();
|
||||
# else // HAVE_LEFDEF
|
||||
cerr << "\nDummy LEF driver call for \"" << cellPath << "\"." << endl;
|
||||
# endif // HAVE_LEFDEF
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
|
@ -0,0 +1,712 @@
|
|||
|
||||
// -*- 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 : Christophe Alexandre |
|
||||
// | E-mail : Christophe.Alexandre@lip6.fr |
|
||||
// | |
|
||||
// | Modify By : Damien Dupuis |
|
||||
// | E-mail : Damien.Dupuis@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./DefParser.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// | * 2007-03-26 : To be compliant with LEFDEF 5.6 |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Component.h"
|
||||
#include "hurricane/Plug.h"
|
||||
#include "hurricane/Contact.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Pin.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Instance.h"
|
||||
|
||||
#include "crlcore/Utilities.h"
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
#include "crlcore/NetExtension.h"
|
||||
#include "crlcore/LefDefExtension.h"
|
||||
#include "LefDef.h"
|
||||
|
||||
#if HAVE_LEFDEF
|
||||
# include "defrReader.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::Name;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::Contact;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::Pin;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Instance;
|
||||
using Hurricane::tab;
|
||||
|
||||
using namespace CRL;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Module Global Variables.
|
||||
|
||||
|
||||
AllianceFramework* __framework = NULL;
|
||||
Technology* __technology = NULL;
|
||||
Cell* __design;
|
||||
long __defUserData = 0;
|
||||
unsigned int __defConvertFactor = 1;
|
||||
unsigned int __lefConvertFactor = 1;
|
||||
|
||||
|
||||
#if HAVE_LEFDEF
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Module Global Functions.
|
||||
|
||||
|
||||
Cell* verifyDesign ()
|
||||
{
|
||||
if ( !__design )
|
||||
throw Error ( "Empty DEF Design." );
|
||||
return __design;
|
||||
}
|
||||
|
||||
|
||||
Instance* verifyInstance ( const Name& name )
|
||||
{
|
||||
Instance* instance = verifyDesign()->getInstance(name);
|
||||
if ( !instance )
|
||||
throw Error ( "No instance " + getString(name) + " in DEF design." );
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
Plug* verifyPlug ( const Name& instanceName, const Name& netName )
|
||||
{
|
||||
Instance* instance = verifyInstance ( instanceName );
|
||||
Cell* model = instance->getMasterCell ();
|
||||
Plug* plug = instance->getPlug ( model->getNet(netName) );
|
||||
if ( !plug )
|
||||
throw Error ( "No Plug " + getString(netName) + " in instance " + getString(instanceName) );
|
||||
return plug;
|
||||
}
|
||||
|
||||
|
||||
Net* verifyNet ( const Name& instanceName, const Name& netName )
|
||||
{
|
||||
Instance* instance = verifyInstance ( instanceName );
|
||||
Cell* model = instance->getMasterCell ();
|
||||
Net* modelNet = model->getNet ( netName );
|
||||
if ( !modelNet )
|
||||
throw Error ( "No net " + getString(netName) + " in cell " + getString(model->getName()) );
|
||||
return modelNet;
|
||||
}
|
||||
|
||||
|
||||
Transformation::Orientation def2Transformation ( int orient )
|
||||
{
|
||||
// Note : the codes between DEF & Hurricane matches.
|
||||
// This function is just to be clear.
|
||||
switch ( orient ) {
|
||||
default:
|
||||
case 0: break; // N, default.
|
||||
case 1: return Transformation::Orientation::R1; // W
|
||||
case 2: return Transformation::Orientation::R2; // S
|
||||
case 3: return Transformation::Orientation::R3; // E
|
||||
case 4: return Transformation::Orientation::MX; // FN
|
||||
case 5: return Transformation::Orientation::XR; // FW
|
||||
case 6: return Transformation::Orientation::MY; // FS
|
||||
case 7: return Transformation::Orientation::YR; // FE
|
||||
}
|
||||
return Transformation::Orientation::ID;
|
||||
}
|
||||
|
||||
|
||||
Transformation getTransformation ( const Box& abox
|
||||
, const DbU::Unit& x
|
||||
, const DbU::Unit& y
|
||||
, const Transformation::Orientation& orientation
|
||||
)
|
||||
{
|
||||
switch (orientation) {
|
||||
case Transformation::Orientation::ID:
|
||||
return Transformation ( x, y, orientation );
|
||||
case Transformation::Orientation::R1:
|
||||
return Transformation ( x, y+abox.getWidth(), orientation );
|
||||
case Transformation::Orientation::R2:
|
||||
return Transformation ( x+abox.getWidth(), y+abox.getHeight(), orientation );
|
||||
case Transformation::Orientation::R3:
|
||||
return Transformation ( x+abox.getHeight(), y, orientation );
|
||||
case Transformation::Orientation::MX:
|
||||
return Transformation ( x+abox.getWidth(), y, orientation );
|
||||
case Transformation::Orientation::XR:
|
||||
return Transformation ( x+abox.getHeight(), y+abox.getWidth(), orientation );
|
||||
case Transformation::Orientation::MY:
|
||||
return Transformation ( x, y+abox.getHeight(), orientation );
|
||||
case Transformation::Orientation::YR:
|
||||
return Transformation ( x+abox.getHeight(), y+abox.getWidth(), orientation );
|
||||
}
|
||||
return Transformation ();
|
||||
}
|
||||
|
||||
|
||||
void defUserDataError ()
|
||||
{
|
||||
cerr << Warning("defParser(): returned DEF user data is not correct.") << endl;
|
||||
}
|
||||
|
||||
|
||||
void checkCbType ( defrCallbackType_e cbType )
|
||||
{
|
||||
if ( (cbType < 0) || (cbType > defrDesignEndCbkType) )
|
||||
cerr << Warning("defParser(): callback type is out of bounds.") << endl;
|
||||
}
|
||||
|
||||
|
||||
int cbDesignName ( defrCallbackType_e cbType, const char* name, defiUserData ud )
|
||||
{
|
||||
checkCbType ( cbType );
|
||||
if ( (long)ud != __defUserData ) defUserDataError ();
|
||||
|
||||
if ( !name || (name[0] == (char)0) ) {
|
||||
cerr << Warning("defParser(): design name empty, aborting.") << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cbDone ( defrCallbackType_e cbType, void* dummy, defiUserData ud )
|
||||
{
|
||||
checkCbType ( cbType );
|
||||
if ( (long)ud != __defUserData ) defUserDataError ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cbUnits ( defrCallbackType_e cbType, double value, defiUserData ud )
|
||||
{
|
||||
checkCbType ( cbType );
|
||||
if ( (long)ud != __defUserData ) defUserDataError ();
|
||||
|
||||
__defConvertFactor = (unsigned)value;
|
||||
LefDefExtension::setDefDbuPerMicron ( verifyDesign(), __defConvertFactor );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cbComponent ( defrCallbackType_e cbType, defiComponent* component, defiUserData ud )
|
||||
{
|
||||
checkCbType ( cbType );
|
||||
if ( (long)ud != __defUserData ) defUserDataError ();
|
||||
|
||||
Cell* model = __framework->getCell ( component->defiComponent::name(), Catalog::State::Views );
|
||||
if ( !model )
|
||||
throw Error ( "Unkown cell: " + string(component->defiComponent::name()) );
|
||||
|
||||
Transformation instancePosition;
|
||||
Instance::PlacementStatus placementStatus ( Instance::PlacementStatus::UNPLACED );
|
||||
if ( component->defiComponent::isPlaced() || component->defiComponent::isFixed() ) {
|
||||
if ( component->defiComponent::isPlaced() )
|
||||
placementStatus = Instance::PlacementStatus::PLACED;
|
||||
else
|
||||
placementStatus = Instance::PlacementStatus::FIXED;
|
||||
instancePosition = getTransformation
|
||||
( model->getAbutmentBox()
|
||||
, DbU::lambda((double)component->defiComponent::placementX() * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
, DbU::lambda((double)component->defiComponent::placementY() * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
, def2Transformation ( component->defiComponent::placementOrient() )
|
||||
);
|
||||
}
|
||||
|
||||
Instance::create ( verifyDesign()
|
||||
, Name(component->defiComponent::id())
|
||||
, model, instancePosition
|
||||
, placementStatus
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cbNet ( defrCallbackType_e cbType, defiNet* defnet, defiUserData ud )
|
||||
{
|
||||
checkCbType ( cbType );
|
||||
if ( (long)ud != __defUserData ) defUserDataError ();
|
||||
if ( cbType != defrNetCbkType ) {
|
||||
cerr << Warning("defParser::cbNet(): Bogus net type.") << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Net* net;
|
||||
Net* tryNet = verifyDesign()->getNet ( Name(defnet->defiNet::name()) );
|
||||
if ( tryNet && !tryNet->isExternal() ) {
|
||||
cerr << Warning("defParser(): Net \"%s\" already exist.",defnet->defiNet::name()) << endl;
|
||||
return 1;
|
||||
}
|
||||
if ( !tryNet ) {
|
||||
net = Net::create ( verifyDesign(), defnet->defiNet::name() );
|
||||
net->setExternal ( false );
|
||||
net->setType ( Net::Type::LOGICAL );
|
||||
} else
|
||||
net = tryNet;
|
||||
|
||||
for ( int i=0 ; i < defnet->numConnections() ; i++ ) {
|
||||
if ( !strcmp(defnet->instance(i),"PIN") ) continue;
|
||||
Plug* plug = verifyPlug ( Name(defnet->instance(i)), Name(defnet->pin(i)) );
|
||||
plug->setNet ( net );
|
||||
}
|
||||
|
||||
for ( int i=0 ; i < defnet->numWires() ; i++ ) {
|
||||
defiWire* wire = defnet->wire(i);
|
||||
for ( int j=0 ; j < wire->numPaths() ; j++ ) {
|
||||
defiPath* p = wire->path(j);
|
||||
p->initTraverse();
|
||||
int path = 0;
|
||||
int x0,y0,x1,y1 = 0;
|
||||
bool hasFirstPoint = false;
|
||||
Layer* layer = NULL;
|
||||
Component* source = NULL;
|
||||
Component* target = NULL;
|
||||
Component* lastComponent = NULL;
|
||||
DbU::Unit layerMinWidth = 0;
|
||||
|
||||
while ( (path = static_cast<int>(p->next())) != DEFIPATH_DONE ) {
|
||||
switch ( path ) {
|
||||
case DEFIPATH_LAYER:
|
||||
layer = __technology->getLayer( Name(p->getLayer()) );
|
||||
if ( !layer )
|
||||
throw Error ( "defParser(): Unknown layer \"%s\".", p->getLayer() );
|
||||
layerMinWidth = layer->getMinimalSize();
|
||||
break;
|
||||
case DEFIPATH_VIA:
|
||||
#if 0
|
||||
{
|
||||
Contact* lastContact = NULL;
|
||||
layer = __technology()->getLayer ( Name(p->getVia()) );
|
||||
if ( !layer )
|
||||
throw Error ( "defParser(): Unknown layer \"%s\".", p->getLayer() );
|
||||
if ( !lastComponent )
|
||||
throw Error( "defParser(): Missing last path component." );
|
||||
lastContact = dynamic_cast<Contact*>(lastComponent);
|
||||
if ( !lastContact )
|
||||
throw Error( "defParser(): Missing last path contact." );
|
||||
lastContact->setLayer ( layer );
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case DEFIPATH_POINT:
|
||||
{
|
||||
if ( !hasFirstPoint ) {
|
||||
p->getPoint ( &x0, &y0 );
|
||||
lastComponent = Contact::create
|
||||
( net, layer
|
||||
, DbU::lambda((double)x0 * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
, DbU::lambda((double)y0 * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
);
|
||||
source = lastComponent;
|
||||
hasFirstPoint = true;
|
||||
} else {
|
||||
p->getPoint ( &x1, &y1 );
|
||||
lastComponent = Contact::create
|
||||
( net, layer
|
||||
, DbU::lambda((double)x1 * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
, DbU::lambda((double)y1 * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
);
|
||||
target = lastComponent;
|
||||
if ( x0 == x1 ) {
|
||||
lastComponent = Vertical::create
|
||||
( source, target, layer, source->getX(), layerMinWidth );
|
||||
source = lastComponent;
|
||||
} else {
|
||||
if (y0 == y1) {
|
||||
lastComponent = Horizontal::create
|
||||
( source, target, layer, source->getY(), layerMinWidth );
|
||||
source = lastComponent;
|
||||
} else {
|
||||
throw Error ( "defParser(): Diagonal segments are not supporteds." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cbSpecialNet ( defrCallbackType_e cbType, defiNet* defnet, defiUserData ud )
|
||||
{
|
||||
checkCbType ( cbType );
|
||||
if ( (long)ud != __defUserData ) defUserDataError ();
|
||||
|
||||
if ( !defnet->hasUse() )
|
||||
throw Error ( "defParser(): Special net with no use precised." );
|
||||
|
||||
bool netCreated = false;
|
||||
Net* net = verifyDesign()->getNet ( Name(defnet->defiNet::name()) );
|
||||
if ( !net ) {
|
||||
net = Net::create ( verifyDesign(), defnet->defiNet::name() );
|
||||
if ( defnet->defiNet::hasUse() ) {
|
||||
if ( !strcmp(defnet->defiNet::use(),"GROUND") ) {
|
||||
net->setGlobal ( true );
|
||||
net->setType ( Net::Type::GROUND );
|
||||
}
|
||||
if ( !strcmp(defnet->defiNet::use(),"POWER") ) {
|
||||
net->setGlobal ( true );
|
||||
net->setType ( Net::Type::POWER );
|
||||
}
|
||||
if ( !strcmp(defnet->defiNet::use(),"CLOCK") ) {
|
||||
net->setType ( Net::Type::CLOCK );
|
||||
}
|
||||
}
|
||||
netCreated = true;
|
||||
}
|
||||
|
||||
if ( !strcasecmp(defnet->use(), "POWER") ) {
|
||||
net->setGlobal ( true );
|
||||
if ( !net->isPower() )
|
||||
throw Error ( "defParser(): Net use discrepency, %s is not power."
|
||||
, getString(net).c_str() );
|
||||
|
||||
for ( int i = 0 ; i < defnet->numConnections() ; i++ ) {
|
||||
Net* modelNet = verifyNet ( Name(defnet->instance(i)), Name(defnet->pin(i)) );
|
||||
if ( !modelNet->isGlobal() )
|
||||
throw Error( "defReader(): %s is not global.", getString(modelNet).c_str() );
|
||||
|
||||
if ( !modelNet->isPower() )
|
||||
throw Error ( "defParser(): Net use discrepency, %s is not power."
|
||||
, getString(modelNet).c_str() );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !strcasecmp(defnet->use(), "GROUND") ) {
|
||||
net->setGlobal ( true );
|
||||
if ( !net->isGround() )
|
||||
throw Error ( "defParser(): Net use discrepency, %s is not ground."
|
||||
, getString(net).c_str() );
|
||||
|
||||
for ( int i = 0 ; i < defnet->numConnections() ; i++ ) {
|
||||
Net* modelNet = verifyNet ( Name(defnet->instance(i)), Name(defnet->pin(i)) );
|
||||
if ( !modelNet->isGlobal() )
|
||||
throw Error( "defReader(): %s is not global.", getString(modelNet).c_str() );
|
||||
|
||||
if ( !modelNet->isGround() )
|
||||
throw Error ( "defParser(): Net use discrepency, %s is not ground."
|
||||
, getString(modelNet).c_str() );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !strcasecmp(defnet->use(), "CLOCK") ) {
|
||||
if ( netCreated ) {
|
||||
net->setType ( Net::Type::CLOCK );
|
||||
} else if ( !net->isClock() )
|
||||
throw Error ( "defParser(): Net use discrepency, %s is not clock."
|
||||
, getString(net).c_str() );
|
||||
|
||||
for ( int i=0 ; i < defnet->numConnections() ; i++ ) {
|
||||
Plug* plug = verifyPlug ( Name(defnet->instance(i)), Name(defnet->pin(i)) );
|
||||
plug->setNet ( net );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
cerr << Warning("defReader(): Special net with unrecognized use.") << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int cls ( defrCallbackType_e cbType, void* cl, defiUserData ud )
|
||||
{
|
||||
defiBox* box;
|
||||
defiPin* pin;
|
||||
defiRow* row;
|
||||
|
||||
checkCbType ( cbType );
|
||||
if ( (long)ud != __defUserData ) defUserDataError ();
|
||||
|
||||
switch ( cbType ) {
|
||||
case defrDieAreaCbkType :
|
||||
{
|
||||
box = (defiBox*)cl;
|
||||
|
||||
verifyDesign()->setAbutmentBox
|
||||
( Box ( DbU::lambda((double)box->xl() * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
, DbU::lambda((double)box->yl() * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
, DbU::lambda((double)box->xh() * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
, DbU::lambda((double)box->yh() * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
));
|
||||
break;
|
||||
}
|
||||
case defrPinCbkType :
|
||||
{
|
||||
pin = (defiPin*)cl;
|
||||
|
||||
Net::Direction pinDirection;
|
||||
if ( pin->defiPin::hasDirection() ) {
|
||||
if ( !strcmp(pin->defiPin::direction(), "INPUT") )
|
||||
pinDirection = Net::Direction::IN;
|
||||
else if ( !strcmp(pin->defiPin::direction(), "OUTPUT") )
|
||||
pinDirection = Net::Direction::OUT;
|
||||
else if ( !strcmp(pin->defiPin::direction(), "INOUT") )
|
||||
pinDirection = Net::Direction::INOUT;
|
||||
else
|
||||
pinDirection = Net::Direction::UNDEFINED;
|
||||
}
|
||||
|
||||
Net* net = verifyDesign()->getNet ( Name ( pin->defiPin::netName() ) );
|
||||
if ( net ) {
|
||||
if ( !net->isExternal() )
|
||||
throw Error("defReader(): External and Internal Net");
|
||||
if ( pin->defiPin::hasUse() ) {
|
||||
if ( !strcmp(pin->defiPin::use(),"GROUND") && !net->isGround() )
|
||||
throw Error ( "defReader(): Discrepency in Supply Net %s."
|
||||
, getString(net->getName()).c_str() );
|
||||
if ( !strcmp(pin->defiPin::use(),"POWER") && !net->isPower() )
|
||||
throw Error ( "defReader(): Discrepency in Supply Net %s"
|
||||
, getString(net->getName()).c_str() );
|
||||
if ( pinDirection != net->getDirection() )
|
||||
throw Error ( "defReader(): Discrepency in Net direction %s."
|
||||
, getString(net->getName()).c_str() );
|
||||
}
|
||||
NetExtension::addPort ( net, Name ( pin->defiPin::pinName() ) );
|
||||
} else {
|
||||
net = Net::create ( verifyDesign(), Name ( pin->defiPin::netName() ) );
|
||||
if ( pin->defiPin::hasUse() ) {
|
||||
if ( !strcmp(pin->defiPin::use(),"GROUND") ) {
|
||||
net->setGlobal ( true );
|
||||
net->setType ( Net::Type::GROUND );
|
||||
}
|
||||
if ( !strcmp(pin->defiPin::use(),"POWER") ) {
|
||||
net->setGlobal ( true );
|
||||
net->setType ( Net::Type::POWER );
|
||||
}
|
||||
if ( !strcmp(pin->defiPin::use(),"CLOCK") ) {
|
||||
net->setType ( Net::Type::CLOCK );
|
||||
}
|
||||
net->setExternal ( true );
|
||||
net->setDirection ( pinDirection );
|
||||
NetExtension::addPort ( net, Name ( pin->defiPin::pinName() ) );
|
||||
} else {
|
||||
net->setType ( Net::Type::LOGICAL );
|
||||
net->setExternal ( true );
|
||||
net->setDirection ( pinDirection );
|
||||
NetExtension::addPort ( net, Name ( pin->defiPin::pinName() ) );
|
||||
}
|
||||
}
|
||||
if ( pin->hasLayer() ) {
|
||||
int xl, yl, xh, yh;
|
||||
Layer* layer = NULL;
|
||||
DbU::Unit width = 0;
|
||||
DbU::Unit height = 0;
|
||||
DbU::Unit pinX = 0;
|
||||
DbU::Unit pinY = 0;
|
||||
int layerId = 0;
|
||||
Pin::PlacementStatus pinPlacementStatus = Pin::PlacementStatus::UNPLACED;
|
||||
|
||||
if ( pin->numLayer() == 1 )
|
||||
layer = __technology->getLayer( Name(pin->layer(layerId)) );
|
||||
else
|
||||
throw Error ( "defReader(): LEF/DEF 5.6 multi-layer pins are not supported." );
|
||||
if ( !layer )
|
||||
throw Error("defReader(): Unknown Layer %s.",pin->layer(layerId));
|
||||
|
||||
pin->bounds ( layerId, &xl, &yl, &xh, &yh );
|
||||
|
||||
if ( pin->hasPlacement() ) {
|
||||
if ( pin->isPlaced() || pin->isFixed() ) {
|
||||
if ( pin->isPlaced() )
|
||||
pinPlacementStatus = Pin::PlacementStatus::PLACED;
|
||||
else
|
||||
pinPlacementStatus = Pin::PlacementStatus::FIXED;
|
||||
|
||||
pinX = DbU::lambda ( (double)pin->placementX() * (double)__lefConvertFactor / (double)__defConvertFactor );
|
||||
pinY = DbU::lambda ( (double)pin->placementY() * (double)__lefConvertFactor / (double)__defConvertFactor );
|
||||
switch ( pin->orient() ) {
|
||||
case 0:
|
||||
case 4:
|
||||
pinX += DbU::lambda ( ( xl + xh ) * (double)__lefConvertFactor / (double)__defConvertFactor ) / 2;
|
||||
pinY += DbU::lambda ( ( yl + yh ) * (double)__lefConvertFactor / (double)__defConvertFactor ) / 2;
|
||||
width = abs(xl) + abs(xh);
|
||||
height = abs(yl) + abs(yh);
|
||||
break;
|
||||
case 1:
|
||||
case 5:
|
||||
pinX -= DbU::lambda ( ( yl + yh ) * (double)__lefConvertFactor / (double)__defConvertFactor ) / 2;
|
||||
pinY += DbU::lambda ( ( xl + xh ) * (double)__lefConvertFactor / (double)__defConvertFactor ) / 2;
|
||||
width = abs(yl) + abs(yh);
|
||||
height = abs(xl) + abs(xh);
|
||||
break;
|
||||
case 2:
|
||||
case 6:
|
||||
pinX += DbU::lambda ( ( xl + xh ) * (double)__lefConvertFactor / (double)__defConvertFactor ) / 2;
|
||||
pinY -= DbU::lambda ( ( yl + yh ) * (double)__lefConvertFactor / (double)__defConvertFactor ) / 2;
|
||||
width = abs(xl) + abs(xh);
|
||||
height = abs(yl) + abs(yh);
|
||||
break;
|
||||
case 3:
|
||||
case 7:
|
||||
pinX += DbU::lambda ( ( yl + yh ) * (double)__lefConvertFactor / (double)__defConvertFactor ) / 2;
|
||||
pinY += DbU::lambda ( ( xl + xh ) * (double)__lefConvertFactor / (double)__defConvertFactor ) / 2;
|
||||
width = abs(yl) + abs(yh);
|
||||
height = abs(xl) + abs(xh);
|
||||
break;
|
||||
default:
|
||||
throw Error ("defReader(): Undefined orientation %i for pin %s"
|
||||
, pin->orient(), pin->defiPin::netName() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Name pinName ( pin->defiPin::pinName() );
|
||||
Pin::create ( net
|
||||
, pinName
|
||||
, Pin::AccessDirection::UNDEFINED
|
||||
, pinPlacementStatus
|
||||
, layer
|
||||
, pinX, pinY
|
||||
, width, height
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case defrRowCbkType :
|
||||
{
|
||||
row = (defiRow*)cl;
|
||||
|
||||
Box rowBox
|
||||
( DbU::lambda((double)(row->x()) * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
, DbU::lambda((double)(row->y()) * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
, DbU::lambda((double)(row->x()+row->xNum()*row->xStep()) * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
, DbU::lambda((double)(row->y()+row->yNum()*row->yStep()) * (double)__lefConvertFactor / (double)__defConvertFactor)
|
||||
);
|
||||
|
||||
LefDefExtension::addRowsBox ( verifyDesign(), rowBox );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw Error ( "defReader(): Unknown callback type %i for cls().", cbType );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // HAVE_LEFDEF
|
||||
|
||||
|
||||
} // End of anonymous namespace.
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
void defParser ( const string& cellPath, Cell *cell )
|
||||
{
|
||||
static unsigned int callNumber = 0;
|
||||
|
||||
cmess2 << " " << tab << "+ " << cellPath << endl;
|
||||
|
||||
#if HAVE_LEFDEF
|
||||
DataBase* db = DataBase::getDB ();
|
||||
if ( !db ) throw Error ( NullDataBase, "defParser()" );
|
||||
|
||||
__technology = db->getTechnology ();
|
||||
if ( !__technology ) throw Error ( NullTechnology, "defParser()" );
|
||||
|
||||
__framework = AllianceFramework::get ();
|
||||
if ( !__framework ) throw Error ( "defParser(): NULL Alliance Framework." );
|
||||
|
||||
|
||||
if ( !cell ) throw Error ( NullCell, "defParser()" );
|
||||
|
||||
__lefConvertFactor = LefDefExtension::getLefDbuPerMicron ( cell );
|
||||
__design = cell;
|
||||
__design->setTerminal ( false );
|
||||
|
||||
CatalogProperty* property
|
||||
= (CatalogProperty*)__design->getProperty ( CatalogProperty::getPropertyName() );
|
||||
if ( property == NULL )
|
||||
throw Error ( "defParser(): Missing Catalog Property on Cell %s."
|
||||
, getString(__design->getName()).c_str() );
|
||||
|
||||
Catalog::State* state = property->getState ();
|
||||
|
||||
state->setPhysical ( true );
|
||||
state->setLogical ( true );
|
||||
|
||||
defrInit();
|
||||
if (callNumber == 0) {
|
||||
defrSetDesignCbk ( cbDesignName );
|
||||
defrSetDesignEndCbk ( cbDone );
|
||||
defrSetUnitsCbk ( cbUnits );
|
||||
defrSetComponentCbk ( cbComponent );
|
||||
defrSetNetCbk ( cbNet );
|
||||
defrSetSNetCbk ( cbSpecialNet );
|
||||
|
||||
defrSetDieAreaCbk ( (defrBoxCbkFnType)cls );
|
||||
defrSetPinCbk ( (defrPinCbkFnType)cls );
|
||||
defrSetRowCbk ( (defrRowCbkFnType)cls );
|
||||
|
||||
//defrSetTechnologyCbk ( TechnoName );
|
||||
defrSetAddPathToNet ();
|
||||
}
|
||||
|
||||
IoFile ccell ( cellPath );
|
||||
ccell.open ( "r" );
|
||||
defrRead ( ccell.getFile(), getString(&ccell).c_str(), (void*)__defUserData, 1 );
|
||||
ccell.close();
|
||||
|
||||
#else // HAVE_LEFDEF
|
||||
|
||||
cerr << "\nDummy DEF parser call for \"" << cellPath << "\"." << endl;
|
||||
|
||||
#endif // HAVE_LEFDEF
|
||||
|
||||
callNumber++;
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
|
||||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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: CLEFDEF.h,v 1.4 2006/02/19 00:52:50 jpc Exp $
|
||||
//
|
||||
// x-----------------------------------------------------------------x
|
||||
// | |
|
||||
// | C O R I O L I S |
|
||||
// | Alliance / Hurricane Interface |
|
||||
// | |
|
||||
// | Author : Christophe Alexandre |
|
||||
// | E-mail : Christophe.Alexandre@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./LefDef.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
# include <iostream>
|
||||
|
||||
namespace Hurricane {
|
||||
class Library;
|
||||
class Cell;
|
||||
}
|
||||
|
||||
# ifndef __CRL_LEFDEF_H__
|
||||
# define __CRL_LEFDEF_H__
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using std::string;
|
||||
using Hurricane::Library;
|
||||
using Hurricane::Cell;
|
||||
|
||||
class Catalog;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// functions.
|
||||
|
||||
extern void CParsLEFTechno ( string fileTechno );
|
||||
extern void lefParser ( const string& libPath, Library* lib, Catalog& catal );
|
||||
extern void defParser ( const string& cellPath, Cell* cell );
|
||||
extern void defDriver ( const string& cellPath, Cell* cell, unsigned int& saveState );
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
||||
|
||||
# endif // __CRL_LEFDEF_H__
|
|
@ -0,0 +1,169 @@
|
|||
|
||||
// -*- 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 : "./LefDefExtension.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Cell.h"
|
||||
|
||||
#include "crlcore/LefDefExtension.h"
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using Hurricane::Error;
|
||||
|
||||
|
||||
const char* MissingLefDefExtension = "LefDefExtension::%s(): %s missing the LEF/DEF extension.";
|
||||
|
||||
|
||||
template<>
|
||||
Name LefDefExtension::Extension::_name = "CRL::LefDefExtension";
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::LefDefExtensionDatas".
|
||||
|
||||
|
||||
LefDefExtensionDatas::LefDefExtensionDatas ()
|
||||
: _lefDbuPerMicron(1)
|
||||
, _defDbuPerMicron(1)
|
||||
, _rowsBox()
|
||||
, _northOrder()
|
||||
, _southOrder()
|
||||
, _eastOrder()
|
||||
, _westOrder()
|
||||
, _undefined()
|
||||
{ }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::LefDefExtension".
|
||||
|
||||
|
||||
Box LefDefExtension::getRowsBox ( const Cell* cell )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell );
|
||||
if ( !extension )
|
||||
return Box ();
|
||||
|
||||
return extension->getValue()._rowsBox;
|
||||
}
|
||||
|
||||
|
||||
const Box& LefDefExtension::addRowsBox ( Cell* cell, Box rowBox )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell, true );
|
||||
|
||||
return extension->getValue()._rowsBox.merge(rowBox);
|
||||
}
|
||||
|
||||
|
||||
unsigned int LefDefExtension::getLefDbuPerMicron ( const Cell* cell )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell );
|
||||
if ( !extension )
|
||||
return 1;
|
||||
|
||||
return extension->getValue()._lefDbuPerMicron;
|
||||
}
|
||||
|
||||
|
||||
void LefDefExtension::setLefDbuPerMicron ( Cell* cell, unsigned int dbuPerMicron )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell, true );
|
||||
|
||||
extension->getValue()._lefDbuPerMicron = dbuPerMicron;
|
||||
}
|
||||
|
||||
|
||||
unsigned int LefDefExtension::getDefDbuPerMicron ( const Cell* cell )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell );
|
||||
if ( !extension )
|
||||
return 1;
|
||||
|
||||
return extension->getValue()._defDbuPerMicron;
|
||||
}
|
||||
|
||||
|
||||
void LefDefExtension::setDefDbuPerMicron ( Cell* cell, unsigned int dbuPerMicron )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell, true );
|
||||
|
||||
extension->getValue()._defDbuPerMicron = dbuPerMicron;
|
||||
}
|
||||
|
||||
|
||||
PinIocOrder& LefDefExtension::getNorthPinIocOrder ( Cell* cell, bool create )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell, create );
|
||||
if ( !extension )
|
||||
throw Error ( MissingLefDefExtension, "getNorthPinOrder", getString(cell).c_str() );
|
||||
|
||||
return extension->getValue()._northOrder;
|
||||
}
|
||||
|
||||
|
||||
PinIocOrder& LefDefExtension::getSouthPinIocOrder ( Cell* cell, bool create )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell, create );
|
||||
if ( !extension )
|
||||
throw Error ( MissingLefDefExtension, "getSouthPinOrder", getString(cell).c_str() );
|
||||
|
||||
return extension->getValue()._southOrder;
|
||||
}
|
||||
|
||||
|
||||
PinIocOrder& LefDefExtension::getEastPinIocOrder ( Cell* cell, bool create )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell, create );
|
||||
if ( !extension )
|
||||
throw Error ( MissingLefDefExtension, "getEastPinOrder", getString(cell).c_str() );
|
||||
|
||||
return extension->getValue()._eastOrder;
|
||||
}
|
||||
|
||||
|
||||
PinIocOrder& LefDefExtension::getWestPinIocOrder ( Cell* cell, bool create )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell, create );
|
||||
if ( !extension )
|
||||
throw Error ( MissingLefDefExtension, "getWestPinOrder", getString(cell).c_str() );
|
||||
|
||||
return extension->getValue()._westOrder;
|
||||
}
|
||||
|
||||
|
||||
PinIocOrder& LefDefExtension::getUndefinedPinIoc ( Cell* cell, bool create )
|
||||
{
|
||||
Extension* extension = Extension::get ( cell, create );
|
||||
if ( !extension )
|
||||
throw Error ( MissingLefDefExtension, "getUndefinedPin", getString(cell).c_str() );
|
||||
|
||||
return extension->getValue()._undefined;
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
|
@ -0,0 +1,729 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
// Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// 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: CParsLEF.cpp,v 1.28 2007/07/29 15:27:25 jpc Exp $
|
||||
//
|
||||
// x-----------------------------------------------------------------x
|
||||
// | |
|
||||
// | C O R I O L I S |
|
||||
// | Alliance / Hurricane Interface |
|
||||
// | |
|
||||
// | Author : Christophe Alexandre |
|
||||
// | E-mail : Christophe.Alexandre@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./LefParser.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
# include "hurricane/Warning.h"
|
||||
# include "hurricane/DataBase.h"
|
||||
# include "hurricane/BasicLayer.h"
|
||||
# include "hurricane/ViaLayer.h"
|
||||
# include "hurricane/Net.h"
|
||||
# include "hurricane/Pad.h"
|
||||
# include "hurricane/Vertical.h"
|
||||
# include "hurricane/Horizontal.h"
|
||||
# include "hurricane/NetExternalComponents.h"
|
||||
# include "hurricane/Cell.h"
|
||||
|
||||
# include "crlcore/AllianceFramework.h"
|
||||
# include "LefDef.h"
|
||||
|
||||
# if HAVE_LEFDEF && defined(LEF_ENABLED)
|
||||
# include "lefrReader.hpp"
|
||||
# endif
|
||||
|
||||
|
||||
# define ONLY_PAD_PINS 1
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::Pad;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Library;
|
||||
|
||||
using namespace CRL;
|
||||
|
||||
|
||||
unsigned int __lefConvertFactor = 1;
|
||||
Library* __library = NULL;
|
||||
AllianceFramework* __framework = NULL;
|
||||
Technology* __technology = NULL;
|
||||
Cell* __cell = NULL;
|
||||
Net* __net = NULL;
|
||||
long __userData = 0;
|
||||
Catalog* __catalog = NULL;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Function : "Obstruction()".
|
||||
|
||||
void Obstruction ( Cell* cell, Layer* layer, const Box& bb )
|
||||
{
|
||||
Net* obsNet = cell->getNet ( "obstaclenet" );
|
||||
|
||||
if (!layer)
|
||||
throw Error("No layer for obstacle");
|
||||
|
||||
if ( obsNet == NULL )
|
||||
obsNet = Net::create ( cell, "obstaclenet" );
|
||||
|
||||
Pad::create ( obsNet, layer, bb );
|
||||
}
|
||||
|
||||
|
||||
} // End of anonymous namespace.
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Instance;
|
||||
using Hurricane::Library;
|
||||
|
||||
|
||||
// x-----------------------------------------------------------------x
|
||||
// | Functions Definitions |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
# if HAVE_LEFDEF && defined(LEF_ENABLED)
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Function : "badOpenTechno()".
|
||||
|
||||
// inline string badOpenTechno ( const string &header, string file )
|
||||
// {
|
||||
// ostringstream m;
|
||||
|
||||
// if ( header.size() > 0 )
|
||||
// m << header << " :";
|
||||
// m << "\n\n";
|
||||
|
||||
// m << " Unable to open LEF technological file : \n"
|
||||
// << " \"" << file << "\".\n\n"
|
||||
// << " Please check LEF_TECHNO_NAME environment variable.\n";
|
||||
|
||||
// return ( m.str() );
|
||||
// }
|
||||
|
||||
|
||||
int propDefCB(lefrCallbackType_e type, lefiProp* propInfo, lefiUserData ud)
|
||||
{
|
||||
//FIXME:checktype
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int layerCB(lefrCallbackType_e type, lefiLayer* layer, lefiUserData ud)
|
||||
{
|
||||
DbU::Unit width = 0;
|
||||
DbU::Unit pitch = 0;
|
||||
DbU::Unit spacing = 0;
|
||||
bool hasWidth = false;
|
||||
bool hasPitch = false;
|
||||
bool hasSpacing = false;
|
||||
|
||||
if ( type != lefrLayerCbkType )
|
||||
throw Error("layerCB: Invalid Callback");
|
||||
|
||||
if ( layer->hasWidth() ) {
|
||||
hasWidth = true;
|
||||
width = DbU::getUnit(layer->width() * (double)__lefConvertFactor);
|
||||
}
|
||||
if ( layer->hasPitch() ) {
|
||||
hasPitch = true;
|
||||
pitch = DbU::getUnit(layer->pitch() * (double)__lefConvertFactor);
|
||||
}
|
||||
for ( int i=0; i < layer->numSpacing(); i++ ) {
|
||||
if ( layer->hasSpacingRange(i) ) continue;
|
||||
if (hasSpacing)
|
||||
spacing = std::min ( spacing, DbU::getUnit(layer->spacing(i) * (double)__lefConvertFactor) );
|
||||
else {
|
||||
hasSpacing = true;
|
||||
spacing = DbU::getUnit(layer->spacing(i) * (double)__lefConvertFactor);
|
||||
}
|
||||
}
|
||||
Layer* hurricaneLayer = __technology->getLayer(Name(layer->name()));
|
||||
if ( !hurricaneLayer ) {
|
||||
hurricaneLayer = BasicLayer::create( __technology
|
||||
, Name(layer->name())
|
||||
, BasicLayer::Type::UNDEFINED
|
||||
, width
|
||||
, spacing
|
||||
, pitch);
|
||||
} else {
|
||||
if (hasWidth ) hurricaneLayer->setMinimalSize(width);
|
||||
if (hasSpacing) hurricaneLayer->setMinimalSpacing(spacing);
|
||||
if (hasPitch ) hurricaneLayer->setPitch(pitch);
|
||||
}
|
||||
|
||||
if (layer->hasType()) {
|
||||
if (layer->type() == "ROUTING") {
|
||||
if (layer->hasDirection()) {
|
||||
if (layer->direction() == "VERTICAL") {
|
||||
// routing layer, direction vertical
|
||||
//setVerticalProperty(hurricaneLayer);
|
||||
//hurricaneLayer->Put(StandardSharedProperty<TRoutingLayerDirection>(Name("ROUTING"), TRoutingLayerDirection(TRoutingLayerDirection::VERTICAL)));
|
||||
}
|
||||
else if (layer->direction() == "HORIZONTAL") {
|
||||
// routing layer, direction horizontal
|
||||
//setHorizontalProperty(hurricaneLayer);
|
||||
} else {
|
||||
// routing layer, direction unknown
|
||||
}
|
||||
} else {
|
||||
// routing layer, no direction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int viaCB(lefrCallbackType_e type, lefiVia* viaInfo, lefiUserData ud)
|
||||
{
|
||||
if ( type != lefrViaCbkType )
|
||||
throw Error("error");
|
||||
|
||||
CompositeLayer* layer = ViaLayer::create(__technology, Name (viaInfo->name()) ) ;
|
||||
|
||||
if ( viaInfo->numLayers() > 0 ) {
|
||||
vector<BasicLayer*> basicLayers;
|
||||
vector<DbU::Unit> enclosures;
|
||||
for ( int i = 0 ; i < viaInfo->numLayers() ; i++ ) {
|
||||
DbU::Unit enclosure = 0;
|
||||
for (int j = 0; j < viaInfo->numRects(i); j++) {
|
||||
enclosure = DbU::getUnit ( ( viaInfo->xh(i,j) * (double)__lefConvertFactor ) - ( viaInfo->xl(i,j) * (double)__lefConvertFactor ) );
|
||||
}
|
||||
BasicLayer* basicLayer = __technology->getBasicLayer(viaInfo->layerName(i));
|
||||
if ( basicLayer ) {
|
||||
basicLayers.push_back ( basicLayer );
|
||||
enclosures.push_back ( enclosure );
|
||||
}
|
||||
}
|
||||
if ( basicLayers.size() == 3 ) {
|
||||
ViaLayer::create ( __technology
|
||||
, viaInfo->name()
|
||||
, basicLayers[0]
|
||||
, basicLayers[1]
|
||||
, basicLayers[2]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int macroObsCB (lefrCallbackType_e type, lefiObstruction *obsInfo, lefiUserData ud)
|
||||
{
|
||||
lefiGeometries* geom;
|
||||
lefiGeomRect* rect;
|
||||
lefiGeomPath* path;
|
||||
Layer* layer;
|
||||
double width = 0.0;
|
||||
|
||||
|
||||
if (type != lefrObstructionCbkType) abort ();
|
||||
|
||||
geom = obsInfo->geometries();
|
||||
for (int i = 0 ; i < geom->numItems() ; i++) {
|
||||
switch (geom->itemType(i)) {
|
||||
case lefiGeomClassE: break;
|
||||
case lefiGeomLayerE:
|
||||
{
|
||||
layer = __technology->getLayer(geom->getLayer(i));
|
||||
if (!layer)
|
||||
throw Error("Unknown Layer: " + string(geom->getLayer(i)));
|
||||
BasicLayer* basicLayer = dynamic_cast<BasicLayer*>(layer);
|
||||
const Name* obstacleLayerName = getObstacleLayerName(basicLayer);
|
||||
if (obstacleLayerName)
|
||||
layer = technology->getLayer(*obstacleLayerName);
|
||||
if (!layer)
|
||||
if (obstacleLayerName)
|
||||
throw Error("Unknown layer: " + obstacleLayerName->_getString());
|
||||
else
|
||||
throw Error("Unknow Layer: (null) Name");
|
||||
break;
|
||||
}
|
||||
case lefiGeomWidthE:
|
||||
width = (geom->getWidth (i) * (double)__lefConvertFactor);
|
||||
break;
|
||||
case lefiGeomPathE:
|
||||
path = geom->getPath(i);
|
||||
|
||||
if (path->numPoints < 2) {
|
||||
cerr << "Un seul point sur le path ???" << endl;
|
||||
abort ();
|
||||
}
|
||||
|
||||
for (int j = 0 ; j < (path->numPoints - 1) ; j++) {
|
||||
if (path->x[j] == path->x[j + 1]) {
|
||||
// horizontal
|
||||
Obstruction ( __cell
|
||||
, layer
|
||||
, Box ( DbU::getUnit(path->x[j] * (double)__lefConvertFactor - width / 2)
|
||||
, DbU::getUnit(path->y[j] * (double)__lefConvertFactor)
|
||||
, DbU::getUnit(path->x[j + 1] * (double)__lefConvertFactor + width / 2)
|
||||
, DbU::getUnit(path->y[j + 1] * (double)__lefConvertFactor)
|
||||
)
|
||||
);
|
||||
} else if (path->y[j] == path->y[j + 1]) {
|
||||
// vertical
|
||||
Obstruction ( __cell
|
||||
, layer
|
||||
, Box ( DbU::getUnit(path->x[j] * (double)__lefConvertFactor)
|
||||
, DbU::getUnit(path->y[j] * (double)__lefConvertFactor - width / 2)
|
||||
, DbU::getUnit(path->x[j + 1] * (double)__lefConvertFactor)
|
||||
, DbU::getUnit(path->y[j + 1] * (double)__lefConvertFactor + width / 2)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// curiosité
|
||||
cerr << "Invalid PATH..." << endl;
|
||||
abort ();
|
||||
}
|
||||
} // for
|
||||
break;
|
||||
case lefiGeomPathIterE:
|
||||
// pas glop
|
||||
break;
|
||||
case lefiGeomRectE:
|
||||
// FIXME
|
||||
// un segment.....
|
||||
// quel net de quel cell ????
|
||||
// utiliser la var globale "cell"
|
||||
rect = geom->getRect (i);
|
||||
|
||||
Obstruction ( __cell
|
||||
, layer
|
||||
, Box ( DbU::getUnit(rect->xl * (double)__lefConvertFactor)
|
||||
, DbU::getUnit(rect->yl * (double)__lefConvertFactor)
|
||||
, DbU::getUnit(rect->xh * (double)__lefConvertFactor)
|
||||
, DbU::getUnit(rect->yh * (double)__lefConvertFactor)
|
||||
)
|
||||
);
|
||||
break;
|
||||
case lefiGeomRectIterE:
|
||||
// pas glop...
|
||||
break;
|
||||
case lefiGeomPolygonE:
|
||||
case lefiGeomPolygonIterE:
|
||||
// pas encore de polygones dans Hurricane
|
||||
cerr << "Polygons are not yet supported" << endl;
|
||||
abort ();
|
||||
break;
|
||||
case lefiGeomViaE:
|
||||
case lefiGeomViaIterE:
|
||||
// pas glop...
|
||||
break;
|
||||
default:
|
||||
// y'en a pas
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int arrayBeginCB(lefrCallbackType_e type, const char* array_name, lefiUserData ud)
|
||||
{
|
||||
if (type != lefrArrayBeginCbkType)
|
||||
throw Error("arrayBeginCB: Invalid Callback");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int macroBeginCB(lefrCallbackType_e type, const char* macroName, lefiUserData ud)
|
||||
{
|
||||
if (type != lefrMacroBeginCbkType)
|
||||
throw Error("macroBeginCB: Invalid Callback");
|
||||
|
||||
if (!macroName || !*macroName)
|
||||
return 1;
|
||||
|
||||
string cellName = macroName;
|
||||
cmess2 << " - \"" << cellName << "\"..." << endl;
|
||||
|
||||
__cell = Cell::create ( __library, cellName );
|
||||
__cell->setTerminal(false);
|
||||
|
||||
Catalog::State* state = __catalog->getState ( cellName );
|
||||
if ( state == NULL )
|
||||
state = __catalog->getState ( cellName, true );
|
||||
// Should check here when a cell is redefined (from another library).
|
||||
|
||||
__cell->put ( CatalogProperty::create(state) );
|
||||
state->setLogical ( true );
|
||||
state->setPhysical ( true );
|
||||
state->setCell ( __cell );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int macroCB(lefrCallbackType_e type, lefiMacro* macroInfo, lefiUserData ud)
|
||||
{
|
||||
if (type != lefrMacroCbkType)
|
||||
throw Error("macroCB: Invalid Callback");
|
||||
|
||||
DbU::Unit originX;
|
||||
DbU::Unit originY;
|
||||
if (macroInfo->hasOrigin()) {
|
||||
originX = DbU::getUnit(macroInfo->originX() * (double)__lefConvertFactor);
|
||||
originY = DbU::getUnit(macroInfo->originY() * (double)__lefConvertFactor);
|
||||
}
|
||||
|
||||
DbU::Unit sizeX;
|
||||
DbU::Unit sizeY;
|
||||
if (macroInfo->hasSize()) {
|
||||
sizeX = DbU::getUnit(macroInfo->sizeX() * (double)__lefConvertFactor);
|
||||
sizeY = DbU::getUnit(macroInfo->sizeY() * (double)__lefConvertFactor);
|
||||
}
|
||||
Box abox ( originX, originY, originX + sizeX, originY + sizeY );
|
||||
__cell->setAbutmentBox(abox);
|
||||
for_each_net(net, cell->getNets()) {
|
||||
net->setPosition(Point(abox.getHalfWidth(), abox.getHalfHeight()));
|
||||
end_for;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int unitsCB(lefrCallbackType_e type, lefiUnits* units, lefiUserData ud)
|
||||
{
|
||||
if (type != lefrUnitsCbkType)
|
||||
throw Error("unitsCB: Invalid Callback");
|
||||
|
||||
if (units->hasDatabase()) {
|
||||
__lefConvertFactor = (unsigned)units->databaseNumber();
|
||||
setLefConvertFactor(__technology, __lefConvertFactor);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int siteCB(lefrCallbackType_e type, lefiSite* site, lefiUserData ud)
|
||||
{
|
||||
if (type != lefrSiteCbkType)
|
||||
throw Error("siteCB: Invalid Callback");
|
||||
|
||||
assert(site->lefiSite::hasClass());
|
||||
assert(site->lefiSite::hasSize());
|
||||
/*BasicLayer::create(technology, Name(site->lefiSite::name()),
|
||||
DbU::getUnit(site->lefiSite::sizeX()), DbU::getUnit(site->lefiSite::sizeX()));
|
||||
*/
|
||||
//set_grid_step(getUnit(site->lefiSite::sizeX()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pinCB(lefrCallbackType_e type, lefiPin* pin, lefiUserData ud)
|
||||
{
|
||||
if (type != lefrPinCbkType)
|
||||
throw Error("pinCB: Invalid Callback");
|
||||
|
||||
net = Net::create(cell, Name(pin->lefiPin::name()));
|
||||
net->setExternal(true);
|
||||
if (pin->hasUse()) {
|
||||
if (!strcmp(pin->use(), "POWER")) {
|
||||
net->setGlobal(true);
|
||||
net->setType(Net::Type::POWER);
|
||||
} else if (!strcmp(pin->use(), "GROUND")) {
|
||||
net->setGlobal(true);
|
||||
net->setType(Net::Type::GROUND);
|
||||
} else if (!strcmp(pin->use(), "CLOCK")) {
|
||||
net->setType(Net::Type::CLOCK);
|
||||
}
|
||||
else
|
||||
net->setType(Net::Type::UNDEFINED);
|
||||
} else
|
||||
net->setType(Net::Type::LOGICAL);
|
||||
|
||||
for (int prop = 0; prop < pin->numProperties(); prop++) {
|
||||
if (!strcmp(pin->propName(prop), "REGISTERPIN")) {
|
||||
setRegisterNet(*net);
|
||||
}
|
||||
}
|
||||
|
||||
if (pin->hasDirection()) {
|
||||
if (!strcmp(pin->direction(), "INPUT"))
|
||||
net->setDirection(Net::Direction::IN);
|
||||
else if (!strcmp(pin->direction(), "OUTPUT"))
|
||||
net->setDirection(Net::Direction::OUT);
|
||||
else if (!strcmp(pin->direction(), "OUTPUT TRISTATE")) {
|
||||
net->setDirection(Net::Direction::TRISTATE);
|
||||
} else if (!strcmp(pin->direction(), "INOUT"))
|
||||
net->setDirection(Net::Direction::INOUT);
|
||||
else
|
||||
net->setDirection(Net::Direction::UNDEFINED);
|
||||
} else
|
||||
net->setDirection(Net::Direction::UNDEFINED);
|
||||
|
||||
// la physique du pin
|
||||
for (int j=0; j<pin->numPorts(); j++) {
|
||||
lefiGeometries* geom = pin->port(j);
|
||||
Layer* layer = NULL;
|
||||
DbU::Unit width = 0;
|
||||
for (int i=0; i<geom->numItems(); i++) {
|
||||
switch (geom->itemType(i)) {
|
||||
case lefiGeomLayerE:
|
||||
{
|
||||
layer = technology->getLayer(geom->getLayer(i));
|
||||
if (!layer)
|
||||
throw Error("Unknown Layer: " + string(geom->getLayer(i)));
|
||||
BasicLayer* basicLayer = dynamic_cast<BasicLayer*>(layer);
|
||||
const Name* connectorLayerName = getConnectorLayerName(basicLayer);
|
||||
if (connectorLayerName)
|
||||
layer = technology->getLayer(*connectorLayerName);
|
||||
if (!layer)
|
||||
if (connectorLayerName)
|
||||
throw Error("Unknown layer: " + connectorLayerName->_getString());
|
||||
else
|
||||
throw Error("Unknow Layer: (null) Name");
|
||||
break;
|
||||
}
|
||||
case lefiGeomRectE:
|
||||
{
|
||||
lefiGeomRect* rect = geom->getRect(i);
|
||||
if (!layer) {
|
||||
throw Error("Unknown Layer: " + string(pin->lefiPin::name()));
|
||||
}
|
||||
# ifdef ONLY_PAD_PINS
|
||||
Pad* pad=Pad::create ( net
|
||||
, layer
|
||||
, Box ( DbU::getUnit(rect->xl * (double)__lefConvertFactor)
|
||||
, DbU::getUnit(rect->yl * (double)__lefConvertFactor)
|
||||
, DbU::getUnit(rect->xh * (double)__lefConvertFactor)
|
||||
, DbU::getUnit(rect->yh * (double)__lefConvertFactor) ) );
|
||||
setExternal(pad);
|
||||
# else
|
||||
DbU::Unit width = DbU::getUnit( (rect->xh - rect->xl) * (double)__lefConvertFactor);
|
||||
DbU::Unit height = DbU::getUnit( (rect->yh - rect->yl) * (double)__lefConvertFactor);
|
||||
DbU::Unit cx = DbU::getUnit(rect->xl * (double)__lefConvertFactor) + width/2;
|
||||
DbU::Unit cy = DbU::getUnit(rect->yl * (double)__lefConvertFactor) + height/2;
|
||||
if (width > height) {
|
||||
Horizontal* horizontal=Horizontal::create(net, layer, cy, height, DbU::getUnit(rect->xl * (double)__lefConvertFactor), DbU::getUnit(rect->xh * (double)__lefConvertFactor));
|
||||
setExternal(horizontal);
|
||||
} else {
|
||||
Vertical* vertical= Vertical::create(net, layer, cx, width, DbU::getUnit(rect->yl * (double)__lefConvertFactor), DbU::getUnit(rect->yh * (double)__lefConvertFactor));
|
||||
setExternal(vertical);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
break;
|
||||
case lefiGeomWidthE:
|
||||
width = DbU::getUnit(geom->getWidth(i) * (double)__lefConvertFactor);
|
||||
break;
|
||||
case lefiGeomPathE:
|
||||
{
|
||||
lefiGeomPath* path = geom->getPath(i);
|
||||
if (path->numPoints == 1) {
|
||||
Pad* pad=Pad::create( net
|
||||
, layer
|
||||
, Box( DbU::getUnit(path->x[0] * (double)__lefConvertFactor) - width/2
|
||||
, DbU::getUnit(path->y[0] * (double)__lefConvertFactor) - width/2
|
||||
, DbU::getUnit(path->x[0] * (double)__lefConvertFactor) + width/2
|
||||
, DbU::getUnit(path->y[0] * (double)__lefConvertFactor) + width/2)
|
||||
);
|
||||
setExternal(pad);
|
||||
break;
|
||||
}
|
||||
for (int point = 0 ; point < (path->numPoints - 1) ; point++) {
|
||||
if (path->x[point] == path->x[point + 1]) {
|
||||
// horizontal
|
||||
Pad* pad=Pad::create ( net
|
||||
, layer
|
||||
, Box ( DbU::getUnit(path->x[point] * (double)__lefConvertFactor) - width/2
|
||||
, DbU::getUnit(path->y[point] * (double)__lefConvertFactor) - width/2
|
||||
, DbU::getUnit(path->x[point+1] * (double)__lefConvertFactor) + width/2
|
||||
, DbU::getUnit(path->y[point+1] * (double)__lefConvertFactor) + width/2
|
||||
)
|
||||
);
|
||||
setExternal(pad);
|
||||
} else if (path->y[point] == path->y[point + 1]) {
|
||||
// vertical
|
||||
Pad* pad=Pad::create ( net
|
||||
, layer
|
||||
, Box ( DbU::getUnit(path->x[point] * (double)__lefConvertFactor) - width/2
|
||||
, DbU::getUnit(path->y[point] * (double)__lefConvertFactor) - width/2
|
||||
, DbU::getUnit(path->x[point+1] * (double)__lefConvertFactor) + width/2
|
||||
, DbU::getUnit(path->y[point+1] * (double)__lefConvertFactor) + width/2
|
||||
)
|
||||
);
|
||||
setExternal(pad);
|
||||
} else {
|
||||
// curiosité
|
||||
cerr << "Invalid PATH..." << endl;
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cerr << "geometry not supported for pin ... "
|
||||
<< pin->lefiPin::name()
|
||||
<< " type is " << geom->itemType(i)
|
||||
<< endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Function : "lefParser()".
|
||||
|
||||
void lefParser ( const string& libPath, Library* library, Catalog& catalog )
|
||||
{
|
||||
static int callNumber = 0;
|
||||
|
||||
# if HAVE_LEFDEF && defined(LEF_ENABLED)
|
||||
if ( !library )
|
||||
throw Error ( "lefParser() : Library argument is NULL." );
|
||||
|
||||
//cmess1 << "\n o Loading library \"" << lib->getName() << "\"." << endl;
|
||||
|
||||
__library = lib;
|
||||
__framework = AllianceFrameWork::get ();
|
||||
__technology = DataBase::getDB()->getTechnology ();
|
||||
__catalog = _framework->getCatalog ();
|
||||
|
||||
lefrInit ();
|
||||
|
||||
if ( !callNumber ) {
|
||||
lefrSetMacroBeginCbk ( macroBeginCB );
|
||||
lefrSetMacroCbk ( macroCB );
|
||||
lefrSetObstructionCbk ( macroObsCB );
|
||||
lefrSetPinCbk ( pinCB );
|
||||
}
|
||||
|
||||
IoFile clibrary ( libPath );
|
||||
clibrary.open ( "r" );
|
||||
lefrRead ( clibrary.getFile(), getString(&clibrary).c_str(), (void*)userData );
|
||||
clibrary.close ();
|
||||
# else // HAVE_LEFDEF
|
||||
cerr << Warning("Dummy LEF parser call for %s.",libPath.c_str()) << endl;
|
||||
# endif // HAVE_LEFDEF
|
||||
|
||||
callNumber++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CParsLEFTechno ( string fileTechno )
|
||||
{
|
||||
static int callNumber = 0;
|
||||
|
||||
# if HAVE_LEFDEF && defined(LEF_ENABLED)
|
||||
string nameTechno = fileTechno;
|
||||
|
||||
nameTechno.erase ( 0, nameTechno.find_last_of ("/")+1 );
|
||||
nameTechno.erase ( nameTechno.find_first_of("."), string::npos );
|
||||
|
||||
assert ( nameTechno.size() > 1 );
|
||||
|
||||
DataBase* db = DataBase::getDB();
|
||||
if ( !db )
|
||||
throw Error ( "CParsLEFTechno(): NULL DataBase." );
|
||||
|
||||
__technology = db->getTechnology();
|
||||
if ( !__technology )
|
||||
__technology = Technology::create ( db, nameTechno );
|
||||
else
|
||||
__technology->setName ( nameTechno );
|
||||
|
||||
lefrInit();
|
||||
if ( !callNumber ) {
|
||||
lefrSetUnitsCbk(unitsCB);
|
||||
lefrSetSiteCbk(siteCB);
|
||||
lefrSetArrayBeginCbk(arrayBeginCB);
|
||||
//lefrSetArrayCbk(arrayCB);
|
||||
lefrSetLayerCbk(layerCB);
|
||||
//lefrSetObstructionCbk(macroObsCB);
|
||||
lefrSetViaCbk(viaCB);
|
||||
}
|
||||
|
||||
FILE* inLefFile = fopen ( fileTechno.c_str(), "r" );
|
||||
|
||||
if ( inLefFile == NULL )
|
||||
throw ( Error("CParsLEFTechno() : Can't open file %s", fileTechno.c_str()) );
|
||||
|
||||
lefrRead(inLefFile, fileTechno.c_str(), (void*)(long)userData);
|
||||
# else // HAVE_LEFDEF
|
||||
cerr << Warning("Dummy LEF technology parser call for \"%s\".",fileTechno.c_str()) << endl;
|
||||
# endif // HAVE_LEFDEF
|
||||
|
||||
callNumber++;
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
|
@ -0,0 +1,335 @@
|
|||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
//
|
||||
// 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 : 15/05/2007
|
||||
// Author : Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
#include "hurricane/Property.h"
|
||||
#include "hurricane/Cell.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
#include "LuTable.h"
|
||||
|
||||
#include "crlcore/CellPath.h"
|
||||
#include "crlcore/CellPaths.h"
|
||||
|
||||
namespace CRL {
|
||||
|
||||
// ****************************************************************************************************
|
||||
// CCellPath_Property declaration
|
||||
// ****************************************************************************************************
|
||||
|
||||
class CCellPath_Property : public PrivateProperty {
|
||||
|
||||
// Types
|
||||
// *****
|
||||
public: typedef PrivateProperty Inherit;
|
||||
|
||||
// Attributes
|
||||
// **********
|
||||
private:list<CCellPath*> _cellPathList;
|
||||
|
||||
// Constructors
|
||||
// ************
|
||||
private: CCellPath_Property(CCellPath* cellPath);
|
||||
public: static CCellPath_Property* create(CCellPath* cellPath);
|
||||
|
||||
// Accessors
|
||||
// *********
|
||||
public: virtual Name getName() const;
|
||||
public: CCellPaths getCellPaths() const { return getCollection(_cellPathList); }
|
||||
|
||||
// Others
|
||||
// ******
|
||||
public: virtual string _getTypeName() const { return _TName("CCellPath_Property"); }
|
||||
public: virtual Record* _getRecord() const;
|
||||
public: static const Name& getPropertyName();
|
||||
|
||||
public: static void RegisterCellPath(CCellPath* cellPath);
|
||||
|
||||
public: void AddCellPath(CCellPath* cellPath);
|
||||
public: CCellPath* getCellPath(Net* relatedNet) const;
|
||||
|
||||
};
|
||||
|
||||
// ****************************************************************************************************
|
||||
// CCellPath definition
|
||||
// ****************************************************************************************************
|
||||
|
||||
CCellPath::CCellPath(Net* net)
|
||||
// ***************************
|
||||
: Inherit()
|
||||
, _net(net)
|
||||
, _relatedNet(NULL)
|
||||
, _type()
|
||||
, _riseDelay(NULL)
|
||||
, _fallDelay(NULL)
|
||||
, _riseTransition(NULL)
|
||||
, _fallTransition(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CCellPath* CCellPath::create(Net* net)
|
||||
// ***********************************
|
||||
{
|
||||
CCellPath* cCellPath= new CCellPath(net);
|
||||
|
||||
cCellPath->_postCreate();
|
||||
|
||||
return cCellPath;
|
||||
}
|
||||
|
||||
void CCellPath::_postCreate()
|
||||
// **************************
|
||||
{
|
||||
Inherit::_postCreate();
|
||||
|
||||
CCellPath_Property::RegisterCellPath(this);
|
||||
}
|
||||
|
||||
string CCellPath::_getString() const
|
||||
// *********************************
|
||||
{
|
||||
string s = Inherit::_getString();
|
||||
s.insert(s.length() - 1," "+getString(_net->getCell()->getName())+ " "+getString(_net->getName()));
|
||||
if (_relatedNet)
|
||||
s.insert(s.length() - 1," ("+getString(_relatedNet->getName())+") ");
|
||||
s.insert(s.length() -1, getString(_type));
|
||||
return s;
|
||||
}
|
||||
|
||||
Record* CCellPath::_getRecord() const
|
||||
// ****************************
|
||||
{
|
||||
Record* record = Inherit::_getRecord();
|
||||
if (record)
|
||||
{
|
||||
record->add(getSlot("Net", _net));
|
||||
record->add(getSlot("Related Net", _relatedNet));
|
||||
record->add(getSlot("Type", _type));
|
||||
record->add(getSlot("Rise Delay Table", _riseDelay));
|
||||
record->add(getSlot("Fall Delay Table", _fallDelay));
|
||||
record->add(getSlot("Rise Transition Table", _riseTransition));
|
||||
record->add(getSlot("Fall Transition Table", _fallTransition));
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
CLuTable* CCellPath::_createRiseDelayTable(CLuTableTemplate* luTemplate)
|
||||
// *********************************************************************
|
||||
{
|
||||
return _riseDelay= CLuTable::create(luTemplate);
|
||||
}
|
||||
|
||||
CLuTable* CCellPath::_createFallDelayTable(CLuTableTemplate* luTemplate)
|
||||
// *********************************************************************
|
||||
{
|
||||
return _fallDelay= CLuTable::create(luTemplate);
|
||||
}
|
||||
|
||||
CLuTable* CCellPath::_createRiseTransitionTable(CLuTableTemplate* luTemplate)
|
||||
// **************************************************************************
|
||||
{
|
||||
return _riseTransition= CLuTable::create(luTemplate);
|
||||
}
|
||||
|
||||
CLuTable* CCellPath::_createFallTransitionTable(CLuTableTemplate* luTemplate)
|
||||
// **************************************************************************
|
||||
{
|
||||
return _fallTransition= CLuTable::create(luTemplate);
|
||||
}
|
||||
|
||||
CLuTable* CCellPath::getDelayTable(CTimingEvent event) const
|
||||
// *********************************************************
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case CRL::CTimingEvent::FALLING_EDGE: return _fallDelay;
|
||||
case CRL::CTimingEvent::RISING_EDGE: return _riseDelay;
|
||||
default:
|
||||
throw Error("Undefined Timing Event");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CLuTable* CCellPath::getTransitionTable(CTimingEvent event) const
|
||||
// **************************************************************
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case CRL::CTimingEvent::FALLING_EDGE: return _fallTransition;
|
||||
case CRL::CTimingEvent::RISING_EDGE: return _riseTransition;
|
||||
default:
|
||||
throw Error("Undefined Timing Event");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ****************************************************************************************************
|
||||
// getCellPaths(Cell*) definition
|
||||
// ****************************************************************************************************
|
||||
|
||||
CCellPaths getCellPaths(const Cell* cell)
|
||||
// **************************************
|
||||
{
|
||||
Property* property=cell->getProperty(CCellPath_Property::getPropertyName());
|
||||
if (!property)
|
||||
return CCellPaths();
|
||||
if (CCellPath_Property* ccpProperty = dynamic_cast<CCellPath_Property*>(property)) {
|
||||
return ccpProperty->getCellPaths();
|
||||
} else {
|
||||
throw Error(getString(CCellPath_Property::getPropertyName())+" : bad property type");
|
||||
}
|
||||
}
|
||||
|
||||
// ****************************************************************************************************
|
||||
// CCellPath_Property definition
|
||||
// ****************************************************************************************************
|
||||
|
||||
CCellPath_Property::CCellPath_Property(CCellPath* cellPath)
|
||||
// ********************************************************
|
||||
: _cellPathList()
|
||||
{
|
||||
_cellPathList.push_back(cellPath);
|
||||
}
|
||||
|
||||
CCellPath_Property* CCellPath_Property::create(CCellPath* cellPath)
|
||||
// ****************************************************************
|
||||
{
|
||||
CCellPath_Property* property = new CCellPath_Property(cellPath);
|
||||
|
||||
property->_postCreate();
|
||||
|
||||
return property;
|
||||
}
|
||||
|
||||
void CCellPath_Property::RegisterCellPath(CCellPath* cellPath)
|
||||
// ***********************************************************
|
||||
{
|
||||
Cell* cell = cellPath->getNet()->getCell();
|
||||
Property* property=cell->getProperty(getPropertyName());
|
||||
if (property) {
|
||||
if (CCellPath_Property* ccpProperty = dynamic_cast<CCellPath_Property*>(property)) {
|
||||
ccpProperty->AddCellPath(cellPath);
|
||||
} else {
|
||||
throw Error(getString(getPropertyName())+" : bad property type");
|
||||
}
|
||||
} else {
|
||||
property = CCellPath_Property::create(cellPath);
|
||||
cell->put(property);
|
||||
}
|
||||
}
|
||||
|
||||
Record* CCellPath_Property::_getRecord() const
|
||||
// *************************************
|
||||
{
|
||||
Record* record = Inherit::_getRecord();
|
||||
if (record) {
|
||||
record->add(getSlot("CellPathList",&_cellPathList));
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
Name CCellPath_Property::getName() const
|
||||
// *************************************
|
||||
{
|
||||
return getPropertyName();
|
||||
}
|
||||
|
||||
const Name& CCellPath_Property::getPropertyName()
|
||||
// **********************************************
|
||||
{
|
||||
static Name NAME = "Coriolis::TimingCellPaths";
|
||||
return NAME;
|
||||
}
|
||||
|
||||
void CCellPath_Property::AddCellPath(CCellPath* cellPath)
|
||||
// ******************************************************
|
||||
{
|
||||
_cellPathList.push_back(cellPath);
|
||||
}
|
||||
|
||||
CCellPath* CCellPath_Property::getCellPath(Net* relatedNet) const
|
||||
// **************************************************************
|
||||
{
|
||||
for(list<CCellPath*>::const_iterator it=_cellPathList.begin();it!=_cellPathList.end();it++)
|
||||
{
|
||||
if ((*it)->getRelatedNet() == relatedNet)
|
||||
return (*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ****************************************************************************************************
|
||||
// CCellPath::Type definition
|
||||
// ****************************************************************************************************
|
||||
|
||||
CCellPath::Type::Type(const Code& code)
|
||||
// ************************************
|
||||
: _code(code)
|
||||
{
|
||||
}
|
||||
|
||||
CCellPath::Type::Type(const CCellPath::Type& type)
|
||||
// ***********************************************
|
||||
: _code(type._code)
|
||||
{
|
||||
}
|
||||
|
||||
CCellPath::Type& CCellPath::Type::operator=(const CCellPath::Type& type)
|
||||
// *********************************************************************
|
||||
{
|
||||
_code = type._code;
|
||||
return *this;
|
||||
}
|
||||
|
||||
string CCellPath::Type::_getString() const
|
||||
// ***************************************
|
||||
{
|
||||
switch (_code) {
|
||||
case UNDEFINED : return "UNDEFINED";
|
||||
case POSITIVE_UNATE: return "POSITIVE_UNATE";
|
||||
case NEGATIVE_UNATE: return "NEGATIVE_UNATE";
|
||||
case LATCH_ACCESS: return "LATCH_ACCESS";
|
||||
case LATCH_SETUP: return "LATCH_SETUP";
|
||||
case LATCH_HOLD: return "LATCH_HOLD";
|
||||
}
|
||||
return "ABNORMAL";
|
||||
}
|
||||
|
||||
Record* CCellPath::Type::_getRecord() const
|
||||
// **********************************
|
||||
{
|
||||
Record* record = new Record(getString(this));
|
||||
record->add(getSlot("Code", (unsigned*)&_code));
|
||||
return record;
|
||||
}
|
||||
|
||||
} //namespace CRL
|
|
@ -0,0 +1,633 @@
|
|||
%{
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
using namespace std;
|
||||
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Library.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
#include "crlcore/Utilities.h"
|
||||
#include "crlcore/CellPath.h"
|
||||
#include "LibertyTechnology.h"
|
||||
#include "LuTable.h"
|
||||
#include "LuTableTemplate.h"
|
||||
using namespace CRL;
|
||||
|
||||
// Symbols from Flex which should be substituted.
|
||||
#define yyrestart LIBERTYrestart
|
||||
#define yytext LIBERTYtext
|
||||
#define yywrap LIBERTYwrap
|
||||
#define yyin LIBERTYin
|
||||
|
||||
extern int yylex ();
|
||||
extern int yywrap ();
|
||||
extern void yyrestart ( FILE* );
|
||||
extern char* yytext;
|
||||
extern FILE* yyin;
|
||||
|
||||
int libertyLineNumber = 1;
|
||||
int yydoubleindex;
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
const char* liberty_filename;
|
||||
|
||||
Library* current_library;
|
||||
Cell* current_cell;
|
||||
Net* current_net;
|
||||
CLibertyTechnology* current_technology;
|
||||
CCellPath* current_cellPath;
|
||||
CLuTableTemplate* current_luTemplate;
|
||||
CLuTable* current_luTable;
|
||||
|
||||
|
||||
Library* start_library(const char* name);
|
||||
void start_cell(const char* name);
|
||||
void start_net(const char* name);
|
||||
|
||||
void start_technology();
|
||||
void register_unit(CLibertyTechnology::Unit,double val,string str);
|
||||
void start_luTemplate(string name);
|
||||
void luTemplate_addVar(unsigned char index,CLuTableTemplate::Variable::Type type);
|
||||
void luTemplate_setVarIndexes(unsigned char index,unsigned short count,double* values);
|
||||
void start_cellPath();
|
||||
void cellPath_setRelatedNet(string name);
|
||||
void cellPath_setType(CCellPath::Type type);
|
||||
void cellPath_riseDelayTable(string name);
|
||||
void cellPath_fallDelayTable(string name);
|
||||
void cellPath_riseTransitionTable(string name);
|
||||
void cellPath_fallTransitionTable(string name);
|
||||
//void cellPath_ignored();
|
||||
void luTable_addValues(unsigned short count, double* values);
|
||||
|
||||
|
||||
void check_net_direction(Net::Direction direction);
|
||||
void set_net_capacitance(double value);
|
||||
|
||||
int yyerror ( const char* message );
|
||||
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
unsigned char _index;
|
||||
int _type;
|
||||
double _value;
|
||||
char _text[1024];
|
||||
double _values[128];
|
||||
}
|
||||
|
||||
%token CLIBP_LIBRARY
|
||||
|
||||
// library statement tokens
|
||||
%token CLIBP_TECHNOLOGY
|
||||
%token CLIBP_DATE
|
||||
%token CLIBP_DELAY_MODEL
|
||||
%token CLIBP_NOM_VOLTAGE
|
||||
%token CLIBP_NOM_TEMPERATURE
|
||||
%token CLIBP_NOM_PROCESS
|
||||
%token CLIBP_SLEW_DERATE_FROM_LIBRARY
|
||||
%token CLIBP_DEFAULT_FANOUT_LOAD
|
||||
%token CLIBP_DEFAULT_INOUT_PIN_CAP
|
||||
%token CLIBP_DEFAULT_INPUT_PIN_CAP
|
||||
%token CLIBP_DEFAULT_OUTPUT_PIN_CAP
|
||||
%token CLIBP_CAPACITIVE_LOAD_UNIT
|
||||
%token CLIBP_VOLTAGE_UNIT
|
||||
%token CLIBP_TIME_UNIT
|
||||
%token CLIBP_PULLING_RESISTANCE_UNIT
|
||||
%token CLIBP_CURRENT_UNIT
|
||||
%token CLIBP_INPUT_THRESHOLD_PCT_RISE
|
||||
%token CLIBP_INPUT_THRESHOLD_PCT_FALL
|
||||
%token CLIBP_OUTPUT_THRESHOLD_PCT_RISE
|
||||
%token CLIBP_OUTPUT_THRESHOLD_PCT_FALL
|
||||
%token CLIBP_SLEW_LOWER_THRESHOLD_PCT_RISE
|
||||
%token CLIBP_SLEW_LOWER_THRESHOLD_PCT_FALL
|
||||
%token CLIBP_SLEW_UPPER_THRESHOLD_PCT_RISE
|
||||
%token CLIBP_SLEW_UPPER_THRESHOLD_PCT_FALL
|
||||
|
||||
// lu table template
|
||||
%token CLIBP_LU_TABLE_TEMPLATE
|
||||
%token CLIBP_VARIABLE_1 CLIBP_VARIABLE_2 CLIBP_VARIABLE_3
|
||||
%token CLIBP_CONSTRAINED_PIN_TRANSITION
|
||||
%token CLIBP_RELATED_PIN_TRANSITION
|
||||
%token CLIBP_INPUT_NET_TRANSITION
|
||||
%token CLIBP_TOTAL_OUTPUT_NET_CAPACITANCE
|
||||
%token CLIBP_INDEX_1 CLIBP_INDEX_2 CLIBP_INDEX_3
|
||||
|
||||
//cell
|
||||
%token CLIBP_CELL
|
||||
%token CLIBP_AREA
|
||||
%token CLIBP_FF CLIBP_CLOCKED_ON CLIBP_NEXT_STATE
|
||||
//cell::pin
|
||||
%token CLIBP_PIN
|
||||
%token CLIBP_DIRECTION CLIBP_INPUT CLIBP_OUTPUT CLIBP_TRISTATE
|
||||
%token CLIBP_FUNCTION CLIBP_THREE_STATE CLIBP_X_FUNCTION
|
||||
%token CLIBP_CAPACITANCE
|
||||
//cell::pin::timing
|
||||
%token CLIBP_TIMING
|
||||
%token CLIBP_RELATED_PIN
|
||||
//cell::pin::timing::timing_sense
|
||||
%token CLIBP_TIMING_SENSE CLIBP_POSITIVE_UNATE CLIBP_NEGATIVE_UNATE
|
||||
//cell::pin::timing::timing_type
|
||||
%token CLIBP_TIMING_TYPE CLIBP_SETUP_RISING CLIBP_HOLD_RISING CLIBP_RISING_EDGE
|
||||
%token CLIBP_THREE_STATE_ENABLE CLIBP_THREE_STATE_DISABLE
|
||||
//cell::pin::timing::lu_tables
|
||||
%token CLIBP_CELL_RISE CLIBP_CELL_FALL CLIBP_VALUES
|
||||
%token CLIBP_RISE_TRANSITION CLIBP_FALL_TRANSITION
|
||||
%token CLIBP_RISE_CONSTRAINT CLIBP_FALL_CONSTRAINT
|
||||
|
||||
//values
|
||||
%token CLIBP_FLOAT CLIBP_STRING CLIBP_NAME CLIBP_FLOAT_LIST
|
||||
%start file
|
||||
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
|
||||
%type<_index> lu_table_template_variable lu_table_template_index
|
||||
%type<_type> lu_table_template_variable_type
|
||||
%type<_value> CLIBP_FLOAT
|
||||
%type<_text> CLIBP_STRING CLIBP_NAME
|
||||
%type<_values> CLIBP_FLOAT_LIST
|
||||
%%
|
||||
|
||||
file: library_header '{' library_content '}' //ok
|
||||
;
|
||||
|
||||
library_header: CLIBP_LIBRARY '(' CLIBP_NAME ')' { if (!start_library($3)) return 0; }
|
||||
;
|
||||
|
||||
library_content: //ok
|
||||
| library_item library_content //ok
|
||||
;
|
||||
|
||||
library_item: library_statement //ok
|
||||
| lu_table_template //ok
|
||||
;
|
||||
|
||||
library_statement: CLIBP_TECHNOLOGY '(' CLIBP_NAME ')' ';' { start_technology(); }
|
||||
| CLIBP_DATE ':' CLIBP_STRING ';'
|
||||
| CLIBP_DELAY_MODEL ':' CLIBP_NAME ';'
|
||||
| CLIBP_NOM_VOLTAGE ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_NOM_TEMPERATURE ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_NOM_PROCESS ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_SLEW_DERATE_FROM_LIBRARY ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_DEFAULT_FANOUT_LOAD ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_DEFAULT_INOUT_PIN_CAP ':' CLIBP_FLOAT ';' //TODO
|
||||
| CLIBP_DEFAULT_INPUT_PIN_CAP ':' CLIBP_FLOAT ';' //TODO
|
||||
| CLIBP_DEFAULT_OUTPUT_PIN_CAP ':' CLIBP_FLOAT ';' //TODO
|
||||
| CLIBP_CAPACITIVE_LOAD_UNIT '(' CLIBP_FLOAT ',' CLIBP_NAME ')' ';'
|
||||
{ register_unit(CLibertyTechnology::Unit::CAPACITANCE,$3,$5); }
|
||||
| CLIBP_VOLTAGE_UNIT ':' CLIBP_STRING ';'
|
||||
| CLIBP_TIME_UNIT ':' CLIBP_STRING ';' { register_unit(CLibertyTechnology::Unit::TIME,0,$3); }
|
||||
| CLIBP_PULLING_RESISTANCE_UNIT ':' CLIBP_STRING ';'
|
||||
| CLIBP_CURRENT_UNIT ':' CLIBP_STRING ';'
|
||||
| CLIBP_INPUT_THRESHOLD_PCT_RISE ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_INPUT_THRESHOLD_PCT_FALL ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_OUTPUT_THRESHOLD_PCT_RISE ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_OUTPUT_THRESHOLD_PCT_FALL ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_SLEW_LOWER_THRESHOLD_PCT_RISE ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_SLEW_LOWER_THRESHOLD_PCT_FALL ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_SLEW_UPPER_THRESHOLD_PCT_RISE ':' CLIBP_FLOAT ';'
|
||||
| CLIBP_SLEW_UPPER_THRESHOLD_PCT_FALL ':' CLIBP_FLOAT ';'
|
||||
;
|
||||
|
||||
lu_table_template: lu_table_template_header '{' lu_table_template_content '}' //ok
|
||||
| cell_header '{' cell_content '}' //ok
|
||||
;
|
||||
|
||||
lu_table_template_header: CLIBP_LU_TABLE_TEMPLATE '(' CLIBP_NAME ')' { start_luTemplate($3); }
|
||||
;
|
||||
|
||||
lu_table_template_content: //ok
|
||||
| lu_table_template_item lu_table_template_content //ok
|
||||
;
|
||||
|
||||
lu_table_template_item: lu_table_template_variable ':' lu_table_template_variable_type ';'
|
||||
{ luTemplate_addVar($1,(CLuTableTemplate::Variable::Type::Code)$3); }
|
||||
| lu_table_template_index '(' CLIBP_FLOAT_LIST ')' ';'
|
||||
{ luTemplate_setVarIndexes($1,yydoubleindex,$3); }
|
||||
;
|
||||
|
||||
lu_table_template_variable: CLIBP_VARIABLE_1 { $$ = 1; }
|
||||
| CLIBP_VARIABLE_2 { $$ = 2; }
|
||||
| CLIBP_VARIABLE_3 { $$ = 3; }
|
||||
;
|
||||
|
||||
lu_table_template_variable_type: CLIBP_CONSTRAINED_PIN_TRANSITION
|
||||
{ $$ = (int)CLuTableTemplate::Variable::Type::CONSTRAINED_PIN_TRANSITION; }
|
||||
| CLIBP_RELATED_PIN_TRANSITION
|
||||
{ $$ = (int)CLuTableTemplate::Variable::Type::RELATED_PIN_TRANSITION; }
|
||||
| CLIBP_INPUT_NET_TRANSITION
|
||||
{ $$ = (int)CLuTableTemplate::Variable::Type::INPUT_NET_TRANSITION; }
|
||||
| CLIBP_TOTAL_OUTPUT_NET_CAPACITANCE
|
||||
{ $$ = (int)CLuTableTemplate::Variable::Type::TOTAL_OUTPUT_NET_CAPACITANCE; }
|
||||
;
|
||||
lu_table_template_index : CLIBP_INDEX_1 { $$ = 1; }
|
||||
| CLIBP_INDEX_2 { $$ = 2; }
|
||||
| CLIBP_INDEX_3 { $$ = 3; }
|
||||
;
|
||||
|
||||
cell_header: CLIBP_CELL '(' CLIBP_NAME ')' { start_cell($3); }
|
||||
;
|
||||
|
||||
cell_content: //ok
|
||||
| cell_item cell_content //ok
|
||||
;
|
||||
|
||||
|
||||
|
||||
cell_item: pin_header '{' pin_content '}' //ok
|
||||
| CLIBP_AREA ':' CLIBP_FLOAT ';' //ignore
|
||||
| CLIBP_FF '(' CLIBP_NAME ',' CLIBP_NAME ')' '{' latch_content '}' //ignore
|
||||
;
|
||||
|
||||
pin_header: CLIBP_PIN '(' CLIBP_NAME ')' { start_net($3); }
|
||||
;
|
||||
|
||||
pin_content: //ok
|
||||
| pin_item pin_content //ok
|
||||
;
|
||||
|
||||
pin_item: CLIBP_DIRECTION ':' direction ';' //ok
|
||||
| CLIBP_CAPACITANCE ':' CLIBP_FLOAT ';' { set_net_capacitance($3);}
|
||||
| timing_header '{' timing_content '}' // ok
|
||||
| CLIBP_FUNCTION ':' CLIBP_STRING ';' // ignore
|
||||
| CLIBP_THREE_STATE ':' CLIBP_STRING ';' // ignore
|
||||
| CLIBP_X_FUNCTION ':' CLIBP_STRING ';' // ignore
|
||||
;
|
||||
|
||||
direction: CLIBP_INPUT { check_net_direction(Net::Direction::IN);}
|
||||
| CLIBP_OUTPUT { check_net_direction(Net::Direction::OUT);}
|
||||
| CLIBP_TRISTATE { check_net_direction(Net::Direction::TRISTATE);}
|
||||
;
|
||||
|
||||
timing_header: CLIBP_TIMING '(' ')' { start_cellPath(); }
|
||||
;
|
||||
|
||||
timing_content: //ok
|
||||
| timing_item timing_content //ok
|
||||
;
|
||||
|
||||
timing_item: CLIBP_RELATED_PIN ':' CLIBP_STRING ';' { cellPath_setRelatedNet($3); }
|
||||
| CLIBP_TIMING_SENSE ':' timing_sense ';' //ok
|
||||
| CLIBP_TIMING_TYPE ':' timing_type ';' //ok
|
||||
| lu_table_header '{' CLIBP_VALUES '(' values ')' ';' '}' //ok
|
||||
;
|
||||
|
||||
timing_sense: CLIBP_POSITIVE_UNATE { cellPath_setType(CCellPath::Type::POSITIVE_UNATE); }
|
||||
| CLIBP_NEGATIVE_UNATE { cellPath_setType(CCellPath::Type::NEGATIVE_UNATE); }
|
||||
;
|
||||
|
||||
timing_type: CLIBP_SETUP_RISING { cellPath_setType(CCellPath::Type::LATCH_SETUP); }
|
||||
| CLIBP_HOLD_RISING { cellPath_setType(CCellPath::Type::LATCH_HOLD); }
|
||||
| CLIBP_RISING_EDGE { cellPath_setType(CCellPath::Type::LATCH_ACCESS); }
|
||||
| CLIBP_THREE_STATE_ENABLE //ignored
|
||||
| CLIBP_THREE_STATE_DISABLE //ignored
|
||||
;
|
||||
|
||||
lu_table_header: CLIBP_CELL_RISE '(' CLIBP_NAME ')' { cellPath_riseDelayTable($3); }
|
||||
| CLIBP_CELL_FALL '(' CLIBP_NAME ')' { cellPath_fallDelayTable($3); }
|
||||
| CLIBP_RISE_CONSTRAINT '(' CLIBP_NAME ')' { cellPath_riseDelayTable($3); }
|
||||
| CLIBP_FALL_CONSTRAINT '(' CLIBP_NAME ')' { cellPath_fallDelayTable($3); }
|
||||
| CLIBP_RISE_TRANSITION '(' CLIBP_NAME ')' { cellPath_riseTransitionTable($3); }
|
||||
| CLIBP_FALL_TRANSITION '(' CLIBP_NAME ')' { cellPath_fallTransitionTable($3); }
|
||||
;
|
||||
|
||||
values: CLIBP_FLOAT_LIST { luTable_addValues(yydoubleindex,$1); }
|
||||
| values ',' CLIBP_FLOAT_LIST { luTable_addValues(yydoubleindex,$3); }
|
||||
;
|
||||
|
||||
latch_content : //ignored
|
||||
| latch_item latch_content //ignored
|
||||
;
|
||||
|
||||
latch_item : CLIBP_CLOCKED_ON ':' CLIBP_STRING ';' //ignored
|
||||
| CLIBP_NEXT_STATE ':' CLIBP_STRING ';' //ignored
|
||||
;
|
||||
%%
|
||||
|
||||
namespace {
|
||||
|
||||
Library* find_library(Library* containing_library,string name)
|
||||
// ***********************************************************
|
||||
{
|
||||
Library* library=containing_library->getLibrary(name);
|
||||
|
||||
if (library)
|
||||
return library;
|
||||
|
||||
for_each_library(sub_library,containing_library->getLibraries())
|
||||
{
|
||||
library=find_library(sub_library,name);
|
||||
if (library)
|
||||
return library;
|
||||
end_for;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Library* start_library(const char* name)
|
||||
// *************************************
|
||||
{
|
||||
current_library=NULL;
|
||||
|
||||
DataBase *database= DataBase::getDB();
|
||||
if (!database)
|
||||
throw Error("LibertyParser(): No DataBase found !");
|
||||
current_library=find_library(database->getRootLibrary(),name);
|
||||
//ltrace(364) << " o Library " << name << " (" << current_library << ")" << endl;
|
||||
if (current_library)
|
||||
cmess1 << " - loading timing caracteristics for library " << current_library->getName() << endl;
|
||||
else
|
||||
cmess1 << "Warning : cannot load timing caracteristics for library " << name << endl;
|
||||
|
||||
return current_library; //Will abort parsing if null
|
||||
}
|
||||
|
||||
void start_cell(const char* name)
|
||||
// ******************************
|
||||
{
|
||||
//current_cell=NULL;
|
||||
//if (!current_library) return;
|
||||
|
||||
current_cell = current_library->getCell(name);
|
||||
//ltrace(363) << " - Cell " << name << " (" << current_cell << ")" << endl;
|
||||
if (current_cell)
|
||||
cmess2 << " - cell " << current_cell->getName() << endl;
|
||||
}
|
||||
|
||||
void start_net(const char* name)
|
||||
// *****************************
|
||||
{
|
||||
current_net=NULL;
|
||||
if (!current_cell) return;
|
||||
|
||||
current_net= current_cell->getNet(name);
|
||||
//ltrace(362) << " * Net " << name << " (" << current_net << ")" << endl;
|
||||
if (!current_net)
|
||||
throw Error("LibertyParser(): No net "+getString(name)+" in cell "+getString(current_cell->getName()));
|
||||
}
|
||||
|
||||
void start_technology()
|
||||
// ********************
|
||||
{
|
||||
//current_technology=NULL;
|
||||
//if (!current_library) return;
|
||||
|
||||
current_technology=CLibertyTechnology::create();
|
||||
current_library->put(current_technology);
|
||||
}
|
||||
|
||||
void register_unit(CLibertyTechnology::Unit unit,double val,string str)
|
||||
// ********************************************************************
|
||||
{
|
||||
char unit_mod;
|
||||
double mod;
|
||||
istringstream iss(str);
|
||||
if (val == 0)
|
||||
iss >> val;
|
||||
iss >> unit_mod;
|
||||
switch (unit_mod) {
|
||||
case 'G':
|
||||
mod= 1e9;break;
|
||||
case 'M':
|
||||
mod= 1e6;break;
|
||||
case 'k':
|
||||
mod= 1e3;break;
|
||||
case 'm':
|
||||
mod= 1e-3;break;
|
||||
case 'u':
|
||||
mod= 1e-6;break;
|
||||
case 'n':
|
||||
mod= 1e-9;break;
|
||||
case 'p':
|
||||
mod= 1e-12;break;
|
||||
case 'f':
|
||||
mod= 1e-15;break;
|
||||
default:
|
||||
mod= 1;
|
||||
}
|
||||
current_technology->SetUnit(unit,val*mod);
|
||||
}
|
||||
|
||||
void start_luTemplate(string name)
|
||||
// *******************************
|
||||
{
|
||||
if (!current_technology)
|
||||
throw Error("LibertyParser error : cannot create luTemplate (no CLibertyTechnology)");
|
||||
current_luTemplate = CLuTableTemplate::create(name,current_technology);
|
||||
}
|
||||
|
||||
void luTemplate_addVar(unsigned char index,CLuTableTemplate::Variable::Type type)
|
||||
// ******************************************************************************
|
||||
{
|
||||
if (current_luTemplate)
|
||||
current_luTemplate->AddVariable(index,type);
|
||||
else
|
||||
throw Error("LibertyParser error : adding variable to undefined luTable template");
|
||||
}
|
||||
|
||||
void luTemplate_setVarIndexes(unsigned char index,unsigned short count,double* values)
|
||||
// ***********************************************************************************
|
||||
{
|
||||
if (current_luTemplate)
|
||||
current_luTemplate->SetVariableIndexes(index,count,values);
|
||||
else
|
||||
throw Error("LibertyParser error : setting variable indexes to undefined luTable template");
|
||||
}
|
||||
|
||||
|
||||
void start_cellPath()
|
||||
// ******************
|
||||
{
|
||||
current_cellPath = NULL;
|
||||
if (!current_net) return;
|
||||
//ltrace(361) << " CCellPath " << current_net << endl;
|
||||
|
||||
current_cellPath = CCellPath::create(current_net);
|
||||
}
|
||||
|
||||
void cellPath_setRelatedNet(string name)
|
||||
// *************************************
|
||||
{
|
||||
if (!current_cellPath) return; //current timing bloc is beeing ignored
|
||||
|
||||
Cell* cell = current_cellPath->getNet()->getCell();
|
||||
Net* relatedNet= cell->getNet(name);
|
||||
if (!relatedNet)
|
||||
{
|
||||
string msg ="No net "+name+" in cell "+getString(cell->getName());
|
||||
yyerror(msg.c_str());
|
||||
}
|
||||
//ltrace(360) << " Related Net : " << relatedNet << endl;
|
||||
current_cellPath->_setRelatedNet(relatedNet);
|
||||
}
|
||||
|
||||
void cellPath_setType(CCellPath::Type type)
|
||||
// ****************************************
|
||||
{
|
||||
if (!current_cellPath) return; //current timing bloc is beeing ignored
|
||||
|
||||
current_cellPath->_setType(type);
|
||||
//ltrace(360) << " Type : " << getString(type) << endl;
|
||||
}
|
||||
|
||||
CLuTableTemplate* cellPath_gettemplate(string name)
|
||||
// ************************************************
|
||||
{
|
||||
CLuTableTemplate* lutemplate = current_technology->getTemplate(name);
|
||||
if (lutemplate == NULL)
|
||||
{
|
||||
string message = "Undefined LuTableTemplate : "+name;
|
||||
yyerror(message.c_str());
|
||||
}
|
||||
return lutemplate;
|
||||
}
|
||||
|
||||
|
||||
void cellPath_riseDelayTable(string name)
|
||||
// **************************************
|
||||
{
|
||||
current_luTable=NULL;
|
||||
if (!current_cellPath) return; //current timing bloc is beeing ignored
|
||||
|
||||
//ltrace(360) << " Rise Delay Table" << endl;
|
||||
current_luTable = current_cellPath->_createRiseDelayTable(cellPath_gettemplate(name));
|
||||
}
|
||||
|
||||
void cellPath_fallDelayTable(string name)
|
||||
// **************************************
|
||||
{
|
||||
current_luTable=NULL;
|
||||
if (!current_cellPath) return; //current timing bloc is beeing ignored
|
||||
|
||||
//ltrace(360) << " Fall Delay Table" << endl;
|
||||
current_luTable = current_cellPath->_createFallDelayTable(cellPath_gettemplate(name));
|
||||
}
|
||||
|
||||
void cellPath_riseTransitionTable(string name)
|
||||
// *******************************************
|
||||
{
|
||||
current_luTable=NULL;
|
||||
if (!current_cellPath) return; //current timing bloc is beeing ignored
|
||||
|
||||
//ltrace(360) << " Rise Transition Table" << endl;
|
||||
current_luTable = current_cellPath->_createRiseTransitionTable(cellPath_gettemplate(name));
|
||||
}
|
||||
|
||||
void cellPath_fallTransitionTable(string name)
|
||||
// *******************************************
|
||||
{
|
||||
current_luTable=NULL;
|
||||
if (!current_cellPath) return; //current timing bloc is beeing ignored
|
||||
|
||||
//ltrace(360) << " Fall Transition Table" << endl;
|
||||
current_luTable = current_cellPath->_createFallTransitionTable(cellPath_gettemplate(name));
|
||||
}
|
||||
|
||||
#if 0
|
||||
void cellPath_ignored()
|
||||
// ********************
|
||||
{
|
||||
current_luTable=NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void luTable_addValues(unsigned short count, double* values)
|
||||
// *********************************************************
|
||||
{
|
||||
if (!current_luTable) return;
|
||||
|
||||
current_luTable->AddValues(count,values);
|
||||
}
|
||||
|
||||
void check_net_direction(Net::Direction direction)
|
||||
// ***********************************************
|
||||
{
|
||||
if (!current_net) return;
|
||||
|
||||
if (current_net->getDirection() != direction)
|
||||
yyerror("Wrong net direction");
|
||||
}
|
||||
|
||||
Name NetCapacitancePropName("Coriolis::NetCapacitance");
|
||||
|
||||
void set_net_capacitance(double value)
|
||||
// ***********************************
|
||||
{
|
||||
if (!current_net) return;
|
||||
|
||||
Property* property = current_net->getProperty(NetCapacitancePropName);
|
||||
if (property)
|
||||
{
|
||||
yyerror("Capacitance already set");
|
||||
}
|
||||
else
|
||||
{
|
||||
property = StandardPrivateProperty<double>::create(NetCapacitancePropName, value);
|
||||
current_net->put(property);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int yyerror ( const char* message )
|
||||
// *********************************
|
||||
{
|
||||
throw Error ( "LibertyParser():\n%s:%d: %s before %s.\n"
|
||||
,liberty_filename,libertyLineNumber,message,yytext);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
namespace CRL {
|
||||
|
||||
void LibertyParser ( const string& libPath)
|
||||
// ****************************************
|
||||
{
|
||||
liberty_filename=libPath.c_str();
|
||||
yyin = fopen(liberty_filename,"r");
|
||||
if (!yyin) {
|
||||
string errstr = strerror(errno);
|
||||
throw Error (libPath+": "+errstr);
|
||||
}
|
||||
//ltrace(365) << "LibertyParser : " << libPath << endl; ltracein(390);
|
||||
yyparse();
|
||||
//ltraceout(365);
|
||||
//ltrace(365) << libPath << " : parsing complete" << endl;
|
||||
}
|
||||
|
||||
double getNetCapacitance(const Net* net)
|
||||
// *************************************
|
||||
{
|
||||
Property* property = net->getProperty(NetCapacitancePropName);
|
||||
if (!property)
|
||||
{
|
||||
throw Error("Can't get capacitance for net "+getString(net->getName())+" : no such property");
|
||||
}
|
||||
|
||||
if (!dynamic_cast<StandardPrivateProperty<double>*>(property))
|
||||
throw Error("Can't get capacitance for net "+getString(net->getName())+" : bad property type");
|
||||
|
||||
double value=(static_cast<StandardPrivateProperty<double>*>(property))->getValue();
|
||||
|
||||
Property* technology_property = net->getCell()->getLibrary()->getProperty(CLibertyTechnology::getPropertyName());
|
||||
if (!technology_property) throw Error("Library " + getString(net->getCell()->getLibrary()->getName())+" has no CLibertyTechnology");
|
||||
if (!dynamic_cast<CLibertyTechnology*>(technology_property)) throw Error(getString(CLibertyTechnology::getPropertyName())+" : Invalid Property Type");
|
||||
|
||||
return value * static_cast<CLibertyTechnology*>(technology_property)->getUnit(CLibertyTechnology::Unit::CAPACITANCE);
|
||||
}
|
||||
|
||||
void LibertyParserError(string message)
|
||||
// ***********************************
|
||||
{
|
||||
yyerror(message.c_str());
|
||||
}
|
||||
|
||||
} //namespace CRL
|
|
@ -0,0 +1,175 @@
|
|||
%{
|
||||
#include "LibertyParserGrammar.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern int libertyLineNumber;
|
||||
extern int yydoubleindex;
|
||||
%}
|
||||
|
||||
%x COMM
|
||||
%x FLOAT_STRING
|
||||
%%
|
||||
|
||||
<INITIAL>[ \t]+
|
||||
<INITIAL>"/*" { BEGIN(COMM); }
|
||||
<COMM>.
|
||||
<COMM>"*/" { BEGIN(INITIAL); }
|
||||
<INITIAL,COMM>\n { libertyLineNumber++; }
|
||||
<INITIAL,COMM>\\\n { libertyLineNumber++; }
|
||||
|
||||
|
||||
<INITIAL>[lL][iI][bB][rR][aA][rR][yY] { return CLIBP_LIBRARY; }
|
||||
|
||||
<INITIAL>[tT][eE][cC][hH][nN][oO][lL][oO][gG][yY] { return CLIBP_TECHNOLOGY; }
|
||||
<INITIAL>[dD][aA][tT][eE] { return CLIBP_DATE; }
|
||||
<INITIAL>[dD][eE][lL][aA][yY]_[mM][oO][dD][eE][lL] { return CLIBP_DELAY_MODEL; }
|
||||
<INITIAL>[nN][oO][mM]_[vV][oO][lL][tT][aA][gG][eE] { return CLIBP_NOM_VOLTAGE; }
|
||||
<INITIAL>[nN][oO][mM]_[tT][eE][mM][pP][eE][rR][aA][tT][uU][rR][eE] {
|
||||
return CLIBP_NOM_TEMPERATURE; }
|
||||
<INITIAL>[nN][oO][mM]_[pP][rR][oO][cC][eE][sS][sS] { return CLIBP_NOM_PROCESS; }
|
||||
<INITIAL>[sS][lL][eE][wW]_[dD][eE][rR][aA][tT][eE]_[fF][rR][oO][mM]_[lL][iI][bB][rR][aA][rR][yY] {
|
||||
return CLIBP_SLEW_DERATE_FROM_LIBRARY; }
|
||||
<INITIAL>[dD][eE][fF][aA][uU][lL][tT]_[fF][aA][nN][oO][uU][tT]_[lL][oO][aA][dD] {
|
||||
return CLIBP_DEFAULT_FANOUT_LOAD; }
|
||||
<INITIAL>[dD][eE][fF][aA][uU][lL][tT]_[iI][nN][oO][uU][tT]_[pP][iI][nN]_[cC][aA][pP] {
|
||||
return CLIBP_DEFAULT_INOUT_PIN_CAP; }
|
||||
<INITIAL>[dD][eE][fF][aA][uU][lL][tT]_[iI][nN][pP][uU][tT]_[pP][iI][nN]_[cC][aA][pP] {
|
||||
return CLIBP_DEFAULT_INPUT_PIN_CAP; }
|
||||
<INITIAL>[dD][eE][fF][aA][uU][lL][tT]_[oO][uU][tT][pP][uU][tT]_[pP][iI][nN]_[cC][aA][pP] {
|
||||
return CLIBP_DEFAULT_OUTPUT_PIN_CAP; }
|
||||
<INITIAL>[cC][aA][pP][aA][cC][iI][tT][iI][vV][eE]_[lL][oO][aA][dD]_[uU][nN][iI][tT] {
|
||||
return CLIBP_CAPACITIVE_LOAD_UNIT; }
|
||||
<INITIAL>[vV][oO][lL][tT][aA][gG][eE]_[uU][nN][iI][tT] {
|
||||
return CLIBP_VOLTAGE_UNIT; }
|
||||
<INITIAL>[tT][iI][mM][eE]_[uU][nN][iI][tT] { return CLIBP_TIME_UNIT; }
|
||||
<INITIAL>[pP][uU][lL][lL][iI][nN][gG]_[rR][eE][sS][iI][sS][tT][aA][nN][cC][eE]_[uU][nN][iI][tT] {
|
||||
return CLIBP_PULLING_RESISTANCE_UNIT; }
|
||||
<INITIAL>[cC][uU][rR][rR][eE][nN][tT]_[uU][nN][iI][tT] {
|
||||
return CLIBP_CURRENT_UNIT; }
|
||||
<INITIAL>[iI][nN][pP][uU][tT]_[tT][hH][rR][eE][sS][hH][oO][lL][dD]_[pP][cC][tT]_[rR][iI][sS][eE] {
|
||||
return CLIBP_INPUT_THRESHOLD_PCT_RISE; }
|
||||
<INITIAL>[iI][nN][pP][uU][tT]_[tT][hH][rR][eE][sS][hH][oO][lL][dD]_[pP][cC][tT]_[fF][aA][lL][lL] {
|
||||
return CLIBP_INPUT_THRESHOLD_PCT_FALL; }
|
||||
<INITIAL>[oO][uU][tT][pP][uU][tT]_[tT][hH][rR][eE][sS][hH][oO][lL][dD]_[pP][cC][tT]_[rR][iI][sS][eE] {
|
||||
return CLIBP_OUTPUT_THRESHOLD_PCT_RISE; }
|
||||
<INITIAL>[oO][uU][tT][pP][uU][tT]_[tT][hH][rR][eE][sS][hH][oO][lL][dD]_[pP][cC][tT]_[fF][aA][lL][lL] {
|
||||
return CLIBP_OUTPUT_THRESHOLD_PCT_FALL; }
|
||||
<INITIAL>[sS][lL][eE][wW]_[lL][oO][wW][eE][rR]_[tT][hH][rR][eE][sS][hH][oO][lL][dD]_[pP][cC][tT]_[rR][iI][sS][eE] {
|
||||
return CLIBP_SLEW_LOWER_THRESHOLD_PCT_RISE; }
|
||||
<INITIAL>[sS][lL][eE][wW]_[lL][oO][wW][eE][rR]_[tT][hH][rR][eE][sS][hH][oO][lL][dD]_[pP][cC][tT]_[fF][aA][lL][lL] {
|
||||
return CLIBP_SLEW_LOWER_THRESHOLD_PCT_FALL; }
|
||||
<INITIAL>[sS][lL][eE][wW]_[uU][pP][pP][eE][rR]_[tT][hH][rR][eE][sS][hH][oO][lL][dD]_[pP][cC][tT]_[rR][iI][sS][eE] {
|
||||
return CLIBP_SLEW_UPPER_THRESHOLD_PCT_RISE; }
|
||||
<INITIAL>[sS][lL][eE][wW]_[uU][pP][pP][eE][rR]_[tT][hH][rR][eE][sS][hH][oO][lL][dD]_[pP][cC][tT]_[fF][aA][lL][lL] {
|
||||
return CLIBP_SLEW_UPPER_THRESHOLD_PCT_FALL; }
|
||||
|
||||
<INITIAL>[lL][uU]_[tT][aA][bB][lL][eE]_[tT][eE][mM][pP][lL][aA][tT][eE] {
|
||||
return CLIBP_LU_TABLE_TEMPLATE; }
|
||||
|
||||
<INITIAL>[vV][aA][rR][iI][aA][bB][lL][eE]_1 { return CLIBP_VARIABLE_1; }
|
||||
<INITIAL>[vV][aA][rR][iI][aA][bB][lL][eE]_2 { return CLIBP_VARIABLE_2; }
|
||||
<INITIAL>[vV][aA][rR][iI][aA][bB][lL][eE]_3 { return CLIBP_VARIABLE_3; }
|
||||
|
||||
<INITIAL>[cC][oO][nN][sS][tT][rR][aA][iI][nN][eE][dD]_[pP][iI][nN]_[tT][rR][aA][nN][sS][iI][tT][iI][oO][nN] {
|
||||
return CLIBP_CONSTRAINED_PIN_TRANSITION; }
|
||||
<INITIAL>[rR][eE][lL][aA][tT][eE][dD]_[pP][iI][nN]_[tT][rR][aA][nN][sS][iI][tT][iI][oO][nN] {
|
||||
return CLIBP_RELATED_PIN_TRANSITION; }
|
||||
<INITIAL>[iI][nN][pP][uU][tT]_[nN][eE][tT]_[tT][rR][aA][nN][sS][iI][tT][iI][oO][nN] {
|
||||
return CLIBP_INPUT_NET_TRANSITION; }
|
||||
<INITIAL>[tT][oO][tT][aA][lL]_[oO][uU][tT][pP][uU][tT]_[nN][eE][tT]_[cC][aA][pP][aA][cC][iI][tT][aA][nN][cC][eE] {
|
||||
return CLIBP_TOTAL_OUTPUT_NET_CAPACITANCE; }
|
||||
|
||||
<INITIAL>[iI][nN][dD][eE][xX]_1 { return CLIBP_INDEX_1; }
|
||||
<INITIAL>[iI][nN][dD][eE][xX]_2 { return CLIBP_INDEX_2; }
|
||||
<INITIAL>[iI][nN][dD][eE][xX]_3 { return CLIBP_INDEX_3; }
|
||||
|
||||
<INITIAL>[cC][eE][lL][lL] { return CLIBP_CELL; }
|
||||
<INITIAL>[aA][rR][eE][aA] { return CLIBP_AREA; }
|
||||
|
||||
<INITIAL>[fF][fF] { return CLIBP_FF; }
|
||||
<INITIAL>[cC][lL][oO][cC][kK][eE][dD]_[oO][nN] { return CLIBP_CLOCKED_ON; }
|
||||
<INITIAL>[nN][eE][xX][tT]_[sS][tT][aA][tT][eE] { return CLIBP_NEXT_STATE; }
|
||||
|
||||
<INITIAL>[pP][iI][nN] { return CLIBP_PIN; }
|
||||
<INITIAL>[dD][iI][rR][eE][cC][tT][iI][oO][nN] { return CLIBP_DIRECTION; }
|
||||
<INITIAL>[iI][nN][pP][uU][tT] { return CLIBP_INPUT; }
|
||||
<INITIAL>[oO][uU][tT][pP][uU][tT] { return CLIBP_OUTPUT; }
|
||||
<INITIAL>[tT][rR][iI][sS][tT][aA][tT][eE] { return CLIBP_TRISTATE; }
|
||||
|
||||
<INITIAL>[cC][aA][pP][aA][cC][iI][tT][aA][nN][cC][eE] {
|
||||
return CLIBP_CAPACITANCE; }
|
||||
<INITIAL>[fF][uU][nN][cC][tT][iI][oO][nN] { return CLIBP_FUNCTION; }
|
||||
<INITIAL>[tT][hH][rR][eE][eE]_[sS][tT][aA][tT][eE] { return CLIBP_THREE_STATE; }
|
||||
<INITIAL>[xX]_[fF][uU][nN][cC][tT][iI][oO][nN] { return CLIBP_X_FUNCTION; }
|
||||
|
||||
<INITIAL>[tT][iI][mM][iI][nN][gG] { return CLIBP_TIMING; }
|
||||
<INITIAL>[rR][eE][lL][aA][tT][eE][dD]_[pP][iI][nN] { return CLIBP_RELATED_PIN; }
|
||||
<INITIAL>[tT][iI][mM][iI][nN][gG]_[sS][eE][nN][sS][eE] {
|
||||
return CLIBP_TIMING_SENSE; }
|
||||
<INITIAL>[tT][iI][mM][iI][nN][gG]_[tT][yY][pP][eE] { return CLIBP_TIMING_TYPE; }
|
||||
<INITIAL>[pP][oO][sS][iI][tT][iI][vV][eE]_[uU][nN][aA][tT][eE] {
|
||||
return CLIBP_POSITIVE_UNATE; }
|
||||
<INITIAL>[nN][eE][gG][aA][tT][iI][vV][eE]_[uU][nN][aA][tT][eE] {
|
||||
return CLIBP_NEGATIVE_UNATE; }
|
||||
<INITIAL>[sS][eE][tT][uU][pP]_[rR][iI][sS][iI][nN][gG] {
|
||||
return CLIBP_SETUP_RISING; }
|
||||
<INITIAL>[hH][oO][lL][dD]_[rR][iI][sS][iI][nN][gG] { return CLIBP_HOLD_RISING; }
|
||||
<INITIAL>[rR][iI][sS][iI][nN][gG]_[eE][dD][gG][eE] { return CLIBP_RISING_EDGE; }
|
||||
<INITIAL>[tT][hH][rR][eE][eE]_[sS][tT][aA][tT][eE]_[eE][nN][aA][bB][lL][eE] {
|
||||
return CLIBP_THREE_STATE_ENABLE; }
|
||||
<INITIAL>[tT][hH][rR][eE][eE]_[sS][tT][aA][tT][eE]_[dD][iI][sS][aA][bB][lL][eE] {
|
||||
return CLIBP_THREE_STATE_DISABLE; }
|
||||
<INITIAL>[cC][eE][lL][lL]_[rR][iI][sS][eE] { return CLIBP_CELL_RISE; }
|
||||
<INITIAL>[cC][eE][lL][lL]_[fF][aA][lL][lL] { return CLIBP_CELL_FALL; }
|
||||
<INITIAL>[rR][iI][sS][eE]_[cC][oO][nN][sS][tT][rR][aA][iI][nN][tT] {
|
||||
return CLIBP_RISE_CONSTRAINT; }
|
||||
<INITIAL>[fF][aA][lL][lL]_[cC][oO][nN][sS][tT][rR][aA][iI][nN][tT] {
|
||||
return CLIBP_FALL_CONSTRAINT; }
|
||||
<INITIAL>[rR][iI][sS][eE]_[tT][rR][aA][nN][sS][iI][tT][iI][oO][nN] {
|
||||
return CLIBP_RISE_TRANSITION; }
|
||||
<INITIAL>[fF][aA][lL][lL]_[tT][rR][aA][nN][sS][iI][tT][iI][oO][nN] {
|
||||
return CLIBP_FALL_TRANSITION; }
|
||||
<INITIAL>[vV][aA][lL][uU][eE][sS] { return CLIBP_VALUES; }
|
||||
|
||||
|
||||
|
||||
|
||||
<INITIAL>-?[0-9]+(\.[0-9]+)?([eE][+-]?[0-9])? {
|
||||
LIBERTYlval._value=atof(yytext);
|
||||
return CLIBP_FLOAT; }
|
||||
|
||||
/*<INITIAL>[a-zA-Z][a-zA-Z0-9_]*\.lib {
|
||||
strcpy(LIBERTYlval._text,yytext);
|
||||
LIBERTYlval._text[strlen(LIBERTYlval._text)-4]='\0';
|
||||
return CLIBP_LIBNAME; } */
|
||||
|
||||
<INITIAL>[a-zA-Z][a-zA-Z0-9_]* {
|
||||
strcpy(LIBERTYlval._text,yytext);
|
||||
return CLIBP_NAME; }
|
||||
|
||||
<INITIAL>\"-?[0-9]+(\.[0-9]+)?(,\ -?[0-9]+(\.[0-9]+)?)+\" {
|
||||
yydoubleindex=0;
|
||||
BEGIN(FLOAT_STRING);
|
||||
yyless(1); }
|
||||
|
||||
<FLOAT_STRING>[ ,]*
|
||||
|
||||
<FLOAT_STRING>-?[0-9]+(\.[0-9]+)? {
|
||||
LIBERTYlval._values[yydoubleindex++]=atof(yytext); }
|
||||
|
||||
<FLOAT_STRING>\" {
|
||||
BEGIN(INITIAL);
|
||||
return CLIBP_FLOAT_LIST; }
|
||||
|
||||
|
||||
<INITIAL>\"[^\"]*\" {
|
||||
strcpy(LIBERTYlval._text,yytext+1);
|
||||
LIBERTYlval._text[strlen(LIBERTYlval._text)-1]='\0';
|
||||
return CLIBP_STRING; }
|
||||
|
||||
<INITIAL>. { return *yytext; }
|
||||
|
||||
%%
|
||||
int yywrap() { return -1; }
|
|
@ -0,0 +1,204 @@
|
|||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
//
|
||||
// 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 : 15/05/2007
|
||||
// Author : Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
#include "hurricane/Error.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
#include "LibertyTechnology.h"
|
||||
|
||||
|
||||
namespace {
|
||||
using namespace CRL;
|
||||
|
||||
map<CLuTableTemplate::Variable::Type,CLibertyTechnology::Unit> __grandeurs;
|
||||
|
||||
void Init()
|
||||
// ********
|
||||
{
|
||||
static bool done=false;
|
||||
__grandeurs[CLuTableTemplate::Variable::Type::CONSTRAINED_PIN_TRANSITION]= CLibertyTechnology::Unit::TIME;
|
||||
__grandeurs[CLuTableTemplate::Variable::Type::RELATED_PIN_TRANSITION]= CLibertyTechnology::Unit::TIME;
|
||||
__grandeurs[CLuTableTemplate::Variable::Type::INPUT_NET_TRANSITION]= CLibertyTechnology::Unit::TIME;
|
||||
__grandeurs[CLuTableTemplate::Variable::Type::TOTAL_OUTPUT_NET_CAPACITANCE]= CLibertyTechnology::Unit::CAPACITANCE;
|
||||
done=true;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
namespace CRL {
|
||||
|
||||
CLibertyTechnology::CLibertyTechnology()
|
||||
// *************************************
|
||||
: Inherit()
|
||||
, _templates()
|
||||
, _units()
|
||||
{
|
||||
}
|
||||
|
||||
CLibertyTechnology* CLibertyTechnology::create()
|
||||
// *********************************************
|
||||
{
|
||||
CLibertyTechnology* technology = new CLibertyTechnology();
|
||||
|
||||
technology->_postCreate();
|
||||
|
||||
return technology;
|
||||
}
|
||||
|
||||
void CLibertyTechnology::_postCreate()
|
||||
// ***********************************
|
||||
{
|
||||
Inherit::_postCreate();
|
||||
Init();
|
||||
}
|
||||
|
||||
Name CLibertyTechnology::getName() const
|
||||
// *************************************
|
||||
{
|
||||
return getPropertyName();
|
||||
}
|
||||
|
||||
const Name& CLibertyTechnology::getPropertyName()
|
||||
// **********************************************
|
||||
{
|
||||
static Name NAME = "Coriolis::CLibertyTechnology";
|
||||
return NAME;
|
||||
}
|
||||
|
||||
string CLibertyTechnology::_getString() const
|
||||
// ******************************************
|
||||
{
|
||||
string s = Inherit::_getString();
|
||||
s.insert(s.length() - 1, " " + getString(getOwner()));
|
||||
return s;
|
||||
}
|
||||
|
||||
Record* CLibertyTechnology::_getRecord() const
|
||||
// *************************************
|
||||
{
|
||||
Record* record = Inherit::_getRecord();
|
||||
if (record) {
|
||||
//record->add(getSlot("Units", &_units));
|
||||
//record->add(getSlot("Fundamental Quantities Map", &__grandeurs));
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
CLuTableTemplate* CLibertyTechnology::getTemplate(string name) const
|
||||
// *****************************************************************
|
||||
{
|
||||
static CLuTableTemplate searchTemplate(name,NULL);
|
||||
|
||||
searchTemplate._name=name;
|
||||
|
||||
TemplateSet::iterator tit = _templates.find(&searchTemplate);
|
||||
|
||||
if (tit != _templates.end()) return *tit;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
double CLibertyTechnology::getUnit(Unit unit) const
|
||||
// ************************************************
|
||||
{
|
||||
map<Unit,double>::const_iterator cit=_units.find(unit);
|
||||
if (cit == _units.end())
|
||||
throw Error("Unknown unit unit");
|
||||
return cit->second;
|
||||
}
|
||||
|
||||
double CLibertyTechnology::getUnit(CLuTableTemplate::Variable::Type type) const
|
||||
// ****************************************************************************
|
||||
{
|
||||
if (__grandeurs.find(type) == __grandeurs.end())
|
||||
throw Error("Oups : variable unit "+getString(type)+" not registered (in CLibertyTechnology::Init())");
|
||||
|
||||
return getUnit(__grandeurs[type]);
|
||||
}
|
||||
|
||||
void CLibertyTechnology::AddTemplate(CLuTableTemplate* lutemplate)
|
||||
// ***************************************************************
|
||||
{
|
||||
_templates.insert(lutemplate);
|
||||
}
|
||||
|
||||
void CLibertyTechnology::SetUnit(Unit unit,double val)
|
||||
// ***************************************************
|
||||
{
|
||||
ltrace(359) << "Setting Unit " << getString((long)unit) << " = " << val << endl;
|
||||
_units[unit]=val;
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
// CLibertyTechnology::Unit definition
|
||||
// ****************************************************************************************************
|
||||
|
||||
CLibertyTechnology::Unit::Unit(const Code& code)
|
||||
// *********************************************
|
||||
: _code(code)
|
||||
{
|
||||
}
|
||||
|
||||
CLibertyTechnology::Unit::Unit(const CLibertyTechnology::Unit& unit)
|
||||
// *****************************************************************
|
||||
: _code(unit._code)
|
||||
{
|
||||
}
|
||||
|
||||
CLibertyTechnology::Unit& CLibertyTechnology::Unit::operator=(const CLibertyTechnology::Unit& unit)
|
||||
// ************************************************************************************************
|
||||
{
|
||||
_code = unit._code;
|
||||
return *this;
|
||||
}
|
||||
|
||||
string CLibertyTechnology::Unit::_getString() const
|
||||
// ************************************************
|
||||
{
|
||||
switch (_code) {
|
||||
case TIME : return "TIME";
|
||||
case CAPACITANCE: return "CAPACITANCE";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "ABNORMAL";
|
||||
}
|
||||
|
||||
Record* CLibertyTechnology::Unit::_getRecord() const
|
||||
// *******************************************
|
||||
{
|
||||
Record* record = new Record(getString((long)this));
|
||||
record->add(getSlot("Code", (unsigned*)&_code));
|
||||
return record;
|
||||
}
|
||||
|
||||
} //namespace CRL
|
|
@ -0,0 +1,129 @@
|
|||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
//
|
||||
// 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 : 15/05/2007
|
||||
// Author : Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
#ifndef CRL_CLIBERTYTECHNOLOGY_H
|
||||
#define CRL_CLIBERTYTECHNOLOGY_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "hurricane/Property.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
#include "LuTableTemplate.h"
|
||||
# include "hurricane/Slot.h"
|
||||
|
||||
namespace CRL {
|
||||
|
||||
class CLibertyTechnology : public PrivateProperty {
|
||||
|
||||
// Types
|
||||
// *****
|
||||
|
||||
public:typedef PrivateProperty Inherit;
|
||||
|
||||
public: class Unit {
|
||||
// *****************
|
||||
|
||||
public: enum Code {UNDEFINED=0, TIME=1, CAPACITANCE=2};
|
||||
|
||||
private: Code _code;
|
||||
|
||||
public: Unit(const Code& code = UNDEFINED);
|
||||
public: Unit(const Unit& unit);
|
||||
|
||||
public: Unit& operator=(const Unit& unit);
|
||||
|
||||
public: operator const Code&() const {return _code;};
|
||||
|
||||
public: const Code& getCode() const {return _code;};
|
||||
|
||||
public: string _getString() const;
|
||||
public: Record* _getRecord() const;
|
||||
|
||||
};
|
||||
|
||||
public: struct TemplateComp : public binary_function<const CLuTableTemplate*, const CLuTableTemplate*, bool> {
|
||||
// **********************************************************************************************************
|
||||
|
||||
public:bool operator() (const CLuTableTemplate* t1,const CLuTableTemplate* t2) const
|
||||
{
|
||||
return (t1->getName() < t2->getName());
|
||||
}
|
||||
};
|
||||
|
||||
public:typedef set<CLuTableTemplate*,TemplateComp> TemplateSet;
|
||||
|
||||
// Attributes
|
||||
// **********
|
||||
|
||||
private:TemplateSet _templates;
|
||||
private:map<Unit,double> _units;
|
||||
|
||||
// Constructor
|
||||
// ***********
|
||||
|
||||
protected:CLibertyTechnology();
|
||||
|
||||
public:static CLibertyTechnology* create();
|
||||
|
||||
// Accessors
|
||||
// *********
|
||||
|
||||
public: virtual Name getName() const;
|
||||
public: static const Name& getPropertyName();
|
||||
|
||||
public:double getUnit(CLuTableTemplate::Variable::Type type) const;
|
||||
public:double getUnit(Unit unit) const;
|
||||
|
||||
public:CLuTableTemplate* getTemplate(string name) const;
|
||||
|
||||
// Updators
|
||||
// ********
|
||||
|
||||
public:void SetUnit(Unit,double);
|
||||
|
||||
public:void AddTemplate(CLuTableTemplate* lutemplate);
|
||||
|
||||
// Others
|
||||
// ******
|
||||
|
||||
public: string _getString() const;
|
||||
public: string _getTypeName() const { return _TName("CLibertyTechnology"); }
|
||||
public: Record* _getRecord() const;
|
||||
|
||||
protected: void _postCreate();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // CRL_CLIBERTYTECHNOLOGY_H
|
|
@ -0,0 +1,304 @@
|
|||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
//
|
||||
// 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 : 15/05/2007
|
||||
// Author : Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
#include <sstream>
|
||||
|
||||
|
||||
#include "LibertyTechnology.h"
|
||||
#include "LuTableTemplate.h"
|
||||
|
||||
#include "LuTable.h"
|
||||
|
||||
namespace {
|
||||
string getUnitString(double val) {
|
||||
if (val < 1e-12) return getString(val*1e15)+"f";
|
||||
else if (val < 1e-9) return getString(val*1e12)+"p";
|
||||
else if (val < 1e-6) return getString(val*1e9)+"n";
|
||||
else if (val < 1e-3) return getString(val*1e6)+"µ";
|
||||
else if (val < 1) return getString(val*1e3)+"m";
|
||||
else if (val < 1e3) return getString(val);
|
||||
else if (val < 1e6) return getString(val*1e3)+"k";
|
||||
else if (val < 1e9) return getString(val*1e6)+"M";
|
||||
else return getString(val*1e9)+"G";
|
||||
}
|
||||
|
||||
template<class t> string getarraystring(int count,t* values) {
|
||||
ostringstream s;
|
||||
for (int i=0; i< count ; i++)
|
||||
s << (i?", ":"") << values[i];
|
||||
return s.str();
|
||||
}
|
||||
template<class t> string getarraystring(int count,vector<t> values) {
|
||||
ostringstream s;
|
||||
for (int i=0; i< count ; i++)
|
||||
s << (i?", ":"") << values[i];
|
||||
return s.str();
|
||||
}
|
||||
template<class t> string getarraystring(vector<t> values) {
|
||||
ostringstream s;
|
||||
for (int i=0; i< values.size() ; i++)
|
||||
s << (i?", ":"") << values[i];
|
||||
return s.str();
|
||||
}
|
||||
}
|
||||
namespace CRL {
|
||||
|
||||
CLuTable::CLuTable(CLuTableTemplate* luTemplate)
|
||||
// *********************************************
|
||||
: Inherit()
|
||||
, _template(luTemplate)
|
||||
, _values()
|
||||
{
|
||||
_values.reserve(_template->getTableSize());
|
||||
}
|
||||
|
||||
CLuTable* CLuTable::create(CLuTableTemplate* luTemplate)
|
||||
// *****************************************************
|
||||
{
|
||||
if (!luTemplate)
|
||||
throw Error("Can't create "+ _TName("CLuTable") + " : null template");
|
||||
|
||||
CLuTable* luTable = new CLuTable(luTemplate);
|
||||
|
||||
luTable->_postCreate();
|
||||
|
||||
return luTable;
|
||||
}
|
||||
|
||||
string CLuTable::_getString() const
|
||||
// ********************************
|
||||
{
|
||||
string s= Inherit::_getString();
|
||||
s.insert(s.length()-1," "+_template->getName()+" [");
|
||||
for (size_t i=0;i<_values.size();i++) s.insert(s.length()-1,(i?", ":"")+getString(_values[i]));
|
||||
s.insert(s.length()-1,"]");
|
||||
return s;
|
||||
}
|
||||
|
||||
Record* CLuTable::_getRecord() const
|
||||
// ***************************
|
||||
{
|
||||
Record* record=Inherit::_getRecord();
|
||||
if (record)
|
||||
{
|
||||
record->add(getSlot("Template",_template));
|
||||
record->add(getSlot("Values",&_values));
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
void CLuTable::AddValues(unsigned short count, double* values)
|
||||
// ***********************************************************
|
||||
{
|
||||
for(int i=0;i<count;i++)
|
||||
_values.push_back(values[i]);
|
||||
}
|
||||
|
||||
unsigned short CLuTable::getDimension() const
|
||||
// *****************************************
|
||||
{
|
||||
return _template->getDimension();
|
||||
}
|
||||
|
||||
double CLuTable::_getValue(unsigned short x,unsigned short y, unsigned short z) const
|
||||
// **********************************************************************************
|
||||
{
|
||||
unsigned value_index=z + _template->getVariableIndexSize(3)*y
|
||||
+ _template->getVariableIndexSize(3)*_template->getVariableIndexSize(2)*x;
|
||||
//ltrace(139) << "_getValue(" << x << ", " << y << ", " << z << ")"
|
||||
// << " _values[" << value_index << "]=" << _values[value_index] << endl;
|
||||
return _values[value_index];
|
||||
}
|
||||
|
||||
double CLuTable::getValue(double var1,double var2,double var3) const
|
||||
// *****************************************************************
|
||||
{
|
||||
double vars[3] = { var1,var2,var3 } ;
|
||||
//ltrace(141) << "getValue(" << var1 << ", " << var2 << ", " << var3 << ")" << endl;ltracein(141);
|
||||
|
||||
unsigned short index;
|
||||
|
||||
/*
|
||||
* coord is [ x0,x1,x2,y0,y1,y2,z0,z1,z2 ]
|
||||
* x0,y0,z0 are the coordonates of requested value in the table
|
||||
* x1,x2 (x1<x2) are the neerest indexes from x0 in the variable template indexes
|
||||
* idem for y1,y2 and z1,z2
|
||||
*/
|
||||
double coord[9];
|
||||
/*
|
||||
* table_indexes is [ i_x1, i_y1, i_z1 ]
|
||||
* where i_*1 is the position of *i in its template variable index array.
|
||||
*/
|
||||
unsigned short table_indexes[3] = { 0, 0, 0};
|
||||
|
||||
for (index=0;index<_template->getDimension();index++)
|
||||
{
|
||||
/*
|
||||
* unapplying the unit modifier to match the unit used in the table
|
||||
*/
|
||||
|
||||
double value = vars[index] / _template->getVariableUnit(index+1);
|
||||
coord[index*3] = value;
|
||||
/*
|
||||
* finding the neerest indexes in the template
|
||||
*/
|
||||
_template->FindIndexes(index+1,value,coord[index*3+1],coord[index*3+2],table_indexes[index]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* at this point : index = the number of dimension of the table
|
||||
*/
|
||||
|
||||
/*
|
||||
* Filling values such as :
|
||||
* values[0]=_getValues(x1,y1,z1)
|
||||
* values[1]=_getValues(x2,y1,z1)
|
||||
* values[2]=_getValues(x1,y2,z1) (if 2 dimension or more)
|
||||
* values[3]=_getValues(x2,y2,z1) "
|
||||
* values[4]=_getValues(x1,y1,z2) (if 3 dimension)
|
||||
* values[5]=_getValues(x2,y1,z2) "
|
||||
* values[6]=_getValues(x1,y2,z2) "
|
||||
* values[7]=_getValues(x2,y2,z2) "
|
||||
*/
|
||||
double values[8];
|
||||
for (unsigned short i=0;i<(1<<index);i++)
|
||||
values[i]=_getValue(table_indexes[0]+(i%2)
|
||||
,table_indexes[1]+((i>>1)%2)
|
||||
,table_indexes[2]+((i>>2)%2)
|
||||
);
|
||||
|
||||
//ltrace(140) << " table_indexes : " << getarraystring(_template->getDimension(),table_indexes) << endl;
|
||||
//ltrace(140) << " coord : " << getarraystring(3*_template->getDimension(),coord) << endl;
|
||||
//ltrace(140) << " values (init) : " << getarraystring(1<<_template->getDimension(),values) << endl;
|
||||
|
||||
|
||||
/*
|
||||
* Pour chaque dimension, on effectue une coupe de notre espace en x0, y0 ou z0, en calculant les valeurs
|
||||
* projetée sur la coupe, les autres valeurs restants constantes.
|
||||
* Par exemple pour x on trouve 'value(x0,y*,z*)' à partir de 'value(x1,y*,z*)' et 'value(x2,y*,z*)' :
|
||||
*
|
||||
* value(x2,..)-value(x1,..)
|
||||
* value(x0,..)=value(x1,..)+ ------------------------- (x1-x)
|
||||
* x2-x1
|
||||
*
|
||||
* Au premier tour on a values = [ v(x1,y1,z1), v(x2,y1,z1), v(x1,y2,z1), v(x2,y2,z1),
|
||||
* v(x1,y1,z2), v(x2,y1,z2), v(x1,y2,z2), v(x2,y2,z2) ]
|
||||
* Au deusieme tour on a values = [ v(x1,y1,z0), v(x2,y1,z0), v(x1,y2,z0), v(x2,y2,z0) ]
|
||||
* Au troisieme tour on a values = [ v(x1,y0,z0), v(x2,y0,z0) ]
|
||||
* Au dernier tour on a values = [ v(x0,y0,z0) ]
|
||||
*
|
||||
* Si la table fait moins de 3 dimensions, on saute les premiers tours.
|
||||
*/
|
||||
while(index--) {
|
||||
|
||||
for (unsigned short i=0; i< (1<<index); i++ )
|
||||
values[i]=values[i]+(values[i+(1<<index)]-values[i])/(coord[index*3+2]-coord[index*3+1])*(coord[index*3]-coord[index*3+1]);
|
||||
//FAUX values[i]=values[2*i]+(values[2*i+1]-values[2*i])/(coord[index*3+2]-coord[index*3+1])*(coord[index*3]-coord[index*3+1]);
|
||||
//ltrace(140) << " values (" << (int)index <<") : " << getarraystring(1<<index,values) << endl;
|
||||
}
|
||||
|
||||
//ltrace(141) << " = " << values[0] * _template->getTechnology()->getUnit(CLibertyTechnology::Unit::TIME) << endl;
|
||||
//ltraceout(141);
|
||||
//FIXME [HARDCODED] I assume all tables contain Time values
|
||||
return values[0] * _template->getTechnology()->getUnit(CLibertyTechnology::Unit::TIME);
|
||||
}
|
||||
|
||||
CLuTable* CLuTable::getCut(unsigned short var, double value)
|
||||
// ***********************************************************
|
||||
{
|
||||
//ltrace(143) << "getting Cut of " << this << " for variable " << (int)var << " at value " << value << endl;ltracein(143);
|
||||
//ltrace(142) << "Original template : " << _template << endl;
|
||||
//for (unsigned short ii=1;ii <= _template->getDimension();ii++)
|
||||
// ltrace(142) << " " << (int)ii << " : " << getarraystring(_template->getVariableIndexes(ii)) << endl;
|
||||
|
||||
|
||||
CLuTableTemplate* newtemplate = _template->RemoveVariable(var);
|
||||
//ltrace(142) << "New template : " << newtemplate << endl;
|
||||
//for (unsigned short ii=1;ii <= newtemplate->getDimension();ii++)
|
||||
// ltrace(142) << " " << (int)ii << " : " << getarraystring(newtemplate->getVariableIndexes(ii)) << endl;
|
||||
|
||||
CLuTable* newtable = create(newtemplate);
|
||||
|
||||
vector<double> newindexes[3];
|
||||
|
||||
unsigned short index;
|
||||
for (index=0;index<_template->getDimension();index++)
|
||||
{
|
||||
if (index == var-1)
|
||||
newindexes[index] = vector<double>(1,value);
|
||||
else
|
||||
{
|
||||
newindexes[index] = _template->getVariableIndexes(index+1);
|
||||
for (unsigned short i=0;i<newindexes[index].size();i++)
|
||||
newindexes[index][i]*=_template->getVariableUnit(index+1);
|
||||
}
|
||||
}
|
||||
for (;index<3;index++)
|
||||
newindexes[index] = vector<double>(1,0.0);
|
||||
|
||||
//ltrace(142) << "New indexes : " << endl;
|
||||
//for (unsigned short ii=1;ii<=3;ii++)
|
||||
// ltrace(142) << " " << (int)ii << " : " << getarraystring(newindexes[ii-1]) << endl;
|
||||
|
||||
for (unsigned short x=0;x < newindexes[0].size();x++)
|
||||
for (unsigned short y=0;y < newindexes[1].size();y++)
|
||||
for (unsigned short z=0;z < newindexes[2].size();z++)
|
||||
newtable->_values.push_back(getValue(newindexes[0][x],newindexes[1][y],newindexes[2][z])/_template->getTechnology()->getUnit(CLibertyTechnology::Unit::TIME));
|
||||
|
||||
//ltrace(142) << "New Table : " << newtable << endl;
|
||||
//ltraceout(143);
|
||||
return newtable;
|
||||
}
|
||||
|
||||
double CLuTable::Linearize()
|
||||
// *************************
|
||||
{
|
||||
//ltrace(143) << "Linearizing " << this << endl;ltracein(143);
|
||||
|
||||
if (getDimension() != 1)
|
||||
throw Error("LuTable must have exactly one dimension to by linearized");
|
||||
|
||||
vector<double> indexes = _template->getVariableIndexes(1);
|
||||
///*dbg*/for (unsigned short i=1;i<_template->getVariableIndexSize(1);i++) {
|
||||
///*dbg*/ double b=_getValue(i);double a=_getValue(i-1);
|
||||
///*dbg*/ ltrace(141) << " . (" << b << "-" << a << ")/(" << indexes[i] << "-" << indexes[i-1] << ") =" << (b-a)/(indexes[i]-indexes[i-1]) << endl;
|
||||
///*dbg*/}
|
||||
///*dbg*/double imax=_getValue(indexes.size()-1);double i0=_getValue(0);
|
||||
///*dbg*/ltrace(142) << " = " << (imax-i0)/(indexes[indexes.size()-1]-indexes[0]) << endl;
|
||||
//ltraceout(143);
|
||||
|
||||
return (_getValue(indexes.size()-1)-_getValue(0))/(indexes[indexes.size()-1]-indexes[0]);
|
||||
}
|
||||
|
||||
|
||||
} //namespace CRL
|
|
@ -0,0 +1,90 @@
|
|||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
//
|
||||
// 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 : 15/05/2007
|
||||
// Author : Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
#ifndef CRL_CLUTABLE_H
|
||||
#define CRL_CLUTABLE_H
|
||||
|
||||
#include "hurricane/DBo.h"
|
||||
# include "hurricane/Slot.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
namespace CRL {
|
||||
|
||||
class CLuTableTemplate;
|
||||
|
||||
class CLuTable : public DBo {
|
||||
|
||||
// Types
|
||||
// *****
|
||||
|
||||
public:typedef DBo Inherit;
|
||||
|
||||
// Atributes
|
||||
// *********
|
||||
|
||||
private: CLuTableTemplate* _template;
|
||||
private: vector<double> _values;
|
||||
|
||||
// Constructors
|
||||
// ************
|
||||
|
||||
public: CLuTable(CLuTableTemplate* luTemplate);
|
||||
|
||||
public: static CLuTable* create(CLuTableTemplate* luTemplate);
|
||||
|
||||
// Updators
|
||||
// ********
|
||||
|
||||
public: void AddValues(unsigned short count, double* values);
|
||||
|
||||
// Others
|
||||
// ******
|
||||
|
||||
public: string _getString() const;
|
||||
public: virtual string _getTypeName() const {return _TName("CLuTable");};
|
||||
public: virtual Record* _getRecord() const;
|
||||
|
||||
public: unsigned short getDimension() const;
|
||||
|
||||
public: double _getValue(unsigned short x=0,unsigned short y=0, unsigned short z=0) const;
|
||||
public: double getValue(double var1, double var2=0.0, double var3=0.0) const;
|
||||
|
||||
//! Return the Cut for var=value. Decrease the table dimension by one.
|
||||
public: CLuTable* getCut(unsigned short var, double value);
|
||||
|
||||
//! Return the average slope of the table (must be one-dimensionnal)
|
||||
public: double Linearize();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CRL_CLUTABLE_H
|
|
@ -0,0 +1,316 @@
|
|||
|
||||
// This file is part of the Coriolis Project.
|
||||
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
||||
// Universite Pierre et Marie Curie
|
||||
//
|
||||
// Main contributors :
|
||||
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
||||
// Hugo Clément <Hugo.Clement@lip6.fr>
|
||||
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||
// Christian Masson <Christian.Masson@lip6.fr>
|
||||
//
|
||||
// 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 : 15/05/2007
|
||||
// Author : Marek Sroka <Marek.Sroka@lip6.fr>
|
||||
//
|
||||
// Authors-Tag
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
using namespace std;
|
||||
|
||||
#include "hurricane/Error.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
#include "LuTableTemplate.h"
|
||||
#include "LibertyTechnology.h"
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
extern void LibertyParserError(string message);
|
||||
|
||||
// **************************************************************************
|
||||
// CLuTableTemplate definition
|
||||
// **************************************************************************
|
||||
|
||||
CLuTableTemplate::CLuTableTemplate(string name, CLibertyTechnology* technology)
|
||||
// ****************************************************************************
|
||||
: Inherit()
|
||||
, _name(name)
|
||||
, _technology(technology)
|
||||
{
|
||||
_variables[0]=_variables[1]=_variables[2]=NULL;
|
||||
}
|
||||
|
||||
CLuTableTemplate* CLuTableTemplate::create(string name, CLibertyTechnology* technology)
|
||||
// ************************************************************************************
|
||||
{
|
||||
CLuTableTemplate* luTableTemplate = new CLuTableTemplate(name,technology);
|
||||
|
||||
luTableTemplate->_postCreate();
|
||||
|
||||
return luTableTemplate;
|
||||
}
|
||||
|
||||
void CLuTableTemplate::_postCreate()
|
||||
// *********************************
|
||||
{
|
||||
Inherit::_postCreate();
|
||||
_technology->AddTemplate(this);
|
||||
}
|
||||
|
||||
CLuTableTemplate::~CLuTableTemplate()
|
||||
// **********************************
|
||||
{
|
||||
for(unsigned short i=0;i<3;i++)
|
||||
if (_variables[i])
|
||||
delete _variables[i];
|
||||
}
|
||||
|
||||
string CLuTableTemplate::_getString() const
|
||||
// ****************************************
|
||||
{
|
||||
string s = Inherit::_getString();
|
||||
s.insert(s.length() -1, " "+_name);
|
||||
return s;
|
||||
}
|
||||
|
||||
Record* CLuTableTemplate::_getRecord() const
|
||||
// ***********************************
|
||||
{
|
||||
Record* record = Inherit::_getRecord();
|
||||
if (record)
|
||||
{
|
||||
record->add(getSlot("Name", _name));
|
||||
record->add(getSlot("Technology", _technology));
|
||||
record->add(getSlot("Dimension", (unsigned int)getDimension()));
|
||||
|
||||
record->add(getSlot("Variable 1", _variables[0]));
|
||||
record->add(getSlot("Variable 2", _variables[1]));
|
||||
record->add(getSlot("Variable 3", _variables[2]));
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
void CLuTableTemplate::AddVariable(unsigned short index,Variable::Type type)
|
||||
// ************************************************************************
|
||||
{
|
||||
assert((index > 0) && (index < 4));
|
||||
if (_variables[index-1])
|
||||
LibertyParserError("variable already defined");
|
||||
|
||||
_variables[index-1] = new Variable(type);
|
||||
}
|
||||
|
||||
void CLuTableTemplate::SetVariableIndexes(unsigned short index,unsigned short count,double* values)
|
||||
// ***********************************************************************************************
|
||||
{
|
||||
assert((index > 0) && (index < 4));
|
||||
if (_variables[index-1] == NULL)
|
||||
LibertyParserError("variable not defined");
|
||||
|
||||
_variables[index-1]->SetIndexes(count,values);
|
||||
}
|
||||
|
||||
unsigned short CLuTableTemplate::getDimension() const
|
||||
// *************************************************
|
||||
{
|
||||
unsigned short dimension=0;
|
||||
while((dimension<3) && (_variables[dimension])) dimension++;
|
||||
return dimension;
|
||||
}
|
||||
|
||||
int CLuTableTemplate::getTableSize() const
|
||||
// ***************************************
|
||||
{
|
||||
return getVariableIndexSize(1)*getVariableIndexSize(2)*getVariableIndexSize(3);
|
||||
}
|
||||
|
||||
int CLuTableTemplate::getVariableIndexSize(unsigned short index) const
|
||||
// ******************************************************************
|
||||
{
|
||||
assert((index > 0) && (index < 4));
|
||||
if (_variables[index-1])
|
||||
return _variables[index-1]->getSize();
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
vector<double> CLuTableTemplate::getVariableIndexes(unsigned short index) const
|
||||
// ***************************************************************************
|
||||
{
|
||||
assert((index > 0) && (index < 4));
|
||||
if (!_variables[index-1])
|
||||
throw Error("getVariableIndexes : variable "+getString(index)+" not defined");
|
||||
return _variables[index-1]->getIndexes();
|
||||
}
|
||||
double CLuTableTemplate::getVariableUnit(unsigned short index) const
|
||||
// ****************************************************************
|
||||
{
|
||||
assert((index > 0) && (index < 4));
|
||||
if (!_variables[index-1])
|
||||
throw Error("getVariableUnit : variable "+getString((unsigned int)index)+" not defined");
|
||||
return _technology->getUnit(_variables[index-1]->getType());
|
||||
}
|
||||
|
||||
|
||||
void CLuTableTemplate::FindIndexes(unsigned short index,double index_value,double& index_min,double& index_max
|
||||
,unsigned short& index_index) const
|
||||
// **********************************************************************************************************
|
||||
{
|
||||
assert((index > 0) && (index < 4));
|
||||
_variables[index-1]->FindIndexes(index_value,index_min,index_max,index_index);
|
||||
}
|
||||
|
||||
CLuTableTemplate* CLuTableTemplate::getClone() const
|
||||
// *************************************************
|
||||
{
|
||||
static unsigned int clone_count=0;
|
||||
string clone_name;
|
||||
|
||||
do {
|
||||
clone_name= _name+"__crl_clone_"+getString(clone_count++);
|
||||
} while (_technology->getTemplate(clone_name));
|
||||
|
||||
CLuTableTemplate* clone = create(clone_name,_technology);
|
||||
for (unsigned int i=0;i<3;i++)
|
||||
if (_variables[i])
|
||||
clone->_variables[i]=_variables[i]->getClone();
|
||||
return clone;
|
||||
}
|
||||
|
||||
CLuTableTemplate* CLuTableTemplate::RemoveVariable(unsigned short index)
|
||||
// ********************************************************************
|
||||
{
|
||||
assert((index > 0) && (index < 4));
|
||||
|
||||
CLuTableTemplate* clone = getClone();
|
||||
for(unsigned int i=index;i<3;i++)
|
||||
clone->_variables[i-1]=clone->_variables[i];
|
||||
clone->_variables[3]=NULL;
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// CLuTableTemplate::Variable definition
|
||||
// **************************************************************************
|
||||
|
||||
CLuTableTemplate::Variable::Variable(Type type)
|
||||
// ********************************************
|
||||
: _type(type)
|
||||
, _indexes()
|
||||
{
|
||||
}
|
||||
|
||||
string CLuTableTemplate::Variable::_getString() const
|
||||
// **************************************************
|
||||
{
|
||||
string s="<CLuTableTemplate::Variable "+getString(_type)+" [";
|
||||
for (int i=0;i<getSize();i++)
|
||||
s+= (i?", ":"")+ getString(_indexes[i]);
|
||||
return s+"]>";
|
||||
}
|
||||
|
||||
Record* CLuTableTemplate::Variable::_getRecord() const
|
||||
// *********************************************
|
||||
{
|
||||
Record* record = new Record(getString(this));
|
||||
if (record) {
|
||||
record->add(getSlot("Type",_type));
|
||||
record->add(getSlot("Indexes",&_indexes));
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
void CLuTableTemplate::Variable::SetIndexes(unsigned short count,double* values)
|
||||
// *****************************************************************************
|
||||
{
|
||||
if (!_indexes.empty())
|
||||
LibertyParserError("variable indexes already defined");
|
||||
|
||||
_indexes.reserve(count);
|
||||
|
||||
for(int i=0;i<count;i++) _indexes.push_back(values[i]);
|
||||
//while(count--) _indexes[count]=values[count]; //a priori ne met pas à jour size()... génant.
|
||||
}
|
||||
|
||||
void CLuTableTemplate::Variable::FindIndexes(double index_value,double& index_min,double& index_max
|
||||
,unsigned short& index_index) const
|
||||
// ************************************************************************************************
|
||||
{
|
||||
index_index=0;
|
||||
while ( (index_index<(getSize()-1)) && (index_value > _indexes[++index_index]) );
|
||||
index_max=_indexes[index_index];
|
||||
index_min=_indexes[--index_index];
|
||||
}
|
||||
|
||||
CLuTableTemplate::Variable* CLuTableTemplate::Variable::getClone() const
|
||||
// *********************************************************************
|
||||
{
|
||||
Variable* variable= new Variable(_type);
|
||||
variable->_indexes = _indexes;
|
||||
return variable;
|
||||
}
|
||||
|
||||
// ****************************************************************************************************
|
||||
// CLuTableTemplate::Variable::Type definition
|
||||
// ****************************************************************************************************
|
||||
|
||||
CLuTableTemplate::Variable::Type::Type(const Code& code)
|
||||
// *****************************************************
|
||||
: _code(code)
|
||||
{
|
||||
}
|
||||
|
||||
CLuTableTemplate::Variable::Type::Type(const CLuTableTemplate::Variable::Type& type)
|
||||
// *********************************************************************************
|
||||
: _code(type._code)
|
||||
{
|
||||
}
|
||||
|
||||
CLuTableTemplate::Variable::Type& CLuTableTemplate::Variable::Type::operator=(const CLuTableTemplate::Variable::Type& type)
|
||||
// ************************************************************************************************************************
|
||||
{
|
||||
_code = type._code;
|
||||
return *this;
|
||||
}
|
||||
|
||||
string CLuTableTemplate::Variable::Type::_getString() const
|
||||
// ********************************************************
|
||||
{
|
||||
switch (_code) {
|
||||
case UNDEFINED : return "UNDEFINED";
|
||||
case CONSTRAINED_PIN_TRANSITION: return "CONSTRAINED_PIN_TRANSITION";
|
||||
case RELATED_PIN_TRANSITION: return "RELATED_PIN_TRANSITION";
|
||||
case INPUT_NET_TRANSITION: return "INPUT_NET_TRANSITION";
|
||||
case TOTAL_OUTPUT_NET_CAPACITANCE: return "TOTAL_OUTPUT_NET_CAPACITANCE";
|
||||
}
|
||||
return "ABNORMAL";
|
||||
}
|
||||
|
||||
Record* CLuTableTemplate::Variable::Type::_getRecord() const
|
||||
// ***************************************************
|
||||
{
|
||||
Record* record = new Record(getString(this));
|
||||
record->add(getSlot("Code", (unsigned*)&_code));
|
||||
return record;
|
||||
}
|
||||
|
||||
} //namespace CRL
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue