Compare commits
89 Commits
coloquinte
...
devel
Author | SHA1 | Date |
---|---|---|
|
947026cced | |
|
ce084fcf73 | |
|
7b304da14b | |
|
b734d61a00 | |
|
c2750ca127 | |
|
cadae8412b | |
|
d258749373 | |
|
3243b12abb | |
|
73265c2d68 | |
|
47aadd8ef4 | |
|
30b92ff33a | |
|
ecdcabb8ad | |
|
b7698e7500 | |
|
e084c1e672 | |
|
7b155d1ecf | |
|
06433cc914 | |
|
554aded65b | |
|
9b38590c60 | |
|
014ec72652 | |
|
007677353f | |
|
f8637737a0 | |
|
b77d86c931 | |
|
d019c6aab5 | |
|
b8f15a2c8f | |
|
70fb5cfe3f | |
|
5cdb8b25f0 | |
|
0aa9010b32 | |
|
ee2ed63d35 | |
|
72b906cb68 | |
|
30b69f634a | |
|
73925094f1 | |
|
56da5ebe32 | |
|
0dc33538a7 | |
|
7b7e852f67 | |
|
04410f1cc2 | |
|
a3c05c0f60 | |
|
5d8b994bb6 | |
|
9b87b92eec | |
|
5233d860f4 | |
|
6f793665c2 | |
|
7f0ab625d2 | |
|
e497a4d48f | |
|
052df5d1c8 | |
|
4731e30bb3 | |
|
078e4e0644 | |
|
23975c541d | |
|
0fe1deac94 | |
|
db01b4ff55 | |
|
1f5549d396 | |
|
62e7640a37 | |
|
1beaaf93e4 | |
|
fb694e1c3d | |
|
d873216447 | |
|
49e95115f2 | |
|
2ea099afec | |
|
26184c5016 | |
|
acf6cfe041 | |
|
585489860e | |
|
4f1ce6cfcb | |
|
393204ba0d | |
|
46c685a7f8 | |
|
1e71b5fb08 | |
|
3830a90482 | |
|
56883db08e | |
|
abee13d669 | |
|
96e6c9dd06 | |
|
c53fc01cb2 | |
|
52fd1c1c40 | |
|
4c7cf227be | |
|
d928a3c7a5 | |
|
c3bed61257 | |
|
57bab117b4 | |
|
31b0c4daf1 | |
|
b9862ecd5e | |
|
518a376c01 | |
|
6361ad4ca0 | |
|
e968a5088f | |
|
5afb4cabe9 | |
|
23c0c24c0f | |
|
2568a1a496 | |
|
e22e7f7476 | |
|
a0911be50a | |
|
e5d9c8808b | |
|
7ed41613de | |
|
50a9036d28 | |
|
8f387620cb | |
|
5879a5b581 | |
|
1f4b9450e5 | |
|
090c13663e |
|
@ -1,4 +1,6 @@
|
|||
[submodule "coloquinte"]
|
||||
path = coloquinte
|
||||
url = git@github.com:Coloquinte/PlaceRoute.git
|
||||
# url = git@github.com:Coloquinte/PlaceRoute.git
|
||||
url = https://github.com/Coloquinte/PlaceRoute.git
|
||||
branch = coriolis-submodule
|
||||
update = merge
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
set_cmake_policies()
|
||||
setup_boost(program_options)
|
||||
setup_qt()
|
||||
setup_python()
|
||||
|
||||
find_package(Libexecinfo REQUIRED)
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(LEFDEF REQUIRED)
|
||||
find_package(FLUTE REQUIRED)
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
set_cmake_policies()
|
||||
setup_boost()
|
||||
setup_qt()
|
||||
setup_python()
|
||||
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(FLUTE REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
|
|
|
@ -3069,6 +3069,7 @@ namespace Anabatic {
|
|||
if (wPitch > 1) segment->setFlags( SegWide );
|
||||
if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag );
|
||||
if (dir & Flags::UseNonPref) segment->setFlags( SegNonPref );
|
||||
if (dir.contains(Flags::UseNonPref|Flags::OnVSmall)) segment->setFlags( SegOnVSmall );
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ endif ( CHECK_DETERMINISM )
|
|||
${QtX_INCLUDE_DIRS}
|
||||
${Python_INCLUDE_DIRS}
|
||||
)
|
||||
find_package (Python3 COMPONENTS Interpreter Development)
|
||||
set( includes anabatic/Constants.h
|
||||
anabatic/Configuration.h
|
||||
anabatic/Matrix.h
|
||||
|
|
|
@ -132,6 +132,7 @@ namespace Anabatic {
|
|||
const BaseFlags Flags::NoMinLength = (1L << 37);
|
||||
const BaseFlags Flags::NoSegExt = (1L << 38);
|
||||
const BaseFlags Flags::NullLength = (1L << 39);
|
||||
const BaseFlags Flags::OnVSmall = (1L << 40);
|
||||
|
||||
|
||||
Flags::~Flags ()
|
||||
|
|
|
@ -277,7 +277,9 @@ namespace Anabatic {
|
|||
|
||||
if (flags & (VSmall|UseNonPref)) {
|
||||
cdebug_log(145,0) << "case: UseNonPref" << endl;
|
||||
|
||||
|
||||
if (flags & VSmall)
|
||||
useNonPref.reset( Flags::UseNonPref );
|
||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getBuildContactLayer(rpDepth+1) );
|
||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical|useNonPref );
|
||||
rpSourceContact = subContact1;
|
||||
|
|
|
@ -109,6 +109,7 @@ namespace Anabatic {
|
|||
static const uint64_t SegNonPref = (1L<<37);
|
||||
static const uint64_t SegAtMinArea = (1L<<38);
|
||||
static const uint64_t SegNoMoveUp = (1L<<39);
|
||||
static const uint64_t SegOnVSmall = (1L<<40);
|
||||
// Masks.
|
||||
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
||||
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
||||
|
@ -202,6 +203,7 @@ namespace Anabatic {
|
|||
inline bool isTerminal () const;
|
||||
inline bool isUnbreakable () const;
|
||||
inline bool isNonPref () const;
|
||||
inline bool isNonPrefOnVSmall () const;
|
||||
inline bool isDrag () const;
|
||||
inline bool isAtMinArea () const;
|
||||
inline bool isNotSourceAligned () const;
|
||||
|
@ -536,6 +538,7 @@ namespace Anabatic {
|
|||
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); }
|
||||
inline bool AutoSegment::isUnbreakable () const { return _flags & SegUnbreakable; }
|
||||
inline bool AutoSegment::isNonPref () const { return _flags & SegNonPref; }
|
||||
inline bool AutoSegment::isNonPrefOnVSmall () const { return (_flags & SegNonPref) and (_flags & SegOnVSmall); }
|
||||
inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; }
|
||||
inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); }
|
||||
inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); }
|
||||
|
|
|
@ -110,6 +110,7 @@ namespace Anabatic {
|
|||
static const BaseFlags NoMinLength ;
|
||||
static const BaseFlags NoSegExt ;
|
||||
static const BaseFlags NullLength ;
|
||||
static const BaseFlags OnVSmall ;
|
||||
public:
|
||||
inline Flags ( uint64_t flags = NoFlags );
|
||||
inline Flags ( const Hurricane::BaseFlags& );
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${Bootstrap_SOURCE_DIR}/cmake_modules/")
|
||||
find_package(Bootstrap REQUIRED)
|
||||
# find_package(Python 3 REQUIRED COMPONENTS Interpreter Development )
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development )
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development.Module )
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
print_cmake_module_path()
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
srcDir=${HOME}${nightly}/coriolis-2.x/src/alliance/alliance/src
|
||||
commonRoot=${HOME}${nightly}/coriolis-2.x/${arch}/Release.Shared
|
||||
#commonRoot=${HOME}${nightly}/coriolis-2.x/${arch}/Debug.Shared
|
||||
buildDir=${commonRoot}/build
|
||||
installDir=${commonRoot}/install
|
||||
|
||||
|
|
|
@ -24,8 +24,9 @@ projects = [
|
|||
#, "knik"
|
||||
#, "katabatic"
|
||||
#, "kite"
|
||||
, "equinox"
|
||||
, "solstice"
|
||||
#, "equinox"
|
||||
#, "solstice"
|
||||
, "tramontana"
|
||||
, "oroshi"
|
||||
, "bora"
|
||||
, "karakaze"
|
||||
|
|
|
@ -35,6 +35,7 @@ class Builder:
|
|||
self._noCache = False
|
||||
self._ninja = False
|
||||
self._clang = False
|
||||
self._manylinux = False
|
||||
self._noSystemBoost = False
|
||||
self._macports = False
|
||||
self._devtoolset = 0
|
||||
|
@ -62,6 +63,7 @@ class Builder:
|
|||
elif attribute == "noCache": self._noCache = value
|
||||
elif attribute == "ninja": self._ninja = value
|
||||
elif attribute == "clang": self._clang = value
|
||||
elif attribute == "manylinux": self._manylinux = value
|
||||
elif attribute == "macports":
|
||||
self._macports = value
|
||||
if value: self._noSystemBoost = True
|
||||
|
@ -177,6 +179,7 @@ class Builder:
|
|||
if self._bfd: command += [ "-D", "USE_LIBBFD:STRING=%s" % self._bfd ]
|
||||
if self._qt4: command += [ "-D", "WITH_QT4:STRING=TRUE" ]
|
||||
if self._openmp: command += [ "-D", "WITH_OPENMP:STRING=TRUE" ]
|
||||
if self._manylinux: command += [ "-D", "USE_MANYLINUX:STRING=TRUE" ]
|
||||
command += [ "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self.buildMode
|
||||
#, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared
|
||||
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir
|
||||
|
|
|
@ -211,6 +211,7 @@ parser.add_option ( "--bfd" , action="store_true" ,
|
|||
parser.add_option ( "--openmp" , action="store_true" , dest="openmp" , help="Enable the use of OpenMP in Gcc." )
|
||||
parser.add_option ( "--ninja" , action="store_true" , dest="ninja" , help="Use Ninja instead of UNIX Makefile." )
|
||||
parser.add_option ( "--clang" , action="store_true" , dest="clang" , help="Force use of Clang C/C++ compiler instead of system default." )
|
||||
parser.add_option ( "--manylinux" , action="store_true" , dest="manylinux" , help="Build target is manylinux (PyPY)." )
|
||||
parser.add_option ( "--make" , action="store" , type="string", dest="makeArguments" , help="Arguments to pass to make (ex: \"-j4 install\")." )
|
||||
parser.add_option ( "--project" , action="append" , type="string", dest="projects" , help="The name of a project to build (may appears any number of time)." )
|
||||
parser.add_option ( "-t", "--tool" , action="append" , type="string", dest="tools" , help="The name of a tool to build (may appears any number of time)." )
|
||||
|
@ -282,6 +283,7 @@ else:
|
|||
if options.llvmtoolset: builder.llvmtoolset = options.llvmtoolset
|
||||
if options.bfd: builder.bfd = "ON"
|
||||
if options.qt4: builder.qt4 = True
|
||||
if options.manylinux: builder.manylinux = True
|
||||
if options.openmp: builder.openmp = True
|
||||
if options.makeArguments: builder.makeArguments = options.makeArguments
|
||||
#if options.svnMethod: builder.svnMethod = options.svnMethod
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
FindQwt.cmake
|
||||
FindSphinx.cmake
|
||||
FindPelican.cmake
|
||||
FindCOLOQUINTE.cmake
|
||||
GetGitRevisionDescription.cmake
|
||||
GetGitRevisionDescription.cmake.in
|
||||
)
|
||||
|
|
|
@ -223,6 +223,20 @@ endif()
|
|||
endmacro(setup_boost)
|
||||
|
||||
|
||||
#
|
||||
# Setup Python, select detection depending on USE_MANYLINUX.
|
||||
#
|
||||
macro(setup_python)
|
||||
set(pydevelArg "Development")
|
||||
|
||||
if (USE_MANYLINUX)
|
||||
message(STATUS "Build for manylinux")
|
||||
set(pydevelArg "Development.Module")
|
||||
endif()
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter ${pydevelArg} )
|
||||
endmacro()
|
||||
|
||||
|
||||
#
|
||||
# Find Qt, the union of all the modules we need for the whole project.
|
||||
#
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
# - Find the Coloquinte includes and libraries.
|
||||
# The following variables are set if Coriolis is found. If COLOQUINTE is not
|
||||
# found, COLOQUINTE_FOUND is set to false.
|
||||
# COLOQUINTE_FOUND - True when the Coriolis include directory is found.
|
||||
# COLOQUINTE_INCLUDE_DIR - the path to where the Coriolis include files are.
|
||||
# COLOQUINTE_LIBRARIES - The path to where the Coriolis library files are.
|
||||
|
||||
|
||||
SET(COLOQUINTE_INCLUDE_PATH_DESCRIPTION "directory containing the Coloquinte include files. E.g /usr/local/include/coriolis2 or /asim/coriolis/include/coriolis2")
|
||||
|
||||
SET(COLOQUINTE_DIR_MESSAGE "Set the COLOQUINTE_INCLUDE_DIR cmake cache entry to the ${COLOQUINTE_INCLUDE_PATH_DESCRIPTION}")
|
||||
|
||||
# don't even bother under WIN32
|
||||
IF(UNIX)
|
||||
#
|
||||
# Look for an installation.
|
||||
#
|
||||
FIND_PATH(COLOQUINTE_INCLUDE_PATH NAMES coloquinte/coloquinte.hpp PATHS
|
||||
# Look in other places.
|
||||
${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES include/coriolis2
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${COLOQUINTE_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
MESSAGE( "COL ${COLOQUINTE_INCLUDE_PATH}" )
|
||||
|
||||
FIND_LIBRARY(COLOQUINTE_LIBRARY_PATH
|
||||
NAMES coloquinte
|
||||
PATHS ${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${COLOQUINTE_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
||||
SET_LIBRARIES_PATH(COLOQUINTE COLOQUINTE)
|
||||
HURRICANE_CHECK_LIBRARIES(COLOQUINTE)
|
||||
|
||||
ENDIF(UNIX)
|
|
@ -284,6 +284,16 @@ class GitRepository ( object ):
|
|||
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
def submoduleInit ( self ):
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'submodule', 'init' ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
def submoduleUpdate ( self ):
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'submodule', 'update' ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
|
||||
class Configuration ( object ):
|
||||
|
||||
|
@ -303,7 +313,7 @@ class Configuration ( object ):
|
|||
def __init__ ( self ):
|
||||
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
|
||||
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
|
||||
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
|
||||
self._supportRepos = [ 'https://github.com/Tencent/rapidjson.git' ]
|
||||
self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
|
||||
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
|
||||
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
|
||||
|
@ -601,6 +611,8 @@ try:
|
|||
if conf.rmSource: gitCoriolis.removeLocalRepo()
|
||||
gitCoriolis.clone ()
|
||||
gitCoriolis.checkout( 'devel' )
|
||||
gitCoriolis.submoduleInit()
|
||||
gitCoriolis.submoduleUpdate()
|
||||
|
||||
if conf.rmSource: gitBenchs.removeLocalRepo()
|
||||
gitBenchs.clone()
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
setup_boost(program_options)
|
||||
setup_qt()
|
||||
setup_qwt()
|
||||
setup_python()
|
||||
|
||||
find_package(Libexecinfo REQUIRED)
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(LEFDEF REQUIRED)
|
||||
find_package(FLUTE REQUIRED)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
|
||||
setup_boost(program_options)
|
||||
setup_qt()
|
||||
setup_python()
|
||||
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
|
||||
|
@ -28,7 +29,6 @@
|
|||
find_package(Libbfd)
|
||||
endif()
|
||||
find_package(BZip2 REQUIRED)
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(BISON REQUIRED)
|
||||
find_package(FLEX REQUIRED)
|
||||
|
|
|
@ -11,6 +11,7 @@ from coriolis.CRL import AllianceFramework, Gds, LefImport, CellGa
|
|||
RoutingGauge, RoutingLayerGauge
|
||||
from coriolis.helpers import l, u, n, overlay, io, ndaTopDir
|
||||
from coriolis.helpers.overlay import CfgCache, UpdateSession
|
||||
from coriolis.Anabatic import StyleFlags
|
||||
|
||||
|
||||
__all__ = [ "setup" ]
|
||||
|
@ -27,7 +28,7 @@ def _routing ():
|
|||
rg.setSymbolic( False )
|
||||
rg.addLayerGauge(
|
||||
RoutingLayerGauge.create( tech.getLayer( 'Metal1' ) # metal
|
||||
, RoutingLayerGauge.Vertical # preferred routing direction
|
||||
, RoutingLayerGauge.Horizontal # preferred routing direction
|
||||
, RoutingLayerGauge.PinOnly # layer usage
|
||||
, 0 # depth
|
||||
, 0.0 # density (deprecated)
|
||||
|
@ -39,7 +40,7 @@ def _routing ():
|
|||
, u(0.0 ) )) # obstacle dW
|
||||
rg.addLayerGauge(
|
||||
RoutingLayerGauge.create( tech.getLayer( 'Metal2' ) # metal
|
||||
, RoutingLayerGauge.Horizontal # preferred routing direction
|
||||
, RoutingLayerGauge.Vertical # preferred routing direction
|
||||
, RoutingLayerGauge.Default # layer usage
|
||||
, 1 # depth
|
||||
, 0.0 # density (deprecated)
|
||||
|
@ -48,10 +49,10 @@ def _routing ():
|
|||
, u(0.28) # wire width
|
||||
, u(0.28) # perpandicular wire width
|
||||
, u(0.26) # VIA side
|
||||
, u(0.0 ) )) # obstacle dW
|
||||
, u(0.0 ) )) # obstacle dW
|
||||
rg.addLayerGauge(
|
||||
RoutingLayerGauge.create( tech.getLayer( 'Metal3' ) # metal
|
||||
, RoutingLayerGauge.Vertical # preferred routing direction
|
||||
, RoutingLayerGauge.Horizontal # preferred routing direction
|
||||
, RoutingLayerGauge.Default # layer usage
|
||||
, 2 # depth
|
||||
, 0.0 # density (deprecated)
|
||||
|
@ -63,7 +64,7 @@ def _routing ():
|
|||
, u(0.0 ) )) # obstacle dW
|
||||
rg.addLayerGauge(
|
||||
RoutingLayerGauge.create( tech.getLayer( 'Metal4' ) # metal
|
||||
, RoutingLayerGauge.Horizontal # preferred routing direction
|
||||
, RoutingLayerGauge.Vertical # preferred routing direction
|
||||
, RoutingLayerGauge.Default # layer usage
|
||||
, 3 # depth
|
||||
, 0.0 # density (deprecated)
|
||||
|
@ -75,7 +76,7 @@ def _routing ():
|
|||
, u(0.0 ) )) # obstacle dW
|
||||
rg.addLayerGauge(
|
||||
RoutingLayerGauge.create( tech.getLayer( 'Metal5' ) # metal
|
||||
, RoutingLayerGauge.Vertical # preferred routing direction
|
||||
, RoutingLayerGauge.Horizontal # preferred routing direction
|
||||
, RoutingLayerGauge.Default # layer usage
|
||||
, 4 # depth
|
||||
, 0.0 # density (deprecated)
|
||||
|
@ -87,7 +88,7 @@ def _routing ():
|
|||
, u(0.0 ) )) # obstacle dW
|
||||
rg.addLayerGauge(
|
||||
RoutingLayerGauge.create( tech.getLayer( 'MetalTop' ) # metal
|
||||
, RoutingLayerGauge.Horizontal # preferred routing direction
|
||||
, RoutingLayerGauge.Vertical # preferred routing direction
|
||||
, RoutingLayerGauge.PowerSupply # layer usage
|
||||
, 5 # depth
|
||||
, 0.0 # density (deprecated)
|
||||
|
@ -161,7 +162,9 @@ def _routing ():
|
|||
cfg.anabatic.globalIterations = [ 1, 100 ]
|
||||
cfg.anabatic.gcell.displayMode = 1
|
||||
cfg.anabatic.gcell.displayMode = (("Boundary", 1), ("Density", 2))
|
||||
cfg.katana.disableStackedVias = True
|
||||
cfg.anabatic.netBuilderStyle = 'VH,3RL+'
|
||||
cfg.anabatic.routingStyle = StyleFlags.VH
|
||||
cfg.katana.disableStackedVias = False
|
||||
cfg.katana.hTracksReservedLocal = 4
|
||||
cfg.katana.hTracksReservedLocal = [0, 20]
|
||||
cfg.katana.vTracksReservedLocal = 3
|
||||
|
|
|
@ -80,20 +80,20 @@ def _setup_techno():
|
|||
setEnclosures( CONT, Poly2 , u(0.07) )
|
||||
setEnclosures( CONT, Metal1, u(0.12) )
|
||||
VIA12 = createVia( tech, 'VIA12', 'Metal1', 'Via1', 'Metal2', u(0.26) )
|
||||
setEnclosures( VIA12, Metal1, u(0.06) )
|
||||
setEnclosures( VIA12, Metal2, u(0.06) )
|
||||
setEnclosures( VIA12, Metal1, (u(0.06), u(0.00)) )
|
||||
setEnclosures( VIA12, Metal2, (u(0.06), u(0.01)) )
|
||||
VIA23 = createVia( tech, 'VIA23', 'Metal2', 'Via2', 'Metal3', u(0.26) )
|
||||
setEnclosures( VIA23, Metal2, u(0.06) )
|
||||
setEnclosures( VIA23, Metal3, u(0.06) )
|
||||
setEnclosures( VIA23, Metal2, (u(0.06), u(0.01)) )
|
||||
setEnclosures( VIA23, Metal3, (u(0.01), u(0.06)) )
|
||||
VIA34 = createVia( tech, 'VIA34', 'Metal3', 'Via3', 'Metal4', u(0.26) )
|
||||
setEnclosures( VIA34, Metal3, u(0.06) )
|
||||
setEnclosures( VIA34, Metal4, u(0.06) )
|
||||
setEnclosures( VIA34, Metal3, (u(0.01), u(0.06)) )
|
||||
setEnclosures( VIA34, Metal4, (u(0.06), u(0.01)) )
|
||||
VIA45 = createVia( tech, 'VIA45', 'Metal4', 'Via4', 'Metal5', u(0.26) )
|
||||
setEnclosures( VIA45, Metal4, u(0.06) )
|
||||
setEnclosures( VIA45, Metal5, u(0.06) )
|
||||
setEnclosures( VIA45, Metal4, (u(0.06), u(0.01)) )
|
||||
setEnclosures( VIA45, Metal5, (u(0.01), u(0.06)) )
|
||||
VIA5T = createVia( tech, 'VIA5T', 'Metal5', 'Via5', 'MetalTop', u(0.26) )
|
||||
setEnclosures( VIA5T, Metal5 , u(0.06) )
|
||||
setEnclosures( VIA5T, MetalTop, u(0.06) )
|
||||
setEnclosures( VIA5T, Metal5 , (u(0.01), u(0.06)) )
|
||||
setEnclosures( VIA5T, MetalTop, (u(0.06), u(0.01)) )
|
||||
|
||||
Border = createBL( tech, 'Border', BasicLayer.Material.other, gds2Layer=63 )
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/__init__.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import coriolis.Cfg as Cfg
|
||||
from coriolis.helpers import truncPath, tagConfModules
|
||||
from coriolis.helpers.io import vprint
|
||||
vprint( 1, ' o Loading "symbolic.lcmos" technology.' )
|
||||
vprint( 2, ' - "%s".' % truncPath(__file__) )
|
||||
|
||||
from coriolis.Hurricane import DataBase
|
||||
from coriolis.CRL import System
|
||||
|
||||
Cfg.Configuration.pushDefaultPriority( Cfg.Parameter.Priority.ConfigurationFile )
|
||||
|
||||
if not DataBase.getDB(): DataBase.create()
|
||||
System.get()
|
||||
|
||||
from . import misc
|
||||
from . import technology
|
||||
from . import display
|
||||
from . import analog
|
||||
from . import alliance
|
||||
from . import etesian
|
||||
from . import kite
|
||||
from . import plugins
|
||||
from . import stratus1
|
||||
|
||||
Cfg.Configuration.popDefaultPriority()
|
||||
|
||||
tagConfModules()
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/alliance.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import os
|
||||
import os.path
|
||||
from coriolis.helpers import truncPath
|
||||
from coriolis.helpers.io import vprint
|
||||
vprint( 2, ' - "{}".'.format(truncPath(__file__)) )
|
||||
|
||||
from coriolis.CRL import Environment, AllianceFramework
|
||||
|
||||
allianceTop = None
|
||||
if 'ALLIANCE_TOP' in os.environ:
|
||||
allianceTop = os.environ['ALLIANCE_TOP']
|
||||
if not os.path.isdir(allianceTop):
|
||||
allianceTop = None
|
||||
if not allianceTop: allianceTop = '/soc/alliance'
|
||||
|
||||
cellsTop = allianceTop+'/cells'
|
||||
af = AllianceFramework.get()
|
||||
env = af.getEnvironment()
|
||||
|
||||
env.setSCALE_X ( 100 )
|
||||
env.setCATALOG ( 'CATAL' )
|
||||
env.setIN_LO ( 'vst' )
|
||||
env.setIN_PH ( 'ap' )
|
||||
env.setOUT_LO ( 'vst' )
|
||||
env.setOUT_PH ( 'ap' )
|
||||
env.setPOWER ( 'vdd' )
|
||||
env.setGROUND ( 'vss' )
|
||||
env.setCLOCK ( '.*ck.*|.*nck.*' )
|
||||
env.setBLOCKAGE ( 'blockage[Nn]et.*' )
|
||||
env.setPad ( '.*_px$' )
|
||||
env.setRegister ( 'sff.*' )
|
||||
|
||||
env.setWORKING_LIBRARY( '.' )
|
||||
env.addSYSTEM_LIBRARY ( library=cellsTop+'/sxlib' , mode=Environment.Append )
|
||||
env.addSYSTEM_LIBRARY ( library=cellsTop+'/dp_sxlib', mode=Environment.Append )
|
||||
env.addSYSTEM_LIBRARY ( library=cellsTop+'/ramlib' , mode=Environment.Append )
|
||||
env.addSYSTEM_LIBRARY ( library=cellsTop+'/romlib' , mode=Environment.Append )
|
||||
env.addSYSTEM_LIBRARY ( library=cellsTop+'/rflib' , mode=Environment.Append )
|
||||
env.addSYSTEM_LIBRARY ( library=cellsTop+'/rf2lib' , mode=Environment.Append )
|
||||
env.addSYSTEM_LIBRARY ( library=cellsTop+'/pxlib' , mode=Environment.Append )
|
||||
env.addSYSTEM_LIBRARY ( library=cellsTop+'/padlib' , mode=Environment.Append )
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/analog.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from coriolis.helpers import truncPath
|
||||
from coriolis.helpers.io import vprint
|
||||
vprint( 2, ' - "%s".' % truncPath(__file__) )
|
||||
|
||||
from ...common import analog
|
|
@ -0,0 +1,474 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/display.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from coriolis.helpers import truncPath
|
||||
from coriolis.helpers.io import vprint
|
||||
import coriolis.Cfg as Cfg
|
||||
import coriolis.Viewer as Viewer
|
||||
from coriolis.helpers import overlay, l, u, n
|
||||
from coriolis.technos.common.colors import toRGB
|
||||
from coriolis.technos.common.patterns import toHexa
|
||||
vprint( 2, ' - "%s".' % truncPath(__file__) )
|
||||
|
||||
|
||||
def createStyles ( scale=1.0 ):
|
||||
with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg:
|
||||
cfg.viewer.minimumSize = 500
|
||||
cfg.viewer.pixelThreshold = 5
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Style: Alliance.Coriolis [black].
|
||||
|
||||
style = Viewer.DisplayStyle( 'Alliance.Coriolis [black]' )
|
||||
style.setDescription( 'Alliance Coriolis Look - black background' )
|
||||
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
|
||||
|
||||
style.addDrawingStyle( group='Viewer', name='fallback' , color=toRGB('Gray238' ), border=1, pattern='55AA55AA55AA55AA' )
|
||||
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('Gray50' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='foreground' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='rubber' , color=toRGB('192,0,192' ), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='phantom' , color=toRGB('Seashell4' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='boundaries' , color=toRGB('208,199,192'), border=1, pattern='0000000000000000', threshold=0 )
|
||||
style.addDrawingStyle( group='Viewer', name='marker' , color=toRGB('80,250,80' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='selectionDraw' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='selectionFill' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('White' ), border=1, threshold=2.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('White' ), border=2, threshold=6.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='ghost' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('White' ), border=1, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.instance' , color=toRGB('Black' ), border=1, threshold=4.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.reference' , color=toRGB('White' ), border=1, threshold=20.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='undef' , color=toRGB('Violet' ), border=0, pattern='2244118822441188' )
|
||||
style.addDrawingStyle( group='Viewer', name='mauka.container', color=toRGB('Magenta4' ), border=4, pattern='0000000000000000', goMatched=False )
|
||||
|
||||
# Group: Active Layer.
|
||||
style.addDrawingStyle( group='Active Layer', name='nWell' , color=toRGB('Tan' ), pattern='55AA55AA55AA55AA' , threshold=1.5 *scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='pWell' , color=toRGB('LightYellow'), pattern='55AA55AA55AA55AA' , threshold=1.50*scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='nImplant', color=toRGB('LawnGreen' ), pattern='55AA55AA55AA55AA' , threshold=1.50*scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='pImplant', color=toRGB('Yellow' ), pattern='55AA55AA55AA55AA' , threshold=1.50*scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='active' , color=toRGB('White' ), pattern=toHexa('antihash1.8'), threshold=1.50*scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='poly' , color=toRGB('Red' ), pattern='55AA55AA55AA55AA' , threshold=1.50*scale )
|
||||
|
||||
# Group: Routing Layer.
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal1' , color=toRGB('Blue' ), pattern=toHexa('poids2.8' ), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal2' , color=toRGB('Aqua' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal3' , color=toRGB('LightPink'), pattern=toHexa('light_antihash1.8'), threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal4' , color=toRGB('Green' ), pattern=toHexa('light_antihash2.8'), threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal5' , color=toRGB('Yellow' ), pattern='1144114411441144' , threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal6' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal7' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal8' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal9' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal10', color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
|
||||
|
||||
# Group: Cuts (VIA holes).
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut0', color=toRGB('0,150,150'), threshold=1.50*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut1', color=toRGB('Aqua' ), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut2', color=toRGB('LightPink'), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut3', color=toRGB('Green' ), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut4', color=toRGB('Yellow' ), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut5', color=toRGB('Violet' ), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut6', color=toRGB('Violet' ), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut7', color=toRGB('Violet' ), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut8', color=toRGB('Violet' ), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut9', color=toRGB('Violet' ), threshold=0.80*scale )
|
||||
|
||||
# Group: MIM6.
|
||||
style.addDrawingStyle( group='MIM6', name='metbot_r', color=toRGB('Aqua' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='MIM6', name='cut6' , color=toRGB('LightPink'), pattern=toHexa('light_antihash1.8'), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='MIM6', name='metal7' , color=toRGB('Green' ), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale )
|
||||
|
||||
# Group: Blockages.
|
||||
style.addDrawingStyle( group='Blockages', name='blockage1' , color=toRGB('Blue' ), pattern='006070381c0e0703' , threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage2' , color=toRGB('Aqua' ), pattern='8103060c183060c0' , threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage3' , color=toRGB('LightPink'), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage4' , color=toRGB('Green' ), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage5' , color=toRGB('Yellow' ), pattern='1144114411441144' , threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage6' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage7' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage8' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage9' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage10', color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
|
||||
|
||||
# Group: Knik & Kite.
|
||||
style.addDrawingStyle( group='Knik & Kite', name='SPL1' , color=toRGB('Red' ) )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='AutoLayer' , color=toRGB('Magenta' ) )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gmetalh' , color=toRGB('128,255,200'), pattern=toHexa('light_antihash0.8'), border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gmetalv' , color=toRGB('200,200,255'), pattern=toHexa('light_antihash1.8'), border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gcut' , color=toRGB('255,255,190'), border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::Edge' , color=toRGB('255,255,190'), pattern='0000000000000000', threshold=0.02*scale, border=4 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::GCell', color=toRGB('255,0,0' ), pattern='0000000000000000', threshold=0.02*scale, border=4 )
|
||||
|
||||
Viewer.Graphics.addStyle( style )
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Style: Alliance.Coriolis [white].
|
||||
|
||||
style = Viewer.DisplayStyle( 'Alliance.Coriolis [white]' )
|
||||
style.inheritFrom( 'Alliance.Coriolis [black]' )
|
||||
style.setDescription( 'Alliance Coriolis Look - white background' )
|
||||
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
|
||||
|
||||
style.addDrawingStyle( group='Viewer', name='fallback' , color=toRGB('Gray238' ), border=1, pattern='55AA55AA55AA55AA' )
|
||||
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('Gray50' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='foreground' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='rubber' , color=toRGB('192,0,192' ), border=4, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='phantom' , color=toRGB('Seashell4' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='boundaries' , color=toRGB('208,199,192'), border=1, pattern='0000000000000000', threshold=0 )
|
||||
style.addDrawingStyle( group='Viewer', name='marker' , color=toRGB('80,250,80' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='selectionDraw' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='selectionFill' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('White' ), border=1, threshold=2.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('White' ), border=2, threshold=6.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='ghost' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('White' ), border=1, threshold=0.0 *scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.instance' , color=toRGB('White' ), border=1, threshold=400.0 *scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.reference', color=toRGB('White' ), border=1, threshold=200.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='undef' , color=toRGB('Violet' ), border=0, pattern='2244118822441188' )
|
||||
|
||||
# Active Layers.
|
||||
style.addDrawingStyle( group='Active Layer', name='nWell' , color=toRGB('Tan' ), pattern=toHexa('urgo.8' ), border=1, threshold=0*scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='pWell' , color=toRGB('LightYellow'), pattern=toHexa('urgo.8' ), border=1, threshold=0*scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='nImplant', color=toRGB('LawnGreen' ), pattern=toHexa('antihash0.8'), border=1, threshold=0*scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='pImplant', color=toRGB('Yellow' ), pattern=toHexa('antihash0.8'), border=1, threshold=0*scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='active' , color=toRGB('White' ), pattern=toHexa('antihash1.8'), border=1, threshold=0*scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='poly' , color=toRGB('Red' ), pattern=toHexa('poids2.8' ), border=1, threshold=0*scale )
|
||||
style.addDrawingStyle( group='Active Layer', name='poly2' , color=toRGB('Orange' ), pattern=toHexa('poids2.8' ), border=1, threshold=0*scale )
|
||||
|
||||
# Routing Layers.
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal1' , color=toRGB('Blue' ), pattern=toHexa('slash.8' ), border=1, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal2' , color=toRGB('Aqua' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metcap' , color=toRGB('DarkTurquoise'), pattern=toHexa('poids2.8'), border=2, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal3' , color=toRGB('LightPink' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal4' , color=toRGB('Green' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal5' , color=toRGB('Yellow' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal6' , color=toRGB('Violet' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal7' , color=toRGB('Red' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal8' , color=toRGB('Blue' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal9' , color=toRGB('Blue' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Routing Layer', name='metal10', color=toRGB('Blue' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
|
||||
|
||||
|
||||
# Cuts (VIA holes).
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut0', color=toRGB('0,150,150'), threshold=0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut1', color=toRGB('Aqua' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut2', color=toRGB('LightPink'), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut3', color=toRGB('Green' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut4', color=toRGB('Yellow' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut5', color=toRGB('Violet' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut6', color=toRGB('Red' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut7', color=toRGB('Blue' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut8', color=toRGB('Blue' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut9', color=toRGB('Blue' ), threshold=0.0*scale )
|
||||
|
||||
# MIM6.
|
||||
style.addDrawingStyle( group='MIM6', name='metbot_r', color=toRGB('Aqua' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='MIM6', name='metal7' , color=toRGB('Green'), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale )
|
||||
|
||||
# Blockages.
|
||||
style.addDrawingStyle( group='Blockages', name='blockage1' , color=toRGB('Blue' ), pattern=toHexa('light_antislash0.8'), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage2' , color=toRGB('Aqua' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage3' , color=toRGB('LightPink'), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage4' , color=toRGB('Green' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage5' , color=toRGB('Yellow' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage6' , color=toRGB('Violet' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage7' , color=toRGB('Red' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage8' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage9' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage10', color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
|
||||
# Knick & Kite.
|
||||
style.addDrawingStyle( group='Knik & Kite', name='SPL1' , color=toRGB('Red' ) )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='AutoLayer' , color=toRGB('Magenta' ) )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gmetalh' , color=toRGB('128,255,200'), pattern=toHexa('antislash2.32' ), border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gmetalv' , color=toRGB('200,200,255'), pattern=toHexa('light_antihash1.8'), border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gcut' , color=toRGB('255,255,190'), border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::Edge' , color=toRGB('255,255,190'), pattern='0000000000000000', border=4, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::GCell', color=toRGB('255,255,190'), pattern='0000000000000000', border=2, threshold=0.10*scale )
|
||||
|
||||
Viewer.Graphics.addStyle( style )
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Style: Alliance.Classic [black]
|
||||
|
||||
style = Viewer.DisplayStyle( 'Alliance.Classic [black]' )
|
||||
style.setDescription( 'Alliance Classic Look - black background' )
|
||||
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
|
||||
|
||||
# Viewer.
|
||||
style.addDrawingStyle( group='Viewer', name='fallback' , color=toRGB('Gray238' ), border=1, pattern='55AA55AA55AA55AA' )
|
||||
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('Gray50' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='foreground' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='rubber' , color=toRGB('192,0,192' ), border=4, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='phantom' , color=toRGB('Seashell4' ), border=1 )
|
||||
#style.addDrawingStyle( group='Viewer', name='boundaries' , color=toRGB('208,199,192'), border=2, threshold=0 )
|
||||
style.addDrawingStyle( group='Viewer', name='boundaries' , color=toRGB('wheat1') , border=2, pattern='0000000000000000', threshold=0 )
|
||||
style.addDrawingStyle( group='Viewer', name='marker' , color=toRGB('80,250,80' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='selectionDraw' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='selectionFill' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('White' ), border=1, threshold=8.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('White' ), border=2, threshold=6.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='ghost' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('White' ), border=1, threshold= 0.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.instance' , color=toRGB('White' ), border=1, threshold=400.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.reference', color=toRGB('White' ), border=1, threshold=200.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='undef' , color=toRGB('Violet' ), border=0, pattern='2244118822441188' )
|
||||
|
||||
# Active Layers.
|
||||
style.addDrawingStyle( group='Active Layers', name='nWell' , color=toRGB('Tan' ), pattern=toHexa('urgo.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='pWell' , color=toRGB('LightYellow'), pattern=toHexa('urgo.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='nImplant', color=toRGB('LawnGreen' ), pattern=toHexa('antihash0.8'), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='pImplant', color=toRGB('Yellow' ), pattern=toHexa('antihash0.8'), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='active' , color=toRGB('White' ), pattern='0000000000000000' , border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='poly' , color=toRGB('Red' ), pattern=toHexa('poids2.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='poly2' , color=toRGB('Orange' ), pattern=toHexa('poids2.8' ), border=1, threshold=0.00*scale )
|
||||
|
||||
# Routing Layers.
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal1' , color=toRGB('Blue' ), pattern=toHexa('slash.8' ), border=1, threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal2' , color=toRGB('Aqua' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metcap' , color=toRGB('DarkTurquoise'), pattern=toHexa('poids2.8' ), border=2, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal3' , color=toRGB('LightPink' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal4' , color=toRGB('Green' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal5' , color=toRGB('Yellow' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal6' , color=toRGB('Violet' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal7' , color=toRGB('Red' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal8' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal9' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal10', color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
|
||||
# Cuts (VIA holes).
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut0', color=toRGB('0,150,150'), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut1', color=toRGB('Aqua' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut2', color=toRGB('LightPink'), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut3', color=toRGB('Green' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut4', color=toRGB('Yellow' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut5', color=toRGB('Violet' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut6', color=toRGB('Red' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut7', color=toRGB('Blue' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut8', color=toRGB('Blue' ), threshold=0.0*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut9', color=toRGB('Blue' ), threshold=0.0*scale )
|
||||
|
||||
# MIM6.
|
||||
style.addDrawingStyle( group='MIMI6', name='metbot_r', color=toRGB('Aqua' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='MIMI6', name='metal7' , color=toRGB('Green'), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale )
|
||||
|
||||
# Blockages.
|
||||
style.addDrawingStyle( group='Blockages', name='blockage1' , color=toRGB('Blue' ), pattern=toHexa('light_antislash0.8'), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage2' , color=toRGB('Aqua' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage3' , color=toRGB('LightPink'), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage4' , color=toRGB('Green' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage5' , color=toRGB('Yellow' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage6' , color=toRGB('Violet' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage7' , color=toRGB('Red' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage8' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage9' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage10', color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
|
||||
|
||||
# Knick & Kite.
|
||||
style.addDrawingStyle( group='Knik & Kite', name='SPL1' , color=toRGB('Red' ) )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='AutoLayer' , color=toRGB('Magenta' ) )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gmetalh' , color=toRGB('128,255,200'), pattern=toHexa('antislash2.32' ), border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gmetalv' , color=toRGB('200,200,255'), pattern=toHexa('light_antihash1.8'), border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gcut' , color=toRGB('255,255,190'), border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::Edge' , color=toRGB('255,255,190'), pattern='0000000000000000' , border=4, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::GCell', color=toRGB('255,255,190'), pattern='0000000000000000' , border=2, threshold=0.10*scale )
|
||||
|
||||
Viewer.Graphics.addStyle( style )
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Style: Alliance.Classic [white].
|
||||
|
||||
style = Viewer.DisplayStyle( 'Alliance.Classic [white]' )
|
||||
style.inheritFrom( 'Alliance.Classic [black]' )
|
||||
style.setDescription( 'Alliance Classic Look - white background' )
|
||||
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
|
||||
|
||||
# Group: Viewer.
|
||||
style.addDrawingStyle( group='Viewer', name='fallback' , color=toRGB('Black'), border=1, pattern='55AA55AA55AA55AA' )
|
||||
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('White'), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='foreground' , color=toRGB('Black'), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='selectionDraw' , color=toRGB('Black'), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='selectionFill' , color=toRGB('Black'), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('Black'), border=1, threshold=6.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('Black'), border=1, threshold=6.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='ghost' , color=toRGB('Black'), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('Black'), border=1, threshold=0.0 *scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.instance' , color=toRGB('Black'), border=1, threshold=4.0 *scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.reference', color=toRGB('Black'), border=1, threshold=20.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='undef' , color=toRGB('Black'), border=0, pattern='2244118822441188' )
|
||||
|
||||
Viewer.Graphics.addStyle( style )
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Style: Layout Design [black]
|
||||
|
||||
style = Viewer.DisplayStyle( 'Layout Design [black]' )
|
||||
style.inheritFrom( 'Alliance.Classic [black]' )
|
||||
style.setDescription( 'Alliance Classic Look - white background' )
|
||||
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
|
||||
|
||||
# Active Layers.
|
||||
style.addDrawingStyle( group='Active Layers', name='nWell' , color=toRGB('Tan' ), pattern='0000000000000000', threshold=1.50*scale, border=2 )
|
||||
style.addDrawingStyle( group='Active Layers', name='pWell' , color=toRGB('LightYellow'), pattern='0000000000000000', threshold=1.50*scale, border=2 )
|
||||
style.addDrawingStyle( group='Active Layers', name='nImplant', color=toRGB('LawnGreen' ), pattern='0000000000000000', threshold=1.50*scale, border=2 )
|
||||
style.addDrawingStyle( group='Active Layers', name='pImplant', color=toRGB('Yellow' ), pattern='0000000000000000', threshold=1.50*scale, border=2 )
|
||||
style.addDrawingStyle( group='Active Layers', name='active' , color=toRGB('White' ), pattern='0000000000000000', threshold=1.50*scale, border=2 )
|
||||
style.addDrawingStyle( group='Active Layers', name='poly' , color=toRGB('Red' ), pattern='0000000000000000', threshold=1.50*scale, border=2 )
|
||||
|
||||
# Routing Layers.
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal1' , color=toRGB('Blue' ), pattern='0000000000000000', threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal2' , color=toRGB('Aqua' ), pattern='0000000000000000', threshold=0.40*scale, border=2 )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal3' , color=toRGB('LightPink'), pattern='0000000000000000', threshold=0.02*scale, border=2 )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal4' , color=toRGB('Green' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal5' , color=toRGB('Yellow' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal6' , color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal7' , color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal8' , color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal9' , color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal10', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
|
||||
|
||||
# Cuts (VIA holes).
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut0', color=toRGB('0,150,150'), pattern=toHexa('poids4.8'), threshold=1.50*scale, border=1 )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut1', color=toRGB('Aqua' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut2', color=toRGB('LightPink'), pattern='0000000000000000', threshold=0.80*scale, border=1 )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut3', color=toRGB('Green' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut4', color=toRGB('Yellow' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut5', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut6', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut7', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut8', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut9', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
|
||||
|
||||
Viewer.Graphics.addStyle( style )
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Style: Layout Design [white]
|
||||
|
||||
style = Viewer.DisplayStyle( 'Layout Design [white]' )
|
||||
style.inheritFrom( 'Layout Design [black]' )
|
||||
style.setDescription( 'Layout Design Look - white background' )
|
||||
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
|
||||
|
||||
|
||||
# Group: Viewer.
|
||||
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('White'), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('Black'), border=1, threshold=2.0 *scale )
|
||||
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('Black'), border=1, threshold=2.0 *scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('Black'), border=1, threshold=0.0 *scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.reference', color=toRGB('Black'), border=1, threshold=20.0*scale )
|
||||
|
||||
# Group: Active Layers.
|
||||
style.addDrawingStyle( group='Active Layers', name='active', color=toRGB('175,175,175'), pattern='0000000000000000', threshold=1.50*scale, border=2 )
|
||||
|
||||
Viewer.Graphics.addStyle( style )
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Style: For Printers [white]
|
||||
|
||||
style = Viewer.DisplayStyle( 'For Printers' )
|
||||
style.setDescription( 'For Printers' )
|
||||
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
|
||||
|
||||
# Group: Viewer.
|
||||
style.addDrawingStyle( group='Viewer', name='fallback' , color=toRGB('Gray238' ), border=1, pattern='55AA55AA55AA55AA' )
|
||||
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('White' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='foreground' , color=toRGB('Black' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='rubber' , color=toRGB('192,0,192'), border=4, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='phantom' , color=toRGB('Seashell4'), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='boundaries' , color=toRGB('Black' ), border=1, pattern='0000000000000000', threshold=0 )
|
||||
style.addDrawingStyle( group='Viewer', name='marker' , color=toRGB('80,250,80'), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='selectionDraw' , color=toRGB('Black' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='selectionFill' , color=toRGB('Black' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('Black' ), border=1, threshold=2.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('Black' ), border=2, threshold=6.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='ghost' , color=toRGB('Black' ), border=1 )
|
||||
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('Black' ), border=1, threshold=0.0 *scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.instance' , color=toRGB('Black' ), border=1, threshold=4.0 *scale )
|
||||
style.addDrawingStyle( group='Viewer', name='text.reference' , color=toRGB('Black' ), border=1, threshold=20.0*scale )
|
||||
style.addDrawingStyle( group='Viewer', name='undef' , color=toRGB('Violet' ), border=0, pattern='2244118822441188' )
|
||||
style.addDrawingStyle( group='Viewer', name='mauka.container', color=toRGB('Magenta4' ), border=4, pattern='0000000000000000', goMatched=False )
|
||||
|
||||
# Group: Active Layers.
|
||||
style.addDrawingStyle( group='Active Layers', name='nWell' , color=toRGB('Tan' ), pattern=toHexa('urgo.32' ), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='pWell' , color=toRGB('LightYellow'), pattern=toHexa('antipoids2.32'), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='nImplant', color=toRGB('LawnGreen' ), pattern=toHexa('diffusion.32' ), border=0, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='pImplant', color=toRGB('Yellow' ), pattern=toHexa('diffusion.32' ), border=0, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='active' , color=toRGB('White' ), pattern=toHexa('active.32' ), border=0, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='poly' , color=toRGB('Red' ), pattern=toHexa('antipoids2.32'), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Active Layers', name='poly2' , color=toRGB('Orange' ), pattern=toHexa('antipoids2.32'), border=1, threshold=0.02*scale )
|
||||
|
||||
# Group: Routing Layers.
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal1' , color=toRGB('Blue' ), pattern=toHexa('slash.32' ), border=4, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal2' , color=toRGB('Aqua' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metcap' , color=toRGB('DarkTurquoise'), pattern=toHexa('poids2.32' ), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal3' , color=toRGB('LightPink' ), pattern=toHexa('antislash3.32'), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal4' , color=toRGB('Green' ), pattern=toHexa('antislash4.32'), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal5' , color=toRGB('Yellow' ), pattern=toHexa('antislash5.32'), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal6' , color=toRGB('Violet' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal7' , color=toRGB('Violet' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal8' , color=toRGB('Violet' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal9' , color=toRGB('Violet' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal10', color=toRGB('Violet' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
|
||||
|
||||
# Group: Cuts (VIA holes)
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut0', color=toRGB('Blue' ), pattern=toHexa('poids2.8' ), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut1', color=toRGB('Aqua' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut2', color=toRGB('LightPink'), pattern=toHexa('poids2.8' ), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut3', color=toRGB('Green' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut4', color=toRGB('Yellow' ), pattern=toHexa('poids2.8' ), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut5', color=toRGB('Violet' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut6', color=toRGB('Violet' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut7', color=toRGB('Violet' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut8', color=toRGB('Violet' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
|
||||
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut9', color=toRGB('Violet' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
|
||||
|
||||
# Group: MIM6.
|
||||
style.addDrawingStyle( group='MIM6', name='metbot_r', color=toRGB('Aqua' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='MIM6', name='cut6' , color=toRGB('LightPink'), pattern=toHexa('light_antihash1.8'), threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='MIM6', name='metal7' , color=toRGB('Green' ), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale )
|
||||
|
||||
# Group: Blockages.
|
||||
style.addDrawingStyle( group='Blockages', name='blockage1' , color=toRGB('Blue' ), pattern='006070381c0e0703' , threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage2' , color=toRGB('Aqua' ), pattern='8103060c183060c0' , threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage3' , color=toRGB('LightPink'), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage4' , color=toRGB('Green' ), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage5' , color=toRGB('Yellow' ), pattern='1144114411441144' , threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage6' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage7' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage8' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage9' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
|
||||
style.addDrawingStyle( group='Blockages', name='blockage10', color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
|
||||
|
||||
# Group: Knik & Kite.
|
||||
style.addDrawingStyle( group='Knik & Kite', name='SPL1' , color=toRGB('Red' ) )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='AutoLayer' , color=toRGB('Magenta' ) )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gmetalh' , color=toRGB('128,255,200'), pattern=toHexa('light_antihash0.8') , border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gmetalv' , color=toRGB('200,200,255'), pattern=toHexa('light_antihash1.8') , border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='gcut' , color=toRGB('255,255,190'), border=1 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::Edge' , color=toRGB('255,255,190'), pattern='0000000000000000', border=2 )
|
||||
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::GCell', color=toRGB('Black' ), pattern='0000000000000000', border=2, threshold=0.80*scale )
|
||||
|
||||
Viewer.Graphics.addStyle( style )
|
||||
|
||||
|
||||
Viewer.Graphics.setStyle( 'Alliance.Classic [black]' )
|
||||
|
||||
createStyles( scale=1.0 )
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/etesian.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from coriolis.helpers import truncPath
|
||||
from coriolis.helpers.io import vprint
|
||||
vprint( 2, ' - "%s".' % truncPath(__file__) )
|
||||
|
||||
from ...common import etesian
|
|
@ -0,0 +1,194 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/kite.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import coriolis.Cfg as Cfg
|
||||
from coriolis.Hurricane import DataBase
|
||||
from coriolis.CRL import AllianceFramework, RoutingGauge, \
|
||||
RoutingLayerGauge, CellGauge
|
||||
from coriolis.helpers import truncPath, l, u, n
|
||||
from coriolis.helpers.io import vprint
|
||||
vprint( 2, ' - "%s".' % truncPath(__file__) )
|
||||
|
||||
from ...common import kite
|
||||
|
||||
|
||||
p = Cfg.getParamDouble ( 'lefImport.minTerminalWidth' ).setDouble ( 0.0 )
|
||||
p = Cfg.getParamString ( 'katabatic.routingGauge' ).setString ( 'sxlib' )
|
||||
p = Cfg.getParamInt ( "katabatic.globalLengthThreshold" ).setInt ( 1450 )
|
||||
p = Cfg.getParamPercentage( "katabatic.saturateRatio" ).setPercentage( 80 )
|
||||
p = Cfg.getParamInt ( "katabatic.saturateRp" ).setInt ( 8 )
|
||||
p = Cfg.getParamString ( 'katabatic.topRoutingLayer' ).setString ( 'METAL5' )
|
||||
|
||||
# Kite parameters.
|
||||
p = Cfg.getParamInt( "kite.hTracksReservedLocal" ); p.setInt( 3 ); p.setMin( 0 ); p.setMax( 20 )
|
||||
p = Cfg.getParamInt( "kite.vTracksReservedLocal" ); p.setInt( 3 ); p.setMin( 0 ); p.setMax( 20 )
|
||||
p = Cfg.getParamInt( "kite.eventsLimit" ); p.setInt( 4000002 )
|
||||
p = Cfg.getParamInt( "kite.ripupCost" ); p.setInt( 3 ); p.setMin( 0 )
|
||||
p = Cfg.getParamInt( "kite.strapRipupLimit" ); p.setInt( 16 ); p.setMin( 1 )
|
||||
p = Cfg.getParamInt( "kite.localRipupLimit" ); p.setInt( 9 ); p.setMin( 1 )
|
||||
p = Cfg.getParamInt( "kite.globalRipupLimit" ); p.setInt( 5 ); p.setMin( 1 )
|
||||
p = Cfg.getParamInt( "kite.longGlobalRipupLimit" ); p.setInt( 5 ); p.setMin( 1 )
|
||||
|
||||
# Anabatic & Katana parameters are temporarily hosted here.
|
||||
p = Cfg.getParamString ( 'anabatic.routingGauge' ); p.setString ( 'sxlib' )
|
||||
p = Cfg.getParamInt ( "anabatic.globalLengthThreshold" ); p.setInt ( 1450 )
|
||||
p = Cfg.getParamPercentage( "anabatic.saturateRatio" ); p.setPercentage( 80 )
|
||||
p = Cfg.getParamInt ( "anabatic.saturateRp" ); p.setInt ( 8 )
|
||||
p = Cfg.getParamString ( 'anabatic.topRoutingLayer' ); p.setString ( 'METAL5' )
|
||||
p = Cfg.getParamInt ( "anabatic.edgeLength" ); p.setInt ( 24 )
|
||||
p = Cfg.getParamInt ( "anabatic.edgeWidth" ); p.setInt ( 4 )
|
||||
p = Cfg.getParamDouble ( "anabatic.edgeCostH" ); p.setDouble ( 19.0 )
|
||||
p = Cfg.getParamDouble ( "anabatic.edgeCostK" ); p.setDouble ( -60.0 )
|
||||
p = Cfg.getParamDouble ( "anabatic.edgeHScaling" ); p.setDouble ( 1.0 )
|
||||
p = Cfg.getParamInt ( "anabatic.globalIterations" ); p.setInt ( 10 ); p.setMin(1); p.setMax(100)
|
||||
p = Cfg.getParamEnumerate ( "anabatic.gcell.displayMode" ); p.setInt ( 1 )
|
||||
p.addValue( "Boundary", 1 )
|
||||
p.addValue( "Density" , 2 )
|
||||
|
||||
p = Cfg.getParamBool ( "katana.useGlobalEstimate" ); p.setBool ( False );
|
||||
p = Cfg.getParamInt ( "katana.hTracksReservedLocal" ); p.setInt ( 3 ); p.setMin(0); p.setMax(20)
|
||||
p = Cfg.getParamInt ( "katana.vTracksReservedLocal" ); p.setInt ( 3 ); p.setMin(0); p.setMax(20)
|
||||
p = Cfg.getParamInt ( "katana.hTracksReservedMin" ); p.setInt ( 1 ); p.setMin(0); p.setMax(20)
|
||||
p = Cfg.getParamInt ( "katana.vTracksReservedMin" ); p.setInt ( 1 ); p.setMin(0); p.setMax(20)
|
||||
p = Cfg.getParamInt ( "katana.termSatReservedLocal" ); p.setInt ( 8 )
|
||||
p = Cfg.getParamInt ( "katana.termSatThreshold" ); p.setInt ( 9 )
|
||||
p = Cfg.getParamInt ( "katana.eventsLimit" ); p.setInt ( 4000002 )
|
||||
p = Cfg.getParamInt ( "katana.ripupCost" ); p.setInt ( 3 ); p.setMin(0)
|
||||
p = Cfg.getParamInt ( "katana.strapRipupLimit" ); p.setInt ( 16 ); p.setMin(1)
|
||||
p = Cfg.getParamInt ( "katana.localRipupLimit" ); p.setInt ( 9 ); p.setMin(1)
|
||||
p = Cfg.getParamInt ( "katana.globalRipupLimit" ); p.setInt ( 5 ); p.setMin(1)
|
||||
p = Cfg.getParamInt ( "katana.longGlobalRipupLimit" ); p.setInt ( 5 ); p.setMin(1)
|
||||
p = Cfg.getParamString( 'chip.padCoreSide' ); p.setString( 'South' )
|
||||
|
||||
|
||||
tech = DataBase.getDB().getTechnology()
|
||||
af = AllianceFramework.get()
|
||||
rg = RoutingGauge.create( 'sxlib' )
|
||||
|
||||
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # metal.
|
||||
, RoutingLayerGauge.Vertical # preferred routing direction.
|
||||
, RoutingLayerGauge.PinOnly # layer usage.
|
||||
, 0 # depth.
|
||||
, 0.0 # density (deprecated).
|
||||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA12).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
||||
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # metal.
|
||||
, RoutingLayerGauge.Horizontal # preferred routing direction.
|
||||
, RoutingLayerGauge.Default # layer usage.
|
||||
, 1 # depth.
|
||||
, 0.0 # density (deprecated).
|
||||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA23).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
||||
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # metal.
|
||||
, RoutingLayerGauge.Vertical # preferred routing direction.
|
||||
, RoutingLayerGauge.Default # layer usage.
|
||||
, 2 # depth.
|
||||
, 0.0 # density (deprecated).
|
||||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA34).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
||||
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # metal.
|
||||
, RoutingLayerGauge.Horizontal # preferred routing direction.
|
||||
, RoutingLayerGauge.Default # layer usage.
|
||||
, 3 # depth.
|
||||
, 0.0 # density (deprecated).
|
||||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA23).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
||||
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL5') # metal.
|
||||
, RoutingLayerGauge.Vertical # preferred routing direction.
|
||||
, RoutingLayerGauge.Default # layer usage.
|
||||
, 4 # depth.
|
||||
, 0.0 # density (deprecated).
|
||||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA23).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
||||
af.addRoutingGauge( rg )
|
||||
|
||||
rg = RoutingGauge.create( 'sxlib-2M' )
|
||||
|
||||
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # metal.
|
||||
, RoutingLayerGauge.Vertical # preferred routing direction.
|
||||
, RoutingLayerGauge.PinOnly # layer usage.
|
||||
, 0 # depth.
|
||||
, 0.0 # density (deprecated).
|
||||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA12).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
||||
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # metal.
|
||||
, RoutingLayerGauge.Horizontal # preferred routing direction.
|
||||
, RoutingLayerGauge.Default # layer usage.
|
||||
, 1 # depth.
|
||||
, 0.0 # density (deprecated).
|
||||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA23).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
||||
af.addRoutingGauge( rg )
|
||||
af.setRoutingGauge( 'sxlib' )
|
||||
|
||||
# Gauge for standard cells.
|
||||
cg = CellGauge.create( 'sxlib'
|
||||
, 'metal2' # pin layer name.
|
||||
, l( 5.0) # pitch.
|
||||
, l( 50.0) # cell slice height.
|
||||
, l( 5.0) # cell slice step.
|
||||
)
|
||||
af.addCellGauge( cg )
|
||||
|
||||
# Gauge for Alliance symbolic I/O pads.
|
||||
cg = CellGauge.create( 'pxlib'
|
||||
, 'metal2' # pin layer name.
|
||||
, l( 5.0) # pitch.
|
||||
, l(400.0) # cell slice height.
|
||||
, l(200.0) # cell slice step.
|
||||
)
|
||||
af.addCellGauge( cg )
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/misc.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from coriolis.helpers import truncPath
|
||||
from coriolis.helpers.io import vprint
|
||||
vprint( 2, ' - "%s".' % truncPath(__file__) )
|
||||
|
||||
from ...common import misc
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/patterns.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from coriolis.helpers import truncPath
|
||||
from coriolis.helpers.io import vprint
|
||||
vprint( 2, ' - "%s".' % truncPath(__file__) )
|
||||
|
||||
from ...common import patterns
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/plugins.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import coriolis.Cfg as Cfg
|
||||
from coriolis.helpers import truncPath, l, u, n
|
||||
from coriolis.helpers.io import vprint
|
||||
vprint( 2, ' - "%s".' % truncPath(__file__) )
|
||||
|
||||
Cfg.getParamInt ( "chip.block.rails.count" ).setInt ( 5 )
|
||||
Cfg.getParamInt ( "chip.block.rails.hWidth" ).setInt ( l( 12) )
|
||||
Cfg.getParamInt ( "chip.block.rails.vWidth" ).setInt ( l( 12) )
|
||||
Cfg.getParamInt ( "chip.block.rails.hSpacing" ).setInt ( l( 3) )
|
||||
Cfg.getParamInt ( "chip.block.rails.vSpacing" ).setInt ( l( 3) )
|
||||
Cfg.getParamBool ( "chip.useAbstractPads" ).setBool ( True )
|
||||
Cfg.getParamInt ( 'clockTree.minimumSide' ).setInt ( l(600) )
|
||||
Cfg.getParamString( 'clockTree.buffer' ).setString( 'buf_x2')
|
||||
Cfg.getParamString( 'clockTree.placerEngine' ).setString( 'Etesian')
|
||||
Cfg.getParamInt ( 'block.spareSide' ).setInt ( 10 )
|
||||
Cfg.getParamString( 'spares.buffer' ).setString( 'buf_x8')
|
||||
Cfg.getParamInt ( 'spares.maxSinks' ).setInt ( 31 )
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/stratus1.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import os.path
|
||||
import coriolis.Cfg as Cfg
|
||||
from coriolis.helpers import sysConfDir, truncPath
|
||||
from coriolis.helpers.io import vprint
|
||||
vprint( 2, ' - "%s".' % truncPath(__file__) )
|
||||
|
||||
from ...common import stratus1
|
||||
|
||||
Cfg.getParamString( "stratus1.format" ).setString( "vst" )
|
||||
Cfg.getParamString( "stratus1.simulator" ).setString( "asimut" )
|
||||
Cfg.getParamString( "stratus1.mappingName" ).setString( os.path.join(sysConfDir,'symbolic/cmos/stratus2sxlib.xml') )
|
|
@ -0,0 +1,401 @@
|
|||
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | Alliance / Hurricane Interface |
|
||||
# | |
|
||||
# | Author : Jean-Paul CHAPUT |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./etc/symbolic/lcmos/technology.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from coriolis.helpers import l, u, n, truncPath
|
||||
from coriolis.helpers.io import WarningMessage, vprint
|
||||
vprint( 2, ' - "{}".'.format(truncPath(__file__)) )
|
||||
|
||||
from coriolis.Hurricane import DbU, DataBase, Technology, Layer, BasicLayer, \
|
||||
DiffusionLayer, TransistorLayer, \
|
||||
RegularLayer, ContactLayer, ViaLayer
|
||||
|
||||
|
||||
def createBL ( layerName, material ):
|
||||
global tech
|
||||
return BasicLayer.create( tech, layerName, BasicLayer.Material(material) )
|
||||
|
||||
|
||||
tech = DataBase.getDB().getTechnology()
|
||||
if tech:
|
||||
print( WarningMessage( 'lcmos.technology: Technology already exists, "{}"'.format(tech.getName()) ))
|
||||
else:
|
||||
tech = Technology.create( DataBase.getDB(), 'lcmos' )
|
||||
|
||||
DbU.setPrecision ( 2 )
|
||||
DbU.setPhysicalsPerGrid ( 0.5, DbU.UnitPowerMicro )
|
||||
DbU.setGridsPerLambda ( 2 )
|
||||
DbU.setSymbolicSnapGridStep( DbU.fromLambda(1.0) )
|
||||
DbU.setPolygonStep ( DbU.fromGrid (2.0) )
|
||||
|
||||
|
||||
from ...common import loadGdsLayers
|
||||
|
||||
|
||||
nWell = createBL( 'nWell' , BasicLayer.Material.nWell ) # Non-Routing Layers.
|
||||
pWell = createBL( 'pWell' , BasicLayer.Material.pWell )
|
||||
nImplant = createBL( 'nImplant' , BasicLayer.Material.nImplant )
|
||||
pImplant = createBL( 'pImplant' , BasicLayer.Material.pImplant )
|
||||
active = createBL( 'active' , BasicLayer.Material.active )
|
||||
poly = createBL( 'poly' , BasicLayer.Material.poly )
|
||||
poly2 = createBL( 'poly2' , BasicLayer.Material.poly )
|
||||
cut0 = createBL( 'cut0' , BasicLayer.Material.cut ) # Routing Layers & VIA Cuts.
|
||||
metal1 = createBL( 'metal1' , BasicLayer.Material.metal ) # WARNING: order *is* meaningful.
|
||||
cut1 = createBL( 'cut1' , BasicLayer.Material.cut )
|
||||
metal2 = createBL( 'metal2' , BasicLayer.Material.metal )
|
||||
metcap = createBL( 'metcap' , BasicLayer.Material.other )
|
||||
cut2 = createBL( 'cut2' , BasicLayer.Material.cut )
|
||||
metal3 = createBL( 'metal3' , BasicLayer.Material.metal )
|
||||
cut3 = createBL( 'cut3' , BasicLayer.Material.cut )
|
||||
metal4 = createBL( 'metal4' , BasicLayer.Material.metal )
|
||||
cut4 = createBL( 'cut4' , BasicLayer.Material.cut )
|
||||
metal5 = createBL( 'metal5' , BasicLayer.Material.metal )
|
||||
cut5 = createBL( 'cut5' , BasicLayer.Material.cut )
|
||||
metal6 = createBL( 'metal6' , BasicLayer.Material.metal )
|
||||
cut6 = createBL( 'cut6' , BasicLayer.Material.cut )
|
||||
metal7 = createBL( 'metal7' , BasicLayer.Material.metal )
|
||||
cut7 = createBL( 'cut7' , BasicLayer.Material.cut )
|
||||
metal8 = createBL( 'metal8' , BasicLayer.Material.metal )
|
||||
cut8 = createBL( 'cut8' , BasicLayer.Material.cut )
|
||||
metal9 = createBL( 'metal9' , BasicLayer.Material.metal )
|
||||
cut9 = createBL( 'cut9' , BasicLayer.Material.cut )
|
||||
metal10 = createBL( 'metal10' , BasicLayer.Material.metal )
|
||||
|
||||
blockage1 = createBL( 'blockage1' , BasicLayer.Material.blockage )
|
||||
blockage2 = createBL( 'blockage2' , BasicLayer.Material.blockage )
|
||||
blockage3 = createBL( 'blockage3' , BasicLayer.Material.blockage )
|
||||
blockage4 = createBL( 'blockage4' , BasicLayer.Material.blockage )
|
||||
blockage5 = createBL( 'blockage5' , BasicLayer.Material.blockage )
|
||||
blockage6 = createBL( 'blockage6' , BasicLayer.Material.blockage )
|
||||
blockage7 = createBL( 'blockage7' , BasicLayer.Material.blockage )
|
||||
blockage8 = createBL( 'blockage8' , BasicLayer.Material.blockage )
|
||||
blockage9 = createBL( 'blockage9' , BasicLayer.Material.blockage )
|
||||
blockage10 = createBL( 'blockage10', BasicLayer.Material.blockage )
|
||||
|
||||
metal1 .setBlockageLayer( blockage1 )
|
||||
metal2 .setBlockageLayer( blockage2 )
|
||||
metal3 .setBlockageLayer( blockage3 )
|
||||
metal4 .setBlockageLayer( blockage4 )
|
||||
metal5 .setBlockageLayer( blockage5 )
|
||||
metal6 .setBlockageLayer( blockage6 )
|
||||
metal7 .setBlockageLayer( blockage7 )
|
||||
metal8 .setBlockageLayer( blockage8 )
|
||||
metal9 .setBlockageLayer( blockage9 )
|
||||
metal10.setBlockageLayer( blockage10 )
|
||||
|
||||
textCell = createBL( 'text.cell' , BasicLayer.Material.other ) # Misc. non-physical layers.
|
||||
textInst = createBL( 'text.instance', BasicLayer.Material.other ) # Used by the software for visualization
|
||||
SPL1 = createBL( 'SPL1' , BasicLayer.Material.other ) # purposes only.
|
||||
AutoLayer = createBL( 'AutoLayer' , BasicLayer.Material.other )
|
||||
gmetalh = createBL( 'gmetalh' , BasicLayer.Material.metal ) # Special BasicLayers for Knik & Kite Routers.
|
||||
gcut = createBL( 'gcut' , BasicLayer.Material.cut ) # *Must be after all others*
|
||||
gmetalv = createBL( 'gmetalv' , BasicLayer.Material.metal )
|
||||
|
||||
# VIAs for real technologies.
|
||||
via12 = ViaLayer.create( tech, 'via12' , metal1, cut1, metal2 )
|
||||
via23 = ViaLayer.create( tech, 'via23' , metal2, cut2, metal3 )
|
||||
via34 = ViaLayer.create( tech, 'via34' , metal3, cut3, metal4 )
|
||||
via45 = ViaLayer.create( tech, 'via45' , metal4, cut4, metal5 )
|
||||
via56 = ViaLayer.create( tech, 'via56' , metal5, cut5, metal6 )
|
||||
via67 = ViaLayer.create( tech, 'via67' , metal6, cut6, metal7 )
|
||||
via78 = ViaLayer.create( tech, 'via78' , metal7, cut7, metal8 )
|
||||
via89 = ViaLayer.create( tech, 'via89' , metal8, cut8, metal9 )
|
||||
via910 = ViaLayer.create( tech, 'via910', metal9, cut9, metal10 )
|
||||
|
||||
# Composite/Symbolic layers.
|
||||
NWELL = RegularLayer .create( tech, 'NWELL' , nWell )
|
||||
PWELL = RegularLayer .create( tech, 'PWELL' , pWell )
|
||||
NTIE = DiffusionLayer .create( tech, 'NTIE' , nImplant , active, nWell)
|
||||
PTIE = DiffusionLayer .create( tech, 'PTIE' , pImplant , active, pWell)
|
||||
NDIF = DiffusionLayer .create( tech, 'NDIF' , nImplant , active, None )
|
||||
PDIF = DiffusionLayer .create( tech, 'PDIF' , pImplant , active, None )
|
||||
GATE = DiffusionLayer .create( tech, 'GATE' , poly , active, None )
|
||||
NTRANS = TransistorLayer.create( tech, 'NTRANS' , nImplant , active, poly, None )
|
||||
PTRANS = TransistorLayer.create( tech, 'PTRANS' , pImplant , active, poly, None )
|
||||
POLY = RegularLayer .create( tech, 'POLY' , poly )
|
||||
POLY2 = RegularLayer .create( tech, 'POLY2' , poly2 )
|
||||
METAL1 = RegularLayer .create( tech, 'METAL1' , metal1 )
|
||||
METAL2 = RegularLayer .create( tech, 'METAL2' , metal2 )
|
||||
metcapdum = RegularLayer .create( tech, 'metcapdum' , metcap )
|
||||
metbot = RegularLayer .create( tech, 'metbot' , metal2 )
|
||||
METAL3 = RegularLayer .create( tech, 'METAL3' , metal3 )
|
||||
METAL4 = RegularLayer .create( tech, 'METAL4' , metal4 )
|
||||
METAL5 = RegularLayer .create( tech, 'METAL5' , metal5 )
|
||||
METAL6 = RegularLayer .create( tech, 'METAL6' , metal6 )
|
||||
METAL7 = RegularLayer .create( tech, 'METAL7' , metal7 )
|
||||
METAL8 = RegularLayer .create( tech, 'METAL8' , metal8 )
|
||||
METAL9 = RegularLayer .create( tech, 'METAL9' , metal9 )
|
||||
METAL10 = RegularLayer .create( tech, 'METAL10' , metal10 )
|
||||
CONT_BODY_N = ContactLayer .create( tech, 'CONT_BODY_N', nImplant , cut0, active, metal1, None )
|
||||
CONT_BODY_P = ContactLayer .create( tech, 'CONT_BODY_P', pImplant , cut0, active, metal1, None )
|
||||
CONT_DIF_N = ContactLayer .create( tech, 'CONT_DIF_N' , nImplant , cut0, active, metal1, None )
|
||||
CONT_DIF_P = ContactLayer .create( tech, 'CONT_DIF_P' , pImplant , cut0, active, metal1, None )
|
||||
CONT_POLY = ViaLayer .create( tech, 'CONT_POLY' , poly , cut0, metal1 )
|
||||
|
||||
# VIAs for symbolic technologies.
|
||||
VIA12 = ViaLayer .create( tech, 'VIA12' , metal1, cut1, metal2 )
|
||||
VIA23 = ViaLayer .create( tech, 'VIA23' , metal2, cut2, metal3 )
|
||||
VIA23cap = ViaLayer .create( tech, 'VIA23cap' , metcap, cut2, metal3 )
|
||||
VIA34 = ViaLayer .create( tech, 'VIA34' , metal3, cut3, metal4 )
|
||||
VIA45 = ViaLayer .create( tech, 'VIA45' , metal4, cut4, metal5 )
|
||||
VIA56 = ViaLayer .create( tech, 'VIA56' , metal5, cut5, metal6 )
|
||||
VIA67 = ViaLayer .create( tech, 'VIA67' , metal6, cut6, metal7 )
|
||||
VIA78 = ViaLayer .create( tech, 'VIA78' , metal7, cut7, metal8 )
|
||||
VIA89 = ViaLayer .create( tech, 'VIA89' , metal8, cut8, metal9 )
|
||||
VIA910 = ViaLayer .create( tech, 'VIA910' , metal9, cut9, metal10 )
|
||||
BLOCKAGE1 = RegularLayer.create( tech, 'BLOCKAGE1' , blockage1 )
|
||||
BLOCKAGE2 = RegularLayer.create( tech, 'BLOCKAGE2' , blockage2 )
|
||||
BLOCKAGE3 = RegularLayer.create( tech, 'BLOCKAGE3' , blockage3 )
|
||||
BLOCKAGE4 = RegularLayer.create( tech, 'BLOCKAGE4' , blockage4 )
|
||||
BLOCKAGE5 = RegularLayer.create( tech, 'BLOCKAGE5' , blockage5 )
|
||||
BLOCKAGE6 = RegularLayer.create( tech, 'BLOCKAGE6' , blockage6 )
|
||||
BLOCKAGE7 = RegularLayer.create( tech, 'BLOCKAGE7' , blockage7 )
|
||||
BLOCKAGE8 = RegularLayer.create( tech, 'BLOCKAGE8' , blockage8 )
|
||||
BLOCKAGE9 = RegularLayer.create( tech, 'BLOCKAGE9' , blockage9 )
|
||||
BLOCKAGE10 = RegularLayer.create( tech, 'BLOCKAGE10', blockage10 )
|
||||
gcontact = ViaLayer .create( tech, 'gcontact' , gmetalh , gcut, gmetalv )
|
||||
|
||||
tech.setSymbolicLayer( CONT_BODY_N.getName() )
|
||||
tech.setSymbolicLayer( CONT_BODY_P.getName() )
|
||||
tech.setSymbolicLayer( CONT_DIF_N .getName() )
|
||||
tech.setSymbolicLayer( CONT_DIF_P .getName() )
|
||||
tech.setSymbolicLayer( CONT_POLY .getName() )
|
||||
tech.setSymbolicLayer( POLY .getName() )
|
||||
tech.setSymbolicLayer( POLY2 .getName() )
|
||||
tech.setSymbolicLayer( METAL1 .getName() )
|
||||
tech.setSymbolicLayer( METAL2 .getName() )
|
||||
tech.setSymbolicLayer( METAL3 .getName() )
|
||||
tech.setSymbolicLayer( METAL4 .getName() )
|
||||
tech.setSymbolicLayer( METAL5 .getName() )
|
||||
tech.setSymbolicLayer( METAL6 .getName() )
|
||||
tech.setSymbolicLayer( METAL7 .getName() )
|
||||
tech.setSymbolicLayer( METAL8 .getName() )
|
||||
tech.setSymbolicLayer( METAL9 .getName() )
|
||||
tech.setSymbolicLayer( METAL10 .getName() )
|
||||
tech.setSymbolicLayer( BLOCKAGE1 .getName() )
|
||||
tech.setSymbolicLayer( BLOCKAGE2 .getName() )
|
||||
tech.setSymbolicLayer( BLOCKAGE3 .getName() )
|
||||
tech.setSymbolicLayer( BLOCKAGE4 .getName() )
|
||||
tech.setSymbolicLayer( BLOCKAGE5 .getName() )
|
||||
tech.setSymbolicLayer( BLOCKAGE6 .getName() )
|
||||
tech.setSymbolicLayer( BLOCKAGE7 .getName() )
|
||||
tech.setSymbolicLayer( BLOCKAGE8 .getName() )
|
||||
tech.setSymbolicLayer( BLOCKAGE9 .getName() )
|
||||
tech.setSymbolicLayer( BLOCKAGE10 .getName() )
|
||||
tech.setSymbolicLayer( VIA12 .getName() )
|
||||
tech.setSymbolicLayer( VIA23 .getName() )
|
||||
tech.setSymbolicLayer( VIA34 .getName() )
|
||||
tech.setSymbolicLayer( VIA45 .getName() )
|
||||
tech.setSymbolicLayer( VIA56 .getName() )
|
||||
tech.setSymbolicLayer( VIA67 .getName() )
|
||||
tech.setSymbolicLayer( VIA78 .getName() )
|
||||
tech.setSymbolicLayer( VIA89 .getName() )
|
||||
tech.setSymbolicLayer( VIA910 .getName() )
|
||||
tech.setSymbolicLayer( gcut .getName() )
|
||||
tech.setSymbolicLayer( gmetalh .getName() )
|
||||
tech.setSymbolicLayer( gmetalv .getName() )
|
||||
tech.setSymbolicLayer( gcontact .getName() )
|
||||
|
||||
NWELL.setExtentionCap ( nWell, l(2.0) )
|
||||
NWELL.setExtentionWidth( nWell, l(0.0) )
|
||||
PWELL.setExtentionCap ( pWell, l(2.0) )
|
||||
PWELL.setExtentionWidth( nWell, l(0.0) )
|
||||
|
||||
NTIE.setMinimalSize ( l(3.0) )
|
||||
NTIE.setExtentionCap ( nWell , l(2.0) )
|
||||
NTIE.setExtentionWidth( nWell , l(2.5) )
|
||||
NTIE.setExtentionCap ( nImplant, l(1.5) )
|
||||
NTIE.setExtentionWidth( nImplant, l(0.0) )
|
||||
NTIE.setExtentionCap ( active , l(0.0) )
|
||||
NTIE.setExtentionWidth( active , l(0.0) )
|
||||
|
||||
PTIE.setMinimalSize ( l(3.0) )
|
||||
PTIE.setExtentionCap ( pWell , l(2.0) )
|
||||
PTIE.setExtentionWidth( pWell , l(2.5) )
|
||||
PTIE.setExtentionCap ( pImplant, l(1.5) )
|
||||
PTIE.setExtentionWidth( pImplant, l(0.0) )
|
||||
PTIE.setExtentionCap ( active , l(0.0) )
|
||||
PTIE.setExtentionWidth( active , l(0.0) )
|
||||
|
||||
NDIF.setMinimalSize ( l(3.0) )
|
||||
NDIF.setExtentionCap ( nImplant, l(0.5) )
|
||||
NDIF.setExtentionWidth( nImplant, l(0.0) )
|
||||
NDIF.setExtentionCap ( active , l(0.5) )
|
||||
NDIF.setExtentionWidth( active , l(0.0) )
|
||||
|
||||
PDIF.setMinimalSize ( l(3.0) )
|
||||
PDIF.setExtentionCap ( pImplant, l(0.5) )
|
||||
PDIF.setExtentionWidth( pImplant, l(0.0) )
|
||||
PDIF.setExtentionCap ( active , l(0.5) )
|
||||
PDIF.setExtentionWidth( active , l(0.0) )
|
||||
|
||||
GATE.setMinimalSize ( l(1.0) )
|
||||
GATE.setExtentionCap ( poly , l(1.5) )
|
||||
|
||||
NTRANS.setMinimalSize ( l( 1.0) )
|
||||
NTRANS.setExtentionCap ( nImplant, l(-1.5) )
|
||||
NTRANS.setExtentionWidth( nImplant, l( 3.0) )
|
||||
NTRANS.setExtentionCap ( active , l(-1.5) )
|
||||
NTRANS.setExtentionWidth( active , l( 2.0) )
|
||||
|
||||
PTRANS.setMinimalSize ( l( 1.0) )
|
||||
PTRANS.setExtentionCap ( nWell , l(-1.5) )
|
||||
PTRANS.setExtentionWidth( nWell , l( 2.5) )
|
||||
PTRANS.setExtentionCap ( pImplant, l(-1.5) )
|
||||
PTRANS.setExtentionWidth( pImplant, l( 2.5) )
|
||||
PTRANS.setExtentionCap ( active , l(-1.5) )
|
||||
PTRANS.setExtentionWidth( active , l( 2.5) )
|
||||
|
||||
POLY .setMinimalSize ( l(1.0) )
|
||||
POLY .setExtentionCap ( poly , l(0.5) )
|
||||
POLY2.setMinimalSize ( l(1.0) )
|
||||
POLY2.setExtentionCap ( poly , l(0.5) )
|
||||
|
||||
METAL1 .setMinimalSize ( l(1.0) )
|
||||
METAL1 .setExtentionCap ( metal1 , l(1.0) )
|
||||
METAL2 .setMinimalSize ( l(1.0) )
|
||||
METAL2 .setExtentionCap ( metal2 , l(1.0) )
|
||||
METAL3 .setMinimalSize ( l(1.0) )
|
||||
METAL3 .setExtentionCap ( metal3 , l(1.0) )
|
||||
METAL4 .setMinimalSize ( l(1.0) )
|
||||
METAL4 .setExtentionCap ( metal4 , l(1.0) )
|
||||
METAL4 .setMinimalSpacing( l(3.0) )
|
||||
METAL5 .setMinimalSize ( l(2.0) )
|
||||
METAL5 .setExtentionCap ( metal5 , l(1.0) )
|
||||
METAL6 .setMinimalSize ( l(2.0) )
|
||||
METAL6 .setExtentionCap ( metal6 , l(1.0) )
|
||||
METAL7 .setMinimalSize ( l(2.0) )
|
||||
METAL7 .setExtentionCap ( metal7 , l(1.0) )
|
||||
METAL8 .setMinimalSize ( l(2.0) )
|
||||
METAL8 .setExtentionCap ( metal8 , l(1.0) )
|
||||
METAL9 .setMinimalSize ( l(2.0) )
|
||||
METAL9 .setExtentionCap ( metal9 , l(1.0) )
|
||||
METAL10.setMinimalSize ( l(2.0) )
|
||||
METAL10.setExtentionCap ( metal10 , l(1.0) )
|
||||
|
||||
# Contacts (i.e. Active <--> Metal) (symbolic).
|
||||
CONT_BODY_N.setMinimalSize( l( 1.0) )
|
||||
#CONT_BODY_N.setEnclosure ( nWell , l( 1.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_BODY_N.setEnclosure ( nImplant, l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_BODY_N.setEnclosure ( cut0 , l( 0.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_BODY_N.setEnclosure ( active , l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_BODY_N.setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
|
||||
CONT_BODY_P.setMinimalSize( l( 1.0) )
|
||||
#CONT_BODY_P.setEnclosure ( pWell , l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_BODY_P.setEnclosure ( pImplant, l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_BODY_P.setEnclosure ( cut0 , l( 0.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_BODY_P.setEnclosure ( active , l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_BODY_P.setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
|
||||
CONT_DIF_N.setMinimalSize( l( 1.0) )
|
||||
CONT_DIF_N.setEnclosure ( nImplant, l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_DIF_N.setEnclosure ( cut0 , l( 0.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_DIF_N.setEnclosure ( active , l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_DIF_N.setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
|
||||
CONT_DIF_P.setMinimalSize( l( 1.0) )
|
||||
CONT_DIF_P.setEnclosure ( pImplant, l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_DIF_P.setEnclosure ( cut0 , l( 0.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_DIF_P.setEnclosure ( active , l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_DIF_P.setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
|
||||
CONT_POLY.setMinimalSize( l( 1.0) )
|
||||
CONT_POLY.setEnclosure ( poly , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
CONT_POLY.setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
|
||||
# VIAs (i.e. Metal <--> Metal) (symbolic).
|
||||
VIA12 .setMinimalSize ( l( 1.0) )
|
||||
VIA12 .setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA12 .setEnclosure ( metal2 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA12 .setMinimalSpacing( l( 4.0) )
|
||||
VIA23 .setMinimalSize ( l( 1.0) )
|
||||
VIA23 .setEnclosure ( metal2 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA23 .setEnclosure ( metal3 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA23 .setMinimalSpacing( l( 4.0) )
|
||||
VIA34 .setMinimalSize ( l( 1.0) )
|
||||
VIA34 .setEnclosure ( metal3 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA34 .setEnclosure ( metal4 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA34 .setMinimalSpacing( l( 4.0) )
|
||||
VIA45 .setMinimalSize ( l( 1.0) )
|
||||
VIA45 .setEnclosure ( metal4 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA45 .setEnclosure ( metal5 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA45 .setMinimalSpacing( l( 4.0) )
|
||||
VIA56 .setMinimalSize ( l( 1.0) )
|
||||
VIA56 .setEnclosure ( metal5 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA56 .setEnclosure ( metal6 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA56 .setMinimalSpacing( l( 4.0) )
|
||||
VIA67 .setMinimalSize ( l( 1.0) )
|
||||
VIA67 .setEnclosure ( metal6 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA67 .setEnclosure ( metal7 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA67 .setMinimalSpacing( l( 4.0) )
|
||||
VIA78 .setMinimalSpacing( l( 4.0) )
|
||||
VIA78 .setMinimalSize ( l( 1.0) )
|
||||
VIA78 .setEnclosure ( metal7 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA78 .setEnclosure ( metal8 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA78 .setMinimalSpacing( l( 4.0) )
|
||||
VIA89 .setMinimalSize ( l( 1.0) )
|
||||
VIA89 .setEnclosure ( metal8 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA89 .setEnclosure ( metal9 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA89 .setMinimalSpacing( l( 4.0) )
|
||||
VIA910.setMinimalSize ( l( 1.0) )
|
||||
VIA910.setEnclosure ( metal9 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA910.setEnclosure ( metal10 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
|
||||
VIA910.setMinimalSpacing( l( 4.0) )
|
||||
|
||||
# Blockages (symbolic).
|
||||
BLOCKAGE1 .setMinimalSize ( l( 1.0) )
|
||||
BLOCKAGE1 .setExtentionCap( blockage1 , l( 0.5) )
|
||||
BLOCKAGE2 .setMinimalSize ( l( 2.0) )
|
||||
BLOCKAGE2 .setExtentionCap( blockage2 , l( 0.5) )
|
||||
BLOCKAGE3 .setMinimalSize ( l( 2.0) )
|
||||
BLOCKAGE3 .setExtentionCap( blockage3 , l( 0.5) )
|
||||
BLOCKAGE4 .setMinimalSize ( l( 2.0) )
|
||||
BLOCKAGE4 .setExtentionCap( blockage4 , l( 0.5) )
|
||||
BLOCKAGE5 .setMinimalSize ( l( 2.0) )
|
||||
BLOCKAGE5 .setExtentionCap( blockage5 , l( 1.0) )
|
||||
BLOCKAGE6 .setMinimalSize ( l( 2.0) )
|
||||
BLOCKAGE6 .setExtentionCap( blockage6 , l( 1.0) )
|
||||
BLOCKAGE7 .setMinimalSize ( l( 2.0) )
|
||||
BLOCKAGE7 .setExtentionCap( blockage7 , l( 1.0) )
|
||||
BLOCKAGE8 .setMinimalSize ( l( 2.0) )
|
||||
BLOCKAGE8 .setExtentionCap( blockage8 , l( 1.0) )
|
||||
BLOCKAGE9 .setMinimalSize ( l( 2.0) )
|
||||
BLOCKAGE9 .setExtentionCap( blockage9 , l( 1.0) )
|
||||
BLOCKAGE10.setMinimalSize ( l( 2.0) )
|
||||
BLOCKAGE10.setExtentionCap( blockage10, l( 1.0) )
|
||||
|
||||
|
||||
gdsLayersTable = \
|
||||
[ ("nWell" , "LNWELL" , 1, 0)
|
||||
, ("nImplant", "LNIF" , 3, 0)
|
||||
, ("pImplant", "LPDIF" , 4, 0)
|
||||
, ("active" , "LACTIVE" , 2, 0)
|
||||
, ("poly" , "LPOLY" , 7, 0)
|
||||
, ("cut0" , "LCONT" , 10, 0)
|
||||
, ("metal1" , "LALU1" , 11, 0)
|
||||
, ("cut1" , "LVIA" , 14, 0)
|
||||
, ("metal2" , "LALU2" , 16, 0)
|
||||
, ("cut2" , "LVIA2" , 18, 0)
|
||||
, ("metal3" , "LALU3" , 19, 0)
|
||||
, ("cut3" , "LVIA3" , 21, 0)
|
||||
, ("metal4" , "LALU4" , 22, 0)
|
||||
, ("cut4" , "LVIA4" , 25, 0)
|
||||
, ("metal5" , "LALU5" , 26, 0)
|
||||
, ("cut5" , "LVIA5" , 28, 0)
|
||||
, ("metal6" , "LALU6" , 29, 0)
|
||||
]
|
||||
|
||||
|
||||
loadGdsLayers( gdsLayersTable )
|
|
@ -191,8 +191,9 @@ namespace CRL {
|
|||
bool ToolEngine::_inDestroyAll = false;
|
||||
|
||||
|
||||
ToolEngine::ToolEngine ( Cell* cell )
|
||||
ToolEngine::ToolEngine ( Cell* cell, bool verbose )
|
||||
: Super()
|
||||
, _verbose (verbose)
|
||||
, _cell (cell)
|
||||
, _placementModificationFlag(0)
|
||||
, _routingModificationFlag (0)
|
||||
|
@ -219,11 +220,13 @@ namespace CRL {
|
|||
|
||||
put( enginesRelation );
|
||||
|
||||
cmess1 << " o Creating ToolEngine<" << getName() << "> for Cell <"
|
||||
<< _cell->getName() << ">" << endl;
|
||||
|
||||
cmess1 << Dots::asString( " - Initial memory"
|
||||
, Timer::getStringMemory(Timer::getMemorySize()) ) << endl;
|
||||
if (_verbose) {
|
||||
cmess1 << " o Creating ToolEngine<" << getName() << "> for Cell <"
|
||||
<< _cell->getName() << ">" << endl;
|
||||
|
||||
cmess1 << Dots::asString( " - Initial memory"
|
||||
, Timer::getStringMemory(Timer::getMemorySize()) ) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -81,13 +81,14 @@ namespace CRL {
|
|||
protected:
|
||||
Cell* _cell;
|
||||
private:
|
||||
bool _verbose;
|
||||
unsigned int _placementModificationFlag;
|
||||
unsigned int _routingModificationFlag;
|
||||
bool _inRelationDestroy;
|
||||
Timer _timer;
|
||||
uint32_t _passNumber;
|
||||
protected:
|
||||
ToolEngine ( Cell* cell );
|
||||
ToolEngine ( Cell* cell, bool verbose=true );
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
protected:
|
||||
|
|
|
@ -110,8 +110,8 @@ namespace {
|
|||
inline int getNthRouting () const;
|
||||
inline void incNthRouting ();
|
||||
inline RoutingGauge* getRoutingGauge () const;
|
||||
inline void addPinSegment ( string name, Segment* );
|
||||
inline void clearPinSegments ();
|
||||
inline void addPinComponent ( string name, Component* );
|
||||
inline void clearPinComponents ();
|
||||
private:
|
||||
static int _unitsCbk ( lefrCallbackType_e, lefiUnits* , lefiUserData );
|
||||
static int _layerCbk ( lefrCallbackType_e, lefiLayer* , lefiUserData );
|
||||
|
@ -131,7 +131,7 @@ namespace {
|
|||
Net* _net;
|
||||
string _busBits;
|
||||
double _unitsMicrons;
|
||||
map< string, vector<Segment*> > _pinSegments;
|
||||
map< string, vector<Component*> > _pinComponents;
|
||||
static map<string,Layer*> _layerLut;
|
||||
vector<string> _unmatchedLayers;
|
||||
vector<string> _errors;
|
||||
|
@ -173,8 +173,8 @@ namespace {
|
|||
inline const vector<string>& LefParser::getErrors () const { return _errors; }
|
||||
inline void LefParser::pushError ( const string& error ) { _errors.push_back(error); }
|
||||
inline void LefParser::clearErrors () { return _errors.clear(); }
|
||||
inline void LefParser::addPinSegment ( string name, Segment* s ) { _pinSegments[name].push_back(s); }
|
||||
inline void LefParser::clearPinSegments () { _pinSegments.clear(); }
|
||||
inline void LefParser::addPinComponent ( string name, Component* comp ) { _pinComponents[name].push_back(comp); }
|
||||
inline void LefParser::clearPinComponents () { _pinComponents.clear(); }
|
||||
|
||||
|
||||
Library* LefParser::_mergeLibrary = nullptr;
|
||||
|
@ -520,6 +520,8 @@ namespace {
|
|||
points.push_back( Point( parser->fromUnitsMicrons(polygon->x[ipoint])
|
||||
, parser->fromUnitsMicrons(polygon->y[ipoint]) ));
|
||||
}
|
||||
points.push_back( Point( parser->fromUnitsMicrons(polygon->x[0])
|
||||
, parser->fromUnitsMicrons(polygon->y[0]) ));
|
||||
Rectilinear::create( blockageNet, blockageLayer, points );
|
||||
continue;
|
||||
}
|
||||
|
@ -577,7 +579,7 @@ namespace {
|
|||
|
||||
if (not isPad) parser->_pinStdPostProcess();
|
||||
else parser->_pinPadPostProcess();
|
||||
parser->clearPinSegments();
|
||||
parser->clearPinComponents();
|
||||
|
||||
cerr << " - " << cellName
|
||||
<< " " << DbU::getValueString(width) << " " << DbU::getValueString(height)
|
||||
|
@ -667,7 +669,7 @@ namespace {
|
|||
, parser->fromUnitsMicrons( r->yh )
|
||||
);
|
||||
}
|
||||
if (segment) parser->addPinSegment( pin->name(), segment );
|
||||
if (segment) parser->addPinComponent( pin->name(), segment );
|
||||
//cerr << " | " << segment << endl;
|
||||
continue;
|
||||
}
|
||||
|
@ -678,7 +680,10 @@ namespace {
|
|||
points.push_back( Point( parser->fromUnitsMicrons(polygon->x[ipoint])
|
||||
, parser->fromUnitsMicrons(polygon->y[ipoint]) ));
|
||||
}
|
||||
Rectilinear::create( net, layer, points );
|
||||
points.push_back( Point( parser->fromUnitsMicrons(polygon->x[0])
|
||||
, parser->fromUnitsMicrons(polygon->y[0]) ));
|
||||
Rectilinear* rectilinear = Rectilinear::create( net, layer, points );
|
||||
if (rectilinear) parser->addPinComponent( pin->name(), rectilinear );
|
||||
continue;
|
||||
}
|
||||
if (geoms->itemType(igeom) == lefiGeomClassE) {
|
||||
|
@ -722,20 +727,27 @@ namespace {
|
|||
const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 );
|
||||
Box ab = _cell->getAbutmentBox();
|
||||
|
||||
//cerr << " @ _pinStdPostProcess" << endl;
|
||||
cerr << " @ _pinStdPostProcess" << endl;
|
||||
|
||||
for ( auto element : _pinSegments ) {
|
||||
string pinName = element.first;
|
||||
vector<Segment*>& segments = element.second;
|
||||
vector<Segment*> ongrids;
|
||||
for ( auto element : _pinComponents ) {
|
||||
string pinName = element.first;
|
||||
vector<Component*>& components = element.second;
|
||||
vector<Segment*> ongrids;
|
||||
|
||||
for ( Segment* segment : segments ) {
|
||||
bool isWide = (segment->getWidth() >= getMinTerminalWidth());
|
||||
for ( Component* component : components ) {
|
||||
Segment* segment = dynamic_cast<Segment*>( component );
|
||||
if (segment) {
|
||||
if (component->getNet()->isSupply()) continue;
|
||||
bool isWide = (segment->getWidth() >= getMinTerminalWidth());
|
||||
|
||||
//cerr << " > " << segment << endl;
|
||||
cerr << " > " << segment << endl;
|
||||
if (not isVH())
|
||||
cerr << "NOT isVH()" << endl;
|
||||
else
|
||||
cerr << "isVH()" << endl;
|
||||
|
||||
if (not segment->getNet()->isSupply()) {
|
||||
if (isVH() and (segment->getLayer()->getMask() == metal1->getMask())) {
|
||||
cerr << "isVH()" << endl;
|
||||
Vertical* v = dynamic_cast<Vertical*>( segment );
|
||||
if (v) {
|
||||
DbU::Unit nearestX = gaugeMetal2->getTrackPosition( ab.getXMin()
|
||||
|
@ -746,7 +758,7 @@ namespace {
|
|||
if (nearestX == v->getX()) {
|
||||
} else {
|
||||
DbU::Unit neighbor = nearestX
|
||||
+ ((nearestX > v->getX()) ? 1 : -1) * gaugeMetal2->getPitch();
|
||||
+ ((nearestX > v->getX()) ? 1 : -1) * gaugeMetal2->getPitch();
|
||||
|
||||
//cerr << " | X:" << DbU::getValueString(v->getX())
|
||||
// << " nearestX:" << DbU::getValueString(nearestX)
|
||||
|
@ -772,16 +784,67 @@ namespace {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isWide) ongrids.push_back( segment );
|
||||
if (isWide) ongrids.push_back( segment );
|
||||
}
|
||||
Rectilinear* rectilinear = dynamic_cast<Rectilinear*>( component );
|
||||
if (not (rectilinear->getLayer()->getMask() == metal1->getMask()))
|
||||
continue;
|
||||
|
||||
if (rectilinear) {
|
||||
cerr << " > " << rectilinear << endl;
|
||||
vector<Box> boxes;
|
||||
rectilinear->getAsRectangles( boxes );
|
||||
|
||||
if (component->getNet()->isSupply()) {
|
||||
ongrids.push_back( Horizontal::create( rectilinear->getNet()
|
||||
, rectilinear->getLayer()
|
||||
, boxes.front().getYCenter()
|
||||
, boxes.front().getHeight()
|
||||
, _cell->getAbutmentBox().getXMin()
|
||||
, _cell->getAbutmentBox().getXMax()
|
||||
)
|
||||
);
|
||||
} else {
|
||||
for ( const Box& box : boxes ) {
|
||||
DbU::Unit nearestX = gaugeMetal2->getTrackPosition( ab.getXMin()
|
||||
, ab.getXMax()
|
||||
, box.getXCenter()
|
||||
, Constant::Nearest );
|
||||
DbU::Unit xmin = std::min( box.getXMin(), nearestX - gaugeMetal2->getViaWidth()/2 );
|
||||
DbU::Unit xmax = std::max( box.getXMax(), nearestX + gaugeMetal2->getViaWidth()/2 );
|
||||
ongrids.push_back( Vertical::create( rectilinear->getNet()
|
||||
, rectilinear->getLayer()
|
||||
, (xmax+xmin)/2
|
||||
, xmax-xmin
|
||||
, box.getYMin()
|
||||
, box.getYMax()
|
||||
)
|
||||
);
|
||||
// DbU::Unit neighbor = nearestY
|
||||
// + ((nearestY > box.getYCenter()) ? 1 : -1) * gaugeMetal2->getPitch();
|
||||
|
||||
// if ( (box.getYMin() > neighbor)
|
||||
// or (box.getYMax() < neighbor) ) {
|
||||
// ongrids.push_back( Vertical::create( rectilinear->getNet()
|
||||
// , rectilinear->getLayer()
|
||||
// , box.getXCenter()
|
||||
// , box.getWidth()
|
||||
// , box.getYMin()
|
||||
// , box.getYMax()
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ongrids.empty()) {
|
||||
cerr << Warning( "LefParser::_pinStdPostProcess(): Pin \"%s\" has no terminal ongrid."
|
||||
, pinName.c_str() ) << endl;
|
||||
for ( Segment* segment : segments ) {
|
||||
NetExternalComponents::setExternal( segment );
|
||||
for ( Component* component : components ) {
|
||||
NetExternalComponents::setExternal( component );
|
||||
}
|
||||
} else {
|
||||
for ( Segment* segment : ongrids ) {
|
||||
|
@ -797,10 +860,10 @@ namespace {
|
|||
Box ab = getCell()->getAbutmentBox();
|
||||
bool isCornerPad = (_cellGauge) and (_cellGauge->getSliceHeight() == _cellGauge->getSliceStep());
|
||||
|
||||
for ( auto element : _pinSegments ) {
|
||||
string pinName = element.first;
|
||||
vector<Segment*>& segments = element.second;
|
||||
vector<Segment*> ongrids;
|
||||
for ( auto element : _pinComponents ) {
|
||||
string pinName = element.first;
|
||||
vector<Component*>& segments = element.second;
|
||||
vector<Segment*> ongrids;
|
||||
|
||||
if (segments.empty()) continue;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# -*- explicit-buffer-name: "CMakeLists.txt<crlcore/src/ccore/cyclop>" -*-
|
||||
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
include_directories ( ${CRLCORE_SOURCE_DIR}/src/ccore
|
||||
${HURRICANE_INCLUDE_DIR}
|
||||
${UTILITIES_INCLUDE_DIR}
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
-lutil
|
||||
)
|
||||
|
||||
find_package (Python3 COMPONENTS Interpreter Development)
|
||||
|
||||
add_definitions( -DCORIOLIS_TOP="${CORIOLIS_TOP}"
|
||||
-DSYS_CONF_DIR="${SYS_CONF_DIR}"
|
||||
-DPYTHON_SITE_PACKAGES="${PYTHON_SITE_PACKAGES}"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# -*- explicit-buffer-name: "CMakeLists.txt<crlcore/src/x2y> -*-
|
||||
|
||||
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
include_directories ( ${CRLCORE_SOURCE_DIR}/src/ccore
|
||||
${HURRICANE_INCLUDE_DIR}
|
||||
${UTILITIES_INCLUDE_DIR}
|
||||
|
|
|
@ -64,7 +64,7 @@ class PnR ( FlowTask ):
|
|||
else:
|
||||
print( 'PnR.doTask() run in interactive CGT mode.' )
|
||||
PnR.textMode = False
|
||||
from .. import Etesian, Anabatic, Katana, Bora, Tutorial, Viewer, Unicorn
|
||||
from .. import Etesian, Anabatic, Katana, Bora, Tramontana, Tutorial, Viewer, Unicorn
|
||||
|
||||
ShellEnv().export()
|
||||
if self.script and not callable(self.script):
|
||||
|
@ -80,8 +80,8 @@ class PnR ( FlowTask ):
|
|||
unicorn = Unicorn.UnicornGui.create()
|
||||
unicorn.setApplicationName ( 'cgt')
|
||||
unicorn.registerTool ( Etesian.GraphicEtesianEngine.grab() )
|
||||
#unicorn.registerTool ( Kite.GraphicKiteEngine.grab() )
|
||||
unicorn.registerTool ( Katana.GraphicKatanaEngine.grab() )
|
||||
unicorn.registerTool ( Tramontana.GraphicTramontanaEngine.grab() )
|
||||
unicorn.registerTool ( Bora.GraphicBoraEngine.grab() )
|
||||
unicorn.registerTool ( Tutorial.GraphicTutorialEngine.grab() )
|
||||
#unicorn.setAnonNetSelectable(False)
|
||||
|
|
|
@ -82,6 +82,46 @@ def setupCMOS ( checkToolkit=None ):
|
|||
break
|
||||
|
||||
|
||||
def setupLCMOS ( checkToolkit=None ):
|
||||
Where( checkToolkit )
|
||||
ShellEnv().export()
|
||||
|
||||
from .. import Cfg
|
||||
from .. import Viewer
|
||||
from .. import CRL
|
||||
from ..helpers import overlay, l, u, n
|
||||
from .yosys import Yosys
|
||||
import coriolis.technos.symbolic.lcmos
|
||||
|
||||
with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg:
|
||||
cfg.misc.catchCore = False
|
||||
cfg.misc.info = False
|
||||
cfg.misc.paranoid = False
|
||||
cfg.misc.bug = False
|
||||
cfg.misc.logMode = True
|
||||
cfg.misc.verboseLevel1 = True
|
||||
cfg.misc.verboseLevel2 = True
|
||||
cfg.misc.minTraceLevel = 1900
|
||||
cfg.misc.maxTraceLevel = 3000
|
||||
cfg.katana.eventsLimit = 1000000
|
||||
cfg.katana.termSatReservedLocal = 6
|
||||
cfg.katana.termSatThreshold = 9
|
||||
Viewer.Graphics.setStyle( 'Alliance.Classic [black]' )
|
||||
af = CRL.AllianceFramework.get()
|
||||
env = af.getEnvironment()
|
||||
env.setCLOCK( '^ck$|m_clock|^clk$' )
|
||||
|
||||
Yosys.setLiberty( Where.checkToolkit / 'cells' / 'lsxlib' / 'lsxlib.lib' )
|
||||
ShellEnv.RDS_TECHNO_NAME = (Where.allianceTop / 'etc' / 'cmos.rds').as_posix()
|
||||
|
||||
path = None
|
||||
for pathVar in [ 'PATH', 'path' ]:
|
||||
if pathVar in os.environ:
|
||||
path = os.environ[ pathVar ]
|
||||
os.environ[ pathVar ] = path + ':' + (Where.allianceTop / 'bin').as_posix()
|
||||
break
|
||||
|
||||
|
||||
def setupCMOS45 ( useNsxlib=False, checkToolkit=None, cellsTop=None ):
|
||||
from .. import Cfg
|
||||
from .. import Viewer
|
||||
|
@ -190,6 +230,7 @@ def setupSky130_c4m ( checkToolkit=None, pdkMasterTop=None ):
|
|||
cfg.misc.logMode = True
|
||||
cfg.misc.verboseLevel1 = False
|
||||
cfg.misc.verboseLevel2 = False
|
||||
cfg.viewer.pixelThreshold = 5
|
||||
cfg.etesian.graphics = 2
|
||||
cfg.anabatic.topRoutingLayer = 'm4'
|
||||
cfg.katana.eventsLimit = 4000000
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
set_cmake_policies()
|
||||
setup_boost(program_options)
|
||||
setup_python()
|
||||
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
#find_package(KATABATIC REQUIRED)
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
${Boost_INCLUDE_DIRS}
|
||||
${Python_INCLUDE_DIRS}
|
||||
)
|
||||
find_package (Python3 COMPONENTS Interpreter Development)
|
||||
set( includes etesian/Configuration.h
|
||||
etesian/Placement.h
|
||||
etesian/FeedCells.h
|
||||
|
|
|
@ -1205,8 +1205,8 @@ namespace Etesian {
|
|||
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
|
||||
string instanceName = occurrence.getCompactString();
|
||||
// Remove the enclosing brackets...
|
||||
instanceName.erase( 0, 1 );
|
||||
instanceName.erase( instanceName.size()-1 );
|
||||
//instanceName.erase( 0, 1 );
|
||||
//instanceName.erase( instanceName.size()-1 );
|
||||
|
||||
auto iid = _instsToIds.find( instance );
|
||||
if (iid == _instsToIds.end() ) {
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
set_cmake_policies()
|
||||
check_distribution()
|
||||
setup_sysconfdir( "${CMAKE_INSTALL_PREFIX}" )
|
||||
setup_python()
|
||||
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
find_package(CORIOLIS REQUIRED)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
${CONFIGURATION_INCLUDE_DIR}
|
||||
${Python_INCLUDE_DIRS}
|
||||
)
|
||||
find_package (Python3 COMPONENTS Interpreter Development)
|
||||
|
||||
set( includes flute.h
|
||||
dl.h
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
set_cmake_policies()
|
||||
setup_boost(program_options)
|
||||
setup_qt()
|
||||
setup_python()
|
||||
|
||||
find_package(Libexecinfo REQUIRED)
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(LEFDEF REQUIRED)
|
||||
find_package(FLUTE REQUIRED)
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
cmake_policy(SET CMP0054 NEW)
|
||||
setup_boost(program_options)
|
||||
setup_qt()
|
||||
setup_python()
|
||||
|
||||
find_package(BZip2 REQUIRED)
|
||||
find_package(BISON REQUIRED)
|
||||
find_package(FLEX REQUIRED)
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development )
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(Libexecinfo REQUIRED)
|
||||
if (USE_LIBBFD)
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace Hurricane {
|
|||
#ifdef HAVE_CXA_DEMANGLE
|
||||
|
||||
string demangle ( const char* symbol )
|
||||
{
|
||||
{
|
||||
int status;
|
||||
size_t length = 4096;
|
||||
char demangled[length];
|
||||
|
@ -49,13 +49,25 @@ string demangle ( const char* symbol )
|
|||
#else
|
||||
|
||||
string demangle ( const char* symbol )
|
||||
{
|
||||
return symbol;
|
||||
}
|
||||
{ return symbol; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
string& split ( string& s )
|
||||
{
|
||||
size_t i = s.find( "<" );
|
||||
while ( i != string::npos ) {
|
||||
if (i+3 > s.size()) break;
|
||||
//if (s[i+2] != '>') {
|
||||
s.insert( i, "\\n" );
|
||||
//}
|
||||
i = s.find( "<", i+3 );
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
} // End of Hurricane namespace.
|
||||
|
||||
|
||||
|
|
|
@ -118,6 +118,9 @@ Contact::Contact(Net* net, const Layer* layer, DbU::Unit x, DbU::Unit y, DbU::Un
|
|||
{
|
||||
if (not _layer)
|
||||
throw Error("Contact::Contact(): Can't create " + _TName("Contact") + ", NULL layer.");
|
||||
|
||||
if ( _width < _layer->getMinimalSize() ) _width = _layer->getMinimalSize();
|
||||
if ( _height < _layer->getMinimalSize() ) _height = _layer->getMinimalSize();
|
||||
}
|
||||
|
||||
Contact::Contact(Net* net, Component* anchor, const Layer* layer, DbU::Unit dx, DbU::Unit dy, DbU::Unit width, DbU::Unit height)
|
||||
|
|
|
@ -111,21 +111,21 @@ bool Interval::intersect(const Interval& interval, bool strict) const
|
|||
if (isEmpty() or interval.isEmpty()) return false;
|
||||
if ( (_vMax < interval._vMin) or (interval._vMax < _vMin) ) return false;
|
||||
|
||||
return not strict or ( (_vMax != interval._vMin) and (interval._vMax != _vMin) );
|
||||
return not strict or ( (_vMax > interval._vMin) or (interval._vMax > _vMin) );
|
||||
}
|
||||
|
||||
bool Interval::inferior(const Interval& interval, bool strict) const
|
||||
// *****************************************************************
|
||||
{
|
||||
if (_vMax < interval._vMin) return true;
|
||||
return not strict and (_vMax == interval._vMin);
|
||||
if (_vMax == interval._vMin) return not strict;
|
||||
return (_vMax < interval._vMin);
|
||||
}
|
||||
|
||||
bool Interval::superior(const Interval& interval, bool strict) const
|
||||
// *****************************************************************
|
||||
{
|
||||
if (_vMin > interval._vMax) return true;
|
||||
return !strict && (_vMin == interval._vMax);
|
||||
return not (strict or (_vMin != interval._vMax));
|
||||
}
|
||||
|
||||
bool Interval::isConstrainedBy(const Interval& interval) const
|
||||
|
|
|
@ -772,15 +772,23 @@ void Net::_preDestroy()
|
|||
cdebug_tabw(18,-1);
|
||||
}
|
||||
|
||||
string Net::_getFlagsAsString() const
|
||||
// **********************************
|
||||
{
|
||||
string ds;
|
||||
ds += ((isDeepNet() ) ? "d" : "-");
|
||||
ds += ((_isExternal ) ? "e" : "-");
|
||||
ds += ((_isGlobal ) ? "g" : "-");
|
||||
ds += ((_isAutomatic) ? "a" : "-");
|
||||
return ds;
|
||||
}
|
||||
|
||||
string Net::_getString() const
|
||||
// ***************************
|
||||
{
|
||||
string bs = Inherit::_getString();
|
||||
string ds = "\"" + getString(_name) + "\" ";
|
||||
ds += ((isDeepNet() ) ? "d" : "-");
|
||||
ds += ((_isExternal ) ? "e" : "-");
|
||||
ds += ((_isGlobal ) ? "g" : "-");
|
||||
ds += ((_isAutomatic) ? "a" : "-");
|
||||
ds += _getFlagsAsString();
|
||||
ds += " ";
|
||||
ds += getString(_type ) + " ";
|
||||
ds += getString(_direction);
|
||||
|
|
|
@ -96,16 +96,27 @@ bool Occurrence::operator!=(const Occurrence& occurrence) const
|
|||
bool Occurrence::operator<(const Occurrence& occurrence) const
|
||||
// ********************************************************
|
||||
{
|
||||
if (not _entity and not occurrence._entity) return false;
|
||||
if (not _entity) return true;
|
||||
if (not occurrence._entity) return false;
|
||||
cdebug_log(0,0) << "Occurrence::operator<()" << endl;
|
||||
cdebug_log(0,0) << "| lhs=" << *this << endl;
|
||||
cdebug_log(0,0) << "| rhs=" << occurrence << endl;
|
||||
if ((not _sharedPath) xor (not occurrence._sharedPath)) return not _sharedPath;
|
||||
if ((not _entity ) xor (not occurrence._entity )) return not _entity;
|
||||
if (_entity and (_entity->getId() != occurrence._entity->getId()))
|
||||
return _entity->getId() < occurrence._entity->getId();
|
||||
if (not _sharedPath) return false;
|
||||
|
||||
if (_entity->getId() < occurrence._entity->getId()) return true;
|
||||
if (_entity->getId() > occurrence._entity->getId()) return false;
|
||||
// if (not _sharedPath) return true;
|
||||
// if (not occurrence._sharedPath) return false;
|
||||
// if (not _sharedPath and not occurrence._sharedPath) return false;
|
||||
// if (not _sharedPath) return true;
|
||||
// if (not occurrence._sharedPath) return false;
|
||||
|
||||
if (not _sharedPath and not occurrence._sharedPath) return false;
|
||||
if (not _sharedPath) return true;
|
||||
if (not occurrence._sharedPath) return false;
|
||||
// if (not _entity and not occurrence._entity) return false;
|
||||
// if (not _entity) return true;
|
||||
// if (not occurrence._entity) return false;
|
||||
|
||||
// if (_entity->getId() < occurrence._entity->getId()) return true;
|
||||
// if (_entity->getId() > occurrence._entity->getId()) return false;
|
||||
|
||||
return _sharedPath->getHash() < occurrence._sharedPath->getHash();
|
||||
|
||||
|
@ -274,11 +285,12 @@ string Occurrence::_getString() const
|
|||
string Occurrence::getCompactString() const
|
||||
// ****************************************
|
||||
{
|
||||
string s = "<";
|
||||
string s;
|
||||
if (_entity) {
|
||||
s += getString(getOwnerCell()->getName());
|
||||
s += ":";
|
||||
if (_sharedPath) s += getString(_sharedPath->getName()) + ":";
|
||||
if (_sharedPath) s += getString(_sharedPath->getName());
|
||||
s += ":";
|
||||
Instance* instance = dynamic_cast<Instance*>(_entity);
|
||||
if (instance) {
|
||||
s += "I."+getString(instance->getName());
|
||||
|
@ -291,7 +303,6 @@ string Occurrence::getCompactString() const
|
|||
}
|
||||
}
|
||||
}
|
||||
s += ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,284 @@
|
|||
#include "hurricane/Warning.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Point;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::Rectilinear;
|
||||
|
||||
|
||||
class SweepInterval : public Interval {
|
||||
public:
|
||||
inline SweepInterval ( DbU::Unit vmin , DbU::Unit vmax, DbU::Unit xmin );
|
||||
inline SweepInterval ( Interval&, DbU::Unit xmin );
|
||||
inline SweepInterval& inflate ( DbU::Unit dvMin, DbU::Unit dvMax );
|
||||
inline SweepInterval& merge ( DbU::Unit v );
|
||||
inline DbU::Unit getXMin () const;
|
||||
inline void setXMin ( DbU::Unit );
|
||||
inline string _getString () const;
|
||||
private:
|
||||
DbU::Unit _xMin;
|
||||
};
|
||||
|
||||
|
||||
inline SweepInterval::SweepInterval ( DbU::Unit vmin , DbU::Unit vmax, DbU::Unit xmin )
|
||||
: Interval(vmin,vmax)
|
||||
, _xMin (xmin)
|
||||
{ }
|
||||
|
||||
inline SweepInterval::SweepInterval ( Interval& base, DbU::Unit xmin )
|
||||
: Interval(base)
|
||||
, _xMin (xmin)
|
||||
{ }
|
||||
|
||||
inline SweepInterval& SweepInterval::inflate ( DbU::Unit dvMin, DbU::Unit dvMax ) { Interval::inflate(dvMin,dvMax); return *this; }
|
||||
inline SweepInterval& SweepInterval::merge ( DbU::Unit v ) { Interval::merge(v); return *this; }
|
||||
inline DbU::Unit SweepInterval::getXMin () const { return _xMin; }
|
||||
inline void SweepInterval::setXMin ( DbU::Unit xmin ) { _xMin=xmin; }
|
||||
|
||||
inline string SweepInterval::_getString () const
|
||||
{
|
||||
string s;
|
||||
s += "@" + DbU::getValueString(_xMin);
|
||||
s += " [" + DbU::getValueString(getVMin());
|
||||
s += " " + DbU::getValueString(getVMax()) + "]";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
||||
GETSTRING_VALUE_SUPPORT(::SweepInterval);
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
class SweepLine {
|
||||
public:
|
||||
SweepLine ( const Rectilinear*, vector<Box>& );
|
||||
~SweepLine ();
|
||||
void addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x );
|
||||
void loadVEdges ();
|
||||
void process ( Interval );
|
||||
void process ( const pair< DbU::Unit, list<Interval> >& );
|
||||
void toBox ( SweepInterval& );
|
||||
void asRectangles ();
|
||||
private:
|
||||
const Rectilinear* _rectilinear;
|
||||
vector<Box>& _boxes;
|
||||
list< pair< DbU::Unit, list<Interval> > > _vedges;
|
||||
list< SweepInterval > _sweepLine;
|
||||
DbU::Unit _prevX;
|
||||
DbU::Unit _currX;
|
||||
};
|
||||
|
||||
|
||||
SweepLine::SweepLine ( const Rectilinear* r, vector<Box>& boxes )
|
||||
: _rectilinear(r)
|
||||
, _boxes (boxes)
|
||||
, _vedges ()
|
||||
, _sweepLine ()
|
||||
, _prevX (0)
|
||||
, _currX (0)
|
||||
{
|
||||
cdebug_log(17,1) << "SweepLine::SweepLine()" << endl;
|
||||
}
|
||||
|
||||
|
||||
SweepLine::~SweepLine ()
|
||||
{
|
||||
cdebug_tabw(17,-1);
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x )
|
||||
{
|
||||
if (ymin > ymax) std::swap( ymin, ymax );
|
||||
|
||||
cdebug_log(17,1) << "SweepLine::addVEdge() @"<< DbU::getValueString(x)
|
||||
<< " [" << DbU::getValueString(ymin)
|
||||
<< " " << DbU::getValueString(ymax) << "]" << endl;
|
||||
|
||||
bool inserted = false;
|
||||
for ( auto ix = _vedges.begin() ; ix != _vedges.end() ; ++ix ) {
|
||||
cdebug_log(17,0) << "| Looking @" << DbU::getValueString(ix->first)
|
||||
<< " size=" << ix->second.size() << endl;
|
||||
|
||||
if (ix->first > x) {
|
||||
_vedges.insert( ix, make_pair( x, list<Interval>() ));
|
||||
cdebug_log(17,0) << "+ add new @" << DbU::getValueString(x) << endl;
|
||||
--ix;
|
||||
}
|
||||
if (ix->first == x) {
|
||||
for ( auto iintv = ix->second.begin() ; iintv != ix->second.end() ; ++iintv ) {
|
||||
if (iintv->getVMin() >= ymax) {
|
||||
ix->second.insert( iintv, Interval(ymin,ymax) );
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (not inserted) {
|
||||
ix->second.push_back( Interval(ymin,ymax) );
|
||||
inserted = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (not inserted) {
|
||||
cdebug_log(17,0) << "+ add new (back) @" << DbU::getValueString(x) << endl;
|
||||
_vedges.push_back( make_pair( x, list<Interval>() ));
|
||||
_vedges.back().second.push_back( Interval(ymin,ymax) );
|
||||
}
|
||||
|
||||
cdebug_tabw(17,-1);
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::loadVEdges ()
|
||||
{
|
||||
const vector<Point>& points = _rectilinear->getPoints();
|
||||
for ( size_t i=0 ; i<points.size()-1 ; ++i ) {
|
||||
const Point& source = points[ i ];
|
||||
const Point& target = points[ (i+1) % points.size() ];
|
||||
DbU::Unit dx = target.getX() - source.getX();
|
||||
//DbU::Unit dy = target.getY() - source.getY();
|
||||
if (dx == 0) {
|
||||
addVEdge( source.getY(), target.getY(), source.getX() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::toBox ( SweepInterval& intv )
|
||||
{
|
||||
if (intv.getXMin() == _currX) return;
|
||||
_boxes.push_back( Box( intv.getXMin(), intv.getVMin()
|
||||
, _currX , intv.getVMax() ));
|
||||
intv.setXMin( _currX );
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::process ( Interval v )
|
||||
{
|
||||
cdebug_log(17,1) << "SweepLine::process(Interval&) "
|
||||
<< " [" << DbU::getValueString(v.getVMin())
|
||||
<< " " << DbU::getValueString(v.getVMax()) << "]" << endl;
|
||||
bool done = false;
|
||||
for ( auto iintv = _sweepLine.begin() ; iintv != _sweepLine.end() ; ++iintv ) {
|
||||
// Extractor p. 9 (a).
|
||||
if (v.getVMax() < iintv->getVMin()) {
|
||||
_sweepLine.insert( iintv, SweepInterval(v,_currX) );
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
// Extractor p. 9 (f).
|
||||
if ( (v.getVMin() == iintv->getVMin())
|
||||
and (v.getVMax() == iintv->getVMax()) ) {
|
||||
toBox( *iintv );
|
||||
_sweepLine.erase( iintv );
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
// Extractor p. 9 (b).
|
||||
if (v.getVMax() == iintv->getVMin()) {
|
||||
toBox( *iintv );
|
||||
iintv->merge( v.getVMin() );
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
// Extractor p. 9 (g).
|
||||
if (v.getVMax() == iintv->getVMax()) {
|
||||
toBox( *iintv );
|
||||
cdebug_log(17,0) << "case (g): carve" << endl;
|
||||
iintv->inflate( 0, v.getVMin() - iintv->getVMax() );
|
||||
cdebug_log(17,0) << "| " << (*iintv) << endl;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
// Extractor p. 9 (h).
|
||||
if (v.getVMin() == iintv->getVMin()) {
|
||||
toBox( *iintv );
|
||||
iintv->inflate(iintv->getVMin() - v.getVMax(), 0 );
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
// Extractor p. 9 (c).
|
||||
if ( (v.getVMin() > iintv->getVMin())
|
||||
and (v.getVMax() < iintv->getVMax()) ) {
|
||||
toBox( *iintv );
|
||||
cdebug_log(17,0) << "case (c): carve" << endl;
|
||||
DbU::Unit wholeVMin = iintv->getVMin();
|
||||
iintv->inflate( iintv->getVMin() - v.getVMax(), 0 );
|
||||
cdebug_log(17,0) << "| " << (*iintv) << endl;
|
||||
_sweepLine.insert( iintv, SweepInterval( wholeVMin, v.getVMin(), _currX ) );
|
||||
cdebug_log(17,0) << "| " << (*(--iintv)) << endl;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
// Extractor p. 9 (d,e).
|
||||
if (v.getVMin() == iintv->getVMax()) {
|
||||
auto iintvNext = iintv;
|
||||
++iintvNext;
|
||||
// Extractor p. 9 (d).
|
||||
if (iintvNext == _sweepLine.end()) {
|
||||
toBox( *iintv );
|
||||
iintv->merge( v.getVMax() );
|
||||
} else {
|
||||
// Extractor p. 9 (d).
|
||||
if (v.getVMax() < iintvNext->getVMin()) {
|
||||
toBox( *iintv );
|
||||
iintv->merge( v.getVMax() );
|
||||
} else {
|
||||
// Extractor p. 9 (e).
|
||||
toBox( *iintv );
|
||||
toBox( *iintvNext );
|
||||
iintv->merge( iintvNext->getVMax() );
|
||||
_sweepLine.erase( iintvNext );
|
||||
}
|
||||
}
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (not done) {
|
||||
_sweepLine.push_back( SweepInterval(v,_currX) );
|
||||
}
|
||||
|
||||
cdebug_tabw(17,-1);
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::process ( const pair< DbU::Unit, list<Interval> >& intervals )
|
||||
{
|
||||
cdebug_log(17,1) << "SweepLine::process() @"<< DbU::getValueString(intervals.first)
|
||||
<< " size=" << intervals.second.size() << endl;
|
||||
_currX = intervals.first;
|
||||
for ( const Interval& v : intervals.second ) process( v );
|
||||
cdebug_tabw(17,-1);
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::asRectangles ()
|
||||
{
|
||||
loadVEdges();
|
||||
for ( auto intervals : _vedges ) {
|
||||
process( intervals );
|
||||
}
|
||||
cdebug_log(17,0) << "SweepLine::asRectangles() size=" << _boxes.size() << endl;
|
||||
for ( const Box& b : _boxes )
|
||||
cdebug_log(17,0) << "| " << b << endl;
|
||||
}
|
||||
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
||||
namespace Hurricane {
|
||||
|
||||
|
||||
|
@ -50,6 +328,7 @@ namespace Hurricane {
|
|||
: Super (net)
|
||||
, _layer (layer)
|
||||
, _points(points)
|
||||
, _flags (IsRectilinear)
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -58,9 +337,21 @@ namespace Hurricane {
|
|||
if (not layer)
|
||||
throw Error( "Rectilinear::create(): Can't create, NULL layer" );
|
||||
|
||||
if (points.size() > 1000)
|
||||
throw Error( "Rectilinear::create(): Rectlinear polygons must not exceed 1000 vertexes." );
|
||||
if (points.size() < 4)
|
||||
throw Error( "Rectilinear::create(): Rectilinear polygons must at least contains 3 vertexes." );
|
||||
|
||||
if (points.size() > 1000)
|
||||
throw Error( "Rectilinear::create(): Rectilinear polygons must not exceed 1000 vertexes." );
|
||||
|
||||
if (points[0] != points[points.size()-1])
|
||||
throw Error( "Rectilinear::create(): First and last point must be the same.\n"
|
||||
"0:%s %d:%s"
|
||||
, getString(points[0]).c_str()
|
||||
, points.size()-1
|
||||
, getString(points[points.size()-1]).c_str()
|
||||
);
|
||||
|
||||
bool isRect = true;
|
||||
DbU::Unit oneGrid = DbU::fromGrid( 1.0 );
|
||||
for ( size_t i=0 ; i<points.size() ; ++i ) {
|
||||
size_t j = (i+1) % points.size();
|
||||
|
@ -68,9 +359,12 @@ namespace Hurricane {
|
|||
DbU::Unit dx = std::abs( points[i].getX() - points[j].getX() );
|
||||
DbU::Unit dy = std::abs( points[i].getY() - points[j].getY() );
|
||||
|
||||
if ( (dx != 0) and (dy != 0) and (dx != dy) )
|
||||
throw Error( "Rectilinear::create(): Can't create, non H/V edge (points %d:%s - %d:%s)."
|
||||
, i, getString(points[i]).c_str(), j, getString(points[j]).c_str() );
|
||||
if ((dx != 0) and (dy != 0)) {
|
||||
isRect = false;
|
||||
if (dx != dy)
|
||||
throw Error( "Rectilinear::create(): Can't create, non H/V edge (points %d:%s - %d:%s)."
|
||||
, i, getString(points[i]).c_str(), j, getString(points[j]).c_str() );
|
||||
}
|
||||
|
||||
if (points[i].getX() % oneGrid)
|
||||
cerr << Warning( "Rectilinear::create(): In Cell \"%s\", Net \"%s\",\n"
|
||||
|
@ -91,7 +385,7 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
Rectilinear* rectilinear = new Rectilinear ( net, layer, points );
|
||||
|
||||
if (not isRect) rectilinear->_flags &= ~IsRectilinear;
|
||||
rectilinear->_postCreate();
|
||||
|
||||
return rectilinear;
|
||||
|
@ -176,6 +470,15 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
|
||||
bool Rectilinear::getAsRectangles ( std::vector<Box>& rectangles ) const
|
||||
{
|
||||
rectangles.clear();
|
||||
if (not isRectilinear()) return false;
|
||||
SweepLine( this, rectangles ).asRectangles();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Rectilinear::_toJson ( JsonWriter* writer ) const
|
||||
{
|
||||
Inherit::_toJson( writer );
|
||||
|
|
|
@ -146,6 +146,9 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
|
||||
string& split ( std::string& );
|
||||
|
||||
|
||||
} // End of Hurricane namespace.
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef HURRICANE_COMPONENT_H
|
||||
#define HURRICANE_COMPONENT_H
|
||||
|
||||
#include <set>
|
||||
#include "hurricane/Points.h"
|
||||
#include "hurricane/Go.h"
|
||||
#include "hurricane/Components.h"
|
||||
|
@ -170,6 +171,9 @@ namespace Hurricane {
|
|||
};
|
||||
|
||||
|
||||
typedef std::set<Component*,DBo::CompareById> ComponentSet;
|
||||
|
||||
|
||||
} // Hurricane namespace.
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved
|
||||
// Copyright (c) BULL S.A. 2000-2023, All Rights Reserved
|
||||
//
|
||||
// This file is part of Hurricane.
|
||||
//
|
||||
|
@ -29,9 +29,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef HURRICANE_INTERVAL_H
|
||||
#define HURRICANE_INTERVAL_H
|
||||
|
||||
#pragma once
|
||||
#include "hurricane/DbU.h"
|
||||
|
||||
namespace Hurricane {
|
||||
|
@ -48,6 +46,11 @@ namespace Hurricane {
|
|||
inline bool operator() ( const Interval& rhs, const Interval& lhs ) const;
|
||||
inline bool operator() ( const Interval* rhs, const Interval* lhs ) const;
|
||||
};
|
||||
class CompareByMinMax {
|
||||
public:
|
||||
inline bool operator() ( const Interval& rhs, const Interval& lhs ) const;
|
||||
inline bool operator() ( const Interval* rhs, const Interval* lhs ) const;
|
||||
};
|
||||
public:
|
||||
Interval ( bool makeEmpty=true );
|
||||
Interval ( const DbU::Unit& );
|
||||
|
@ -124,6 +127,20 @@ namespace Hurricane {
|
|||
{ return lhs->getVMin() < rhs->getVMin(); }
|
||||
|
||||
|
||||
inline bool Interval::CompareByMinMax::operator() ( const Interval& lhs, const Interval& rhs ) const
|
||||
{
|
||||
if (lhs.getVMin() != rhs.getVMin()) return lhs.getVMin() < rhs.getVMin();
|
||||
return lhs.getVMax() < rhs.getVMax();
|
||||
}
|
||||
|
||||
|
||||
inline bool Interval::CompareByMinMax::operator() ( const Interval* lhs, const Interval* rhs ) const
|
||||
{
|
||||
if (lhs->getVMin() != rhs->getVMin()) return lhs->getVMin() < rhs->getVMin();
|
||||
return lhs->getVMax() < rhs->getVMax();
|
||||
}
|
||||
|
||||
|
||||
} // Hurricane namespace.
|
||||
|
||||
|
||||
|
@ -136,7 +153,5 @@ inline void jsonWrite ( JsonWriter* w, const std::string& key, const Hurricane:
|
|||
w->endArray();
|
||||
}
|
||||
|
||||
|
||||
INSPECTOR_PR_SUPPORT(Hurricane::Interval);
|
||||
|
||||
|
||||
#endif // HURRICANE_INTERVAL_H
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// Copyright (c) BULL S.A. 2018-2018, All Rights Reserved
|
||||
// Copyright (c) BULL S.A. 2018-2023, All Rights Reserved
|
||||
//
|
||||
// This file is part of Hurricane.
|
||||
//
|
||||
|
@ -34,9 +34,7 @@
|
|||
// Third edition, MIT press, 2011, p. 348.
|
||||
|
||||
|
||||
#ifndef HURRICANE_INTERVAL_TREE_H
|
||||
#define HURRICANE_INTERVAL_TREE_H
|
||||
|
||||
#pragma once
|
||||
#include "hurricane/Interval.h"
|
||||
#include "hurricane/RbTree.h"
|
||||
|
||||
|
@ -57,6 +55,7 @@ namespace Hurricane {
|
|||
inline Data& getData () const;
|
||||
inline DbU::Unit getChildsVMax () const;
|
||||
inline DbU::Unit updateChildsVMax ( DbU::Unit lvmax, DbU::Unit rvmax );
|
||||
inline bool operator== ( const IntervalData& ) const;
|
||||
string _getString () const;
|
||||
Record* _getRecord () const;
|
||||
private:
|
||||
|
@ -64,7 +63,7 @@ namespace Hurricane {
|
|||
Data data_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline IntervalData<Data>::IntervalData ()
|
||||
: Interval(1,-1)
|
||||
|
@ -93,7 +92,17 @@ namespace Hurricane {
|
|||
|
||||
template< typename Data >
|
||||
inline DbU::Unit IntervalData<Data>::updateChildsVMax ( DbU::Unit lvmax, DbU::Unit rvmax )
|
||||
{ childsVMax_ = std::max( getVMax(), std::max( lvmax, rvmax ) ); return childsVMax_; }
|
||||
{
|
||||
cdebug_log(0,0) << "IntervalData::updateChildsVMax() " << DbU::getValueString(lvmax)
|
||||
<< " " << DbU::getValueString(lvmax)
|
||||
<< " " << this << endl;
|
||||
childsVMax_ = std::max( getVMax(), std::max( lvmax, rvmax ) ); return childsVMax_;
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline bool IntervalData<Data>::operator== ( const IntervalData<Data>& other ) const
|
||||
{ return Interval::operator==(*this) and (data_ == other.data_); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
|
@ -117,14 +126,35 @@ namespace Hurricane {
|
|||
return record;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Hurricane::IntervalDataCompare".
|
||||
|
||||
template< typename Data, typename DataCompare=std::less<Data> >
|
||||
class IntervalDataCompare {
|
||||
public:
|
||||
inline bool operator() ( const IntervalData<Data>& lhs, const IntervalData<Data>& rhs ) const
|
||||
{
|
||||
static Interval::CompareByMinMax compare;
|
||||
static DataCompare dataCompare;
|
||||
if ( (lhs.getVMin() == rhs.getVMin())
|
||||
and (lhs.getVMax() == rhs.getVMax())) {
|
||||
cdebug_log(0,0) << "IntervalDataCompare::operator<() - Data fallback." << endl;
|
||||
cdebug_log(0,0) << "| " << lhs.getData() << endl;
|
||||
return dataCompare( lhs.getData(), rhs.getData() );
|
||||
}
|
||||
return compare( lhs, rhs );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Hurricane::IntervalTree".
|
||||
|
||||
|
||||
template< typename Data >
|
||||
class IntervalTree : public RbTree< IntervalData<Data>, Interval::CompareByMin > {
|
||||
template< typename Data, typename DataCompare=std::less<Data> >
|
||||
class IntervalTree : public RbTree< IntervalData<Data>, IntervalDataCompare<Data,DataCompare> > {
|
||||
public:
|
||||
typedef RbTree< IntervalData<Data>, Interval::CompareByMin > Super;
|
||||
typedef RbTree< IntervalData<Data>, IntervalDataCompare<Data,DataCompare> > Super;
|
||||
public:
|
||||
class overlap_iterator : public Super::iterator {
|
||||
public:
|
||||
|
@ -171,31 +201,39 @@ namespace Hurricane {
|
|||
size_t getThickness () const;
|
||||
overlap_iterator beginOverlaps ( const Interval& ) const;
|
||||
inline OverlapElements getOverlaps ( const Interval& ) const;
|
||||
void checkVMax () const;
|
||||
void checkVMax ( typename Super::Node* node ) const;
|
||||
private:
|
||||
inline void updateChildsVMax ( typename Super::Node* );
|
||||
};
|
||||
|
||||
|
||||
template< typename Data >
|
||||
IntervalTree<Data>::overlap_iterator::overlap_iterator ( const typename Super::Node* node, const Interval& overlap )
|
||||
template< typename Data, typename DataCompare >
|
||||
IntervalTree<Data,DataCompare>::overlap_iterator::overlap_iterator ( const typename Super::Node* node, const Interval& overlap )
|
||||
: Super::iterator(node)
|
||||
, overlap_(overlap)
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
typename IntervalTree<Data>::overlap_iterator& IntervalTree<Data>::overlap_iterator::operator++ ()
|
||||
{
|
||||
while (this->isValid()) {
|
||||
cdebug_log(0,0) << "IntervalTree::overlap_iterator CTOR "
|
||||
<< (node ? ::getString(node->getValue()) : "node=NULL")
|
||||
<< " " << overlap << endl;
|
||||
}
|
||||
|
||||
|
||||
template< typename Data, typename DataCompare >
|
||||
typename IntervalTree<Data,DataCompare>::overlap_iterator&
|
||||
IntervalTree<Data,DataCompare>::overlap_iterator::operator++ ()
|
||||
{
|
||||
cdebug_log(0,0) << "IntervalTree::overlap_iterator::operator++()" << endl;
|
||||
while ( true ) {
|
||||
Super::iterator::operator++();
|
||||
if (not this->isValid()) break;
|
||||
|
||||
cdebug_log(0,0) << "IntervalTree::overlap_iterator::operator++() "
|
||||
<< ::getString(this->getNode()) << std::endl;
|
||||
cdebug_log(0,0) << " ==> " << ::getString(this->getNode()->getValue()) << std::endl;
|
||||
|
||||
if (this->getNode()->getValue().intersect(overlap_,true)) break;
|
||||
cdebug_log(0,0) << "NO intersections" << endl;
|
||||
if (overlap_.inferior(this->getNode()->getValue(),true)) {
|
||||
cdebug_log(0,0) << "Node is inferior, stop here." << endl;
|
||||
if (this->getNode()->getValue().intersect(overlap_,false)) break;
|
||||
cdebug_log(0,0) << " NO intersections" << endl;
|
||||
if (overlap_.inferior(this->getNode()->getValue(),false)) {
|
||||
cdebug_log(0,0) << " Node is inferior, stop here." << endl;
|
||||
this->setNode( NULL );
|
||||
break;
|
||||
}
|
||||
|
@ -208,44 +246,45 @@ namespace Hurricane {
|
|||
// Class : "Hurricane::IntervalTree::OverlapOverlapElements" (implementation)
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline IntervalTree<Data>::OverlapElements::Locator::Locator ( const Locator &locator )
|
||||
template< typename Data, typename DataCompare >
|
||||
inline IntervalTree<Data,DataCompare>::OverlapElements::Locator::Locator ( const Locator &locator )
|
||||
: Hurricane::Locator< IntervalData<Data> >()
|
||||
, iterator_(locator.iterator_)
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
IntervalTree<Data>::OverlapElements::Locator::Locator ( const IntervalTree<Data>& tree, const Interval& span )
|
||||
template< typename Data, typename DataCompare >
|
||||
IntervalTree<Data,DataCompare>::OverlapElements::Locator::Locator ( const IntervalTree<Data,DataCompare>& tree, const Interval& span )
|
||||
: Hurricane::Locator< IntervalData<Data> >()
|
||||
, iterator_(tree.beginOverlaps(span))
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
typename IntervalTree<Data>::OverlapElements::Locator* IntervalTree<Data>::OverlapElements::Locator::getClone () const
|
||||
template< typename Data, typename DataCompare >
|
||||
typename IntervalTree<Data,DataCompare>::OverlapElements::Locator*
|
||||
IntervalTree<Data,DataCompare>::OverlapElements::Locator::getClone () const
|
||||
{ return new Locator(*this); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
IntervalData<Data> IntervalTree<Data>::OverlapElements::Locator::getElement () const
|
||||
template< typename Data, typename DataCompare >
|
||||
IntervalData<Data> IntervalTree<Data,DataCompare>::OverlapElements::Locator::getElement () const
|
||||
{ return (*iterator_); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
bool IntervalTree<Data>::OverlapElements::Locator::isValid () const
|
||||
template< typename Data, typename DataCompare >
|
||||
bool IntervalTree<Data,DataCompare>::OverlapElements::Locator::isValid () const
|
||||
{ return iterator_.isValid(); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
void IntervalTree<Data>::OverlapElements::Locator::progress ()
|
||||
template< typename Data, typename DataCompare >
|
||||
void IntervalTree<Data,DataCompare>::OverlapElements::Locator::progress ()
|
||||
{
|
||||
if (isValid()) ++iterator_;
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
std::string IntervalTree<Data>::OverlapElements::Locator::_getString () const
|
||||
template< typename Data, typename DataCompare >
|
||||
std::string IntervalTree<Data,DataCompare>::OverlapElements::Locator::_getString () const
|
||||
{
|
||||
std::string s = "<" + _TName("OverlapElements::Locator")
|
||||
+ ">";
|
||||
|
@ -253,34 +292,34 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline IntervalTree<Data>::OverlapElements::OverlapElements ( const IntervalTree& tree, const Interval& span )
|
||||
template< typename Data, typename DataCompare >
|
||||
inline IntervalTree<Data,DataCompare>::OverlapElements::OverlapElements ( const IntervalTree& tree, const Interval& span )
|
||||
: Collection< IntervalData<Data> >()
|
||||
, tree_(tree)
|
||||
, span_(span)
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline IntervalTree<Data>::OverlapElements::OverlapElements ( const OverlapElements& elements )
|
||||
template< typename Data, typename DataCompare >
|
||||
inline IntervalTree<Data,DataCompare>::OverlapElements::OverlapElements ( const OverlapElements& elements )
|
||||
: Collection< IntervalData<Data> >()
|
||||
, tree_(elements.tree_)
|
||||
, span_(elements.span_)
|
||||
{ }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
Collection< IntervalData<Data> >* IntervalTree<Data>::OverlapElements::getClone () const
|
||||
template< typename Data, typename DataCompare >
|
||||
Collection< IntervalData<Data> >* IntervalTree<Data,DataCompare>::OverlapElements::getClone () const
|
||||
{ return new OverlapElements(*this); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
typename IntervalTree<Data>::OverlapElements::Locator* IntervalTree<Data>::OverlapElements::getLocator () const
|
||||
template< typename Data, typename DataCompare >
|
||||
typename IntervalTree<Data,DataCompare>::OverlapElements::Locator* IntervalTree<Data,DataCompare>::OverlapElements::getLocator () const
|
||||
{ return new Locator( tree_, span_ ); }
|
||||
|
||||
|
||||
template< typename Data >
|
||||
std::string IntervalTree<Data>::OverlapElements::_getString () const
|
||||
template< typename Data, typename DataCompare >
|
||||
std::string IntervalTree<Data,DataCompare>::OverlapElements::_getString () const
|
||||
{
|
||||
std::string s = "<" + _TName("OverlapElements") + " "
|
||||
+ getString(tree_)
|
||||
|
@ -293,39 +332,45 @@ namespace Hurricane {
|
|||
// Class : "Hurricane::IntervalTree" (implementation).
|
||||
|
||||
|
||||
template< typename Data >
|
||||
inline void IntervalTree<Data>::updateChildsVMax ( typename Super::Node* node )
|
||||
template< typename Data, typename DataCompare >
|
||||
inline void IntervalTree<Data,DataCompare>::updateChildsVMax ( typename Super::Node* node )
|
||||
{
|
||||
cdebug_log(0,1) << "IntervalTree::updateChildsVMax() " << node->getValue() << endl;
|
||||
DbU::Unit lchildVMax = (node->getLeft ()) ? node->getLeft ()->getValue().getChildsVMax() : node->getValue().getVMax();
|
||||
DbU::Unit rchildVMax = (node->getRight()) ? node->getRight()->getValue().getChildsVMax() : node->getValue().getVMax();
|
||||
|
||||
const_cast< IntervalData<Data>& >( node->getValue() ).updateChildsVMax( lchildVMax, rchildVMax );
|
||||
cdebug_tabw(0,-1);
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
void IntervalTree<Data>::postRotateLeft ( typename Super::Node* node )
|
||||
template< typename Data, typename DataCompare >
|
||||
void IntervalTree<Data,DataCompare>::postRotateLeft ( typename Super::Node* node )
|
||||
{
|
||||
cdebug_log(0,1) << "IntervalTree::postRotateLeft() " << node->getValue() << endl;
|
||||
updateChildsVMax( node );
|
||||
if (node->getParent()) updateChildsVMax( node->getParent() );
|
||||
cdebug_tabw(0,-1);
|
||||
}
|
||||
|
||||
|
||||
template< typename Data, typename DataCompare >
|
||||
void IntervalTree<Data,DataCompare>::postRotateRight ( typename Super::Node* node )
|
||||
{
|
||||
cdebug_log(0,0) << "IntervalTree::postRotateRight() " << node->getValue() << endl;
|
||||
updateChildsVMax( node );
|
||||
if (node->getParent()) updateChildsVMax( node->getParent() );
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
void IntervalTree<Data>::postRotateRight ( typename Super::Node* node )
|
||||
template< typename Data, typename DataCompare >
|
||||
void IntervalTree<Data,DataCompare>::postInsert ( typename Super::Node* node )
|
||||
{
|
||||
updateChildsVMax( node );
|
||||
if (node->getParent()) updateChildsVMax( node->getParent() );
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
void IntervalTree<Data>::postInsert ( typename Super::Node* node )
|
||||
{
|
||||
cdebug_log(0,1) << "IntervalTree::postInsert() " << node << std::endl;
|
||||
cdebug_log(0,1) << "IntervalTree::postInsert() "
|
||||
<< ((node) ? ::getString(node->getValue()) : "node=NULL") << std::endl;
|
||||
|
||||
while ( node ) {
|
||||
cdebug_log(0,0) << "| " << node << std::endl;
|
||||
cdebug_log(0,0) << "| " << node->getValue() << std::endl;
|
||||
|
||||
updateChildsVMax( node );
|
||||
node = node->getParent();
|
||||
|
@ -335,26 +380,38 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
void IntervalTree<Data>::postRemove ( typename Super::Node* node )
|
||||
template< typename Data, typename DataCompare >
|
||||
void IntervalTree<Data,DataCompare>::postRemove ( typename Super::Node* node )
|
||||
{
|
||||
cdebug_log(0,1) << "IntervalTree::postRemove() "
|
||||
<< ((node) ? ::getString(node->getValue()) : "node=NULL") << std::endl;
|
||||
|
||||
if (not node) {
|
||||
cdebug_tabw(0,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
typename Super::Node* parent = node->getParent();
|
||||
if (parent) {
|
||||
typename Super::Node* child = NULL;
|
||||
DbU::Unit childsVMax = parent->getValue().getVMax();
|
||||
typename Super::Node* child1 = parent->getLeft ();
|
||||
typename Super::Node* child2 = parent->getRight();
|
||||
if (child1 == node) std::swap( child1, child2 );
|
||||
if (child1) childsVMax = std::max( childsVMax, child1->getValue().getChildsVMax() );
|
||||
if (child2->getLeft ()) childsVMax = std::max( childsVMax, child2->getLeft ()->getValue().getChildsVMax() );
|
||||
if (child2->getRight()) childsVMax = std::max( childsVMax, child2->getRight()->getValue().getChildsVMax() );
|
||||
|
||||
if (parent->hasLeftChild(node)) child = parent->getRight();
|
||||
else child = parent->getLeft ();
|
||||
|
||||
DbU::Unit childVMax = (child) ? child->getValue().getChildsVMax() : parent->getValue().getVMax();
|
||||
const_cast< IntervalData<Data>& >( parent->getValue() ).updateChildsVMax( childVMax, childVMax );
|
||||
const_cast< IntervalData<Data>& >( parent->getValue() ).updateChildsVMax( childsVMax, childsVMax );
|
||||
|
||||
postInsert( parent->getParent() );
|
||||
}
|
||||
|
||||
cdebug_tabw(0,-1);
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
size_t IntervalTree<Data>::getThickness () const
|
||||
template< typename Data, typename DataCompare >
|
||||
size_t IntervalTree<Data,DataCompare>::getThickness () const
|
||||
{
|
||||
cdebug_log(0,0) << "IntervalTree::getThickness() " << std::endl;
|
||||
|
||||
|
@ -382,36 +439,70 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
typename IntervalTree<Data>::overlap_iterator IntervalTree<Data>::beginOverlaps ( const Interval& overlap ) const
|
||||
template< typename Data, typename DataCompare >
|
||||
typename IntervalTree<Data,DataCompare>::overlap_iterator
|
||||
IntervalTree<Data,DataCompare>::beginOverlaps ( const Interval& overlap ) const
|
||||
{
|
||||
cdebug_log(0,0) << "IntervalTree::beginOverlaps() " << overlap << std::endl;
|
||||
|
||||
const typename Super::Node* current = this->getRoot();
|
||||
const typename Super::Node* leftMost = NULL;
|
||||
const typename Super::Node* leftMost = nullptr;
|
||||
while ( current ) {
|
||||
cdebug_log(0,0) << "| " << ::getString(current) << endl;
|
||||
cdebug_log(0,0) << "| " << ::getString(current->getValue()) << endl;
|
||||
|
||||
if (current->getValue().intersect(overlap)) leftMost = current;
|
||||
if (current->getValue().intersect(overlap,false)) {
|
||||
cdebug_log(0,0) << "* Leftmost candidate." << endl;
|
||||
leftMost = current;
|
||||
}
|
||||
if ( current->getLeft()
|
||||
and (overlap.getVMin() < current->getLeft()->getValue().getChildsVMax()) )
|
||||
current = current->getLeft();
|
||||
else
|
||||
current = current->getRight();
|
||||
and (overlap.getVMin() < current->getLeft()->getValue().getChildsVMax()) ) {
|
||||
current = current->getLeft();
|
||||
leftMost = nullptr;
|
||||
} else {
|
||||
if (not leftMost)
|
||||
current = current->getRight();
|
||||
else
|
||||
current = nullptr;
|
||||
}
|
||||
}
|
||||
return overlap_iterator( leftMost, overlap );
|
||||
}
|
||||
|
||||
|
||||
template< typename Data >
|
||||
typename IntervalTree<Data>::OverlapElements IntervalTree<Data>::getOverlaps ( const Interval& overlap ) const
|
||||
template< typename Data, typename DataCompare >
|
||||
typename IntervalTree<Data,DataCompare>::OverlapElements
|
||||
IntervalTree<Data,DataCompare>::getOverlaps ( const Interval& overlap ) const
|
||||
{
|
||||
cdebug_log(0,0) << "IntervalTree::getOverlaps() " << overlap << std::endl;
|
||||
return OverlapElements( *this, overlap );
|
||||
}
|
||||
|
||||
|
||||
template< typename Data, typename DataCompare >
|
||||
void IntervalTree<Data,DataCompare>::checkVMax () const
|
||||
{
|
||||
checkVMax( this->getRoot() );
|
||||
}
|
||||
|
||||
|
||||
template< typename Data, typename DataCompare >
|
||||
void IntervalTree<Data,DataCompare>::checkVMax ( typename Super::Node* node ) const
|
||||
{
|
||||
if (not node) return;
|
||||
|
||||
DbU::Unit lchildVMax = (node->getLeft ()) ? node->getLeft ()->getValue().getChildsVMax() : node->getValue().getVMax();
|
||||
DbU::Unit rchildVMax = (node->getRight()) ? node->getRight()->getValue().getChildsVMax() : node->getValue().getVMax();
|
||||
DbU::Unit childsVMax = std::max( lchildVMax, rchildVMax );
|
||||
childsVMax = std::max( childsVMax, node->getValue().getVMax() );
|
||||
|
||||
if (node->getValue().getChildsVMax() != childsVMax) {
|
||||
cerr << "ChildVMax discrepency on vmax=" << DbU::getValueString(childsVMax)
|
||||
<< " " << ::getString(node->getValue()) << endl;
|
||||
}
|
||||
|
||||
checkVMax( node->getLeft() );
|
||||
checkVMax( node->getRight() );
|
||||
}
|
||||
|
||||
|
||||
} // HUrricane namespace.
|
||||
|
||||
#endif // HURRICANE_INTERVAL_TREE_H
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
// not, see <http://www.gnu.org/licenses/>.
|
||||
// ****************************************************************************************************
|
||||
|
||||
#ifndef HURRICANE_NET
|
||||
#define HURRICANE_NET
|
||||
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include "hurricane/Entity.h"
|
||||
#include "hurricane/Nets.h"
|
||||
|
@ -253,6 +251,7 @@ class Net : public Entity {
|
|||
public: virtual void _toJsonSignature(JsonWriter*) const;
|
||||
public: virtual void _toJsonCollections(JsonWriter*) const;
|
||||
public: virtual string _getTypeName() const {return _TName("Net");};
|
||||
public: string _getFlagsAsString() const;
|
||||
public: virtual string _getString() const;
|
||||
public: virtual Record* _getRecord() const;
|
||||
public: NetMainName& _getMainName() { return _mainName; }
|
||||
|
@ -445,9 +444,10 @@ namespace Hurricane {
|
|||
// Because sometimes it didn't happens (?).
|
||||
const SlotTemplate<Net*> dummyNetSlot ( string("dummyNetSlot"), NULL );
|
||||
|
||||
}
|
||||
|
||||
#endif // HURRICANE_NET
|
||||
typedef std::set<Net*,DBo::CompareById> NetSet;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
|
|
|
@ -121,6 +121,10 @@ class JsonOccurrence : public JsonObject {
|
|||
public: virtual void toData(JsonStack&);
|
||||
};
|
||||
|
||||
|
||||
typedef std::set<Occurrence> OccurrenceSet;
|
||||
|
||||
|
||||
} // End of Hurricane namespace.
|
||||
|
||||
|
||||
|
|
|
@ -34,9 +34,7 @@
|
|||
// Third edition, MIT press, 2011, p. 308.
|
||||
|
||||
|
||||
#ifndef HURRICANE_RBTREE_H
|
||||
#define HURRICANE_RBTREE_H
|
||||
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
@ -90,7 +88,7 @@ namespace Hurricane {
|
|||
inline void copyColor ( Node* );
|
||||
void updateEdge ( Node* oldChild, Node* newChild );
|
||||
void clear ();
|
||||
inline void copy ( const Node* );
|
||||
inline void swap ( Node* );
|
||||
virtual std::string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
private:
|
||||
|
@ -284,8 +282,15 @@ namespace Hurricane {
|
|||
|
||||
|
||||
template< typename Data, typename Compare >
|
||||
inline void RbTree<Data,Compare>::Node::copy ( const Node* other )
|
||||
{ value_ = other->value_; }
|
||||
inline void RbTree<Data,Compare>::Node::swap ( Node* other )
|
||||
{
|
||||
cdebug_log(0,0) << "Node::swap()" << endl;
|
||||
cdebug_log(0,0) << "| " << value_ << endl;
|
||||
cdebug_log(0,0) << "| " << other->value_ << endl;
|
||||
Data tmp = value_; value_ = other->value_; other->value_ = tmp;
|
||||
cdebug_log(0,0) << "| " << value_ << endl;
|
||||
cdebug_log(0,0) << "| " << other->value_ << endl;
|
||||
}
|
||||
|
||||
|
||||
template< typename Data, typename Compare >
|
||||
|
@ -515,7 +520,7 @@ namespace Hurricane {
|
|||
template< typename Data, typename Compare >
|
||||
void RbTree<Data,Compare>::rotateLeft ( typename RbTree<Data,Compare>::Node* node )
|
||||
{
|
||||
cdebug_log(0,0) << "RbTree::rotateLeft() " << node << std::endl;
|
||||
cdebug_log(0,0) << "RbTree::rotateLeft() " << node->getValue() << std::endl;
|
||||
|
||||
Node* rchild = node->getRight();
|
||||
|
||||
|
@ -534,7 +539,7 @@ namespace Hurricane {
|
|||
template< typename Data, typename Compare >
|
||||
void RbTree<Data,Compare>::rotateRight ( typename RbTree<Data,Compare>::Node* node )
|
||||
{
|
||||
cdebug_log(0,0) << "RbTree::rotateRight() " << node << std::endl;
|
||||
cdebug_log(0,0) << "RbTree::rotateRight() " << node->getValue() << std::endl;
|
||||
|
||||
Node* lchild = node->getLeft();
|
||||
|
||||
|
@ -557,15 +562,21 @@ namespace Hurricane {
|
|||
|
||||
Node* current = root_;
|
||||
while ( current ) {
|
||||
cdebug_log(0,0) << "| " << current << std::endl;
|
||||
cdebug_log(0,0) << "| " << current->getValue() << std::endl;
|
||||
|
||||
if (current->getValue() == value) {
|
||||
cdebug_log(0,-1) << "> Value found: " << current <<std::endl;
|
||||
cdebug_log(0,-1) << "> Value found: " << current->getValue() << std::endl;
|
||||
return iterator(current);
|
||||
}
|
||||
|
||||
if (compare_(value,current->getValue())) current = current->getLeft ();
|
||||
else current = current->getRight();
|
||||
if (compare_(value,current->getValue())) {
|
||||
current = current->getLeft ();
|
||||
cdebug_log(0,0) << "| Go left " << ((current) ? ::getString(current->getValue()) : "NULL") << std::endl;
|
||||
}
|
||||
else {
|
||||
current = current->getRight();
|
||||
cdebug_log(0,0) << "| Go right " << ((current) ? ::getString(current->getValue()) : "NULL") << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_log(0,-1) << "Value not found." << std::endl;
|
||||
|
@ -630,21 +641,22 @@ namespace Hurricane {
|
|||
|
||||
Node* rmNode = const_cast<Node*>( find( value ).getNode() );
|
||||
if (not rmNode) {
|
||||
cdebug_log(0,1) << "No node of value=" << value << std::endl;
|
||||
cdebug_log(0,-1) << "No node of value=" << value << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
Node* rmLeaf = nullptr;
|
||||
if (rmNode->getLeft() and rmNode->getRight()) {
|
||||
Node* rmLeaf = rmNode->getLeft();
|
||||
Node* rmMax = rmLeaf->getMax();
|
||||
rmLeaf = rmNode->getLeft();
|
||||
Node* rmMax = rmLeaf->getMax();
|
||||
if (rmMax) rmLeaf = rmMax;
|
||||
|
||||
rmNode->copy( rmLeaf );
|
||||
rmNode = rmLeaf;
|
||||
rmNode->swap( rmLeaf );
|
||||
std::swap( rmNode, rmLeaf );
|
||||
}
|
||||
|
||||
postRemove ( rmNode );
|
||||
|
||||
removeRepair( rmNode, 0 );
|
||||
postRemove ( rmNode );
|
||||
|
||||
Node* parent = rmNode->getParent();
|
||||
Node* child = (rmNode->getLeft()) ? rmNode->getLeft() : rmNode->getRight();
|
||||
|
@ -660,8 +672,9 @@ namespace Hurricane {
|
|||
}
|
||||
}
|
||||
|
||||
cdebug_log(0,0) << "delete " << rmNode << std::endl;
|
||||
cdebug_log(0,0) << "delete " << rmNode->getValue() << std::endl;
|
||||
delete rmNode;
|
||||
|
||||
--count_;
|
||||
|
||||
cdebug_tabw(0,-1);
|
||||
|
@ -671,8 +684,13 @@ namespace Hurricane {
|
|||
template< typename Data, typename Compare >
|
||||
void RbTree<Data,Compare>::removeRepair ( typename RbTree<Data,Compare>::Node* rmNode, size_t depth )
|
||||
{
|
||||
cdebug_log(0,1) << "RbTree::removeRepair() rmNode:" << rmNode
|
||||
cdebug_log(0,1) << "RbTree::removeRepair() rmNode:" << rmNode->getValue()
|
||||
<< " depth:" << depth << std::endl;
|
||||
|
||||
if (not rmNode) {
|
||||
cdebug_tabw(0,-1);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (rmNode->isBlack()) {
|
||||
Node* parent = rmNode->getParent();
|
||||
|
@ -979,6 +997,7 @@ namespace Hurricane {
|
|||
void RbTreeToDot<Data,Compare,RbTree>::write ( std::ostream& o ) const
|
||||
{
|
||||
o << "digraph RbTree {\n";
|
||||
o << " ratio=\"1.0\";\n";
|
||||
toDot( o, tree_->getRoot() );
|
||||
o << "}";
|
||||
}
|
||||
|
@ -989,8 +1008,9 @@ namespace Hurricane {
|
|||
{
|
||||
if (not node) return;
|
||||
|
||||
string svalue = ::getString( node->getValue() );
|
||||
o << " id_" << getId(node) << " "
|
||||
<< "[label=\"id:" << getId(node) << "\\n" << ::getString(node->getValue())
|
||||
<< "[label=\"id:" << getId(node) << "\\n" << split( svalue )
|
||||
<< "\""
|
||||
<< ",color=" << (node->isRed() ? "red" : "black")
|
||||
<< ",fontcolor=" << (node->isRed() ? "red" : "black")
|
||||
|
@ -1031,6 +1051,3 @@ namespace Hurricane {
|
|||
|
||||
|
||||
} // Hurricane namespace.
|
||||
|
||||
|
||||
#endif // HURRICANE_RBTREE_H
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// Copyright (c) BULL S.A. 2018-2018, All Rights Reserved
|
||||
// Copyright (c) BULL S.A. 2018-2023, All Rights Reserved
|
||||
//
|
||||
// This file is part of Hurricane.
|
||||
//
|
||||
|
@ -28,10 +28,7 @@
|
|||
// | C++ Header : "./hurricane/Rectilinear.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef HURRICANE_RECTILINEAR_H
|
||||
#define HURRICANE_RECTILINEAR_H
|
||||
|
||||
#pragma once
|
||||
#include "hurricane/Component.h"
|
||||
|
||||
|
||||
|
@ -46,11 +43,13 @@ namespace Hurricane {
|
|||
class Rectilinear : public Component {
|
||||
public:
|
||||
typedef Component Super;
|
||||
static const uint32_t IsRectilinear = (1<<0);
|
||||
|
||||
public:
|
||||
static Rectilinear* create ( Net*, const Layer*, const vector<Point>& );
|
||||
// Accessors.
|
||||
virtual bool isNonRectangle () const;
|
||||
inline bool isRectilinear () const;
|
||||
virtual DbU::Unit getX () const;
|
||||
virtual DbU::Unit getY () const;
|
||||
virtual Box getBoundingBox () const;
|
||||
|
@ -59,6 +58,7 @@ namespace Hurricane {
|
|||
virtual Point getPoint ( size_t i ) const;
|
||||
virtual const Layer* getLayer () const;
|
||||
inline Points getContour () const;
|
||||
bool getAsRectangles ( std::vector<Box>& ) const;
|
||||
inline const vector<Point>& getPoints () const;
|
||||
// Mutators.
|
||||
void setLayer ( const Layer* );
|
||||
|
@ -75,11 +75,13 @@ namespace Hurricane {
|
|||
private:
|
||||
const Layer* _layer;
|
||||
vector<Point> _points;
|
||||
uint32_t _flags;
|
||||
};
|
||||
|
||||
|
||||
inline Points Rectilinear::getContour () const { return new VectorCollection<Point>(_points); }
|
||||
inline const vector<Point>& Rectilinear::getPoints () const { return _points; }
|
||||
inline bool Rectilinear::isRectilinear () const { return _flags & IsRectilinear; }
|
||||
inline Points Rectilinear::getContour () const { return new VectorCollection<Point>(_points); }
|
||||
inline const vector<Point>& Rectilinear::getPoints () const { return _points; }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -99,5 +101,3 @@ namespace Hurricane {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Hurricane::Rectilinear);
|
||||
|
||||
#endif // HURRICANE_RECTILINEAR_H
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
${Boost_INCLUDE_DIRS}
|
||||
${Python_INCLUDE_DIRS}
|
||||
)
|
||||
find_package (Python3 COMPONENTS Interpreter Development)
|
||||
set( pyCpps ProxyProperty.cpp
|
||||
PythonAttributes.cpp
|
||||
PyBreakpoint.cpp
|
||||
|
|
|
@ -45,6 +45,24 @@ namespace Isobar {
|
|||
}
|
||||
|
||||
|
||||
PyObject* VectorToList ( const std::vector<Box>& v )
|
||||
{
|
||||
PyObject* pyList = PyList_New( v.size() );
|
||||
|
||||
for ( size_t i=0 ; i<v.size() ; ++i ) {
|
||||
PyBox* pyBox = PyObject_NEW( PyBox, &PyTypeBox );
|
||||
if (not pyBox) { return NULL; }
|
||||
|
||||
HTRY
|
||||
pyBox->_object = new Box ( v[i] );
|
||||
HCATCH
|
||||
PyList_SetItem( pyList, i, (PyObject*)pyBox );
|
||||
}
|
||||
|
||||
return pyList;
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
|
@ -168,20 +186,54 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
static PyObject* PyRectilinear_getAsRectangles ( PyRectilinear *self, PyObject* args )
|
||||
{
|
||||
cdebug_log(20,0) << "Rectilinear.getAsRectangles()" << endl;
|
||||
|
||||
HTRY
|
||||
METHOD_HEAD( "Rectilinear.getAsRectangles()" )
|
||||
|
||||
PyObject* pyList = NULL;
|
||||
if (not PyArg_ParseTuple( args, "O:Rectilinear.getAsRectangles", &pyList )) {
|
||||
PyErr_SetString( ConstructorError, "Rectilinear.getAsRectangles(): Must have exactly one parameter." );
|
||||
return NULL;
|
||||
}
|
||||
if (not PyList_Check(pyList)) {
|
||||
PyErr_SetString( ConstructorError, "Rectilinear.getAsRectangles(): Argument must be a list." );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyList_SetSlice( pyList, 0, PyList_Size(pyList), NULL );
|
||||
vector<Box> boxes;
|
||||
rectilinear->getAsRectangles( boxes );
|
||||
for ( size_t i=0 ; i<boxes.size() ; ++i ) {
|
||||
PyBox* pyBox = PyObject_NEW( PyBox, &PyTypeBox );
|
||||
if (not pyBox) { return NULL; }
|
||||
|
||||
pyBox->_object = new Box ( boxes[i] );
|
||||
PyList_Append( pyList, (PyObject*)pyBox );
|
||||
}
|
||||
HCATCH
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// PyRectilinear Attribute Method table.
|
||||
|
||||
PyMethodDef PyRectilinear_Methods[] =
|
||||
{ { "create" , (PyCFunction)PyRectilinear_create , METH_VARARGS|METH_STATIC
|
||||
, "Create a new Rectilinear polygon." }
|
||||
, { "isNonRectangle", (PyCFunction)PyRectilinear_isNonRectangle, METH_NOARGS , "Tells if the shape is not a rectangle." }
|
||||
, { "getX" , (PyCFunction)PyRectilinear_getX , METH_NOARGS , "Return the Rectilinear X value." }
|
||||
, { "getY" , (PyCFunction)PyRectilinear_getY , METH_NOARGS , "Return the Rectilinear Y value." }
|
||||
, { "getBoundingBox", (PyCFunction)PyRectilinear_getBoundingBox, METH_NOARGS , "Return the Rectilinear Bounding Box." }
|
||||
, { "setPoints" , (PyCFunction)PyRectilinear_setPoints , METH_VARARGS, "Sets the Rectilinear Bounding Box." }
|
||||
, { "translate" , (PyCFunction)PyRectilinear_translate , METH_VARARGS, "Translates the Rectilinear of dx and dy." }
|
||||
, { "destroy" , (PyCFunction)PyRectilinear_destroy , METH_NOARGS
|
||||
, "Destroy associated hurricane object, the python object remains." }
|
||||
{ { "create" , (PyCFunction)PyRectilinear_create , METH_VARARGS|METH_STATIC
|
||||
, "Create a new Rectilinear polygon." }
|
||||
, { "isNonRectangle" , (PyCFunction)PyRectilinear_isNonRectangle , METH_NOARGS , "Tells if the shape is not a rectangle." }
|
||||
, { "getX" , (PyCFunction)PyRectilinear_getX , METH_NOARGS , "Return the Rectilinear X value." }
|
||||
, { "getY" , (PyCFunction)PyRectilinear_getY , METH_NOARGS , "Return the Rectilinear Y value." }
|
||||
, { "getBoundingBox" , (PyCFunction)PyRectilinear_getBoundingBox , METH_NOARGS , "Return the Rectilinear Bounding Box." }
|
||||
, { "setPoints" , (PyCFunction)PyRectilinear_setPoints , METH_VARARGS, "Sets the Rectilinear Bounding Box." }
|
||||
, { "translate" , (PyCFunction)PyRectilinear_translate , METH_VARARGS, "Translates the Rectilinear of dx and dy." }
|
||||
, { "getAsRectangles", (PyCFunction)PyRectilinear_getAsRectangles, METH_VARARGS, "Return the rectangle coverage." }
|
||||
, { "destroy" , (PyCFunction)PyRectilinear_destroy , METH_NOARGS
|
||||
, "Destroy associated hurricane object, the python object remains." }
|
||||
, {NULL, NULL, 0, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
|
@ -1625,31 +1625,31 @@ extern "C" {
|
|||
catch ( const Warning& w ) { \
|
||||
std::string message = getString(w); \
|
||||
PyErr_Warn ( HurricaneWarning, const_cast<char*>(message.c_str()) ); \
|
||||
std::cerr << message << std::endl; \
|
||||
std::cerr << message << std::endl; \
|
||||
} \
|
||||
catch ( const Error& e ) { \
|
||||
std::string message = getString(e); \
|
||||
if (not e.where().empty()) message += "\n" + e.where(); \
|
||||
PyErr_SetString ( HurricaneError, message.c_str() ); \
|
||||
std::cerr << message << std::endl; \
|
||||
std::cerr << message << std::endl; \
|
||||
return NULL; \
|
||||
} \
|
||||
catch ( const Bug& e ) { \
|
||||
std::string message = getString(e); \
|
||||
PyErr_SetString ( HurricaneError, message.c_str() ); \
|
||||
std::cerr << message << std::endl; \
|
||||
std::cerr << message << std::endl; \
|
||||
return NULL; \
|
||||
} \
|
||||
catch ( const Exception& e ) { \
|
||||
std::string message = "Unknown Hurricane::Exception"; \
|
||||
PyErr_SetString ( HurricaneError, message.c_str() ); \
|
||||
std::cerr << message << std::endl; \
|
||||
std::cerr << message << std::endl; \
|
||||
return NULL; \
|
||||
} \
|
||||
catch ( const std::exception& e ) { \
|
||||
std::string message = std::string(e.what()); \
|
||||
PyErr_SetString ( HurricaneError, message.c_str() ); \
|
||||
std::cerr << message << std::endl; \
|
||||
std::cerr << message << std::endl; \
|
||||
return NULL; \
|
||||
} \
|
||||
catch ( ... ) { \
|
||||
|
@ -1657,7 +1657,7 @@ extern "C" {
|
|||
"Unmanaged exception, neither a Hurricane::Error nor" \
|
||||
" a std::exception."; \
|
||||
PyErr_SetString ( HurricaneError, message.c_str() ); \
|
||||
std::cerr << message << std::endl; \
|
||||
std::cerr << message << std::endl; \
|
||||
return NULL; \
|
||||
} \
|
||||
|
||||
|
|
|
@ -157,8 +157,9 @@ namespace Hurricane {
|
|||
|
||||
//int scale = 80 * Cfg::getParamEnumerate("viewer.printer.mode")->asInt();
|
||||
int scale = (Graphics::isHighDpi()) ? 4 : 2;
|
||||
_drawingWidth = _cellWidget->width () * scale;
|
||||
_drawingHeight = _cellWidget->height() * scale;
|
||||
_drawingWidth = _screenCellWidget->geometry().width () * scale;
|
||||
_drawingHeight = _screenCellWidget->geometry().height() * scale;
|
||||
_cellWidget->resize( _drawingWidth, _drawingHeight );
|
||||
|
||||
_image = new QImage( _drawingWidth
|
||||
, _drawingHeight + ((_flags&ShowScale) ? 60 : 0)
|
||||
|
@ -188,7 +189,7 @@ namespace Hurricane {
|
|||
setFitOnAbutmentBox( true );
|
||||
_cellWidget->fitToContents();
|
||||
} else {
|
||||
//_cellWidget->reframe( _screenCellWidget->getVisibleArea() );
|
||||
_cellWidget->reframe( _screenCellWidget->getVisibleArea() );
|
||||
}
|
||||
|
||||
cerr << " After resize CellWidget: " << _cellWidget->geometry().width() << "x" << _cellWidget->geometry().height() << endl;
|
||||
|
|
|
@ -584,7 +584,7 @@ namespace Hurricane {
|
|||
|
||||
void CellViewer::refreshTitle ()
|
||||
{
|
||||
QString cellName = "None";
|
||||
QString cellName = "empty";
|
||||
if ( getCell() )
|
||||
cellName = getString(getCell()->getName()).c_str();
|
||||
|
||||
|
|
|
@ -2683,7 +2683,86 @@ namespace Hurricane {
|
|||
} else
|
||||
selected = false;
|
||||
|
||||
if ( (--_delaySelectionChanged == 0) and selected ) emit selectionChanged( _selectors );
|
||||
if ( (--_delaySelectionChanged == 0) and selected )
|
||||
emit selectionChanged( _selectors );
|
||||
}
|
||||
|
||||
|
||||
void CellWidget::selectSet ( const ComponentSet& components )
|
||||
{
|
||||
if ( (++_delaySelectionChanged == 1) and not _state->cumulativeSelection() ) {
|
||||
openRefreshSession();
|
||||
unselectAll();
|
||||
closeRefreshSession();
|
||||
}
|
||||
|
||||
bool selected = true;
|
||||
// SelectorCriterion* criterion = _state->getSelection().add ( selectArea );
|
||||
// if ( criterion and (not criterion->isEnabled()) ) {
|
||||
// criterion->enable();
|
||||
|
||||
for ( Component* component : components ) {
|
||||
if (component->getCell() == getCell()) {
|
||||
select( Occurrence( component ));
|
||||
}
|
||||
}
|
||||
// } else
|
||||
// selected = false;
|
||||
|
||||
if ( (--_delaySelectionChanged == 0) and selected )
|
||||
emit selectionChanged( _selectors );
|
||||
}
|
||||
|
||||
|
||||
void CellWidget::selectSet ( const OccurrenceSet& occurrences )
|
||||
{
|
||||
if ( (++_delaySelectionChanged == 1) and not _state->cumulativeSelection() ) {
|
||||
openRefreshSession();
|
||||
unselectAll();
|
||||
closeRefreshSession();
|
||||
}
|
||||
|
||||
bool selected = true;
|
||||
// SelectorCriterion* criterion = _state->getSelection().add ( selectArea );
|
||||
// if ( criterion and (not criterion->isEnabled()) ) {
|
||||
// criterion->enable();
|
||||
|
||||
for ( const Occurrence& occurrence : occurrences ) {
|
||||
if (occurrence.getOwnerCell() == getCell()) {
|
||||
select( occurrence );
|
||||
}
|
||||
}
|
||||
// } else
|
||||
// selected = false;
|
||||
|
||||
if ( (--_delaySelectionChanged == 0) and selected )
|
||||
emit selectionChanged( _selectors );
|
||||
}
|
||||
|
||||
|
||||
void CellWidget::select ( Occurrences occurrences )
|
||||
{
|
||||
if ( (++_delaySelectionChanged == 1) and not _state->cumulativeSelection() ) {
|
||||
openRefreshSession();
|
||||
unselectAll();
|
||||
closeRefreshSession();
|
||||
}
|
||||
|
||||
bool selected = true;
|
||||
// SelectorCriterion* criterion = _state->getSelection().add ( selectArea );
|
||||
// if ( criterion and (not criterion->isEnabled()) ) {
|
||||
// criterion->enable();
|
||||
|
||||
for ( const Occurrence& occurrence : occurrences ) {
|
||||
if (occurrence.getOwnerCell() == getCell()) {
|
||||
select( occurrence );
|
||||
}
|
||||
}
|
||||
// } else
|
||||
// selected = false;
|
||||
|
||||
if ( (--_delaySelectionChanged == 0) and selected )
|
||||
emit selectionChanged( _selectors );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2744,7 +2823,7 @@ namespace Hurricane {
|
|||
|
||||
if ( (--_delaySelectionChanged == 0) and selected ) {
|
||||
if ( _state->showSelection() ) _redrawManager.refresh ();
|
||||
emit selectionChanged(_selectors);
|
||||
emit selectionChanged(_selectors);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2782,7 +2861,47 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
_selectionHasChanged = true;
|
||||
if ( (_delaySelectionChanged == 0) and unselected ) emit selectionChanged( _selectors );
|
||||
if ( (_delaySelectionChanged == 0) and unselected )
|
||||
emit selectionChanged( _selectors );
|
||||
}
|
||||
|
||||
|
||||
void CellWidget::unselectSet ( const ComponentSet& components )
|
||||
{
|
||||
++_delaySelectionChanged;
|
||||
for ( Component* component : components ) {
|
||||
if (component->getCell() == getCell()) {
|
||||
unselect( Occurrence( component ));
|
||||
}
|
||||
}
|
||||
if ( --_delaySelectionChanged == 0 )
|
||||
emit selectionChanged( _selectors );
|
||||
}
|
||||
|
||||
|
||||
void CellWidget::unselectSet ( const OccurrenceSet& occurrences )
|
||||
{
|
||||
++_delaySelectionChanged;
|
||||
for ( const Occurrence& occurrence : occurrences ) {
|
||||
if (occurrence.getOwnerCell() == getCell()) {
|
||||
unselect( occurrence );
|
||||
}
|
||||
}
|
||||
if ( --_delaySelectionChanged == 0 )
|
||||
emit selectionChanged( _selectors );
|
||||
}
|
||||
|
||||
|
||||
void CellWidget::unselect ( Occurrences occurrences )
|
||||
{
|
||||
++_delaySelectionChanged;
|
||||
for ( const Occurrence& occurrence : occurrences ) {
|
||||
if (occurrence.getOwnerCell() == getCell()) {
|
||||
unselect( occurrence );
|
||||
}
|
||||
}
|
||||
if ( --_delaySelectionChanged == 0 )
|
||||
emit selectionChanged( _selectors );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2793,7 +2912,8 @@ namespace Hurricane {
|
|||
_state->getSelection().clear ();
|
||||
_unselectAll ();
|
||||
|
||||
if ( --_delaySelectionChanged == 0 ) emit selectionChanged(_selectors);
|
||||
if ( --_delaySelectionChanged == 0 )
|
||||
emit selectionChanged(_selectors);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -658,6 +658,19 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
|
||||
void ControllerWidget::insertTabAfter ( const QString& ref, QWidget* tab, const QString& label )
|
||||
{
|
||||
for ( int itab=0 ; true; ++itab ) {
|
||||
QWidget* refTab = widget( itab );
|
||||
if (not refTab) break;
|
||||
if (refTab->objectName() != ref) continue;
|
||||
insertTab( itab, tab, label );
|
||||
return;
|
||||
}
|
||||
addTab( tab, label );
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "ControllerWidget::GraphicsObserver".
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace Hurricane {
|
|||
|
||||
|
||||
int SimpleNetInformations::getColumnCount ()
|
||||
{ return 3; }
|
||||
{ return 6; }
|
||||
|
||||
|
||||
QVariant SimpleNetInformations::getColumnName ( int column )
|
||||
|
@ -71,7 +71,10 @@ namespace Hurricane {
|
|||
switch ( column ) {
|
||||
case 0: return QVariant(QObject::tr("Net"));
|
||||
case 1: return QVariant(QObject::tr("Plugs"));
|
||||
case 2: return QVariant(QObject::tr("RoutingPads"));
|
||||
case 2: return QVariant(QObject::tr("RPs"));
|
||||
case 3: return QVariant(QObject::tr("Flags"));
|
||||
case 4: return QVariant(QObject::tr("Type"));
|
||||
case 5: return QVariant(QObject::tr("Direction"));
|
||||
}
|
||||
return QVariant(QObject::tr("Column Out of Bound"));
|
||||
}
|
||||
|
@ -84,11 +87,15 @@ namespace Hurricane {
|
|||
case 1: return (unsigned int)_plugsCount;
|
||||
case 2:
|
||||
if (_net->isGlobal()) {
|
||||
if (not _rpsCount) return "N/A (global)";
|
||||
string s = getString(_rpsCount) + " (global)";
|
||||
if (not _rpsCount) return "N/A";
|
||||
string s = getString(_rpsCount);
|
||||
return s.c_str();
|
||||
}
|
||||
return (unsigned int)_rpsCount;
|
||||
case 3: return QString::fromStdString( getString( _net->_getFlagsAsString() ));
|
||||
case 4: return QString::fromStdString( getString( _net->getType() ));
|
||||
case 5: return QString::fromStdString( getString( _net->getDirection() ));
|
||||
|
||||
}
|
||||
return QVariant(QObject::tr("Column Out of Bound"));
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace Hurricane {
|
|||
|
||||
QHeaderView* horizontalHeader = _view->horizontalHeader();
|
||||
horizontalHeader->setDefaultAlignment ( Qt::AlignHCenter );
|
||||
horizontalHeader->setMinimumSectionSize( (Graphics::isHighDpi()) ? 300 : 150 );
|
||||
horizontalHeader->setMinimumSectionSize( (Graphics::isHighDpi()) ? 150 : 75 );
|
||||
horizontalHeader->setStretchLastSection( true );
|
||||
|
||||
QHeaderView* verticalHeader = _view->verticalHeader();
|
||||
|
@ -151,24 +151,18 @@ namespace Hurricane {
|
|||
_forceReselect = false;
|
||||
}
|
||||
|
||||
SelectedNetSet::iterator remove;
|
||||
SelectedNetSet::iterator isel = _selecteds.begin ();
|
||||
SelectedNetSet::iterator isel = _selecteds.begin ();
|
||||
while ( isel != _selecteds.end() ) {
|
||||
switch ( isel->getAccesses() ) {
|
||||
case 1: break;
|
||||
case 64:
|
||||
emit netSelected ( Occurrence(isel->getNet()) );
|
||||
break;
|
||||
case 0:
|
||||
emit netUnselected ( Occurrence(isel->getNet()) );
|
||||
remove = isel;
|
||||
++isel;
|
||||
_selecteds.erase ( remove );
|
||||
continue;
|
||||
default:
|
||||
cerr << Bug("NetlistWidget::updateSelecteds(): invalid code %d"
|
||||
,isel->getAccesses()) << endl;
|
||||
SelectedNetSet::iterator remove = isel++;
|
||||
if ( remove->getAccesses() == 0 ) {
|
||||
emit netUnselected ( Occurrence(remove->getNet()) );
|
||||
_selecteds.erase ( remove );
|
||||
}
|
||||
}
|
||||
isel = _selecteds.begin ();
|
||||
while ( isel != _selecteds.end() ) {
|
||||
if ( isel->getAccesses() == 64 )
|
||||
emit netSelected ( Occurrence(isel->getNet()) );
|
||||
++isel;
|
||||
}
|
||||
|
||||
|
|
|
@ -219,6 +219,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
cw->setApplicationName ( name );
|
||||
cw->refreshTitle ();
|
||||
HCATCH
|
||||
|
||||
Py_RETURN_NONE;
|
||||
|
|
|
@ -91,8 +91,8 @@ namespace Hurricane {
|
|||
{
|
||||
if (not _cellWidget) return;
|
||||
|
||||
if (not isCumulative()) clear ();
|
||||
beginResetModel();
|
||||
if (not isCumulative()) _selection.clear ();
|
||||
|
||||
for ( Selector* selector : selection ) {
|
||||
if (not selector->isInModel(_cellWidget)) {
|
||||
|
|
|
@ -87,6 +87,7 @@ namespace Hurricane {
|
|||
CellViewer ( QWidget* parent=NULL );
|
||||
virtual ~CellViewer ();
|
||||
inline bool isToolInterrupted () const;
|
||||
void refreshTitle ();
|
||||
QMenu* createDebugMenu ();
|
||||
bool hasMenu ( const QString& path ) const;
|
||||
bool hasMenuAction ( const QString& path ) const;
|
||||
|
@ -166,7 +167,6 @@ namespace Hurricane {
|
|||
void cellPostModificated ();
|
||||
protected:
|
||||
void createMenus ();
|
||||
void refreshTitle ();
|
||||
void refreshHistory ();
|
||||
void rebuildHistory ();
|
||||
private:
|
||||
|
|
|
@ -265,10 +265,16 @@ namespace Hurricane {
|
|||
inline DrawingPlanes& getDrawingPlanes ();
|
||||
// void select ( const Net* );
|
||||
void select ( Occurrence );
|
||||
void select ( Occurrences );
|
||||
void selectSet ( const OccurrenceSet& );
|
||||
void selectSet ( const ComponentSet& );
|
||||
bool isSelected ( Occurrence );
|
||||
void selectOccurrencesUnder ( Box selectArea );
|
||||
// void unselect ( const Net* );
|
||||
void unselect ( Occurrence );
|
||||
void unselect ( Occurrences );
|
||||
void unselectSet ( const ComponentSet& );
|
||||
void unselectSet ( const OccurrenceSet& );
|
||||
void unselectAll ();
|
||||
void toggleSelection ( Occurrence );
|
||||
void setShowSelection ( bool state );
|
||||
|
|
|
@ -312,6 +312,7 @@ namespace Hurricane {
|
|||
inline TabSettings* getSettings ();
|
||||
void setCellWidget ( CellWidget* );
|
||||
//inline int addSetting ( QWidget* page, const QString& label );
|
||||
void insertTabAfter ( const QString& ref, QWidget*, const QString& label );
|
||||
public slots:
|
||||
void graphicsUpdated ();
|
||||
void cellPreModificate ();
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
set_cmake_policies()
|
||||
#setup_apple()
|
||||
setup_boost(program_options)
|
||||
setup_python()
|
||||
|
||||
set(QT_USE_QTXML "true")
|
||||
find_package(Qt4 REQUIRED)
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
find_package(CORIOLIS REQUIRED)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
check_distribution()
|
||||
|
||||
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
setup_python()
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
find_package(CORIOLIS REQUIRED)
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
set_cmake_policies()
|
||||
setup_boost(program_options)
|
||||
setup_qt()
|
||||
setup_python()
|
||||
|
||||
find_package(Libexecinfo REQUIRED)
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(LEFDEF REQUIRED)
|
||||
find_package(FLUTE REQUIRED)
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
${Boost_INCLUDE_DIRS}
|
||||
${Python_INCLUDE_DIRS}
|
||||
)
|
||||
find_package (Python3 COMPONENTS Interpreter Development)
|
||||
set( includes katana/Constants.h
|
||||
katana/Block.h
|
||||
katana/TrackCost.h
|
||||
|
|
|
@ -76,6 +76,16 @@ namespace {
|
|||
cdebug_tabw(159,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (segment->isNonPrefOnVSmall()) {
|
||||
cdebug_log(159,0) << "Infinite cost from (NonPref on VSmall): " << segment << endl;
|
||||
cost.setInfinite ();
|
||||
cost.setOverlap ();
|
||||
cost.setHardOverlap();
|
||||
cost.setBlockage ();
|
||||
cdebug_tabw(159,-1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cost.getInterval().getVMax() > intersect.getVMax()) cost.setLeftOverlap();
|
||||
|
|
|
@ -152,6 +152,7 @@ namespace Katana {
|
|||
bool TrackElement::isAnalog () const { return false; }
|
||||
bool TrackElement::isWide () const { return false; }
|
||||
bool TrackElement::isNonPref () const { return false; }
|
||||
bool TrackElement::isNonPrefOnVSmall () const { return false; }
|
||||
bool TrackElement::isShortNet () const { return false; }
|
||||
// Predicates.
|
||||
bool TrackElement::hasSymmetric () const { return false; }
|
||||
|
|
|
@ -195,6 +195,7 @@ namespace Katana {
|
|||
bool TrackSegment::isWide () const { return _base->isWide(); }
|
||||
bool TrackSegment::isShortNet () const { return _base->isShortNet(); }
|
||||
bool TrackSegment::isPriorityLocked () const { return _flags & PriorityLocked; }
|
||||
bool TrackSegment::isNonPrefOnVSmall () const { return _base->isNonPrefOnVSmall(); }
|
||||
// Predicates.
|
||||
bool TrackSegment::hasSymmetric () const { return _symmetric != NULL; }
|
||||
// Accessors.
|
||||
|
|
|
@ -106,6 +106,7 @@ namespace Katana {
|
|||
virtual bool isVertical () const = 0;
|
||||
virtual bool isWide () const;
|
||||
virtual bool isNonPref () const;
|
||||
virtual bool isNonPrefOnVSmall () const;
|
||||
virtual bool isUnbreakable () const;
|
||||
virtual bool isLocal () const;
|
||||
virtual bool isGlobal () const;
|
||||
|
|
|
@ -82,6 +82,7 @@ namespace Katana {
|
|||
virtual bool isAnalog () const;
|
||||
virtual bool isWide () const;
|
||||
virtual bool isShortNet () const;
|
||||
virtual bool isNonPrefOnVSmall () const;
|
||||
virtual bool isPriorityLocked () const;
|
||||
// Predicates.
|
||||
virtual bool hasSymmetric () const;
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
set_cmake_policies()
|
||||
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
|
||||
setup_boost(program_options)
|
||||
setup_python()
|
||||
|
||||
if (USE_LIBBFD)
|
||||
find_package(Libbfd)
|
||||
endif()
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
find_package(CORIOLIS REQUIRED)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||
find_package(Bootstrap REQUIRED)
|
||||
setup_project_paths(CORIOLIS)
|
||||
setup_python()
|
||||
|
||||
find_package(Bootstrap REQUIRED)
|
||||
set_cmake_policies()
|
||||
|
@ -19,7 +20,6 @@
|
|||
cmake_policy(SET CMP0002 OLD)
|
||||
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
find_package(CORIOLIS REQUIRED)
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# -*- explicit-buffer-name: "CMakeLists.txt<tramontana>" -*-
|
||||
|
||||
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
|
||||
project(TRAMONTANA)
|
||||
|
||||
set(ignoreVariables "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
|
||||
|
||||
option(BUILD_DOC "Build the documentation (doxygen)" OFF)
|
||||
option(USE_LIBBFD "Link with BFD libraries to print stack traces" OFF)
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||
find_package(Bootstrap REQUIRED)
|
||||
setup_project_paths(CORIOLIS)
|
||||
|
||||
set_cmake_policies()
|
||||
setup_boost()
|
||||
setup_qt()
|
||||
setup_python()
|
||||
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
find_package(CORIOLIS REQUIRED)
|
||||
find_package(Doxygen)
|
||||
|
||||
add_subdirectory(src)
|
||||
#add_subdirectory(cmake_modules)
|
||||
#add_subdirectory(doc)
|
|
@ -0,0 +1,78 @@
|
|||
# -*- explicit-buffer-name: "CMakeLists.txt<tramontana/src>" -*-
|
||||
|
||||
# include( ${QT_USE_FILE} )
|
||||
include_directories( ${TRAMONTANA_SOURCE_DIR}/src
|
||||
${CORIOLIS_INCLUDE_DIR}
|
||||
${HURRICANE_INCLUDE_DIR}
|
||||
${CONFIGURATION_INCLUDE_DIR}
|
||||
${QtX_INCLUDE_DIRS}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${Python_INCLUDE_DIRS}
|
||||
)
|
||||
set( includes tramontana/Tile.h
|
||||
tramontana/QueryTiles.h
|
||||
tramontana/SweepLine.h
|
||||
tramontana/Equipotential.h
|
||||
tramontana/EquipotentialRelation.h
|
||||
tramontana/EquipotentialComponents.h
|
||||
tramontana/TramontanaEngine.h
|
||||
tramontana/GraphicTramontanaEngine.h
|
||||
)
|
||||
set( pyIncludes tramontana/PyTramontanaEngine.h
|
||||
tramontana/PyGraphicTramontanaEngine.h
|
||||
)
|
||||
set( mocIncludes tramontana/GraphicTramontanaEngine.h
|
||||
tramontana/EquipotentialsModel.h
|
||||
tramontana/EquipotentialsWidget.h
|
||||
tramontana/TabEquipotentials.h
|
||||
)
|
||||
set( cpps Tile.cpp
|
||||
QueryTiles.cpp
|
||||
SweepLine.cpp
|
||||
Equipotential.cpp
|
||||
EquipotentialRelation.cpp
|
||||
EquipotentialComponents.cpp
|
||||
TramontanaEngine.cpp
|
||||
GraphicTramontanaEngine.cpp
|
||||
EquipotentialsModel.cpp
|
||||
EquipotentialsWidget.cpp
|
||||
TabEquipotentials.cpp
|
||||
)
|
||||
set( pyCpps PyTramontana.cpp
|
||||
PyTramontanaEngine.cpp
|
||||
PyGraphicTramontanaEngine.cpp
|
||||
)
|
||||
qtX_wrap_cpp( mocCpps ${mocIncludes} )
|
||||
|
||||
set( depLibs ${CORIOLIS_PYTHON_LIBRARIES}
|
||||
${CORIOLIS_LIBRARIES}
|
||||
${HURRICANE_PYTHON_LIBRARIES}
|
||||
${HURRICANE_GRAPHICAL_LIBRARIES}
|
||||
${HURRICANE_LIBRARIES}
|
||||
${CONFIGURATION_LIBRARY}
|
||||
${UTILITIES_LIBRARY}
|
||||
${LEFDEF_LIBRARIES}
|
||||
${QtX_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${Python3_LIBRARIES}
|
||||
-lutil
|
||||
${LIBEXECINFO_LIBRARIES}
|
||||
)
|
||||
|
||||
add_library( tramontana ${cpps} ${mocCpps} ${pyCpps} )
|
||||
set_target_properties( tramontana PROPERTIES VERSION 1.0 SOVERSION 1 )
|
||||
target_link_libraries( tramontana ${depLibs} )
|
||||
|
||||
add_python_module( "${pyCpps}"
|
||||
"${pyIncludes}"
|
||||
"Do_not_generate_C_library"
|
||||
Tramontana
|
||||
"tramontana;${depLibs}"
|
||||
include/coriolis2/tramontana
|
||||
)
|
||||
|
||||
install( TARGETS tramontana DESTINATION lib${LIB_SUFFIX} )
|
||||
install( FILES ${includes}
|
||||
${mocIncludes} DESTINATION include/coriolis2/tramontana )
|
||||
|
||||
|
|
@ -0,0 +1,533 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./Equipotential.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <iomanip>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include "hurricane/utilities/Path.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/UpdateSession.h"
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/Timer.h"
|
||||
#include "hurricane/Layer.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/Contact.h"
|
||||
#include "hurricane/Plug.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "crlcore/Utilities.h"
|
||||
#include "tramontana/Equipotential.h"
|
||||
#include "tramontana/EquipotentialRelation.h"
|
||||
#include "tramontana/EquipotentialComponents.h"
|
||||
#include "tramontana/TramontanaEngine.h"
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::dec;
|
||||
using std::setw;
|
||||
using std::setfill;
|
||||
using std::left;
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
using std::ofstream;
|
||||
using std::ostringstream;
|
||||
using std::setprecision;
|
||||
using std::vector;
|
||||
using std::set;
|
||||
using std::make_pair;
|
||||
using Hurricane::dbo_ptr;
|
||||
using Hurricane::UpdateSession;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Breakpoint;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Entity;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::Contact;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::RoutingPad;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Instance;
|
||||
using Hurricane::Path;
|
||||
|
||||
|
||||
bool NetCompareByName::operator() ( const Net* lhs, const Net* rhs ) const
|
||||
{
|
||||
if (lhs->isFused () != rhs->isFused ()) return rhs->isFused();
|
||||
if (lhs->isAutomatic() != rhs->isAutomatic()) return rhs->isAutomatic();
|
||||
if (lhs->isGlobal () != rhs->isGlobal ()) return rhs->isGlobal();
|
||||
|
||||
if (lhs->getName().size() != rhs->getName().size())
|
||||
return lhs->getName().size() < rhs->getName().size();
|
||||
return lhs->getName() < rhs->getName();
|
||||
}
|
||||
|
||||
|
||||
bool OccNetCompareByName::operator() ( const Occurrence& lhs, const Occurrence& rhs ) const
|
||||
{
|
||||
static NetCompareByName compareByName;
|
||||
|
||||
size_t lhsLength = lhs.getPath().getInstances().getSize();
|
||||
size_t rhsLength = rhs.getPath().getInstances().getSize();
|
||||
|
||||
if (lhsLength != rhsLength) return lhsLength < rhsLength;
|
||||
return compareByName( static_cast<Net*>(lhs.getEntity()), static_cast<Net*>(rhs.getEntity()) );
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tramontana::Equipotential".
|
||||
|
||||
|
||||
Equipotential* Equipotential::get ( Component* component )
|
||||
{
|
||||
EquipotentialRelation* relation = dynamic_cast<EquipotentialRelation*>(
|
||||
component->getNet()->getProperty( EquipotentialRelation::staticGetName() ));
|
||||
if (not relation) {
|
||||
relation = dynamic_cast<EquipotentialRelation*>(
|
||||
component->getProperty( EquipotentialRelation::staticGetName() ));
|
||||
}
|
||||
if (not relation) return nullptr;
|
||||
return dynamic_cast<Equipotential*>( relation->getMasterOwner() );
|
||||
}
|
||||
|
||||
|
||||
Equipotential* Equipotential::get ( Occurrence occurrence )
|
||||
{
|
||||
EquipotentialRelation* relation = dynamic_cast<EquipotentialRelation*>(
|
||||
occurrence.getProperty( EquipotentialRelation::staticGetName() ));
|
||||
if (not relation) return nullptr;
|
||||
return dynamic_cast<Equipotential*>( relation->getMasterOwner() );
|
||||
}
|
||||
|
||||
|
||||
Occurrence Equipotential::getChildEqui ( Occurrence flatOccurrence )
|
||||
{
|
||||
Component* component = dynamic_cast<Component*>( flatOccurrence.getEntity() );
|
||||
if (not component) {
|
||||
cerr << Error( "Equipotential::getChildEqui(): Occurrence must be over a Component.\n"
|
||||
" (on:%s)"
|
||||
, getString(flatOccurrence).c_str()
|
||||
) << endl;
|
||||
return Occurrence();
|
||||
}
|
||||
|
||||
Equipotential* equi = Equipotential::get( component );
|
||||
if (not equi) {
|
||||
cerr << Error( "Equipotential::getChildEqui(): Component not associated to an Equipotential.\n"
|
||||
" (on:%s)"
|
||||
, getString(flatOccurrence).c_str()
|
||||
) << endl;
|
||||
return Occurrence();
|
||||
}
|
||||
|
||||
if (flatOccurrence.getPath().isEmpty()) return flatOccurrence;
|
||||
|
||||
// cerr << "childEqui:" << flatOccurrence << endl;
|
||||
// cerr << " " << equi << endl;
|
||||
Instance* tailInst = flatOccurrence.getPath().getTailInstance();
|
||||
Path headPath = flatOccurrence.getPath().getHeadPath();
|
||||
Occurrence tailOccurrence;
|
||||
while ( tailInst ) {
|
||||
tailOccurrence = Occurrence( equi, tailInst );
|
||||
equi = Equipotential::get( tailOccurrence );
|
||||
tailInst = headPath.getTailInstance();
|
||||
headPath = headPath.getHeadPath();
|
||||
}
|
||||
|
||||
// cerr << " ==> " << tailOccurrence << endl;
|
||||
// cerr << " " << equi << endl;
|
||||
return tailOccurrence;
|
||||
}
|
||||
|
||||
|
||||
Equipotential::Equipotential ( Cell* owner )
|
||||
: _owner (owner)
|
||||
, _boundingBox ()
|
||||
, _components ()
|
||||
, _childs ()
|
||||
, _name ()
|
||||
, _type (Net::Type::UNDEFINED)
|
||||
, _direction (Net::Direction::DirUndefined)
|
||||
, _netCount (0)
|
||||
, _isBuried (false)
|
||||
, _isExternal (false)
|
||||
, _isGlobal (false)
|
||||
, _isAutomatic (false)
|
||||
, _hasFused (false)
|
||||
, _shortCircuits()
|
||||
{
|
||||
_name = "Unnamed_" + getString( getId() );
|
||||
}
|
||||
|
||||
|
||||
void Equipotential::_postCreate ()
|
||||
{
|
||||
Super::_postCreate();
|
||||
TramontanaEngine* tramontana = TramontanaEngine::get( _owner );
|
||||
tramontana->add( this );
|
||||
}
|
||||
|
||||
|
||||
Equipotential* Equipotential::create ( Cell* owner )
|
||||
{
|
||||
Equipotential* equi = new Equipotential ( owner );
|
||||
equi->_postCreate();
|
||||
return equi;
|
||||
}
|
||||
|
||||
|
||||
void Equipotential::_preDestroy ()
|
||||
{
|
||||
Super::_preDestroy();
|
||||
}
|
||||
|
||||
|
||||
Equipotential::~Equipotential ()
|
||||
{
|
||||
for ( ShortCircuit* shortCircuit : _shortCircuits ) delete shortCircuit;
|
||||
}
|
||||
|
||||
|
||||
Cell* Equipotential::getCell () const
|
||||
{ return _owner; }
|
||||
|
||||
|
||||
Box Equipotential::getBoundingBox () const
|
||||
{ return _boundingBox; }
|
||||
|
||||
|
||||
Occurrences Equipotential::getFlatComponents () const
|
||||
{ return EquipotentialComponents( this ); }
|
||||
|
||||
|
||||
void Equipotential::add ( Occurrence occ, const Box& boundingBox )
|
||||
{
|
||||
if(occ.getPath().isEmpty()) {
|
||||
Contact* contact = dynamic_cast<Contact*>( occ.getEntity() );
|
||||
if ((_components.find(occ) != _components.end())) {
|
||||
if (not contact)
|
||||
cdebug_log(160,0) << "Equipotential::add(): Duplicated " << occ.getCompactString() << endl;
|
||||
return;
|
||||
}
|
||||
Component* comp = dynamic_cast<Component*>( occ.getEntity() );
|
||||
if (not comp) {
|
||||
cerr << Error( "Equipotential::add(): Occurrences with null Path must be Components.\n"
|
||||
" (on:%s)"
|
||||
, getString(occ).c_str()
|
||||
) << endl;
|
||||
return;
|
||||
}
|
||||
cdebug_log(160,0) << "Equipotential::add(): " << occ << endl;
|
||||
_components.insert( occ );
|
||||
NetMap::iterator inet = _nets.find( comp->getNet() );
|
||||
if (inet != _nets.end()) {
|
||||
inet->second.first++;
|
||||
if (inet->second.first > inet->second.second) {
|
||||
cerr << Error( "Equipotential::add(): Doubly counted component of %s.\n"
|
||||
" (on:%s)"
|
||||
, getString(inet->first).c_str()
|
||||
, getString(occ).c_str()
|
||||
) << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
uint32_t compCount = 0;
|
||||
for ( Component* component : comp->getNet()->getComponents() ) {
|
||||
if (dynamic_cast<Plug*>(component)) continue;
|
||||
++compCount;
|
||||
}
|
||||
_nets.insert( make_pair( comp->getNet(), make_pair(1,compCount) ));
|
||||
if (comp->getNet()->isFused()) {
|
||||
_hasFused = true;
|
||||
return;
|
||||
}
|
||||
if (_nets.size() <= 1 + ((_hasFused) ? 1 : 0))
|
||||
return;
|
||||
Net* netA = nullptr;
|
||||
for ( auto item : _nets ) {
|
||||
if (not item.first->isFused() and (item.first != comp->getNet())) {
|
||||
netA = item.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_shortCircuits.push_back( new ShortCircuit( netA, comp->getNet(), comp ));
|
||||
} else {
|
||||
Equipotential* equi = dynamic_cast<Equipotential*>( occ.getEntity() );
|
||||
if (not equi) {
|
||||
cerr << Error( "Equipotential::add(): Occurrence is not an Equipotential.\n"
|
||||
" (on:%s)"
|
||||
, getString(occ).c_str()
|
||||
) << endl;
|
||||
return;
|
||||
}
|
||||
if (not occ.getPath().getTailPath().isEmpty()) {
|
||||
cerr << Error( "Equipotential::add(): Occurrence is more than one instances deep.\n"
|
||||
" (on:%s)"
|
||||
, getString(occ).c_str()
|
||||
) << endl;
|
||||
return;
|
||||
}
|
||||
_childs.insert( occ );
|
||||
}
|
||||
_boundingBox.merge( boundingBox );
|
||||
}
|
||||
|
||||
void Equipotential::merge ( Equipotential* other )
|
||||
{
|
||||
if (this == other) {
|
||||
cerr << Warning( "Equipotential::merge(): Attempt to merge itself (ignored).\n"
|
||||
" (on: %s)"
|
||||
, getString(this).c_str()
|
||||
) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for ( auto otherNetData : other->_nets ) {
|
||||
NetMap::iterator inet = _nets.find( otherNetData.first );
|
||||
if (inet != _nets.end()) {
|
||||
//inet->second.first += otherNetData.second.first;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (otherNetData.first->isFused()) _hasFused = true;
|
||||
_nets.insert( make_pair( otherNetData.first, make_pair(0,otherNetData.second.second) ));
|
||||
|
||||
if (_nets.size() > 1 + ((_hasFused) ? 1 : 0)) {
|
||||
cdebug_log(169,0) << "Short by merging equis." << _nets.size() << endl;
|
||||
for ( auto inet : _nets ) {
|
||||
cdebug_log(169,0) << "this | " << inet.first << endl;
|
||||
}
|
||||
for ( auto inet : other->_nets ) {
|
||||
cdebug_log(169,0) << "other | " << inet.first << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//cerr << "Equipotential::merge() " << this << endl;
|
||||
//cerr << " " << other << endl;
|
||||
for ( const Occurrence& component : other->getComponents () ) add( component );
|
||||
for ( const Occurrence& child : other->getChilds () ) add( child );
|
||||
for ( ShortCircuit* shortCircuit : other->getShortCircuits () ) add( shortCircuit );
|
||||
_boundingBox.merge( other->_boundingBox );
|
||||
//cerr << "Equipotential::merge() done" << endl;
|
||||
other->clear();
|
||||
}
|
||||
|
||||
|
||||
void Equipotential::consolidate ()
|
||||
{
|
||||
EquipotentialRelation* relation = EquipotentialRelation::create( this );
|
||||
|
||||
|
||||
for ( const Occurrence& occurrence : getComponents() ) {
|
||||
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
|
||||
if (not component) continue;
|
||||
if (not occurrence.getPath().isEmpty()) {
|
||||
//cerr << "Occurrence from a DeepNet " << occurrence << endl;
|
||||
continue;
|
||||
}
|
||||
component->put( relation );
|
||||
}
|
||||
|
||||
if (not _nets.empty()) {
|
||||
_name = getString( (*_nets.begin()).first->getName() );
|
||||
}
|
||||
|
||||
for ( auto netData : _nets ) {
|
||||
Net* net = netData.first;
|
||||
if (net->isFused()) continue;
|
||||
if (net->isExternal ()) _isExternal = true;
|
||||
if (net->isGlobal ()) _isGlobal = true;
|
||||
if (net->isAutomatic()) _isAutomatic = true;
|
||||
_type = net->getType();
|
||||
_direction |= net->getDirection();
|
||||
|
||||
if (netData.second.first >= netData.second.second) {
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
if (dynamic_cast<Plug*>(component)) continue;
|
||||
component->remove( relation );
|
||||
}
|
||||
net->put( relation );
|
||||
}
|
||||
cdebug_log(169,0) << netData.first << " [" << netData.second.first
|
||||
<< " / " << netData.second.second << "]" << endl;
|
||||
}
|
||||
|
||||
for ( Occurrence childEqui : _childs ) {
|
||||
childEqui.put( relation );
|
||||
}
|
||||
if (_components.empty() and _nets.empty()) _isBuried = true;
|
||||
|
||||
#if FIRST_IMPLEMENTATION
|
||||
EquipotentialRelation* relation = EquipotentialRelation::create( this );
|
||||
map<Net*,uint32_t,NetCompareByName> nets;
|
||||
set<Occurrence,OccNetCompareByName> deepNets;
|
||||
for ( const Occurrence& occurrence : getComponents() ) {
|
||||
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
|
||||
if (not component) continue;
|
||||
if (not occurrence.getPath().isEmpty()) {
|
||||
deepNets.insert( Occurrence( component->getNet(), occurrence.getPath() ));
|
||||
continue;
|
||||
}
|
||||
component->put( relation );
|
||||
Net* net = component->getNet();
|
||||
if (net->isFused()) _hasFused = true;
|
||||
else {
|
||||
if (net->isExternal ()) _isExternal = true;
|
||||
if (net->isGlobal ()) _isGlobal = true;
|
||||
if (net->isAutomatic()) _isAutomatic = true;
|
||||
_type = net->getType();
|
||||
_direction |= net->getDirection();
|
||||
}
|
||||
uint32_t accounted = (dynamic_cast<Plug*>(component)) ? 0 : 1;
|
||||
auto inet = nets.find( component->getNet() );
|
||||
if (inet != nets.end())
|
||||
inet->second += accounted;
|
||||
else
|
||||
nets.insert( make_pair( component->getNet(), accounted ) );
|
||||
}
|
||||
if (not nets.empty()) {
|
||||
_name = getString( (*nets.begin()).first->getName() );
|
||||
} else {
|
||||
if (not deepNets.empty()) {
|
||||
_name = (*deepNets.begin()).getCompactString();
|
||||
}
|
||||
}
|
||||
_netCount = nets.size();
|
||||
|
||||
for ( auto item : nets ) {
|
||||
Net* net = item.first;
|
||||
uint32_t count = 0;
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
count += (dynamic_cast<Plug*>(component)) ? 0 : 1;
|
||||
}
|
||||
if (count > item.second) continue;
|
||||
if (count < item.second) {
|
||||
cerr << Error( "Equipotential::consolidate(): On %s, found more components of %s than existing (%d > %d)."
|
||||
, getString(this).c_str()
|
||||
, getString(net).c_str()
|
||||
, item.second
|
||||
, count ) << endl;
|
||||
}
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
if (dynamic_cast<Plug*>(component)) continue;
|
||||
component->remove( relation );
|
||||
}
|
||||
net->put( relation );
|
||||
//_nets.insert( net );
|
||||
}
|
||||
for ( Occurrence childEqui : _childs ) {
|
||||
childEqui.put( relation );
|
||||
}
|
||||
if (_components.empty() and _nets.empty()) _isBuried = true;
|
||||
|
||||
// if (_name == "abc_11873_auto_rtlil_cc_2560_muxgate_11612")
|
||||
// show();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Equipotential::clear ()
|
||||
{
|
||||
_components .clear();
|
||||
_childs .clear();
|
||||
_nets .clear();
|
||||
_shortCircuits.clear();
|
||||
}
|
||||
|
||||
|
||||
void Equipotential::show () const
|
||||
{
|
||||
cerr << this << endl;
|
||||
cerr << "+ Components:" << endl;
|
||||
for ( const Occurrence& component : _components ) {
|
||||
cerr << "| " << component << endl;
|
||||
}
|
||||
cerr << "+ Occurrences:" << endl;
|
||||
for ( Occurrence occ : _childs ) {
|
||||
cerr << "| " << occ << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string Equipotential::getFlagsAsString () const
|
||||
{
|
||||
string sflags;
|
||||
sflags += ((_isExternal ) ? "e" : "-");
|
||||
sflags += ((_isGlobal ) ? "g" : "-");
|
||||
sflags += ((_isAutomatic) ? "a" : "-");
|
||||
sflags += ((_isBuried ) ? "B" : "-");
|
||||
sflags += " [N:" + getString( _nets.size() - ((_hasFused) ? 1 : 0) );
|
||||
sflags += "+E:" + getString( _childs.size() );
|
||||
if (_hasFused)
|
||||
sflags += "+fused";
|
||||
sflags += "] ";
|
||||
return sflags;
|
||||
}
|
||||
|
||||
|
||||
string Equipotential::_getTypeName () const
|
||||
{ return "Tramontana::Equipotential"; }
|
||||
|
||||
|
||||
string Equipotential::_getString () const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "<Equipotential id:" << getId() << " "
|
||||
<< getFlagsAsString()
|
||||
<< " " << getName()
|
||||
<< " " << getType()
|
||||
<< " " << getDirection()
|
||||
<< ">";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
||||
Record* Equipotential::_getRecord () const
|
||||
{
|
||||
Record* record = Super::_getRecord();
|
||||
if (record) {
|
||||
record->add( getSlot( "_name" , &_name ) );
|
||||
record->add( getSlot( "_boundingBox", &_boundingBox ) );
|
||||
//record->add( getSlot( "_nets" , &_nets ) );
|
||||
record->add( getSlot( "_components" , &_components ) );
|
||||
record->add( getSlot( "_childs" , &_childs ) );
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // Tramontana namespace.
|
|
@ -0,0 +1,245 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./EquipotentialComponents.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "hurricane/Error.h"
|
||||
#include "tramontana/EquipotentialComponents.h"
|
||||
#include "tramontana/Equipotential.h"
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Path;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tramontana::EquipotentialComponents".
|
||||
|
||||
EquipotentialComponents::EquipotentialComponents ()
|
||||
: Super()
|
||||
, _equipotential(nullptr)
|
||||
{ }
|
||||
|
||||
|
||||
EquipotentialComponents::EquipotentialComponents ( const Equipotential* equi )
|
||||
: Super()
|
||||
, _equipotential(equi)
|
||||
{ }
|
||||
|
||||
|
||||
EquipotentialComponents::EquipotentialComponents ( const EquipotentialComponents& other )
|
||||
: Super()
|
||||
, _equipotential(other._equipotential)
|
||||
{ }
|
||||
|
||||
|
||||
EquipotentialComponents& EquipotentialComponents::operator= ( const EquipotentialComponents& other )
|
||||
{
|
||||
_equipotential = other._equipotential;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Collection<Occurrence>* EquipotentialComponents::getClone () const
|
||||
{ return new EquipotentialComponents( *this ); }
|
||||
|
||||
|
||||
Locator<Occurrence>* EquipotentialComponents::getLocator () const
|
||||
{ return new Locator ( _equipotential ); }
|
||||
|
||||
|
||||
string EquipotentialComponents::_getString () const
|
||||
{
|
||||
string s = "<EquipotentialComponents ";
|
||||
if (_equipotential) {
|
||||
s += " " + getString( _equipotential );
|
||||
} else {
|
||||
s += " NULL";
|
||||
}
|
||||
s += ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tramontana::EquipotentialComponents::Locator".
|
||||
|
||||
|
||||
EquipotentialComponents::Locator::Locator ()
|
||||
: Super()
|
||||
, _equipotential (nullptr)
|
||||
, _state (Constructed)
|
||||
, _componentsIterator()
|
||||
, _netsIterator ()
|
||||
, _childsIterator ()
|
||||
, _childCompsLocator (nullptr)
|
||||
, _componentsLocator (nullptr)
|
||||
{ }
|
||||
|
||||
|
||||
EquipotentialComponents::Locator::Locator ( const Equipotential* equi )
|
||||
: Super()
|
||||
, _equipotential (equi)
|
||||
, _state (Constructed)
|
||||
, _componentsIterator(equi->getComponents().end())
|
||||
, _netsIterator (equi->getNets().end())
|
||||
, _childsIterator (equi->getChilds().end())
|
||||
, _childCompsLocator (nullptr)
|
||||
, _componentsLocator (nullptr)
|
||||
{
|
||||
progress();
|
||||
}
|
||||
|
||||
|
||||
EquipotentialComponents::Locator::Locator ( const Locator& other )
|
||||
: Super()
|
||||
, _equipotential (other._equipotential)
|
||||
, _state (other._state)
|
||||
, _componentsIterator(other._componentsIterator)
|
||||
, _netsIterator (other._netsIterator)
|
||||
, _childsIterator (other._childsIterator)
|
||||
, _childCompsLocator (nullptr)
|
||||
, _componentsLocator (nullptr)
|
||||
{
|
||||
if (other._childCompsLocator) _childCompsLocator = other._childCompsLocator->getClone();
|
||||
if (other._componentsLocator) _componentsLocator = other._componentsLocator->getClone();
|
||||
}
|
||||
|
||||
|
||||
EquipotentialComponents::Locator& EquipotentialComponents::Locator::operator= ( const Locator& other )
|
||||
{
|
||||
_equipotential = other._equipotential;
|
||||
_state = other._state;
|
||||
_componentsIterator= other._componentsIterator;
|
||||
_netsIterator = other._netsIterator;
|
||||
_childsIterator = other._childsIterator;
|
||||
_componentsLocator = (other._componentsLocator) ? other._componentsLocator->getClone() : nullptr;
|
||||
_childCompsLocator = (other._childCompsLocator) ? other._childCompsLocator->getClone() : nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Occurrence EquipotentialComponents::Locator::getElement () const
|
||||
{
|
||||
if (not _equipotential or (_state >= Finished)) return Occurrence();
|
||||
switch ( _state ) {
|
||||
case InComponents: return (*_componentsIterator);
|
||||
case InNets: return Occurrence( _componentsLocator->getElement() );
|
||||
case InChildEquis: {
|
||||
Path compPath = (*_childsIterator).getPath();
|
||||
Path tailPath = _childCompsLocator->getElement().getPath();
|
||||
while ( not tailPath.isEmpty() ) {
|
||||
compPath = Path( compPath, tailPath.getHeadInstance() );
|
||||
tailPath = tailPath.getTailPath();
|
||||
}
|
||||
return Occurrence( _childCompsLocator->getElement().getEntity(), compPath );
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Occurrence();
|
||||
}
|
||||
|
||||
|
||||
Locator<Occurrence>* EquipotentialComponents::Locator::getClone () const
|
||||
{ return new Locator( *this ); }
|
||||
|
||||
|
||||
bool EquipotentialComponents::Locator::isValid () const
|
||||
{ return (_equipotential) and (_state < Finished); }
|
||||
|
||||
|
||||
void EquipotentialComponents::Locator::progress ()
|
||||
{
|
||||
while ( isValid() ) {
|
||||
switch ( _state ) {
|
||||
case Constructed: {
|
||||
_state = InComponents;
|
||||
_componentsIterator = _equipotential->getComponents().begin();
|
||||
if (_componentsIterator != _equipotential->getComponents().end()) return;
|
||||
}
|
||||
case InComponents: {
|
||||
if (_componentsIterator != _equipotential->getComponents().end()) {
|
||||
++_componentsIterator;
|
||||
if (_componentsIterator != _equipotential->getComponents().end()) return;
|
||||
}
|
||||
_state = InNets;
|
||||
_netsIterator = _equipotential->getNets().begin();
|
||||
}
|
||||
case InNets: {
|
||||
if (_netsIterator != _equipotential->getNets().end()) {
|
||||
if ( not _netsIterator->first->isFused()
|
||||
and _netsIterator->first->getProperty(EquipotentialRelation::staticGetName())) {
|
||||
if (not _componentsLocator) {
|
||||
_componentsLocator = _netsIterator->first->getComponents().getLocator()->getClone();
|
||||
if (_componentsLocator->isValid()) return;
|
||||
} else {
|
||||
_componentsLocator->progress();
|
||||
if (_componentsLocator->isValid()) return;
|
||||
}
|
||||
}
|
||||
|
||||
_componentsLocator = nullptr;
|
||||
++_netsIterator;
|
||||
if (_netsIterator != _equipotential->getNets().end())
|
||||
continue;
|
||||
}
|
||||
_state = InChildEquis;
|
||||
_childsIterator = _equipotential->getChilds().begin();
|
||||
}
|
||||
case InChildEquis: {
|
||||
if (_childsIterator != _equipotential->getChilds().end()) {
|
||||
if (not _childCompsLocator) {
|
||||
Equipotential* child = dynamic_cast<Equipotential*>( (*_childsIterator).getEntity() );
|
||||
_childCompsLocator = child->getFlatComponents().getLocator()->getClone();
|
||||
if (_childCompsLocator->isValid()) return;
|
||||
} else {
|
||||
_childCompsLocator->progress();
|
||||
if (_childCompsLocator->isValid()) return;
|
||||
}
|
||||
|
||||
_childCompsLocator = nullptr;
|
||||
++_childsIterator;
|
||||
if (_childsIterator != _equipotential->getChilds().end())
|
||||
continue;
|
||||
}
|
||||
_state = Finished;
|
||||
}
|
||||
case Finished:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string EquipotentialComponents::Locator::_getString () const
|
||||
{
|
||||
string s = "<EquipotentialComponents::Locator";
|
||||
if (_equipotential) {
|
||||
s += " " + getString(_equipotential);
|
||||
} else {
|
||||
s += " NULL";
|
||||
}
|
||||
s += ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
} // Tramontana namespace.
|
|
@ -0,0 +1,86 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./EquipotentialRelation.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "tramontana/EquipotentialRelation.h"
|
||||
#include "tramontana/TramontanaEngine.h"
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using std::string;
|
||||
using Hurricane::Property;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tramontana::EquipotentialRelation".
|
||||
|
||||
const Name EquipotentialRelationName = "EquipotentialRelation";
|
||||
|
||||
|
||||
EquipotentialRelation::EquipotentialRelation ( Equipotential* owner )
|
||||
: Super(owner)
|
||||
{ }
|
||||
|
||||
|
||||
EquipotentialRelation* EquipotentialRelation::create ( Equipotential* owner )
|
||||
{
|
||||
EquipotentialRelation* relation = new EquipotentialRelation ( owner );
|
||||
relation->_postCreate();
|
||||
return relation;
|
||||
}
|
||||
|
||||
|
||||
void EquipotentialRelation::_preDestroy ()
|
||||
{ Super::_preDestroy(); }
|
||||
|
||||
|
||||
Name EquipotentialRelation::staticGetName ()
|
||||
{ return EquipotentialRelationName; }
|
||||
|
||||
|
||||
Name EquipotentialRelation::getName () const
|
||||
{ return EquipotentialRelationName; }
|
||||
|
||||
|
||||
string EquipotentialRelation::_getTypeName () const
|
||||
{ return "EquipotentialRelation"; }
|
||||
|
||||
|
||||
Record* EquipotentialRelation::_getRecord () const
|
||||
{
|
||||
Record* record = Super::_getRecord();
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
EquipotentialRelation* EquipotentialRelation::get ( const Component* component )
|
||||
{
|
||||
if (not component) return nullptr;
|
||||
|
||||
Property* property = component->getProperty( EquipotentialRelationName );
|
||||
if (not property) return nullptr;
|
||||
|
||||
EquipotentialRelation* relation = dynamic_cast<EquipotentialRelation*>( property );
|
||||
if (not relation) return nullptr;
|
||||
return relation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // Tramontana namespace.
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./EquipotentialsModel.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <QFont>
|
||||
#include <QApplication>
|
||||
#include "hurricane/Name.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/viewer/Graphics.h"
|
||||
#include "tramontana/EquipotentialsModel.h"
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using Hurricane::Graphics;
|
||||
|
||||
|
||||
EquipotentialsModel::EquipotentialsModel ( QObject* parent )
|
||||
: QAbstractTableModel(parent)
|
||||
, _cell (nullptr)
|
||||
, _equipotentials ()
|
||||
{ }
|
||||
|
||||
|
||||
QVariant EquipotentialsModel::data ( const QModelIndex& index, int role ) const
|
||||
{
|
||||
static QFont nameFont = Graphics::getFixedFont ( QFont::Bold );
|
||||
static QFont valueFont = Graphics::getFixedFont ( QFont::Normal, true );
|
||||
|
||||
if (role == Qt::FontRole) {
|
||||
switch (index.column()) {
|
||||
case 0: return nameFont;
|
||||
default: return valueFont;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (not index.isValid()) return QVariant ();
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
Equipotential* equi = _equipotentials[ index.row() ];
|
||||
switch ( index.column() ) {
|
||||
case 0: return QString::fromStdString( equi->getName() );
|
||||
case 1: return QString::fromStdString( equi->getFlagsAsString() );
|
||||
case 2: return QString::fromStdString( getString( equi->getType() ));
|
||||
case 3: return QString::fromStdString( getString( equi->getDirection() ));
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
QVariant EquipotentialsModel::headerData ( int section
|
||||
, Qt::Orientation orientation
|
||||
, int role ) const
|
||||
{
|
||||
if (orientation == Qt::Vertical) return QVariant();
|
||||
|
||||
static QFont headerFont = Graphics::getFixedFont( QFont::Bold, false, false, +0 );
|
||||
|
||||
if (role == Qt::FontRole ) return headerFont;
|
||||
if (role != Qt::DisplayRole) return QVariant();
|
||||
if (section == 0) return QVariant( "Name" );
|
||||
if (section == 1) return QVariant( "Flags" );
|
||||
if (section == 2) return QVariant( "Type" );
|
||||
if (section == 3) return QVariant( "Direction" );
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
int EquipotentialsModel::rowCount ( const QModelIndex& parent ) const
|
||||
{ return _equipotentials.size(); }
|
||||
|
||||
|
||||
int EquipotentialsModel::columnCount ( const QModelIndex& parent ) const
|
||||
{ return 4; }
|
||||
|
||||
|
||||
const Equipotential* EquipotentialsModel::getEqui ( int row )
|
||||
{
|
||||
if (row >= (int)_equipotentials.size()) return nullptr;
|
||||
return _equipotentials[ row ];
|
||||
}
|
||||
|
||||
|
||||
void EquipotentialsModel::setCell ( Cell* cell )
|
||||
{
|
||||
if (_cell != cell) {
|
||||
emit layoutAboutToBeChanged ();
|
||||
|
||||
if (_cell) _equipotentials.clear();
|
||||
_cell = cell;
|
||||
|
||||
if (_cell) {
|
||||
TramontanaEngine* tramontana = TramontanaEngine::get( _cell );
|
||||
if (tramontana) {
|
||||
for ( Equipotential* equi : tramontana->getEquipotentials() )
|
||||
_equipotentials.push_back( equi );
|
||||
}
|
||||
}
|
||||
|
||||
emit layoutChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // Tramontana namespace.
|
|
@ -0,0 +1,269 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./EquipotentialsWidget.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <QFontMetrics>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QHeaderView>
|
||||
#include <QKeyEvent>
|
||||
#include <QGroupBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QAction>
|
||||
#include <QModelIndex>
|
||||
#include "hurricane/Commons.h"
|
||||
#include "hurricane/viewer/Graphics.h"
|
||||
#include "tramontana/EquipotentialsModel.h"
|
||||
#include "tramontana/EquipotentialsWidget.h"
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Graphics;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "BuriedFilterProxymodel".
|
||||
|
||||
|
||||
EquiFilterProxyModel::EquiFilterProxyModel ( QObject* parent )
|
||||
: Super (parent)
|
||||
, _filter(NoFilter)
|
||||
{ }
|
||||
|
||||
|
||||
void EquiFilterProxyModel::setFilter ( uint32_t filter )
|
||||
{ _filter = filter; invalidateFilter(); }
|
||||
|
||||
|
||||
bool EquiFilterProxyModel::filterAcceptsRow ( int row, const QModelIndex& index ) const
|
||||
{
|
||||
EquipotentialsModel* model = dynamic_cast<EquipotentialsModel*>( sourceModel() );
|
||||
if (not model) return true;
|
||||
|
||||
const Equipotential* equi = model->getEqui( row );
|
||||
if (not (_filter & ShowBuried) and equi->isBuried()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "EquipotentialsWidget".
|
||||
|
||||
|
||||
EquipotentialsWidget::EquipotentialsWidget ( QWidget* parent )
|
||||
: QWidget (parent)
|
||||
, _cellWidget (NULL)
|
||||
, _cell (NULL)
|
||||
, _baseModel (new EquipotentialsModel(this))
|
||||
, _sortModel (new QSortFilterProxyModel(this))
|
||||
, _filterModel (new EquiFilterProxyModel(this))
|
||||
, _view (new QTableView(this))
|
||||
, _rowHeight (20)
|
||||
, _selecteds ()
|
||||
, _forceReselect(false)
|
||||
{
|
||||
setAttribute( Qt::WA_DeleteOnClose );
|
||||
setAttribute( Qt::WA_QuitOnClose, false );
|
||||
setContextMenuPolicy( Qt::ActionsContextMenu );
|
||||
|
||||
_rowHeight = QFontMetrics( Graphics::getFixedFont() ).height() + 4;
|
||||
|
||||
_filterModel->setSourceModel ( _baseModel );
|
||||
//_filterModel->setFilter ( EquiFilterProxyModel::ShowBuried );
|
||||
_sortModel->setSourceModel ( _filterModel );
|
||||
_sortModel->setDynamicSortFilter( true );
|
||||
_sortModel->setFilterKeyColumn ( 0 );
|
||||
|
||||
_view->setShowGrid ( false );
|
||||
_view->setAlternatingRowColors( true );
|
||||
_view->setSelectionBehavior ( QAbstractItemView::SelectRows );
|
||||
_view->setSortingEnabled ( true );
|
||||
_view->setModel ( _sortModel );
|
||||
|
||||
QHeaderView* horizontalHeader = _view->horizontalHeader();
|
||||
horizontalHeader->setDefaultAlignment ( Qt::AlignHCenter );
|
||||
horizontalHeader->setMinimumSectionSize( (Graphics::isHighDpi()) ? 150 : 75 );
|
||||
horizontalHeader->setStretchLastSection( true );
|
||||
|
||||
QHeaderView* verticalHeader = _view->verticalHeader();
|
||||
verticalHeader->setVisible( false );
|
||||
verticalHeader->setDefaultSectionSize( _rowHeight );
|
||||
|
||||
// verticalHeader->setStyleSheet( "QHeaderView::section {"
|
||||
// "padding-bottom: 0px;"
|
||||
// "padding-top: 0px;"
|
||||
// "padding-left: 0px;"
|
||||
// "padding-right: 1px;"
|
||||
// "margin: 0px;"
|
||||
// "}"
|
||||
// );
|
||||
|
||||
_filterPatternLineEdit = new QLineEdit( this );
|
||||
QLabel* filterPatternLabel = new QLabel( tr("&Filter pattern:"), this );
|
||||
filterPatternLabel->setBuddy( _filterPatternLineEdit );
|
||||
|
||||
QGridLayout* gLayout = new QGridLayout();
|
||||
gLayout->addWidget( _view , 1, 0, 1, 2 );
|
||||
gLayout->addWidget( filterPatternLabel , 2, 0 );
|
||||
gLayout->addWidget( _filterPatternLineEdit, 2, 1 );
|
||||
|
||||
setLayout( gLayout );
|
||||
|
||||
QAction* fitAction = new QAction( tr("&Fit to Equi"), this );
|
||||
fitAction->setShortcut ( QKeySequence(tr("CTRL+F")) );
|
||||
fitAction->setStatusTip( tr("Fit the view to the Equipotentials's bounding box") );
|
||||
addAction( fitAction );
|
||||
|
||||
connect( _filterPatternLineEdit , SIGNAL(textChanged(const QString &))
|
||||
, this , SLOT (textFilterChanged()) );
|
||||
connect( _view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&))
|
||||
, this , SLOT (updateSelecteds (const QItemSelection&,const QItemSelection&)) );
|
||||
connect( fitAction, SIGNAL(triggered()), this, SLOT(fitToEqui()) );
|
||||
|
||||
resize( 300, 300 );
|
||||
}
|
||||
|
||||
|
||||
QModelIndex EquipotentialsWidget::mapToSource ( QModelIndex viewIndex ) const
|
||||
{ return _filterModel->mapToSource( _sortModel->mapToSource( viewIndex )); }
|
||||
|
||||
|
||||
void EquipotentialsWidget::setShowBuried ( bool state )
|
||||
{
|
||||
_filterModel->setFilter( (state) ? EquiFilterProxyModel::ShowBuried
|
||||
: EquiFilterProxyModel::NoFilter );
|
||||
}
|
||||
|
||||
|
||||
void EquipotentialsWidget::goTo ( int delta )
|
||||
{
|
||||
if ( delta == 0 ) return;
|
||||
|
||||
QModelIndex newIndex = _sortModel->index( _view->currentIndex().row()+delta, 0, QModelIndex() );
|
||||
if (newIndex.isValid())
|
||||
_view->selectRow( newIndex.row() );
|
||||
}
|
||||
|
||||
|
||||
void EquipotentialsWidget::updateSelecteds ()
|
||||
{
|
||||
_forceReselect = true;
|
||||
|
||||
QItemSelection dummy;
|
||||
updateSelecteds( dummy, dummy );
|
||||
}
|
||||
|
||||
|
||||
void EquipotentialsWidget::updateSelecteds ( const QItemSelection& , const QItemSelection& )
|
||||
{
|
||||
if (_cellWidget) _cellWidget->openRefreshSession ();
|
||||
|
||||
_selecteds.resetAccesses ();
|
||||
|
||||
const Equipotential* equi = nullptr;
|
||||
QModelIndexList iList = _view->selectionModel()->selectedRows();
|
||||
for ( int i=0 ; i<iList.size() ; i++ ) {
|
||||
equi = _baseModel->getEqui( mapToSource(iList[i]).row() );
|
||||
if ( equi )
|
||||
_selecteds.insert( equi );
|
||||
}
|
||||
|
||||
if (_forceReselect) {
|
||||
_selecteds.forceInserteds();
|
||||
_forceReselect = false;
|
||||
}
|
||||
|
||||
SelectedEquiSet::iterator isel = _selecteds.begin ();
|
||||
while ( isel != _selecteds.end() ) {
|
||||
SelectedEquiSet::iterator remove = isel++;
|
||||
if (remove->getAccesses() == 0) {
|
||||
emit equipotentialUnselect ( remove->getEqui()->getFlatComponents() );
|
||||
_selecteds.erase( remove );
|
||||
}
|
||||
}
|
||||
isel = _selecteds.begin ();
|
||||
while ( isel != _selecteds.end() ) {
|
||||
if (isel->getAccesses() == 64) {
|
||||
emit equipotentialSelect ( isel->getEqui()->getFlatComponents() );
|
||||
}
|
||||
++isel;
|
||||
}
|
||||
isel = _selecteds.begin ();
|
||||
|
||||
if (_cellWidget) _cellWidget->closeRefreshSession ();
|
||||
}
|
||||
|
||||
|
||||
void EquipotentialsWidget::textFilterChanged ()
|
||||
{
|
||||
_sortModel->setFilterRegExp( _filterPatternLineEdit->text() );
|
||||
//updateSelecteds ();
|
||||
}
|
||||
|
||||
|
||||
void EquipotentialsWidget::fitToEqui ()
|
||||
{
|
||||
const Equipotential* equi = _baseModel->getEqui( mapToSource(_view->currentIndex()).row() );
|
||||
if (equi) emit reframe ( equi->getBoundingBox() );
|
||||
}
|
||||
|
||||
|
||||
void EquipotentialsWidget::setCellWidget ( CellWidget* cw )
|
||||
{
|
||||
if (_cellWidget) {
|
||||
disconnect( this, 0, _cellWidget, 0 );
|
||||
}
|
||||
|
||||
_cellWidget = cw;
|
||||
if (_cellWidget) {
|
||||
setCell( _cellWidget->getCell() );
|
||||
connect( this, SIGNAL( reframe(const Box&) ), _cellWidget, SLOT( reframe(const Box&) ));
|
||||
} else
|
||||
setCell( nullptr );
|
||||
}
|
||||
|
||||
|
||||
void EquipotentialsWidget::setCell ( Cell* cell )
|
||||
{
|
||||
_cell = cell;
|
||||
_view->setVisible( false );
|
||||
_view->selectionModel()->clear();
|
||||
_baseModel->setCell( cell );
|
||||
|
||||
string windowTitle = "Equis" + getString(cell);
|
||||
setWindowTitle( tr(windowTitle.c_str()) );
|
||||
|
||||
QHeaderView* header = _view->horizontalHeader();
|
||||
|
||||
_view->selectRow( 0 );
|
||||
for ( int i=0 ; i<_baseModel->columnCount() ; ++i ) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
header->setSectionResizeMode( i, QHeaderView::Interactive );
|
||||
#else
|
||||
header->setResizeMode( i, QHeaderView::Interactive );
|
||||
#endif
|
||||
_view->resizeColumnToContents( i );
|
||||
}
|
||||
_view->setVisible( true );
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./GraphicTramontanaEngine.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QApplication>
|
||||
#include <hurricane/Warning.h>
|
||||
#include <hurricane/Error.h>
|
||||
#include <hurricane/Breakpoint.h>
|
||||
#include <hurricane/DebugSession.h>
|
||||
#include <hurricane/Go.h>
|
||||
#include <hurricane/Net.h>
|
||||
#include <hurricane/Cell.h>
|
||||
#include <hurricane/viewer/Graphics.h>
|
||||
#include <hurricane/viewer/CellWidget.h>
|
||||
#include <hurricane/viewer/CellViewer.h>
|
||||
#include <hurricane/viewer/ControllerWidget.h>
|
||||
#include <hurricane/viewer/ExceptionWidget.h>
|
||||
#include <crlcore/Utilities.h>
|
||||
#include <crlcore/AllianceFramework.h>
|
||||
#include <anabatic/GCell.h>
|
||||
#include <tramontana/TabEquipotentials.h>
|
||||
#include <tramontana/GraphicTramontanaEngine.h>
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Exception;
|
||||
using Hurricane::Breakpoint;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::Point;
|
||||
using Hurricane::Entity;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Graphics;
|
||||
using Hurricane::ColorScale;
|
||||
using Hurricane::DisplayStyle;
|
||||
using Hurricane::ControllerWidget;
|
||||
using Hurricane::ExceptionWidget;
|
||||
using CRL::Catalog;
|
||||
using CRL::AllianceFramework;
|
||||
|
||||
|
||||
size_t GraphicTramontanaEngine::_references = 0;
|
||||
GraphicTramontanaEngine* GraphicTramontanaEngine::_singleton = NULL;
|
||||
|
||||
|
||||
#if THIS_IS_DISABLED
|
||||
void GraphicTramontanaEngine::initGCell ( CellWidget* widget )
|
||||
{
|
||||
widget->getDrawingPlanes().setPen( Qt::NoPen );
|
||||
TramontanaEngine* tramontana = TramontanaEngine::get( widget->getCell() );
|
||||
if (tramontana) tramontana->setDensityMode( GCell::MaxDensity );
|
||||
}
|
||||
|
||||
|
||||
void GraphicTramontanaEngine::drawGCell ( CellWidget* widget
|
||||
, const Go* go
|
||||
, const BasicLayer* basicLayer
|
||||
, const Box& box
|
||||
, const Transformation& transformation
|
||||
)
|
||||
{
|
||||
const GCell* gcell = static_cast<const GCell*>(go);
|
||||
|
||||
QPainter& painter = widget->getPainter();
|
||||
QPen pen = Graphics::getPen ("Anabatic::GCell",widget->getDarkening());
|
||||
Box bb = gcell->getBoundingBox();
|
||||
QRect pixelBb = widget->dbuToScreenRect(bb);
|
||||
|
||||
if (GCell::getDisplayMode() == GCell::Density) {
|
||||
uint32_t density = (unsigned int)( 255.0 * gcell->getDensity() );
|
||||
if (density > 255) density = 255;
|
||||
|
||||
painter.setBrush( Graphics::getColorScale( ColorScale::Fire ).getBrush( density, widget->getDarkening() ) );
|
||||
painter.drawRect( pixelBb );
|
||||
} else {
|
||||
int fontScale = 0;
|
||||
int halfHeight = 20;
|
||||
int halfWidth = 80;
|
||||
if (widget->isPrinter()) {
|
||||
fontScale = -5;
|
||||
halfHeight = 9;
|
||||
halfWidth = 39;
|
||||
}
|
||||
|
||||
painter.setPen ( pen );
|
||||
painter.setBrush( Graphics::getBrush("Anabatic::GCell",widget->getDarkening()) );
|
||||
painter.drawRect( pixelBb );
|
||||
|
||||
if ( (pixelBb.width() > 2*halfWidth) and (pixelBb.height() > 2*halfHeight) ) {
|
||||
QString text = QString("%1").arg(gcell->getId());
|
||||
QFont font = Graphics::getFixedFont( QFont::Normal, false, false, fontScale );
|
||||
painter.setFont(font);
|
||||
|
||||
pen.setWidth( 1 );
|
||||
painter.setPen( pen );
|
||||
|
||||
painter.save ();
|
||||
painter.translate( widget->dbuToScreenPoint(bb.getCenter().getX(), bb.getCenter().getY()) );
|
||||
painter.drawRect ( QRect( -halfWidth, -halfHeight, 2*halfWidth, 2*halfHeight ) );
|
||||
painter.drawText ( QRect( -halfWidth, -halfHeight, 2*halfWidth, 2*halfHeight )
|
||||
, text
|
||||
, QTextOption(Qt::AlignCenter)
|
||||
);
|
||||
painter.restore ();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
TramontanaEngine* GraphicTramontanaEngine::createEngine ()
|
||||
{
|
||||
Cell* cell = getCell ();
|
||||
|
||||
TramontanaEngine* tramontana = TramontanaEngine::get( cell );
|
||||
if (not tramontana) {
|
||||
tramontana = TramontanaEngine::create( cell );
|
||||
tramontana->setViewer( _viewer );
|
||||
} else
|
||||
cerr << Warning( "%s already has a Tramontana engine.", getString(cell).c_str() ) << endl;
|
||||
|
||||
return tramontana;
|
||||
}
|
||||
|
||||
|
||||
TramontanaEngine* GraphicTramontanaEngine::getForFramework ( uint32_t flags )
|
||||
{
|
||||
// Currently, only one framework is avalaible: Alliance.
|
||||
|
||||
TramontanaEngine* tramontana = TramontanaEngine::get( getCell() );
|
||||
if (tramontana) return tramontana;
|
||||
|
||||
if (flags & CreateEngine) {
|
||||
tramontana = createEngine();
|
||||
if (not tramontana)
|
||||
throw Error( "Failed to create Tramontana engine on %s.", getString(getCell()).c_str() );
|
||||
} else {
|
||||
throw Error( "TramontanaEngine not created yet, run the global router first." );
|
||||
}
|
||||
|
||||
return tramontana;
|
||||
}
|
||||
|
||||
|
||||
void GraphicTramontanaEngine::_extract ()
|
||||
{
|
||||
TramontanaEngine* tramontana = getForFramework( CreateEngine );
|
||||
tramontana->extract();
|
||||
|
||||
//Breakpoint::stop( 0, "GraphicTramontanaEngine::_extract() done." );
|
||||
}
|
||||
|
||||
|
||||
void GraphicTramontanaEngine::addToMenu ( CellViewer* viewer )
|
||||
{
|
||||
assert(_viewer == NULL);
|
||||
|
||||
_viewer = viewer;
|
||||
|
||||
if (_viewer->hasMenuAction("tools.extract")) {
|
||||
cerr << Warning( "GraphicTramontanaEngine::addToMenu() - Tramontana extractor already hooked in." ) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
_viewer->addToMenu( "tools.extract"
|
||||
, "E&xtract . . . . . [Tramontana]"
|
||||
, "Run the extractor"
|
||||
, std::bind(&GraphicTramontanaEngine::_extract,this)
|
||||
);
|
||||
|
||||
ControllerWidget* controller = viewer->getControllerWidget();
|
||||
if (controller) {
|
||||
TabEquipotentials* tabEqui = new TabEquipotentials ();
|
||||
tabEqui->setObjectName( "controller.tabEquipotentials" );
|
||||
tabEqui->setCellWidget( viewer->getCellWidget() );
|
||||
controller->insertTabAfter( "controller.tabNetlist", tabEqui, "Equipotentials" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Name& GraphicTramontanaEngine::getName () const
|
||||
{ return TramontanaEngine::staticGetName(); }
|
||||
|
||||
|
||||
Cell* GraphicTramontanaEngine::getCell ()
|
||||
{
|
||||
if (not _viewer) {
|
||||
throw Error( "<b>Tramontana:</b> GraphicTramontanaEngine not bound to any Viewer." );
|
||||
return NULL;
|
||||
}
|
||||
if (not _viewer->getCell()) {
|
||||
throw Error( "<b>Tramontana:</b> No Cell is loaded into the Viewer." );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _viewer->getCell();
|
||||
}
|
||||
|
||||
|
||||
GraphicTramontanaEngine* GraphicTramontanaEngine::grab ()
|
||||
{
|
||||
if (not _references) {
|
||||
_singleton = new GraphicTramontanaEngine ();
|
||||
}
|
||||
_references++;
|
||||
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
|
||||
size_t GraphicTramontanaEngine::release ()
|
||||
{
|
||||
--_references;
|
||||
if (not _references) {
|
||||
delete _singleton;
|
||||
_singleton = NULL;
|
||||
}
|
||||
return _references;
|
||||
}
|
||||
|
||||
|
||||
GraphicTramontanaEngine::GraphicTramontanaEngine ()
|
||||
: GraphicTool()
|
||||
, _viewer (NULL)
|
||||
{
|
||||
#if THIS_IS_DISABLED
|
||||
addDrawGo( "Anabatic::GCell", initGCell, drawGCell );
|
||||
addDrawGo( "Anabatic::Edge" , initEdge , drawEdge );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
GraphicTramontanaEngine::~GraphicTramontanaEngine ()
|
||||
{ }
|
||||
|
||||
|
||||
} // Tramontana namespace.
|
|
@ -0,0 +1,113 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./PyGraphicTramontanaEngine.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "tramontana/PyGraphicTramontanaEngine.h"
|
||||
#include "hurricane/isobar/PyCell.h"
|
||||
#include "hurricane/Cell.h"
|
||||
|
||||
|
||||
#undef ACCESS_OBJECT
|
||||
#undef ACCESS_CLASS
|
||||
#define ACCESS_OBJECT _baseObject._object
|
||||
#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject)
|
||||
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(GraphicTramontanaEngine,gtool,function)
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using namespace Hurricane;
|
||||
using namespace Isobar;
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyGraphicTramontanaEngine" Python Module Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
#if defined(__PYTHON_MODULE__)
|
||||
|
||||
|
||||
static PyObject* PyGraphicTramontanaEngine_grab ( PyObject* )
|
||||
{
|
||||
cdebug_log(40,0) << "PyGraphicTramontanaEngine_grab()" << endl;
|
||||
PyGraphicTramontanaEngine* pyGraphicTramontanaEngine = NULL;
|
||||
HTRY
|
||||
pyGraphicTramontanaEngine = PyObject_NEW ( PyGraphicTramontanaEngine, &PyTypeGraphicTramontanaEngine );
|
||||
if ( pyGraphicTramontanaEngine == NULL ) return NULL;
|
||||
pyGraphicTramontanaEngine->ACCESS_OBJECT = GraphicTramontanaEngine::grab();
|
||||
HCATCH
|
||||
return (PyObject*)pyGraphicTramontanaEngine;
|
||||
}
|
||||
|
||||
|
||||
static PyObject* PyGraphicTramontanaEngine_getCell ( PyGraphicTramontanaEngine* self )
|
||||
{
|
||||
cdebug_log(40,0) << "PyGraphicTramontanaEngine_getCell ()" << endl;
|
||||
Cell* cell = NULL;
|
||||
HTRY
|
||||
METHOD_HEAD("GraphicTramontanaEngine.getCell()")
|
||||
cell = gtool->getCell ();
|
||||
HCATCH
|
||||
if (cell == NULL) Py_RETURN_NONE;
|
||||
return PyCell_Link(cell);
|
||||
}
|
||||
|
||||
|
||||
GetNameMethod(GraphicTramontanaEngine, gtool)
|
||||
|
||||
// Standart destroy (Attribute).
|
||||
|
||||
|
||||
PyMethodDef PyGraphicTramontanaEngine_Methods[] =
|
||||
{ { "grab" , (PyCFunction)PyGraphicTramontanaEngine_grab , METH_NOARGS|METH_STATIC
|
||||
, "Returns the GraphicTramontanaEngine singleton." }
|
||||
, { "getName" , (PyCFunction)PyGraphicTramontanaEngine_getName , METH_NOARGS
|
||||
, "Returns the name of the GraphicTramontanaEngine (class attribute)." }
|
||||
, { "getCell" , (PyCFunction)PyGraphicTramontanaEngine_getCell , METH_NOARGS
|
||||
, "Returns the Cell on which this GraphicTramontanaEngine is attached." }
|
||||
, {NULL, NULL, 0, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// PyGraphicTramontanaEngine Type Methods.
|
||||
|
||||
|
||||
PythonOnlyDeleteMethod(GraphicTramontanaEngine)
|
||||
PyTypeObjectLinkPyType(GraphicTramontanaEngine)
|
||||
|
||||
|
||||
#else // End of Python Module Code Part.
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyGraphicTramontanaEngine" Shared Library Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
// Link/Creation Method.
|
||||
LinkCreateMethod(GraphicTramontanaEngine)
|
||||
|
||||
PyTypeInheritedObjectDefinitions(GraphicTramontanaEngine,GraphicTool)
|
||||
|
||||
|
||||
#endif // End of Shared Library Code Part.
|
||||
|
||||
} // extern "C".
|
||||
|
||||
} // CRL namespace.
|
|
@ -0,0 +1,107 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./PyTramontana.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "hurricane/isobar/PyHurricane.h"
|
||||
#include "hurricane/isobar/PyCell.h"
|
||||
#include "tramontana/PyTramontanaEngine.h"
|
||||
#include "tramontana/PyGraphicTramontanaEngine.h"
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using Hurricane::tab;
|
||||
using Isobar::getPyHash;
|
||||
using Isobar::__cs;
|
||||
using CRL::PyTypeToolEngine;
|
||||
using CRL::PyTypeGraphicTool;
|
||||
|
||||
|
||||
#if !defined(__PYTHON_MODULE__)
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyTramontana" Shared Library Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
|
||||
# else // End of PyHurricane Shared Library Code Part.
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyTramontana" Python Module Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
static PyMethodDef PyTramontana_Methods[] =
|
||||
{ {NULL, NULL, 0, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
static PyModuleDef PyTramontana_ModuleDef =
|
||||
{ PyModuleDef_HEAD_INIT
|
||||
, .m_name = "Tramontana"
|
||||
, .m_doc = "Layout extractor & LVX."
|
||||
, .m_size = -1
|
||||
, .m_methods = PyTramontana_Methods
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Module Initialization : "PyInit_Tramontana ()"
|
||||
|
||||
PyMODINIT_FUNC PyInit_Tramontana ( void )
|
||||
{
|
||||
cdebug_log(40,0) << "PyInit_Tramontana()" << endl;
|
||||
|
||||
PyTramontanaEngine_LinkPyType();
|
||||
PyGraphicTramontanaEngine_LinkPyType();
|
||||
|
||||
PYTYPE_READY_SUB( TramontanaEngine , ToolEngine );
|
||||
PYTYPE_READY_SUB( GraphicTramontanaEngine, GraphicTool );
|
||||
|
||||
|
||||
PyObject* module = PyModule_Create( &PyTramontana_ModuleDef );
|
||||
if (module == NULL) {
|
||||
cerr << "[ERROR]\n"
|
||||
<< " Failed to initialize Tramontana module." << endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF( &PyTypeTramontanaEngine );
|
||||
PyModule_AddObject( module, "TramontanaEngine", (PyObject*)&PyTypeTramontanaEngine );
|
||||
Py_INCREF( &PyTypeGraphicTramontanaEngine );
|
||||
PyModule_AddObject( module, "GraphicTramontanaEngine", (PyObject*)&PyTypeGraphicTramontanaEngine );
|
||||
|
||||
//PyTramontanaEngine_postModuleInit();
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
} // End of extern "C".
|
||||
|
||||
|
||||
#endif // End of Python Module Code Part.
|
||||
|
||||
|
||||
} // End of Tramontana namespace.
|
|
@ -0,0 +1,216 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./PyTramontanaEngine.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "hurricane/isobar/PyNet.h"
|
||||
#include "hurricane/isobar/PyCell.h"
|
||||
#include "hurricane/viewer/PyCellViewer.h"
|
||||
#include "hurricane/viewer/ExceptionWidget.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "crlcore/Utilities.h"
|
||||
#include "tramontana/PyTramontanaEngine.h"
|
||||
#include <functional>
|
||||
|
||||
# undef ACCESS_OBJECT
|
||||
# undef ACCESS_CLASS
|
||||
# define ACCESS_OBJECT _baseObject._object
|
||||
# define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject)
|
||||
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(TramontanaEngine,tramontana,function)
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::hex;
|
||||
using std::ostringstream;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::Exception;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::ExceptionWidget;
|
||||
using Isobar::__cs;
|
||||
using Isobar::Converter;
|
||||
using Isobar::ProxyProperty;
|
||||
using Isobar::ProxyError;
|
||||
using Isobar::ConstructorError;
|
||||
using Isobar::HurricaneError;
|
||||
using Isobar::HurricaneWarning;
|
||||
using Isobar::getPyHash;
|
||||
using Isobar::ParseOneArg;
|
||||
using Isobar::ParseTwoArg;
|
||||
using Isobar::PyNet;
|
||||
using Isobar::PyCell;
|
||||
using Isobar::PyCell_Link;
|
||||
using Isobar::PyCellViewer;
|
||||
using Isobar::PyTypeCellViewer;
|
||||
using CRL::PyToolEngine;
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
#if defined(__PYTHON_MODULE__)
|
||||
|
||||
|
||||
#define DirectVoidToolMethod(SELF_TYPE, SELF_OBJECT, FUNC_NAME) \
|
||||
static PyObject* Py##SELF_TYPE##_##FUNC_NAME(Py##SELF_TYPE* self) \
|
||||
{ \
|
||||
cdebug_log(40,0) << "Py" #SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
||||
HTRY \
|
||||
METHOD_HEAD(#SELF_TYPE "." #FUNC_NAME "()") \
|
||||
if (SELF_OBJECT->getViewer()) { \
|
||||
if (ExceptionWidget::catchAllWrapper( std::bind(&TramontanaEngine::FUNC_NAME,SELF_OBJECT) )) { \
|
||||
PyErr_SetString( HurricaneError, #FUNC_NAME "() has thrown an exception (C++)." ); \
|
||||
return NULL; \
|
||||
} \
|
||||
} else { \
|
||||
SELF_OBJECT->FUNC_NAME(); \
|
||||
} \
|
||||
HCATCH \
|
||||
Py_RETURN_NONE; \
|
||||
}
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyTramontanaEngine" Python Module Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
|
||||
static PyObject* PyTramontanaEngine_get ( PyObject*, PyObject* args )
|
||||
{
|
||||
cdebug_log(40,0) << "PyTramontanaEngine_get()" << endl;
|
||||
TramontanaEngine* tramontana = NULL;
|
||||
HTRY
|
||||
PyObject* arg0;
|
||||
if (not ParseOneArg("Tramontana.get", args, CELL_ARG, &arg0)) return NULL;
|
||||
tramontana = TramontanaEngine::get(PYCELL_O(arg0));
|
||||
HCATCH
|
||||
return PyTramontanaEngine_Link(tramontana);
|
||||
}
|
||||
|
||||
|
||||
static PyObject* PyTramontanaEngine_create ( PyObject*, PyObject* args )
|
||||
{
|
||||
cdebug_log(40,0) << "PyTramontanaEngine_create()" << endl;
|
||||
TramontanaEngine* tramontana = NULL;
|
||||
HTRY
|
||||
PyObject* arg0;
|
||||
if (not ParseOneArg("Tramontana.get", args, CELL_ARG, &arg0)) return NULL;
|
||||
Cell* cell = PYCELL_O(arg0);
|
||||
tramontana = TramontanaEngine::get(cell);
|
||||
if (tramontana == NULL) {
|
||||
tramontana = TramontanaEngine::create(cell);
|
||||
} else
|
||||
cerr << Warning("%s already has a Tramontana engine.",getString(cell).c_str()) << endl;
|
||||
HCATCH
|
||||
return PyTramontanaEngine_Link(tramontana);
|
||||
}
|
||||
|
||||
|
||||
static PyObject* PyTramontanaEngine_setViewer ( PyTramontanaEngine* self, PyObject* args )
|
||||
{
|
||||
cdebug_log(40,0) << "PyTramontanaEngine_setViewer ()" << endl;
|
||||
HTRY
|
||||
METHOD_HEAD( "TramontanaEngine.setViewer()" )
|
||||
PyObject* pyViewer = NULL;
|
||||
if (not PyArg_ParseTuple(args,"O:TramontanaEngine.setViewer()",&pyViewer)) {
|
||||
PyErr_SetString( ConstructorError, "Bad parameters given to TramontanaEngine.setViewer()." );
|
||||
return NULL;
|
||||
}
|
||||
if (IsPyCellViewer(pyViewer)) {
|
||||
tramontana->setViewer( PYCELLVIEWER_O(pyViewer) );
|
||||
}
|
||||
HCATCH
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyObject* PyTramontanaEngine_extract ( PyTramontanaEngine* self )
|
||||
{
|
||||
cdebug_log(40,0) << "PyTramontanaEngine_extract()" << endl;
|
||||
HTRY
|
||||
METHOD_HEAD("TramontanaEngine.extract()")
|
||||
if (tramontana->getViewer()) {
|
||||
if (ExceptionWidget::catchAllWrapper( std::bind(&TramontanaEngine::extract,tramontana) )) {
|
||||
PyErr_SetString( HurricaneError, "TramontanaEngine::extract() has thrown an exception (C++)." );
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
tramontana->extract();
|
||||
}
|
||||
HCATCH
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
// Standart Accessors (Attributes).
|
||||
|
||||
// Standart Destroy (Attribute).
|
||||
DBoDestroyAttribute(PyTramontanaEngine_destroy,PyTramontanaEngine)
|
||||
|
||||
|
||||
PyMethodDef PyTramontanaEngine_Methods[] =
|
||||
{ { "get" , (PyCFunction)PyTramontanaEngine_get , METH_VARARGS|METH_STATIC
|
||||
, "Returns the Tramontana engine attached to the Cell, None if there isnt't." }
|
||||
, { "create" , (PyCFunction)PyTramontanaEngine_create , METH_VARARGS|METH_STATIC
|
||||
, "Create a Tramontana engine on this cell." }
|
||||
, { "destroy" , (PyCFunction)PyTramontanaEngine_destroy , METH_NOARGS
|
||||
, "Destroy a Tramontana engine." }
|
||||
, { "setViewer" , (PyCFunction)PyTramontanaEngine_setViewer , METH_VARARGS
|
||||
, "Associate a Viewer to this TramontanaEngine." }
|
||||
, { "extract" , (PyCFunction)PyTramontanaEngine_extract , METH_NOARGS
|
||||
, "Perform the layout extraction." }
|
||||
, {NULL, NULL, 0, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
DBoDeleteMethod(TramontanaEngine)
|
||||
PyTypeObjectLinkPyType(TramontanaEngine)
|
||||
|
||||
|
||||
#else // End of Python Module Code Part.
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyTramontanaEngine" Shared Library Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
|
||||
// Link/Creation Method.
|
||||
PyTypeInheritedObjectDefinitions(TramontanaEngine,PyToolEngine)
|
||||
DBoLinkCreateMethod(TramontanaEngine)
|
||||
|
||||
|
||||
// extern void PyTramontanaEngine_postModuleInit ()
|
||||
// {
|
||||
// PyTramontanaFlags_postModuleInit();
|
||||
|
||||
// PyDict_SetItemString( PyTypeTramontanaEngine.tp_dict, "Flags", (PyObject*)&PyTypeTramontanaFlags );
|
||||
|
||||
// PyObject* constant = NULL;
|
||||
// LoadObjectConstant( PyTypeTramontanaEngine.tp_dict, TramontanaEngine::GlobalRoutingSuccess , "GlobalRoutingSuccess" )
|
||||
// LoadObjectConstant( PyTypeTramontanaEngine.tp_dict, TramontanaEngine::DetailedRoutingSuccess, "DetailedRoutingSuccess" )
|
||||
// }
|
||||
|
||||
|
||||
#endif // Shared Library Code Part.
|
||||
|
||||
} // extern "C".
|
||||
|
||||
} // Tramontana namespace.
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./QueryTiles.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include "tramontana/QueryTiles.h"
|
||||
#include "tramontana/SweepLine.h"
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::vector;
|
||||
|
||||
|
||||
QueryTiles::QueryTiles ( SweepLine* sweepLine )
|
||||
: Query ()
|
||||
, _sweepLine (sweepLine)
|
||||
, _goMatchCount (0)
|
||||
, _processedLayers(0)
|
||||
{
|
||||
setCell ( sweepLine->getCell() );
|
||||
setArea ( sweepLine->getCell()->getBoundingBox() );
|
||||
setFilter( Query::DoComponents|Query::DoTerminalCells );
|
||||
}
|
||||
|
||||
|
||||
void QueryTiles::setBasicLayer ( const BasicLayer* basicLayer )
|
||||
{
|
||||
_processedLayers |= basicLayer->getMask();
|
||||
Query::setBasicLayer ( basicLayer );
|
||||
}
|
||||
|
||||
|
||||
bool QueryTiles::isProcessed ( Component* component ) const
|
||||
{
|
||||
Layer::Mask fullyProcesseds = _processedLayers & ~getBasicLayer()->getMask();
|
||||
return component->getLayer()->getMask().intersect( fullyProcesseds );
|
||||
}
|
||||
|
||||
|
||||
void QueryTiles::masterCellCallback ()
|
||||
{ }
|
||||
|
||||
|
||||
void QueryTiles::rubberCallback ( Rubber* )
|
||||
{ }
|
||||
|
||||
|
||||
void QueryTiles::extensionGoCallback ( Go* )
|
||||
{ }
|
||||
|
||||
|
||||
bool QueryTiles::hasGoCallback () const
|
||||
{ return true; }
|
||||
|
||||
|
||||
void QueryTiles::goCallback ( Go* go )
|
||||
{
|
||||
Tile* rootTile = nullptr;
|
||||
Component* component = dynamic_cast<Component*>( go );
|
||||
if (not component) return;
|
||||
if (isProcessed(component)) return;
|
||||
Occurrence occurrence = Occurrence( go, getPath() );
|
||||
for ( const BasicLayer* layer : _sweepLine->getExtracteds() ) {
|
||||
if (not component->getLayer()->getMask().intersect(layer->getMask())) continue;
|
||||
Tile* tile = Tile::create( occurrence
|
||||
, layer
|
||||
, rootTile
|
||||
, _sweepLine );
|
||||
if (not rootTile) rootTile = tile;
|
||||
}
|
||||
|
||||
BasicLayer* cutLayer = component->getLayer()->getBasicLayers().getFirst();
|
||||
if (cutLayer->getMaterial() == BasicLayer::Material::cut) {
|
||||
const SweepLine::LayerSet& connexSet = _sweepLine->getCutConnexLayers( cutLayer );
|
||||
for ( const BasicLayer* connexLayer : connexSet ) {
|
||||
Tile::create( occurrence
|
||||
, connexLayer
|
||||
, rootTile
|
||||
, _sweepLine
|
||||
, Tile::ForceLayer );
|
||||
}
|
||||
}
|
||||
|
||||
_goMatchCount++;
|
||||
}
|
||||
|
||||
|
||||
} // Tramontana namespace.
|
|
@ -0,0 +1,382 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | T r a m o n t a n a - Extractor & LVX |
|
||||
// | |
|
||||
// | Algorithm : Christian MASSON |
|
||||
// | First impl. : Yifei WU |
|
||||
// | Second impl. : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./SweepLine.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <iomanip>
|
||||
#include "hurricane/utilities/Path.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/UpdateSession.h"
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/Timer.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/Layer.h"
|
||||
#include "hurricane/ViaLayer.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/Plug.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "crlcore/Utilities.h"
|
||||
#include "tramontana/SweepLine.h"
|
||||
#include "tramontana/QueryTiles.h"
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::dec;
|
||||
using std::setw;
|
||||
using std::setfill;
|
||||
using std::left;
|
||||
using std::right;
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
using std::ofstream;
|
||||
using std::ostringstream;
|
||||
using std::setprecision;
|
||||
using std::vector;
|
||||
using std::make_pair;
|
||||
using Hurricane::dbo_ptr;
|
||||
using Hurricane::UpdateSession;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Breakpoint;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::ViaLayer;
|
||||
using Hurricane::Entity;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::RoutingPad;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Instance;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tramontana::SweepLine".
|
||||
|
||||
|
||||
SweepLine::SweepLine ( TramontanaEngine* tramontana )
|
||||
: _tramontana (tramontana)
|
||||
, _extracteds ()
|
||||
, _extractedsMask()
|
||||
, _connexityMap ()
|
||||
, _tiles ()
|
||||
, _intervalTrees ()
|
||||
{
|
||||
for ( const BasicLayer* bl : DataBase::getDB()->getTechnology()->getBasicLayers() ) {
|
||||
// HARDCODED. Should read the gauge.
|
||||
if (getString(bl->getName()).substr(0,6) == "gmetal") continue;
|
||||
if ( (bl->getMaterial() == BasicLayer::Material::metal)
|
||||
or (bl->getMaterial() == BasicLayer::Material::poly)
|
||||
or (bl->getMaterial() == BasicLayer::Material::cut)) {
|
||||
_extracteds.push_back( bl );
|
||||
_extractedsMask |= bl->getMask();
|
||||
}
|
||||
}
|
||||
_buildCutConnexMap();
|
||||
|
||||
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal5" ));
|
||||
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal4" ));
|
||||
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal3" ));
|
||||
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal2" ));
|
||||
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal1" ));
|
||||
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "poly" ));
|
||||
}
|
||||
|
||||
|
||||
SweepLine::~SweepLine ()
|
||||
{ }
|
||||
|
||||
|
||||
void SweepLine::_buildCutConnexMap ()
|
||||
{
|
||||
for ( const ViaLayer* viaLayer : DataBase::getDB()->getTechnology()->getViaLayers() ) {
|
||||
const BasicLayer* cutLayer = nullptr;
|
||||
for ( const BasicLayer* layer : viaLayer->getBasicLayers() ) {
|
||||
if (layer->getMaterial() == BasicLayer::Material::cut) {
|
||||
cutLayer = layer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (not cutLayer) {
|
||||
cerr << Error( "SweepLine::_buildConnexityMap(): ViaLayer \"%s\" does not contains any *cut* (ignored)."
|
||||
, getString(viaLayer->getName()).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
auto iCutMap = _connexityMap.find( cutLayer );
|
||||
if (iCutMap == _connexityMap.end()) {
|
||||
_connexityMap.insert( make_pair( cutLayer, LayerSet() ));
|
||||
iCutMap = _connexityMap.find( cutLayer );
|
||||
}
|
||||
for ( const BasicLayer* layer : viaLayer->getBasicLayers() ) {
|
||||
if ( (layer->getMaterial() != BasicLayer::Material::cut)
|
||||
and (_extractedsMask.intersect(layer->getMask())) ) {
|
||||
iCutMap->second.insert( layer );
|
||||
}
|
||||
}
|
||||
}
|
||||
// for ( auto item : _connexityMap ) {
|
||||
// cerr << "BasicLayers connex to cut: " << item.first << endl;
|
||||
// for ( const BasicLayer* bl : item.second ) {
|
||||
// cerr << "| " << bl << endl;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
const SweepLine::LayerSet& SweepLine::getCutConnexLayers ( const BasicLayer* cutLayer ) const
|
||||
{
|
||||
static LayerSet emptySet;
|
||||
auto iCutMap = _connexityMap.find( cutLayer );
|
||||
if (iCutMap == _connexityMap.end())
|
||||
return emptySet;
|
||||
return iCutMap->second;
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::run ()
|
||||
{
|
||||
//DebugSession::open( 160, 169 );
|
||||
cdebug_log(160,1) << "SweepLine::run()" << endl;
|
||||
loadTiles();
|
||||
//bool debugOn = false;
|
||||
//bool written = false;
|
||||
size_t processedTiles = 0;
|
||||
for ( Element& element : _tiles ) {
|
||||
processedTiles++;
|
||||
if (tty::enabled()) {
|
||||
cmess2 << " <tile:" << tty::bold << right << setw(10) << setfill('0')
|
||||
<< processedTiles << tty::reset
|
||||
<< " remains:" << right << setw(10) << setfill('0')
|
||||
<< (_tiles.size() - processedTiles)
|
||||
<< setfill(' ') << tty::reset << ">" << tty::cr;
|
||||
cmess2.flush ();
|
||||
}
|
||||
|
||||
Tile* tile = element.getTile();
|
||||
TileIntv tileIntv ( tile, tile->getYMin(), tile->getYMax() );
|
||||
// if (tile->getOccurrence().getEntity()->getId() == 3348) {
|
||||
// DebugSession::open( 160, 169 );
|
||||
// }
|
||||
// if (getString(tile->getNet()->getName()) == "a(13)") {
|
||||
// cerr << tile << endl;
|
||||
// }
|
||||
// if (not debugOn and (element.getX() == DbU::fromLambda(1724.0))) {
|
||||
// debugOn = true;
|
||||
// DebugSession::open( 0, 169 );
|
||||
// }
|
||||
// if (debugOn and (element.getX() > DbU::fromLambda(1726.0))) {
|
||||
// debugOn = false;
|
||||
// DebugSession::close();
|
||||
// }
|
||||
cdebug_log(160,1) << "X@ + " << DbU::getValueString(element.getX()) << " " << tile << endl;
|
||||
auto intvTree = _intervalTrees.find( element.getMask() );
|
||||
if (intvTree == _intervalTrees.end()) {
|
||||
cerr << Error( "SweepLine::run(): Missing interval tree for layer(mask) %s."
|
||||
" (for tile: %s)"
|
||||
, getString(element.getMask()).c_str()
|
||||
, getString(element.getTile()).c_str()
|
||||
) << endl;
|
||||
cdebug_tabw(160,-1);
|
||||
continue;
|
||||
}
|
||||
if (element.isLeftEdge()) {
|
||||
// if (tile->getOccurrence().getEntity()->getId() == 3348) {
|
||||
// //if (not written) intvTree->second.write( "tree-before.gv" );
|
||||
// cdebug_log(160,0) << " Interval tree *before* insertion." << endl;
|
||||
// for ( auto elt : intvTree->second.getElements() ) {
|
||||
// cdebug_log(160,0) << " | in tree:" << elt << endl;
|
||||
// if (elt.getData()->getBoundingBox().getXMax() < tile->getLeftEdge())
|
||||
// cdebug_log(160,0) << " * Should have been removed !" << endl;
|
||||
// }
|
||||
// }
|
||||
for ( const TileIntv& overlap : intvTree->second.getOverlaps(
|
||||
Interval(tile->getYMin(), tile->getYMax() ))) {
|
||||
cdebug_log(160,0) << " | intersect " << overlap.getData() << endl;
|
||||
tile->merge( overlap.getData() );
|
||||
}
|
||||
cdebug_log(160,0) << " | insert tile" << endl;
|
||||
// if (tile->getId() == 60117) {
|
||||
// cerr << " | insert in " << element.getMask() << endl;
|
||||
// cerr << " | " << tile << endl;
|
||||
// }
|
||||
// if (tile->getId() == 46373) {
|
||||
// cerr << " | insert " << tile << endl;
|
||||
// }
|
||||
intvTree->second.insert( tileIntv );
|
||||
if (tile->getOccurrence().getEntity()->getId() == 3348) {
|
||||
//if (not written) intvTree->second.write( "tree-after.gv" );
|
||||
//written = true;
|
||||
}
|
||||
} else {
|
||||
// if (tile->getId() == 289) {
|
||||
// DebugSession::open( 0, 169 );
|
||||
// }
|
||||
// cdebug_log(160,0) << " | remove tile from " << element.getMask() << endl;
|
||||
// cdebug_log(160,0) << " | " << tile << endl;
|
||||
// if ((tile->getId() == 289) and not written) {
|
||||
// cerr << "(before) written is " << written << endl;
|
||||
// DebugSession::open( 0, 169 );
|
||||
// intvTree->second.write( "tree-before.gv" );
|
||||
// //DebugSession::close();
|
||||
// for ( auto elt : intvTree->second.getElements() ) {
|
||||
// cerr << " | in tree:" << elt << endl;
|
||||
// }
|
||||
// }
|
||||
cdebug_log(160,0) << " | remove tile" << endl;
|
||||
intvTree->second.remove( tileIntv );
|
||||
// DebugSession::open( 0, 169 );
|
||||
// intvTree->second.checkVMax();
|
||||
// DebugSession::close();
|
||||
// if ((tile->getId() == 289) and not written) {
|
||||
// //DebugSession::open( 0, 169 );
|
||||
// written = true;
|
||||
// cerr << "(after) written is " << written << endl;
|
||||
// intvTree->second.write( "tree-after.gv" );
|
||||
// DebugSession::close();
|
||||
// }
|
||||
// if (intvTree->second.find( tileIntv ) != intvTree->second.end()) {
|
||||
// cerr << "NOT Removed " << tileIntv << endl;
|
||||
// }
|
||||
// if (tile->getId() == 289) {
|
||||
// cerr << " | removed " << tile << endl;
|
||||
// intvTree->second.write( "tree.gv" );
|
||||
// for ( auto elt : intvTree->second.getElements() ) {
|
||||
// cerr << " | in tree:" << elt << endl;
|
||||
// }
|
||||
// DebugSession::close();
|
||||
// }
|
||||
// if (tile->getId() == 46055) {
|
||||
// intvTree->second.write( "we_at_remove.gv" );
|
||||
// for ( auto tile : intvTree->second.getElements() ) {
|
||||
// cerr << "| in tree:" << tile << endl;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
//intvTree->second.checkVMax();
|
||||
// cdebug_tabw(160,-1);
|
||||
// if (tile->getOccurrence().getEntity()->getId() == 3348) {
|
||||
// DebugSession::close();
|
||||
// }
|
||||
cdebug_tabw(160,-1);
|
||||
}
|
||||
//if (debugOn) DebugSession::close();
|
||||
cdebug_tabw(160,-1);
|
||||
//DebugSession::close();
|
||||
mergeEquipotentials();
|
||||
deleteTiles();
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::loadTiles ()
|
||||
{
|
||||
//cerr << "SweepLine::loadTiles()" << endl;
|
||||
|
||||
for ( const BasicLayer* layer : _extracteds ) {
|
||||
_intervalTrees.insert( make_pair( layer->getMask(), TileIntvTree() ));
|
||||
}
|
||||
|
||||
QueryTiles query ( this );
|
||||
for ( const BasicLayer* layer : _extracteds ) {
|
||||
query.setBasicLayer( layer );
|
||||
query.doQuery();
|
||||
}
|
||||
cmess2 << " - Loaded " << _tiles.size() << " tiles (from "
|
||||
<< query.getGoMatchCount() << " gos)." << endl;
|
||||
|
||||
// for ( Occurrence occurrence : getCell()->getOccurrencesUnder( getCell()->getBoundingBox() ) ) {
|
||||
// vector<Tile*> tiles;
|
||||
// Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
|
||||
// if (occurrence.getPath().getInstances().getSize() > 0) {
|
||||
// cerr << occurrence << endl;
|
||||
// }
|
||||
// if (not component) continue;
|
||||
// for ( const BasicLayer* layer : extracteds ) {
|
||||
// if (not component->getLayer()->getMask().intersect(layer->getMask())) continue;
|
||||
// tiles.push_back( Tile::create( occurrence, layer ));
|
||||
// _tiles.push_back( Element( tiles.back(), Tile::LeftEdge ) );
|
||||
// _tiles.push_back( Element( tiles.back(), Tile::RightEdge ) );
|
||||
// if (tiles.size() > 1)
|
||||
// tiles.back()->setParent( tiles[0] );
|
||||
// }
|
||||
// tiles.clear();
|
||||
// }
|
||||
sort( _tiles.begin(), _tiles.end() );
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::deleteTiles ()
|
||||
{
|
||||
Tile::deleteAllTiles();
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::mergeEquipotentials ()
|
||||
{
|
||||
//DebugSession::open( 160, 169 );
|
||||
cdebug_log(160,1) << "SweepLine::mergeEquipotentials()" << endl;
|
||||
//cerr << "SweepLine::mergeEquipotentials()" << endl;
|
||||
Tile::timeTick();
|
||||
for ( Tile* tile : Tile::getAllTiles() ) {
|
||||
tile->getRoot( Tile::MergeEqui|Tile::MakeLeafEqui );
|
||||
}
|
||||
cdebug_tabw(160,-1);
|
||||
//DebugSession::close();
|
||||
}
|
||||
|
||||
|
||||
string SweepLine::_getTypeName () const
|
||||
{ return "Tramontana::SweepLine"; }
|
||||
|
||||
|
||||
string SweepLine::_getString () const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "<SweepLine \"" << _tramontana->getCell()->getName() << "\">";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
||||
Record* SweepLine::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( _getString() );
|
||||
if (record) {
|
||||
record->add( getSlot( "_tramontana" , &_tramontana ) );
|
||||
record->add( getSlot( "_tiles" , &_tiles ) );
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // Tramontana namespace.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue