* ./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:
Jean-Paul Chaput 2010-03-09 15:20:13 +00:00
parent 905c7b4960
commit c5d8077730
132 changed files with 28275 additions and 0 deletions

28
crlcore/CMakeLists.txt Normal file
View File

@ -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)

View File

@ -0,0 +1,4 @@
install ( FILES FindCORIOLIS.cmake
FindOPENACCESS.cmake
FindLEFDEF.cmake
DESTINATION /share/cmake_modules )

View File

@ -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)

View File

@ -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 )

View File

@ -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)

View File

@ -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 )

250
crlcore/etc/display.xml Normal file
View File

@ -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 &amp; 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 &amp; 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 &amp; 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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,4 @@
add_subdirectory(fonts)
add_subdirectory(ccore)
add_subdirectory(cyclop)
add_subdirectory(x2y)

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -0,0 +1 @@
#cmakedefine CORIOLIS_TOP

View File

@ -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

View File

@ -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 )

View File

@ -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() );
}
}

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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
}
}

View File

@ -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 );
}
}

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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; }

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
add_subdirectory(vst)

View File

@ -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

View File

@ -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 ();
}
}

View File

@ -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.

View File

@ -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

View File

@ -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 ();
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
/* #undef CORIOLIS_TOP */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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

View File

@ -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__

View File

@ -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 */

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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__

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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.

View File

@ -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.

View File

@ -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__

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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; }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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