diff --git a/.gitignore b/.gitignore index fce9d34f..49569275 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ GRTAGS .dir-locals.el .projectile +lefdef/src/lef/lef/lef.tab.h man/ rtf/ diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 6ea9d630..ba7f6749 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -217,7 +217,7 @@ namespace Anabatic { } - void Vertex::setRestricted () + void Vertex::setRestricted () { setNRestricted(); setSRestricted(); @@ -235,7 +235,7 @@ namespace Anabatic { } - bool Vertex::hasRP( Net* net ) const + bool Vertex::hasRP ( Net* net ) const { if (getGCell() != NULL ){ Cell* cell = getGCell()->getAnabatic()->getCell(); @@ -251,7 +251,7 @@ namespace Anabatic { } - bool Vertex::hasVRP( Net* net ) const + bool Vertex::hasVRP ( Net* net ) const { if (getGCell() != NULL){ Cell* cell = getGCell()->getAnabatic()->getCell(); @@ -271,7 +271,7 @@ namespace Anabatic { } - bool Vertex::hasHRP( Net* net ) const + bool Vertex::hasHRP ( Net* net ) const { if (getGCell() != NULL){ Cell* cell = getGCell()->getAnabatic()->getCell(); @@ -347,7 +347,7 @@ namespace Anabatic { } - Point Vertex::getNextPathPoint( Point pcurr, const Vertex* vnext ) const + Point Vertex::getNextPathPoint ( Point pcurr, const Vertex* vnext ) const { cdebug_log(112,1) << "Point Dijkstra::getNextPathPoint( Point pcurr, const Vertex* vnext )" << endl; if (vnext == NULL){ @@ -456,7 +456,7 @@ namespace Anabatic { } - Point Vertex::getStartPathPoint( const Vertex* next ) const + Point Vertex::getStartPathPoint ( const Vertex* next ) const { cdebug_log(112,1) << "Point Vertex::getStartPathPoint( const Vertex* next ) const:" << this << endl; @@ -669,7 +669,7 @@ namespace Anabatic { } - bool Vertex::isH() const + bool Vertex::isH () const { GCell* gcell = getGCell(); if (gcell->isDevice()) return isiHorizontal(); @@ -679,7 +679,7 @@ namespace Anabatic { } - bool Vertex::isV() const + bool Vertex::isV () const { GCell* gcell = getGCell(); if (gcell->isDevice()) return isiVertical(); @@ -866,7 +866,7 @@ namespace Anabatic { } - void Vertex::createAData() + void Vertex::createAData () { if (!getGCell()->isMatrix()){ if (_adata == NULL) _adata = GRAData::create(); @@ -874,14 +874,14 @@ namespace Anabatic { } - bool Vertex::isiSet() const + bool Vertex::isiSet () const { if (_adata) return _adata->isiSet(); else return false; } - DbU::Unit Vertex::getIAxis() const + DbU::Unit Vertex::getIAxis () const { if (_adata) return _adata->getIAxis(); else { @@ -907,7 +907,7 @@ namespace Anabatic { } - DbU::Unit Vertex::getIMax() const + DbU::Unit Vertex::getIMax () const { if (_adata){ return _adata->getIMax(); @@ -941,26 +941,25 @@ namespace Anabatic { - DbU::Unit Vertex::getIMin() const + DbU::Unit Vertex::getIMin () const { if (_adata){ return _adata->getIMin(); } else { - //cdebug_log(112,0) << "DbU::Unit Vertex::getIMin() const: Digital vertex. " << endl; - if (_from){ + if (_from) { GCell* gcurr = getGCell(); GCell* gprev = _from->getOpposite(gcurr); - Vertex* vprev = gprev->getObserver(GCell::Observable::Vertex); + Vertex* vprev = gprev->getObserver( GCell::Observable::Vertex ); if (isH()){ - if (isNorth(vprev)||isSouth(vprev)||isEast (vprev)) return getGCell()->getXCenter(); - else if (isWest (vprev)) return getGCell()->getXMin(); + if (isNorth(vprev) or isSouth(vprev) or isEast (vprev)) return getGCell()->getXCenter(); + else if (isWest (vprev)) return getGCell()->getXMin(); else { cdebug_log(112,0) << "DbU::Unit Vertex::getIMin() const: Not a neighbour GCell. " << endl; return 0; } } else { - if (isWest(vprev)||isEast(vprev)||isNorth (vprev)) return getGCell()->getYCenter(); - else if (isSouth (vprev)) return getGCell()->getYMin(); + if (isWest (vprev) or isEast(vprev) or isNorth (vprev)) return getGCell()->getYCenter(); + else if (isSouth(vprev)) return getGCell()->getYMin(); else { cdebug_log(112,0) << "DbU::Unit Vertex::getIMin() const: Not a neighbour GCell. " << endl; return 0; @@ -974,7 +973,7 @@ namespace Anabatic { } - DbU::Unit Vertex::getPIAxis() const + DbU::Unit Vertex::getPIAxis () const { if (_adata){ return _adata->getPIAxis(); @@ -1010,7 +1009,7 @@ namespace Anabatic { } - DbU::Unit Vertex::getPIMax() const + DbU::Unit Vertex::getPIMax () const { if (_adata){ return _adata->getPIMax(); @@ -1044,7 +1043,7 @@ namespace Anabatic { } - DbU::Unit Vertex::getPIMin() const + DbU::Unit Vertex::getPIMin () const { if (_adata){ return _adata->getPIMin(); @@ -1078,7 +1077,7 @@ namespace Anabatic { } - void Vertex::setInterv( DbU::Unit min, DbU::Unit max, DbU::Unit axis ) + void Vertex::setInterv ( DbU::Unit min, DbU::Unit max, DbU::Unit axis ) { if (_adata){ _adata->setInterv(min, max, axis); @@ -1088,7 +1087,7 @@ namespace Anabatic { } - void Vertex::setIntervfrom( DbU::Unit min, DbU::Unit max, DbU::Unit axis ) + void Vertex::setIntervfrom ( DbU::Unit min, DbU::Unit max, DbU::Unit axis ) { if (_adata){ _adata->setIntervfrom(min, max, axis); @@ -1098,7 +1097,7 @@ namespace Anabatic { } - void Vertex::setIntervfrom2( DbU::Unit min, DbU::Unit max, DbU::Unit axis ) + void Vertex::setIntervfrom2 ( DbU::Unit min, DbU::Unit max, DbU::Unit axis ) { if (_adata){ _adata->setIntervfrom2(min, max, axis); @@ -1108,7 +1107,7 @@ namespace Anabatic { } - void Vertex::resetIntervals() + void Vertex::resetIntervals () { if (_adata){ _adata->resetIntervals(); @@ -1119,7 +1118,7 @@ namespace Anabatic { } - void Vertex::clearFrom2() + void Vertex::clearFrom2 () { if (_adata){ _adata->clearFrom2(); @@ -1451,13 +1450,11 @@ namespace Anabatic { vector rps; NetRoutingState* state = NetRoutingExtension::get( _net ); - if (state){ - if (state->isSelfSym()){ + if (state) { + if (state->isSelfSym()) { cdebug_log(112,0) << "Dijkstra::SELF SYMMETRY CASE " << DbU::getValueString(state->getSymAxis()) << endl; } - } /*else { - cerr << "Error: No RoutingExtension for net: " << _net << endl; - }*/ + } for ( Component* component : _net->getComponents() ) { RoutingPad* rp = dynamic_cast( component ); @@ -1470,6 +1467,8 @@ namespace Anabatic { } } + if (rps.size() < 2) return; + for ( auto rp : rps ) { if (not _anabatic->getConfiguration()->selectRpComponent(rp)) cerr << Warning( "Dijktra::load(): %s has no components on grid.", getString(rp).c_str() ) << endl; diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index ac02747c..6e5f2a80 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -471,15 +471,16 @@ namespace Anabatic { } - bool Edge::isMaxCapacity ( Net* net ) const + bool Edge::isMaxCapacity ( Net* net ) const { + unsigned int wpitch = 0; if (net) { cdebug_log(112,0) << "_capacity:" << getCapacity() << endl; Hurricane::NetRoutingState* state = Hurricane::NetRoutingExtension::get( net ); - return ((_realOccupancy + state->getWPitch()) > getCapacity()) ? true : false; + wpitch = (state) ? state->getWPitch()-1 : 0; } - return (_realOccupancy >= getCapacity()) ? true : false; + return (_realOccupancy + wpitch >= getCapacity()); } diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index a9117e27..9601ef3f 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -194,82 +194,77 @@ namespace Anabatic { static DbU::Unit unreached; static DbU::Unit unreachable; public: - static void notify ( Vertex*, unsigned flags ); - static inline Vertex* lookup ( GCell* ); - public: - inline Vertex ( GCell* ); - //inline Vertex ( size_t id ); - inline ~Vertex (); - inline bool isAnalog () const; - inline bool hasDoneAllRps () const; - inline Contact* hasGContact ( Net* ) const; - inline unsigned int getId () const; - inline GCell* getGCell () const; - inline Box getBoundingBox () const; - inline Edges getEdges ( Flags sides=Flags::AllSides ) const; - inline AnabaticEngine* getAnabatic () const; - inline Contact* getGContact ( Net* ); - bool hasValidStamp () const; - inline Point getCenter () const; - inline DbU::Unit getDistance () const; - inline int getStamp () const; - inline int getBranchId () const; - inline int getConnexId () const; - inline int getDegree () const; - inline int getRpCount () const; - Edge* getFrom () const; - inline Vertex* getPredecessor () const; - inline Vertex* getNeighbor ( Edge* ) const; - inline void setDistance ( DbU::Unit ); - inline void setStamp ( int ); - inline void setConnexId ( int ); - inline void setBranchId ( int ); - inline void setDegree ( int ); - inline void incDegree ( int delta=1 ); - inline void setRpCount ( int ); - inline void incRpCount ( int delta=1 ); - inline void setFrom ( Edge* ); - inline void add ( RoutingPad* ); - inline void clearRps (); - inline Contact* breakGoThrough ( Net* ); - - //////////////////////////////////////// Analog - inline bool isNorth ( const Vertex* ) const; - inline bool isSouth ( const Vertex* ) const; - inline bool isEast ( const Vertex* ) const; - inline bool isWest ( const Vertex* ) const; - inline bool isNRestricted () const; - inline bool isSRestricted () const; - inline bool isERestricted () const; - inline bool isWRestricted () const; - inline bool hasRestrictions() const; - - void setRestricted (); - void clearRestriction (); - inline void setNRestricted (); - inline void setSRestricted (); - inline void setERestricted (); - inline void setWRestricted (); - bool hasRP ( Net* ) const; - bool hasVRP ( Net* ) const; - bool hasHRP ( Net* ) const; - static bool isRestricted ( const Vertex* v1, const Vertex* v2, const Edge* e, DbU::Unit hpitch = 0, DbU::Unit vpitch = 0, Net* net = NULL); - bool areSameSide ( const Vertex*, const Vertex* ) const; - - inline bool isFromFrom2 () const; - inline bool isFrom2Mode () const; - inline bool isAxisTarget () const; - inline bool isiHorizontal() const; - inline bool isiVertical () const; - inline void setFlags ( uint32_t ); - inline void unsetFlags ( uint32_t ); - bool isH () const; - bool isV () const; - inline void createAData (); - //////////////////////////////////// + static void notify ( Vertex*, unsigned flags ); + static inline Vertex* lookup ( GCell* ); + public: + inline Vertex ( GCell* ); + //inline Vertex ( size_t id ); + inline ~Vertex (); + inline bool isAnalog () const; + inline bool hasDoneAllRps () const; + inline Contact* hasGContact ( Net* ) const; + inline unsigned int getId () const; + inline GCell* getGCell () const; + inline Box getBoundingBox () const; + inline Edges getEdges ( Flags sides=Flags::AllSides ) const; + inline AnabaticEngine* getAnabatic () const; + inline Contact* getGContact ( Net* ); + bool hasValidStamp () const; + inline Point getCenter () const; + inline DbU::Unit getDistance () const; + inline int getStamp () const; + inline int getBranchId () const; + inline int getConnexId () const; + inline int getDegree () const; + inline int getRpCount () const; + Edge* getFrom () const; + inline Vertex* getPredecessor () const; + inline Vertex* getNeighbor ( Edge* ) const; + inline void setDistance ( DbU::Unit ); + inline void setStamp ( int ); + inline void setConnexId ( int ); + inline void setBranchId ( int ); + inline void setDegree ( int ); + inline void incDegree ( int delta=1 ); + inline void setRpCount ( int ); + inline void incRpCount ( int delta=1 ); + inline void setFrom ( Edge* ); + inline void add ( RoutingPad* ); + inline void clearRps (); + inline Contact* breakGoThrough ( Net* ); + // Analog related methods. + inline bool isNorth ( const Vertex* ) const; + inline bool isSouth ( const Vertex* ) const; + inline bool isEast ( const Vertex* ) const; + inline bool isWest ( const Vertex* ) const; + inline bool isNRestricted () const; + inline bool isSRestricted () const; + inline bool isERestricted () const; + inline bool isWRestricted () const; + inline bool hasRestrictions () const; + void setRestricted (); + void clearRestriction (); + inline void setNRestricted (); + inline void setSRestricted (); + inline void setERestricted (); + inline void setWRestricted (); + bool hasRP ( Net* ) const; + bool hasVRP ( Net* ) const; + bool hasHRP ( Net* ) const; + static bool isRestricted ( const Vertex* v1, const Vertex* v2, const Edge* e, DbU::Unit hpitch = 0, DbU::Unit vpitch = 0, Net* net = NULL); + bool areSameSide ( const Vertex*, const Vertex* ) const; + inline bool isFromFrom2 () const; + inline bool isFrom2Mode () const; + inline bool isAxisTarget () const; + inline bool isiHorizontal () const; + inline bool isiVertical () const; + inline void setFlags ( uint32_t ); + inline void unsetFlags ( uint32_t ); + bool isH () const; + bool isV () const; + inline void createAData (); Point getStartPathPoint ( const Vertex* next ) const; Point getNextPathPoint ( Point, const Vertex* ) const; - //////////////////////////////////////// GRDATA void setIntervals ( Vertex* ); inline bool hasAData () const; bool isiSet () const; @@ -297,10 +292,10 @@ namespace Anabatic { GCell* getGPrev ( uint32_t criteria=0 ) const; // Inspector support. - string _getString () const; + string _getString () const; private: - Vertex ( const Vertex& ); - Vertex& operator= ( const Vertex& ); + Vertex ( const Vertex& ); + Vertex& operator= ( const Vertex& ); private: size_t _id; GCell* _gcell; @@ -502,52 +497,52 @@ namespace Anabatic { public: typedef std::function distance_t; public: - Dijkstra ( AnabaticEngine* ); - ~Dijkstra (); - public: - inline bool isBipoint () const; - inline bool isSourceVertex ( Vertex* ) const; - inline bool isTargetVertex ( Vertex* ) const; - inline DbU::Unit getSearchAreaHalo () const; - template - inline DistanceT* setDistance ( DistanceT ); - inline void setSearchAreaHalo ( DbU::Unit ); - void load ( Net* net ); - void run ( Mode mode=Mode::Standart ); - inline const VertexSet& getSources () const; - private: - Dijkstra ( const Dijkstra& ); - Dijkstra& operator= ( const Dijkstra& ); - static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* ); - Point _getPonderedPoint () const; - void _cleanup (); - bool _propagate ( Flags enabledSides ); - void _traceback ( Vertex* ); - void _materialize (); - void _selectFirstSource (); - void _toSources ( Vertex*, int connexId ); - void _getConnecteds ( Vertex*, VertexSet& ); - void _checkEdges () const; - void _createSelfSymSeg ( Segment* ); - - inline void setAxisTarget (); - inline bool needAxisTarget () const; - inline void setFlags ( Flags ); - inline void unsetFlags ( Flags ); - void setAxisTargets (); - void unsetAxisTargets (); - - bool _attachSymContactsHook ( RoutingPad* ); - void _limitSymSearchArea ( RoutingPad* rp ); - void _setSourcesGRAData ( Vertex*, RoutingPad*); - bool _checkFrom2 ( Edge*, Vertex* ); - bool _isDistance2Shorter ( DbU::Unit&, Vertex*, Vertex*, Edge* ); - void _pushEqualDistance ( DbU::Unit, bool, Vertex*, Vertex*, Edge* ); - void _updateGRAData ( Vertex*, bool, Vertex* ); - void _initiateUpdateIntervals ( Vertex* ); - bool _updateIntervals ( bool&, Vertex*, bool&, int&, Edge* ); - void _updateRealOccupancy ( Vertex* ); - + Dijkstra ( AnabaticEngine* ); + ~Dijkstra (); + public: + inline bool isBipoint () const; + inline bool isSourceVertex ( Vertex* ) const; + inline Net* getNet () const; + inline bool isTargetVertex ( Vertex* ) const; + inline DbU::Unit getSearchAreaHalo () const; + template + inline DistanceT* setDistance ( DistanceT ); + inline void setSearchAreaHalo ( DbU::Unit ); + void load ( Net* net ); + void run ( Mode mode=Mode::Standart ); + inline const VertexSet& getSources () const; + private: + Dijkstra ( const Dijkstra& ); + Dijkstra& operator= ( const Dijkstra& ); + static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* ); + Point _getPonderedPoint () const; + void _cleanup (); + bool _propagate ( Flags enabledSides ); + void _traceback ( Vertex* ); + void _materialize (); + void _selectFirstSource (); + void _toSources ( Vertex*, int connexId ); + void _getConnecteds ( Vertex*, VertexSet& ); + void _checkEdges () const; + void _createSelfSymSeg ( Segment* ); + + inline void setAxisTarget (); + inline bool needAxisTarget () const; + inline void setFlags ( Flags ); + inline void unsetFlags ( Flags ); + void setAxisTargets (); + void unsetAxisTargets (); + + bool _attachSymContactsHook ( RoutingPad* ); + void _limitSymSearchArea ( RoutingPad* rp ); + void _setSourcesGRAData ( Vertex*, RoutingPad*); + bool _checkFrom2 ( Edge*, Vertex* ); + bool _isDistance2Shorter ( DbU::Unit&, Vertex*, Vertex*, Edge* ); + void _pushEqualDistance ( DbU::Unit, bool, Vertex*, Vertex*, Edge* ); + void _updateGRAData ( Vertex*, bool, Vertex* ); + void _initiateUpdateIntervals ( Vertex* ); + bool _updateIntervals ( bool&, Vertex*, bool&, int&, Edge* ); + void _updateRealOccupancy ( Vertex* ); private: AnabaticEngine* _anabatic; vector _vertexes; @@ -571,6 +566,7 @@ namespace Anabatic { inline bool Dijkstra::isBipoint () const { return _net and (_targets.size()+_sources.size() == 2); } inline bool Dijkstra::isSourceVertex ( Vertex* v ) const { return (_sources.find(v) != _sources.end()); } inline bool Dijkstra::isTargetVertex ( Vertex* v ) const { return (_targets.find(v) != _targets.end()); } + inline Net* Dijkstra::getNet () const { return _net; } inline DbU::Unit Dijkstra::getSearchAreaHalo () const { return _searchAreaHalo; } inline void Dijkstra::setSearchAreaHalo ( DbU::Unit halo ) { _searchAreaHalo = halo; } diff --git a/bootstrap/build.conf b/bootstrap/build.conf index 88bf54f1..de43eaeb 100644 --- a/bootstrap/build.conf +++ b/bootstrap/build.conf @@ -17,9 +17,6 @@ projects = [ , "vlsisapd" , "hurricane" , "crlcore" - #, "nimbus" - #, "metis" - #, "mauka" , "anabatic" , "katana" , "knik" @@ -29,6 +26,9 @@ projects = [ , "etesian" , "equinox" , "solstice" + , "oroshi" + , "bora" + , "karakaze" , "unicorn" , "tutorial" #, "testbench" @@ -36,23 +36,9 @@ projects = [ , "cumulus" , "stratus1" , "documentation" + , "unittests" ] , 'repository': 'ssh://asim-t/users/largo2/git/coriolis.git' } - - , { 'name' : "chams" - , 'tools' : [ "hurricaneAMS" - , "amsCore" - , "opSim" - #, "scribe" - , "graph" - , "pharos" - , "isis" - , "horus" - #, "schematic" - , "solver" - , "autoDTR" - ] - , 'repository':"ssh://melon-t/users/outil/chams/chams.git" } ] package = { 'name' : 'coriolis2' diff --git a/bootstrap/ccb.py b/bootstrap/ccb.py index b3e99667..45faceb8 100755 --- a/bootstrap/ccb.py +++ b/bootstrap/ccb.py @@ -159,12 +159,8 @@ def autoLocate (): locations = [ os.path.abspath(os.path.dirname(sys.argv[0])) , os.environ['HOME']+'/coriolis-2.x/src/coriolis/bootstrap' , os.environ['HOME']+'/coriolis/src/coriolis/bootstrap' - , os.environ['HOME']+'/chams-1.x/src/coriolis/bootstrap' - , os.environ['HOME']+'/chams/src/coriolis/bootstrap' , '/users/outil/coriolis/coriolis-2.x/src/coriolis/bootstrap' , os.environ['HOME']+'/coriolis-2.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage - , os.environ['HOME']+'/chams-1.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage - , os.environ['HOME']+'/chams/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage , '/users/outil/coriolis/coriolis-2.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage ] diff --git a/bootstrap/coriolisEnv.py b/bootstrap/coriolisEnv.py index 0a3c8502..037e09f0 100755 --- a/bootstrap/coriolisEnv.py +++ b/bootstrap/coriolisEnv.py @@ -185,7 +185,6 @@ if __name__ == "__main__": parser.add_option ( "--devel" , action="store_true" , dest="devel" ) parser.add_option ( "--static" , action="store_true" , dest="static" ) parser.add_option ( "--shared" , action="store_true" , dest="shared" ) - parser.add_option ( "--chams" , action="store_true" , dest="chams" ) parser.add_option ( "--no-python" , action="store_true" , dest="nopython" ) parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" ) ( options, args ) = parser.parse_args () diff --git a/bootstrap/socInstaller.py b/bootstrap/socInstaller.py index 17aaedee..9ef2bbd3 100755 --- a/bootstrap/socInstaller.py +++ b/bootstrap/socInstaller.py @@ -220,7 +220,7 @@ class Configuration ( object ): PrimaryNames = \ [ 'sender' , 'receivers' - , 'coriolisRepo', 'chamsRepo' , 'benchsRepo', 'supportRepos' + , 'coriolisRepo', 'benchsRepo', 'supportRepos' , 'homeDir' , 'masterHost' , 'debugArg' , 'nightlyMode' , 'rmSource' , 'rmBuild', 'doGit', 'doBuild', 'doBenchs', 'doSendReport' @@ -235,7 +235,6 @@ class Configuration ( object ): self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', 'Eric.Lao@lip6.fr' ] self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ] self._coriolisRepo = 'https://www-soc.lip6.fr/git/coriolis.git' - self._chamsRepo = 'file:///users/outil/chams/chams.git' self._benchsRepo = 'https://www-soc.lip6.fr/git/alliance-check-toolkit.git' self._homeDir = os.environ['HOME'] self._debugArg = '' @@ -458,7 +457,6 @@ try: for supportRepo in conf.supportRepos: gitSupports.append( GitRepository( supportRepo, conf.srcDir+'/support' ) ) gitCoriolis = GitRepository( conf.coriolisRepo, conf.srcDir, conf.fds['build'] ) - gitChams = GitRepository( conf.chamsRepo , conf.srcDir, conf.fds['build'] ) gitBenchs = GitRepository( conf.benchsRepo , conf.srcDir, conf.fds['build'] ) if conf.doGit: @@ -492,7 +490,7 @@ try: , ' <%s>' % ccbBin ] ) - buildCommand = '%s --root=%s --project=support --project=coriolis --project=chams --make="-j%%d install" %%s' \ + buildCommand = '%s --root=%s --project=support --project=coriolis --make="-j%%d install" %%s' \ % (ccbBin,conf.rootDir) benchsCommand = 'cd %s/benchs && ./bin/go.sh clean && ./bin/go.sh lvx' \ % (gitBenchs.localRepoDir) diff --git a/bora/CMakeLists.txt b/bora/CMakeLists.txt new file mode 100644 index 00000000..a05c86b9 --- /dev/null +++ b/bora/CMakeLists.txt @@ -0,0 +1,34 @@ +# -*- explicit-buffer-name: "CMakeLists.txt" -*- + + set(CMAKE_LEGACY_CYGWIN_WIN32 0) + project(BORA) + + option(BUILD_DOC "Build the documentation (doxygen)" OFF) + + cmake_minimum_required(VERSION 2.8.9) + + set(ignoreVariables "${BUILD_DOC}") + + 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(program_options filesystem python regex) + setup_qt() + setup_qwt() + + find_package(Libexecinfo REQUIRED) + find_package(PythonLibs 2 REQUIRED) + find_package(PythonSitePackages REQUIRED) + find_package(LEFDEF REQUIRED) + find_package(VLSISAPD REQUIRED) + find_package(HURRICANE REQUIRED) + find_package(CORIOLIS REQUIRED) + find_package(ANABATIC REQUIRED) + find_package(KATANA REQUIRED) + find_package(Doxygen) + + add_subdirectory(src) +#add_subdirectory(cmake_modules) +#add_subdirectory(doc) diff --git a/bora/src/BoraEngine.cpp b/bora/src/BoraEngine.cpp new file mode 100644 index 00000000..e6816644 --- /dev/null +++ b/bora/src/BoraEngine.cpp @@ -0,0 +1,351 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./BoraEngine.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/DebugSession.h" +#include "hurricane/DataBase.h" +#include "hurricane/Library.h" +#include "hurricane/viewer/HApplication.h" +#include "hurricane/viewer/ExceptionWidget.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/analog/AnalogCellExtension.h" +#include "hurricane/analog/LayoutGenerator.h" +#include "hurricane/analog/TransistorFamily.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/GdsDriver.h" +#include "anabatic/Dijkstra.h" +#include "katana/KatanaEngine.h" +#include "bora/SlicingPlotWidget.h" +#include "bora/SlicingDataWidget.h" +#include "bora/AnalogDistance.h" +#include "bora/BoraEngine.h" + + +namespace Bora { + + using namespace std; + using Hurricane::Error; + using Hurricane::DebugSession; + using Hurricane::NetRoutingState; + using Hurricane::NetRoutingExtension; + using Hurricane::Net; + using Hurricane::Cell; + using Hurricane::Box; + using Hurricane::Transformation; + using Hurricane::UpdateSession; + using Analog::AnalogCellExtension; + using Analog::Device; + using CRL::GdsDriver; + + +// ------------------------------------------------------------------- +// Class : "BoraEngine". + + Name BoraEngine::_toolName = "Bora"; + bool first = false; + + + const Name& BoraEngine::staticGetName () + { return _toolName; } + + + BoraEngine* BoraEngine::get ( const Cell* cell ) + { + return static_cast( ToolEngine::get(cell,staticGetName()) ); + } + + + BoraEngine::BoraEngine ( Cell* cell ) + : Super (cell) + , _viewer(NULL) + { } + + + void BoraEngine::_postCreate () + { + Super::_postCreate(); + } + + + BoraEngine* BoraEngine::create ( Cell* cell ) + { + cdebug_log(539,0) << "BoraEngine* BoraEngine::create( Cell* cell )" << endl; + BoraEngine* bora = new BoraEngine( cell ); + + bora->_postCreate(); + return bora; + } + + + BoraEngine::~BoraEngine () + { } + + + void BoraEngine::_preDestroy () + { + cdebug.log(539,1) << "BoraEngine::_preDestroy()" << endl; + + cmess1 << " o Deleting ToolEngine<" << getName() << "> from Cell <" + << getCell()->getName() << ">" << endl; + + cdebug.tabw(539,-1); + + Super::_preDestroy(); + } + + + const Name& BoraEngine::getName () const + { return _toolName; } + + + void BoraEngine::setViewer ( Hurricane::CellViewer* viewer ) + { _viewer = viewer; } + + + void BoraEngine::updateSlicingTree() + { + SlicingNode* slicingtree = AnalogCellExtension::get( getCell() ); + if (slicingtree) { + cmess1 << " o Updating the SlicingTree." << endl; + + startMeasures(); + + slicingtree->updateGlobalSize(); + + stopMeasures(); + printMeasures(); + } else { + cerr << Error( "BoraEngine::updateSlicingTree(): " + "Cannot update, the SlicingTree needs to be created first." ) << endl; + } + } + + + void BoraEngine::updatePlacement ( DbU::Unit width, DbU::Unit height ) + { + cdebug_log(536,1) << "BoraEngine::updatePlacement(DbU::Unit,DbU::Unit)" << endl; + + SlicingNode* slicingtree = AnalogCellExtension::get( getCell() ); + if (slicingtree){ + BoxSet* bs = slicingtree->getPairHW( width, height ); + if (bs) updatePlacement( bs ); + } else + cerr << "[Error]: The slicing tree needs to be created first." << endl; + + cdebug_tabw(536,-1); + } + + + void BoraEngine::updatePlacement ( size_t index ) + { + cdebug_log(536,1) << "BoraEngine::updatePlacement(int)" << endl; + + SlicingNode* slicingtree = AnalogCellExtension::get( getCell() ); + if (slicingtree) { + cmess2 << Dots::asInt( " o Selecting analog placement (index)", index ) << endl; + + BoxSet* bs = slicingtree->getPairHW( index ); + if (bs) updatePlacement( bs ); + } else + cerr << Error( "BoraEngine::updatePlacement(): The slicing tree needs to be created first." ) << endl; + + cdebug_tabw(536,-1); + } + + + void BoraEngine::updatePlacement ( BoxSet* boxSet ) + { + cdebug_log(536,1) << "BoraEngine::updatePlacement(BoxSet*)" << endl; + + //DebugSession::addToTrace( getCell(), "vin+" ); + + SlicingNode* slicingtree = AnalogCellExtension::get( getCell() ); + if (slicingtree) { + NodeSets nodeSets = slicingtree->getNodeSets(); + if (not nodeSets.empty()) { + Cell* cell = SlicingNode::getCell(); + Katana::KatanaEngine* katana = Katana::KatanaEngine::get( cell ); + if (katana) katana->destroy(); + + slicingtree->_setGlobalSize( boxSet ); + + if (_viewer) emitCellPreModificated (); + UpdateSession::open(); + slicingtree->clearGlobalRouting(); + slicingtree->place(); + + CRL::RoutingGauge* rg = slicingtree->getRoutingGauge(); + DbU::Unit hpitch = rg->getHorizontalPitch(); + DbU::Unit vpitch = rg->getVerticalPitch(); + + slicingtree->expandRoutingChannel( hpitch*2, vpitch*2 ); + slicingtree->replace(); + slicingtree->updateSymNetAxis(); + UpdateSession::close(); + + katana = Katana::KatanaEngine::create(cell); + katana->openSession(); + Anabatic::GCell* gcell = katana->getSouthWestGCell(); + slicingtree->setKatana( katana ); + slicingtree->setGCell( gcell ); + slicingtree->clearRoutingPads(); + slicingtree->flattenDigitalNets(); + slicingtree->createRoutingPads(); + slicingtree->resetWireOccupation(); + Katana::Session::close(); + katana->openSession(); + + Anabatic::Dijkstra* dijkstra = new Anabatic::Dijkstra( katana ); + AnalogDistance distance = AnalogDistance( cell, hpitch, vpitch ); + dijkstra->setDistance( distance ); + + for ( Net* net : cell->getNets() ) { + distance.setNet( net ); + dijkstra->load( net ); + NetRoutingState* state = NetRoutingExtension::get( net ); + if ( not (state and state->isSymSlave()) ) { + slicingtree->setVertexRestriction( net, katana ); + dijkstra->run(); + slicingtree->updateWireOccupation( dijkstra ); + } + } + katana->setState( Anabatic::EngineState::EngineGlobalLoaded ); + + slicingtree->expandRoutingChannel(); + slicingtree->replace(); + slicingtree->updateSymNetAxis(); + + katana->updateMatrix(); + katana->analogInit(); + Katana::Session::close(); + + if (_viewer) { + getCellWidget()->fitToContents(); + emitCellPostModificated(); + } + } else + cerr << Error( "BoraEngine::updatePlacement(): The slicing tree can not be placed.\n" + " The slicing tree needs to be updated first." ) << endl; + } else + cerr << Error( "BoraEngine::updatePlacement(): The slicing tree can not be set.\n" + " The slicing tree needs to be created first." ) << endl; + + cdebug_tabw(536,-1); + } + + + void BoraEngine::setToleranceRatio ( DbU::Unit ratioh, DbU::Unit ratiow ) + { + SlicingNode* slicingtree = AnalogCellExtension::get( _viewer->getCellWidget()->getCell() ); + if (slicingtree) { + slicingtree->setToleranceRatioH( ratioh ); + slicingtree->setToleranceRatioW( ratiow ); + resetPlacement(); + } else + cerr << Error( "BoraEngine::setToleranceRatio(): The slicing tree's tolerance ratio cannot be set.\n" + " The slicing tree needs to be created first." ) << endl; + } + + + void BoraEngine::setToleranceBand ( DbU::Unit bandh, DbU::Unit bandw ) + { + SlicingNode* slicingtree = AnalogCellExtension::get( _viewer->getCellWidget()->getCell() ); + if (slicingtree) { + slicingtree->setToleranceBandH( bandh ); + slicingtree->setToleranceBandW( bandw ); + resetPlacement(); + } else + cerr << Error( "BoraEngine::setToleranceBand(): The slicing tree's tolerance ratio can not be set.\n" + " The slicing tree needs to be created first." ) << endl; + } + + + void BoraEngine::showPareto () + { } + + + void BoraEngine::resetPlacement () + { + emitCellPreModificated (); + DbU::Unit y = 0; + for ( Instance* instance : getCell()->getInstances() ) { + UpdateSession::open(); + instance->setTransformation ( Transformation( 0, y ) ); + instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); + UpdateSession::close(); + + Cell* model = instance->getMasterCell(); + if (model) { + Device* device = dynamic_cast( model ); + if (device) y += device->getAbutmentBox().getHeight(); + } + } + getCellWidget()->fitToContents(); + emitCellPostModificated(); + } + + + DbU::Unit BoraEngine::getToleranceRatioH () const + { + SlicingNode* slicingtree = AnalogCellExtension::get( _viewer->getCellWidget()->getCell() ); + if (slicingtree) return slicingtree->getToleranceRatioH(); + + cerr << Error( "BoraEngine::getToleranceRatioH(): The slicing tree needs to be created first." ) << endl; + return 0; + } + + + DbU::Unit BoraEngine::getToleranceRatioW () const + { + SlicingNode* slicingtree = AnalogCellExtension::get( _viewer->getCellWidget()->getCell() ); + if (slicingtree) return slicingtree->getToleranceRatioW(); + + cerr << Error( "BoraEngine::getToleranceRatioW(): The slicing tree needs to be created first." ) << endl; + return 0; + } + + + DbU::Unit BoraEngine::getToleranceBandH () const + { + SlicingNode* slicingtree = AnalogCellExtension::get( _viewer->getCellWidget()->getCell() ); + if (slicingtree) return slicingtree->getToleranceBandH(); + + cerr << Error( "BoraEngine::getToleranceBandH(): The slicing tree needs to be created first." ) << endl; + return 0; + } + + + DbU::Unit BoraEngine::getToleranceBandW () const + { + SlicingNode* slicingtree = AnalogCellExtension::get( _viewer->getCellWidget()->getCell() ); + if (slicingtree) return slicingtree->getToleranceBandW(); + + cerr << Error( "BoraEngine::getToleranceBandW(): The slicing tree needs to be created first." ) << endl; + return 0; + } + + +} // Bora namespace. diff --git a/bora/src/BoxSet.cpp b/bora/src/BoxSet.cpp new file mode 100644 index 00000000..857c9de3 --- /dev/null +++ b/bora/src/BoxSet.cpp @@ -0,0 +1,414 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./BoxSet.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "bora/BoxSet.h" + + +namespace Bora { + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + + +// ------------------------------------------------------------------- +// Class : "Bora::BoxSet". + + + BoxSet::BoxSet ( DbU::Unit height, DbU::Unit width ) + : _height(height) + , _width (width) + , _cpt (1) + { } + + + BoxSet::BoxSet ( BoxSet* boxSet ) + : _height(0) + , _width (0) + , _cpt (1) + { + if (boxSet) { + _height = boxSet->getHeight(); + _width = boxSet->getWidth(); + _cpt = boxSet->getCpt(); + } + } + + + BoxSet::~BoxSet () + { } + + + void BoxSet::print () const + { + cerr << "area: " << setprecision(4) << getOccupationArea() ; + cerr << "%, \t cpt: " << getCpt(); + if ((getWidth() == 0) && (getHeight() == 0)) cerr << ", \t ratio (W/H):inf"; + else cerr << ", \t ratio (W/H):" << setprecision(2) << getWidth()/getHeight(); + cerr << ", \t ratio (W*H):" << setprecision(4) << DbU::getPhysical(getWidth(),DbU::Micro) * DbU::getPhysical(getHeight(),DbU::Micro) << "um²"; + if (getType() == DeviceSNode){ cerr << ", \t Nfing: " << getNFing(); } + cerr << ", \t H: " << setprecision(4) << DbU::getPhysical(getHeight(),DbU::Micro) << "um" ; + cerr << ", W: " << DbU::getPhysical(getWidth(),DbU::Micro)<< "um"; + cerr << endl; +} + + + const vector& BoxSet::getSet () const + { + cerr << Warning( "BoxSet::getSet(): DBoxSet and RHVBoxSet do not have vector of BoxSets." ) << endl; + + static const vector emptyBoxSet = vector(); + return emptyBoxSet; + } + + + int BoxSet::getNFing () const + { + cerr << Warning( "BoxSet::getNFing(): Only DBoxSet has fingers." ) << endl; + return 0; + } + + + void BoxSet::destroy() + { delete this; } + + + void BoxSet::setWidth ( DbU::Unit ) + { cerr << Warning( "BoxSet::setWidth(): Must never be called." ) << endl; } + + + void BoxSet::setHeight ( DbU::Unit ) + { cerr << Warning( "BoxSet::setWidth(): Must never be called." ) << endl; } + + +// ------------------------------------------------------------------- +// Class : "Bora::HVBoxSet". + + + HVBoxSet::HVBoxSet ( const vector& dimensionSet, DbU::Unit height, DbU::Unit width ) + : BoxSet(height,width) + ,_dimensionSet(dimensionSet) + { } + + + HVBoxSet::HVBoxSet ( HVBoxSet* boxSet ) + : BoxSet( boxSet ) + , _dimensionSet( boxSet->getSet() ) + { } + + + HVBoxSet::~HVBoxSet () + { } + + + double HVBoxSet::getDevicesArea () const + { + double area = 0; + for ( BoxSet* bs : _dimensionSet ) area += bs->getDevicesArea(); + return area; + } + + +// ------------------------------------------------------------------- +// Class : "Bora::HBoxSet". + + + int HBoxSet::_count = 0; + int HBoxSet::_countAll = 0; + + + HBoxSet::HBoxSet ( const vector& dimensionSet, DbU::Unit height, DbU::Unit width ) + : HVBoxSet( dimensionSet, height, width ) + { + if ((_height == 0) and (_width == 0)) { + calculateHeight(); + calculateWidth (); + } + } + + + HBoxSet::HBoxSet( HBoxSet* boxSet ) + : HVBoxSet( boxSet ) + { + ++_count; + ++_countAll; + } + + + HBoxSet::~HBoxSet () + { + --_count; + } + + + HBoxSet* HBoxSet::create ( const vector& dimensionSet, DbU::Unit height, DbU::Unit width ) + { + return new HBoxSet( dimensionSet, height, width ); + } + + + HBoxSet* HBoxSet::clone () + { return HBoxSet::create( getSet(), getHeight(), getWidth() ); } + + + void HBoxSet::calculateHeight () + { + DbU::Unit currentH = 0; + for ( BoxSet* bs : _dimensionSet ) currentH += bs->getHeight(); + _height = currentH; + } + + + void HBoxSet::calculateWidth () + { + DbU::Unit currentW = 0; + for ( BoxSet* bs : _dimensionSet ) { + if (currentW < bs->getWidth()) currentW = bs->getWidth(); + } + _width = currentW; + } + + + void HBoxSet::destroy() + { + BoxSet::destroy(); + } + + +// ------------------------------------------------------------------- +// Class : "Bora::VBoxSet". + + + int VBoxSet::_count = 0; + int VBoxSet::_countAll = 0; + + + VBoxSet::VBoxSet ( const vector& dimensionSet, DbU::Unit height, DbU::Unit width ) + : HVBoxSet( dimensionSet, height, width ) + { + ++_count; + ++_countAll; + if ((_height == 0) and (_width == 0)){ + calculateHeight(); + calculateWidth (); + } + } + + + VBoxSet::VBoxSet ( VBoxSet* boxSet ) + : HVBoxSet( boxSet ) + { } + + + VBoxSet::~VBoxSet () + { + --_count; + } + + + VBoxSet* VBoxSet::create ( const vector& dimensionSet, DbU::Unit height, DbU::Unit width ) + { + return new VBoxSet( dimensionSet, height, width ); + } + + + VBoxSet* VBoxSet::clone () + { + return VBoxSet::create( getSet(), getHeight(), getWidth() ); + } + + + void VBoxSet::calculateHeight() + { + DbU::Unit currentH = 0; + for ( BoxSet* bs : _dimensionSet ) { + if (currentH < bs->getHeight()) currentH = bs->getHeight(); + } + _height = currentH; + } + + + void VBoxSet::calculateWidth () + { + DbU::Unit currentW = 0; + for ( BoxSet* bs : _dimensionSet ) currentW += bs->getWidth(); + _width = currentW; + } + + + void VBoxSet::destroy() + { + BoxSet::destroy(); + } + + +// ------------------------------------------------------------------- +// Class : "Bora::DBoxSet". + + + int DBoxSet::_count = 0; + int DBoxSet::_countAll = 0; + + + DBoxSet::DBoxSet ( DbU::Unit height, DbU::Unit width, int nfing ) + : BoxSet( height, width ) + , _nfing(nfing) + { + ++_count; + ++_countAll; + } + + + DBoxSet::DBoxSet ( DBoxSet* boxSet ) + : BoxSet( boxSet ) + , _nfing( boxSet->getNFing() ) + { } + + + DBoxSet::~DBoxSet () + { + --_count; + } + + + DBoxSet* DBoxSet::create ( DbU::Unit height, DbU::Unit width, int nfing ) + { + return new DBoxSet( height, width, nfing ); + } + + + DBoxSet* DBoxSet::clone () + { + return DBoxSet::create( getHeight(), getWidth(), getNFing() ); + } + + + void DBoxSet::destroy() + { + BoxSet::destroy(); + } + + +// ------------------------------------------------------------------- +// Class : "Bora::RHVBoxSet". + + + int RHVBoxSet::_count = 0; + int RHVBoxSet::_countAll = 0; + + + RHVBoxSet::RHVBoxSet ( DbU::Unit height, DbU::Unit width ) + : BoxSet( height, width ) + { + _width = width; + _height = height; + } + + + RHVBoxSet::RHVBoxSet ( RHVBoxSet* boxSet ) + : BoxSet( boxSet ) + { } + + + RHVBoxSet::~RHVBoxSet () + { } + + + void RHVBoxSet::destroy () + { + delete this; + } + + + void RHVBoxSet::print () const + { + cerr << "area: " << setprecision(4) << getOccupationArea() ; + cerr << "%, \t cpt: " << getCpt(); + cerr << ", \t H: " << setprecision(4) << DbU::getPhysical(_height,DbU::Micro) << "um" ; + cerr << ", W: " << DbU::getPhysical(_width,DbU::Micro)<< "um"; + cerr << endl; + } + + +// ------------------------------------------------------------------- +// Class : "Bora::RHBoxSet". + + + RHBoxSet::RHBoxSet ( DbU::Unit height ) + : RHVBoxSet( height, 0 ) + { + _count++; + _countAll++; + } + + + RHBoxSet::RHBoxSet ( RHBoxSet* boxSet ) + : RHVBoxSet( boxSet ) + { } + + + RHBoxSet::~RHBoxSet () + { } + + + RHBoxSet* RHBoxSet::create ( DbU::Unit height ) + { + return new RHBoxSet ( height ); + } + + + RHBoxSet* RHBoxSet::clone () + { + return RHBoxSet::create( getHeight() ); + } + + +// ------------------------------------------------------------------- +// Class : "Bora::RVBoxSet". + + + RVBoxSet::RVBoxSet ( DbU::Unit width ) + : RHVBoxSet( 0, width ) + { + ++_count; + ++_countAll; + } + + + RVBoxSet::RVBoxSet( RVBoxSet* boxSet ) + : RHVBoxSet( boxSet ) + { } + + + RVBoxSet::~RVBoxSet () + { } + + + RVBoxSet* RVBoxSet::create ( DbU::Unit width ) + { + return new RVBoxSet( width ); + } + + + RVBoxSet* RVBoxSet::clone() + { + return RVBoxSet::create( getWidth() ); + } + + +} // Bora namespace. diff --git a/bora/src/CMakeLists.txt b/bora/src/CMakeLists.txt new file mode 100644 index 00000000..bdaef0b0 --- /dev/null +++ b/bora/src/CMakeLists.txt @@ -0,0 +1,112 @@ +# -*- explicit-buffer-name: "CMakeLists.txt" -*- + + include_directories( ${BORA_SOURCE_DIR}/src + ${CORIOLIS_INCLUDE_DIR} + ${HURRICANE_INCLUDE_DIR} + ${CONFIGURATION_INCLUDE_DIR} + ${Boost_INCLUDE_DIRS} + ${QWT_INCLUDE_DIR} + ${QtX_INCLUDE_DIR} + ${PYTHON_INCLUDE_PATH} + ) + set( includes bora/Constants.h + bora/BoxSet.h + bora/NodeSets.h + bora/HVSetState.h + bora/ChannelRouting.h + bora/SlicingNode.h + bora/HVSlicingNode.h + bora/HSlicingNode.h + bora/VSlicingNode.h + bora/DSlicingNode.h + bora/RHVSlicingNode.h + bora/RHSlicingNode.h + bora/RVSlicingNode.h + bora/AnalogDistance.h + bora/Pareto.h + bora/BoraEngine.h + + ) + set( pyIncludes bora/PySlicingNode.h + bora/PyDSlicingNode.h + bora/PyHSlicingNode.h + bora/PyVSlicingNode.h + bora/PyRHSlicingNode.h + bora/PyRVSlicingNode.h + bora/PyBoraEngine.h + bora/PyGraphicBoraEngine.h + ) + set( mocIncludes bora/SlicingDataModel.h + bora/SlicingDataWidget.h + bora/SlicingPlotWidget.h + bora/SlicingWidget.h + bora/GraphicBoraEngine.h + ) + set( cpps BoxSet.cpp + NodeSets.cpp + HVSetState.cpp + SlicingNode.cpp + HVSlicingNode.cpp + HSlicingNode.cpp + VSlicingNode.cpp + DSlicingNode.cpp + RHVSlicingNode.cpp + RHSlicingNode.cpp + RVSlicingNode.cpp + ChannelRouting.cpp + BoraEngine.cpp + Pareto.cpp + SlicingDataModel.cpp + SlicingDataWidget.cpp + SlicingPlotWidget.cpp + SlicingWidget.cpp + GraphicBoraEngine.cpp + ) + set( pyCpps PySlicingNode.cpp + PyDSlicingNode.cpp + PyHSlicingNode.cpp + PyRHSlicingNode.cpp + PyRVSlicingNode.cpp + PyVSlicingNode.cpp + PyBoraEngine.cpp + PyGraphicBoraEngine.cpp + PyBora.cpp + ) + qtX_wrap_cpp( mocCpps ${mocIncludes} ) + + set( depLibs ${KATANA_LIBRARIES} + ${ANABATIC_LIBRARIES} + ${CORIOLIS_PYTHON_LIBRARIES} + ${CORIOLIS_LIBRARIES} + ${HURRICANE_PYTHON_LIBRARIES} + ${HURRICANE_ANALOG_LIBRARIES} + ${HURRICANE_GRAPHICAL_LIBRARIES} + ${HURRICANE_LIBRARIES} + ${CONFIGURATION_LIBRARY} + ${CIF_LIBRARY} + ${AGDS_LIBRARY} + ${LEFDEF_LIBRARIES} + ${OA_LIBRARIES} + ${QWT_LIBRARY} + ${QtX_LIBRARIES} + ${Boost_LIBRARIES} + ${PYTHON_LIBRARIES} -lutil + ) + + add_library( bora ${cpps} ${mocCpps} ) + set_target_properties( bora PROPERTIES VERSION 1.0 SOVERSION 1 ) + target_link_libraries( bora ${depLibs} ) + + add_python_module( "${pyCpps}" + "${pyIncludes}" + "pybora;1.0;1" + Bora + "bora;${depLibs}" + include/coriolis2/bora + ) + + install( TARGETS bora DESTINATION lib${LIB_SUFFIX} ) + install( FILES ${includes} + ${mocIncludes} DESTINATION include/coriolis2/bora ) + + diff --git a/bora/src/ChannelRouting.cpp b/bora/src/ChannelRouting.cpp new file mode 100644 index 00000000..eff1e744 --- /dev/null +++ b/bora/src/ChannelRouting.cpp @@ -0,0 +1,94 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./ChannelRouting.cpp" | +// +-----------------------------------------------------------------+ + + +#include "bora/ChannelRouting.h" + + +namespace Bora { + + using namespace std; + + +// ------------------------------------------------------------------- +// Class : "Bora::ChannelRouting". + + + ChannelRouting::ChannelRouting () + : _wireIntervals() + { } + + + ChannelRouting::~ChannelRouting () + { } + + + ChannelRouting* ChannelRouting::create () + { + return new ChannelRouting(); + } + + + void ChannelRouting::destroy () + { + delete this; + } + + + void ChannelRouting::reset () + { + _wireIntervals.clear(); + } + + + int ChannelRouting::getMaxCount () const + { + return _wireIntervals.getThickness(); + } + + + void ChannelRouting::insertChannel ( DbU::Unit xy1, DbU::Unit xy2, unsigned int w ) + { + cdebug_log(535,0) << "ChannelRouting::insertChannel(DbU::Unit,DbU::Unit,unsigned) [" + << DbU::getValueString(xy1) << " : " + << DbU::getValueString(xy2) << "] width:" + << w << endl; + + for ( unsigned int i=0; iclone() + , getAlignment() + , getInstance() + , getBoxSet() + ); + node->setPreset( getPreset() ); + node->setSet ( getSet() ); + node->setPlaced( getPlaced() ); + return node; + } + + + void DSlicingNode::setNFing ( int nfing ) + { _boxSet = _nodeSets->find( nfing ); } + + + int DSlicingNode::getNFing () const + { return (_boxSet) ? _boxSet->getNFing() : 1 ; } + + + double DSlicingNode::getStartParameter () const + { return _nodeSets->getStartParameter(); } + + + double DSlicingNode::getStepParameter () const + { return _nodeSets->getStepParameter(); } + + + double DSlicingNode::getCountParameter () const + { return _nodeSets->getCountParameter(); } + + + void DSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace ) + { + cdebug_log(536,1) << "DSlicingNode::_place(DbU::Unit,DbU::Unit,bool replace)" << endl; + + if (replace){ + SlicingNode::place( x, y ); + if (_instance) { + Cell* model = _instance->getMasterCell(); + _instance->setTransformation ( Transformation( _x - model->getAbutmentBox().getXMin() + , _y - model->getAbutmentBox().getYMin() ) ); + _instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); + } + } else { + if (isSet()) { + SlicingNode::place( x, y ); + + if (_instance) { + Cell* model = _instance->getMasterCell(); + Device* device = dynamic_cast( model ); + + if (device) { + TransistorFamily* tf = dynamic_cast( device ); + if (tf) { + tf->setNfing( getNFing() ); + FormFactorParameter* pff = NULL; + if ((pff = dynamic_cast(tf->getParameter("M"))) != NULL) + pff->setValue( tf->getNfing() ); + + shared_ptr layoutGenerator ( new LayoutGenerator() ); + layoutGenerator->setDevice (device); + layoutGenerator->drawLayout(); + } + } + _instance->setTransformation ( Transformation( _x - model->getAbutmentBox().getXMin() + , _y - model->getAbutmentBox().getYMin() ) ); + _instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); + } + } + } + + cdebug_tabw(536,-1); + } + + + void DSlicingNode::place ( DbU::Unit x, DbU::Unit y ) + { DSlicingNode::_place(x, y); } + + + void DSlicingNode::preDestroy () + { + SlicingNode::preDestroy(); + } + + + void DSlicingNode::destroy() + { + DSlicingNode::preDestroy(); + delete this; + } + + + void DSlicingNode::preRecursiveDestroy () + { + SlicingNode::preRecursiveDestroy(); + } + + + void DSlicingNode::recursiveDestroy () + { + DSlicingNode::preRecursiveDestroy(); + delete this; + } + + + bool DSlicingNode::checkInitialPlacement ( int& cpt ) const + { + // Notes: Initial placement criteria is having at least 2 devices + // placed at (x,y) = (0 0) + // + // jpc: Very suspicious code, have to check how it is called. + + bool initialPlacement = false; + if (cpt < 2) { + if ( (_x == 0) and (_y == 0) ) { + cpt++; + if (cpt < 2) initialPlacement = true; + } else + initialPlacement = true; + } + return initialPlacement; + } + + + void DSlicingNode::setGCell ( Anabatic::GCell* gcell ) + { + cdebug_log(535,0) << "DSlicingNode::setGCell(Anabatic::GCell*) " << gcell << endl; + + if (getParent()) { + if (getParent()->getType() == HorizontalSNode) { + if (getAlignment() == AlignLeft) { + Anabatic::GCell* strut = gcell->vcut( getX() + getWidth() ); + _gcell = gcell; + strut->setType( Anabatic::Flags::StrutGCell ); + } else if (getAlignment() == AlignCenter) { + _gcell = gcell->vcut( getX() ); + Anabatic::GCell* strut = _gcell->vcut( getX() + getWidth() ); + gcell->setType( Anabatic::Flags::StrutGCell ); + strut->setType( Anabatic::Flags::StrutGCell ); + } else if (getAlignment() == AlignRight ){ + _gcell = gcell->vcut( getX() ); + gcell->setType( Anabatic::Flags::StrutGCell ); + } + } else if (getParent()->getType() == VerticalSNode) { + if (getAlignment() == AlignBottom){ + Anabatic::GCell* strut = gcell->hcut( getY() + getHeight() ); + _gcell = gcell; + strut->setType( Anabatic::Flags::StrutGCell ); + } else if (getAlignment() == AlignCenter) { + _gcell = gcell->hcut( getY() ); + Anabatic::GCell* strut = _gcell->hcut( getY() + getHeight() ); + gcell->setType( Anabatic::Flags::StrutGCell ); + strut->setType( Anabatic::Flags::StrutGCell ); + } else if (getAlignment() == AlignTop) { + _gcell = gcell->hcut( getY() ); + gcell->setType( Anabatic::Flags::StrutGCell ); + } + } else + _gcell = gcell; + } else + _gcell = gcell; + + if (_gcell) { + if (dynamic_cast(_instance->getMasterCell())) { + _gcell->setType( Anabatic::Flags::DeviceGCell ); + } else { + _gcell->setType( Anabatic::Flags::MatrixGCell ); + if( (_gcell->getWidth() > Anabatic::Session::getSliceHeight()) + and (_gcell->getHeight() > Anabatic::Session::getSliceHeight()) ) { + _gcell->doGrid(); + } + } + } + + cdebug_log(535,0) << "> Device:" << _instance << endl; + cdebug_log(535,0) << "> GCell: " << _gcell << endl; + } + + + bool DSlicingNode::isSame ( SlicingNode* node, unsigned int flags ) const + { + bool isSame = _nodeSets->compare( node->getNodeSets(), flags ); + if ( not isSame and (flags & ShowDiff) ) + cerr << "DSlicingNode::isSame() Check " << this << " vs. " << node << endl; + return isSame; + } + + + bool DSlicingNode::isSymmetric ( SlicingNode* node, unsigned int symmetryType, unsigned int flags ) const + { + bool isSame = _nodeSets->compare( node->getNodeSets(), flags ); + if (not isSame and (flags & ShowDiff)) + cerr << Warning( "DSlicingNode::isSymmetric(): Different nodesets Check %s vs. %s." + , getString(this).c_str(), getString(node).c_str() ) << endl; + + if (_instance) { + Cell* model1 = _instance->getMasterCell(); + Cell* model2 = node->getInstance()->getMasterCell(); + Device* device1 = dynamic_cast( model1 ); + Device* device2 = dynamic_cast( model2 ); + + if (device1 and device2) { + CommonSourcePair* csp1 = dynamic_cast( model1 ); + DifferentialPair* dp1 = dynamic_cast( model1 ); + Transistor* ts1 = dynamic_cast( model1 ); + + CommonSourcePair* csp2 = dynamic_cast( model2 ); + DifferentialPair* dp2 = dynamic_cast( model2 ); + Transistor* ts2 = dynamic_cast( model2 ); + + if (csp1 and csp2) isSame = csp1->isSame( csp2 ); + else if (dp1 and dp2 ) isSame = dp1 ->isSame( dp2 ); + else if (ts1 and ts2 ) isSame = ts1 ->isSame( ts2 ); + else isSame = false; + } + + if (not isSame) + cerr << Warning( "DSlicingNode::isSymmetric(): Different devices. Check %s vs. %s." + , getString(this).c_str(), getString(node).c_str() ) << endl; + } + + return isSame; + } + + + void DSlicingNode::updateMatrixGCellPosition () + { + DbU::Unit tx = getX() -_gcell->getXMin(); + DbU::Unit ty = getY() -_gcell->getYMin(); + Anabatic::GCell* ygcell = _gcell; + Anabatic::GCell* xgcell = ygcell; + + while ( ygcell ) { + while ( xgcell ) { + xgcell->setSouthWestCorner( xgcell->getXMin() + tx, xgcell->getYMin() + ty ); + if (xgcell->getEast()->isMatrix()) xgcell = xgcell->getEast(); + else xgcell = NULL; + } + if (ygcell->getNorth()->isMatrix()) ygcell = ygcell->getNorth(); + else ygcell = NULL; + xgcell = ygcell; + } + } + + + void DSlicingNode::updateMatrixGContacts () + { + Anabatic::GCell* ygcell = _gcell; + Anabatic::GCell* xgcell = ygcell; + + while ( ygcell ) { + while ( xgcell ) { + xgcell->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + if (xgcell->getEast()->isMatrix()) xgcell = xgcell->getEast(); + else xgcell = NULL; + } + if (ygcell->getNorth()->isMatrix()) ygcell = ygcell->getNorth(); + else ygcell = NULL; + xgcell = ygcell; + } + } + + + void DSlicingNode::updateGCellPosition () + { + cdebug_log(535,0) << "DSlicingNode::updateGCellPosition() " << _gcell << endl; + + if (_gcell) { + if (_parent) { + if (_parent->getType() == HorizontalSNode) { + DbU::Unit hpitch = _rg->getHorizontalPitch(); + + if (getAlignment() == AlignLeft) { + _gcell->getEastNMatrix()->setSouthWestCorner( getX()+getWidth(), getY() ); + _gcell->getEastNMatrix()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/hpitch) + , floor(getHeight()/hpitch) + ); + } else if (getAlignment() == AlignCenter) { + _gcell->getWest()->setSouthWestCorner( _parent->getX(), getY() ); + _gcell->getWest()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/(2*hpitch)) + , floor(getHeight()/(2*hpitch)) + ); + + _gcell->getEastNMatrix()->setSouthWestCorner( getX()+getWidth(), getY() ); + _gcell->getEastNMatrix()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/(2*hpitch)) + , floor(getHeight()/(2*hpitch)) + ); + } else if (getAlignment() == AlignRight) { + _gcell->getWest()->setSouthWestCorner( _parent->getX(), getY() ); + _gcell->getWest()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/hpitch) + , floor(getHeight()/hpitch) + ); + + } + } else if (_parent->getType() == VerticalSNode) { + DbU::Unit vpitch = _rg->getVerticalPitch(); + + if (getAlignment() == AlignBottom) { + _gcell->getNorthNMatrix()->setSouthWestCorner( getX(), getY()+getHeight() ); + _gcell->getNorthNMatrix()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/vpitch) + , floor(getWidth()/vpitch) + ); + } else if (getAlignment() == AlignCenter) { + _gcell->getSouth()->setSouthWestCorner( getX(), _parent->getY() ); + _gcell->getSouth()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/(2*vpitch)) + , floor(getWidth()/(2*vpitch)) + ); + + _gcell->getNorthNMatrix()->setSouthWestCorner( getX(), getY()+getHeight() ); + _gcell->getNorthNMatrix()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/(2*vpitch)) + , floor(getWidth()/(2*vpitch)) + ); + } else if (getAlignment() == AlignTop) { + _gcell->getSouth()->setSouthWestCorner( getX(), _parent->getY() ); + _gcell->getSouth()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/vpitch) + , floor(getWidth()/vpitch) + ); + } + } + } + + if (_gcell->isMatrix()) updateMatrixGCellPosition(); + else _gcell->setSouthWestCorner( getX(), getY() ); + cdebug_log(535,0) << "| Updated:" << _gcell << endl; + } + } + + + void DSlicingNode::updateGContacts () + { + cdebug_log(535,0) << "DSlicingNode::updateGContacts() " << _gcell << endl; + + if (_gcell) { + if (_parent) { + if (_parent->getType() == HorizontalSNode) { + if (getAlignment() == AlignLeft) { + _gcell->getEastNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + } else if (getAlignment() == AlignCenter) { + _gcell->getWest()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + _gcell->getEastNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + } else if (getAlignment() == AlignRight) { + _gcell->getWest()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + } + } else if (_parent->getType() == VerticalSNode) { + if (getAlignment() == AlignBottom) { + _gcell->getNorthNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + } else if (getAlignment() == AlignCenter) { + _gcell->getSouth()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + _gcell->getNorthNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + } else if (getAlignment() == AlignTop) { + _gcell->getSouth()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + } + } + } + + if (_gcell->isMatrix()) updateMatrixGContacts(); + else _gcell->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + + cdebug_log(535,0) << "| Updated:" << _gcell << endl; + } + } + + + void DSlicingNode::restrictDevices () + { + if (_gcell) { + Anabatic::Vertex* vertex = _gcell->getObserver< Anabatic::Vertex>( Anabatic::GCell::Observable::Vertex ); + vertex->setRestricted(); + + if (not vertex->hasValidStamp()) { + if ( (_gcell->getWidth() > _gcell->getHeight()) + or (_gcell->getWidth() == _gcell->getHeight()) ) { + vertex->unsetFlags( Anabatic::Vertex::iVertical ); + vertex->setFlags ( Anabatic::Vertex::iHorizontal ); + } else { + vertex->unsetFlags( Anabatic::Vertex::iHorizontal ); + vertex->setFlags ( Anabatic::Vertex::iVertical ); + } + } + } + } + + + void DSlicingNode::printLine () const + { + cerr << "Instance: " << _instance << ", "; + SlicingNode::printLine(); + } + + + string DSlicingNode::_getString () const + { + string s = Super::_getString(); + s.insert( s.size()-1, " "+getString(_instance->getName())); + return s; + } + + + string DSlicingNode::_getTypeName () const + { return "DSlicingNode"; } + + + bool DSlicingNode::isAnalog () const + { + if (not _instance) return false; + return dynamic_cast(_instance->getMasterCell() ); + } + + + bool DSlicingNode::isDigital () const + { return not isAnalog(); } + + + bool DSlicingNode::checkCellInstances ( Cell* cell ) + { + if (not _instance) return false; + return cell->getInstance(_instance->getName()); + } + + + void DSlicingNode::resetWireOccupation () + { } + + +} // Bora namespace. diff --git a/bora/src/GraphicBoraEngine.cpp b/bora/src/GraphicBoraEngine.cpp new file mode 100644 index 00000000..dd325071 --- /dev/null +++ b/bora/src/GraphicBoraEngine.cpp @@ -0,0 +1,302 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul Chaput, Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./GraphicBoraEngine.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include +#include +#include +#include +#include +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/DebugSession.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/DataBase.h" +#include "hurricane/Library.h" +#include "hurricane/viewer/Graphics.h" +#include "hurricane/viewer/HApplication.h" +#include "hurricane/viewer/CellWidget.h" +#include "hurricane/viewer/ExceptionWidget.h" +#include "crlcore/GdsDriver.h" +#include "hurricane/analog/AnalogCellExtension.h" +#include "hurricane/analog/LayoutGenerator.h" +#include "hurricane/analog/TransistorFamily.h" +#include "bora/SlicingWidget.h" +#include "bora/SlicingDataWidget.h" +#include "bora/SlicingPlotWidget.h" +#include "bora/GraphicBoraEngine.h" +#include "bora/SlicingWidget.h" + + +namespace Bora { + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Breakpoint; + using Hurricane::DebugSession; + using Hurricane::UpdateSession; + using Hurricane::Point; + using Hurricane::Net; + using Hurricane::Graphics; + using Hurricane::ColorScale; + using Hurricane::ControllerWidget; + using Hurricane::ExceptionWidget; + using CRL::GdsDriver; + + +// ------------------------------------------------------------------- +// Class : "Bora". + + size_t GraphicBoraEngine::_references = 0; + GraphicBoraEngine* GraphicBoraEngine::_singleton = NULL; + + + BoraEngine* GraphicBoraEngine::createEngine () + { + cdebug_log(536,0) << "BoraEngine* GraphicBoraEngine::createEngine ()" << endl; + Cell* cell = getCell (); + if (_slicingWidget == NULL) _slicingWidget = new SlicingWidget(); + + BoraEngine* bora = BoraEngine::get( cell ); + if (not bora) { + bora = BoraEngine::create( cell ); + bora->setViewer( _viewer ); + _slicingWidget->setViewer( _viewer ); + } else + cerr << Warning( "%s already has a Bora engine.", getString(cell).c_str() ) << endl; + + return bora; + } + + + BoraEngine* GraphicBoraEngine::getForFramework ( unsigned int flags ) + { + cdebug_log(536,0) << "BoraEngine* GraphicBoraEngine::getForFramework(unsigned int flags) flags:" << (flags==CreateEngine) << endl; + // Currently, only one framework is avalaible: Alliance. + + BoraEngine* bora = BoraEngine::get( getCell() ); + if (bora){ + if (not _slicingWidget){ + bora->setViewer( _viewer ); + _slicingWidget = new SlicingWidget(); + _slicingWidget->setViewer( _viewer ); + connect( _slicingWidget, SIGNAL(updatePlacement ( BoxSet* )) + , this , SLOT (updatePlacementST( BoxSet* )) ); + } + return bora; + } + + if (flags & CreateEngine) { + bora = createEngine(); + if (not bora) + throw Error( "Failed to create Bora engine on %s.", getString( getCell()).c_str() ); + connect( _slicingWidget, SIGNAL(updatePlacement ( BoxSet* )) + , this , SLOT (updatePlacementST( BoxSet* )) ); + } else + throw Error( "BoraEngine not created yet, out of sequence action." ); + + return bora; + } + + + void GraphicBoraEngine::updateSlicingTree () + { + _viewer->clearToolInterrupt(); + + BoraEngine* bora = getForFramework( CreateEngine ); + bora->updateSlicingTree(); + _slicingWidget->updateContents(); + } + + + void GraphicBoraEngine::updatePlacementST ( BoxSet* boxSet ) + { + cdebug_log(536,0) << "GraphicBoraEngine::updatePlacementST(BoxSet*)" << endl; + _viewer->clearToolInterrupt(); + + BoraEngine* bora = getForFramework( CreateEngine ); + + if (bora) bora->updatePlacement( boxSet ); + } + + + void GraphicBoraEngine::updatePlacementST ( size_t index ) + { + cdebug_log(536,0) << "GraphicBoraEngine::updatePlacementST(int)" << endl; + _viewer->clearToolInterrupt(); + + BoraEngine* bora = getForFramework( CreateEngine ); + if (bora){ + BoxSet* bs = _slicingWidget->getDataWidget()->getBoxSet( index ); + bora->updatePlacement( bs ); + } + } + + + void GraphicBoraEngine::setToleranceRatio () + { + _viewer->clearToolInterrupt(); + + BoraEngine* bora = getForFramework( CreateEngine ); + if (bora) { + double ratioh = QInputDialog::getDouble( _slicingWidget + , "Set height tolerance ratio" + , "Write the desired height tolerance ratio:" + , DbU::getPhysical(bora->getToleranceRatioH(),DbU::Micro) + , 0, 10000, 2 ); + double ratiow = QInputDialog::getDouble( _slicingWidget + , "Set width tolerance ratio" + , "Write the desired width tolerance ratio:" + , DbU::getPhysical(bora->getToleranceRatioW(),DbU::Micro) + , 0, 10000, 2 ); + bora->setToleranceRatio( DbU::fromPhysical(ratioh, DbU::Micro) + , DbU::fromPhysical(ratiow, DbU::Micro) ); + _slicingWidget->updateContents(); + } + } + + + void GraphicBoraEngine::setToleranceBand () + { + _viewer->clearToolInterrupt(); + + BoraEngine* bora = getForFramework( CreateEngine ); + if (bora) { + double bandh = QInputDialog::getDouble( _slicingWidget + , "Set height tolerance band" + , "Write the desired height tolerance band:" + , DbU::getPhysical(bora->getToleranceBandH(),DbU::Micro) + , 0, 10000, 2 ); + double bandw = QInputDialog::getDouble( _slicingWidget + , "Set width tolerance band" + , "Write the desired width tolerance band:" + , DbU::getPhysical(bora->getToleranceBandW(),DbU::Micro) + , 0, 10000, 2 ); + bora->setToleranceBand( DbU::fromPhysical(bandh, DbU::Micro) + , DbU::fromPhysical(bandw, DbU::Micro) ); + _slicingWidget->updateContents(); + } + } + + + void GraphicBoraEngine::showPareto () + { + cdebug_log(536,0) << "GraphicBoraEngine::showPareto(): " << _viewer << endl; + if (_viewer) _viewer->clearToolInterrupt(); + + BoraEngine* bora = getForFramework( CreateEngine ); + if (bora) _slicingWidget->show(); + + } + + + void GraphicBoraEngine::addToMenu ( CellViewer* viewer ) + { + assert( _viewer == NULL ); + + _viewer = viewer; + _viewer->addMenu ( "analog" , "Analog" , CellViewer::TopMenu ); + if (_slicingWidget) _slicingWidget->setViewer( _viewer ); // ?? + + if (_viewer->hasMenuAction("analog.STree.create")) { + cerr << Warning( "GraphicBoraEngine::addToMenu() - Bora tool already hooked in." ) << endl; + return; + } + + _viewer->addMenu( "analog.STree", "Slicing Tree", NoFlags ); + + _viewer->addToMenu( "analog.STree.update" + , "Update possible dimensions" + , "Update the possible dimensions at each node of the SlicingTree." + , std::bind( &GraphicBoraEngine::updateSlicingTree, this ) + ); + _viewer->addToMenu( "analog.STree.setTR" + , "Set global tolerance ratio" + , "Set the tolerance of the global ratio." + , std::bind( &GraphicBoraEngine::setToleranceRatio, this ) + ); + _viewer->addToMenu( "analog.STree.setBR" + , "Set band tolerance" + , "Set the tolerance of the bands inside of the slicing tree." + , std::bind( &GraphicBoraEngine::setToleranceBand, this ) + ); + _viewer->addToMenu( "analog.STree.show" + , "Slicing tree curve" + , "Show the complete slicing tree curve." + , std::bind( &GraphicBoraEngine::showPareto, this ) + ); + } + + + const Name& GraphicBoraEngine::getName () const + { return BoraEngine::staticGetName(); } + + + Cell* GraphicBoraEngine::getCell () + { + if (_viewer == NULL) { + throw Error( "Bora: GraphicBoraEngine not bound to any Viewer." ); + return NULL; + } + if (_viewer->getCell() == NULL) { + throw Error( "Bora: No Cell is loaded into the Viewer." ); + return NULL; + } + + return _viewer->getCell(); + } + + + GraphicBoraEngine* GraphicBoraEngine::grab () + { + cdebug_log(536,0) << "GraphicBoraEngine::grab()" << endl; + if (not _references) { + _singleton = new GraphicBoraEngine(); + } + _references++; + + return _singleton; + } + + + size_t GraphicBoraEngine::release () + { + --_references; + if (not _references) { + delete _singleton; + _singleton = NULL; + } + return _references; + } + + + GraphicBoraEngine::GraphicBoraEngine () + : GraphicTool() + , _viewer (NULL) + , _slicingWidget(NULL) + { } + + + GraphicBoraEngine::~GraphicBoraEngine () + { + _slicingWidget->deleteLater(); + } + + +} // End of Bora namespace. diff --git a/bora/src/HSlicingNode.cpp b/bora/src/HSlicingNode.cpp new file mode 100644 index 00000000..d1c1cfc0 --- /dev/null +++ b/bora/src/HSlicingNode.cpp @@ -0,0 +1,453 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./HVSlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "crlcore/RoutingGauge.h" +#include "bora/HVSetState.h" +#include "bora/HSlicingNode.h" +#include "bora/RHSlicingNode.h" + + +namespace Bora { + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + + +// ------------------------------------------------------------------- +// Class : "Bora::HSlicingNode". + + + int HSlicingNode::_count = 0; + int HSlicingNode::_countAll = 0; + + + HSlicingNode::HSlicingNode ( unsigned int type, unsigned int alignment ) + : HVSlicingNode(type,alignment) + { ++_count; } + + + HSlicingNode::~HSlicingNode () + { --_count; } + + + HSlicingNode* HSlicingNode::create ( unsigned int alignment ) + { + --_countAll; + return new HSlicingNode( HorizontalSNode, alignment ); + } + + + void HSlicingNode::createRouting( DbU::Unit space ) + { + push_back( RHSlicingNode::create( space ) ); + resetSlicingTree(); + } + + + void HSlicingNode::print () const + { + cerr << "- Print from Slicing Node - " << endl; + cerr << "SlicingType: Horizontal Node" << endl; + if (isAlignLeft ()) cerr << "Alignment : Left" << endl; + else if (isAlignCenter()) cerr << "Alignment : Middle" << endl; + else if (isAlignRight ()) cerr << "Alignment : Right" << endl; + else cerr << "Alignment : Unknown" << endl; + cerr << "Tolerances : RatioH: " << DbU::getPhysical(_toleranceRatioH,DbU::Micro) + << ", RatioW: " << DbU::getPhysical(_toleranceRatioW,DbU::Micro) + << ", BandH: " << DbU::getPhysical(_toleranceBandH ,DbU::Micro) + << ", BandW: " << DbU::getPhysical(_toleranceBandW ,DbU::Micro) << endl; + + HVSlicingNode::print(); + } + + + HSlicingNode* HSlicingNode::clone ( unsigned int tr ) + { + HSlicingNode* node = HSlicingNode::create( getAlignment() ); + node->setTolerances( getToleranceRatioH() + , getToleranceRatioW() + , getToleranceBandH () + , getToleranceBandW () + ); + node->setBoxSet ( getBoxSet() ); + node->setNodeSets ( _nodeSets->clone() ); + node->setPreset ( getPreset() ); + node->setSet ( getSet() ); + node->setPlaced ( getPlaced() ); + node->setSymmetries( getSymmetries() ); + + for ( SlicingNode* child : _children ) { + if (tr == MY) node->push_front( child->clone(tr) ); + else node->push_back ( child->clone(tr) ); + } + return node; + } + + + void HSlicingNode::place ( DbU::Unit x, DbU::Unit y ) + { + if (recursiveCheckSet()) { + if (not _slicingRouting.empty()) { + destroySlicingRouting(); + resetSlicingRouting(); + } + _place(x,y); + + if (_slicingRouting.empty()) + createSlicingRouting(); + + updateCellAbutmentBox(); + } else + cerr << Warning( "HSlicingNode::place(): The SlicingTree is not completely set." ) << endl; + } + + + void HSlicingNode::replace ( DbU::Unit x, DbU::Unit y ) + { + // WARNING: This will change GCell edges. + + if (recursiveCheckSet()) { + _place( x, y, true ); + updateCellAbutmentBox(); + updateGCellPosition (); + updateGContacts (); + } else { + cerr << Warning( "HSlicingNode::replace(): The SlicingTree is not completely set." ) << endl; + } + } + + + void HSlicingNode::_place ( DbU::Unit x, DbU::Unit y, bool replace ) + { + cdebug_log(536,1) << "HSlicingNode::_place(DbU::Unit,DbU::Unit,bool)" << endl; + + vector::iterator itspace = _slicingRouting.begin(); + DbU::Unit xref = x; + DbU::Unit yref = y; + + if (isRoutingEstimated()) { + (*itspace)->_place( xref, yref, replace ); + yref += (*itspace)->getHeight(); + itspace++; + } + + for ( SlicingNode* child : _children ) { + if ( (child->isHorizontal()) or (child->isVertical()) ) { + if (child->isAlignLeft()) { + child->setX( xref ); + child->setY( yref ); + } else if (child->isAlignCenter()) { + child->setX( xref + (getWidth()/2) - (child->getWidth()/2) ); + child->setY( yref ); + } else if (child->isAlignRight()) { + child->setX( xref + getWidth() - child->getWidth() ); + child->setY( yref ); + } + } + + if (child->isAlignLeft() ) child->_place( xref , yref, replace); + else if (child->isAlignCenter()) child->_place( xref + (getWidth()/2) - (child->getWidth()/2), yref, replace); + else if (child->isAlignRight() ) child->_place( xref + getWidth() - child->getWidth() , yref, replace); + else if (child->isRouting() ) child->_place( xref , yref, replace); + else { + cerr << Warning( "HSlicingNode::_place(): Unknown Alignment in SlicingTree." ) << endl; + child->print(); + } + + xref = x; + yref += child->getHeight(); + if (isRoutingEstimated()) { + (*itspace)->_place( xref, yref, replace ); + yref += (*itspace)->getHeight(); + itspace++; + } + } + + setPlaced( Placed ); + + cdebug_tabw(536,-1); + } + + + void HSlicingNode::updateGlobalSize () + { + cdebug_log(535,1) << "HSlicingNode::updateGlobalsize() - " << this << endl; + + for ( SlicingNode* child : _children ) child->updateGlobalSize(); + + if (not getMaster()) { + if (getNbChild() == 1) { + _nodeSets->clear(); + NodeSets* node = _children[0]->getNodeSets(); + + for ( BoxSet* bs : node->getBoxSets() ) { + vector bss; + + bss.push_back( bs ); + _nodeSets->push_back( bss, bs->getHeight(), bs->getWidth(), HorizontalSNode ); + } + } else if ( not hasEmptyChildrenNodeSets() and _nodeSets->empty() ) { + HSetState state = HSetState( this ); + while ( not state.end() ) state.next(); + + _nodeSets = state.getNodeSets(); + } + if (_nodeSets->empty()) + cerr << Warning( "HSlicingNode::updateGlobalSize(): No solution has been found, try to set larger tolerances." ) << endl; + } else { + _nodeSets = _master->getNodeSets(); + } + + cdebug_log(535,0) << "Found " << _nodeSets->size() << " choices" << endl; + cdebug_tabw(535,-1); + } + + + void HSlicingNode::preDestroy () + { + HVSlicingNode::preDestroy(); + } + + + void HSlicingNode::destroy () + { + HSlicingNode::preDestroy(); + delete this; + } + + + void HSlicingNode::preRecursiveDestroy () + { + HVSlicingNode::preRecursiveDestroy(); + } + + + void HSlicingNode::recursiveDestroy () + { + HSlicingNode::preRecursiveDestroy(); + delete this; + } + + + void HSlicingNode::createSlicingRouting () + { + if (not _boxSet) { + cerr << Warning( "HSlicingNode::createSlicingRouting(): SlicingTree needs to be placed first." ) << endl; + return; + } + + size_t childrenCount = getNbChild(); + size_t ichild = 0; + DbU::Unit x = getX(); + DbU::Unit y = getY(); + DbU::Unit heightValue = 0; + + if (_parent) { + if (_parent->getType() == VerticalSNode) { + if ( (getAlignment() == AlignBottom) or (getAlignment() == AlignTop) ) { + heightValue = _parent->getHeight() - getHeight(); + } else if (getAlignment() == AlignCenter) { + heightValue = (_parent->getHeight() - getHeight()) / 2; + } + } + } + + DbU::Unit hpitch = _rg->getHorizontalPitch(); + if (heightValue % hpitch) + cerr << Warning( "HSlicingNode::createSlicingRouting(): On %s, height is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(heightValue).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; + + for ( size_t inode=0; inodesetParent( this ); + + if (inode == 0) { + if (getAlignment() == AlignBottom) node->place( x, y ); + else if ( (getAlignment() == AlignCenter) + or (getAlignment() == AlignTop) ) node->place( x, y-heightValue ); + } else + node->place( x, y ); + + if (_master) node->setMaster( _master->getSlicingRouting(inode) ); + _slicingRouting.push_back( node ); + + if (inode < childrenCount) y += getChild( ichild++ )->getHeight(); + } + + if (_master) { + if (isHSymmetry()) { + for ( size_t i=0; i<_slicingRouting.size(); ++i ) + getSlicingRouting( i )->setMaster( _master->getSlicingRouting( _slicingRouting.size()-1-i ) ); + } else { + for ( size_t i=0; i<_slicingRouting.size(); ++i ) + getSlicingRouting( i )->setMaster( _master->getSlicingRouting( i ) ); + } + } else if ( not _symmetries.empty() and isAlignCenter() ) { + for ( size_t i=0; i<(_slicingRouting.size()/2); ++i ) { + getSlicingRouting( _slicingRouting.size()-1-i )->setMaster( getSlicingRouting(i) ); + } + } + + for ( SlicingNode* child : _children ) { + if ( child->isHorizontal() or child->isVertical() ) child->createSlicingRouting(); + } + + setRoutingCreated( RoutingCreated ); + } + + + DbU::Unit HSlicingNode::getHeight () const + { + DbU::Unit hpitch = _rg->getHorizontalPitch(); + DbU::Unit height = 0; + + if (isRoutingEstimated()){ + for ( SlicingNode* child : _children ) height += child->getHeight(); + for ( RHVSlicingNode* node : _slicingRouting ) height += node ->getHeight(); + } else { + if (_boxSet != NULL) height = _boxSet->getHeight(); + } + + if (height % hpitch) + cerr << Warning( "HSlicingNode::getHeight(): On %s, height is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(height).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; + return height; + } + + + DbU::Unit HSlicingNode::getWidth () const + { + cdebug_log(536,0) << "HSlicingNode::getWidth()" << endl; + + DbU::Unit vpitch = _rg->getVerticalPitch(); + DbU::Unit width = 0; + + if (isRoutingEstimated()) { + SlicingNode* m = NULL; + for ( SlicingNode* node : _children ) { + if ( (node->getType() != RoutingSNode) and (node->getWidth() > width) ) { + width = node->getWidth(); + m = node; + } + } + if (m->isDevice()) width += vpitch*2; + } else { + if (_boxSet) width = _boxSet->getWidth(); + } + + if (width % vpitch) + cerr << Warning( "HSlicingNode::getWidth(): On %s, width is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(width).c_str() + , DbU::getValueString(vpitch).c_str() + ) << endl; + return width; + } + + + void HSlicingNode::setGCell ( Anabatic::GCell* gcell ) + { + cdebug_log(535,1) << "HSlicingNode::setGCell(), start Y: " + << _slicingRouting[0]->getY() << ", GCell:" << gcell << endl; + + Anabatic::GCell* childGCell = gcell; + Anabatic::GCell* remainGCell = gcell; + DbU::Unit y = _slicingRouting[0]->getY(); + + for ( size_t ichild=0 ; ichild<_children.size() ; ++ichild ) { + // Setting up the GCell for the channel *before* the current child. + cdebug_log(535,0) << "node[" << ichild << "] height:" + << DbU::getValueString(_slicingRouting[ ichild ]->getHeight()) << endl; + + y += _slicingRouting[ ichild ]->getHeight(); + remainGCell = childGCell->hcut( y ); + _slicingRouting[ ichild ]->setGCell( childGCell ); + childGCell = remainGCell; + + // Setting up the GCell for the current child. + cdebug_log(535,0) << "children[" << ichild << "] height:" + << DbU::getValueString(_children[ ichild ]->getHeight()) << endl; + + y += _children[ ichild ]->getHeight(); + remainGCell = childGCell->hcut( y ); + _children[ ichild ]->setGCell( childGCell ); + childGCell = remainGCell; + } + + // Setting up the GCell for the channel *after* the last child. + _slicingRouting.back()->setGCell( childGCell ); + + cdebug_tabw(535,-1); + } + + + void HSlicingNode::adjustBorderChannels () + { + if (_parent) { + if (_parent->getHeight() > getHeight()) { + DbU::Unit space = _parent->getHeight() - getHeight(); + + if (getAlignment() == AlignTop) { + RHVSlicingNode* channel = _slicingRouting.front(); + channel->setHeight( channel->getHeight() + space ); + } else if (getAlignment() == AlignCenter) { + RHVSlicingNode* firstChannel = _slicingRouting.front(); + RHVSlicingNode* lastChannel = _slicingRouting.back (); + firstChannel->setHeight( firstChannel->getHeight() + space/2 ); + lastChannel ->setHeight( lastChannel ->getHeight() + space/2 ); + } else if (getAlignment() == AlignBottom) { + RHVSlicingNode* channel = _slicingRouting.back(); + channel->setHeight( channel->getHeight() + space ); + } + } + } + + for ( SlicingNode* child : _children ) child->adjustBorderChannels(); + } + + + string HSlicingNode::_getString () const + { + string s = Super::_getString(); + return s; + } + + + string HSlicingNode::_getTypeName () const + { return "HSlicingNode"; } + + +} // Bora namespace. diff --git a/bora/src/HVSetState.cpp b/bora/src/HVSetState.cpp new file mode 100644 index 00000000..68978cef --- /dev/null +++ b/bora/src/HVSetState.cpp @@ -0,0 +1,403 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./HVSetState.cpp" | +// +-----------------------------------------------------------------+ + + +#include "bora/HVSetState.h" +#include "bora/HSlicingNode.h" +#include "bora/VSlicingNode.h" + + +namespace Bora { + + using namespace std; + + +// ------------------------------------------------------------------- +// Class : "Bora::HVSetState". + + + HVSetState::HVSetState ( HVSlicingNode* node ) + : _HVSnode ( node ) + , _counter ( 1 ) + , _currentSet() + , _nextSet () + , _nodeSets ( NodeSets::create() ) + { + initSet(); + initModulos(); + } + + + HVSetState::~HVSetState () + { } + + + NodeSets* HVSetState::getNodeSets () + { + _nodeSets->sort(); + return _nodeSets; + } + + + void HVSetState::print () + { + int index = 0; + cerr << "currentSet:" << endl; + + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; ichildgetNodeSets(); + + cerr << index << ": H = " << nodes->at(_currentSet[ichild])->getHeight() + << ", W = " << nodes->at(_currentSet[ichild])->getWidth () << endl; + } + cerr << "counter = " << _counter << endl; + cerr << "end counter = " << _modulos.back() << endl; + + cerr << "modulos:" << endl; + for ( size_t i=0 ; i<_modulos.size() ; ++i ) + cerr << i << ": modulo = " << _modulos[i] << endl; + + _nodeSets->print(); + } + + + void HVSetState::initSet () + { + _nextSet.clear(); + for ( SlicingNode* child : _HVSnode->getChildren() ) { + if (child->isPreset()) + _nextSet.push_back( child->getNodeSets()->findIndex( child->getHeight() + , child->getWidth () ) ); + else + _nextSet.push_back( 0 ); + } + _currentSet = _nextSet; + } + + + // Notes: + // + // Considering a horizontal/vertical node with X children and each children + // has N possibilities: + // + // child 0: N0 possibilities, + // child 1: N1 possibilities, + // . + // . + // . + // child X: NX possibilities. + // + // If a child is preset then, it only has 1 possibility and N = 1. So we have: + // + // number of possibilities to be studied = N0 * N1 * ... * NX. + // + // Children are seen like a and modulos are used to know when a + // child needs to choose its next possibility. + // + // It starts like this: + // - Child 0 goes through its N0 possibilities + // - When child 0 was at its last possibility, it goes back to its first one + // and child 1 pick its second possibility. + // - And we keep going . . . + + void HVSetState::initModulos () + { + cdebug_log(535,0) << "HVSetState::initModulos()" << endl; + + int modulo = 1; + + _modulos.clear(); + _modulos.push_back( 1 ); + + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; ichildisPreset() ) { + cdebug_log(535,0) << "child:" << ichild << " is preset, one choice." << endl; + continue; + } + + cdebug_log(535,0) << "child:" << ichild << " is ordinary, " + << "has " << children[ichild]->getNodeSets()->size() << " choices." + << endl; + modulo *= children[ichild]->getNodeSets()->size(); + } + + _modulos.push_back( modulo ); + + for ( size_t i=0 ; i<_modulos.size() ; ++i ) + cdebug_log(535,0) << "_modulos[" << i << "]:" << _modulos[i] << endl; + } + + + void HVSetState::next () + { + // Notes: Set the next combination. See notes above. + cdebug_log(535,0) << "HVSetState::next(): counter_:" << _counter << endl; + + Symmetry symmetry; + vector::iterator itpair = _nextSet.begin(); + + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; ichildisPreset() ) { + if (_nextSet[ichild]+1 != children[ichild]->getNodeSets()->size() ) _nextSet[ichild]++; + else _nextSet[ichild] = 0; + } + } + } + + _counter += 1; + _currentSet = _nextSet; + } + + +// ------------------------------------------------------------------- +// Class : "Bora::HSetState". + + + HSetState::HSetState ( HSlicingNode* node ) + : HVSetState(node) + { } + + + HSetState::~HSetState () + { } + + + pair HSetState::getCurrentWs () + { + // Notes: + // Calculate the min and max width of the current combination Routing nodes + // need to be taken into account to not calculate a wrong width. + + DbU::Unit wmin = 0; + DbU::Unit wmax = 0; + + if (not _currentSet.empty()) { + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; (wmin == 0) and (ichildgetNodeSets(); + wmin = nodes->at( _currentSet[ichild] )->getWidth(); + } + + for ( size_t ichild=0 ; ichildgetNodeSets(); + DbU::Unit width = nodes->at( _currentSet[ichild] )->getWidth(); + + if ( width and (width < wmin) ) wmin = width; + if (width > wmax) wmax = width; + } + } + + return pair( wmin, wmax ); + } + + + DbU::Unit HSetState::getCurrentH () + { + // Notes: + // Calculate the height of the current combination. + // Routing nodes need to be taken into account to not calculate a wrong height. + + DbU::Unit currentH = 0; + + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; ichildgetNodeSets(); + currentH += nodes->at( _currentSet[ichild] )->getHeight(); + } + + return currentH; + } + + + DbU::Unit HSetState::getCurrentW () + { + // Notes: + // Calculate the width of the current combination + // Routing nodes need to be taken into account to not calculate a wrong width. + + DbU::Unit currentW = 0; + + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; ichildgetNodeSets(); + + currentW = std::max( currentW, nodes->at( _currentSet[ichild] )->getWidth() ); + } + + return currentW; + } + + + void HSetState::print () + { + HVSetState::print(); + cerr << "currentH = " << getCurrentH() << endl; + cerr << "currentW = " << getCurrentW() << endl; + cerr << endl; + } + + + void HSetState::next () + { + push_back(); + HVSetState::next(); + } + + + void HSetState::push_back () + { + // Notes: + // Check if conditions on tolerance are filled. + // If yes, add the current set to the NodeSets + + pair paireWidths = getCurrentWs(); + DbU::Unit width = paireWidths.second; + DbU::Unit wmin = paireWidths.first; + DbU::Unit height = 0; + + if (width - wmin <= _HVSnode->getToleranceBandW()) { + vector bss; + + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; ichildgetNodeSets(); + + bss.push_back( nodes->at( _currentSet[ichild] ) ); + height += bss.back()->getHeight(); + } + + // create the BoxSet of the current accepted set. + _nodeSets->push_back( bss, height, width, HorizontalSNode ); + } + } + + +// ------------------------------------------------------------------- +// Class : "Bora::VSetState". + + + VSetState::VSetState ( VSlicingNode* node ) + : HVSetState(node) + { } + + + VSetState::~VSetState () + { } + + + pair VSetState::getCurrentHs () + { + // Note: Same as HSetState but for Vertical Node (see above). + + DbU::Unit hmin = 0; + DbU::Unit hmax = 0; + + if (not _currentSet.empty()) { + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; (hmin == 0) and (ichildgetNodeSets(); + DbU::Unit height = nodes->at( _currentSet[ichild] )->getHeight(); + + if ( height and (height < hmin) ) hmin = height; + if (height > hmax) hmax = height; + } + } + + return pair( hmin, hmax ); + } + + + DbU::Unit VSetState::getCurrentH () + { + DbU::Unit currentH = 0; + + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; ichildgetNodeSets(); + + currentH = std::max( currentH, nodes->at( _currentSet[ichild] )->getHeight() ); + } + + return currentH; + } + + + DbU::Unit VSetState::getCurrentW () + { + DbU::Unit currentW = 0; + + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; ichildgetNodeSets(); + + currentW += nodes->at( _currentSet[ichild] )->getWidth(); + } + + return currentW; + } + + + void VSetState::print () + { + HVSetState::print(); + cerr << "currentH = " << getCurrentH() << endl; + cerr << "currentW = " << getCurrentW() << endl; + cerr << endl; + } + + + void VSetState::next () + { + push_back(); + HVSetState::next(); + } + + + void VSetState::push_back () + { + pair paireHeights = getCurrentHs(); + DbU::Unit height = paireHeights.second; + DbU::Unit hmin = paireHeights.first; + DbU::Unit width = 0; + + if (height - hmin <= _HVSnode->getToleranceBandH()) { + vector bss; + + const VSlicingNodes& children = _HVSnode->getChildren(); + for ( size_t ichild=0 ; (hmin == 0) and (ichildgetNodeSets(); + + bss.push_back( nodes->at( _currentSet[ichild] ) ); + width += bss.back()->getWidth(); + } + _nodeSets->push_back( bss, height, width, VerticalSNode ); + } + } + + +} // Bora namespace. diff --git a/bora/src/HVSlicingNode.cpp b/bora/src/HVSlicingNode.cpp new file mode 100644 index 00000000..96dad935 --- /dev/null +++ b/bora/src/HVSlicingNode.cpp @@ -0,0 +1,1313 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./HVSlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/NetRoutingProperty.h" +#include "hurricane/analog/Device.h" +#include "katana/KatanaEngine.h" +#include "bora/HVSlicingNode.h" +#include "bora/HSlicingNode.h" +#include "bora/VSlicingNode.h" +#include "bora/DSlicingNode.h" +#include "bora/RHVSlicingNode.h" + + +namespace Bora { + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Point; + using Hurricane::Box; + using Hurricane::RoutingPad; + using Hurricane::NetRoutingState; + using Hurricane::NetRoutingExtension; + using Analog::Device; + + +// ------------------------------------------------------------------- +// Class : "Bora::HVSlicingNode". + + + HVSlicingNode::HVSlicingNode ( unsigned int type, unsigned int alignment ) + : Super( type, NodeSets::create(), alignment, NULL ) + , _children () + , _toleranceRatioH(0) + , _toleranceRatioW(0) + , _toleranceBandH (0) + , _toleranceBandW (0) + , _symmetries () + , _slicingRouting () + , _netSymmetries () + { } + + + HVSlicingNode::~HVSlicingNode () + { } + + + DbU::Unit HVSlicingNode::getToleranceRatioH () const + { return _toleranceRatioH; } + + + DbU::Unit HVSlicingNode::getToleranceRatioW () const + { return _toleranceRatioW; } + + + DbU::Unit HVSlicingNode::getToleranceBandH () const + { return _toleranceBandH; } + + + DbU::Unit HVSlicingNode::getToleranceBandW () const + { return _toleranceBandW; } + + + void HVSlicingNode::setToleranceRatioH ( DbU::Unit tolerance ) + { + _toleranceRatioH = tolerance; + getRoot()->_resetSlicingTree(); + } + + + void HVSlicingNode::setToleranceRatioW ( DbU::Unit tolerance ) + { + _toleranceRatioW = tolerance; + getRoot()->_resetSlicingTree(); + } + + + void HVSlicingNode::setToleranceBandH ( DbU::Unit tolerance ) + { + _toleranceBandH = tolerance; + resetSlicingTree(); + } + + + void HVSlicingNode::setToleranceBandW ( DbU::Unit tolerance ) + { + _toleranceBandW = tolerance; + resetSlicingTree(); + } + + + void HVSlicingNode::recursiveSetToleranceRatioH ( DbU::Unit tolerance ) + { + _recursiveSetToleranceRatioH( tolerance ); + getRoot()->_resetSlicingTree(); + } + + + void HVSlicingNode::recursiveSetToleranceRatioW ( DbU::Unit tolerance ) + { + _recursiveSetToleranceRatioW( tolerance ); + getRoot()->_resetSlicingTree(); + } + + + void HVSlicingNode::recursiveSetToleranceBandH ( DbU::Unit tolerance ) + { + resetSlicingTree(); + _recursiveSetToleranceBandH( tolerance ); + } + + + void HVSlicingNode::recursiveSetToleranceBandW ( DbU::Unit tolerance ) + { + resetSlicingTree(); + _recursiveSetToleranceBandW( tolerance ); + } + + + void HVSlicingNode::_recursiveSetToleranceRatioH ( DbU::Unit tolerance ) + { + for ( SlicingNode* node : _children ) { + if ( (not node->isDevice()) and (not node->isRouting()) ) + node->recursiveSetToleranceRatioH( tolerance ); + } + _toleranceRatioH = tolerance; + } + + + void HVSlicingNode::_recursiveSetToleranceRatioW ( DbU::Unit tolerance ) + { + for ( SlicingNode* node : _children ) { + if ( (not node->isDevice()) and (not node->isRouting()) ) + node->recursiveSetToleranceRatioW( tolerance ); + } + _toleranceRatioW = tolerance; + } + + + void HVSlicingNode::_recursiveSetToleranceBandH ( DbU::Unit tolerance ) + { + for ( SlicingNode* node : _children ) { + if ( (not node->isDevice()) and (not node->isRouting()) ) + node->recursiveSetToleranceBandH( tolerance ); + } + _toleranceBandH = tolerance; + } + + + void HVSlicingNode::_recursiveSetToleranceBandW ( DbU::Unit tolerance ) + { + for ( SlicingNode* node : _children ) { + if ( (not node->isDevice()) and (not node->isRouting()) ) + node->recursiveSetToleranceBandW( tolerance ); + } + _toleranceBandW = tolerance; + } + + + void HVSlicingNode::setTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ) + { + resetSlicingTree(); + _toleranceRatioH = trh; + _toleranceRatioW = trw; + _toleranceBandH = tbh; + _toleranceBandW = tbw; + } + + + void HVSlicingNode::recursiveSetTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ) + { + resetSlicingTree(); + _recursiveSetTolerances( trh, trw, tbh, tbw ); + } + + + void HVSlicingNode::_recursiveSetTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ) + { + _recursiveSetToleranceRatioH(trh); + _recursiveSetToleranceRatioW(trw); + _recursiveSetToleranceBandH (tbh); + _recursiveSetToleranceBandW (tbw); + } + + + bool HVSlicingNode::hasEmptyChildrenNodeSets () const + { + // WARNING: The original code was nonsensical, have to check it. + for ( SlicingNode* node : _children ) { + NodeSets* ns = node->getNodeSets(); + if (ns->empty() and not node->isRouting() ) + return true; + } + return false; + } + + + size_t HVSlicingNode::getChildIndex ( SlicingNode* node ) const + { + for ( size_t i=0 ; i<_children.size() ; ++i ) { + if ( (_children[i]->getType() == node->getType() ) + and (_children[i]->getHeight() == node->getHeight()) + and (_children[i]->getWidth () == node->getWidth ()) + and (_children[i]->getX() == node->getX() ) + and (_children[i]->getY() == node->getY() ) ) + return i; + } + return NodeSets::NotFound; + } + + + SlicingNode* HVSlicingNode::getChild ( size_t index ) const + { return _children[index]; } + + + void HVSlicingNode::createChild ( unsigned int type, unsigned int alignment ) + { + if (type == HorizontalSNode) { + HSlicingNode* hsn = HSlicingNode::create( alignment ); + hsn->setTolerances( getToleranceRatioH() + , getToleranceRatioW() + , getToleranceBandH () + , getToleranceBandW () + ); + push_back( hsn ); + resetSlicingTree(); + } else if (type == VerticalSNode) { + VSlicingNode* vsn = VSlicingNode::create( alignment ); + vsn->setTolerances( getToleranceRatioH() + , getToleranceRatioW() + , getToleranceBandH () + , getToleranceBandW () + ); + push_back( vsn ); + resetSlicingTree(); + } + else + cerr << Warning( "HVSlicingNode::createChild(SlicingType, Alignment): Unknown type." ) << endl; + } + + + void HVSlicingNode::createChild ( NodeSets* nodeSets + , unsigned int alignment + , Instance* instance + , BoxSet* boxSet + ) + { + DSlicingNode* node = DSlicingNode::create( nodeSets, alignment, instance, boxSet ); + node->setParent( this ); + push_back( node ); + resetSlicingTree(); + } + + + void HVSlicingNode::createChild ( size_t childIndex, size_t copyIndex, unsigned int tr ) + { + if (childIndex != copyIndex) { + SlicingNode* node = this->getChild( childIndex )->clone(tr); + insertNode( node, copyIndex ); + _symmetries.push_back( Symmetry( min(childIndex, copyIndex), max(childIndex, copyIndex) ) ); + resetSlicingTree(); + normalizeSymmetries(); + } + else + cerr << Warning( "HVSlicingNode::createChild(size_t,size_t, unsigned int): Indexes cannot be the same." ) << endl; + } + + + void HVSlicingNode::insertNode ( SlicingNode* node, size_t index ) + { + vector::iterator it = _children.begin(); + for ( size_t i=0; i < index; i++ ) { if (it != _children.end()) ++it; } + _children.insert( it, node ); + node->setParent( this ); + resetSlicingTree(); + } + + + void HVSlicingNode::push_back ( SlicingNode* node, bool reset ) + { + node->setParent( this ); + _children.push_back( node ); + if (reset) resetSlicingTree(); + } + + + void HVSlicingNode::push_front ( SlicingNode* node ) + { + node->setParent( this ); + _children.insert( _children.begin(), node ); + resetSlicingTree(); + } + + + void HVSlicingNode::removeNode ( SlicingNode* node ) + { + size_t index = 0; + for ( VSlicingNodes::iterator inode = _children.begin() + ; inode != _children.end() + ; ++inode, ++index ) { + if ((*inode) == node) { + _children.erase( inode ); + removeSymmetry( index ); + resetSlicingTree(); + node->removeParent(); + node->setX ( 0 ); + node->setY ( 0 ); + node->setPlaced ( false ); + return; + } + } + } + + + bool HVSlicingNode::isSymmetry ( size_t index, Symmetry& symmetry ) + { + if (_symmetries.empty()) return false; + + for ( LSymmetries::iterator isym=_symmetries.begin() ; isym != _symmetries.end() ; ++isym ) { + if ((*isym).second == index) { + symmetry = Symmetry( (*isym) ); + return true; + } + } + return false; + } + + + bool HVSlicingNode::isSymmetry ( size_t index ) + { + if (_symmetries.empty()) return false; + + for ( Symmetry& sym : _symmetries ) { + if (sym.second == index) return true; + } + return false; + } + + + void HVSlicingNode::addSymmetry ( size_t childIndex, size_t copyIndex, bool reset ) + { + if (childIndex >= getChildren().size()) { + cerr << Warning( "HVSlicingNode::addSymmetry(size_t,size_t): Child index out of range %d (> %d), symmetry is ignored." + , childIndex, getChildren().size() ) << endl; + return; + } + + if (copyIndex >= getChildren().size()) { + cerr << Warning( "HVSlicingNode::addSymmetry(size_t,size_t): Copy index out of range %d (> %d), symmetry is ignored." + , copyIndex, getChildren().size() ) << endl; + return; + } + + if (childIndex == copyIndex) { + cerr << Warning( "HVSlicingNode::addSymmetry(size_t,size_t): Indexes cannot be identical (%d), symmetry is ignored." + , childIndex ) << endl; + return; + } + + unsigned int symmetryType = 0; + if (getType() == HorizontalSNode) symmetryType = HSymmetry; + if (getType() == VerticalSNode ) symmetryType = VSymmetry; + + + if (not getChild(childIndex)->isSymmetric(getChild(copyIndex), symmetryType, ShowDiff)) { + cerr << Warning( "HVSlicingNode::addSymmetry(int,int)): Children %d and %d are not the same, symmetry is ignored." + , childIndex, copyIndex ) << endl; + return; + } + + _symmetries.push_back( Symmetry( min(childIndex, copyIndex), max(childIndex, copyIndex) ) ); + if (reset) resetSlicingTree(); + unsigned int flag = 0; + if (getType() == HorizontalSNode) flag = HSymmetry; + if (getType() == VerticalSNode ) flag = VSymmetry; + getChild(copyIndex)->setSymmetryFlag( flag ); + + getChild( copyIndex )->setMaster(getChild( childIndex )); + normalizeSymmetries(); + } + + + void HVSlicingNode::removeSymmetry ( size_t index ) + { + bool first = true; + bool isReference = true; + size_t erasedFirst = 0; + size_t erasedSecond = 0; + + for ( LSymmetries::iterator it = _symmetries.begin(); it != _symmetries.end(); it++ ) { + if ( ( ((*it).first == index) or ((*it).second == index)) and first ) { + LSymmetries::iterator itToerase = it; + it++; + resetSlicingTree(); + first = false; + + if ((*it).first == index){ + erasedFirst = (*itToerase).first; + erasedSecond = (*itToerase).second; + } else + isReference = false; + + _symmetries.erase(itToerase); + it--; + } else { + if ( not first and isReference ) { + if ((*it).first == erasedFirst) (*it).first = erasedSecond; + } + if ((*it).first > index) (*it).first--; + if ((*it).second > index) (*it).second--; + } + } + } + + + void HVSlicingNode::normalizeSymmetries () + { + // Notes : + // Symmetries must be described in a specific way, in case it is not, this method correct it. + // Examples: + // WRONG: Symmetries [< 1, 2 >, < 2, 3 >, < 3, 4 >]; RIGHT: [< 1, 2 >, < 1, 3 >, < 1, 4 >]; + // WRONG: Symmetries [< 3, 4 >, < 5, 6 >, < 1, 2 >]; RIGHT: [< 1, 2 >, < 3, 4 >, < 5, 6 >]; + // WRONG: Symmetries [< 1, 2 >, < 1, 2 >, < 3, 4 >]; RIGHT: [< 1, 2 >, < 3, 4 >]; + + LSymmetries adjustedSymmetries; + for ( Symmetry& sym : _symmetries ) { + if (sym.first > sym.second) adjustedSymmetries.push_back( Symmetry( sym.second, sym.first ) ); + else adjustedSymmetries.push_back( Symmetry( sym.first , sym.second ) ); + } + adjustedSymmetries.sort(); + + for ( LSymmetries::iterator isym = adjustedSymmetries.begin() + ; isym != adjustedSymmetries.end() + ; isym++ ) { + for ( LSymmetries::iterator idup = isym + ; idup != adjustedSymmetries.end() + ; idup++ ) { + if (idup == isym) continue; + + if ((*isym).second == (*idup).first) (*idup).first = (*isym).first; + if ((*isym).second < (*idup).first) break; + } + } + + _symmetries = adjustedSymmetries; + } + + + void HVSlicingNode::_resetSlicingTree () + { + _x = 0; + _y = 0; + setPlaced( false ); + + if (not isPreset()) { + _boxSet = NULL; + setSet( false ); + + for ( SlicingNode* child : _children ) child->_resetSlicingTree(); + } + } + + + void HVSlicingNode::print () const + { + SlicingNode::print(); + + if (not _symmetries.empty()) { + cerr << "Symmetries: " << endl; + for ( const Symmetry& sym : _symmetries ) + cerr << "Children: " << sym.first << " and " << sym.second << endl; + cerr << endl; + } else + cerr << "Symmetries: None" << endl; + + if (not _slicingRouting.empty()) { + cerr<< "Slicing Routing: " << endl; + + size_t index = 0; + for ( const RHVSlicingNode* node : _slicingRouting ) { + cerr << "---------------- " << setprecision(4) << index << " -----------------" << endl; + cerr << "Print - Slicing Routing: "; + cerr << "X: " << DbU::getPhysical(node->getX (), DbU::Micro); + cerr << ", Y: " << DbU::getPhysical(node->getY (), DbU::Micro); + cerr << ", height: " << DbU::getPhysical(node->getHeight(), DbU::Micro); + cerr << ", width: " << DbU::getPhysical(node->getWidth (), DbU::Micro) << endl; + cerr << "GCell: " << node->getGCell() << endl; + + if(node->getGCell()){ + cerr << "GCell : " << node->getGCell() << endl; + + cerr << "Edges : " << endl; + for ( const Anabatic::Edge* edge : node->getGCell()->getNorthEdges() ) + cerr << edge->getOpposite(node->getGCell()) << endl; + + for ( const Anabatic::Edge* edge : node->getGCell()->getSouthEdges() ) + cerr << edge->getOpposite(node->getGCell()) << endl; + + for ( const Anabatic::Edge* edge : node->getGCell()->getEastEdges() ) + cerr << edge->getOpposite(node->getGCell()) << endl; + + for ( const Anabatic::Edge* edge : node->getGCell()->getWestEdges() ) + cerr << edge->getOpposite(node->getGCell()) << endl; + } + + cerr << "------------------------------------" << endl; + ++index; + } + } else + cerr << "Slicing Routing: empty" << endl; + + cerr << endl; + } + + + void HVSlicingNode::printChildren () const + { + size_t index = 0; + for ( const SlicingNode* child : _children ) { + if ( child->isDevice() or child->isRouting() ) { + cerr << "-- Children: " << index << "/" << _children.size()-1 << " --" << endl; + child->print(); + } else { + cerr << "-- Children: " << index << "/" << _children.size()-1 << " --" << endl; + child->print(); + child->printChildren(); + } + ++index; + } + } + + + void HVSlicingNode::printLine () const + { + SlicingNode::printLine(); + + if (not _symmetries.empty()) { + cerr << "Symmetries: " << endl; + for ( const Symmetry& sym : _symmetries ) + cerr << "Children: " << sym.first << " and " << sym.second << endl; + cerr << endl; + } + } + + + void HVSlicingNode::printChildrenLine () const + { + size_t index = 0; + for ( const SlicingNode* child : _children ) { + if ( child->isDevice() or child->isRouting() ) { + cerr << "-- Children: " << index << "/" << _children.size()-1 << " --" << endl; + child->printLine(); + } else { + cerr << endl; + cerr << "-- Children: " << index << "/" << _children.size()-1 << " --" << endl; + child->printLine(); + child->printChildrenLine(); + } + ++index; + } + } + + + bool HVSlicingNode::recursiveCheckPreset () const + { + bool preset = isPreset(); + if (preset) { + for ( const SlicingNode* child : _children ) preset = child->recursiveCheckPreset(); + } + return preset; + } + + + bool HVSlicingNode::recursiveCheckSet () const + { + bool rset = isSet(); + if (rset) { + for ( const SlicingNode* child : _children ) rset = child->recursiveCheckSet(); + } + return rset; + } + + + bool HVSlicingNode::recursiveCheckPlaced () const + { + bool placed = isPlaced(); + if (placed) { + for ( const SlicingNode* child : _children ) placed = child->recursiveCheckPlaced(); + } + return placed; + } + + + int HVSlicingNode::getLeafNumber() const + { + int leafs = 0; + for ( const SlicingNode* child : _children ) leafs += child->getLeafNumber(); + return leafs; + } + + + double HVSlicingNode::getDevicesArea () const + { + double area = 0.0; + for ( const SlicingNode* child : _children ) area += child->getDevicesArea(); + return area; + } + + + double HVSlicingNode::getOccupationArea () const + { + double estimation = 0; + if (recursiveCheckPlaced()) + estimation = (100 * getDevicesArea()) / (getHeight() * getWidth()); + else + cerr << Warning( "HVSlicingNode::getSpaceEstimation()): SlicingNodes dimensions need to be set first before being estimated." ) << endl; + + return estimation; + } + + + void HVSlicingNode::setGlobalSize ( DbU::Unit height, DbU::Unit width ) + { + if (not _nodeSets->empty()) { + DbU::Unit bestH = 0; + DbU::Unit bestW = 0; + DbU::Unit currentH = 0; + DbU::Unit currentW = 0; + BoxSet* boxSet = _nodeSets->at( 0 ); + + for ( BoxSet* bs : _nodeSets->getBoxSets() ) { + currentH = bs->getHeight(); + currentW = bs->getWidth(); + if ( (currentH <= height) and (currentW <= width) ) { + if ( ((height-currentH) <= _toleranceRatioH) and ((height-bestH) <= _toleranceRatioH) ) { + if (currentW > bestW) { + bestH = currentH; + bestW = currentW; + boxSet = bs; + } + } else if (currentH > bestH) { + bestH = currentH; + bestW = currentW; + boxSet = bs; + } + } + } + + _setGlobalSize( boxSet ); + } else + cerr << Warning( "HVSlicingNode::setGlobalSize(DbU::Unit h, DbU::Unit w): NodeSets empty. UpdateGlobalSize needs to be used first or with higher tolerances." ) << endl; + } + + + void HVSlicingNode::setGlobalSize ( size_t index ) + { + if (not _nodeSets->empty()) { + if (index+1 > _nodeSets->size()) + cerr << Warning( "HVSlicingNode::setGlobalSize(size_t): Out of bound index." ) << endl; + else + _setGlobalSize( _nodeSets->at(index) ); + } else + cerr << Warning( "HVSlicingNode::setGlobalSize(size_t): NodeSets empty. UpdateGlobalSize needs to be used first or with higher tolerances." ) << endl; + } + + + void HVSlicingNode::_setGlobalSize ( BoxSet* boxSet ) + { + if (not isPreset()) { + if (not getMaster()) + _setBoxSet( boxSet ); + else + _setBoxSet( _master->getBoxSet() ); + + if ( ((getType() == HorizontalSNode) and (isHSymmetry())) + or ((getType() == VerticalSNode ) and (isVSymmetry())) ) { + vector::const_iterator ibs = boxSet->getSet().begin(); + for ( VSlicingNodes::reverse_iterator ichild = _children.rbegin() + ; ichild != _children.rend(); ++ichild ) { + (*ichild)->_setGlobalSize( *ibs ); + ibs++; + } + } else { + vector::const_iterator ibs = boxSet->getSet().begin(); + for ( VSlicingNodes::iterator ichild = _children.begin() + ; ichild != _children.end(); ichild++){ + (*ichild)->_setGlobalSize( *ibs ); + ibs++; + } + } + } + } + + + void HVSlicingNode::preDestroy () + { + Super::preDestroy(); + for ( SlicingNode* child : _children ) child->removeParent(); + } + + + void HVSlicingNode::destroy () + { + HVSlicingNode::preDestroy(); + delete this; + } + + + void HVSlicingNode::preRecursiveDestroy () + { + Super::preRecursiveDestroy(); + for ( SlicingNode* child : _children ) { + if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) { + child->removeParent(); + child->recursiveDestroy(); + } else { + child->removeParent(); + child->destroy(); + } + } + } + + + void HVSlicingNode::recursiveDestroy () + { + HVSlicingNode::preRecursiveDestroy(); + delete this; + } + + + LSlicingNodes HVSlicingNode::getLeaves () + { + LSlicingNodes leaves; + for ( SlicingNode* child : _children ) { + if ( (child->getType() == DeviceSNode) or (child->getType() == RoutingSNode) ) + leaves.push_back( child ); + else + leaves.splice( leaves.end(), child->getLeaves() ); + } + return leaves; + } + + + bool HVSlicingNode::checkInitialPlacement ( int& cpt ) const + { + // Notes:: + // Initial placement criteria is having at least 2 devices placed at (x,y) = (0,0) + + bool initialPlacement = false; + if (cpt < 2) { + initialPlacement = true; + for ( const SlicingNode* child : _children ) { + if (cpt < 2) initialPlacement = child->checkInitialPlacement( cpt ); + } + } + return initialPlacement; + } + + + bool HVSlicingNode::isSame ( SlicingNode* node, unsigned int flags ) const + { + if ( (getType() == node->getType() ) + and (getNbChild() == node->getNbChild() ) + and (getToleranceBandH() == node->getToleranceBandH()) + and (getToleranceBandW() == node->getToleranceBandW()) ) { + bool isSame = true; + + for ( size_t ichild = 0 ; isSame and (ichild < getNbChild()) ; ++ichild ) { + isSame = getChild(ichild)->isSame( node->getChild(ichild) ); + } + + if (not isSame and (flags & ShowDiff)) + cerr << "HVSlicingNode::isSame() " << this << " and " << node << " differs (childs)." << endl; + + return isSame; + } else { + if (flags & ShowDiff) + cerr << "HVSlicingNode::isSame() " << this << " and " << node << " differs." << endl; + return false; + } + } + + + bool HVSlicingNode::checkCellInstances ( Cell* cell ) + { + if (not cell) { + cerr << Warning( "HVSlicingNode::checkCellInstances(): Cell is NULL." ) << endl; + return false; + } + + for ( SlicingNode* child : _children ) { + if (not child->checkCellInstances(cell)) return false; + } + return true; + } + + + SlicingNode* HVSlicingNode::findInstance ( Instance* instance ) + { + for ( SlicingNode* child : _children ) { + if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) { + SlicingNode* node = child->findInstance( instance ); + if (node) return node; + } else if (child->getType() == DeviceSNode) { + if ( child->getInstance() == instance ) + return child; + } + } + return NULL; + } + + + SlicingNode* HVSlicingNode::findSlicingNode ( Anabatic::GCell* gcell ) + { + if (getGCell() == gcell) return this; + + for ( RHVSlicingNode* node : _slicingRouting ) { + if (node->getGCell() == gcell) return node; + } + + for ( SlicingNode* child : _children ) { + if( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) { + SlicingNode* node = child->findSlicingNode( gcell ); + if (node) return node; + } else if (child->getType() == DeviceSNode) { + if (child->getGCell() == gcell) + return child; + } + } + + return NULL; + } + + + void HVSlicingNode::resetSlicingRouting () + { + for ( RHVSlicingNode* node : _slicingRouting ) node->resetSize(); + for ( SlicingNode* child : _children ) { + if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) + child->resetSlicingRouting(); + } + setRoutingEstimated(0); + } + + + void HVSlicingNode::destroySlicingRouting () + { + for ( RHVSlicingNode* node : _slicingRouting ) node->destroy(); + _slicingRouting.clear(); + + for ( SlicingNode* child : _children ) { + if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) + child->destroySlicingRouting(); + } + + setRoutingEstimated(0); + } + + + size_t HVSlicingNode::getRoutingIndex ( SlicingNode* node ) const + { + size_t index = 0; + for ( const RHVSlicingNode* node : _slicingRouting ) { + if ( (node->getHeight() == node->getHeight()) + and (node->getWidth () == node->getWidth ()) + and (node->getX () == node->getX ()) + and (node->getY () == node->getY ()) ) + return index; + ++index; + } + + return NodeSets::NotFound; + } + + + SlicingNode* HVSlicingNode::getSlicingRouting ( size_t index ) const + { return _slicingRouting.at( index ); } + + + void HVSlicingNode::restrictDevices () + { + for ( SlicingNode* child : _children ) child->restrictDevices(); + for ( RHVSlicingNode* node : _slicingRouting ) node ->restrictDevices(); + } + + + void HVSlicingNode::setVertexRestriction ( Net* net, Katana::KatanaEngine* katana ) + { + cdebug_log(536,1) << "HVSlicingNode::setVertexRestriction(Net*,KatanaEngine*)" << endl; + + restrictDevices(); + vector rps; + for ( RoutingPad* rp : net->getRoutingPads() ) rps.push_back( rp ); + for ( RoutingPad* rp : rps ) { + Box rpBb = rp->getBoundingBox(); + Point center = rpBb.getCenter(); + Anabatic::GCell* gcell = katana->getGCellUnder( center ); + + if (not gcell) { + cerr << Error( "HVSlicingNode::setVetexRestriction(): %s of %s is not under any GCell.\n" + " It will be ignored ans the routing will be incomplete." + , getString(rp ).c_str() + , getString(net).c_str() + ) << endl; + continue; + } + + Anabatic::Vertex* vertex = gcell->getObserver(Anabatic::GCell::Observable::Vertex); + // Analog Restrictions + Plug* plug = dynamic_cast( rp->getPlugOccurrence().getEntity() ); + Cell* cell = plug->getInstance()->getMasterCell(); + Device* device = dynamic_cast( cell ); + + if (device) { + cdebug_log(536,0) << "Underlying device: " << device << endl; + + unsigned int rule = device->getRestrictions2(plug->getMasterNet()); + vertex->clearRestriction(); + + cdebug_log(536,0) << "Restrictions rule: " << rule << endl; + if (rule & WestBlocked ) vertex->setWRestricted(); + if (rule & EastBlocked ) vertex->setERestricted(); + if (rule & SouthBlocked) vertex->setSRestricted(); + if (rule & NorthBlocked) vertex->setNRestricted(); + cdebug_log(536,0) << "Applied restrictions: " << vertex << endl; + } else { + vertex->clearRestriction(); + } + } + + cdebug_tabw(536,-1); + } + + + void HVSlicingNode::estimateChannelsSize () + { + for ( RHVSlicingNode* node : _slicingRouting ) node ->estimateChannelsSize(); + for ( SlicingNode* child : _children ) child->estimateChannelsSize(); + } + + + void HVSlicingNode::expandRoutingChannel () + { + estimateChannelsSize(); + _expandRoutingChannel(); + } + + + void HVSlicingNode::_expandRoutingChannel () + { + for ( RHVSlicingNode* node : _slicingRouting ) node->_expandRoutingChannel(); + for ( SlicingNode* child : _children ) { + if (child->getType() != RoutingSNode) child->_expandRoutingChannel(); + } + setRoutingEstimated(RoutingEstimated); + if (not _parent) { + for ( SlicingNode* child : _children ) child->adjustBorderChannels(); + } + } + + + void HVSlicingNode::expandRoutingChannel ( DbU::Unit height, DbU::Unit width ) + { + for ( RHVSlicingNode* node : _slicingRouting ) node->expandRoutingChannel( height, width ); + for ( SlicingNode* child : _children ) { + if (child->getType() != RoutingSNode) child->expandRoutingChannel( height, width ); + } + setRoutingEstimated( RoutingEstimated ); + if (_parent == NULL) + for ( SlicingNode* child : _children ) child->adjustBorderChannels(); + } + + + bool HVSlicingNode::isRoutingEstimated () const + { + bool estimated = true; + if (_slicingRouting.empty()){ + estimated = false; + } else { + for ( RHVSlicingNode* node : _slicingRouting ) estimated &= node->isRoutingEstimated(); + } + + for ( SlicingNode* child : _children ) { + if ( (child->getType() == HorizontalSNode ) or (child->getType() == VerticalSNode) ) + estimated &= child->isRoutingEstimated(); + } + + return estimated; + } + + + void HVSlicingNode::updateGCellPosition () + { + cdebug_log(535,1) << "HVSlicingNode::updateGCellPosition()" << endl; + + for ( SlicingNode* node : _slicingRouting ) node ->updateGCellPosition(); + for ( SlicingNode* child : _children ) child->updateGCellPosition(); + + cdebug_tabw(535,-1); + } + + + void HVSlicingNode::updateGContacts () + { + cdebug_log(535,1) << "HVSlicingNode::updateGContacts()" << endl; + + for ( SlicingNode* node : _slicingRouting ) node ->updateGContacts(); + for ( SlicingNode* child : _children ) child->updateGContacts(); + + cdebug_tabw(535,-1); + } + + + void HVSlicingNode::clearGCells () + { + for ( RHVSlicingNode* node : _slicingRouting ) node ->clearGCells(); + for ( SlicingNode* child : _children ) child->clearGCells(); + _gcell = NULL; + } + + + int HVSlicingNode::getNbDevices () + { + int count = 0; + for ( SlicingNode* child : _children ) count += child->getNbDevices(); + return count; + } + + + string HVSlicingNode::_getString () const + { + string s = Super::_getString(); + s.insert( s.size()-1, " childs:" + getString(_children.size()) ); + return s; + } + + + string HVSlicingNode::_getTypeName () const + { return "HVSlicingNode"; } + + + void HVSlicingNode::setSymmetryFlag ( unsigned int flag ) + { + SlicingNode::setSymmetryFlag( flag ); + for ( RHVSlicingNode* node : _slicingRouting ) node ->setSymmetryFlag( flag ); + for ( SlicingNode* child : _children ) child->setSymmetryFlag( flag ); + } + + + void HVSlicingNode::setMaster ( SlicingNode* master ) + { + _master = master; + + if ( ((getType() == HorizontalSNode) and isHSymmetry()) + or ((getType() == VerticalSNode ) and isVSymmetry()) ) { + for ( size_t i=0 ; i<_children.size() ; ++i ) + _children[ _children.size()-1 - i ]->setMaster( master->getChild(i) ); + } else { + for ( size_t i=0 ; i<_children.size() ; ++i ) + _children[ i ]->setMaster( master->getChild(i) ); + } + } + + + bool HVSlicingNode::isSymmetric ( SlicingNode* node, unsigned int symmetryType, unsigned int flags ) const + { + if ( (getType() == node->getType() ) + and (getNbChild() == node->getNbChild() ) + and (getToleranceBandH() == node->getToleranceBandH()) + and (getToleranceBandW() == node->getToleranceBandW()) ) { + bool isSame = true; + + if ( ((getType() == HorizontalSNode) and (symmetryType == HSymmetry)) + or ((getType() == VerticalSNode ) and (symmetryType == VSymmetry)) ) { + size_t nbChilds = _children.size(); + for ( size_t i=0 ; isSame and (iisSymmetric( node->getChild(nbChilds-1-i), symmetryType ); + } + } else { + size_t nbChilds = _children.size(); + for ( size_t i=0 ; isSame and (iisSymmetric( node->getChild(i), symmetryType ); + } + } + + if (not isSame and (flags & ShowDiff)) + cerr << Warning( "HVSlicingNode::isSame() %s and %s differs (childs)." + , getString(this).c_str() + , getString(node).c_str() ) << endl; + return isSame; + } + + if (flags & ShowDiff) + cerr << Warning( "HVSlicingNode::isSame() %s and %s differs." + , getString(this).c_str() + , getString(node).c_str() ) << endl; + return false; + } + + + bool HVSlicingNode::checkSymmetryNet ( unsigned int type, Net* net1, Net* net2 ) const + { + for ( const NetSymmetry& netSym : _netSymmetries ) { + if ( (get<1>(netSym) == net1) + and (get<2>(netSym) == net2) + and (get<0>(netSym) == type) ) + return true; + } + return false; + } + + + void HVSlicingNode::addSymmetryNet ( unsigned int type, Net* net1, Net* net2 ) + { + if (checkSymmetryNet(type,net1,net2)) { + cerr << Warning( "HVSlicingNode::addSymmetryNet(): Net symmetry already set." ) << endl; + return; + } + + unsigned int ftype = type; + if (type == 1) ftype = NetRoutingState::Vertical; + else if (type == 2) ftype = NetRoutingState::Horizontal; + _netSymmetries.push_back( make_tuple(ftype,net1,net2) ); + } + + + void HVSlicingNode::updateNetConstraints () + { + if (not _cell) { + cerr << Warning( "HVSlicingNode::updateNetConstraints(): Cell not set." ) << endl; + return; + } + + for ( NetSymmetry& netSym : _netSymmetries ) { + if (get<2>(netSym)) { + Net* masterNet = get<1>(netSym); + if (not masterNet) + cerr << Warning( "HVSlicingNode::updateNetConstraints() Reference Net not set." ) << endl; + else { + NetRoutingState* masterState = NetRoutingExtension::get( masterNet ); + if (not masterState) masterState = NetRoutingExtension::create( masterNet ); + + masterState->setFlags ( NetRoutingState::AutomaticGlobalRoute + | NetRoutingState::Symmetric + | NetRoutingState::SymmetricMaster + | get<0>(netSym) ); + + Net* slaveNet = get<2>(netSym); + NetRoutingState* slaveState = NetRoutingExtension::get( slaveNet ); + if (not slaveState) slaveState = NetRoutingExtension::create( slaveNet ); + + slaveState ->setFlags ( NetRoutingState::AutomaticGlobalRoute + | NetRoutingState::Symmetric + | get<0>((netSym)) ); + slaveState ->setSymNet( masterNet ); + masterState->setSymNet( slaveNet ); + } + } else { + Net* net = get<1>(netSym); + if (not net) + cerr << Warning( "HVSlicingNode::updateNetConstraints() Single master Net not set." ) << endl; + else { + NetRoutingState* state = NetRoutingExtension::get( net ); + if (not state) state = NetRoutingExtension::create( net ); + + state->setFlags( NetRoutingState::AutomaticGlobalRoute + | NetRoutingState::Symmetric + | get<0>(netSym) ); + } + } + } + + for ( SlicingNode* child : _children ) { + if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) + child->updateNetConstraints(); + } + } + + + void HVSlicingNode::updateSymNetAxis () + { + if (not _cell) { + cerr << Warning( "HVSlicingNode::updateSymNetAxis(): Cell not set." ) << endl; + return; + } + + for ( const NetSymmetry& symNet : _netSymmetries ) { + SlicingNode* n1 = getChild( _symmetries.front().first ); + SlicingNode* n2 = getChild( _symmetries.front().second ); + DbU::Unit xCenter = (n1->getX() + n2->getX() + n2->getWidth())/2; + DbU::Unit yCenter = (n1->getY() + n2->getY() + n2->getHeight())/2; + + if (get<2>(symNet)) { + Net* masterNet = get<1>( symNet ); + if (not masterNet) + cerr << Warning( "HVSlicingNode::updateSymNetAxis() Master net not set." ) << endl; + else { + NetRoutingState* masterState = NetRoutingExtension::get( masterNet ); + if (not masterState) + cerr << Warning( "HVSlicingNode::updateSymNetAxis(): UpdateNetConstraint need to be called first." ) << endl; + else { + if (get<0>(symNet) == NetRoutingState::Vertical ) masterState->setSymAxis( xCenter ); + else if (get<0>(symNet) == NetRoutingState::Horizontal) masterState->setSymAxis( yCenter ); + else + cerr << Warning( "HVSlicingNode::updateSymNetAxis(): Unknown NetRoutingState type." ) << endl; + + Net* slaveNet = get<2>(symNet); + NetRoutingState* slaveState = NetRoutingExtension::get( slaveNet ); + if (not slaveState) + cerr << Warning( "HVSlicingNode::updateSymNetAxis(): updateSymNetAxis need to be called first." ) << endl; + else { + if (get<0>(symNet) == NetRoutingState::Vertical ) slaveState->setSymAxis( xCenter ); + else if (get<0>(symNet) == NetRoutingState::Horizontal) slaveState->setSymAxis( yCenter ); + else + cerr << Warning( "HVSlicingNode::updateSymNetAxis(): Unknown NetRoutingState type." ) << endl; + } + } + } + } else { + Net* net = get<1>(symNet); + if (not net) + cerr << Warning( "HVSlicingNode::updateSymNetAxis() Signle master net not set." ) << endl; + else { + NetRoutingState* state = NetRoutingExtension::get( net ); + if (not state) + cerr << Warning( "HVSlicingNode::updateSymNetAxis(): UpdateNetConstraint need to be called first." ) << endl; + else { + if (get<0>(symNet) == NetRoutingState::Vertical ) state->setSymAxis( xCenter ); + else if (get<0>(symNet) == NetRoutingState::Horizontal) state->setSymAxis( yCenter ); + else + cerr << Warning( "HVSlicingNode::updateSymNetAxis(): Unknown NetRoutingState type." ) << endl; + } + } + } + + for ( SlicingNode* child : _children ) { + if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) + child->updateSymNetAxis(); + } + } + } + + + void HVSlicingNode::flattenDigitalNets () + { + if (not _cell) { + cerr << Warning( "HVSlicingNode::flattenDigitalNets(): Cell not set." ) << endl; + return; + } + + for ( SlicingNode* child : _children ) { + if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) { + child->flattenDigitalNets(); + } else if (child->getType() == DeviceSNode) { + if ( child->getGCell() + and child->getInstance() + and child->getGCell()->isMatrix()) { + _cell->flattenNets( child->getInstance() + , Cell::Flags::BuildRings|Cell::Flags::WarnOnUnplacedInstances ); + } + } + } + } + + + void HVSlicingNode::updateWireOccupation ( Anabatic::Dijkstra* dijkstra ) + { + cdebug_log(535,1) << "HVSlicingNode::updateWireOccupation() on " << this << endl; + + if (not _parent) { + for ( Anabatic::Vertex* vertex : dijkstra->getSources() ) { + cdebug_log(535,0) << "> " << vertex << endl; + + Anabatic::GCell* gcell = vertex->getGCell(); + SlicingNode* snode = findSlicingNode( gcell ); + + if (snode) { + cdebug_log(535,0) << "| isRouting():" << snode->isRouting() << endl; + + if (snode->isRouting() and vertex->hasAData() ) + snode->addWireOccupation( vertex->getIMin(), vertex->getIMax(), dijkstra->getNet() ); + } + } + } + + cdebug_tabw(535,-1); + } + + + void HVSlicingNode::resetWireOccupation () + { + for ( RHVSlicingNode* node : _slicingRouting ) node ->resetWireOccupation(); + for ( SlicingNode* child : _children ) child->resetWireOccupation(); + } + + +} // Bora namespace. diff --git a/bora/src/NodeSets.cpp b/bora/src/NodeSets.cpp new file mode 100644 index 00000000..0db644db --- /dev/null +++ b/bora/src/NodeSets.cpp @@ -0,0 +1,364 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./NodeSets.cpp" | +// +-----------------------------------------------------------------+ + + +#include "bora/NodeSets.h" +#include "hurricane/Warning.h" +#include "hurricane/analog/Device.h" +#include "hurricane/analog/TransistorFamily.h" +#include "hurricane/analog/LayoutGenerator.h" +#include "crlcore/RoutingGauge.h" + + +namespace Bora { + + using namespace Hurricane; + using namespace Analog; + + + NodeSets::NodeSets ( double start, double step, double count ) + : _boxSets() + , _start ( start ) + , _step ( step ) + , _count ( count ) + { } + + + NodeSets::NodeSets ( const NodeSets* other ) + : _boxSets( other->getBoxSets() ) + , _start ( other->getStartParameter() ) + , _step ( other->getStepParameter() ) + , _count ( other->getCountParameter() ) + { } + + + NodeSets::~NodeSets () + { } + + + NodeSets* NodeSets::create ( Cell* cell + , double start + , double step + , double count + , CRL::RoutingGauge* rg ) + { + NodeSets* nodeset = new NodeSets( start, step, count ); + + if (not cell) return nodeset; + + Device* dev = dynamic_cast( cell ); + if (dev) { + //cdebug_log(536,0) << "createNodeSets for an Analog Device" << endl; + TransistorFamily* tf = dynamic_cast(dev); + + for ( int i = 0; i < count; ++i ) { + tf->setNfing( start + i*step ); + + FormFactorParameter* pff = NULL; + if ( (pff = dynamic_cast(tf->getParameter("M"))) != NULL ) + pff->setValue( tf->getNfing() ); + + auto_ptr layoutGenerator ( new LayoutGenerator() ); + layoutGenerator->setDevice( dev ); + layoutGenerator->drawLayout(); + + if (rg) { + float h2pitch = rg->getHorizontalPitch()*2; + float v2pitch = rg->getVerticalPitch ()*2; + + float h = dev->getAbutmentBox().getHeight(); + float w = dev->getAbutmentBox().getWidth(); + + if (fmod(h,h2pitch) > 1e-06) { + cerr << Warning( "NodeSets::create(): The height of device \"%s\" (%s) is not pitched on 2*%s (adjusted)." + , getString(dev->getName()).c_str() + , DbU::getValueString(dev->getAbutmentBox().getWidth()).c_str() + , DbU::getValueString(rg->getHorizontalPitch()*2).c_str() + ) << endl; + } + if (fmod(w,v2pitch) > 1e-06) { + cerr << Warning( "NodeSets::create(): The width of device \"%s\" (%s) is not pitched on 2*%s (adjusted)." + , getString(dev->getName()).c_str() + , DbU::getValueString(dev->getAbutmentBox().getWidth()).c_str() + , DbU::getValueString(rg->getVerticalPitch()*2).c_str() + ) << endl; + } + + nodeset->push_back( DBoxSet::create( ceil(h/h2pitch)*h2pitch + , ceil(w/v2pitch)*v2pitch + , start + i*step + ) ); + } else { + nodeset->push_back( DBoxSet::create( dev->getAbutmentBox().getHeight() + , dev->getAbutmentBox().getWidth() + , start + i*step + ) ); + } + } + } else { + //cdebug_log(536,0) << "createNodeSets for a Digital Device: " << cell << endl; + if (rg) { + DbU::Unit h2pitch = rg->getHorizontalPitch()*2; + DbU::Unit v2pitch = rg->getVerticalPitch ()*2; + DbU::Unit h = cell->getAbutmentBox().getHeight(); + DbU::Unit w = cell->getAbutmentBox().getWidth(); + + if (h % h2pitch) { + cerr << Warning( "NodeSets::create(): The height of device \"%s\" (%s) is not pitched on %s*2 (adjusted)." + , getString(cell->getName()).c_str() + , DbU::getValueString(cell->getAbutmentBox().getHeight()).c_str() + , DbU::getValueString(rg->getHorizontalPitch()).c_str() + ) << endl; + } + if (w % v2pitch) { + cerr << Warning( "NodeSets::create(): The width of device \"%s\" (%s) is not pitched on %s*2 (adjusted)." + , getString(cell->getName()).c_str() + , DbU::getValueString(cell->getAbutmentBox().getWidth()).c_str() + , DbU::getValueString(rg->getVerticalPitch()).c_str() + ) << endl; + } + + nodeset->push_back( DBoxSet::create( ceil(h/h2pitch)*h2pitch + , ceil(w/v2pitch)*v2pitch + ) ); + } else { + nodeset->push_back( DBoxSet::create( cell->getAbutmentBox().getHeight() + , cell->getAbutmentBox().getWidth() + ) ); + } + } + + return nodeset; + } + + + // NodeSets* NodeSets::create () + // { + // return new NodeSets(); + // } + + + BoxSet* NodeSets::operator[] ( size_t i ) + { + if (i < _boxSets.size()) return _boxSets[i]; + return NULL; + } + + + BoxSet* NodeSets::at ( size_t i ) + { + if (i < _boxSets.size()) return _boxSets[i]; + return NULL; + } + + + void NodeSets::clear () + { + if (not _boxSets.empty()) { + for ( BoxSet* bs : _boxSets ) bs->destroy(); + } + _boxSets.clear(); + } + + + BoxSet* NodeSets::getPairH ( DbU::Unit height ) const + { + DbU::Unit w = 0; + DbU::Unit hclosest = 0; + BoxSet* boxSet = (*_boxSets.begin()); + + for ( BoxSet* bs : _boxSets ) { + if ( (bs->getHeight() > hclosest) and (height >= bs->getHeight()) ) { + hclosest = bs->getHeight(); + w = bs->getWidth (); + boxSet = bs; + } + } + + if ( (w == 0) and (hclosest == 0) ) + cerr << Warning( "NodeSets::getPairH(): No solution for h=%s has been found." + , DbU::getValueString(height).c_str() ) << endl; + + return boxSet; + } + + + BoxSet* NodeSets::getPairHW ( DbU::Unit height, DbU::Unit width ) const + { + vector::const_iterator it = _boxSets.begin(); + DbU::Unit bestH = (*it)->getHeight(); + DbU::Unit bestW = (*it)->getWidth(); + DbU::Unit currentH = 0; + DbU::Unit currentW = 0; + BoxSet* boxSet = (*it); + + while ( it != _boxSets.end() ) { + currentH = (*it)->getHeight(); + currentW = (*it)->getWidth (); + + if (currentH <= height) { + if (currentH > bestH) { + bestH = currentH; + bestW = currentW; + boxSet = (*it); + } else if (currentH == bestH) { + if ( (currentW > bestW) and (currentW <= width) ) { + bestH = currentH; + bestW = currentW; + boxSet = (*it); + } + else if ( (currentW < bestW) and (bestW > width) ) { + bestH = currentH; + bestW = currentW; + boxSet = (*it); + } + } + ++it; + } else { + it = _boxSets.end(); + } + } + + return boxSet; + } + + + BoxSet* NodeSets::getPairHW ( unsigned int index ) const + { + if (index < _boxSets.size()) return _boxSets[index]; + return NULL; + } + + + size_t NodeSets::findIndex ( DbU::Unit height, DbU::Unit width ) const + { + for ( size_t i=0 ; i<_boxSets.size() ; ++i ) { + if ( (_boxSets[i]->getHeight() == height) + and (_boxSets[i]->getWidth () == width ) ) + return i; + } + + return NotFound; + } + + + BoxSet* NodeSets::find ( DbU::Unit height, DbU::Unit width ) + { + size_t i = 0; + for ( ; i<_boxSets.size() ; ++i ) { + if ( (_boxSets[i]->getHeight() == height) + and (_boxSets[i]->getWidth () == width ) ) + return _boxSets[i]; + } + + return NULL; + } + + + BoxSet* NodeSets::find ( BoxSet* boxSet ) + { + return find( boxSet->getHeight(), boxSet->getWidth() ); + } + + + BoxSet* NodeSets::find ( int nfing ) + { + size_t i = 0; + for ( ; i<_boxSets.size() ; ++i ) { + if (_boxSets[i]->getNFing() == nfing) + return _boxSets[i]; + } + + return NULL; + } + + + void NodeSets::print() const + { + cerr << "Print - NodeSets:" << endl; + int index = 0; + if (not size()) { + cerr << "--- EMPTY ---" << endl; + } else { + for ( size_t i=0 ; _boxSets.size() ; ++i ) { + cerr << "[" << setw(3) << index << "] "; + _boxSets[i]->print(); + } + cerr << endl; + } + } + + + bool NodeSets::compare ( NodeSets nodeSets2, unsigned int flags ) const + { + if (_boxSets.size() != nodeSets2.size()) { + if (flags & ShowDiff) + cerr << "NodeSets::compare() size differs: " << _boxSets.size() + << " vs. " << nodeSets2.size() << endl; + return false; + } + + bool isSame = true; + for ( size_t iset = 0 ; iset<_boxSets.size() ; ++iset ) { + if ( (_boxSets[iset]->getHeight() != nodeSets2[iset]->getHeight()) + or (_boxSets[iset]->getWidth () != nodeSets2[iset]->getWidth ()) ) { + isSame = false; + if (flags & ShowDiff) + cerr << "NodeSets::compare() Box [" << iset << "] differs " + << " (" << DbU::getValueString(_boxSets[iset]->getWidth()) << "," << DbU::getValueString(_boxSets[iset]->getHeight()) << ") vs." + << " (" << DbU::getValueString(nodeSets2[iset]->getWidth()) << "," << DbU::getValueString(nodeSets2[iset]->getHeight()) << ")" + << endl; + } + } + + return isSame; + } + + + void NodeSets::push_back ( BoxSet* boxSet ) + { + if (find(boxSet) == NULL) _boxSets.push_back( boxSet ); + else { + find( boxSet )->incrementCpt(); + boxSet->destroy(); + } + } + + + void NodeSets::push_back ( vector vect + , DbU::Unit height + , DbU::Unit width + , unsigned int type ) + { + if (find(height,width) == NULL) { + if (type == HorizontalSNode) { + _boxSets.push_back( HBoxSet::create( vect, height, width ) ); + } else if (type == VerticalSNode) { + _boxSets.push_back( VBoxSet::create( vect, height, width ) ); + } + } else + find( height, width )->incrementCpt(); + } + + + NodeSets* NodeSets::clone() + { + NodeSets* nodesets = new NodeSets( _start, _step, _count ); + for ( BoxSet* bs : _boxSets ) _boxSets.push_back( bs->clone() ); + return nodesets; + } + + +} // Bora namespace. diff --git a/bora/src/Pareto.cpp b/bora/src/Pareto.cpp new file mode 100644 index 00000000..6e3b5457 --- /dev/null +++ b/bora/src/Pareto.cpp @@ -0,0 +1,156 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Pareto.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "bora/Pareto.h" + + +namespace Bora { + + using namespace std; + + + Pareto::Pareto () + : _capacity(0) + , _size (0) + , _xs (NULL) + , _ys (NULL) + { } + + + Pareto::~Pareto () + { clear(); } + + + void Pareto::_resize ( int capacity ) + { + if (capacity <= _capacity) return; + + int newcapacity = (_capacity) ? _capacity*2 : 4; + while ( newcapacity < capacity ) newcapacity <<= 1; + + double* xs = new double [newcapacity]; + double* ys = new double [newcapacity]; + + for ( int i=0 ; i<_capacity ; ++i ) { + xs[i] = _xs[i]; + ys[i] = _ys[i]; + } + + delete [] _xs; + delete [] _ys; + + _capacity = newcapacity; + _xs = xs; + _ys = ys; + } + + + void Pareto::_insert ( int index, double x, double y ) + { + if (_size == _capacity) _resize( _capacity+1 ); + + if (index < _size) { + for ( int i=_size ; i>index ; --i ) { + _xs[i] = _xs[i-1]; + _ys[i] = _ys[i-1]; + } + } + + _xs[index] = x; + _ys[index] = y; + _size++; + } + + + void Pareto::_remove ( int index ) + { + if (index >= _size) return; + + for ( int i=index ; i<_size-1 ; ++i ) { + _xs[i] = _xs[i+1]; + _ys[i] = _ys[i+1]; + } + --_size; + } + + + void Pareto::_restoreMonotonic () + { + for ( int i=0 ; i<_size-1 ; ) { + if (_ys[i] >= _ys[i+1]) { + ++i; + continue; + } + _remove( i+1 ); + } + } + + + void Pareto::mergePoint ( double x, double y ) + { + //cerr << "Merge: [" << x << " " << y << "] " << _size << endl; + + if (_size == 0) { _insert( 0, x, y ); return; } + if (x < _xs[0]) { + _insert( 0, x, y ); + //cerr << " insert at 0" << endl; + } else { + int i = 1; + for ( ; i<_size ; ++i ) { + if ( (x == _xs[i-1]) and (y < _ys[i-1]) ) { _ys[i-1] = y; break; } + if ( (x == _xs[i ]) and (y < _ys[i ]) ) { _ys[i ] = y; break; } + + //cerr << " check between x[" << i-1 << "]: " << _xs[i-1] + // << " and x[" << i << "]: " << _xs[i] << endl; + if (x < _xs[i]) { + // double ypareto = _ys[i-1]; + // ypareto += (_ys[i]-_ys[i-1]) / ((double)_xs[i] - (double)_xs[i-1]) * (x - _xs[i-1]); + // if (y < ypareto) + // _insert( i, x, y ); + _insert( i, x, y ); + break; + } + } + if (i == _size) { + //cerr << " insert at " << _size << " (end)" << endl; + _insert( _size, x, y ); + } + } + + _restoreMonotonic(); + } + + + void Pareto::dump () + { + for ( int i=0 ; i<_size ; ++i ) { + cerr << " point[" << i << "]: [" << _xs[i] << " " << _ys[i] << "]" << endl; + } + } + + + void Pareto::clear () + { + if (_xs) delete [] _xs; + if (_ys) delete [] _ys; + _capacity = 0; + _size = 0; + } + + +} // Bora namespace. diff --git a/bora/src/PyBora.cpp b/bora/src/PyBora.cpp new file mode 100644 index 00000000..b42a8a75 --- /dev/null +++ b/bora/src/PyBora.cpp @@ -0,0 +1,123 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./bora/PyBora.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/isobar/PyHurricane.h" +#include "hurricane/isobar/PyCell.h" +#include "bora/PySlicingNode.h" +#include "bora/PyHSlicingNode.h" +#include "bora/PyVSlicingNode.h" +#include "bora/PyDSlicingNode.h" +#include "bora/PyRHSlicingNode.h" +#include "bora/PyRVSlicingNode.h" +#include "bora/PyBoraEngine.h" +#include "bora/PyGraphicBoraEngine.h" + + +namespace Bora { + + using std::cerr; + using std::endl; + using Hurricane::tab; + using Isobar::__cs; + using CRL::PyTypeToolEngine; + using CRL::PyTypeGraphicTool; + + +#if !defined(__PYTHON_MODULE__) + +// +=================================================================+ +// | "PyBora" Shared Library Code Part | +// +=================================================================+ + + +#else // PyBora Shared Library Code Part. + + +// +=================================================================+ +// | "PyBora" Python Module Code Part | +// +=================================================================+ + + +extern "C" { + + + static PyMethodDef PyBora_Methods[] = + { {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + // --------------------------------------------------------------- + // Module Initialization : "initBora ()" + + DL_EXPORT(void) initBora () + { + cdebug.log(61) << "initBora()" << endl; + + PySlicingNode_LinkPyType(); + PyHSlicingNode_LinkPyType(); + PyVSlicingNode_LinkPyType(); + PyDSlicingNode_LinkPyType(); + PyRHSlicingNode_LinkPyType(); + PyRVSlicingNode_LinkPyType(); + PyBoraEngine_LinkPyType(); + PyGraphicBoraEngine_LinkPyType(); + + PYTYPE_READY( SlicingNode ) + + PYTYPE_READY_SUB( HSlicingNode , SlicingNode ) + PYTYPE_READY_SUB( VSlicingNode , SlicingNode ) + PYTYPE_READY_SUB( DSlicingNode , SlicingNode ) + PYTYPE_READY_SUB( RHSlicingNode , SlicingNode ) + PYTYPE_READY_SUB( RVSlicingNode , SlicingNode ) + PYTYPE_READY_SUB( BoraEngine , ToolEngine ); + PYTYPE_READY_SUB( GraphicBoraEngine, GraphicTool ); + + + PyObject* module = Py_InitModule( "Bora", PyBora_Methods ); + if (module == NULL) { + cerr << "[ERROR]\n" + << " Failed to initialize Bora module." << endl; + return; + } + + Py_INCREF( &PyTypeSlicingNode ); + PyModule_AddObject( module, "SlicingNode" , (PyObject*)&PyTypeSlicingNode ); + Py_INCREF( &PyTypeHSlicingNode ); + PyModule_AddObject( module, "HSlicingNode" , (PyObject*)&PyTypeHSlicingNode ); + Py_INCREF( &PyTypeVSlicingNode ); + PyModule_AddObject( module, "VSlicingNode" , (PyObject*)&PyTypeVSlicingNode ); + Py_INCREF( &PyTypeDSlicingNode ); + PyModule_AddObject( module, "DSlicingNode" , (PyObject*)&PyTypeDSlicingNode ); + Py_INCREF( &PyTypeRHSlicingNode ); + PyModule_AddObject( module, "RHSlicingNode" , (PyObject*)&PyTypeRHSlicingNode ); + Py_INCREF( &PyTypeRVSlicingNode ); + PyModule_AddObject( module, "RVSlicingNode" , (PyObject*)&PyTypeRVSlicingNode ); + Py_INCREF( &PyTypeBoraEngine ); + PyModule_AddObject( module, "BoraEngine" , (PyObject*)&PyTypeBoraEngine ); + Py_INCREF( &PyTypeGraphicBoraEngine ); + PyModule_AddObject( module, "GraphicBoraEngine", (PyObject*)&PyTypeGraphicBoraEngine ); + + PySlicingNode_postModuleInit(); + PyBoraEngine_postModuleInit(); + } + + +} // extern "C". + + +#endif // Python Module Code Part. + +} // Bora namespace. diff --git a/bora/src/PyBoraEngine.cpp b/bora/src/PyBoraEngine.cpp new file mode 100644 index 00000000..a0162be5 --- /dev/null +++ b/bora/src/PyBoraEngine.cpp @@ -0,0 +1,191 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./bora/PyBoraEngine.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/isobar/PyCell.h" +#include "bora/PyBoraEngine.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(BoraEngine,bora,function) + + +namespace Bora { + + using namespace std; + using Hurricane::tab; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Exception; + using Isobar::__cs; + using Isobar::Converter; + using Isobar::ProxyProperty; + using Isobar::ProxyError; + using Isobar::ConstructorError; + using Isobar::HurricaneError; + using Isobar::HurricaneWarning; + using Isobar::ParseOneArg; + using Isobar::ParseTwoArg; + using Isobar::PyCell; + using Isobar::PyCell_Link; + using Isobar::PyAny_AsLong; + using CRL::PyToolEngine; + using Bora::BoraEngine; + + +extern "C" { + +#if defined(__PYTHON_MODULE__) + + +// +=================================================================+ +// | "PyBoraEngine" Python Module Code Part | +// +=================================================================+ + + + static PyObject* PyBoraEngine_get ( PyObject*, PyObject* args ) + { + cdebug.log(61) << "PyBoraEngine_get()" << endl; + + BoraEngine* bora = NULL; + + HTRY + PyObject* arg0; + + if (not ParseOneArg("Bora.get", args, CELL_ARG, &arg0)) return NULL; + bora = BoraEngine::get(PYCELL_O(arg0)); + HCATCH + + return PyBoraEngine_Link(bora); + } + + + static PyObject* PyBoraEngine_create ( PyObject*, PyObject* args ) + { + cdebug.log(61) << "PyBoraEngine_create()" << endl; + + BoraEngine* bora = NULL; + + HTRY + PyObject* arg0; + + if (not ParseOneArg("Bora.get", args, CELL_ARG, &arg0)) return NULL; + + Cell* cell = PYCELL_O(arg0); + bora = BoraEngine::get(cell); + + if (bora == NULL) { + bora = BoraEngine::create(cell); + //if (cmess1.enabled()) + // bora->getBoraConfiguration()->print(cell); + } else + cerr << Warning("%s already has a Bora engine.",getString(cell).c_str()) << endl; + HCATCH + + return PyBoraEngine_Link(bora); + } + + + static PyObject* PyBoraEngine_updatePlacement ( PyBoraEngine* self, PyObject* args ) + { + unsigned int bsIndex = 0; + + METHOD_HEAD( "BoraEngine.updatePlacement()" ) + HTRY + PyObject* arg0; + PyObject* arg1; + __cs.init ("BoraEngine.updatePlacement"); + + if (not PyArg_ParseTuple(args, "O&|O&:BoraEngine.updatePlacement" + , Converter, &arg0 + , Converter, &arg1 )) { + return NULL; + } + + if (__cs.getObjectIds() == INT_ARG ) { bora->updatePlacement( PyAny_AsLong(arg0) ); } + else if (__cs.getObjectIds() == INTS2_ARG) { bora->updatePlacement( PyAny_AsLong(arg0), PyAny_AsLong(arg1) ); } + else { + PyErr_SetString( ConstructorError, "BoraEngine.updatePlacement(): Invalid/bad type parameters ." ); + return NULL; + } + HCATCH + + Py_RETURN_NONE; + } + + // Standart Accessors (Attributes). + DirectVoidMethod(BoraEngine,bora,updateSlicingTree) + + // DirectVoidMethod(BoraEngine,bora,runNegociate) + // DirectVoidMethod(BoraEngine,bora,printConfiguration) + // DirectVoidMethod(BoraEngine,bora,saveGlobalSolution) + // DirectVoidMethod(BoraEngine,bora,finalizeLayout) + // DirectVoidMethod(BoraEngine,bora,dumpMeasures) + // DirectGetBoolAttribute(PyBoraEngine_getToolSuccess,getToolSuccess,PyBoraEngine,BoraEngine) + + // Standart Destroy (Attribute). + DBoDestroyAttribute(PyBoraEngine_destroy,PyBoraEngine) + + + PyMethodDef PyBoraEngine_Methods[] = + { { "get" , (PyCFunction)PyBoraEngine_get , METH_VARARGS|METH_STATIC + , "Returns the Bora engine attached to the Cell, None if there isn't." } + , { "create" , (PyCFunction)PyBoraEngine_create , METH_VARARGS|METH_STATIC + , "Create an Bora engine on this cell." } + //, { "place" , (PyCFunction)PyBoraEngine_place , METH_NOARGS + // , "Run the placer (Bora)." } + , { "updateSlicingTree" , (PyCFunction)PyBoraEngine_updateSlicingTree , METH_NOARGS + , "Update/compute slicing tree possible dimensions table." } + , { "updatePlacement" , (PyCFunction)PyBoraEngine_updatePlacement , METH_VARARGS + , "Select placement at the given index in the table." } + , { "destroy" , (PyCFunction)PyBoraEngine_destroy , METH_NOARGS + , "Destroy the associated hurricane object. The python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + DBoDeleteMethod(BoraEngine) + PyTypeObjectLinkPyType(BoraEngine) + + +#else // End of Python Module Code Part. + + +// +=================================================================+ +// | "PyBoraEngine" Shared Library Code Part | +// +=================================================================+ + + + // Link/Creation Method. + PyTypeInheritedObjectDefinitions(BoraEngine,PyToolEngine) + DBoLinkCreateMethod(BoraEngine) + + + extern void PyBoraEngine_postModuleInit () + { + //PyObject* constant; + //LoadObjectConstant(PyTypeBoraEngine.tp_dict,BoraEngine::SlowMotion,"SlowMotion"); + } + + +#endif // Shared Library Code Part. + +} // extern "C". + +} // Bora namespace. + diff --git a/bora/src/PyDSlicingNode.cpp b/bora/src/PyDSlicingNode.cpp new file mode 100644 index 00000000..4639dae7 --- /dev/null +++ b/bora/src/PyDSlicingNode.cpp @@ -0,0 +1,152 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./bora/PyDSlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/analog/PyDevice.h" +#include "crlcore/PyRoutingGauge.h" +#include "bora/PyDSlicingNode.h" + + +namespace Bora { + + using namespace Hurricane; + using namespace Isobar; + using CRL::PyRoutingGauge; + using CRL::PyTypeRoutingGauge; + using CRL::RoutingGauge; + using Analog::Device; + + +extern "C" { + + +#undef ACCESS_OBJECT +#undef ACCESS_CLASS +#define ACCESS_OBJECT _baseObject._object +#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject) +#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(DSlicingNode,node,function) + + +// +=================================================================+ +// | "PyDSlicingNode" Python Module Code Part | +// +=================================================================+ + +#if defined(__PYTHON_MODULE__) + + + // +-------------------------------------------------------------+ + // | "PyDSlicingNode" Attribute Methods | + // +-------------------------------------------------------------+ + + + static PyObject* PyDSlicingNode_create ( PyObject* , PyObject* args ) + { + PyObject* pyInstance = NULL; + PyObject* pyCell = NULL; + PyObject* pyRoutingGauge = NULL; + double start = 0.0; + double step = 0.0; + double count = 0.0; + DSlicingNode* node = NULL; + + HTRY + if (not PyArg_ParseTuple( args,"SOddd|O:DSlicingNode.create" + , &pyInstance + , &pyCell + , &start + , &step + , &count + , &pyRoutingGauge ) ) { + PyErr_SetString ( ConstructorError, "DSlicingNode.create(): Invalid/bad number of parameters ." ); + return NULL; + } + if (not IsPyCell(pyCell)) { + PyErr_SetString( ConstructorError, "DSlicingNode.create(): First argument *must* be of type Cell." ); + return NULL; + } + if (pyRoutingGauge and not IsPyRoutingGauge(pyRoutingGauge)) { + PyErr_SetString( ConstructorError, "DSlicingNode.create(): Fifth argument *must* be of type RoutingGauge." ); + return NULL; + } + + Cell* cell = PYCELL_O( pyCell ); + Instance* instance = cell->getInstance( PyString_AsString(pyInstance) ); + //Device* device = dynamic_cast( instance->getMasterCell() ); + RoutingGauge* rg = (pyRoutingGauge) ? PYROUTINGGAUGE_O(pyRoutingGauge) : NULL; + + node = DSlicingNode::create( NodeSets::create( instance->getMasterCell(), start, step, count, rg ) + , UnknownAlignment + , instance ); + HCATCH + + return PyDSlicingNode_NEW(node); + } + + + DirectGetIntAttribute(PyDSlicingNode_getNFing,getNFing,PyDSlicingNode,DSlicingNode) + DirectSetIntAttribute(PyDSlicingNode_setNFing,setNFing,PyDSlicingNode,DSlicingNode) + // Standart Destroy (Attribute). + + + // --------------------------------------------------------------- + // PyDSlicingNode Attribute Method table. + + PyMethodDef PyDSlicingNode_Methods[] = + { { "create" , (PyCFunction)PyDSlicingNode_create , METH_VARARGS|METH_STATIC + , "Create a new DSlicingNode." } + , { "getNFing" , (PyCFunction)PyDSlicingNode_getNFing , METH_NOARGS , "To be documented." } + , { "setNFing" , (PyCFunction)PyDSlicingNode_setNFing , METH_VARARGS, "To be documented." } + , { NULL, NULL, 0, NULL } /* sentinel */ + }; + + + // +-------------------------------------------------------------+ + // | "PyDSlicingNode" Object Methods | + // +-------------------------------------------------------------+ + + + PythonOnlyDeleteMethod(DSlicingNode) + PyTypeObjectLinkPyType(DSlicingNode) + + +#else // End of Python Module Code Part. + +// +=================================================================+ +// | "PyDSlicingNode" Shared Library Code Part | +// +=================================================================+ + + + extern PyObject* PyDSlicingNode_NEW ( DSlicingNode* node ) + { + if (not node) Py_RETURN_NONE; + + PyDSlicingNode* pyNode = NULL; + HTRY + pyNode = PyObject_NEW( PyDSlicingNode, &PyTypeDSlicingNode ); + if (not pyNode) return NULL; + pyNode->ACCESS_OBJECT = node; + HCATCH + return (PyObject*)pyNode; + } + + + PyTypeInheritedObjectDefinitions(DSlicingNode, SlicingNode) + + +#endif // End of Shared Library Code Part. + +} // extern "C". + +} // Bora namespace. diff --git a/bora/src/PyGraphicBoraEngine.cpp b/bora/src/PyGraphicBoraEngine.cpp new file mode 100644 index 00000000..ae9ec264 --- /dev/null +++ b/bora/src/PyGraphicBoraEngine.cpp @@ -0,0 +1,116 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./bora/PyGraphicBoraEngine.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/isobar/PyCell.h" +#include "bora/PyGraphicBoraEngine.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(GraphicBoraEngine,gtool,function) + + +namespace Bora { + +using namespace Hurricane; +using namespace Isobar; + +extern "C" { + + +// +=================================================================+ +// | "PyGraphicBoraEngine" Python Module Code Part | +// +=================================================================+ + +#if defined(__PYTHON_MODULE__) + + + static PyObject* PyGraphicBoraEngine_grab ( PyObject* ) + { + cdebug.log(61) << "PyGraphicBoraEngine_grab()" << endl; + PyGraphicBoraEngine* pyGraphicBoraEngine = NULL; + + HTRY + pyGraphicBoraEngine = PyObject_NEW ( PyGraphicBoraEngine, &PyTypeGraphicBoraEngine ); + if ( pyGraphicBoraEngine == NULL ) return NULL; + + pyGraphicBoraEngine->ACCESS_OBJECT = GraphicBoraEngine::grab(); + HCATCH + + return (PyObject*)pyGraphicBoraEngine; + } + + + static PyObject* PyGraphicBoraEngine_getCell ( PyGraphicBoraEngine* self ) + { + cdebug.log(61) << "PyGraphicBoraEngine_getCell ()" << endl; + + Cell* cell = NULL; + + HTRY + METHOD_HEAD("GraphicBoraEngine.getCell()") + cell = gtool->getCell (); + HCATCH + + if (cell == NULL) Py_RETURN_NONE; + return PyCell_Link(cell); + } + + + GetNameMethod(GraphicBoraEngine, gtool) + + // Standart destroy (Attribute). + + + PyMethodDef PyGraphicBoraEngine_Methods[] = + { { "grab" , (PyCFunction)PyGraphicBoraEngine_grab , METH_NOARGS|METH_STATIC + , "Returns the GraphicBoraEngine singleton." } + , { "getName" , (PyCFunction)PyGraphicBoraEngine_getName , METH_NOARGS + , "Returns the name of the GraphicBoraEngine (class attribute)." } + , { "getCell" , (PyCFunction)PyGraphicBoraEngine_getCell , METH_NOARGS + , "Returns the Cell on which this GraphicBoraEngine is attached." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + // --------------------------------------------------------------- + // PyGraphicBoraEngine Type Methods. + + + PythonOnlyDeleteMethod(GraphicBoraEngine) + PyTypeObjectLinkPyType(GraphicBoraEngine) + + +#else // End of Python Module Code Part. + + +// +=================================================================+ +// | "PyGraphicBoraEngine" Shared Library Code Part | +// +=================================================================+ + + // Link/Creation Method. + LinkCreateMethod(GraphicBoraEngine) + + PyTypeInheritedObjectDefinitions(GraphicBoraEngine,GraphicTool) + + +#endif // End of Shared Library Code Part. + +} // extern "C". + +} // Bora namespace. diff --git a/bora/src/PyHSlicingNode.cpp b/bora/src/PyHSlicingNode.cpp new file mode 100644 index 00000000..a5e3570d --- /dev/null +++ b/bora/src/PyHSlicingNode.cpp @@ -0,0 +1,115 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./bora/PyHSlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "bora/PyHSlicingNode.h" + + +namespace Bora { + + using namespace Hurricane; + using namespace Isobar; + + +extern "C" { + + +#undef ACCESS_OBJECT +#undef ACCESS_CLASS +#define ACCESS_OBJECT _baseObject._object +#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject) +#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(HSlicingNode,node,function) + + +// +=================================================================+ +// | "PyHSlicingNode" Python Module Code Part | +// +=================================================================+ + +#if defined(__PYTHON_MODULE__) + + + // +-------------------------------------------------------------+ + // | "PyHSlicingNode" Attribute Methods | + // +-------------------------------------------------------------+ + + + static PyObject* PyHSlicingNode_create ( PyObject* , PyObject* args ) + { + unsigned int alignment = AlignLeft; + HSlicingNode* node = NULL; + + HTRY + if (not PyArg_ParseTuple(args,"I:HSlicingNode.create", &alignment) ) { + PyErr_SetString ( ConstructorError, "HSlicingNode.create(): Invalid/bad type parameters ." ); + return NULL; + } + node = HSlicingNode::create( alignment ); + HCATCH + + return PyHSlicingNode_NEW(node); + } + + + // Standart Destroy (Attribute). + + + // --------------------------------------------------------------- + // PyHSlicingNode Attribute Method table. + + PyMethodDef PyHSlicingNode_Methods[] = + { { "create" , (PyCFunction)PyHSlicingNode_create , METH_VARARGS|METH_STATIC + , "Create a new HSlicingNode." } + , { NULL, NULL, 0, NULL } /* sentinel */ + }; + + + // +-------------------------------------------------------------+ + // | "PyHSlicingNode" Object Methods | + // +-------------------------------------------------------------+ + + + PythonOnlyDeleteMethod(HSlicingNode) + PyTypeObjectLinkPyType(HSlicingNode) + + +#else // End of Python Module Code Part. + +// +=================================================================+ +// | "PyHSlicingNode" Shared Library Code Part | +// +=================================================================+ + + + extern PyObject* PyHSlicingNode_NEW ( HSlicingNode* node ) + { + if (not node) Py_RETURN_NONE; + + PyHSlicingNode* pyNode = NULL; + HTRY + pyNode = PyObject_NEW( PyHSlicingNode, &PyTypeHSlicingNode ); + if (not pyNode) return NULL; + pyNode->ACCESS_OBJECT = node; + HCATCH + return (PyObject*)pyNode; + } + + + PyTypeInheritedObjectDefinitions(HSlicingNode, SlicingNode) + + +#endif // End of Shared Library Code Part. + +} // extern "C". + +} // Bora namespace. diff --git a/bora/src/PyRHSlicingNode.cpp b/bora/src/PyRHSlicingNode.cpp new file mode 100644 index 00000000..a9e59d49 --- /dev/null +++ b/bora/src/PyRHSlicingNode.cpp @@ -0,0 +1,137 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./bora/PyRHSlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/isobar/PyNet.h" +#include "hurricane/isobar/PyLayer.h" +#include "bora/PyRHSlicingNode.h" + + +namespace Bora { + + using namespace Hurricane; + using namespace Isobar; + + +extern "C" { + + +#undef ACCESS_OBJECT +#undef ACCESS_CLASS +#define ACCESS_OBJECT _baseObject._object +#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject) +#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(RHSlicingNode,node,function) + + +// +=================================================================+ +// | "PyRHSlicingNode" Python Module Code Part | +// +=================================================================+ + +#if defined(__PYTHON_MODULE__) + + + // +-------------------------------------------------------------+ + // | "PyRHSlicingNode" Attribute Methods | + // +-------------------------------------------------------------+ + + + static PyObject* PyRHSlicingNode_create ( PyObject* , PyObject* args ) + { + + PyObject* pyNet = NULL; + PyObject* pyLayer = NULL; + int npitch = 0; + const char* cname; + const char* iname; + RHSlicingNode* node = NULL; + + HTRY + if (not PyArg_ParseTuple( args,"OOiss|O:RHSlicingNode.create" + , &pyNet + , &pyLayer + , &npitch + , &cname + , &iname) ) { + PyErr_SetString ( ConstructorError, "RHSlicingNode.create(): Invalid/bad number of parameters ." ); + return NULL; + } + if (not IsPyNet(pyNet)) { + PyErr_SetString( ConstructorError, "RHSlicingNode.create(): First argument *must* be of type Net." ); + return NULL; + } + Layer* layer = PYDERIVEDLAYER_O( pyLayer ); + if (not layer) { + PyErr_SetString( ConstructorError, "RHSlicingNode.create(): Fifth argument *must* be of type Layer." ); + return NULL; + } + + Net* net = PYNET_O( pyNet ); + + node = RHSlicingNode::create( net, layer, npitch, cname, iname ); + HCATCH + return PyRHSlicingNode_NEW(node); + } + + // Standart Destroy (Attribute). + + + // --------------------------------------------------------------- + // PyRHSlicingNode Attribute Method table. + + PyMethodDef PyRHSlicingNode_Methods[] = + { { "create" , (PyCFunction)PyRHSlicingNode_create , METH_VARARGS|METH_STATIC + , "Create a new RHSlicingNode." } + , { NULL, NULL, 0, NULL } /* sentinel */ + }; + + + // +-------------------------------------------------------------+ + // | "PyRHSlicingNode" Object Methods | + // +-------------------------------------------------------------+ + + + PythonOnlyDeleteMethod(RHSlicingNode) + PyTypeObjectLinkPyType(RHSlicingNode) + + +#else // End of Python Module Code Part. + +// +=================================================================+ +// | "PyRHSlicingNode" Shared Library Code Part | +// +=================================================================+ + + + extern PyObject* PyRHSlicingNode_NEW ( RHSlicingNode* node ) + { + if (not node) Py_RETURN_NONE; + + PyRHSlicingNode* pyNode = NULL; + HTRY + pyNode = PyObject_NEW( PyRHSlicingNode, &PyTypeRHSlicingNode ); + if (not pyNode) return NULL; + pyNode->ACCESS_OBJECT = node; + HCATCH + return (PyObject*)pyNode; + } + + + PyTypeInheritedObjectDefinitions(RHSlicingNode, SlicingNode) + + +#endif // End of Shared Library Code Part. + +} // extern "C". + +} // Bora namespace. diff --git a/bora/src/PyRVSlicingNode.cpp b/bora/src/PyRVSlicingNode.cpp new file mode 100644 index 00000000..a87262c3 --- /dev/null +++ b/bora/src/PyRVSlicingNode.cpp @@ -0,0 +1,138 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./bora/PyRVSlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/isobar/PyNet.h" +#include "hurricane/isobar/PyLayer.h" +#include "bora/PyRVSlicingNode.h" + + +namespace Bora { + + using namespace Hurricane; + using namespace Isobar; + + +extern "C" { + + +#undef ACCESS_OBJECT +#undef ACCESS_CLASS +#define ACCESS_OBJECT _baseObject._object +#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject) +#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(RVSlicingNode,node,function) + + +// +=================================================================+ +// | "PyRVSlicingNode" Python Module Code Part | +// +=================================================================+ + +#if defined(__PYTHON_MODULE__) + + + // +-------------------------------------------------------------+ + // | "PyRVSlicingNode" Attribute Methods | + // +-------------------------------------------------------------+ + + + static PyObject* PyRVSlicingNode_create ( PyObject* , PyObject* args ) + { + + PyObject* pyNet = NULL; + PyObject* pyLayer = NULL; + int npitch = 0; + const char* cname = ""; + const char* iname = ""; + RVSlicingNode* node = NULL; + + HTRY + if (not PyArg_ParseTuple( args,"OOiss|O:RVSlicingNode.create" + , &pyNet + , &pyLayer + , &npitch + , &cname + , &iname) ) { + PyErr_SetString ( ConstructorError, "RVSlicingNode.create(): Invalid/bad number of parameters ." ); + return NULL; + } + if (not IsPyNet(pyNet)) { + PyErr_SetString( ConstructorError, "RVSlicingNode.create(): First argument *must* be of type Net." ); + return NULL; + } + Layer* layer = PYDERIVEDLAYER_O( pyLayer ); + if (not layer) { + PyErr_SetString( ConstructorError, "RVSlicingNode.create(): Fifth argument *must* be of type Layer." ); + return NULL; + } + + Net* net = PYNET_O( pyNet ); + + node = RVSlicingNode::create( net, layer, npitch, cname, iname ); + HCATCH + + return PyRVSlicingNode_NEW(node); + } + + // Standart Destroy (Attribute). + + + // --------------------------------------------------------------- + // PyRVSlicingNode Attribute Method table. + + PyMethodDef PyRVSlicingNode_Methods[] = + { { "create" , (PyCFunction)PyRVSlicingNode_create , METH_VARARGS|METH_STATIC + , "Create a new RVSlicingNode." } + , { NULL, NULL, 0, NULL } /* sentinel */ + }; + + + // +-------------------------------------------------------------+ + // | "PyRVSlicingNode" Object Methods | + // +-------------------------------------------------------------+ + + + PythonOnlyDeleteMethod(RVSlicingNode) + PyTypeObjectLinkPyType(RVSlicingNode) + + +#else // End of Python Module Code Part. + +// +=================================================================+ +// | "PyRVSlicingNode" Shared Library Code Part | +// +=================================================================+ + + + extern PyObject* PyRVSlicingNode_NEW ( RVSlicingNode* node ) + { + if (not node) Py_RETURN_NONE; + + PyRVSlicingNode* pyNode = NULL; + HTRY + pyNode = PyObject_NEW( PyRVSlicingNode, &PyTypeRVSlicingNode ); + if (not pyNode) return NULL; + pyNode->ACCESS_OBJECT = node; + HCATCH + return (PyObject*)pyNode; + } + + + PyTypeInheritedObjectDefinitions(RVSlicingNode, SlicingNode) + + +#endif // End of Shared Library Code Part. + +} // extern "C". + +} // Bora namespace. diff --git a/bora/src/PySlicingNode.cpp b/bora/src/PySlicingNode.cpp new file mode 100644 index 00000000..3e591d23 --- /dev/null +++ b/bora/src/PySlicingNode.cpp @@ -0,0 +1,542 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./bora/PySlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "bora/PySlicingNode.h" +#include "bora/PyHSlicingNode.h" +#include "bora/PyVSlicingNode.h" +#include "bora/PyDSlicingNode.h" +#include "bora/PyRHSlicingNode.h" +#include "bora/PyRVSlicingNode.h" +#include "hurricane/isobar/PyCell.h" +#include "hurricane/isobar/PyNet.h" +#include "crlcore/PyRoutingGauge.h" + + +namespace Bora { + + using namespace Hurricane; + using namespace Isobar; + using CRL::PyRoutingGauge; + using CRL::PyRoutingGauge_Link; + using CRL::PyTypeRoutingGauge; + + +extern "C" { + + +#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(SlicingNode,node,function) + + +// +=================================================================+ +// | "PySlicingNode" Python Module Code Part | +// +=================================================================+ + +#if defined(__PYTHON_MODULE__) + + + // +-------------------------------------------------------------+ + // | "PySlicingNode" Attribute Methods | + // +-------------------------------------------------------------+ + + // Standart destroy (Attribute). + //DBoDestroyAttribute(PySlicingNode_destroy ,PySlicingNode) + + + static PyObject* PySlicingNode_getCell ( PySlicingNode *self ) + { + cdebug_log(20,0) << "PySlicingNode_getCell ()" << endl; + Cell* cell = NULL; + HTRY + METHOD_HEAD( "SlicingNode.getCell()" ) + cell = node->getCell(); + HCATCH + return PyCell_Link( cell ); + } + + + static PyObject* PySlicingNode_getRoot ( PySlicingNode *self ) + { + cdebug_log(20,0) << "PySlicingNode_getRoot ()" << endl; + SlicingNode* node = NULL; + HTRY + METHOD_HEAD( "SlicingNode.getRoot()" ) + node = node->getRoot(); + HCATCH + return PySlicingNode_NEW( node ); + } + + + static PyObject* PySlicingNode_getParent ( PySlicingNode *self ) + { + cdebug_log(20,0) << "PySlicingNode_getParent ()" << endl; + SlicingNode* node = NULL; + HTRY + METHOD_HEAD( "SlicingNode.getParent()" ) + node = node->getParent(); + HCATCH + return PySlicingNode_NEW( node ); + } + + + static PyObject* PySlicingNode_setCell ( PySlicingNode* self, PyObject* args ) + { + PyObject* pyCell = NULL; + + HTRY + METHOD_HEAD( "SlicingNode.setCell()" ) + if (not PyArg_ParseTuple(args,"O:SlicingNode.setCell", &pyCell)) { + PyErr_SetString( ConstructorError, "SlicingNode.setCell(): Invalid/bad type parameters ." ); + return NULL; + } + if (not IsPyCell(pyCell)) { + PyErr_SetString( ConstructorError, "SlicingNode.setCell(): Argument *must* be of Cell type." ); + return NULL; + } + node->setCell( PYCELL_O(pyCell) ); + HCATCH + + Py_RETURN_NONE; + } + + + static PyObject* PySlicingNode_setParent ( PySlicingNode* self, PyObject* args ) + { + PyObject* pyNode = NULL; + + HTRY + METHOD_HEAD( "SlicingNode.setParent()" ) + if (not PyArg_ParseTuple(args,"O:SlicingNode.setParent", &pyNode)) { + PyErr_SetString( ConstructorError, "SlicingNode.setParent(): Invalid/bad type parameters ." ); + return NULL; + } + if (not IsPySlicingNode(pyNode)) { + PyErr_SetString( ConstructorError, "SlicingNode.setParent(): Argument *must* be of SlicingNode type." ); + return NULL; + } + node->setParent( PYSLICINGNODE_O(pyNode) ); + HCATCH + + Py_RETURN_NONE; + } + + + static PyObject* PySlicingNode_setRoutingGauge ( PySlicingNode* self, PyObject* args ) + { + PyObject* pyRG = NULL; + + HTRY + METHOD_HEAD( "SlicingNode.setRoutingGauge()" ) + if (not PyArg_ParseTuple(args,"O:SlicingNode.setRoutingGauge", &pyRG)) { + PyErr_SetString( ConstructorError, "SlicingNode.setRoutingGauge(): Invalid/bad type parameters ." ); + return NULL; + } + if (not IsPyRoutingGauge(pyRG)) { + PyErr_SetString( ConstructorError, "SlicingNode.setRoutingGauge(): Argument *must* be of RoutingGauge type." ); + return NULL; + } + node->setRoutingGauge( PYROUTINGGAUGE_O(pyRG) ); + HCATCH + + Py_RETURN_NONE; + } + + + static PyObject* PySlicingNode_push_back ( PySlicingNode* self, PyObject* args ) + { + PyObject* pyNode = NULL; + PyObject* pyReset = NULL; + + HTRY + METHOD_HEAD( "SlicingNode.push_back()" ) + if (not PyArg_ParseTuple(args,"O|O:SlicingNode.push_back", &pyNode, &pyReset)) { + PyErr_SetString( ConstructorError, "SlicingNode.push_back(): Invalid/bad type parameters ." ); + return NULL; + } + PyObject* pyRepr = PyObject_Repr( pyNode ); + string repr = PyString_AsString( pyRepr ); + + SlicingNode* child = SlicingNodeCast( pyNode ); + if (not child) { + PyErr_SetString( ConstructorError, "SlicingNode.push_back(): Argument *must* be of SlicingNode type." ); + return NULL; + } + bool reset = false; + if (pyReset) reset = (PyObject_IsTrue(pyReset) == 1); + node->push_back( child, reset ); + HCATCH + + Py_RETURN_NONE; + } + + + static PyObject* PySlicingNode_addSymmetryNet ( PySlicingNode* self, PyObject* args ) + { + unsigned int type = 0; + PyObject* pyNet1 = NULL; + PyObject* pyNet2 = NULL; + + HTRY + METHOD_HEAD( "SlicingNode.addSymmetryNet()" ) + if (not PyArg_ParseTuple(args,"IO|O:SlicingNode.addSymmetryNet", &type, &pyNet1, &pyNet2)) { + PyErr_SetString( ConstructorError, "SlicingNode.addSymmetryNet(): Invalid/bad type parameters." ); + return NULL; + } + + if (not IsPyNet(pyNet1)) { + PyErr_SetString( ConstructorError, "SlicingNode.setParent(): Argument *must* be of Net type." ); + return NULL; + } + if (pyNet2){ + if (not IsPyNet(pyNet2)) { + PyErr_SetString( ConstructorError, "SlicingNode.setParent(): Argument *must* be of Net type." ); + return NULL; + } + //cerr << "type : " << type << endl; + // cerr << "pyNet1: " << pyNet1 << endl; + //cerr << "pyNet2: " << pyNet2 << endl; + node->addSymmetryNet( type, PYNET_O(pyNet1), PYNET_O(pyNet2) ); + } else { + //cerr << "type : " << type << endl; + //cerr << "pyNet1: " << pyNet1 << endl; + //cerr << "pyNet2: " << pyNet2 << endl; + node->addSymmetryNet( type, PYNET_O(pyNet1) ); + } + HCATCH + + Py_RETURN_NONE; + } + + + static PyObject* PySlicingNode_addSymmetry ( PySlicingNode* self, PyObject* args ) + { + int childIndex = 0; + int copyIndex = 0; + PyObject* pyReset = NULL; + + HTRY + METHOD_HEAD( "SlicingNode.addSymmetry()" ) + if (not PyArg_ParseTuple(args,"ii|O:SlicingNode.addSymmetry", &childIndex, ©Index, &pyReset)) { + PyErr_SetString( ConstructorError, "SlicingNode.addSymmetry(): Invalid/bad type parameters ." ); + return NULL; + } + bool reset = true; + if (pyReset) reset = (PyObject_IsTrue(pyReset) == 1); + node->addSymmetry( childIndex, copyIndex, reset ); + HCATCH + + Py_RETURN_NONE; + } + + + static PyObject* PySlicingNode_setGlobalSize ( PySlicingNode* self, PyObject* args ) + { + unsigned int bsIndex = 0; + PyObject* pyWidth = 0; + PyObject* pyHeight = 0; + + HTRY + METHOD_HEAD( "SlicingNode.setGlobalSize()" ) + if (PyArg_ParseTuple(args,"OO:SlicingNode.setGlobalSize", &pyWidth, &pyHeight)) { + node->setGlobalSize( PyAny_AsLong(pyWidth), PyAny_AsLong(pyHeight) ); + } else if (PyArg_ParseTuple(args,"I:SlicingNode.setGlobalSize", &bsIndex)) { + node->setGlobalSize( bsIndex ); + } else { + PyErr_SetString( ConstructorError, "SlicingNode.setGlobalSize(): Invalid/bad type parameters ." ); + return NULL; + } + HCATCH + + Py_RETURN_NONE; + } + + // Standart Accessors (Attributes). + DirectGetBoolAttribute(PySlicingNode_isPreset ,isPreset ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isSet ,isSet ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isPlaced ,isPlaced ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isAlignLeft ,isAlignLeft ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isAlignRight ,isAlignRight ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isAlignCenter ,isAlignCenter ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isAlignTop ,isAlignTop ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isAlignBottom ,isAlignBottom ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isHorizontal ,isHorizontal ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isVertical ,isVertical ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isDevice ,isDevice ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isRouting ,isRouting ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isEmpty ,isEmpty ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isOverCell ,isOverCell ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isRoutingCreated ,isRoutingCreated ,PySlicingNode,SlicingNode) + DirectGetBoolAttribute(PySlicingNode_isRoutingEstimated,isRoutingEstimated,PySlicingNode,SlicingNode) + + DirectGetUIntAttribute( PySlicingNode_getId ,getId ,PySlicingNode,SlicingNode) + DirectGetUIntAttribute( PySlicingNode_getPreset ,getPreset ,PySlicingNode,SlicingNode) + DirectGetUIntAttribute( PySlicingNode_getSet ,getSet ,PySlicingNode,SlicingNode) + DirectGetUIntAttribute( PySlicingNode_getPlaced ,getPlaced ,PySlicingNode,SlicingNode) + DirectGetUIntAttribute( PySlicingNode_getAlignment ,getAlignment ,PySlicingNode,SlicingNode) + DirectGetUIntAttribute( PySlicingNode_getType ,getType ,PySlicingNode,SlicingNode) + DirectGetIntAttribute( PySlicingNode_getCpt ,getCpt ,PySlicingNode,SlicingNode) + DirectGetDoubleAttribute(PySlicingNode_getRatio ,getRatio ,PySlicingNode,SlicingNode) + DirectGetDoubleAttribute(PySlicingNode_getArea ,getArea ,PySlicingNode,SlicingNode) + DirectGetLongAttribute( PySlicingNode_getHeight ,getHeight ,PySlicingNode,SlicingNode) + DirectGetLongAttribute( PySlicingNode_getWidth ,getWidth ,PySlicingNode,SlicingNode) + DirectGetLongAttribute( PySlicingNode_getX ,getX ,PySlicingNode,SlicingNode) + DirectGetLongAttribute( PySlicingNode_getY ,getY ,PySlicingNode,SlicingNode) + DirectGetLongAttribute( PySlicingNode_getXCenter ,getXCenter ,PySlicingNode,SlicingNode) + DirectGetLongAttribute( PySlicingNode_getYCenter ,getYCenter ,PySlicingNode,SlicingNode) + DirectGetLongAttribute( PySlicingNode_getToleranceRatioH,getToleranceRatioH,PySlicingNode,SlicingNode) + DirectGetLongAttribute( PySlicingNode_getToleranceRatioW,getToleranceRatioW,PySlicingNode,SlicingNode) + DirectGetLongAttribute( PySlicingNode_getToleranceBandH ,getToleranceBandH ,PySlicingNode,SlicingNode) + DirectGetLongAttribute( PySlicingNode_getToleranceBandW ,getToleranceBandW ,PySlicingNode,SlicingNode) + + DirectSetIntAttribute (PySlicingNode_setPreset ,setPreset ,PySlicingNode,SlicingNode) + DirectSetIntAttribute (PySlicingNode_setSet ,setSet ,PySlicingNode,SlicingNode) + DirectSetIntAttribute (PySlicingNode_setPlaced ,setPlaced ,PySlicingNode,SlicingNode) + DirectSetIntAttribute (PySlicingNode_setAlignment ,setAlignment ,PySlicingNode,SlicingNode) + DirectSetIntAttribute (PySlicingNode_setType ,setType ,PySlicingNode,SlicingNode) + DirectSetIntAttribute (PySlicingNode_setOverCell ,setOverCell ,PySlicingNode,SlicingNode) + DirectSetIntAttribute (PySlicingNode_setRoutingCreated ,setRoutingCreated ,PySlicingNode,SlicingNode) + DirectSetIntAttribute (PySlicingNode_setRoutingEstimated,setRoutingEstimated,PySlicingNode,SlicingNode) + DirectSetLongAttribute(PySlicingNode_setX ,setX ,PySlicingNode,SlicingNode) + DirectSetLongAttribute(PySlicingNode_setY ,setY ,PySlicingNode,SlicingNode) + DirectSetLongAttribute(PySlicingNode_setToleranceRatioH ,setToleranceRatioH ,PySlicingNode,SlicingNode) + DirectSetLongAttribute(PySlicingNode_setToleranceRatioW ,setToleranceRatioW ,PySlicingNode,SlicingNode) + DirectSetLongAttribute(PySlicingNode_setToleranceBandH ,setToleranceBandH ,PySlicingNode,SlicingNode) + DirectSetLongAttribute(PySlicingNode_setToleranceBandW ,setToleranceBandW ,PySlicingNode,SlicingNode) + + DirectVoidMethod(SlicingNode,node,updateGlobalSize) + DirectVoidMethod(SlicingNode,node,clearNodeSets) + DirectVoidMethod(SlicingNode,node,clearParentsNodeSets) + DirectVoidMethod(SlicingNode,node,removeParent) + DirectVoidMethod(SlicingNode,node,resetSlicingTree) + DirectVoidMethod(SlicingNode,node,print) + DirectVoidMethod(SlicingNode,node,updateNetConstraints) + + accessorVectorFromVoid(getChildren,PySlicingNode,SlicingNode,SlicingNode) + + + // --------------------------------------------------------------- + // PySlicingNode Attribute Method table. + + PyMethodDef PySlicingNode_Methods[] = + { { "isPreset" , (PyCFunction)PySlicingNode_isPreset , METH_NOARGS , "To be documented." } + , { "isSet" , (PyCFunction)PySlicingNode_isSet , METH_NOARGS , "To be documented." } + , { "isPlaced" , (PyCFunction)PySlicingNode_isPlaced , METH_NOARGS , "To be documented." } + , { "isAlignLeft" , (PyCFunction)PySlicingNode_isAlignLeft , METH_NOARGS , "To be documented." } + , { "isAlignRight" , (PyCFunction)PySlicingNode_isAlignRight , METH_NOARGS , "To be documented." } + , { "isAlignCenter" , (PyCFunction)PySlicingNode_isAlignCenter , METH_NOARGS , "To be documented." } + , { "isAlignTop" , (PyCFunction)PySlicingNode_isAlignTop , METH_NOARGS , "To be documented." } + , { "isAlignBottom" , (PyCFunction)PySlicingNode_isAlignBottom , METH_NOARGS , "To be documented." } + , { "isHorizontal" , (PyCFunction)PySlicingNode_isHorizontal , METH_NOARGS , "To be documented." } + , { "isVertical" , (PyCFunction)PySlicingNode_isVertical , METH_NOARGS , "To be documented." } + , { "isDevice" , (PyCFunction)PySlicingNode_isDevice , METH_NOARGS , "To be documented." } + , { "isRouting" , (PyCFunction)PySlicingNode_isRouting , METH_NOARGS , "To be documented." } + , { "isEmpty" , (PyCFunction)PySlicingNode_isEmpty , METH_NOARGS , "To be documented." } + , { "isPreset" , (PyCFunction)PySlicingNode_isPreset , METH_NOARGS , "To be documented." } + , { "isOverCell" , (PyCFunction)PySlicingNode_isOverCell , METH_NOARGS , "To be documented." } + , { "isRoutingCreated" , (PyCFunction)PySlicingNode_isRoutingCreated , METH_NOARGS , "To be documented." } + , { "isRoutingEstimated" , (PyCFunction)PySlicingNode_isRoutingEstimated , METH_NOARGS , "To be documented." } + , { "getId" , (PyCFunction)PySlicingNode_getId , METH_NOARGS , "To be documented." } + , { "getPreset" , (PyCFunction)PySlicingNode_getPreset , METH_NOARGS , "To be documented." } + , { "getSet" , (PyCFunction)PySlicingNode_getSet , METH_NOARGS , "To be documented." } + , { "getPlaced" , (PyCFunction)PySlicingNode_getPlaced , METH_NOARGS , "To be documented." } + , { "getAlignment" , (PyCFunction)PySlicingNode_getAlignment , METH_NOARGS , "To be documented." } + , { "getType" , (PyCFunction)PySlicingNode_getType , METH_NOARGS , "To be documented." } + , { "getCpt" , (PyCFunction)PySlicingNode_getCpt , METH_NOARGS , "To be documented." } + , { "getRatio" , (PyCFunction)PySlicingNode_getRatio , METH_NOARGS , "To be documented." } + , { "getArea" , (PyCFunction)PySlicingNode_getArea , METH_NOARGS , "To be documented." } + , { "getHeight" , (PyCFunction)PySlicingNode_getHeight , METH_NOARGS , "To be documented." } + , { "getWidth" , (PyCFunction)PySlicingNode_getWidth , METH_NOARGS , "To be documented." } + , { "getX" , (PyCFunction)PySlicingNode_getX , METH_NOARGS , "To be documented." } + , { "getY" , (PyCFunction)PySlicingNode_getY , METH_NOARGS , "To be documented." } + , { "getXCenter" , (PyCFunction)PySlicingNode_getXCenter , METH_NOARGS , "To be documented." } + , { "getYCenter" , (PyCFunction)PySlicingNode_getYCenter , METH_NOARGS , "To be documented." } + , { "getCell" , (PyCFunction)PySlicingNode_getCell , METH_NOARGS , "To be documented." } + , { "getRoot" , (PyCFunction)PySlicingNode_getRoot , METH_NOARGS , "To be documented." } + , { "getToleranceRatioH" , (PyCFunction)PySlicingNode_getToleranceRatioH , METH_NOARGS , "To be documented." } + , { "getToleranceRatioW" , (PyCFunction)PySlicingNode_getToleranceRatioW , METH_NOARGS , "To be documented." } + , { "getToleranceBandH" , (PyCFunction)PySlicingNode_getToleranceBandW , METH_NOARGS , "To be documented." } + , { "getToleranceBandW" , (PyCFunction)PySlicingNode_getToleranceBandH , METH_NOARGS , "To be documented." } + , { "getParent" , (PyCFunction)PySlicingNode_getParent , METH_NOARGS , "To be documented." } + , { "setPreset" , (PyCFunction)PySlicingNode_setPreset , METH_VARARGS, "To be documented." } + , { "setSet" , (PyCFunction)PySlicingNode_setSet , METH_VARARGS, "To be documented." } + , { "setPlaced" , (PyCFunction)PySlicingNode_setPlaced , METH_VARARGS, "To be documented." } + , { "setAlignment" , (PyCFunction)PySlicingNode_setAlignment , METH_VARARGS, "To be documented." } + , { "setType" , (PyCFunction)PySlicingNode_setType , METH_VARARGS, "To be documented." } + , { "setOverCell" , (PyCFunction)PySlicingNode_setOverCell , METH_VARARGS, "To be documented." } + , { "setRoutingCreated" , (PyCFunction)PySlicingNode_setRoutingCreated , METH_VARARGS, "To be documented." } + , { "setRoutingEstimated" , (PyCFunction)PySlicingNode_setRoutingEstimated , METH_VARARGS, "To be documented." } + , { "setX" , (PyCFunction)PySlicingNode_setX , METH_VARARGS, "To be documented." } + , { "setY" , (PyCFunction)PySlicingNode_setY , METH_VARARGS, "To be documented." } + , { "updateGlobalSize" , (PyCFunction)PySlicingNode_updateGlobalSize , METH_NOARGS , "To be documented." } + , { "setGlobalSize" , (PyCFunction)PySlicingNode_setGlobalSize , METH_VARARGS, "To be documented." } + , { "clearNodeSets" , (PyCFunction)PySlicingNode_clearNodeSets , METH_NOARGS , "To be documented." } + , { "clearParentsNodeSets" , (PyCFunction)PySlicingNode_clearParentsNodeSets, METH_NOARGS , "To be documented." } + , { "removeParent" , (PyCFunction)PySlicingNode_removeParent , METH_NOARGS , "To be documented." } + , { "resetSlicingTree" , (PyCFunction)PySlicingNode_resetSlicingTree , METH_NOARGS , "To be documented." } + , { "setCell" , (PyCFunction)PySlicingNode_setCell , METH_VARARGS, "To be documented." } + , { "setParent" , (PyCFunction)PySlicingNode_setParent , METH_VARARGS, "To be documented." } + , { "setRoutingGauge" , (PyCFunction)PySlicingNode_setRoutingGauge , METH_VARARGS, "To be documented." } + , { "setToleranceRatioH" , (PyCFunction)PySlicingNode_setToleranceRatioH , METH_VARARGS, "To be documented." } + , { "setToleranceRatioW" , (PyCFunction)PySlicingNode_setToleranceRatioW , METH_VARARGS, "To be documented." } + , { "setToleranceBandH" , (PyCFunction)PySlicingNode_setToleranceBandW , METH_VARARGS, "To be documented." } + , { "setToleranceBandW" , (PyCFunction)PySlicingNode_setToleranceBandH , METH_VARARGS, "To be documented." } + , { "addSymmetry" , (PyCFunction)PySlicingNode_addSymmetry , METH_VARARGS, "To be documented." } + , { "push_back" , (PyCFunction)PySlicingNode_push_back , METH_VARARGS, "To be documented." } + , { "getChildren" , (PyCFunction)PySlicingNode_getChildren , METH_NOARGS , "To be documented." } + , { "cprint" , (PyCFunction)PySlicingNode_print , METH_NOARGS , "To be documented." } + , { "updateNetConstraints" , (PyCFunction)PySlicingNode_updateNetConstraints, METH_NOARGS , "To be documented." } + , { "addSymmetryNet" , (PyCFunction)PySlicingNode_addSymmetryNet , METH_VARARGS, "To be documented." } + //, { "destroy" , (PyCFunction)PySlicingNode_destroy , METH_NOARGS + // , "Destroy associated hurricane object, the python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + // +-------------------------------------------------------------+ + // | "PySlicingNode" Object Methods | + // +-------------------------------------------------------------+ + + PythonOnlyDeleteMethod(SlicingNode) + PyTypeObjectLinkPyType(SlicingNode) + + + static PyObject* PySlicingNodeIteratorNext ( PySlicingNodeVectorIterator* pyIterator ) + { + HTRY + if (pyIterator->_iterator != pyIterator->_pyContainer->_container->end()) { + SlicingNode* object = *(pyIterator->_iterator); + ++(pyIterator->_iterator); + return PySlicingNode_NEW(object); + } + HCATCH + return NULL; + } + + + VectorMethods (SlicingNode) + + +#else // End of Python Module Code Part. + + +// +=================================================================+ +// | "PySlicingNode" Shared Library Code Part | +// +=================================================================+ + + + // --------------------------------------------------------------- + // Allocator Method : "PySlicingNode_NEW ()" + // + // No PySlicingNode should ever be created, it's not a terminal object + // of the class hierarchy. Instead create the real underlying PyObject. + + PyObject* PySlicingNode_NEW ( SlicingNode* node ) { + if (not node) { + PyErr_SetString ( HurricaneError, "PySlicingNode_NEW(): NULL node argument." ); + return NULL; + } + + // HVSlicingNode* hvnode = dynamic_cast(node); + // if (hvnode) return PyHVSlicingNode_NEW( hvnode ); + + HSlicingNode* hnode = dynamic_cast(node); + if (hnode) return PyHSlicingNode_NEW( hnode ); + + VSlicingNode* vnode = dynamic_cast(node); + if (vnode) return PyVSlicingNode_NEW( vnode ); + + DSlicingNode* dnode = dynamic_cast(node); + if (dnode) return PyDSlicingNode_NEW( dnode ); + + RHSlicingNode* rhnode = dynamic_cast(node); + if (rhnode) return PyRHSlicingNode_NEW( rhnode ); + + RVSlicingNode* rvnode = dynamic_cast(node); + if (rvnode) return PyRVSlicingNode_NEW( rvnode ); + + Py_RETURN_NONE; + } + + + PyTypeRootObjectDefinitions(SlicingNode) + + PyTypeVectorObjectDefinitions(SlicingNodeVector) + PyTypeVectorObjectDefinitions(SlicingNodeVectorIterator) + + + extern void PySlicingNode_postModuleInit () + { + PyObject* constant; + + LoadObjectConstant(PyTypeSlicingNode.tp_dict,Preset ,"Preset" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,Set ,"Set" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,Placed ,"Placed" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,UnknownAlignment ,"UnknownAlignment" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,AlignLeft ,"AlignLeft" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,AlignRight ,"AlignRight" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,AlignCenter ,"AlignCenter" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,AlignTop ,"AlignTop" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,AlignBottom ,"AlignBottom" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,UnknownType ,"UnknownType" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,HorizontalSNode ,"HorizontalSNode" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,VerticalSNode ,"VerticalSNode" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,DeviceSNode ,"DeviceSNode" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,RoutingSNode ,"RoutingSNode" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,None ,"None" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,MX ,"MX" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,MY ,"MY" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,FixedRoutingSNode,"FixedRoutingSNode"); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,OverCell ,"OverCell" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,RoutingEstimated ,"RoutingEstimated" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,RoutingCreated ,"RoutingCreated" ); + //LoadObjectConstant(PyTypeSlicingNode.tp_dict,HasDijkstra ,"HasDijkstra" ); + + LoadObjectConstant(PyTypeSlicingNode.tp_dict,presetMask ,"presetMask" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,setMask ,"setMask" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,placedMask ,"placedMask" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,alignmentMask ,"alignmentMask" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,slicingTypeMask ,"slicingTypeMask" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,overCellMask ,"overCellMask" ); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,routingEstimatedMask,"routingEstimateMask"); + LoadObjectConstant(PyTypeSlicingNode.tp_dict,routingCreatedMask ,"routingCreateMask" ); + } + + +#endif // Shared Library Code Part. + +} // extern "C". + + +// +=================================================================+ +// | "PySlicingNode" Shared Library Code Part | +// +=================================================================+ + + +# if !defined(__PYTHON_MODULE__) + +SlicingNode* SlicingNodeCast ( PyObject* derivedObject ) { +//if (IsPyHVSlicingNode(derivedObject)) return PYHVSLICINGNODE_O(derivedObject); + if (IsPyHSlicingNode(derivedObject)) return PYHSLICINGNODE_O(derivedObject); + if (IsPyVSlicingNode(derivedObject)) return PYVSLICINGNODE_O(derivedObject); + if (IsPyDSlicingNode(derivedObject)) return PYDSLICINGNODE_O(derivedObject); + if (IsPyRHSlicingNode(derivedObject)) return PYRHSLICINGNODE_O(derivedObject); + if (IsPyRVSlicingNode(derivedObject)) return PYRVSLICINGNODE_O(derivedObject); + + return NULL; +} + +#endif + +} // Bora namespace. diff --git a/bora/src/PyVSlicingNode.cpp b/bora/src/PyVSlicingNode.cpp new file mode 100644 index 00000000..a9ab463b --- /dev/null +++ b/bora/src/PyVSlicingNode.cpp @@ -0,0 +1,115 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./bora/PyVSlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "bora/PyVSlicingNode.h" + + +namespace Isobar { + + using namespace Hurricane; + using namespace Bora; + + +extern "C" { + + +#undef ACCESS_OBJECT +#undef ACCESS_CLASS +#define ACCESS_OBJECT _baseObject._object +#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject) +#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(VSlicingNode,node,function) + + +// +=================================================================+ +// | "PyVSlicingNode" Python Module Code Part | +// +=================================================================+ + +#if defined(__PYTHON_MODULE__) + + + // +-------------------------------------------------------------+ + // | "PyVSlicingNode" Attribute Methods | + // +-------------------------------------------------------------+ + + + static PyObject* PyVSlicingNode_create ( PyObject* , PyObject* args ) + { + unsigned int alignment = AlignBottom; + VSlicingNode* node = NULL; + + HTRY + if (not PyArg_ParseTuple(args,"I:VSlicingNode.create", &alignment) ) { + PyErr_SetString ( ConstructorError, "VSlicingNode.create(): Invalid/bad type parameters ." ); + return NULL; + } + node = VSlicingNode::create( alignment ); + HCATCH + + return PyVSlicingNode_NEW(node); + } + + + // Standart Destroy (Attribute). + + + // --------------------------------------------------------------- + // PyVSlicingNode Attribute Method table. + + PyMethodDef PyVSlicingNode_Methods[] = + { { "create" , (PyCFunction)PyVSlicingNode_create , METH_VARARGS|METH_STATIC + , "Create a new VSlicingNode." } + , { NULL, NULL, 0, NULL } /* sentinel */ + }; + + + // +-------------------------------------------------------------+ + // | "PyVSlicingNode" Object Methods | + // +-------------------------------------------------------------+ + + + PythonOnlyDeleteMethod(VSlicingNode) + PyTypeObjectLinkPyType(VSlicingNode) + + +#else // End of Python Module Code Part. + +// +=================================================================+ +// | "PyVSlicingNode" Shared Library Code Part | +// +=================================================================+ + + + extern PyObject* PyVSlicingNode_NEW ( VSlicingNode* node ) + { + if (not node) Py_RETURN_NONE; + + PyVSlicingNode* pyNode = NULL; + HTRY + pyNode = PyObject_NEW( PyVSlicingNode, &PyTypeVSlicingNode ); + if (not pyNode) return NULL; + pyNode->ACCESS_OBJECT = node; + HCATCH + return (PyObject*)pyNode; + } + + + PyTypeInheritedObjectDefinitions(VSlicingNode, SlicingNode) + + +#endif // End of Shared Library Code Part. + +} // extern "C". + +} // Isobar namespace. diff --git a/bora/src/RHSlicingNode.cpp b/bora/src/RHSlicingNode.cpp new file mode 100644 index 00000000..c2b70e52 --- /dev/null +++ b/bora/src/RHSlicingNode.cpp @@ -0,0 +1,208 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./RHSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DataBase.h" +#include "hurricane/NetExternalComponents.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/AllianceFramework.h" +#include "bora/RHSlicingNode.h" + + +namespace Bora { + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::DataBase; + using Hurricane::Box; + using Hurricane::NetExternalComponents; + + +// ------------------------------------------------------------------- +// Class : "Bora::RHSlicingNode". + + + RHSlicingNode::RHSlicingNode ( DbU::Unit height ) + : RHVSlicingNode() + { + RHBoxSet* node = RHBoxSet::create( height ); + _nodeSets->push_back( node ); + _boxSet = node; + _minHeight = height; + if (_parent) _minWidth = _parent->getWidth(); + else _minWidth = 0; + + DbU::Unit hpitch = _rg->getHorizontalPitch(); + if (height % hpitch) + cerr << Warning( "RHSlicingNode::RHSlicingNode(): On %s, height is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(height).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; + } + + + RHSlicingNode::RHSlicingNode ( Hurricane::Instance* instance ) + : RHVSlicingNode() + { + RHBoxSet* node = RHBoxSet::create( instance->getMasterCell()->getAbutmentBox().getHeight() ); + _nodeSets->push_back( node ); + _boxSet = node; + _minHeight = instance->getMasterCell()->getAbutmentBox().getHeight(); + setRailInstance( instance ); + if (_parent) _minWidth = _parent->getWidth(); + else _minWidth = 0; + } + + + RHSlicingNode::~RHSlicingNode () + { } + + + RHSlicingNode* RHSlicingNode::create ( DbU::Unit height ) + { + return new RHSlicingNode( height ); + } + + + RHSlicingNode* RHSlicingNode::create ( Hurricane::Net* net + , Hurricane::Layer* layer + , int npitch + , string cname + , string iname ) + { + Cell* cell = Hurricane::Cell::create( Hurricane::DataBase::getDB()->getRootLibrary(), cname ); + Net* subnet = Hurricane::Net::create( cell, net->getName() ); + DbU::Unit height = CRL::AllianceFramework::get()->getRoutingGauge()->getHorizontalPitch() * npitch; + subnet->setExternal( true ); + + Hurricane::Horizontal* h = Hurricane::Horizontal::create( subnet, layer, height/2, height ); + NetExternalComponents::setExternal( h ); + + Hurricane::Instance* instance = Hurricane::Instance::create( _cell, iname, cell ); + instance->getPlug( subnet )->setNet( net ); + cell->setAbutmentBox( Box( 0, 0, 0, height ) ); + SlicingNode::addRailSegments( h ); + + return new RHSlicingNode( instance ); + } + + + RHSlicingNode* RHSlicingNode::clone ( unsigned int tr ) + { + RHSlicingNode* node = RHSlicingNode::create( getHeight() ); + return node; + } + + + DbU::Unit RHSlicingNode::getWidth () const + { return (_parent) ? _parent->getWidth() : 0; } + + + void RHSlicingNode::setHeight ( DbU::Unit height ) + { + _boxSet->setHeight( height ); + + DbU::Unit hpitch = _rg->getHorizontalPitch(); + if (height % hpitch) + cerr << Warning( "RHSlicingNode::getHeight(): On %s, height is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(height).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; + } + + + void RHSlicingNode::estimateChannelsSize () + { + cdebug_log(535,0) << "RHSlicingNode::estimateChannelsSize() " << this << endl; + + if (not getRailInstance()) { + if (_gcell and _rg) { + DbU::Unit hpitch = _rg->getHorizontalPitch(); + + if (getMaxWireOccupation() > 0) { + int occupancyH = getMaxWireOccupation(); //+1 for having enough space + if (occupancyH % 2) ++occupancyH; + updateMasterSize( occupancyH*hpitch ); + } else + updateMasterSize( 2*hpitch ); + + setRoutingEstimated(RoutingEstimated); + } else + cerr << Error( "RHSlicingNode::estimateChannelsSize()): Technology missing." ) << endl; + } + } + + + void RHSlicingNode::_expandRoutingChannel () + { + SlicingNode* master = this; + while ( master->getMaster() ) master = master->getMaster(); + + cdebug_log(535,0) << "RHSlicingNode::_expandRoutingChannel() " + << this << " height:" << DbU::getValueString(master->getHeight()) << endl; + + setHeight( master->getHeight() ); + setRoutingEstimated( RoutingEstimated ); + } + + + void RHSlicingNode::expandRoutingChannel ( DbU::Unit height, DbU::Unit width ) + { + cdebug_log(535,0) << "RHSlicingNode::expandRoutingChannel(DbU::Unit,DbU::Unit) " + << this << " height:" << DbU::getValueString(height) << endl; + + setHeight( height ); + setRoutingEstimated( RoutingEstimated ); + } + + + void RHSlicingNode::updateMasterSize ( DbU::Unit size ) + { + SlicingNode* master = this; + while ( master->getMaster() ) master = master->getMaster(); + if (master->getHeight() < size) master->setHeight( size ); + } + + + void RHSlicingNode::setGCell ( Anabatic::GCell* gcell ) + { + cdebug_log(535,1) << "RHSlicingNode::setGCell() " << gcell << endl; + + _gcell = gcell; + if (_gcell) { + if (_railInstance) _gcell->setType( Anabatic::Flags::HRailGCell ); + else _gcell->setType( Anabatic::Flags::HChannelGCell ); + } + + cdebug_tabw(535,-1); + } + + + void RHSlicingNode::setWidth ( DbU::Unit width ) + { + cerr << Error( "RHSlicingNode::setWidth(): Unimplemented on this type." ) << endl; + } + + + string RHSlicingNode::_getTypeName () const + { return "RHSlicingNode"; } + + +} diff --git a/bora/src/RHVSlicingNode.cpp b/bora/src/RHVSlicingNode.cpp new file mode 100644 index 00000000..f6ca6cb8 --- /dev/null +++ b/bora/src/RHVSlicingNode.cpp @@ -0,0 +1,230 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./bora/RHVSlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Box.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/Transformation.h" +#include "hurricane/UpdateSession.h" +#include "bora/ChannelRouting.h" +#include "bora/RHVSlicingNode.h" + + +namespace Bora { + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Box; + using Hurricane::Component; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::UpdateSession; + using Hurricane::Transformation; + + +// ------------------------------------------------------------------- +// Class : "Bora::RHVSlicingNode". + + + int RHVSlicingNode::_count = 0; + int RHVSlicingNode::_countAll = 0; + + + RHVSlicingNode::RHVSlicingNode() + : SlicingNode( RoutingSNode, NodeSets::create(), UnknownAlignment, NULL ) + , _railInstance (NULL) + , _minHeight (0) + , _minWidth (0) + , _wireOccupation(NULL) + { + ++_count; + + setPreset (Preset); + setSet (Set ); + setOverCell(OverCell); + _wireOccupation = ChannelRouting::create(); + } + + + RHVSlicingNode::~RHVSlicingNode () + { --_count; } + + + void RHVSlicingNode::print () const + { + cerr << "- Print from Slicing Node - " << endl; + if (_railInstance) cerr << "RailInstance: " << _railInstance << endl; + SlicingNode::print(); + } + + + void RHVSlicingNode::_setGlobalSize ( DbU::Unit height, DbU::Unit width ) + { } + + + void RHVSlicingNode::preDestroy () + { + if(_wireOccupation) _wireOccupation->destroy(); + SlicingNode::preDestroy(); + } + + + void RHVSlicingNode::destroy () + { + RHVSlicingNode::preDestroy(); + delete this; + } + + + void RHVSlicingNode::preRecursiveDestroy () + { + SlicingNode::preRecursiveDestroy(); + } + + + void RHVSlicingNode::recursiveDestroy () + { + RHVSlicingNode::preRecursiveDestroy(); + delete this; + } + + + void RHVSlicingNode::resetSize () + { + _boxSet->setHeight( _minHeight ); + _boxSet->setWidth ( _minWidth ); + } + + + bool RHVSlicingNode::isSame ( SlicingNode* node, unsigned int flags ) const + { + return ( (getHeight() == node->getHeight()) + and (getWidth () == node->getWidth ()) ); + } + + + bool RHVSlicingNode::isSymmetric ( SlicingNode* node, unsigned int symmetryType, unsigned int flags ) const + { + return ( (getHeight() == node->getHeight()) + and (getWidth () == node->getWidth ()) ); + } + + + void RHVSlicingNode::setRailInstance ( Hurricane::Instance* instance ) + { _railInstance = instance; } + + + void RHVSlicingNode::_place ( DbU::Unit x, DbU::Unit y, bool replace ) + { + SlicingNode::_place( x, y, replace ); + if (_railInstance) { + Net* supplyNet = NULL; + size_t count = 0; + for ( Net* net : _railInstance->getMasterCell()->getNets()) + { supplyNet = net; ++count; } + + if (count != 1) + cerr << Error( "RHVSlicingNode::_place(DbU::Unit,DbU::Unit,bool): Several Nets in Rail Instance Cell." ) << endl; + + Component* wire = NULL; + count = 0; + + for ( Component* component : supplyNet->getComponents() ) + { wire = component; ++count; } + + if (count != 1) + cerr << Error( "RHVSlicingNode::_place(DbU::Unitx,DbU::Unit,bool): Several Components in Rail Instance Cell." ) << endl; + + Horizontal* h = dynamic_cast(wire); + Vertical* v = dynamic_cast (wire); + UpdateSession::open(); + + if (h) { + h->setDxSource( 0 ); + h->setDxTarget( getRootWidth() ); + + _railInstance->getMasterCell()->setAbutmentBox( Box( 0, 0, getRootWidth(), getHeight() ) ); + _railInstance->setTransformation( Transformation( _cell->getAbutmentBox().getXMin(), getY() ) ); + } else if (v) { + v->setDySource( 0 ); + v->setDyTarget( getRootHeight() ); + _railInstance->getMasterCell()->setAbutmentBox( Box( 0, 0, getWidth(), getRootHeight() ) ); + _railInstance->setTransformation(Transformation( getX(), _cell->getAbutmentBox().getYMin() ) ); + } else + cerr << Error( "RHVSlicingNode::_place(DbU::Unit,DbU::Unit,bool): Unknown segment type." ) << endl; + + _railInstance->setPlacementStatus( Instance::PlacementStatus::PLACED ); + UpdateSession::close(); + } + } + + + void RHVSlicingNode::addWireOccupation ( DbU::Unit min, DbU::Unit max, Net* net ) + { if ( _wireOccupation and (min != max) ) _wireOccupation->insertChannel(min, max, net); } + + + void RHVSlicingNode::resetWireOccupation () + { if (_wireOccupation) _wireOccupation->reset(); } + + + int RHVSlicingNode::getMaxWireOccupation () + { return (_wireOccupation) ? _wireOccupation->getMaxCount()+1 : 0; } + + + unsigned int RHVSlicingNode::getAlignment () const + { + cerr << Error( "RHVSlicingNode::getAlignment(): Unimplemented on this type." ) << endl; + return UnknownAlignment; + } + + + NodeSets* RHVSlicingNode::getNodeSets () const + { + cerr << Error( "RHVSlicingNode::getNodeSets(): Unimplemented on this type." ) << endl; + return NULL; + } + + + BoxSet* RHVSlicingNode::getPairH ( DbU::Unit ) const + { + cerr << Error( "RHVSlicingNode::getPaitH(): Unimplemented on this type." ) << endl; + return _boxSet; + } + + + BoxSet* RHVSlicingNode::getPairHW( DbU::Unit , DbU::Unit ) const + { + cerr << Error( "RHVSlicingNode::getPaitHW(): Unimplemented on this type." ) << endl; + return _boxSet; + } + + + void RHVSlicingNode::setPairH( DbU::Unit ) + { + cerr << Error( "RHVSlicingNode::setPaitH(): Unimplemented on this type." ) << endl; + } + + + void RHVSlicingNode::setPairHW( DbU::Unit , DbU::Unit ) + { + cerr << Error( "RHVSlicingNode::setPaitHW(): Unimplemented on this type." ) << endl; + } + + +} // Bora namespace. diff --git a/bora/src/RVSlicingNode.cpp b/bora/src/RVSlicingNode.cpp new file mode 100644 index 00000000..53a6183c --- /dev/null +++ b/bora/src/RVSlicingNode.cpp @@ -0,0 +1,194 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./RVSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DataBase.h" +#include "hurricane/NetExternalComponents.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/AllianceFramework.h" +#include "bora/RVSlicingNode.h" + + +namespace Bora { + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::DataBase; + using Hurricane::Box; + using Hurricane::NetExternalComponents; + + +// ------------------------------------------------------------------- +// Class : "Bora::RVSlicingNode". + + + RVSlicingNode::RVSlicingNode ( DbU::Unit width ) + : RHVSlicingNode() + { + RVBoxSet* node = RVBoxSet::create( width ); + _nodeSets->push_back( node ); + _boxSet = node; + _minWidth = width; + if (_parent) _minHeight = _parent->getHeight(); + else _minHeight = 0; + + DbU::Unit vpitch = _rg->getVerticalPitch(); + if (width % vpitch) + cerr << Warning( "RVSlicingNode::RVSlicingNode(): On %s, width is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(width).c_str() + , DbU::getValueString(vpitch).c_str() + ) << endl; + } + + + RVSlicingNode::RVSlicingNode ( Hurricane::Instance* instance ) + : RHVSlicingNode() + { + RVBoxSet* node = RVBoxSet::create( instance->getMasterCell()->getAbutmentBox().getWidth() ); + _nodeSets->push_back( node ); + _boxSet = node; + _minHeight = instance->getMasterCell()->getAbutmentBox().getWidth(); + setRailInstance( instance ); + if (_parent) _minWidth = _parent->getWidth(); + else _minWidth = 0; + } + + + RVSlicingNode::~RVSlicingNode () + { } + + + RVSlicingNode* RVSlicingNode::create ( DbU::Unit width ) + { + return new RVSlicingNode( width ); + } + + + RVSlicingNode* RVSlicingNode::create ( Hurricane::Net* net + , Hurricane::Layer* layer + , int npitch + , string cname + , string iname ) + { + Cell* cell = Hurricane::Cell::create( Hurricane::DataBase::getDB()->getRootLibrary(), cname ); + Net* subnet = Hurricane::Net::create( cell, net->getName() ); + + DbU::Unit width = CRL::AllianceFramework::get()->getRoutingGauge()->getVerticalPitch()* npitch; + subnet->setExternal( true ); + + Hurricane::Vertical* v = Hurricane::Vertical::create( subnet, layer, width/2, width ); + NetExternalComponents::setExternal( v ); + + Hurricane::Instance* instance = Hurricane::Instance::create( _cell, iname, cell ); + instance->getPlug( subnet )->setNet( net ); + cell->setAbutmentBox( Box( 0, 0, width, 0) ); + + SlicingNode::addRailSegments( v ); + + return new RVSlicingNode( instance ); + } + + + RVSlicingNode* RVSlicingNode::clone ( unsigned int tr ) + { + RVSlicingNode* node = RVSlicingNode::create( getWidth() ); + return node; + } + + + DbU::Unit RVSlicingNode::getHeight () const + { return (_parent) ? _parent->getHeight() : 0; } + + + void RVSlicingNode::setWidth ( DbU::Unit width ) + { _boxSet->setWidth( width ); } + + + void RVSlicingNode::estimateChannelsSize () + { + cdebug_log(535,0) << "RVSlicingNode::estimateChannelsSize() " << this << endl; + + if (not getRailInstance()) { + if (_gcell and _rg) { + DbU::Unit vpitch = _rg->getVerticalPitch(); + + if (getMaxWireOccupation() > 0) { + int occupancyV = getMaxWireOccupation(); // +1 for having enough space + cdebug_log(535,0) << this << " has " << getMaxWireOccupation() << " (-1) tracks" << endl; + + if (occupancyV % 2) ++occupancyV; + updateMasterSize( occupancyV * vpitch ); + } else + updateMasterSize( 2 * vpitch ); + setRoutingEstimated( RoutingEstimated ); + } else + cerr << Error( "RHSlicingNode::estimateChannelsSize(: Technology missing." ) << endl; + } + } + + + void RVSlicingNode::_expandRoutingChannel () + { + SlicingNode* master = this; + while ( master->getMaster() ) master = master->getMaster(); + setWidth( master->getWidth() ); + setRoutingEstimated( RoutingEstimated ); + } + + + void RVSlicingNode::expandRoutingChannel ( DbU::Unit height, DbU::Unit width ) + { + setWidth( width ); + setRoutingEstimated( RoutingEstimated ); + } + + + void RVSlicingNode::setGCell ( Anabatic::GCell* gcell ) + { + cdebug_log(535,1) << "RVSlicingNode::setGCell() " << gcell << endl; + + _gcell = gcell; + if (_gcell) { + if (_railInstance) _gcell->setType( Anabatic::Flags::VRailGCell ); + else _gcell->setType( Anabatic::Flags::VChannelGCell ); + } + + cdebug_tabw(535,-1); + } + + + void RVSlicingNode::updateMasterSize ( DbU::Unit size ) + { + SlicingNode* master = this; + while ( master->getMaster() ) master = master->getMaster(); + if (master->getWidth() < size) master->setWidth( size ); + } + + + void RVSlicingNode::setHeight( DbU::Unit height ) + { + cerr << Error( "RVSlicingNode::setWidth(): Unimplemented on this type." ) << endl; + } + + + string RVSlicingNode::_getTypeName () const + { return "RVSlicingNode"; } + + +} // Bora namespace. diff --git a/bora/src/SlicingDataModel.cpp b/bora/src/SlicingDataModel.cpp new file mode 100644 index 00000000..bf3f14f4 --- /dev/null +++ b/bora/src/SlicingDataModel.cpp @@ -0,0 +1,163 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul Chaput, Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./SlicingDataModel.h" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/DbU.h" +#include "hurricane/viewer/Graphics.h" +#include "hurricane/analog/AnalogCellExtension.h" +#include "bora/SlicingDataModel.h" + + +namespace Bora { + + + using namespace std; + using Hurricane::Graphics; + using Hurricane::DbU; + using Analog::AnalogCellExtension; + + + SlicingDataModel::SlicingDataModel ( QObject* parent ) + : QAbstractTableModel(parent) + , _cell(NULL) + { } + + + SlicingDataModel::~SlicingDataModel () + { } + + + void SlicingDataModel::setCell( Hurricane::Cell* cell ) + { + _cell = cell; + } + + + QVariant SlicingDataModel::data ( const QModelIndex& index, int role ) const + { + static QFont nameFont = Graphics::getFixedFont ( QFont::Bold ); + static QFont valueFont = Graphics::getFixedFont ( QFont::Normal, true ); + SlicingNode* slicingtree = AnalogCellExtension::get( _cell ); + + if ( (not slicingtree) or (not index.isValid()) ) return QVariant(); + + if ( role == Qt::SizeHintRole ) { + switch (index.column()) { + case 0: return 200; + default: + case 1: return -1; + } + } + + if ( role == Qt::FontRole ) { + switch (index.column()) { + case 0: return nameFont; + default: + case 1: return valueFont; + } + } + + if ( role == Qt::DisplayRole ) { + int row = index.row(); + if ( row < (int)rowCount() ) { + NodeSets nodeSets = slicingtree->getNodeSets(); + switch ( index.column() ) { + case 0: return QVariant( row ); + case 1: return QVariant( DbU::toPhysical(nodeSets[row]->getHeight() , DbU::Micro) ); + case 2: return QVariant( DbU::toPhysical(nodeSets[row]->getWidth() , DbU::Micro) ); + case 3: return QVariant( nodeSets[row]->getOccupationArea() ); + case 4: return QVariant( nodeSets[row]->getCpt() ); + case 5: return QVariant( (double) ( nodeSets[row]->getWidth() + / nodeSets[row]->getHeight()) ); + case 6: return QVariant( DbU::getPhysical( nodeSets[row]->getWidth() ,DbU::Micro) + * DbU::getPhysical( nodeSets[row]->getHeight(),DbU::Micro) ); + default: + if (index.column() >= columnCount()) return QVariant(); + } + } + } + if ( role == Qt::UserRole ){ + return QVariant( index.row() ); + } + + return QVariant(); + } + + + QVariant SlicingDataModel::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(); + + switch ( section ) { + case 0: return QVariant ( tr("Order" ) ); + case 1: return QVariant ( QString::fromUtf8("Height (µm)") ); + case 2: return QVariant ( QString::fromUtf8("Width (µm)") ); + case 3: return QVariant ( tr("Occupation Area (%)") ); + case 4: return QVariant ( tr("Counter" ) ); + case 5: return QVariant ( tr("Ratio (W/H)" ) ); + case 6: return QVariant ( QString::fromUtf8("Area (µm²)") ); + default: + if (section >= columnCount()) return QVariant(); + } + + return QVariant ( tr("?") ); + } + + + int SlicingDataModel::rowCount ( const QModelIndex& parent ) const + { + SlicingNode* slicingtree = AnalogCellExtension::get( _cell ); + if (slicingtree != NULL){ + NodeSets nodeSets = slicingtree->getNodeSets(); + return nodeSets.size(); + } else { + return 0; + } + } + + + int SlicingDataModel::columnCount ( const QModelIndex& parent ) const + { + return 7; + } + + + BoxSet* SlicingDataModel::getBoxSet( int index ) + { + SlicingNode* slicingtree = AnalogCellExtension::get( _cell ); + if (slicingtree){ + NodeSets nodeSets = slicingtree->getNodeSets(); + return nodeSets[index]; + } + return NULL; + } + + + void SlicingDataModel::updateContents() + { + beginResetModel(); + endResetModel(); + } + + +} // Bora namespace. + diff --git a/bora/src/SlicingDataWidget.cpp b/bora/src/SlicingDataWidget.cpp new file mode 100644 index 00000000..f003de0f --- /dev/null +++ b/bora/src/SlicingDataWidget.cpp @@ -0,0 +1,177 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul Chaput, Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./SlicingDataWidget.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hurricane/viewer/Graphics.h" +#include "hurricane/viewer/CellViewer.h" +#include "bora/SlicingDataModel.h" +#include "bora/SlicingDataWidget.h" +#include "bora/GraphicBoraEngine.h" + + +namespace Bora { + + using namespace std; + using Hurricane::Graphics; + using Analog::AnalogCellExtension; + + + SlicingDataWidget::SlicingDataWidget ( QWidget* parent ) + : QWidget (parent) + , _viewer (NULL) + , _baseModel(NULL) + , _sortModel(NULL) + , _view (NULL) + , _rowHeight(20) + { + setAttribute ( Qt::WA_DeleteOnClose ); + setAttribute ( Qt::WA_QuitOnClose, false ); + + _rowHeight = QFontMetrics(Graphics::getFixedFont()).height() + 4; + + _view = new QTableView ( this ); + _view->setShowGrid ( false ); + _view->setAlternatingRowColors ( true ); + _view->setSelectionBehavior ( QAbstractItemView::SelectRows ); + _view->setSelectionMode ( QAbstractItemView::SingleSelection ); + _view->setSortingEnabled ( true ); + _view->installEventFilter ( this ); + _view->viewport()->installEventFilter ( this ); + + QHeaderView* horizontalHeader = _view->horizontalHeader (); + //horizontalHeader->setStretchLastSection ( true ); + horizontalHeader->setMinimumSectionSize ( 20 ); + //horizontalHeader->setResizeMode ( QHeaderView::ResizeToContents ); + //horizontalHeader->setDefaultSectionSize ( 100 ); + horizontalHeader->setSortIndicatorShown(true); + horizontalHeader->setStretchLastSection(true); + + QHeaderView* verticalHeader = _view->verticalHeader (); + verticalHeader->setVisible ( false ); + verticalHeader->setDefaultSectionSize ( _rowHeight ); + + _baseModel = new SlicingDataModel( this ); + _sortModel = new QSortFilterProxyModel( this ); + _sortModel->setSourceModel ( _baseModel ); + _sortModel->setDynamicSortFilter( true ); + //_sortModel->setFilterKeyColumn ( 1 ); + + _view->setModel( _sortModel ); + //_view->horizontalHeader()->setStretchLastSection( true ); + //_view->resizeColumnToContents( 0 ); + //_view->model()->setCurrentIndex() + + QGridLayout* slicingDataLayout = new QGridLayout(); + slicingDataLayout->addWidget(_view, 0, 0, 1, 1); + + setLayout( slicingDataLayout ); + + setWindowTitle( tr("SlicingTree Datas") ); + resize( 500, 300 ); + + connect( _view->horizontalHeader () , SIGNAL(sectionClicked(int)), this, SLOT(columnPressed(int)) ); + connect( _view , SIGNAL(clicked(const QModelIndex &)), this, SLOT(cellClicked(const QModelIndex &)) ); + + } + + + SlicingDataWidget::~SlicingDataWidget () + { } + + + void SlicingDataWidget::setViewer ( CellViewer* viewer ) + { + if (_viewer) { + disconnect( _viewer, 0, this , 0 ); + disconnect( this , 0, _viewer, 0 ); + } + + _viewer = viewer; + _baseModel->setCell(_viewer->getCellWidget()->getCell()); + } + + + void SlicingDataWidget::columnPressed ( int column ) + { + _view->sortByColumn(column); + } + + + void SlicingDataWidget::cellClicked (const QModelIndex& index) + { + SlicingNode* slicingtree = AnalogCellExtension::get( _viewer->getCellWidget()->getCell() ); + if ( index.isValid() ) { + cdebug_log(540,0) << "SlicingDatasWidget::cellClicked(): index=(" + << index.column() << "," << index.row() << ")" << endl; + + BoxSet* boxSet = _baseModel->getBoxSet((_view->model()->data(index, Qt::UserRole)).toInt()); + emit updatePlacement( boxSet ); + emit updateSelectedPoint( DbU::getPhysical(slicingtree->getWidth() , DbU::Micro) + , DbU::getPhysical(slicingtree->getHeight(), DbU::Micro) + ); + } + } + + + BoxSet* SlicingDataWidget::getBoxSet ( int index ) + { return _baseModel->getBoxSet( index ); } + + + void SlicingDataWidget::updateSelectedRow ( double x, double y ) + { + QAbstractItemModel* model = _view->model(); + int row = 0; + for( int irow = 0; irow < model->rowCount(); ++irow ) { + QModelIndex idxH = model->index( irow, 1 ); + QModelIndex idxW = model->index( irow, 2 ); + if ( (_view->model()->data(idxH).toDouble() == y) && (_view->model()->data(idxW).toDouble() == x) ){ row = irow; break; } + } + _view->selectRow(row); + } + + + bool SlicingDataWidget::eventFilter ( QObject* object, QEvent* event ) + { + if ( event->type() == QEvent::KeyPress ) { + QModelIndex index = _view->currentIndex(); + if ( index.isValid() ) { + BoxSet* boxSet = _baseModel->getBoxSet((_view->model()->data(index, Qt::UserRole)).toInt()); + emit updatePlacement( boxSet ); + } + } + return QObject::eventFilter( object, event ); + } + + + void SlicingDataWidget::updateContents() + { + _baseModel->updateContents(); + } + + +} // Bora namespace. diff --git a/bora/src/SlicingNode.cpp b/bora/src/SlicingNode.cpp new file mode 100644 index 00000000..a76042c7 --- /dev/null +++ b/bora/src/SlicingNode.cpp @@ -0,0 +1,1173 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./SlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Warning.h" +#include "hurricane/DeepNet.h" +#include "hurricane/RoutingPad.h" +#include "crlcore/RoutingGauge.h" +#include "bora/SlicingNode.h" + + +namespace Bora { + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Point; + using Hurricane::Box; + using Hurricane::DeepNet; + using Hurricane::Component; + using Hurricane::Plug; + using Hurricane::RoutingPad; + using Analog::AnalogCellExtension; + + +// ------------------------------------------------------------------- +// Class : "Bora::SlicingNode". + + + CRL::RoutingGauge* SlicingNode::_rg = NULL; + Cell* SlicingNode::_cell = NULL; + Katana::KatanaEngine* SlicingNode::_katana = NULL; + vector SlicingNode::_railSegments = vector(); + size_t SlicingNode::_idCounter = 0; + + + SlicingNode::SlicingNode ( unsigned int type + , NodeSets* nodeSets + , unsigned int alignment + , BoxSet* boxSet + ) + : Super() + , _id (_idCounter++) + , _parent (NULL) + , _flags (0) + , _nodeSets(nodeSets) + , _x (0) + , _y (0) + , _boxSet (NULL) + , _gcell (NULL) + , _master (NULL) + { + + setType (type); + setAlignment(alignment); + + if (boxSet != NULL) { + setBoxSet(boxSet); + setPreset(Preset); + setSet (Set); + } + + //cdebug_log(536,0) << "SlicingNode::SlicingNode(unsigned,NodeSet*,unsigned,BoxSet*) - " << this << endl; + } + + + SlicingNode::SlicingNode ( unsigned int type ) + : Super() + , _parent (NULL) + , _flags (0) + , _nodeSets(NodeSets::create( NULL, 0.0, 0.0, 0.0 )) + , _x (0) + , _y (0) + , _boxSet (NULL) + , _gcell (NULL) + , _master (NULL) + { + setType (type); + setAlignment(UnknownAlignment); + + //cdebug_log(536,1) << "SlicingNode::SlicingNode(unsigned) - " << this << endl; + } + + + SlicingNode::~SlicingNode () + { } + + + bool SlicingNode::isSameSize ( BoxSet* boxSet ) const + { + if ( _boxSet and boxSet ) { + if ( (_boxSet->getHeight() == boxSet->getHeight()) + and (_boxSet->getWidth () == boxSet->getWidth ()) ) + return true; + } + return false; + } + + + bool SlicingNode::isSameSize ( DbU::Unit height, DbU::Unit width ) const + { + if (_boxSet) { + if ( (_boxSet->getHeight() == height) and (_boxSet->getWidth() == width) ) + return true; + } + return false; + } + + + bool SlicingNode::isEmpty () const + { return _nodeSets->empty(); } + + + bool SlicingNode::isSame ( SlicingNode* , unsigned int ) const + { + cerr << Error( "SlicingNode::isSame(): Base class method must never be called." ) << endl; + return false; + } + + + bool SlicingNode::isSymmetric ( SlicingNode* , unsigned int , unsigned int ) const + { + cerr << Error( "SlicingNode::isSymmetric(): Base class method must never be called." ) << endl; + return false; + } + + + DbU::Unit SlicingNode::getHeight () const + { return (_boxSet) ? _boxSet->getHeight() : 0; } + + + DbU::Unit SlicingNode::getWidth () const + { return (_boxSet) ? _boxSet->getWidth() : 0; } + + + DbU::Unit SlicingNode::getRootHeight () const + { return getRoot()->getHeight(); } + + + DbU::Unit SlicingNode::getRootWidth () const + { return getRoot()->getWidth(); } + + + DbU::Unit SlicingNode::getRootX () const + { return getRoot()->getX(); } + + + DbU::Unit SlicingNode::getRootY () const + { return getRoot()->getY(); } + + + int SlicingNode::getCpt () + { return (_boxSet) ? _boxSet->getCpt() : 0 ; } + + + double SlicingNode::getRatio () + { return (_boxSet) ? _boxSet->getRatio() : 0 ; } + + + double SlicingNode::getArea () + { return (_boxSet) ? _boxSet->getArea() : 0 ; } + + + DbU::Unit SlicingNode::getVPitch () + { + if (_rg) return _rg->getVerticalPitch(); + + cerr << Error( "SlicingNode::getVPitch(): RoutingGauge has not been defined." ) << endl; + return 0; + } + + + DbU::Unit SlicingNode::getHPitch () + { + if (_rg) return _rg->getHorizontalPitch(); + + cerr << Error( "SlicingNode::getHPitch(): RoutingGauge has not been defined." ) << endl; + return 0; + } + + + void SlicingNode::setBoxSet( BoxSet* boxSet ) + { + if (not isPreset()) { + if (_nodeSets->find(boxSet) != NULL) { + setSet( Set ); + _boxSet = boxSet; + } else { + cerr << Warning( "SlicingNode::setBoxSet(BoxSet*): Boxset not found." ) << endl; + } + } + } + + + void SlicingNode::setBoxSet ( DbU::Unit height, DbU::Unit width ) + { + if (not isPreset()) { + BoxSet* match = _nodeSets->find( height, width ); + if (match) { + setSet( Set ); + _boxSet = match; + } else { + cerr << Warning( "SlicingNode::setBoxSet(DbU::Unit w,DbU::Unit h): Boxset not found." ) << endl; + } + } + } + + + void SlicingNode::setBoxSet ( size_t index ) + { + if (index+1 > _nodeSets->size()) + cerr << Warning( "SlicingNode::setBoxSet(size_t): Out of bound index." ) << endl; + else + _boxSet = _nodeSets->at( index ); + } + + + void SlicingNode::_setBoxSet ( BoxSet* boxSet ) + { + if (isPreset()) return; + + setSet( Set ); + _boxSet = boxSet; + } + + + void SlicingNode::setX ( DbU::Unit x ) + { + float pitch = _rg->getVerticalPitch(); + + if (fmod(x,pitch) > 1e-06) { + cerr << Warning( "SlicingNode::setX(): On %s, X position %s is not pitched on %s (will be adjusted)." + , getString(this).c_str() + , DbU::getValueString(x ).c_str() + , DbU::getValueString(pitch).c_str() + ) << endl; + } + + _x = x; + } + + + void SlicingNode::setY ( DbU::Unit y ) + { + float pitch = _rg->getHorizontalPitch(); + + if (fmod(y,pitch) > 1e-06) { + cerr << Warning( "SlicingNode::setY(): On %s, Y position %s is not pitched on %s (will be adjusted)." + , getString(this).c_str() + , DbU::getValueString(y ).c_str() + , DbU::getValueString(pitch).c_str() + ) << endl; + } + + _y = y; + } + + + void SlicingNode::clearParentsNodeSets () + { + if (_parent) _parent->clearParentsNodeSets(); + if (getMaster()) _nodeSets->clear(); + } + + + void SlicingNode::resetSlicingTree() + { + // Notes: Reset a slicing tree means: + // - Empty NodeSets of every parent + // - Unset every nodes that are not preset + // - Unplace every nodes + + clearParentsNodeSets(); + getRoot()->_resetSlicingTree(); + } + + + void SlicingNode::_resetSlicingTree () + { + _x = 0; + _y = 0; + setPlaced( false ); + + if (not isPreset()){ + _boxSet = NULL; + setSet( false ); + } + } + + + void SlicingNode::print () const + { + printParent(); + if (isPreset()) cerr << "Preset : True" << endl; + else cerr << "Preset : False " << endl; + if (isSet()) cerr << "Set : True" << endl; + else cerr << "Set : False " << endl; + if (isPlaced()) cerr << "Placed : True" << endl; + else cerr << "Placed : False " << endl; + if (getMaster()) { + cerr << "Master : "; + getMaster()->printLine(); + } + + unsigned int type = getType(); + if (type == HorizontalSNode) cerr << "Type : HorizontalSNode"<< endl; + else if (type == VerticalSNode ) cerr << "Type : VerticalSNode" << endl; + else if (type == DeviceSNode ) cerr << "Type : DeviceSNode" << endl; + else if (type == RoutingSNode ) cerr << "Type : RoutingSNode" << endl; + else cerr << "Type : UnknownType" << endl; + + cerr << "Height : " << DbU::getPhysical(getHeight(),DbU::Micro) << endl; + cerr << "Width : " << DbU::getPhysical(getWidth(),DbU::Micro) << endl; + cerr << "X : " << DbU::getPhysical(_x,DbU::Micro) << endl; + cerr << "Y : " << DbU::getPhysical(_y,DbU::Micro) << endl; + if (isRoutingEstimated()) cerr << "REstimated : True" << endl; + else cerr << "REstimated : False" << endl; + + //_nodeSets->print(); + cerr << "GCell : " << _gcell << endl; + if (not ((getType() == HorizontalSNode) or (getType() == VerticalSNode))) { + cerr << "GCell : " << _gcell << endl; + if (_gcell) { + cerr << "Edges : " << endl; + vector ne = _gcell->getNorthEdges(); + vector se = _gcell->getSouthEdges(); + vector ee = _gcell->getEastEdges(); + vector we = _gcell->getWestEdges(); + + cerr << "--- North : " << endl; + for ( Anabatic::Edge* edge : ne ) cerr << edge->getOpposite(_gcell) << endl; + cerr << "--- South : " << endl; + for ( Anabatic::Edge* edge : se ) cerr << edge->getOpposite(_gcell) << endl; + cerr << "--- East : " << endl; + for ( Anabatic::Edge* edge : ee ) cerr << edge->getOpposite(_gcell) << endl; + cerr << "--- West : " << endl; + for ( Anabatic::Edge* edge : we ) cerr << edge->getOpposite(_gcell) << endl; + } + } + cerr << endl; + } + + + void SlicingNode::printLine() const + { + unsigned int type = getType(); + if (_master) { + cerr << " [MASTER]: "; + _master->printLine(); + } + + if (type == HorizontalSNode) cerr << "Type : HorizontalSNode"; + else if (type == VerticalSNode ) cerr << "Type : VerticalSNode" ; + else if (type == DeviceSNode ) cerr << "Type : DeviceSNode" ; + else if (type == RoutingSNode ) cerr << "Type : RoutingSNode" ; + else cerr << "Type : UnknownType" ; + cerr << ", X: " << DbU::getPhysical(getX(),DbU::Micro); + cerr << ", Y: " << DbU::getPhysical(getY(),DbU::Micro); + cerr << ", W: " << setprecision(4) << DbU::getPhysical(getWidth() ,DbU::Micro); + cerr << ", H: " << setprecision(4) << DbU::getPhysical(getHeight(),DbU::Micro) << endl; + } + + + void SlicingNode::printParent() const + { + if (_parent) { + unsigned int type = _parent->getType(); + if (type == HorizontalSNode) cerr << "Parent : Type: HorizontalSNode"; + else if (type == VerticalSNode ) cerr << "Parent : Type: VerticalSNode"; + else cerr << "Parent : Type: UnknownType"; + cerr << ", H: " << setprecision(4) << DbU::getPhysical(_parent->getHeight(),DbU::Micro); + cerr << ", W: " << setprecision(4) << DbU::getPhysical(_parent->getWidth(),DbU::Micro); + cerr << ", X: " << DbU::getPhysical(_parent->getX(),DbU::Micro); + cerr << ", Y: " << DbU::getPhysical(_parent->getY(),DbU::Micro) << endl; + } else { + cerr << "Parent : IsROOT " << endl; + } +} + + + string SlicingNode::_getString () const + { + ostringstream os; + os << "<" << _getTypeName(); + os << " id:" << getId() << " gid:"; + if (getGCell()) os << getGCell()->getId(); + else os << "-"; + os << " choices:" << getNodeSets()->getBoxSets().size(); + os << ">"; + return os.str(); + } + + + string SlicingNode::_getTypeName () const + { return "SlicingNode"; } + + + void SlicingNode::printBoxSet () const + { if (_boxSet) _boxSet->print(); } + + + void SlicingNode::place ( DbU::Unit x, DbU::Unit y ) + { + cdebug_log(536,1) << "SlicingNode::place(DbU::Unit x, DbU::Unit y)" << endl; + + if (isSet()) { + _x = x; + _y = y; + setPlaced( Placed ); + + DbU::Unit hpitch = _rg->getHorizontalPitch(); + DbU::Unit vpitch = _rg->getVerticalPitch(); + + if (_x % vpitch) + cerr << Warning( "SlicingNode::place(): On %s, _x is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(_x).c_str() + , DbU::getValueString(vpitch).c_str() + ) << endl; + + if (_y % hpitch) + cerr << Warning( "SlicingNode::place(): On %s, _y is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(_y).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; + } else + cerr << Error( "SlicingNode::place(DbU::Unit x, DbU::Unit y): Device has not been set." ) << endl; + + cdebug_tabw(536,-1); + } + + + void SlicingNode::replace ( DbU::Unit x, DbU::Unit y ) + { + cdebug_log(536,1) << "SlicingNode::replace(DbU::Unit x, DbU::Unit y)" << endl; + + if (isSet()) { + _x = x; + _y = y; + setPlaced( Placed ); + } else + cerr << Error( "SlicingNode::replace(DbU::Unit x, DbU::Unit y): Device has not been set." ) << endl; + + cdebug_tabw(536,-1); + } + + + void SlicingNode::_place ( DbU::Unit x, DbU::Unit y, bool replace ) + { + cdebug_log(536,1) << "SlicingNode::place(DbU::Unit x, DbU::Unit y)" << endl; + SlicingNode::place(x,y); + cdebug_tabw(536,-1); + } + + + void SlicingNode::setGlobalSize ( DbU::Unit height, DbU::Unit width ) + { + cmess2 << " o Selecting box set (" << DbU::getValueString(height) + << "," << DbU::getValueString(width) << ")" << endl; + setBoxSet( height, width ); + } + + + void SlicingNode::setGlobalSize ( size_t index ) + { + cmess2 << " o Selecting box set at index " << index << endl; + setBoxSet( index ); + } + + + void SlicingNode::_setGlobalSize ( BoxSet* boxSet ) + { + cdebug_log(535,1) << "SlicingNode::_setGlobalSize( BoxSet* boxSet ) " << endl; + _setBoxSet( boxSet ); + cdebug_log(535,-1); + } + + + void SlicingNode::preDestroy () + { + if (_parent) _parent->removeNode(this); + //else { + // if (_railCell) _railCell->destroy(); + //} + if (getMaster()) _nodeSets->clear(); + } + + + void SlicingNode::destroy() + { + SlicingNode::preDestroy(); + delete this; + } + + + void SlicingNode::preRecursiveDestroy() + { + SlicingNode::preDestroy(); + } + + + void SlicingNode::recursiveDestroy () + { + SlicingNode::preRecursiveDestroy(); + delete this; + } + + + LSlicingNodes SlicingNode::getLeaves () + { + return LSlicingNodes(); + } + + + bool SlicingNode::checkInitialPlacement ( int& cpt ) const + { + // Notes:: Initial placement criteria is having at least 2 devices placed at (x, y) = (0, 0) + + bool initialPlacement = false; + if (cpt < 2) initialPlacement = true; + return initialPlacement; + } + + + void SlicingNode::updateCellAbutmentBox () + { + Point pmin = Point( getX(), getY() ); + Point pmax = Point( getX()+getWidth(), getY()+getHeight() ); + _cell->setAbutmentBox( Box(pmin,pmax) ); + } + + + void SlicingNode::setGCell ( Anabatic::GCell* gcell ) + { + _gcell = gcell; + cdebug_log(535,0) << "SlicingNode::setGCell() " << _gcell << endl; + } + + + void SlicingNode::setCell ( Cell* cell ) + { + if (not _parent) { + if (checkCellInstances(cell)) { + _cell = cell; + AnalogCellExtension::set( cell, this ); + } + } else + cerr << Warning( "SlicingNode::setCell(Cell*): Slicing tree's cell can only be set at root node." ) << endl; + } + + + void SlicingNode::setKatana ( Katana::KatanaEngine* katana ) + { _katana = katana; } + + + bool SlicingNode::checkCellInstances ( Cell* cell ) + { return true; } + + + SlicingNode* SlicingNode::findInstance ( Instance* instance ) + { return NULL; } + + + SlicingNode* SlicingNode::findSlicingNode ( Anabatic::GCell* gcell ) + { return NULL; } + + + SlicingNode* SlicingNode::findHorizontalParent () const + { + SlicingNode* node = _parent; + while ( node ) { + if (node->getType() == HorizontalSNode) break; + node = node->getParent(); + } + return node; + } + + + SlicingNode* SlicingNode::findVerticalParent () const + { + SlicingNode* node = _parent; + while ( node ) { + if (node->getType() == VerticalSNode) break; + node = node->getParent(); + } + return node; + } + + + size_t SlicingNode::getIndexInHorizontalParent () const + { + if (getParent()) { + if (getParent()->getType() == HorizontalSNode) { + const vector& children = getParent()->getChildren(); + + size_t i = 0; + for ( ; igetType() == getType() ) + and (children[i]->getHeight() == getHeight()) + and (children[i]->getWidth () == getWidth ()) + and (children[i]->getX() == getX() ) + and (children[i]->getY() == getY() ) ) + return i; + } + } else { + SlicingNode* node = getParent(); + + while ( node->getParent() ) { + if (node->getParent()->getType() == HorizontalSNode) + return node->getParent()->getChildIndex(node); + + node = node->getParent(); + } + } + } + return NodeSets::NotFound; + } + + + size_t SlicingNode::getIndexInVerticalParent () const + { + if (getParent()) { + if (getParent()->getType() == VerticalSNode) { + const vector& children = getParent()->getChildren(); + + size_t i = 0; + for ( ; igetType() == getType() ) + and (children[i]->getHeight() == getHeight()) + and (children[i]->getWidth () == getWidth ()) + and (children[i]->getX() == getX() ) + and (children[i]->getY() == getY() ) ) + return i; + } + } else { + SlicingNode* node = getParent(); + + while ( node->getParent() ) { + if (node->getParent()->getType() == VerticalSNode) + return node->getParent()->getChildIndex(node); + + node = node->getParent(); + } + } + } + return NodeSets::NotFound; + } + + + void SlicingNode::createRoutingPads () + { + cdebug_log(536,1) << "SlicingNode::createRoutingPads()" << endl; + + if (not _cell) { + cdebug_tabw(536,-1); + return; + } + + //_cell->flattenNets( Cell::Flags::StayOnPlugs ); + _cell->flattenNets(); + + cdebug_tabw(536,-1); + } + + + void SlicingNode::clearRoutingPads () + { + vector nets; + + for ( Net* net : _cell->getNets() ) { + DeepNet* n = dynamic_cast(net); + if (n) nets.push_back(n); + } + for ( DeepNet* net : nets ){ + net->destroy(); + } + for ( Net* net : _cell->getNets() ) { + vector rps; + for ( RoutingPad* rp : net->getRoutingPads() ) rps.push_back( rp ); + for ( RoutingPad* rp : rps ) rp->destroy(); + } + } + + + void SlicingNode::restrictDevices () + { + if (_gcell) { + Anabatic::Vertex* vertex + = _gcell->getObserver( Anabatic::GCell::Observable::Vertex ); + vertex->clearRestriction(); + } + } + + + void SlicingNode::setVertexRestriction ( Net* , Katana::KatanaEngine* ) + { } + + + void SlicingNode::estimateChannelsSize () + { setRoutingEstimated( RoutingEstimated ); } + + + void SlicingNode::expandRoutingChannel () + { setRoutingEstimated( RoutingEstimated ); } + + + void SlicingNode::_expandRoutingChannel () + { setRoutingEstimated( RoutingEstimated ); } + + + void SlicingNode::expandRoutingChannel ( DbU::Unit height, DbU::Unit width ) + { setRoutingEstimated( RoutingEstimated ); } + + + void SlicingNode::clearGlobalRouting () + { + vector segments; + vector contacts; + + for ( Net* net: _cell->getNets() ) { + for ( Component* component : net->getComponents() ) { + if (not SlicingNode::isRailSegments(dynamic_cast(component))) { + Hurricane::Horizontal* h = dynamic_cast(component); + Hurricane::Vertical* v = dynamic_cast (component); + Hurricane::Contact* c = dynamic_cast (component); + + if (h or v) segments.push_back(component); + if (c) contacts.push_back(component); + } + } + } + + for ( Component* component : segments ) component->destroy(); + for ( Component* component : contacts ) component->destroy(); + clearGCells(); + } + + + void SlicingNode::clearGCells () + { _gcell = NULL; } + + + void SlicingNode::updateGCellPosition () + { + if (_gcell) _gcell->setSouthWestCorner( getX(), getY() ); + + cdebug_log(535,0) << "SlicingNode::updateGCellPosition(): " << _gcell << endl; + } + + + void SlicingNode::updateGContacts() + { + if (_gcell) _gcell->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + + cdebug_log(535,0) << "SlicingNode::updateGContacts(): " << _gcell << endl; + } + + + int SlicingNode::getNbDevices() + { return 1; } + + + bool SlicingNode::containAxis ( DbU::Unit axis, unsigned int symmetryType ) + { + if (symmetryType == HSymmetry) return ( (axis > getX()) and (axis < getX()+getWidth ())); + else if (symmetryType == VSymmetry) return ( (axis > getY()) and (axis < getY()+getHeight())); + return false; + } + + + void SlicingNode::setRoutingGauge ( CRL::RoutingGauge* rg ) + { _rg = rg; } + + + void SlicingNode::addRailSegments ( Segment* segment ) + { _railSegments.push_back(segment); } + + + bool SlicingNode::isRailSegments ( Segment* segment ) + { + for ( Segment* rail : _railSegments ) { + if (segment == rail) return true; + } + return false; + } + + + bool SlicingNode::isRailSegments ( Plug* plug ) + { + Instance* instance = plug->getInstance(); + + if (instance->getMasterCell()->getNets().getSize() != 1) return false; + Net* net = instance->getMasterCell()->getNets().getFirst(); + + if (net->getComponents().getSize() != 1) return false; + Segment* segment = dynamic_cast( net->getComponents().getFirst() ); + + return segment and isRailSegments( segment ); + } + + + void SlicingNode::setNFing ( int ) + { cerr << Error( "SlicingNode::setNFing(): Base class method must never be called." ) << endl; } + + + int SlicingNode::getNFing () const + { + cerr << Error( "SlicingNode::getNFing(): Base class method must never be called." ) << endl; + return 0; + } + + + double SlicingNode::getStartParameter () const + { + cerr << Error( "SlicingNode::getStartParameter(): Base class method must never be called." ) << endl; + return 0.0; + } + + + double SlicingNode::getStepParameter () const + { + cerr << Error( "SlicingNode::getStepParameter(): Base class method must never be called." ) << endl; + return 0.0; + } + + + double SlicingNode::getCountParameter () const + { + cerr << Error( "SlicingNode::getCountParameter(): Base class method must never be called." ) << endl; + return 0.0; + } + + + Instance* SlicingNode::getInstance () const + { + cerr << Error( "SlicingNode::getInstance(): Base class method must never be called." ) << endl; + return NULL; + } + + + void SlicingNode::setHeight ( DbU::Unit ) + { cerr << Error( "SlicingNode::setHeight(): Base class method must never be called." ) << endl; } + + + void SlicingNode::setWidth ( DbU::Unit ) + { cerr << Error( "SlicingNode::setWidth(): Base class method must never be called." ) << endl; } + + + void SlicingNode::setInstance ( Instance* ) + { cerr << Error( "SlicingNode::setInstance(): Base class method must never be called." ) << endl; } + + + void SlicingNode::updateMatrixGCellPosition () + { cerr << Error( "SlicingNode::updateMatrixGCellPosition(): Base class method must never be called." ) << endl; } + + + void SlicingNode::updateMatrixGContacts () + { cerr << Error( "SlicingNode::updateMatrixGContacts(): Base class method must never be called." ) << endl; } + + + void SlicingNode::addWireOccupation ( DbU::Unit , DbU::Unit, Net* ) + { cerr << Error( "SlicingNode::addWireOccupation(): Base class method must never be called." ) << endl; } + + + int SlicingNode::getMaxWireOccupation () + { + cerr << Error( "SlicingNode::getMaxWireOccupation(): Base class method must never be called." ) << endl; + return 0; + } + + + DbU::Unit SlicingNode::getToleranceRatioH () const + { + cerr << Error( "SlicingNode::getMaxWireOccupation(): Base class method must never be called." ) << endl; + return 0; + } + + + DbU::Unit SlicingNode::getToleranceRatioW () const + { + cerr << Error( "SlicingNode::getMaxWireOccupation(): Base class method must never be called." ) << endl; + return 0; + } + + + void SlicingNode::setToleranceRatioH ( DbU::Unit ) + { cerr << Error( "SlicingNode::setToleranceRatioH(): Base class method must never be called." ) << endl; } + + + void SlicingNode::setToleranceRatioW ( DbU::Unit ) + { cerr << Error( "SlicingNode::setToleranceRatioW(): Base class method must never be called." ) << endl; } + + + DbU::Unit SlicingNode::getToleranceBandH () const + { + cerr << Error( "SlicingNode::getToleranceBandH(): Base class method must never be called." ) << endl; + return 0; + } + + + DbU::Unit SlicingNode::getToleranceBandW () const + { + cerr << Error( "SlicingNode::getToleranceBandW(): Base class method must never be called." ) << endl; + return 0; + } + + + void SlicingNode::setToleranceBandH ( DbU::Unit ) + { cerr << Error( "SlicingNode::setToleranceBandH(): Base class method must never be called." ) << endl; } + + + void SlicingNode::setToleranceBandW ( DbU::Unit ) + { cerr << Error( "SlicingNode::setToleranceBandW(): Base class method must never be called." ) << endl; } + + + void SlicingNode::recursiveSetToleranceRatioH ( DbU::Unit ) + { cerr << Error( "SlicingNode::recursiveSetToleranceRatioH(): Base class method must never be called." ) << endl; } + + + void SlicingNode::recursiveSetToleranceRatioW ( DbU::Unit ) + { cerr << Error( "SlicingNode::recursiveSetToleranceRatioW(): Base class method must never be called." ) << endl; } + + + void SlicingNode::recursiveSetToleranceBandH ( DbU::Unit ) + { cerr << Error( "SlicingNode::recursiveSetToleranceBandH(): Base class method must never be called." ) << endl; } + + + void SlicingNode::recursiveSetToleranceBandW ( DbU::Unit ) + { cerr << Error( "SlicingNode::recursiveSetToleranceBandW(): Base class method must never be called." ) << endl; } + + + void SlicingNode::_recursiveSetToleranceRatioH ( DbU::Unit ) + { cerr << Error( "SlicingNode::_recursiveSetToleranceRatioH(): Base class method must never be called." ) << endl; } + + + void SlicingNode::_recursiveSetToleranceRatioW ( DbU::Unit ) + { cerr << Error( "SlicingNode::_recursiveSetToleranceRatioW(): Base class method must never be called." ) << endl; } + + + void SlicingNode::_recursiveSetToleranceBandH ( DbU::Unit ) + { cerr << Error( "SlicingNode::_recursiveSetToleranceBandH(): Base class method must never be called." ) << endl; } + + + void SlicingNode::_recursiveSetToleranceBandW ( DbU::Unit ) + { cerr << Error( "SlicingNode::_recursiveSetToleranceBandW(): Base class method must never be called." ) << endl; } + + + void SlicingNode::_recursiveSetTolerances ( DbU::Unit , DbU::Unit , DbU::Unit , DbU::Unit ) + { cerr << Error( "SlicingNode::_recursiveSetTolerances(): Base class method must never be called." ) << endl; } + + + void SlicingNode::setTolerances ( DbU::Unit , DbU::Unit , DbU::Unit , DbU::Unit ) + { cerr << Error( "SlicingNode::setTolerances(): Base class method must never be called." ) << endl; } + + + void SlicingNode::recursiveSetTolerances ( DbU::Unit , DbU::Unit , DbU::Unit , DbU::Unit ) + { cerr << Error( "SlicingNode::recursiveSetTolerances(): Base class method must never be called." ) << endl; } + + + bool SlicingNode::hasEmptyChildrenNodeSets () const + { + cerr << Error( "SlicingNode::(): Base class method must never be called." ) << endl; + return 0; + } + + + const VSlicingNodes& SlicingNode::getChildren () const + { + static VSlicingNodes empty; + cerr << Error( "SlicingNode::getChildren(): Base class method must never be called." ) << endl; + return empty; + } + + + SlicingNode* SlicingNode::getChild ( size_t ) const + { + cerr << Error( "SlicingNode::getChild(): Base class method must never be called." ) << endl; + return NULL; + } + + + size_t SlicingNode::getChildIndex ( SlicingNode* ) const + { + cerr << Error( "SlicingNode::getChildIndex(): Base class method must never be called." ) << endl; + return 0; + } + + + size_t SlicingNode::getNbChild () const + { + cerr << Error( "SlicingNode::getNbChild(): Base class method must never be called." ) << endl; + return 0; + } + + + void SlicingNode::createChild ( unsigned int type, unsigned int alignment ) + { cerr << Error( "SlicingNode::createChild(): Base class method must never be called." ) << endl; } + + + void SlicingNode::createChild ( NodeSets*, unsigned int, Instance*, BoxSet* ) + { cerr << Error( "SlicingNode::createChild(): Base class method must never be called." ) << endl; } + + + void SlicingNode::createChild ( size_t childIndex, size_t copyIndex, unsigned int tr ) + { cerr << Error( "SlicingNode::createChild(): Base class method must never be called." ) << endl; } + + + void SlicingNode::createRouting ( DbU::Unit ) + { cerr << Error( "SlicingNode::createRouting(): Base class method must never be called." ) << endl; } + + + void SlicingNode::insertNode ( SlicingNode* , size_t index ) + { cerr << Error( "SlicingNode::insertNode(): Base class method must never be called." ) << endl; } + + + void SlicingNode::push_back ( SlicingNode* , bool reset ) + { cerr << Error( "SlicingNode::push_back(): Base class method must never be called." ) << endl; } + + + void SlicingNode::push_front ( SlicingNode* ) + { cerr << Error( "SlicingNode::push_front(): Base class method must never be called." ) << endl; } + + + void SlicingNode::removeNode ( SlicingNode* ) + { cerr << Error( "SlicingNode::removeNode(): Base class method must never be called." ) << endl; } + + + void SlicingNode::removeAllNodes () + { cerr << Error( "SlicingNode::removeAllNodes(): Base class method must never be called." ) << endl; } + + + const LSymmetries& SlicingNode::getSymmetries () const + { + static LSymmetries empty; + cerr << Error( "SlicingNode::getSymmetries(): Base class method must never be called." ) << endl; + return empty; + } + + + void SlicingNode::setSymmetries ( const LSymmetries& ) + { cerr << Error( "SlicingNode::setSymmetries(): Base class method must never be called." ) << endl; } + + + bool SlicingNode::isSymmetry ( size_t index, Symmetry& ) + { + cerr << Error( "SlicingNode::isSymmetry(): Base class method must never be called." ) << endl; + return false; + } + + + bool SlicingNode::isSymmetry ( size_t index ) + { + cerr << Error( "SlicingNode::isSymmetry(): Base class method must never be called." ) << endl; + return false; + } + + + void SlicingNode::addSymmetry ( size_t childIndex, size_t copyIndex, bool reset ) + { cerr << Error( "SlicingNode::addSymmetry(): Base class method must never be called." ) << endl; } + + + void SlicingNode::removeSymmetry ( size_t index ) + { cerr << Error( "SlicingNode::removeSymmetry(): Base class method must never be called." ) << endl; } + + + void SlicingNode::normalizeSymmetries () + { cerr << Error( "SlicingNode::normalizeSymmetries(): Base class method must never be called." ) << endl; } + + + void SlicingNode::printChildren () const + { cerr << Error( "SlicingNode::printChildren(): Base class method must never be called." ) << endl; } + + + void SlicingNode::printChildrenLine () const + { cerr << Error( "SlicingNode::printChildrenLine(): Base class method must never be called." ) << endl; } + + + SlicingNode* SlicingNode::clone ( unsigned int ) + { + cerr << Error( "SlicingNode::clone(): Base class method must never be called." ) << endl; + return NULL; + } + + + double SlicingNode::getDevicesArea () const + { + cerr << Error( "SlicingNode::getDevicesArea(): Base class method must never be called." ) << endl; + return 0.0; + } + + + double SlicingNode::getOccupationArea () const + { + cerr << Error( "SlicingNode::getOccupationArea(): Base class method must never be called." ) << endl; + return 0.0; + } + + + void SlicingNode::createSlicingRouting () + { cerr << Error( "SlicingNode::createSlicingRouting(): Base class method must never be called." ) << endl; } + + + void SlicingNode::resetSlicingRouting () + { cerr << Error( "SlicingNode::resetSlicingRouting(): Base class method must never be called." ) << endl; } + + + void SlicingNode::destroySlicingRouting () + { cerr << Error( "SlicingNode::destroySlicingRouting(): Base class method must never be called." ) << endl; } + + + size_t SlicingNode::getRoutingIndex ( SlicingNode* ) const + { + cerr << Error( "SlicingNode::getRoutingIndex(): Base class method must never be called." ) << endl; + return 0; + } + + + SlicingNode* SlicingNode::getSlicingRouting ( size_t ) const + { + cerr << Error( "SlicingNode::getSlicingRouting(): Base class method must never be called." ) << endl; + return NULL; + } + + + bool SlicingNode::checkSymmetryNet ( unsigned int , Net* , Net* ) const + { + cerr << Error( "SlicingNode::checkSymmetryNet(): Base class method must never be called." ) << endl; + return false; + } + + + void SlicingNode::addSymmetryNet ( unsigned int , Net* , Net* ) + { cerr << Error( "SlicingNode::addSymmetryNet(): Base class method must never be called." ) << endl; } + + + void SlicingNode::updateNetConstraints () + { cerr << Error( "SlicingNode::updateNetConstraints(): Base class method must never be called." ) << endl; } + + + void SlicingNode::updateSymNetAxis () + { cerr << Error( "SlicingNode::updateSymNetAxis(): Base class method must never be called." ) << endl; } + + + void SlicingNode::flattenDigitalNets () + { cerr << Error( "SlicingNode::flattenDigitalNets(): Base class method must never be called." ) << endl; } + + + void SlicingNode::updateWireOccupation ( Anabatic::Dijkstra* ) + { cerr << Error( "SlicingNode::updateWireOccupation(): Base class method must never be called." ) << endl; } + + + void SlicingNode::resetWireOccupation () + { + cerr << Error( "SlicingNode::resetWireOccupation(): Base class method must never be called.\n" + " (on %s)" + , getString(this).c_str() ) << endl; + } + + +} // Bora namespace. diff --git a/bora/src/SlicingPlotWidget.cpp b/bora/src/SlicingPlotWidget.cpp new file mode 100644 index 00000000..f12617a1 --- /dev/null +++ b/bora/src/SlicingPlotWidget.cpp @@ -0,0 +1,409 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul Chaput, Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./SlicingPlotWidget.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hurricane/Error.h" +#include "hurricane/DbU.h" +#include "hurricane/viewer/Graphics.h" +#include "hurricane/viewer/CellViewer.h" +#include "hurricane/viewer/DynamicLabel.h" +#include "hurricane/analog/AnalogCellExtension.h" +#include "hurricane/analog/Device.h" +#include "hurricane/analog/TransistorFamily.h" +#include "crlcore/Utilities.h" +#include "bora/SlicingPlotWidget.h" + + +namespace { + + + class SlicingScaleDraw : public QwtScaleDraw { + protected: + virtual QwtText label ( double value ) const; + }; + + + QwtText SlicingScaleDraw::label ( double value ) const + { return QString("%1").arg( value, 0, 'f', 1 ); } + + +} // Anonymous namespace. + + +namespace Bora { + + using namespace std; + using Hurricane::tab; + using Hurricane::Error; + using Hurricane::DbU; + using Hurricane::DynamicLabel; + using Hurricane::Graphics; + using Analog::AnalogCellExtension; + using Analog::Device; + using Analog::TransistorFamily; + + + SlicingPlotWidget::SlicingPlotWidget ( QWidget* parent ) + : QWidget (parent) + , _viewer (NULL) + , _plot (new QwtPlot ()) + , _picker (new QwtPlotPicker( QwtPlot::xBottom // X Axis id. + , QwtPlot::yLeft // Y Axis id. + , QwtPicker::CrossRubberBand + , QwtPicker::ActiveOnly + , _plot->canvas()) ) + , _gridDisplay (new QGridLayout()) + , _gridLabel () // Label line 2: text + , _widths (NULL) // Coordinates X for STreeCurve + , _heights (NULL) // Coordinates Y for STreeCurve + , _widthSelected (NULL) // Coordinate X for selectedPoint + , _heightSelected(NULL) // Coordinate Y for selectedPoint + , _pareto () + , _STreeCurve (new QwtPlotCurve("SlicingTree's dimensions")) // Blue dots : possible dimensions + , _paretoCurve (new QwtPlotCurve("Pareto")) // Black curve: pareto curve + , _selectedPoint (new QwtPlotCurve("Selected")) // Red dot : selected placement + { + _picker->setStateMachine(new QwtPickerClickPointMachine()); + setStyleSheet ( "border: 0px" ); + + int ptSize = Graphics::isHighDpi() ? 5 : 3; + + QwtText xTitle ( QString::fromUtf8("Width (µm)") ); + QwtText yTitle ( QString::fromUtf8("Height (µm)") ); + xTitle.setFont( Graphics::getFixedFont(QFont::Bold,false,false,-1) ); + yTitle.setFont( Graphics::getFixedFont(QFont::Bold,false,false,-1) ); + + _plot->setAxisTitle ( QwtPlot::xBottom, xTitle ); + _plot->setAxisTitle ( QwtPlot::yLeft , yTitle ); + _plot->insertLegend ( new QwtLegend(), QwtPlot::BottomLegend ); + _plot->setAxisFont ( QwtPlot::xBottom, Graphics::getFixedFont(QFont::Normal,false,false,-2) ); + _plot->setAxisFont ( QwtPlot::yLeft , Graphics::getFixedFont(QFont::Normal,false,false,-2) ); + + QString styleSheet("color: black; background:rgb(255,255,221); padding: 5px"); + _plot->setStyleSheet(styleSheet); + _plot->canvas()->setStyleSheet(styleSheet); + _plot->legend()->setStyleSheet( QString("padding: 0px") ); + + QPen paretoPen ( Qt::green ); + paretoPen.setWidth( Graphics::isHighDpi() ? 3 : 1 ); + _paretoCurve->setStyle( QwtPlotCurve::Lines ); + _paretoCurve->setPen ( paretoPen ); + _paretoCurve->attach ( _plot ); + + QPen dotPen ( Qt::blue ); + dotPen.setWidth( ptSize ); + _STreeCurve->setStyle( QwtPlotCurve::Dots ); + _STreeCurve->setPen ( dotPen ); + _STreeCurve->attach ( _plot ); + + QwtSymbol* symbol = new QwtSymbol(); + symbol->setStyle( QwtSymbol::Cross ); + symbol->setSize ( 20 ); + symbol->setPen ( dotPen ); + _STreeCurve->setSymbol( symbol ); + + QPen selectPen ( Qt::red ); + selectPen.setWidth( ptSize+2 ); + _selectedPoint->setStyle( QwtPlotCurve::Dots ); + _selectedPoint->setPen ( selectPen ); + _selectedPoint->attach ( _plot ); + + connect( _picker, SIGNAL(selected(const QPointF&)), this, SLOT(onPointSelect(const QPointF&)) ); + + QVBoxLayout* vLayout = new QVBoxLayout(); + vLayout->addWidget ( _plot ); + + QHBoxLayout* line = new QHBoxLayout (); + line->addStretch(); + + DynamicLabel* dlabel = new DynamicLabel(); + dlabel->setStaticText ( QString::fromUtf8("Width (µm):") ); + dlabel->setDynamicWidth( 4, DynamicLabel::NoIndent ); + dlabel->setDynamicText( QString("%1").arg( "0" ) ); + _gridLabel.push_back( dlabel ); + line->addWidget( dlabel ); + line->addStretch(); + + dlabel = new DynamicLabel(); + dlabel->setStaticText ( QString::fromUtf8("Height (µm):") ); + dlabel->setDynamicWidth( 4, DynamicLabel::NoIndent ); + dlabel->setDynamicText( QString("%1").arg( "0" ) ); + _gridLabel.push_back( dlabel ); + line->addWidget( dlabel ); + line->addStretch(); + vLayout->addLayout( line ); + + line = new QHBoxLayout (); + line->addStretch(); + + dlabel = new DynamicLabel(); + dlabel->setStaticText ( "Occupation Area (%):" ); + dlabel->setDynamicWidth( 4, DynamicLabel::NoIndent ); + dlabel->setDynamicText( QString("%1").arg( "100" ) ); + _gridLabel.push_back( dlabel ); + line->addWidget( dlabel ); + line->addStretch(); + + dlabel = new DynamicLabel(); + dlabel->setStaticText ( "Ratio(W/H):" ); + dlabel->setDynamicWidth( 4, DynamicLabel::NoIndent ); + dlabel->setDynamicText( QString("%1").arg( "0" ) ); + _gridLabel.push_back( dlabel ); + line->addWidget( dlabel ); + line->addStretch(); + + dlabel = new DynamicLabel(); + dlabel->setStaticText ( QString::fromUtf8("Area (µm²):") ); + dlabel->setDynamicWidth( 4, DynamicLabel::NoIndent ); + dlabel->setDynamicText( QString("%1").arg( "0" ) ); + _gridLabel.push_back( dlabel ); + line->addWidget( dlabel ); + line->addStretch(); + vLayout->addLayout( line ); + + QFrame* separator = new QFrame (); + separator->setFrameShape ( QFrame::HLine ); + separator->setFrameShadow ( QFrame::Sunken ); + vLayout->addWidget ( separator ); + + vLayout->addLayout ( _gridDisplay ); + + setLayout( vLayout ); + } + + + SlicingPlotWidget::~SlicingPlotWidget () + { + delete _STreeCurve; + delete _paretoCurve; + delete _selectedPoint; + delete _plot; + + if ( _widths != NULL ) delete [] _widths; + if ( _heights != NULL ) delete [] _heights; + } + + + void SlicingPlotWidget::setViewer ( CellViewer* viewer ) + { + if (_viewer) { + disconnect( _viewer, 0, this , 0 ); + disconnect( this , 0, _viewer, 0 ); + } + + _viewer = viewer; + setDatas(); + } + + + void SlicingPlotWidget::setDatas () + { + // Clear previous datas + if (_widths != NULL) delete [] _widths; + if (_heights != NULL) delete [] _heights; + + _pareto = Pareto(); + + for ( size_t igrid = 5 ; igrid < _gridLabel.size() ; ++igrid ) + delete _gridLabel[igrid]; + _gridLabel.resize( 5 ); + + while ( _gridDisplay->count() ) { + _gridDisplay->removeItem( _gridDisplay->itemAt(0) ); + } + + if (_widthSelected != NULL) delete [] _widthSelected; + if (_heightSelected != NULL) delete [] _heightSelected; + _selectedPoint->hide(); + + SlicingNode* slicingtree = AnalogCellExtension::get( _viewer->getCellWidget()->getCell() ); + if (not slicingtree) { + _STreeCurve->hide(); + _paretoCurve->hide(); + _selectedPoint->hide(); + return; + } + + // Set new datas + _widths = new double [ slicingtree->getNodeSets()->size() ]; + _heights = new double [ slicingtree->getNodeSets()->size() ]; + size_t i = 0; + NodeSets* nodeSets = slicingtree->getNodeSets(); + for (vector::iterator it = nodeSets->begin(); it != nodeSets->end(); it++){ + _widths [i] = DbU::toPhysical ( (*it)->getWidth (), DbU::Micro ); + _heights[i] = DbU::toPhysical ( (*it)->getHeight(), DbU::Micro ); + _pareto.mergePoint( _widths[i], _heights[i] ); + i++; + } + + _STreeCurve->setSamples ( _widths , _heights , nodeSets->size() ); + _paretoCurve->setSamples( _pareto.xs(), _pareto.ys(), _pareto.size() ); + _STreeCurve->show(); + _paretoCurve->show(); + _plot->replot(); + + int ii = 0; + int jj = 0; + + Cell* analogCell = _viewer->getCellWidget()->getCell(); + + vector instances = vector(); + for( Instance* instance : analogCell->getInstances() ) { + Cell* model = instance->getMasterCell(); + Device* device = dynamic_cast( model ); + if (device) instances.push_back( instance ); + } + + for( Instance* instance : instances ) { + Cell* model = instance->getMasterCell(); + Device* device = dynamic_cast( model ); + + if (device) { + TransistorFamily* tf = dynamic_cast( device ); + if (tf) { + DynamicLabel* dlabel = new DynamicLabel(); + dlabel->setDynamicWidth( 4, DynamicLabel::NoIndent ); + dlabel->setStaticText ( QString("%1:").arg( instance->getName()._getString().c_str() ) ); + dlabel->setDynamicText ( QString("%1" ).arg( 0 ) ); + _gridDisplay->addWidget( dlabel, ii, jj ); + _gridLabel.push_back( dlabel ); + jj++; + if (jj == 5){ + jj = 0; + ii++; + } + } + } + } + } + + + void SlicingPlotWidget::onPointSelect ( const QPointF& point ) + { + // Clicking on SlicingTree's Pareto Graph: + // 1) Update slicing tree + // 2) Update selected point and labels + // 3) Update selected row + + double distance = 0.0; + QwtScaleMap xMap = _plot->canvasMap( QwtPlot::xBottom ); + QwtScaleMap yMap = _plot->canvasMap( QwtPlot::yLeft ); + QPoint qpoint ( xMap.transform(point.x()), yMap.transform(point.y()) ); + int iclosest = _STreeCurve->closestPoint( qpoint, &distance ); + int dataSize = _STreeCurve->dataSize(); + + cdebug.log(539) << " Selection: [" << point.x() << " " << point.y() << "]" << endl; + + if ( (iclosest >= 0) and (iclosest < dataSize) ) { + double x = _STreeCurve->sample( iclosest ).x(); + double y = _STreeCurve->sample( iclosest ).y(); + + ostringstream message; + message << "(" << DbU::getValueString(x) << "," << DbU::getValueString(y) << ")"; + cmess2 << " o Selecting analog placement" << endl; + cmess2 << Dots::asInt ( " - Index" , iclosest ) << endl; + cmess2 << Dots::asString( " - Size (w,h)", message.str() ) << endl; + + SlicingNode* slicingtree = AnalogCellExtension::get( _viewer->getCellWidget()->getCell() ); + BoxSet* boxSet = slicingtree->getPairHW( DbU::fromPhysical(y, DbU::Micro) + , DbU::fromPhysical(x, DbU::Micro) + ); + + cdebug.log(539) << " iclosest: " << iclosest + << " (" << DbU::getValueString(DbU::fromPhysical(x, DbU::Micro)) + << "," << DbU::getValueString(DbU::fromPhysical(y, DbU::Micro)) + << ")" << endl; + + emit updatePlacement( boxSet ); + updateSelectedPoint ( x, y ); + emit updateSelectedRow( x, y ); + + } else { + cdebug.log(539) << " No closest point " << iclosest << endl; + } + } + + + void SlicingPlotWidget::updateSelectedPoint ( double x, double y ) + { + // Clicking on SlicingTree's possible dimensions table: + // 1) Update selected point + // 2) Update labels + + if (_widthSelected != NULL) delete [] _widthSelected; + if (_heightSelected != NULL) delete [] _heightSelected; + + double* _widthSelected = new double [ 1 ]; + double* _heightSelected = new double [ 1 ]; + + _widthSelected [0] = x; + _heightSelected[0] = y; + + _selectedPoint->setSamples ( _widthSelected, _heightSelected, 1 ); + _selectedPoint->show(); + _plot->replot(); + + SlicingNode* slicingtree = AnalogCellExtension::get( _viewer->getCellWidget()->getCell() ); + + _gridLabel[0]->setDynamicText( QString("%1").arg( DbU::getValueString(slicingtree->getWidth ()).c_str() ) ); + _gridLabel[1]->setDynamicText( QString("%1").arg( DbU::getValueString(slicingtree->getHeight()).c_str() ) ); + _gridLabel[2]->setDynamicText( QString("%1").arg( slicingtree->getOccupationArea() )); + if ( slicingtree->getHeight() != 0 ){ + _gridLabel[3]->setDynamicText( QString("%1").arg( DbU::getPhysical( slicingtree->getWidth (), DbU::Micro ) + / DbU::getPhysical( slicingtree->getHeight(), DbU::Micro ) + )); + } else _gridLabel[3]->setDynamicText( QString("%1").arg(0)); + + _gridLabel[4]->setDynamicText( QString("%1").arg( DbU::getPhysical( slicingtree->getWidth (), DbU::Micro ) + * DbU::getPhysical( slicingtree->getHeight(), DbU::Micro ) + )); + + Cell* analogCell = _viewer->getCellWidget()->getCell(); + size_t i = 0; + + vector instances; + for( Instance* iInstance : analogCell->getInstances() ) { + Cell* model = iInstance->getMasterCell(); + Device* device = dynamic_cast(model); + if (device) instances.push_back(iInstance); + } + for( Instance* iInstance : instances ) { + Cell* model = iInstance->getMasterCell(); + Device* device = dynamic_cast(model); + + if (device) { + TransistorFamily* tf = dynamic_cast( device ); + if (tf) _gridLabel[i+5]->setDynamicText ( QString("%1" ).arg( tf->getNfing() ) ); + } + i++; + } + } + + +} // Bora namespace. diff --git a/bora/src/SlicingWidget.cpp b/bora/src/SlicingWidget.cpp new file mode 100644 index 00000000..655af37f --- /dev/null +++ b/bora/src/SlicingWidget.cpp @@ -0,0 +1,201 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul Chaput, Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./SlicingWidget.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/Cell.h" +#include "hurricane/viewer/Graphics.h" +#include "hurricane/viewer/CellViewer.h" +#include "bora/SlicingPlotWidget.h" +#include "bora/SlicingDataWidget.h" +#include "bora/SlicingWidget.h" + + +namespace Bora { + + using std::cerr; + using std::endl; + using Hurricane::Graphics; + + +// ------------------------------------------------------------------- +// Class : "Bora::SlicingTab". + + + SlicingTab::SlicingTab ( QWidget* parent ) + : QWidget(parent) + , _viewer(NULL) + { } + + void SlicingTab::setViewer ( CellViewer* viewer ) { _viewer = viewer; } + void SlicingTab::cellPreModificate () { } + void SlicingTab::cellPostModificate () { } + + +// ------------------------------------------------------------------- +// Class : "Bora::TabPlot". + + + TabPlot::TabPlot ( QWidget* parent ) + : SlicingTab(parent) + , _plot (new SlicingPlotWidget()) + { + _plot->setObjectName( "STree.tabPlot.plot" ); + + QVBoxLayout* wLayout = new QVBoxLayout(); + wLayout->setContentsMargins( 0, 0, 0, 0 ); + wLayout->addWidget( _plot ); + setLayout( wLayout ); + } + + + void TabPlot::setViewer ( CellViewer* viewer ) + { + if (getViewer() != viewer) { + SlicingTab::setViewer( viewer ); + _plot->setViewer( viewer ); + } + } + + + void TabPlot::setDatas() + { + _plot->setDatas(); + } + + +// ------------------------------------------------------------------- +// Class : "Bora::TabDatas". + + + TabDatas::TabDatas ( QWidget* parent ) + : SlicingTab(parent) + , _datas (new SlicingDataWidget()) + { + _datas->setObjectName( "STree.tabDatas.plot" ); + + QVBoxLayout* wLayout = new QVBoxLayout(); + wLayout->setContentsMargins( 0, 0, 0, 0 ); + wLayout->addWidget( _datas ); + setLayout( wLayout ); + } + + + void TabDatas::setViewer ( CellViewer* viewer ) + { + if (getViewer() != viewer) { + SlicingTab::setViewer( viewer ); + _datas->setViewer( viewer ); + } + } + + + void TabDatas::updateContents() + { + _datas->updateContents(); + } + + +// ------------------------------------------------------------------- +// Class : "Bora::SlicingWidget". + + + SlicingWidget::SlicingWidget ( QWidget* parent ) + : QTabWidget(parent) + , _cell (NULL) + , _viewer (NULL) + , _tabPlot (new TabPlot()) + , _tabDatas (new TabDatas()) + { + setObjectName ( "Slicing" ); + setAttribute ( Qt::WA_QuitOnClose, false ); + setWindowTitle( tr("SlicingTree Viewer") ); + + _tabPlot ->setObjectName( "slicing.plot" ); + _tabDatas->setObjectName( "slicing.datas" ); + + addTab( _tabPlot , "SlicingTree's Pareto" ); + addTab( _tabDatas, "SlicingTree's possible dimensions" ); + + QAction* toggleShow = new QAction ( tr("SlicingTree Viewer"), this ); + toggleShow->setObjectName( "slicing.action.hideShow" ); + toggleShow->setShortcut ( QKeySequence(tr("CTRL+J")) ); + addAction( toggleShow ); + + connect( toggleShow , SIGNAL( triggered ()) , this , SLOT ( toggleShow ()) ); + connect( _tabPlot->getPlot (), SIGNAL( updatePlacement (BoxSet*)) , this , SIGNAL( updatePlacement (BoxSet*)) ); + connect( _tabDatas->getDatas(), SIGNAL( updatePlacement (BoxSet*)) , this , SIGNAL( updatePlacement (BoxSet*)) ); + connect( _tabDatas->getDatas(), SIGNAL( updateSelectedPoint(double,double)), _tabPlot->getPlot (), SLOT ( updateSelectedPoint(double,double)) ); + connect( _tabPlot->getPlot (), SIGNAL( updateSelectedRow (double,double)), _tabDatas->getDatas(), SLOT ( updateSelectedRow (double,double)) ); + + resize( Graphics::isHighDpi() ? QSize(1300,1300) : QSize(870,670) ); + } + + + void SlicingWidget::toggleShow () + { + setVisible(not isVisible()); + } + + + void SlicingWidget::setViewer ( CellViewer* viewer ) + { + _viewer = viewer; + if (_viewer) { + for ( int i=0 ; i(widget(i)))->setViewer( _viewer ); + + connect( _viewer->getCellWidget(), SIGNAL(cellChanged (Cell*)), this, SLOT(cellChanged (Cell*))); + connect( _viewer->getCellWidget(), SIGNAL(cellPreModificated () ), this, SLOT(cellPreModificate () )); + connect( _viewer->getCellWidget(), SIGNAL(cellPostModificated() ), this, SLOT(cellPostModificate() )); + } + } + + + void SlicingWidget::setCell ( Cell* cell ) + { + _cell = cell; + } + + + void SlicingWidget::cellChanged ( Cell* cell ) + { + cerr << "[WARNING] SlicingWidget::cellChanged() does nothing yet." << endl; + } + + + void SlicingWidget::cellPreModificate () + { + for ( int i=0 ; i(widget(i)))->cellPreModificate(); + } + + + void SlicingWidget::cellPostModificate () + { + for ( int i=0 ; i(widget(i)))->cellPostModificate(); + } + + + void SlicingWidget::updateContents() + { + _tabPlot->setDatas(); + _tabDatas->updateContents(); + } + + +} // Bora namespace. diff --git a/bora/src/VSlicingNode.cpp b/bora/src/VSlicingNode.cpp new file mode 100644 index 00000000..a88524ae --- /dev/null +++ b/bora/src/VSlicingNode.cpp @@ -0,0 +1,450 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./VSlicingNode.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "crlcore/RoutingGauge.h" +#include "bora/HVSetState.h" +#include "bora/VSlicingNode.h" +#include "bora/RVSlicingNode.h" + +namespace Bora { + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + + +// ------------------------------------------------------------------- +// Class : "Bora::VSlicingNode". + + + int VSlicingNode::_count = 0; + int VSlicingNode::_countAll = 0; + + + VSlicingNode::VSlicingNode ( unsigned int type, unsigned int alignment ) + : HVSlicingNode(type,alignment) + { ++_count; } + + + VSlicingNode::~VSlicingNode () + { --_count; } + + + VSlicingNode* VSlicingNode::create ( unsigned int alignment ) + { + ++_countAll; + return new VSlicingNode( VerticalSNode, alignment ); + } + + + void VSlicingNode::createRouting ( DbU::Unit space ) + { + push_back( RVSlicingNode::create( space ) ); + resetSlicingTree(); + } + + + void VSlicingNode::print () const + { + cerr << "- Print from Slicing Node - " << endl; + cerr << "SlicingType: Vertical Node" << endl; + if (isAlignBottom()) cerr << "Alignment : Bottom" << endl; + else if (isAlignCenter()) cerr << "Alignment : Middle" << endl; + else if (isAlignTop ()) cerr << "Alignment : Top" << endl; + else cerr << "Alignment : Unknown" << endl; + cerr << "Tolerances : RatioH: " << DbU::getPhysical(_toleranceRatioH,DbU::Micro) << ", RatioW: " << DbU::getPhysical(_toleranceRatioW,DbU::Micro) << ", BandH: " << DbU::getPhysical(_toleranceBandH,DbU::Micro) << ", BandW: " << DbU::getPhysical(_toleranceBandW,DbU::Micro) << endl; + HVSlicingNode::print(); + } + + + VSlicingNode* VSlicingNode::clone ( unsigned int tr ) + { + VSlicingNode* node = VSlicingNode::create( this->getAlignment() ); + node->setTolerances( getToleranceRatioH() + , getToleranceRatioW() + , getToleranceBandH() + , getToleranceBandW() + ); + node->setBoxSet ( getBoxSet() ); + node->setNodeSets ( _nodeSets->clone() ); + node->setPreset ( getPreset() ); + node->setSet ( getSet() ); + node->setPlaced ( getPlaced() ); + node->setSymmetries( getSymmetries() ); + + for ( SlicingNode* child : _children ) { + if (tr == MX) node->push_front( child->clone(tr) ); + else node->push_back ( child->clone(tr) ); + } + return node; + } + + + void VSlicingNode::place ( DbU::Unit x, DbU::Unit y ) + { + if (recursiveCheckSet()) { + if (not _slicingRouting.empty()) { + destroySlicingRouting(); + resetSlicingRouting(); + } + _place(x,y); + if (_slicingRouting.empty()) createSlicingRouting(); + updateCellAbutmentBox(); + } else + cerr << Error( "VSlicingNode::place(DbU::Unit x, DbU::Unit y): The SlicingTree is not completely set." ) << endl; + } + + + void VSlicingNode::replace ( DbU::Unit x, DbU::Unit y ) + { + // WARNING: This will change GCell edges. + if (recursiveCheckSet()) { + _place( x, y, true ); + updateCellAbutmentBox(); + updateGCellPosition(); + updateGContacts(); + } else { + cerr << Error( "HVlicingNode::place(DbU::Unit,DbU::Unit): The SlicingTree is not completely set." ) << endl; + } + } + + + void VSlicingNode::_place ( DbU::Unit x, DbU::Unit y, bool replace ) + { + cdebug_log(536,1) << "VSlicingNode::_place(DbU::Unit,DbU::Unit,bool)" << endl; + + vector::iterator itspace = _slicingRouting.begin(); + DbU::Unit xref = x; + DbU::Unit yref = y; + + if (isRoutingEstimated()){ + (*itspace)->_place( xref, yref, replace ); + xref += (*itspace)->getWidth(); + itspace++; + } + + for ( SlicingNode* child : _children ) { + if ( child->isHorizontal() or child->isVertical() ) { + if (child->isAlignBottom()) { + child->setX( xref ); + child->setY( yref ); + } else if (child->isAlignCenter()) { + child->setX( xref ); + child->setY( yref + (getHeight() - child->getHeight()) / 2 ); + } else if (child->isAlignTop()) { + child->setX( xref ); + child->setY( yref + getHeight() - child->getHeight() ); + } + } + + if (child->isAlignBottom()) child->_place( xref, yref , replace ); + else if (child->isAlignCenter()) child->_place( xref, yref + (getHeight() - child->getHeight())/2, replace ); + else if (child->isAlignTop ()) child->_place( xref, yref + getHeight() - child->getHeight() , replace ); + else if (child->isRouting ()) child->_place( xref, yref , replace ); + else { + cerr << Error( "VSlicingNode::place(DbU::Unit,DbU::Unit): Unknown Alignment in SlicingTree." ) << endl ; + child->print(); + } + + xref += child->getWidth(); + yref = y; + if (isRoutingEstimated()) { + (*itspace)->_place( xref, yref, replace ); + xref += (*itspace)->getWidth(); + itspace++; + } + } + + setPlaced( Placed ); + cdebug_tabw(536,-1); + } + + + void VSlicingNode::updateGlobalSize () + { + cdebug_log(535,1) << "VSlicingNode::updateGlobalsize() - " << this << endl; + + for ( SlicingNode* child : _children ) child->updateGlobalSize(); + + if (not getMaster()) { + if (getNbChild() == 1) { + _nodeSets->clear(); + NodeSets* node = _children[0]->getNodeSets(); + + for ( BoxSet* bs : node->getBoxSets() ) { + vector bss; + + bss.push_back( bs ); + _nodeSets->push_back( bss, bs->getHeight(), bs->getWidth(), VerticalSNode ); + } + } + else if ( not hasEmptyChildrenNodeSets() and _nodeSets->empty() ) { + VSetState state = VSetState( this ); + while ( not state.end() ) state.next(); + + _nodeSets = state.getNodeSets(); + } + if (_nodeSets->empty()) + cerr << Error( "VSlicingNode::updateGlobalSize(): No solution has been found. Try to set larger tolerances.\n" + " - Width tolerance ratio: %s\n" + " - Height tolerance ratio: %s\n" + " - Width band: %s\n" + " - Height band: %s" + , DbU::getValueString(getToleranceRatioW()).c_str() + , DbU::getValueString(getToleranceRatioH()).c_str() + , DbU::getValueString(getToleranceBandW ()).c_str() + , DbU::getValueString(getToleranceBandH ()).c_str() + ) << endl; + } else { + _nodeSets = _master->getNodeSets(); + } + + cdebug_log(535,0) << "Computed " << _nodeSets->size() << " choices" << endl; + cdebug_tabw(535,-1); + } + + + void VSlicingNode::preDestroy () + { + HVSlicingNode::preDestroy(); + } + + + void VSlicingNode::destroy () + { + VSlicingNode::preDestroy(); + delete this; + } + + + void VSlicingNode::preRecursiveDestroy () + { + HVSlicingNode::preRecursiveDestroy(); + } + + + void VSlicingNode::recursiveDestroy () + { + VSlicingNode::preRecursiveDestroy(); + delete this; + } + + + void VSlicingNode::createSlicingRouting () + { + if (not isPlaced()) { + cerr << Warning( "VSlicingNode::createSlicingRouting(): SlicingTree needs to be placed first." ) << endl; + return; + } + + size_t childrenCount = getNbChild(); + size_t ichild = 0; + DbU::Unit x = getX(); + DbU::Unit y = getY(); + DbU::Unit widthValue = 0; + + if (_parent) { + if ( _parent->getType() == HorizontalSNode) { + if ( (getAlignment() == AlignLeft) or (getAlignment() == AlignRight) ) { + widthValue = _parent->getWidth() - getWidth(); + } else if (getAlignment() == AlignCenter) { + widthValue = (_parent->getWidth() - getWidth())/2; + } + } + } + + DbU::Unit vpitch = _rg->getVerticalPitch(); + if (widthValue % vpitch) + cerr << Warning( "VSlicingNode::createSlicingRouting(): On %s, width is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(widthValue).c_str() + , DbU::getValueString(vpitch).c_str() + ) << endl; + + for ( size_t inode = 0; inodesetParent( this ); + + if (inode == 0) { + if (getAlignment() == AlignLeft) node->place( x, y ); + else if ( (getAlignment() == AlignCenter) + or (getAlignment() == AlignRight) ) + node->place( x-widthValue, y ); + } else + node->place( x, y ); + + _slicingRouting.push_back( node ); + + if (inode < childrenCount) x += getChild( ichild++ )->getWidth(); + } + + if (_master) { + if (isVSymmetry()) { + for ( size_t i=0; i<_slicingRouting.size(); ++i ) { + getSlicingRouting( i )->setMaster( _master->getSlicingRouting( _slicingRouting.size()-1-i ) ); + } + } else { + for ( size_t i=0; i<_slicingRouting.size(); ++i ) { + getSlicingRouting( i )->setMaster( _master->getSlicingRouting( i ) ); + } + } + } else if ( not _symmetries.empty() and isAlignCenter()) { + for ( size_t i=0; i<(_slicingRouting.size()/2); ++i ) { + getSlicingRouting( _slicingRouting.size()-1-i )->setMaster( getSlicingRouting( i ) ); + } + } + + for ( SlicingNode* child : _children ) { + if ( child->isHorizontal() or child->isVertical() ) child->createSlicingRouting(); + } + + setRoutingCreated(RoutingCreated); + } + + + DbU::Unit VSlicingNode::getWidth () const + { + DbU::Unit vpitch = _rg->getVerticalPitch(); + DbU::Unit width = 0; + + if (isRoutingEstimated()) { + for ( SlicingNode* node : _children ) width += node->getWidth(); + for ( RHVSlicingNode* node : _slicingRouting ) width += node->getWidth(); + } else { + if (_boxSet) width = _boxSet->getWidth(); + } + + if (width % vpitch) + cerr << Warning( "VSlicingNode::getWidth(): On %s, width is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(width).c_str() + , DbU::getValueString(vpitch).c_str() + ) << endl; + return width; + } + + + DbU::Unit VSlicingNode::getHeight () const + { + DbU::Unit hpitch = _rg->getHorizontalPitch(); + DbU::Unit height = 0; + + if (isRoutingEstimated()) { + SlicingNode* m = NULL; + for ( SlicingNode* node : _children ) { + if ( (node->getType() != RoutingSNode) and (node->getHeight() > height) ) { + height = node->getHeight(); + m = node; + } + } + if (m->isDevice()) height += hpitch*2; + } else { + if (_boxSet) height = _boxSet->getHeight(); + } + + if (height % hpitch) + cerr << Warning( "VSlicingNode::getHeight(): On %s, height is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(height).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; + return height; + } + + + void VSlicingNode::setGCell ( Anabatic::GCell* gcell ) + { + cdebug_log(535,1) << "VSlicingNode::setGCell(Anabatic::GCell*) " << gcell << endl; + + Anabatic::GCell* childGCell = gcell; + Anabatic::GCell* remainGCell = NULL; + DbU::Unit x = _slicingRouting[0]->getX(); + + for ( size_t ichild=0 ; ichild<_children.size() ; ++ichild ) { + // Setting up the GCell for the channel *before* the current child. + cdebug_log(535,0) << "node[" << ichild << "] width:" + << DbU::getValueString(_slicingRouting[ ichild ]->getWidth()) << endl; + + x += _slicingRouting[ ichild ]->getWidth(); + remainGCell = childGCell->vcut( x ); + _slicingRouting[ ichild ]->setGCell( childGCell ); + childGCell = remainGCell; + + // Setting up the GCell for the current child. + cdebug_log(535,0) << "children[" << ichild << "] width:" + << DbU::getValueString(_slicingRouting[ ichild ]->getWidth()) << endl; + + x += _children[ ichild ]->getWidth(); + remainGCell = childGCell->vcut( x ); + _children[ ichild ]->setGCell( childGCell ); + childGCell = remainGCell; + } + + // Setting up the GCell for the channel *after* the last child. + _slicingRouting.back()->setGCell( childGCell ); + + cdebug_tabw(535,-1); + } + + + void VSlicingNode::adjustBorderChannels () + { + if (_parent) { + DbU::Unit space = _parent->getWidth() - getWidth(); + + if (getAlignment() == AlignRight) { + RHVSlicingNode* node = _slicingRouting.front(); + node->setWidth( node->getWidth() + space ); + } else if (getAlignment() == AlignCenter) { + RHVSlicingNode* first = _slicingRouting.front(); + RHVSlicingNode* last = _slicingRouting.back (); + first->setWidth( first->getWidth() + space/2 ); + last ->setWidth( last ->getWidth() + space/2 ); + } else if (getAlignment() == AlignLeft) { + RHVSlicingNode* node = _slicingRouting.back(); + node->setWidth( node->getWidth() + space ); + } + } + + for ( SlicingNode* child : _children ) child->adjustBorderChannels(); + } + + + string VSlicingNode::_getString () const + { + string s = Super::_getString(); + return s; + } + + + string VSlicingNode::_getTypeName () const + { return "VSlicingNode"; } + + +} // Bora namespace. diff --git a/bora/src/attic/SlicingNode-full.cpp b/bora/src/attic/SlicingNode-full.cpp new file mode 100644 index 00000000..221ea021 --- /dev/null +++ b/bora/src/attic/SlicingNode-full.cpp @@ -0,0 +1,6230 @@ +// -*- C++ -*- +// +// This file is part of the Chams Software. +// Copyright (c) UPMC 2012-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C H A M S | +// | H o r u s - S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricaneAMS/layout/SlicingNode.cpp" | +// +-----------------------------------------------------------------+ + +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricaneAMS/analogic/AnalogCellExtension.h" +#include "hurricaneAMS/layout/SlicingNode.h" +#include "anabatic/AnabaticEngine.h" +#include "hurricane/DeepNet.h" +#include "hurricane/Property.h" +#include "crlcore/AllianceFramework.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/RoutingLayerGauge.h" + +using namespace std; +using Hurricane::Warning; +using Hurricane::Breakpoint; +using Hurricane::Error; +using Hurricane::NetRoutingState; +using Hurricane::NetRoutingExtension; +using Hurricane::NetExternalComponents; +using Hurricane::Net; +using Hurricane::Cell; +using Hurricane::DeepNet; + + +// -----------------------------------------------------------------------------------------------// +// Class : BoxSet +// -----------------------------------------------------------------------------------------------// + + +BoxSet::BoxSet( DbU::Unit height, DbU::Unit width ): _height( height ) + , _width ( width ) + , _cpt ( 1 ){} + + +BoxSet::BoxSet( BoxSet* boxSet ) +{ + if ( boxSet != NULL ){ + _height = boxSet->getHeight(); + _width = boxSet->getWidth(); + _cpt = boxSet->getCpt(); + } else { + _height = 0; + _width = 0; + _cpt = 1; + } +} + + +BoxSet::~BoxSet(){} + + +void BoxSet::print() const +{ + cerr << "area: " << setprecision(4) << this->getOccupationArea() ; + cerr << "%, \t cpt: " << this->getCpt(); + if ((this->getWidth() == 0) && (this->getHeight() == 0)) cerr << ", \t ratio (W/H):inf"; + else cerr << ", \t ratio (W/H):" << setprecision(2) << this->getWidth()/this->getHeight(); + cerr << ", \t ratio (W*H):" << setprecision(4) << DbU::getPhysical(this->getWidth(),DbU::Micro) * DbU::getPhysical(this->getHeight(),DbU::Micro) << "um²"; + if (this->getType() == DeviceSNode){ cerr << ", \t Nfing: " << this->getNFing(); } + cerr << ", \t H: " << setprecision(4) << DbU::getPhysical(this->getHeight(),DbU::Micro) << "um" ; + cerr << ", W: " << DbU::getPhysical(this->getWidth(),DbU::Micro)<< "um"; + cerr << endl; +} + + +const vector& BoxSet::getSet() const +{ + cerr << "Error(vector< BoxSet*> getSet () const): DBoxSet and RHVBoxSet do not have vector of BoxSets." << endl; + static const vector boxSet = vector (); + return boxSet; +} + + +int BoxSet::getNFing() const +{ + cerr << "Error(int BoxSet::getNFing() const): Only DBoxSet has fingers." << endl; + return 0; +} + + +void BoxSet::destroy() +{ + delete(this); +} + + +// -----------------------------------------------------------------------------------------------// +// Class : HVBoxSet +// -----------------------------------------------------------------------------------------------// + + +HVBoxSet::HVBoxSet( vector dimensionSet, DbU::Unit height, DbU::Unit width ): BoxSet ( height, width ) + ,_dimensionSet ( dimensionSet ){} + + +HVBoxSet::HVBoxSet( HVBoxSet* boxSet ): BoxSet ( boxSet ) + , _dimensionSet ( boxSet->getSet() ){} + + +HVBoxSet::~HVBoxSet(){} + + +double HVBoxSet::getDevicesArea() const +{ + double area = 0; + for (vector::const_iterator it = _dimensionSet.begin(); it != _dimensionSet.end(); it++){ + area += (*it)->getDevicesArea(); + } + return area; +} + + +// -----------------------------------------------------------------------------------------------// +// Class : HBoxSet +// -----------------------------------------------------------------------------------------------// + + +int HBoxSet::_count = 0; +int HBoxSet::_countAll = 0; + + +HBoxSet::HBoxSet( vector< BoxSet*> dimensionSet, DbU::Unit height, DbU::Unit width ): HVBoxSet( dimensionSet, height, width ) +{ + if ( (_height == 0) && (_width == 0) ){ + calculateHeight(); + calculateWidth(); + } +} + + +HBoxSet::HBoxSet( HBoxSet* boxSet ): HVBoxSet( boxSet ){} + + +HBoxSet::~HBoxSet(){} + + +HBoxSet* HBoxSet::create( vector< BoxSet*> dimensionSet, DbU::Unit height, DbU::Unit width ) +{ + _count++; + _countAll++; + return new HBoxSet( dimensionSet, height, width ); +} + + +HBoxSet* HBoxSet::clone() +{ + return HBoxSet::create( getSet(), getHeight(), getWidth() ); +} + + +void HBoxSet::calculateHeight() +{ + DbU::Unit currentH = 0; + for (vector::const_iterator it = _dimensionSet.begin(); it != _dimensionSet.end(); it++){ + currentH += (*it)->getHeight(); + } + _height = currentH; +} + + +void HBoxSet::calculateWidth() +{ + DbU::Unit currentW = 0; + for (vector::const_iterator it = _dimensionSet.begin(); it != _dimensionSet.end(); it++){ + if (currentW < (*it)->getWidth()){ currentW = (*it)->getWidth(); } + } + _width = currentW; +} + + +void HBoxSet::destroy() +{ + _count--; + BoxSet::destroy(); +} + + +// -----------------------------------------------------------------------------------------------// +// Class : VBoxSet +// -----------------------------------------------------------------------------------------------// + + +int VBoxSet::_count = 0; +int VBoxSet::_countAll = 0; + + +VBoxSet::VBoxSet( vector dimensionSet, DbU::Unit height, DbU::Unit width ): HVBoxSet( dimensionSet, height, width ) +{ + if ( (_height == 0) && (_width == 0) ){ + calculateHeight(); + calculateWidth (); + } +} + + +VBoxSet::VBoxSet( VBoxSet* boxSet ): HVBoxSet( boxSet ){} + + +VBoxSet::~VBoxSet(){} + + +VBoxSet* VBoxSet::create( vector dimensionSet, DbU::Unit height, DbU::Unit width ) +{ + _count++; + _countAll++; + return new VBoxSet( dimensionSet, height, width ); +} + + +VBoxSet* VBoxSet::clone() +{ + return VBoxSet::create( getSet(), getHeight(), getWidth() ); +} + + +void VBoxSet::calculateHeight() +{ + DbU::Unit currentH = 0; + for (vector::const_iterator it = _dimensionSet.begin(); it != _dimensionSet.end(); it++){ + if (currentH < (*it)->getHeight()){ currentH = (*it)->getHeight(); } + } + _height = currentH; +} + + +void VBoxSet::calculateWidth() +{ + DbU::Unit currentW = 0; + for (vector::const_iterator it = _dimensionSet.begin(); it != _dimensionSet.end(); it++){ + currentW += (*it)->getWidth(); + } + _width = currentW; +} + + +void VBoxSet::destroy() +{ + _count--; + BoxSet::destroy(); +} + + +// -----------------------------------------------------------------------------------------------// +// Class : DBoxSet +// -----------------------------------------------------------------------------------------------// + + +int DBoxSet::_count = 0; +int DBoxSet::_countAll = 0; + + +DBoxSet::DBoxSet( DbU::Unit height, DbU::Unit width, int nfing ): BoxSet( height, width ), _nfing(nfing){} + + +DBoxSet::DBoxSet( DBoxSet* boxSet ): BoxSet( boxSet ), _nfing(boxSet->getNFing()){} + + +DBoxSet::~DBoxSet(){} + + +DBoxSet* DBoxSet::create( DbU::Unit height, DbU::Unit width, int nfing ) +{ + _count++; + _countAll++; + return new DBoxSet( height, width, nfing ); +} + + +DBoxSet* DBoxSet::clone() +{ + return DBoxSet::create( getHeight(), getWidth(), getNFing() ); +} + + +void DBoxSet::destroy() +{ + _count--; + BoxSet::destroy(); +} + + +// -----------------------------------------------------------------------------------------------// +// Class : RHVBoxSet +// -----------------------------------------------------------------------------------------------// + + +int RHVBoxSet::_count = 0; +int RHVBoxSet::_countAll = 0; + + +RHVBoxSet::RHVBoxSet( DbU::Unit height, DbU::Unit width ): BoxSet( height, width ) +{ + _width = width; + _height = height; +} + + +RHVBoxSet::RHVBoxSet( RHVBoxSet* boxSet ): BoxSet( boxSet ){} + + +RHVBoxSet::~RHVBoxSet(){} + + +void RHVBoxSet::destroy() +{ + _count--; + delete(this); +} + + +void RHVBoxSet::print() const +{ + cerr << "area: " << setprecision(4) << this->getOccupationArea() ; + cerr << "%, \t cpt: " << this->getCpt(); +// if ( (_width == 0)&&(_height == 0) ) cerr << ", \t ratio (W/H):inf"; +// else cerr << ", \t ratio (W/H):" << _width/_height; +// cerr << ", \t ratio (W*H):" << setprecision(4) << DbU::getPhysical(_width,DbU::Micro) * DbU::getPhysical(_height,DbU::Micro) << "um²"; + +// if (this->getType() == DeviceSNode){ cerr << ", \t Nfing: " << this->getNFing(); } + cerr << ", \t H: " << setprecision(4) << DbU::getPhysical(_height,DbU::Micro) << "um" ; + cerr << ", W: " << DbU::getPhysical(_width,DbU::Micro)<< "um"; + cerr << endl; +} + + +// -----------------------------------------------------------------------------------------------// +// Class : RHBoxSet +// -----------------------------------------------------------------------------------------------// + + +RHBoxSet::RHBoxSet( DbU::Unit height ): RHVBoxSet( height, 0 ){} + + +RHBoxSet::RHBoxSet( RHBoxSet* boxSet ): RHVBoxSet( boxSet ){} + + +RHBoxSet::~RHBoxSet(){} + + +RHBoxSet* RHBoxSet::create( DbU::Unit height ) +{ + _count++; + _countAll++; + return new RHBoxSet ( height ); +} + + +RHBoxSet* RHBoxSet::clone() +{ + return RHBoxSet::create( getHeight() ); +} + + +// -----------------------------------------------------------------------------------------------// +// Class : RVBoxSet +// -----------------------------------------------------------------------------------------------// + + +RVBoxSet::RVBoxSet( DbU::Unit width ): RHVBoxSet( 0, width ){} + + +RVBoxSet::RVBoxSet( RVBoxSet* boxSet ): RHVBoxSet( boxSet ){} + + +RVBoxSet::~RVBoxSet(){} + + +RVBoxSet* RVBoxSet::create( DbU::Unit width ) +{ + _count++; + _countAll++; + return new RVBoxSet( width ); +} + + +RVBoxSet* RVBoxSet::clone() +{ + return RVBoxSet::create( getWidth() ); +} + + +// -----------------------------------------------------------------------------------------------// +// Class : NodeSets +// -----------------------------------------------------------------------------------------------// + + +NodeSets::NodeSets( double start, double step, double count ) +{ + _nodeSets = std::vector(); + _nodeSets.clear(); + _start = start; + _step = step; + _count = count; +} + + +NodeSets::NodeSets( const NodeSets* other ) +{ + _nodeSets = other->getNodeSets(); + _start = other->getStartParameter(); + _step = other->getStepParameter(); + _count = other->getCountParameter(); +} + + +NodeSets::~NodeSets(){} + + +NodeSets* NodeSets::create( Cell* cell, double start, double step, double count, CRL::RoutingGauge* rg ) +{ + NodeSets* nodeset = new NodeSets(start, step, count); + + Device* dev = dynamic_cast( cell ); + if (dev) { + //cdebug_log(536,0) << "createNodeSets for an Analog Device" << endl; + TransistorFamily* tf = dynamic_cast(dev); + + for (int i = 0; i < count; i++){ + tf->setNfing( start + i*step ); + + FormFactorParameter* pff = NULL; + if ( (pff = dynamic_cast(tf->getParameter("M"))) != NULL ) + pff->setValue( tf->getNfing() ); + + auto_ptr layoutGenerator ( new LayoutGenerator() ); + layoutGenerator->setDevice(dev); + layoutGenerator->drawLayout(); + + if (rg){ + float h2pitch = rg->getHorizontalPitch()*2; + float v2pitch = rg->getVerticalPitch ()*2; + + float h = dev->getAbutmentBox().getHeight(); + float w = dev->getAbutmentBox().getWidth(); + + if (fmod(h,h2pitch) > 1e-06) { + cerr << Warning( "NodeSets::create(): The height of device \"%s\" (%s) is not pitched on 2*%s (adjusted)." + , getString(dev->getName()).c_str() + , DbU::getValueString(dev->getAbutmentBox().getWidth()).c_str() + , DbU::getValueString(rg->getHorizontalPitch()*2).c_str() + ) << endl; + } + if (fmod(w,v2pitch) > 1e-06) { + cerr << Warning( "NodeSets::create(): The width of device \"%s\" (%s) is not pitched on 2*%s (adjusted)." + , getString(dev->getName()).c_str() + , DbU::getValueString(dev->getAbutmentBox().getWidth()).c_str() + , DbU::getValueString(rg->getVerticalPitch()*2).c_str() + ) << endl; + } + + nodeset->push_back(DBoxSet::create( ceil(h/h2pitch)*h2pitch + , ceil(w/v2pitch)*v2pitch + , start + i*step + ) + ); + } else { + nodeset->push_back(DBoxSet::create( dev->getAbutmentBox().getHeight() + , dev->getAbutmentBox().getWidth() + , start + i*step + ) + ); + } + } + } else { + //cdebug_log(536,0) << "createNodeSets for a Digital Device: " << cell << endl; + if (rg) { + DbU::Unit h2pitch = rg->getHorizontalPitch()*2; + DbU::Unit v2pitch = rg->getVerticalPitch ()*2; + DbU::Unit h = cell->getAbutmentBox().getHeight(); + DbU::Unit w = cell->getAbutmentBox().getWidth(); + + if (h % h2pitch) { + cerr << Warning( "NodeSets::create(): The height of device \"%s\" (%s) is not pitched on %s*2 (adjusted)." + , getString(cell->getName()).c_str() + , DbU::getValueString(cell->getAbutmentBox().getHeight()).c_str() + , DbU::getValueString(rg->getHorizontalPitch()).c_str() + ) << endl; + } + if (w % v2pitch) { + cerr << Warning( "NodeSets::create(): The width of device \"%s\" (%s) is not pitched on %s*2 (adjusted)." + , getString(cell->getName()).c_str() + , DbU::getValueString(cell->getAbutmentBox().getWidth()).c_str() + , DbU::getValueString(rg->getVerticalPitch()).c_str() + ) << endl; + } + + nodeset->push_back(DBoxSet::create( ceil(h/h2pitch)*h2pitch + , ceil(w/v2pitch)*v2pitch + ) + ); + } else { + nodeset->push_back(DBoxSet::create( cell->getAbutmentBox().getHeight() + , cell->getAbutmentBox().getWidth() + ) + ); + } + } + return nodeset; +} + +NodeSets* NodeSets::create() +{ + return new NodeSets(); +} + + +BoxSet* NodeSets::operator[] ( size_t i ) +{ + if (i < _nodeSets.size()) return _nodeSets[i]; + return NULL; +} + + +BoxSet* NodeSets::at ( size_t i ) +{ + if (i < _nodeSets.size()) return _nodeSets[i]; + return NULL; +} + + +void NodeSets::clear() +{ + if ( _nodeSets.empty() != true ){ + for (vector::iterator it = _nodeSets.begin(); it != _nodeSets.end(); it++){ + (*it)->destroy(); + } + _nodeSets.clear(); + } +} + + +BoxSet* NodeSets::getPairH( DbU::Unit height ) const +{ + DbU::Unit w = 0; + DbU::Unit hclosest = 0; + BoxSet* boxSet = (*_nodeSets.begin()); + + for (vector::const_iterator itHW = _nodeSets.begin(); itHW != _nodeSets.end(); itHW++){ + + if ( ((*itHW)->getHeight() > hclosest) && (height >= (*itHW)->getHeight()) ){ + hclosest = (*itHW)->getHeight(); + w = (*itHW)->getWidth(); + boxSet = (*itHW); + } + } + + if ( (w == 0) && (hclosest == 0) ) + { cerr << "Error(pair NodeSets::getPairH( DbU::Unit height ) const): No solution for h = " << height << " has been found." << endl; } + + return boxSet; +} + + +BoxSet* NodeSets::getPairHW( DbU::Unit height, DbU::Unit width ) const +{ + vector::const_iterator it = _nodeSets.begin(); + DbU::Unit bestH = (*it)->getHeight(); + DbU::Unit bestW = (*it)->getWidth(); + DbU::Unit currentH = 0; + DbU::Unit currentW = 0; + BoxSet* boxSet = (*it); + + while (it != _nodeSets.end()){ + currentH = (*it)->getHeight(); + currentW = (*it)->getWidth(); + + if (currentH <= height){ + if ( currentH > bestH ){ + bestH = currentH; + bestW = currentW; + boxSet = (*it); + } else if (currentH == bestH){ + if ( (currentW > bestW) && (currentW <= width) ){ + bestH = currentH; + bestW = currentW; + boxSet = (*it); + } + else if ( (currentW < bestW) && (bestW > width) ){ + bestH = currentH; + bestW = currentW; + boxSet = (*it); + } + } + it++; + } else { + it = _nodeSets.end(); + } + } + + return boxSet; +} + + +BoxSet* NodeSets::getPairHW( unsigned int index ) const +{ + BoxSet* bs = NULL; + if ( index < _nodeSets.size() ){ + bs = _nodeSets[index]; + } + return bs; +} + + +int NodeSets::findIndex( DbU::Unit height, DbU::Unit width ) const +{ + bool end = false; + int indextbd = 0; + int index = 0; + vector::const_iterator it = _nodeSets.begin(); + + while(end == false){ + if ( ((*it)->getHeight() == height) && ((*it)->getWidth() == width) ){ + indextbd = index; + end = true; + } + index++; + it++; + if (it == _nodeSets.end()){ end = true; } + } + + return indextbd; +} + + +vector::iterator NodeSets::find( DbU::Unit height, DbU::Unit width ) +{ + vector::iterator it = _nodeSets.begin(); + vector::iterator itFind = _nodeSets.end(); + + if (_nodeSets.empty() != true){ + + while(it != _nodeSets.end()){ + if ( ((*it)->getHeight() == height) && ((*it)->getWidth() == width) ){ + itFind = it; + it = _nodeSets.end(); + } + else { it++; } + if ( it == _nodeSets.end() ){ it = _nodeSets.end(); } + } + } else { it = _nodeSets.end(); } + + return itFind; +} + + +vector::iterator NodeSets::find( BoxSet* boxSet ) +{ + vector::iterator it = _nodeSets.begin(); + vector::iterator itFind = _nodeSets.end(); + + if ( (_nodeSets.empty() != true) && (boxSet != NULL) ){ + + while(it != _nodeSets.end()){ + if ( ((*it)->getHeight() == boxSet->getHeight()) && ((*it)->getWidth() == boxSet->getWidth()) ){ + itFind = it; + it = _nodeSets.end(); + } + else { it++; } + } + } else { it = _nodeSets.end(); } + + return itFind; +} + + +vector::iterator NodeSets::find( int nfing ) +{ + vector::iterator it = _nodeSets.begin(); + vector::iterator itFind = _nodeSets.end(); + + if ( (_nodeSets.empty() != true) ){ + + while(it != _nodeSets.end()){ + if ( (*it)->getNFing() == nfing ){ + itFind = it; + it = _nodeSets.end(); + } + else { it++; } + } + } else { it = _nodeSets.end(); } + + return itFind; +} + + +void NodeSets::print() const +{ + cerr << "Print - NodeSets:" << endl; + int index = 0; + if ( this->size() == 0){ cerr << "--- EMPTY ---" << endl; } + else { + for (vector::const_iterator itPrint = _nodeSets.begin(); itPrint != _nodeSets.end(); itPrint++) + { + cerr << index << ": \t"; + (*itPrint)->print(); + index++; + } + cerr << endl; + } +} + + +bool NodeSets::compare ( NodeSets nodeSets2, unsigned int flags ) const +{ + if (_nodeSets.size() != nodeSets2.size()) { + if (flags & ShowDiff) + cerr << "NodeSets::compare() size differs: " << _nodeSets.size() + << " vs. " << nodeSets2.size() << endl; + return false; + } + + bool isSame = true; + for ( size_t iset = 0 ; iset<_nodeSets.size() ; ++iset ) { + if ( (_nodeSets[iset]->getHeight() != nodeSets2[iset]->getHeight()) + or (_nodeSets[iset]->getWidth () != nodeSets2[iset]->getWidth ()) ) { + isSame = false; + if (flags & ShowDiff) + cerr << "NodeSets::compare() Box [" << iset << "] differs " + << " (" << DbU::getValueString(_nodeSets[iset]->getWidth()) << "," << DbU::getValueString(_nodeSets[iset]->getHeight()) << ") vs." + << " (" << DbU::getValueString(nodeSets2[iset]->getWidth()) << "," << DbU::getValueString(nodeSets2[iset]->getHeight()) << ")" + << endl; + } + } + + return isSame; +} + + +void NodeSets::push_back( BoxSet* boxSet ) +{ + if( this->find(boxSet) == _nodeSets.end() ){ _nodeSets.push_back(boxSet); } + else { + (*find(boxSet))->incrementCpt(); + boxSet->destroy(); + } +} + + +void NodeSets::push_back( vector vect, DbU::Unit height, DbU::Unit width, unsigned int type ) +{ + if( this->find(height, width) == _nodeSets.end() ){ + if (type == HorizontalSNode){ + _nodeSets.push_back(HBoxSet::create(vect, height, width)); + } + else if (type == VerticalSNode){ + _nodeSets.push_back(VBoxSet::create(vect, height, width)); + } + } + else { + (*find(height, width))->incrementCpt(); + } +} + + +NodeSets* NodeSets::clone() +{ + NodeSets* nodesets = new NodeSets( _start, _step, _count ); + for (vector::iterator it = _nodeSets.begin(); it != _nodeSets.end(); it++) + { + nodesets->push_back((*it)->clone()); + } + return nodesets; +} + + +// -----------------------------------------------------------------------------------------------// +// Class : SlicingNode +// -----------------------------------------------------------------------------------------------// + +CRL::RoutingGauge* SlicingNode::_rg = NULL; +Cell* SlicingNode::_cell = NULL; +Katana::KatanaEngine* SlicingNode::_katana = NULL; +vector SlicingNode::_railSegments = vector(); + +SlicingNode::SlicingNode( unsigned int type + , NodeSets* nodeSets + , unsigned int alignment + , BoxSet* boxSet + ):_nodeSets(nodeSets) + ,_x(0), _y(0) +{ + _flags = 0; + _parent = NULL; + _master = NULL; + _gcell = NULL; + _nodeSets = nodeSets; + _x = 0; + _y = 0; + this->setType(type); + this->setAlignment(alignment); + + if ( boxSet != NULL ){ + this->setBoxSet(boxSet); + this->setPreset(Preset); + this->setSet(Set); + } +} + + +SlicingNode::~SlicingNode(){} + + +bool SlicingNode::isSameSize( BoxSet* boxSet ) const +{ + bool same = false; + if ( (_boxSet != NULL)&&(boxSet != NULL) ){ + if ((_boxSet->getHeight() == boxSet->getHeight()) && (_boxSet->getWidth() == boxSet->getWidth())){ + same = true; + } + } + return same; +} + + +bool SlicingNode::isSameSize( DbU::Unit height, DbU::Unit width ) const +{ + bool same = false; + if ( _boxSet != NULL ){ + if ( (_boxSet->getHeight() == height) && (_boxSet->getWidth() == width) ){ + same = true; + } + } + return same; +} + + +bool SlicingNode::isEmpty() const +{ + return _nodeSets->empty(); +} + + +DbU::Unit SlicingNode::getHeight () const +{ + if (_boxSet != NULL){ + return _boxSet->getHeight(); + } else { return 0; } +} + + +DbU::Unit SlicingNode::getWidth () const +{ + if (_boxSet != NULL){ + return _boxSet->getWidth(); + } else { return 0; } +} + + + +DbU::Unit SlicingNode::getRootHeight () const +{ + if (_parent){ + SlicingNode* p = _parent; + while(p->getParent()){ + p = p->getParent(); + } + return p->getHeight(); + } else { + return getHeight(); + } +} + + +DbU::Unit SlicingNode::getRootWidth () const +{ + if (_parent){ + SlicingNode* p = _parent; + while(p->getParent()){ + p = p->getParent(); + } + return p->getWidth(); + } else { + return getWidth(); + } +} + + +DbU::Unit SlicingNode::getRootX () const +{ + if (_parent){ + SlicingNode* p = _parent; + while(p->getParent()){ + p = p->getParent(); + } + return p->getX(); + } else { + return getX(); + } +} + + +DbU::Unit SlicingNode::getRootY () const +{ + if (_parent){ + SlicingNode* p = _parent; + while(p->getParent()){ + p = p->getParent(); + } + return p->getY(); + } else { + return getY(); + } +} + + +SlicingNode* SlicingNode::getRoot() +{ + SlicingNode* parent = this; + if (_parent != NULL){ parent = _parent->getRoot(); } + return parent; +} + + +int SlicingNode::getCpt() +{ + if (_boxSet != NULL){ return _boxSet->getCpt(); } + else { return 0; } +} + + +double SlicingNode::getRatio() +{ + if (_boxSet != NULL){ return _boxSet->getRatio(); } + else { return 0; } +} + + +double SlicingNode::getArea() +{ + if (_boxSet != NULL){ return _boxSet->getArea(); } + else { return 0; } +} + + +DbU::Unit SlicingNode::getVPitch () +{ + if (_rg) return _rg->getVerticalPitch(); + + cerr << Error( "DbU::Unit getVPitch(): RoutingGauge has not been defined." ) << endl; + return 0; +} + +DbU::Unit SlicingNode::getHPitch () +{ + if (_rg) return _rg->getHorizontalPitch(); + + cerr << Error( "DbU::Unit getHPitch(): RoutingGauge has not been defined." ) << endl; + return 0; +} + +void SlicingNode::setBoxSet( BoxSet* boxSet ) +{ + if ( (!this->isPreset()) ){ + if (_nodeSets->find(boxSet) != _nodeSets->end()){ + this->setSet(Set); + _boxSet = boxSet; + } else { + cerr << "Error(void SlicingNode::setBoxSet( BoxSet* boxSet )): Boxset not found."; + } + } +} + + +void SlicingNode::setBoxSet( DbU::Unit height, DbU::Unit width ) +{ + if (!this->isPreset()){ + if (_nodeSets->find(height, width) != _nodeSets->end()){ + this->setSet(Set); + _boxSet = (*_nodeSets->find(height, width)); + } else { + cerr << "Error(void SlicingNode::setBoxSet( BoxSet* boxSet )): Boxset not found."; + } + } +} + + + +void SlicingNode::setBoxSet( size_t index ) +{ + if (index > (_nodeSets->size()-1)){ cerr << "Error(void SlicingNode::setBoxSet( int index )): Out of bound index." << endl; } + else { + this->_setBoxSet((*(_nodeSets->begin() + index))); + } +} + + +void SlicingNode::_setBoxSet( BoxSet* boxSet ) +{ + if (isPreset()) return; + + setSet( Set ); + _boxSet = boxSet; +} + + +void SlicingNode::setX ( DbU::Unit x ) +{ + float pitch = _rg->getVerticalPitch(); + + if (fmod(x,pitch) > 1e-06) { + cerr << Warning( "SlicingNode::setX(): On %s, X position %s is not pitched on %s (will be adjusted)." + , getString(this).c_str() + , DbU::getValueString(x ).c_str() + , DbU::getValueString(pitch).c_str() + ) << endl; + } + + _x = x; +} + + +void SlicingNode::setY ( DbU::Unit y ) +{ + float pitch = _rg->getHorizontalPitch(); + + if (fmod(y,pitch) > 1e-06) { + cerr << Warning( "SlicingNode::setY(): On %s, Y position %s is not pitched on %s (will be adjusted)." + , getString(this).c_str() + , DbU::getValueString(y ).c_str() + , DbU::getValueString(pitch).c_str() + ) << endl; + } + + _y = y; +} + + +void SlicingNode::clearParentsNodeSets() +{ + if ( _parent != NULL ){ _parent->clearParentsNodeSets(); } + if (getMaster() == NULL) _nodeSets->clear(); +} + + +void SlicingNode::resetSlicingTree() +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Reset a slicing tree means: +// - Empty NodeSets of every parent +// - Unset every nodes that are not preset +// - Unplace every nodes +// -----------------------------------------------------------------------------------------------// + + clearParentsNodeSets(); + getRoot()->_resetSlicingTree(); +} + + +void SlicingNode::_resetSlicingTree() +{ + _x = 0; + _y = 0; + setPlaced(false); + + if (!this->isPreset()){ + _boxSet = NULL; + setSet(false); + } +} + + +void SlicingNode::print() const +{ + printParent(); + if ( this->isPreset() ){ cerr << "Preset : True" << endl; } + else { cerr << "Preset : False " << endl; } + if ( this->isSet() ) { cerr << "Set : True" << endl; } + else { cerr << "Set : False " << endl; } + if ( this->isPlaced() ){ cerr << "Placed : True" << endl; } + else { cerr << "Placed : False " << endl; } + if ( this->getMaster()){ + cerr << "Master : "; + this->getMaster()->printLine(); + } + unsigned int type = getType(); + if ( type == HorizontalSNode ){ cerr << "Type : HorizontalSNode"<< endl; } + else if ( type == VerticalSNode ){ cerr << "Type : VerticalSNode" << endl; } + else if ( type == DeviceSNode ){ cerr << "Type : DeviceSNode" << endl; } + else if ( type == RoutingSNode ){ cerr << "Type : RoutingSNode" << endl; } + else { cerr << "Type : UnknownType" << endl; } + cerr << "Height : " << DbU::getPhysical(getHeight(),DbU::Micro) << endl; + cerr << "Width : " << DbU::getPhysical(getWidth(),DbU::Micro) << endl; + cerr << "X : " << DbU::getPhysical(_x,DbU::Micro) << endl; + cerr << "Y : " << DbU::getPhysical(_y,DbU::Micro) << endl; + if (isRoutingEstimated()) cerr << "REstimated : True" << endl; + else cerr << "REstimated : False" << endl; + +//_nodeSets->print(); + cerr << "GCell : " << _gcell << endl; + if (!((getType() == HorizontalSNode)||(getType() == VerticalSNode))){ + cerr << "GCell : " << _gcell << endl; + if(_gcell){ + cerr << "Edges : " << endl; + vector ne = _gcell->getNorthEdges(); + vector se = _gcell->getSouthEdges(); + vector ee = _gcell->getEastEdges(); + vector we = _gcell->getWestEdges(); + + cerr << "--- North : " << endl; + for (vector::const_iterator itn = ne.begin(); itn != ne.end(); itn++){ + cerr << (*itn)->getOpposite(_gcell) << endl; + } + cerr << "--- South : " << endl; + for (vector::const_iterator its = se.begin(); its != se.end(); its++){ + cerr << (*its)->getOpposite(_gcell) << endl; + } + cerr << "--- East : " << endl; + for (vector::const_iterator ite = ee.begin(); ite != ee.end(); ite++){ + cerr << (*ite)->getOpposite(_gcell) << endl; + } + cerr << "--- West : " << endl; + for (vector::const_iterator itw = we.begin(); itw != we.end(); itw++){ + cerr << (*itw)->getOpposite(_gcell) << endl; + } + } + } + cerr << endl; + +} + + +void SlicingNode::printLine() const +{ + unsigned int type = getType(); + if (_master) { + cerr << " [MASTER]: "; + _master->printLine(); + } + if ( type == HorizontalSNode ){ cerr << "Type : HorizontalSNode"; } + else if ( type == VerticalSNode ){ cerr << "Type : VerticalSNode" ; } + else if ( type == DeviceSNode ){ cerr << "Type : DeviceSNode" ; } + else if ( type == RoutingSNode ){ cerr << "Type : RoutingSNode" ; } + else { cerr << "Type : UnknownType" ; } + cerr << ", X: " << DbU::getPhysical(getX(),DbU::Micro); + cerr << ", Y: " << DbU::getPhysical(getY(),DbU::Micro); + cerr << ", W: " << setprecision(4) << DbU::getPhysical(getWidth() ,DbU::Micro); + cerr << ", H: " << setprecision(4) << DbU::getPhysical(getHeight(),DbU::Micro) << endl; +} + + +void SlicingNode::printParent() const +{ + if (_parent != NULL){ + unsigned int type = _parent->getType(); + if ( type == HorizontalSNode ){ cerr << "Parent : Type: HorizontalSNode" ; } + else if ( type == VerticalSNode ){ cerr << "Parent : Type: VerticalSNode" ; } + else { cerr << "Parent : Type: UnknownType"; } + cerr << ", H: " << setprecision(4) << DbU::getPhysical(_parent->getHeight(),DbU::Micro); + cerr << ", W: " << setprecision(4) << DbU::getPhysical(_parent->getWidth(),DbU::Micro); + cerr << ", X: " << DbU::getPhysical(_parent->getX(),DbU::Micro); + cerr << ", Y: " << DbU::getPhysical(_parent->getY(),DbU::Micro) << endl; + } else { + cerr << "Parent : IsROOT " << endl; + } +} + + +string SlicingNode::_getString () const +{ + ostringstream os; + os << "<" << _getTypeName(); + if (getGCell()) os << " id:" << getGCell()->getId(); + os << " " << (void*)this << ">"; + return os.str(); +} + + +string SlicingNode::_getTypeName () const +{ return "SlicingNode"; } + + +void SlicingNode::printBoxSet() const +{ + if (_boxSet != NULL){ + _boxSet->print(); + } +} + + +void SlicingNode::place( DbU::Unit x, DbU::Unit y ) +{ + cdebug_log(536,1) << "SlicingNode::place(DbU::Unit x, DbU::Unit y)" << endl; + + if (isSet()) { + _x = x; + _y = y; + setPlaced( Placed ); + + DbU::Unit hpitch = _rg->getHorizontalPitch(); + DbU::Unit vpitch = _rg->getVerticalPitch(); + + if (_x % vpitch) + cerr << Warning( "SlicingNode::place(): On %s, _x is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(_x).c_str() + , DbU::getValueString(vpitch).c_str() + ) << endl; + + if (_y % hpitch) + cerr << Warning( "SlicingNode::place(): On %s, _y is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(_y).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; + } else + cerr << Error( "SlicingNode::place(DbU::Unit x, DbU::Unit y): Device has not been set." ) << endl; + + cdebug_tabw(536,-1); +} + + +void SlicingNode::replace( DbU::Unit x, DbU::Unit y ) +{ + cdebug_log(536,1) << "SlicingNode::replace(DbU::Unit x, DbU::Unit y)" << endl; + + if (isSet()) { + _x = x; + _y = y; + setPlaced( Placed ); + } else + cerr << Error( "SlicingNode::replace(DbU::Unit x, DbU::Unit y): Device has not been set." ) << endl; + + cdebug_tabw(536,-1); +} + + +void SlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace ) +{ + cdebug_log(536,1) << "SlicingNode::place(DbU::Unit x, DbU::Unit y)" << endl; + SlicingNode::place(x,y); + cdebug_tabw(536,-1); +} + + +void SlicingNode::setGlobalSize( DbU::Unit height, DbU::Unit width ) +{ + cmess2 << " o Selecting box set (" << DbU::getValueString(height) + << "," << DbU::getValueString(width) << ")" << endl; + + this->setBoxSet( height, width ); +} + + +void SlicingNode::setGlobalSize( size_t index ) +{ + cmess2 << " o Selecting box set at index " << index << endl; + + this->setBoxSet( index ); +} + + +void SlicingNode::_setGlobalSize ( BoxSet* boxSet ) +{ + cdebug_log(535,1) << "SlicingNode::_setGlobalSize( BoxSet* boxSet ) " << endl; + _setBoxSet( boxSet ); + cdebug_log(535,-1); +} + + +void SlicingNode::preDestroy() +{ + if ( _parent != NULL ){ + _parent->removeNode(this); + }/* else { + if (_railCell) _railCell->destroy(); + }*/ + if (this->getMaster() == NULL) _nodeSets->clear(); +} + + +void SlicingNode::destroy() +{ + SlicingNode::preDestroy(); + delete(this); +} + + +void SlicingNode::preRecursiveDestroy() +{ + SlicingNode::preDestroy(); +} + + +void SlicingNode::recursiveDestroy() +{ + SlicingNode::preRecursiveDestroy(); + delete(this); +} + + +list SlicingNode::getLeaves() const +{ + return list(); +} + + +bool SlicingNode::checkInitialPlacement( int& cpt ) const +{ +// -----------------------------------------------------------------------------------------------// +// Notes:: Initial placement criteria is having at least 2 devices placed at (x, y) = (0, 0) +// -----------------------------------------------------------------------------------------------// + bool initialPlacement = false; + if ( cpt < 2 ){ initialPlacement = true; } + return initialPlacement; +} + +void SlicingNode::updateCellAbutmentBox() +{ + Point pmin = Point(getX(), getY()); + Point pmax = Point(getX()+getWidth(), getY()+getHeight()); + Box box = Box(pmin, pmax); + _cell->setAbutmentBox(box); +} + + +void SlicingNode::setGCell( Anabatic::GCell* gcell ) +{ + _gcell = gcell; + cdebug_log(535,0) << "SlicingNode::setGCell() " << _gcell << endl; +} + +// Error Methods +DbU::Unit SlicingNode::getToleranceRatioH() const +{ + cerr << "Error(DbU::Unit SlicingNode::getToleranceH()): Device and Routing do not have tolerance parameters." << endl; + return 0; +} + + +DbU::Unit SlicingNode::getToleranceRatioW() const +{ + cerr << "Error(DbU::Unit SlicingNode::getToleranceW()): Device and Routing do not have tolerance parameters." << endl; + return 0; +} + + +void SlicingNode::setToleranceRatioH( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::setToleranceH( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::setToleranceRatioW( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::setToleranceW( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +DbU::Unit SlicingNode::getToleranceBandH() const +{ + cerr << "Error(DbU::Unit SlicingNode::getToleranceBandH()): Device and Routing do not have tolerance parameters." << endl; + return 0; +} + + +DbU::Unit SlicingNode::getToleranceBandW() const +{ + cerr << "Error(DbU::Unit SlicingNode::getToleranceBandW()): Device and Routing do not have tolerance parameters." << endl; + return 0; +} + + +void SlicingNode::setToleranceBandH( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::setToleranceBandH( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::setToleranceBandW( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::setToleranceBandW(DbU::Unit tolerance)): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::recursiveSetToleranceRatioH( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::recursiveSetToleranceRatioH( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::recursiveSetToleranceRatioW( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::recursiveSetToleranceRatioW( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::recursiveSetToleranceBandH( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::recursiveSetToleranceBandH( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::recursiveSetToleranceBandW( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::recursiveSetToleranceBandW( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::_recursiveSetToleranceRatioH( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::_recursiveSetToleranceRatioH( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::_recursiveSetToleranceRatioW( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::_recursiveSetToleranceRatioW( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::_recursiveSetToleranceBandH( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::_recursiveSetToleranceBandH( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::_recursiveSetToleranceBandW( DbU::Unit tolerance ) +{ + cerr << "Error(void SlicingNode::_recursiveSetToleranceBandW( DbU::Unit tolerance )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::setTolerances( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ) +{ + cerr << "Error(void SlicingNode::setTolerances( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::recursiveSetTolerances( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ) +{ + cerr << "Error(void SlicingNode::recursiveSetTolerances( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw )): Device and Routing do not have tolerance parameters." << endl; +} + + +void SlicingNode::_recursiveSetTolerances( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ) +{ + cerr << "Error(void SlicingNode::_recursiveSetTolerances( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw )): Device and Routing do not have tolerance parameters." << endl; +} + + +bool SlicingNode::hasEmptyChildrenNodeSets() const +{ + cerr << "Error(bool SlicingNode::hasEmptyChildrenNodeSets()): Device and routing do not have child." << endl; + return true; +} + + +const vector& SlicingNode::getChildren() const +{ + cerr << "Error(vector SlicingNode::getChildren()): Device and Routing do not have child." << endl; + static vector dummyVectorSlicingNode; + return dummyVectorSlicingNode; +} + + +SlicingNode* SlicingNode::getChild( int index ) const +{ + cerr << "Error(SlicingNode* SlicingNode::getChild(int index)): Device and Routing do not have child." << endl; + return NULL; +} + + +int SlicingNode::getChildIndex( SlicingNode* node ) const +{ + cerr << "Error(int SlicingNode::getChildIndex( SlicingNode* node )): Device and Routing do not have child." << endl; + return 0; +} + + +size_t SlicingNode::getNbChild() const +{ + cerr << "Error(int SlicingNode::getNbChild()): Device and Routing do not have child." << endl; + return 0; +} + + +void SlicingNode::createChild( unsigned int type, unsigned int alignment ) +{ + cerr << "Error(void createChild( SlicingType type, Alignment alignment = UnknownAlignment)): Device and Routing do not have child." << endl; +} + + +void SlicingNode::createChild( NodeSets* nodeSets + , unsigned int alignment + , Instance* instance + , BoxSet* boxSet + ) +{ + cerr << "Error(void createChild( NodeSets* nodeSets, Alignment alignment, Instance* instance, BoxSet* boxset )): Device and Routing do not have child." << endl; +} + + +void SlicingNode::createChild( int childIndex, int copyIndex, unsigned int tr ) +{ + std::cerr << "Error(createChild( int childIndex, int copyIndex, unsigned int tr )): Device and Routing do not have child." << endl; +} + + +void SlicingNode::createRouting( DbU::Unit space ) +{ + std::cerr << "Error(void createChild( DbU::Unit space )): Device and Routing do not have child." << endl; +} + + +void SlicingNode::insertNode( SlicingNode* node, int index ) +{ + cerr << "Error(void SlicingNode::insertNode( SlicingNode* node, int index )): Device and Routing do not have child." << endl; +} + + +void SlicingNode::push_back( SlicingNode* node, bool reset ) +{ + cerr << "Error(void SlicingNode::push_back( SlicingNode* node, bool reset )): Device and Routing do not have child." << endl; +} + + +void SlicingNode::push_front( SlicingNode* node ) +{ + cerr << "Error(void SlicingNode::push_front( SlicingNode* node )): Device and Routing do not have child." << endl; +} + + +void SlicingNode::removeNode( SlicingNode* node ) +{ + cerr << "Error(void SlicingNode::removeNode( SlicingNode* node )): Device and Routing do not have child." << endl; +} + + +void SlicingNode::removeAllNodes() +{ + cerr << "Error(void SlicingNode::removeAllNodes()): Device and Routing do not have child." << endl; +} + + +list > SlicingNode::getSymmetries() const +{ + cerr << "Error(list > SlicingNode::getSymmetries() const) : Device and Routing do not have symmetries." << endl; + return list >(); +} + + +void SlicingNode::setSymmetries( list > sym ) +{ + cerr << "Error(void SlicingNode::setSymmetries( list > sym )) : Device and Routing do not have symmetries." << endl; +} + + +bool SlicingNode::isSymmetry( int index, std::pair& symmetry ) +{ + cerr << "Error(bool SlicingNode::isSymmetry( int index, std::pair& symmetry )) : Device and Routing do not have symmetries." << endl; + return false; +} + + +bool SlicingNode::isSymmetry( int index ) +{ + cerr << "Error(bool SlicingNode::isSymmetry( int index )) : Device and Routing do not have symmetries." << endl; + return false; +} + + +void SlicingNode::addSymmetry( int childIndex, int copyIndex, bool reset ) +{ + cerr << "Error(void SlicingNode::addSymmetry( int childIndex, int copyIndex, bool reset )) : Device and Routing do not have symmetries." << endl; +} + + +void SlicingNode::removeSymmetry( int index ) +{ + cerr << "Error(void SlicingNode::removeSymmetry( int index )) : Device and Routing do not have symmetries." << endl; +} + + +void SlicingNode::normalizeSymmetries() +{ + cerr << "Error(void SlicingNode::normalizeSymmetries() const) : Device and Routing do not have symmetries." << endl; +} + + +void SlicingNode::printChildren() const +{ + cerr << "Error(void SlicingNode::printChildren() const): Device and Routing do not have child." << endl; +} + + +void SlicingNode::printChildrenLine() const +{ + cerr << "Error(void SlicingNode::printChildrenLine() const): Device and Routing do not have child." << endl; +} + + +double SlicingNode::getOccupationArea() const +{ + cerr << "Error(double SlicingNode::getOccupationArea() const) : Occupied Area is not relevant for Routing and Devices." << endl; + return 100; +} + + +void SlicingNode::setNFing( int nfing ) +{ + cerr << "Error(void SlicingNode::setNFing( int nfing )): Only DlicingNode have NFing parameter." << endl; +} + + +int SlicingNode::getNFing() const +{ + cerr << "Error(int SlicingNode::getNFing() const): Only DSlicingNode have NFing parameter." << endl; + return 0; +} + + +double SlicingNode::getStartParameter() const +{ + cerr << "Error(int SlicingNode::getStartParameter() const): Only DSlicingNode have Start parameter." << endl; + return 0; +} + + +double SlicingNode::getStepParameter() const +{ + cerr << "Error(int SlicingNode::getStepParameter() const): Only DSlicingNode have Step parameter." << endl; + return 0; +} + + +double SlicingNode::getCountParameter() const +{ + cerr << "Error(int SlicingNode::getCountParameter() const): Only DSlicingNode have Count parameter." << endl; + return 0; +} + + +Instance* SlicingNode::getInstance() const +{ + cerr << "Error(Instance* getInstance() const): Only DSlicingNode have an Instance." << endl; + return NULL; +} + + +void SlicingNode::setInstance( Instance* instance ) +{ + cerr << "Error(Instance* setInstance( Instance* instance ) const): Only DSlicingNode have an Instance." << endl; +} + + +void SlicingNode::setCell( Cell* cell ) +{ + if (_parent == NULL){ + if (checkCellInstances(cell)){ + _cell = cell; + AnalogCellExtension::setSlicingTree( cell, this ); + } + } else { + cerr << "Error(void SlicingNode::setCell( Cell* cell )): SlicingTree's root only can set the Slicing tree's cell." << endl; + } +} + + +void SlicingNode::setKatana( Katana::KatanaEngine* katana ) +{ + _katana = katana; +} + + +bool SlicingNode::checkCellInstances( Cell* cell ) +{ + return true; +} + + +SlicingNode* SlicingNode::findInstance( Instance* instance ) +{ + return NULL; +} + + +SlicingNode* SlicingNode::findSlicingNode( Anabatic::GCell* gcell ) +{ + return NULL; +} + + + +void SlicingNode::createSlicingRouting() +{ + cerr << "Error(void SlicingNode::createSlicingRouting()): Used for HVSlicingNode only." << endl; +} + + +void SlicingNode::resetSlicingRouting() +{ + cerr << "Error(void SlicingNode::resetSlicingRouting()): Used for HVSlicingNode only." << endl; +} + + +void SlicingNode::destroySlicingRouting() +{ + cerr << "Error(void SlicingNode::destroySlicingRouting()): Used for HVSlicingNode only." << endl; +} + + +int SlicingNode::getRoutingIndex ( SlicingNode* node ) const +{ + cerr << "Error(int SlicingNode::getRoutingIndex ( SlicingNode* node ) const ): Routing index is used for Horizontal/Vertical nodes." << endl; + return 0; +} + + +SlicingNode* SlicingNode::getSlicingRouting ( int index ) const +{ + cerr << "Error(SlicingNode* SlicingNode::getSlicingRouting ( int index ) const): Used for Horizontal/Vertical Slicing node only." << endl; + return NULL; +} + + +SlicingNode* SlicingNode::findHorizontalParent () const +{ + if (_parent) { + SlicingNode* node = _parent; + while(node){ + if (node->getType() == HorizontalSNode){ break; } + else { node = node->getParent(); } + } + return node; + } else { + return NULL; + } +} + + +SlicingNode* SlicingNode::findVerticalParent () const +{ + if (_parent) { + SlicingNode* node = _parent; + while(node){ + if (node->getType() == VerticalSNode){ break; } + else { node = node->getParent(); } + } + return node; + } else { + return NULL; + } +} + + +int SlicingNode::getIndexInHorizontalParent() const +{ + if (_parent) { + if (this->getParent()->getType() == HorizontalSNode){ + int i = 0; + vector::const_iterator it = this->getParent()->getChildren().begin(); + while (it != this->getParent()->getChildren().end()){ + if ( ((*it)->getType() == this->getType() ) + && ((*it)->getHeight() == this->getHeight()) + && ((*it)->getWidth () == this->getWidth ()) + && ((*it)->getX() == this->getX() ) + && ((*it)->getY() == this->getY() ) + ) + { it = this->getParent()->getChildren().end(); } + else { + i++; + it++; + } + } + return i; + } else { + bool found = false; + SlicingNode* node = this->getParent(); + + while((node->getParent() != NULL) && (found == false)){ + if (node->getParent()->getType() == HorizontalSNode){ + found = true; + } else { + node = node->getParent(); + } + } + + if (found){ + return node->getParent()->getChildIndex(node); + } else { + return -1; + } + } + } else { + return -1; + } +} + + +int SlicingNode::getIndexInVerticalParent() const +{ + if (_parent) { + if (this->getParent()->getType() == VerticalSNode){ + int i = 0; + vector::const_iterator it = this->getParent()->getChildren().begin(); + while (it != this->getParent()->getChildren().end()){ + if ( ((*it)->getType() == this->getType() ) + && ((*it)->getHeight() == this->getHeight()) + && ((*it)->getWidth () == this->getWidth ()) + && ((*it)->getX() == this->getX() ) + && ((*it)->getY() == this->getY() ) + ) + { it = this->getParent()->getChildren().end(); } + else { + i++; + it++; + } + } + return i; + } else { + bool found = false; + SlicingNode* node = this->getParent(); + + while((node->getParent() != NULL) && (found == false)){ + if (node->getParent()->getType() == VerticalSNode){ + found = true; + } else { + node = node->getParent(); + } + } + + if (found){ + return node->getParent()->getChildIndex(node); + } else { + return -1; + } + } + } else { + return -1; + } +} + + +void SlicingNode::createRoutingPads () +{ + cdebug_log(536,1) << "SlicingNode::createRoutingPads()" << endl; + + if (not _cell) { + cdebug_tabw(536,-1); + return; + } + +//_cell->flattenNets( Cell::Flags::StayOnPlugs ); + _cell->flattenNets(); + +#if THIS_IS_DISABLED + for ( Net* net : _cell->getNets() ) { + cdebug_log(536,0) << "Net: " << net << endl; + + if ( net->getPlugs().getSize() > 1 ) { + cdebug_log(530,1) << "Not a rail supply and has " << net->getPlugs().getSize() << " plugs" << endl; + + vector plugs; + for ( Plug* plug : net->getPlugs() ) { + cdebug_log(530,0) << "| " << plug << endl; + + if (dynamic_cast(plug->getMasterNet()->getCell())){ + cdebug_log(530,0) << "| Device: " << plug << endl; + plugs.push_back( plug ); + } else if (isRailSegments(plug)){ + cdebug_log(530,0) << "| PR: " << plug << endl; + plugs.push_back( plug ); + } else { + if (not plug->getNet()->isSupply()) + plugs.push_back( plug ); + } + } + + for ( Plug* plug : plugs ) { + cdebug_log(536,0) << "Building RoutingPad for " << plug << endl; + + RoutingPad* rp = RoutingPad::create( net, Occurrence(plug) ); + cdebug_log(536,0) << "+ " << rp << ", instance: " << plug->getInstance()->getTransformation() << endl; + cdebug_log(536,0) << "+ instance ab: " << plug->getInstance()->getMasterCell()->getAbutmentBox() << endl; + + // Select the Component with the highest layer. + Net* masterNet = static_cast( rp->getOccurrence().getEntity() )->getMasterNet(); + Horizontal* hbest = NULL; + Vertical* vbest = NULL; + + for ( Component* c : masterNet->getComponents() ) { + //cdebug_log(530,0) << "| " << c << endl; + + Horizontal* h = dynamic_cast(c); + Vertical* v = dynamic_cast(c); + + if (h) { + if (not hbest) hbest = h; + else { + if (h->getLayer()->above(hbest->getLayer())){ + hbest = h; + } else if (h->getLayer() == hbest->getLayer()){ + if ( hbest->getBoundingBox().getWidth() * hbest->getBoundingBox().getHeight() + < h->getBoundingBox().getWidth() * h->getBoundingBox().getHeight() + ) { + hbest = h; + } + } + } + } else if (v) { + if (not vbest) vbest = v; + else { + if (v->getLayer()->above(vbest->getLayer())){ + vbest = v; + } else if (v->getLayer() == vbest->getLayer()){ + if ( vbest->getBoundingBox().getWidth() * vbest->getBoundingBox().getHeight() + < v->getBoundingBox().getWidth() * v->getBoundingBox().getHeight() + ) { + vbest = v; + } + } + } + } + } + + if (hbest) { + cdebug_log(536,0) << "* " << hbest << endl; + rp->setExternalComponent(hbest); + } else if (vbest) { + cdebug_log(536,0) << "* " << vbest << endl; + rp->setExternalComponent(vbest); + } + } + + RoutingPad* previousRp = NULL; + for ( RoutingPad* rp : net->getRoutingPads() ) { + if ( previousRp + and ( not rp ->getBodyHook()->isAttached() + or not previousRp->getBodyHook()->isAttached()) ) { + rp->getBodyHook()->attach( previousRp->getBodyHook() ); + } + previousRp = rp; + } + cdebug_tabw(530,-1); + } + } +#endif + + cdebug_tabw(536,-1); +} + + +void SlicingNode::clearRoutingPads() +{ + vector nets; + + for ( Net* net : _cell->getNets() ) { + DeepNet* n = dynamic_cast(net); + if (n) nets.push_back(n); + } + for ( DeepNet* net : nets ){ + net->destroy(); + } + for ( Net* net : _cell->getNets() ) { + vector rps; + for ( RoutingPad* rp : net->getRoutingPads() ) rps.push_back( rp ); + for ( RoutingPad* rp : rps ) rp->destroy(); + } +} + + +void SlicingNode::restrictDevices() +{ + if (_gcell){ + Anabatic::Vertex* vertex = _gcell->getObserver< Anabatic::Vertex>( Anabatic::GCell::Observable::Vertex); + vertex->clearRestriction(); + } +} + + +void SlicingNode::setVertexRestriction ( Net* net, Katana::KatanaEngine* kanata ){} + + +void SlicingNode::estimateChannelsSize () +{ + setRoutingEstimated (RoutingEstimated); +} + + +void SlicingNode::expandRoutingChannel () +{ + setRoutingEstimated (RoutingEstimated); +} + + +void SlicingNode::_expandRoutingChannel () +{ + setRoutingEstimated (RoutingEstimated); +} + + +void SlicingNode::expandRoutingChannel ( DbU::Unit height, DbU::Unit width ) +{ + setRoutingEstimated (RoutingEstimated); +} + + +void SlicingNode::clearGlobalRouting() +{ + vector c = vector(); + c.clear(); + vector s = vector(); + + int hcpt = 0; + int vcpt = 0; + int ccpt = 0; + + for(Net* net: _cell->getNets()){ + for(Component* component: net->getComponents()){ + if (SlicingNode::isRailSegments(dynamic_cast (component)) == false){ + Hurricane::Horizontal* h = dynamic_cast(component); + Hurricane::Vertical* v = dynamic_cast (component); + Hurricane::Contact* cc = dynamic_cast (component); + + if (h) s.push_back(component); + if (v) s.push_back(component); + if (cc) c.push_back(component); + + if (h) hcpt++; + if (v) vcpt++; + if (cc) ccpt++; + } + } + } + for (vector::iterator it = s.begin(); it != s.end(); it++){ + (*it)->destroy(); + } + for (vector::iterator it = c.begin(); it != c.end(); it++){ + (*it)->destroy(); + } + this->clearGCells(); +} + + +void SlicingNode::clearGCells() +{ + _gcell = NULL; +} + + +void SlicingNode::updateGCellPosition() +{ + if (_gcell) { + _gcell->setSouthWestCorner( getX(), getY() ); + } + cdebug_log(535,0) << "SlicingNode::updateGCellPosition(): " << _gcell << endl; +} + + +void SlicingNode::updateGContacts() +{ + if (_gcell) { + _gcell->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + } + cdebug_log(535,0) << "SlicingNode::updateGContacts(): " << _gcell << endl; +} + + +/*<<<<<<< HEAD*/ +void SlicingNode::updateMatrixGCellPosition() +{ + cerr << "Error(void SlicingNode::updateMatrixGCellPosition()): Only used by DSlicingNode" << endl; +} + +void SlicingNode::updateMatrixGContacts() +{ + cerr << "Error(void SlicingNode::updateMatrixGContacts()): Only used by DSlicingNode" << endl; +} + +/*void SlicingNode::updateMatrixGContactsPosition() +{ + cerr << "Error(void SlicingNode::updateMatrixGContactsPosition()): Only used by DSlicingNode" << endl; +} + + +void SlicingNode::updateGContactsPosition() +{ + if (_gcell)_gcell->updateContactsPosition(); +} + + +======= +>>>>>>> ad94201dbefd0e6f98b1e28a032a3b2a6d57390d*/ +int SlicingNode::getNbDevices() +{ + return 1; +} + + +bool SlicingNode::containAxis( DbU::Unit axis, unsigned int symmetryType ) +{ + if (symmetryType == HSymmetry){ + return ( (axis > getX()) && (axis < getX()+getWidth())); + } else if (symmetryType == VSymmetry){ + return ( (axis > getY()) && (axis < getY()+getHeight())); + } else return false; +} + + +bool SlicingNode::checkSymmetryNet ( unsigned int type, Net* net1, Net* net2 ) const +{ + cerr << "Error(bool checkSymmetryNet ( unsigned int type, Net* net1, Net* net2 ) const): Only used by HVSlicingNode" << endl; + return false; +} + + +void SlicingNode::addSymmetryNet ( unsigned int type, Net* net1, Net* net2 ) +{ + cerr << "Error(void addSymmetryNet ( unsigned int type, Net* net1, Net* net2 )): Only used by HVSlicingNode" << endl; +} + + +void SlicingNode::updateNetConstraints () +{ + cerr << "Error(void SlicingNode::updateNetConstraints ()): Only used by HVSlicingNode" << endl; +} + + + +void SlicingNode::updateSymNetAxis() +{ + cerr << "Error(void SlicingNode::updateSymNetAxis ()): Only used by HVSlicingNode" << endl; +} + +void SlicingNode::setRoutingGauge ( CRL::RoutingGauge* rg ) +{ + _rg = rg; +} + + +void SlicingNode::addRailSegments( Hurricane::Segment* s ) +{ + _railSegments.push_back(s); +} + + +bool SlicingNode::isRailSegments ( Hurricane::Segment* s ) +{ + bool is = false; + for (Segment* seg : _railSegments){ + if ( s == seg ) { + is = true; + break; + } + } + return is; +} + +bool SlicingNode::isRailSegments ( Hurricane::Plug* p ) +{ + Instance* i = p->getInstance(); + Net* net = NULL; + int t = 0; + for (Net* n : i->getMasterCell()->getNets()) { + net = n; + t++; + } + if (t != 1) return false; + Component* component = NULL; + t = 0; + for (Component* c : net->getComponents()){ + component = c; + t++; + } + if (t != 1) return false; + + Horizontal* h = dynamic_cast(component); + Vertical* v = dynamic_cast (component); + if (h) return isRailSegments(h); + else if (v) return isRailSegments(v); + else return false; +} + + +void SlicingNode::flattenDigitalNets () +{ + cerr << "Error(void SlicingNode::flattenDigitalNets ()): Only used by HVSlicingNode" << endl; +} + +void SlicingNode::updateWireOccupation ( Anabatic::VertexSet ) +{ + cerr << "Error(void SlicingNode::updateWireOccupation ( Anabatic::VertexSet )): Only used by HVSlicingNode" << endl; +} + +void SlicingNode::addWireOccupation ( DbU::Unit min, DbU::Unit max ) +{ + cerr << "Error(void SlicingNode::addWireOccupation ( DbU::Unit min, DbU::Unit max )): Only used by HVSlicingNode and RHVSlicingNode" << endl; +} + +void SlicingNode::resetWireOccupation () +{ + cerr << "Error(void SlicingNode::resetWireOccupation()): Only used by HVSlicingNode and RHVSlicingNode" << endl; +} + + +int SlicingNode::getMaxWireOccupation () +{ + cerr << "Error(int SlicingNode::getMaxWireOccupation()): Only used by HVSlicingNode and RHVSlicingNode" << endl; + return 0; +} + + +// -----------------------------------------------------------------------------------------------// +// Class : HVSlicingNode +// -----------------------------------------------------------------------------------------------// + + +HVSlicingNode::HVSlicingNode( unsigned int type, unsigned int alignment ): SlicingNode( type, NodeSets::create(), alignment, NULL ) +{ + _toleranceRatioH = 0; + _toleranceRatioW = 0; + _toleranceBandH = 0; + _toleranceBandW = 0; + _children = vector(); + _symmetries = list >(); + _slicingRouting = vector(); + _netsymmetries = vector >(); +} + + +HVSlicingNode::~HVSlicingNode(){} + + + +void HVSlicingNode::setToleranceRatioH ( DbU::Unit tolerance ) +{ + _toleranceRatioH = tolerance; + getRoot()->_resetSlicingTree(); +} + + +void HVSlicingNode::setToleranceRatioW ( DbU::Unit tolerance ) +{ + _toleranceRatioW = tolerance; + getRoot()->_resetSlicingTree(); +} + + +void HVSlicingNode::setToleranceBandH ( DbU::Unit tolerance ) +{ + _toleranceBandH = tolerance; + resetSlicingTree(); +} + + +void HVSlicingNode::setToleranceBandW ( DbU::Unit tolerance ) +{ + _toleranceBandW = tolerance; + resetSlicingTree(); +} + + +void HVSlicingNode::recursiveSetToleranceRatioH( DbU::Unit tolerance ) +{ + _recursiveSetToleranceRatioH(tolerance); + getRoot()->_resetSlicingTree(); +} + + +void HVSlicingNode::recursiveSetToleranceRatioW( DbU::Unit tolerance ) +{ + _recursiveSetToleranceRatioW(tolerance); + getRoot()->_resetSlicingTree(); +} + + +void HVSlicingNode::recursiveSetToleranceBandH( DbU::Unit tolerance ) +{ + resetSlicingTree(); + _recursiveSetToleranceBandH(tolerance); +} + + +void HVSlicingNode::recursiveSetToleranceBandW( DbU::Unit tolerance ) +{ + resetSlicingTree(); + _recursiveSetToleranceBandW(tolerance); +} + + +void HVSlicingNode::_recursiveSetToleranceRatioH( DbU::Unit tolerance ) +{ + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + + if ( (!(*it)->isDevice()) && (!(*it)->isRouting()) ) + { (*it)->recursiveSetToleranceRatioH(tolerance); } + } + _toleranceRatioH = tolerance; +} + + +void HVSlicingNode::_recursiveSetToleranceRatioW( DbU::Unit tolerance ) +{ + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + + if ( (!(*it)->isDevice()) && (!(*it)->isRouting()) ) + { (*it)->recursiveSetToleranceRatioW(tolerance); } + } + _toleranceRatioW = tolerance; +} + + +void HVSlicingNode::_recursiveSetToleranceBandH( DbU::Unit tolerance ) +{ + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + + if ( (!(*it)->isDevice()) && (!(*it)->isRouting()) ) + { (*it)->recursiveSetToleranceBandH(tolerance); } + } + _toleranceBandH = tolerance; +} + + +void HVSlicingNode::_recursiveSetToleranceBandW( DbU::Unit tolerance ) +{ + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + + if ( (!(*it)->isDevice()) && (!(*it)->isRouting()) ) + { (*it)->recursiveSetToleranceBandW(tolerance); } + } + _toleranceBandW = tolerance; +} + + +void HVSlicingNode::setTolerances( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ) +{ + resetSlicingTree(); + _toleranceRatioH = trh; + _toleranceRatioW = trw; + _toleranceBandH = tbh; + _toleranceBandW = tbw; +} + + +void HVSlicingNode::recursiveSetTolerances( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ) +{ + resetSlicingTree(); + _recursiveSetTolerances( trh, trw, tbh, tbw ); +} + + +void HVSlicingNode::_recursiveSetTolerances( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ) +{ + _recursiveSetToleranceRatioH(trh); + _recursiveSetToleranceRatioW(trw); + _recursiveSetToleranceBandH(tbh); + _recursiveSetToleranceBandW(tbw); +} + + +bool HVSlicingNode::hasEmptyChildrenNodeSets() const +{ + bool flag = false; + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + NodeSets* node = (*it)->getNodeSets(); + if ( (node->empty() != true) && (!(*it)->isRouting()) ) + { if (node->empty() == true) {flag = true;} } + } + return flag; +} + + +int HVSlicingNode::getChildIndex( SlicingNode* node ) const +{ + int i = 0; + vector::const_iterator it = _children.begin(); + while (it != _children.end()){ + if ( ((*it)->getType() == node->getType() ) + && ((*it)->getHeight() == node->getHeight()) + && ((*it)->getWidth () == node->getWidth ()) + && ((*it)->getX() == node->getX() ) + && ((*it)->getY() == node->getY() ) + ) + { it = _children.end(); } + else { + i++; + it++; + } + } + return i; +} + + +void HVSlicingNode::createChild( unsigned int type, unsigned int alignment ) +{ + if (type == HorizontalSNode) { + HSlicingNode* hsn = HSlicingNode::create(alignment); + hsn->setTolerances( getToleranceRatioH() + , getToleranceRatioW() + , getToleranceBandH() + , getToleranceBandW() + ); + push_back(hsn); + resetSlicingTree(); + } + + else if (type == VerticalSNode) { + VSlicingNode* vsn = VSlicingNode::create(alignment); + vsn->setTolerances( getToleranceRatioH() + , getToleranceRatioW() + , getToleranceBandH() + , getToleranceBandW() + ); + push_back(vsn); + resetSlicingTree(); + } + else + { cerr << " Error(void HVSlicingNode::createChild(SlicingType type, Alignment alignment)): Unknown type." << endl; } +} + + +void HVSlicingNode::createChild( NodeSets* nodeSets + , unsigned int alignment + , Instance* instance + , BoxSet* boxSet + ) +{ + DSlicingNode* node = DSlicingNode::create( nodeSets, alignment, instance, boxSet ); + node->setParent(this); + this->push_back(node); + resetSlicingTree(); +} + + +void HVSlicingNode::createChild( int childIndex, int copyIndex, unsigned int tr ) +{ + if (childIndex != copyIndex){ + + SlicingNode* node = this->getChild(childIndex)->clone(tr); + this->insertNode( node, copyIndex ); + _symmetries.push_back( pair(min(childIndex, copyIndex), max(childIndex, copyIndex)) ); + resetSlicingTree(); + normalizeSymmetries(); + } + else { cerr << "Error(void HVSlicingNode::createChild( int childIndex, int copyIndex, unsigned int tr )): Indexes cannot be the same." << endl; } +} + + +void HVSlicingNode::insertNode( SlicingNode* node, int index ) +{ + vector::iterator it = _children.begin(); + for (int i = 0; i < index; i++){ if (it != _children.end()){ it++; } } + _children.insert(it,node); + node->setParent(this); + resetSlicingTree(); +} + + +void HVSlicingNode::push_back( SlicingNode* node, bool reset ) +{ + node->setParent(this); + _children.push_back(node); + if (reset) { resetSlicingTree(); } +} + + +void HVSlicingNode::push_front( SlicingNode* node ) +{ + node->setParent(this); + _children.insert(_children.begin(), node); + resetSlicingTree(); +} + + +void HVSlicingNode::removeNode( SlicingNode* node ) +{ + int index = 0; + bool found = false; + vector::iterator it = _children.begin(); +//(*it)->printLine(); + while( it != _children.end() ){ + if ((*it) == node) { + _children.erase(it); + found = true; + it = _children.end(); + } + else { + it++; + index++; + } + } + + if (found == true){ + removeSymmetry(index); + resetSlicingTree(); + node->removeParent(); + node->setX(0); + node->setY(0); + node->setPlaced(false); + } /*else { + cerr << "Didn't found" << endl; + }*/ +} + + +bool HVSlicingNode::isSymmetry( int index, pair& symmetry ) +{ + bool symmetryFound = false; + + if (_symmetries.empty() != true){ + for (list >::const_iterator it2 = _symmetries.begin(); it2 != _symmetries.end(); it2++){ + + if ((*it2).second == index){ + symmetry = pair((*it2).first,(*it2).second); + symmetryFound = true; + } + } + } + return symmetryFound; +} + + +bool HVSlicingNode::isSymmetry( int index ) +{ + bool symmetryFound = false; + + if (_symmetries.empty() != true){ + for (list >::const_iterator it2 = _symmetries.begin(); it2 != _symmetries.end(); it2++){ + + if ((*it2).second == index){ + symmetryFound = true; + } + } + } + return symmetryFound; +} + + +void HVSlicingNode::addSymmetry( int childIndex, int copyIndex, bool reset ) +{ + if (childIndex >= (int)getChildren().size()) { + cerr << Warning( "HVSlicingNode::addSymmetry(int,int)): Child index out of range:%d (> %d), symmetry is ignored." + , childIndex, getChildren().size() ) << endl; + return; + } + + if (copyIndex >= (int)getChildren().size()) { + cerr << Warning( "HVSlicingNode::addSymmetry(int,int)): Copy index out of range:%d (> %d), symmetry is ignored." + , copyIndex, getChildren().size() ) << endl; + return; + } + + if (childIndex == copyIndex) { + cerr << Warning( "HVSlicingNode::addSymmetry(int,int)): Indexes cannot be identical (%d), symmetry is ignored." + , childIndex ) << endl; + return; + } + unsigned int symmetryType = 0; + if (this->getType() == HorizontalSNode) symmetryType = HSymmetry; + if (this->getType() == VerticalSNode ) symmetryType = VSymmetry; + + + if (not getChild(childIndex)->isSymmetric(getChild(copyIndex), symmetryType, ShowDiff)) { + cerr << Warning( "HVSlicingNode::addSymmetry(int,int)): Children %d and %d are not the same, symmetry is ignored." + , childIndex, copyIndex ) << endl; + return; + } + + _symmetries.push_back( pair(min(childIndex, copyIndex), max(childIndex, copyIndex)) ); + if (reset) resetSlicingTree(); + unsigned int flag = 0; + if (this->getType() == HorizontalSNode) flag = HSymmetry; + if (this->getType() == VerticalSNode ) flag = VSymmetry; + getChild(copyIndex)->setSymmetryFlag(flag); + + getChild(copyIndex)->setMaster(getChild(childIndex)); + normalizeSymmetries(); +} + + +void HVSlicingNode::removeSymmetry( int index ) +{ + bool first = true; + int erasedFirst = 0; + int erasedSecond = 0; + bool isReference = true; + + for ( list >::iterator it = _symmetries.begin(); it != _symmetries.end(); it++ ){ + if ((((*it).first == index) || ((*it).second == index) ) && (first == true)){ + list >::iterator itToerase = it; + it++; + resetSlicingTree(); + first = false; + + if ((*it).first == index){ + erasedFirst = (*itToerase).first; + erasedSecond = (*itToerase).second; + } else { isReference = false; } + + _symmetries.erase(itToerase); + it--; + } + else { + if ( (first == false) && (isReference) ){ + if ((*it).first == erasedFirst){ (*it).first = erasedSecond; } + } + if ((*it).first > index) { (*it).first--; } + if ((*it).second > index) { (*it).second--; } + } + } +} + +void HVSlicingNode::normalizeSymmetries() +{ +// -----------------------------------------------------------------------------------------------// +// Notes : Symmetries must be described in a specific way, in case it is not, this method correct it. +// Examples: +// WRONG: Symmetries [< 1, 2 >, < 2, 3 >, < 3, 4 >]; RIGHT: [< 1, 2 >, < 1, 3 >, < 1, 4 >]; +// WRONG: Symmetries [< 3, 4 >, < 5, 6 >, < 1, 2 >]; RIGHT: [< 1, 2 >, < 3, 4 >, < 5, 6 >]; +// WRONG: Symmetries [< 1, 2 >, < 1, 2 >, < 3, 4 >]; RIGHT: [< 1, 2 >, < 3, 4 >]; +// -----------------------------------------------------------------------------------------------// + + list > adjustedSymmetries = list >(); + for (list >::const_iterator it = _symmetries.begin(); it != _symmetries.end(); it++){ + + if ((*it).first > (*it).second ){ adjustedSymmetries.push_back(pair((*it).second,(*it).first)); } + else { adjustedSymmetries.push_back(pair((*it).first,(*it).second)); } + } + adjustedSymmetries.sort(); + + bool next = false; + list >::iterator it2 = adjustedSymmetries.begin(); + it2++; + + for (list >::iterator it = adjustedSymmetries.begin(); it != adjustedSymmetries.end(); it++){ + it2 = it; + it2++; + + while(next != true){ + if ( (*it).second == (*it2).first ){ (*it2).first = (*it).first; } + if ( (*it).second < (*it2).first ){ next = true; } + it2++; + if ( it2 == adjustedSymmetries.end() ) { next = true; } + } + next = false; + } + _symmetries = adjustedSymmetries; +} + + +void HVSlicingNode::_resetSlicingTree() +{ + _x = 0; + _y = 0; + setPlaced(false); + + if (!this->isPreset()){ + _boxSet = NULL; + setSet(false); + + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + (*it)->_resetSlicingTree(); + } + } +} + + +void HVSlicingNode::print() const +{ + SlicingNode::print(); + if (_symmetries.empty() == false){ + cerr << "Symmetries: " << endl; + for (list >::const_iterator it = _symmetries.begin(); it != _symmetries.end(); it++) + { cerr << "Children: " << (*it).first << " and " << (*it).second << endl; } + cerr << endl; + } else { + cerr << "Symmetries: None" << endl; + } + if (_slicingRouting.empty() == false){ + cerr<< "Slicing Routing: " << endl; + int index = 0; + for (vector::const_iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); it++){ + cerr << "---------------- " << setprecision(4) << index << " -----------------" << endl; + cerr << "Print - Slicing Routing: "; + cerr << "X: " << DbU::getPhysical((*it)->getX(), DbU::Micro); + cerr << ", Y: " << DbU::getPhysical((*it)->getY(), DbU::Micro); + cerr << ", \t height: " << DbU::getPhysical((*it)->getHeight(), DbU::Micro); + cerr << ", width: " << DbU::getPhysical((*it)->getWidth(), DbU::Micro) << endl; + cerr << "GCell: " << (*it)->getGCell() << endl; + if((*it)->getGCell()){ + cerr << "GCell : " << (*it)->getGCell() << endl; + + cerr << "Edges : " << endl; + vector ne = (*it)->getGCell()->getNorthEdges(); + vector se = (*it)->getGCell()->getSouthEdges(); + vector ee = (*it)->getGCell()->getEastEdges(); + vector we = (*it)->getGCell()->getWestEdges(); + + cerr << "--- North : " << ne.empty() << endl; + for (vector::const_iterator itn = ne.begin(); itn != ne.end(); itn++){ + cerr << (*itn)->getOpposite((*it)->getGCell()) << endl; + } + cerr << "--- South : " << se.empty()<< endl; + for (vector::const_iterator its = se.begin(); its != se.end(); its++){ + cerr << (*its)->getOpposite((*it)->getGCell()) << endl; + } + cerr << "--- East : " << ee.empty()<< endl; + for (vector::const_iterator ite = ee.begin(); ite != ee.end(); ite++){ + cerr << (*ite)->getOpposite((*it)->getGCell()) << endl; + } + cerr << "--- West : "<< we.empty() << endl; + for (vector::const_iterator itw = we.begin(); itw != we.end(); itw++){ + cerr << (*itw)->getOpposite((*it)->getGCell()) << endl; + } + } + cerr << "------------------------------------" << endl; + index++; + } + } else { + cerr<< "Slicing Routing: empty" << endl; + } + cerr << endl; +} + + +void HVSlicingNode::printChildren() const +{ + int count = 0; + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->isDevice()) || ((*it)->isRouting()) ){ + cerr << "-- Children: " << count << "/" << _children.size()-1 << " --" << endl; + (*it)->print(); + } + else { + cerr << "-- Children: " << count << "/" << _children.size()-1 << " --" << endl; + (*it)->print(); + (*it)->printChildren(); + } + count++; + } +} + + +void HVSlicingNode::printLine() const +{ + SlicingNode::printLine(); + + if (_symmetries.empty() == false){ + cerr << "Symmetries: " << endl; + for (list >::const_iterator it = _symmetries.begin(); it != _symmetries.end(); it++) + { cerr << "Children: " << (*it).first << " and " << (*it).second << endl; } + cerr << endl; + } + + /*int index = 0; + cerr << "Print - Slicing Routing: " << endl; + for (vector::const_iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); it++){ + cerr << "Index: " << index; + cerr << ", X: " << DbU::getPhysical((*it)->getX(), DbU::Micro); + cerr << ", Y: " << DbU::getPhysical((*it)->getY(), DbU::Micro); + cerr << ", \t height: " << DbU::getPhysical((*it)->getHeight(), DbU::Micro); + cerr << ", width: " << DbU::getPhysical((*it)->getWidth(), DbU::Micro); + if ((*it)->getMaster()){ + cerr << ", MASTER: "; + (*it)->getMaster()->printLine(); + } else { + cerr << endl; + } + index++; + }*/ +} + + +void HVSlicingNode::printChildrenLine() const +{ + int count = 0; + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->isDevice()) || ((*it)->isRouting()) ){ + cerr << "-- Children: " << count << "/" << _children.size()-1 << " --" << endl; + (*it)->printLine(); + } + else { + cerr << endl; + cerr << "-- Children: " << count << "/" << _children.size()-1 << " --" << endl; + (*it)->printLine(); + (*it)->printChildrenLine(); + } + count++; + } +} + + +bool HVSlicingNode::recursiveCheckPreset() const +{ + bool isPreset = this->isPreset(); + if (isPreset){ + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + isPreset = (*it)->recursiveCheckPreset(); + } + } + return isPreset; +} + + +bool HVSlicingNode::recursiveCheckSet() const +{ + bool isSet = this->isSet(); + if (isSet){ + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + isSet = (*it)->recursiveCheckSet(); + } + } + return isSet; +} + + +bool HVSlicingNode::recursiveCheckPlaced() const +{ + bool isPlaced = this->isPlaced(); + if (isPlaced){ + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + isPlaced = (*it)->recursiveCheckPlaced(); + } + } + return isPlaced; +} + + +int HVSlicingNode::getLeafNumber() const +{ + int cpt = 0; + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++) + { cpt += (*it)->getLeafNumber(); } + return cpt; +} + + +double HVSlicingNode::getDevicesArea() const +{ + double area = 0; + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + area += (*it)->getDevicesArea(); + } + return area; +} + + +double HVSlicingNode::getOccupationArea() const +{ + double estimation = 0; + if(recursiveCheckPlaced()) + { + estimation = getDevicesArea()/(getHeight() * getWidth())*100; + } + else { cerr << "Error(double HVSlicingNode::getSpaceEstimation()): SlicingNodes dimensions need to be set first before being estimated." << endl; } + return estimation; +} + + +void HVSlicingNode::setGlobalSize( DbU::Unit height, DbU::Unit width ) +{ + if ( (_nodeSets->empty() != true) ){ + vector::const_iterator it = _nodeSets->begin(); + DbU::Unit bestH = 0; + DbU::Unit bestW = 0; + DbU::Unit currentH = 0; + DbU::Unit currentW = 0; + BoxSet* boxSet = (*_nodeSets->begin()); + + while (it != _nodeSets->end()){ + currentH = (*it)->getHeight(); + currentW = (*it)->getWidth(); + if ( (currentH <= height) && (currentW <= width) ){ + if ( ((height-currentH) <= _toleranceRatioH) && ((height-bestH) <= _toleranceRatioH) ) { + if (currentW > bestW){ + bestH = currentH; + bestW = currentW; + boxSet = (*it); + } + } else if (currentH > bestH) { + bestH = currentH; + bestW = currentW; + boxSet = (*it); + } + } + it++; + } + this->_setGlobalSize(boxSet); + + } else { cerr << "Error(void HVSlicingNode::setGlobalSize( DbU::Unit height, DbU::Unit width )): NodeSets empty. UpdateGlobalSize needs to be used first or with higher tolerances." << endl; } +} + + +void HVSlicingNode::setGlobalSize( size_t index ) +{ + if ( _nodeSets->empty() != true ){ + if (index > (_nodeSets->size()-1)){ cerr << "Error(void HVSlicingNode::setGlobalSize( size_t index )): Out of bound index." << endl; } + else { + this->_setGlobalSize((*(_nodeSets->begin() + index))); + } + } else { cerr << "Error(void HVSlicingNode::setGlobalSize( int index )): NodeSets empty. UpdateGlobalSize needs to be used first or with higher tolerances." << endl; } +} + + +void HVSlicingNode::_setGlobalSize ( BoxSet* boxSet ) +{ +//cerr << "void HVSlicingNode::_setGlobalSize ( BoxSet* boxSet ) " << endl; + if ( (!this->isPreset()) ){ + if (this->getMaster() == NULL) { + this->_setBoxSet(boxSet); + } else { + this->_setBoxSet(_master->getBoxSet()); + } + if ( ((getType() == HorizontalSNode) && (isHSymmetry())) + || ((getType() == VerticalSNode ) && (isVSymmetry())) + ){ + vector::const_iterator itBoxSet = boxSet->getSet().begin(); + for (vector::reverse_iterator it = _children.rbegin(); it != _children.rend(); ++it){ + (*it)->_setGlobalSize((*itBoxSet)); + itBoxSet++; + } + } else { + vector::const_iterator itBoxSet = boxSet->getSet().begin(); + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + (*it)->_setGlobalSize((*itBoxSet)); + itBoxSet++; + } + } + } +} + + + +void HVSlicingNode::preDestroy() +{ + SlicingNode::preDestroy(); + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + (*it)->removeParent(); + } +} + + +void HVSlicingNode::destroy() +{ + HVSlicingNode::preDestroy(); + delete(this); +} + + +void HVSlicingNode::preRecursiveDestroy() +{ + SlicingNode::preRecursiveDestroy(); + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->getType() == HorizontalSNode) || ((*it)->getType() == VerticalSNode) ){ + (*it)->removeParent(); + (*it)->recursiveDestroy(); + } else { + (*it)->removeParent(); + (*it)->destroy(); + } + } +} + + +void HVSlicingNode::recursiveDestroy() +{ + HVSlicingNode::preRecursiveDestroy(); + delete(this); +} + +void printList( list liste ) +{ + for ( list::const_iterator it = liste.begin(); it != liste.end(); it++ ){ + (*it)->print(); + } +} + +list HVSlicingNode::getLeaves () const +{ + list leaves = list(); + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->getType() == DeviceSNode) || ((*it)->getType() == RoutingSNode) ){ + leaves.push_back((*it)); + } else { + leaves.splice(leaves.end(), (*it)->getLeaves()); + } + } + return leaves; +} + + +bool HVSlicingNode::checkInitialPlacement( int& cpt ) const +{ +// -----------------------------------------------------------------------------------------------// +// Notes:: Initial placement criteria is having at least 2 devices placed at (x, y) = (0, 0) +// -----------------------------------------------------------------------------------------------// + + bool initialPlacement = false; + if (cpt < 2){ + initialPlacement = true; + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if (cpt < 2){ initialPlacement = (*it)->checkInitialPlacement(cpt); } + } + } + return initialPlacement; +} + + +bool HVSlicingNode::isSame( SlicingNode* node, unsigned int flags ) const +{ + if ( ( getType() == node->getType() ) + and ( getNbChild() == node->getNbChild() ) + and ( getToleranceBandH() == node->getToleranceBandH() ) + and ( getToleranceBandW() == node->getToleranceBandW() ) ) { + bool isSame = true; + + for ( size_t ichild = 0 ; isSame and (ichild < getNbChild()) ; ++ichild ) { + isSame = getChild(ichild)->isSame( node->getChild(ichild) ); + } + + if (not isSame and (flags & ShowDiff)) + cerr << "HVSlicingNode::isSame() " << this << " and " << node << " differs (childs)." << endl; + + return isSame; + } else { + if (flags & ShowDiff) + cerr << "HVSlicingNode::isSame() " << this << " and " << node << " differs." << endl; + return false; + } +} + + +/*bool HVSlicingNode::checkCellInstances ( Cell* cell ) +{ + if (cell) { + bool found = true; + for ( Instance* instance : cell->getInstances() ) { + if (not findInstance(instance)) { + found = false; + cerr << Warning( "HVSlicingNode::checkCellInstances() Instance \"%s\" is missing from the SlicingTree. " + , getString(instance->getName()).c_str() + ) << endl; + } + } + return found; + } + + return false; +}*/ +bool HVSlicingNode::checkCellInstances ( Cell* cell ) +{ + if (cell) { + bool found = true; + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if (not (*it)->checkCellInstances(cell)) found = false; + } + return found; + } else { + cerr << "HVSlicingNode::checkCellInstances() Cell is NULL. " << endl; + return false; + } +} + +SlicingNode* HVSlicingNode::findInstance( Instance* instance ) +{ + SlicingNode* node = NULL; + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if( ((*it)->getType() == HorizontalSNode) || ((*it)->getType() == VerticalSNode) ){ + SlicingNode* inode = (*it)->findInstance(instance); + if (inode != NULL){ node = inode; } + } else if ((*it)->getType() == DeviceSNode){ + if ( (*it)->getInstance() == instance ){ + node = (*it); + } + } + } + return node; +} + + + +SlicingNode* HVSlicingNode::findSlicingNode( Anabatic::GCell* gcell ) +{ + SlicingNode* node = NULL; + for (vector::iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); ++it){ + if ( (*it)->getGCell() == gcell ){ + node = (*it); + break; + } + } + + if (node == NULL){ + for (vector::const_iterator it = _children.begin(); it != _children.end(); ++it){ + if( ((*it)->getType() == HorizontalSNode) || ((*it)->getType() == VerticalSNode) ){ + SlicingNode* inode = (*it)->findSlicingNode(gcell); + if (inode != NULL){ node = inode; } + } else if ((*it)->getType() == DeviceSNode){ + if ( (*it)->getGCell() == gcell ){ + node = (*it); + break; + } + } + } + } + return node; +} + + +void HVSlicingNode::resetSlicingRouting() +{ + for (vector::iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); it++){ + (*it)->resetSize(); + } + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->getType() == HorizontalSNode)||((*it)->getType() == VerticalSNode) ){ + (*it)->resetSlicingRouting(); + } + } + this->setRoutingEstimated(0); +} + + +void HVSlicingNode::destroySlicingRouting() +{ + for (vector::iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); it++){ + (*it)->destroy(); + } + _slicingRouting.clear(); + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->getType() == HorizontalSNode)||((*it)->getType() == VerticalSNode) ){ + (*it)->destroySlicingRouting(); + } + } + this->setRoutingEstimated(0); +} + + +int HVSlicingNode::getRoutingIndex( SlicingNode* node ) const +{ + int i = 0; + vector::const_iterator it = _slicingRouting.begin(); + while (it != _slicingRouting.end()){ + if ( ((*it)->getHeight() == node->getHeight()) + && ((*it)->getWidth () == node->getWidth ()) + && ((*it)->getX() == node->getX() ) + && ((*it)->getY() == node->getY() ) + ) + { it = _slicingRouting.end(); } + else { + i++; + it++; + } + } + return i; +} + + +SlicingNode* HVSlicingNode::getSlicingRouting( int index ) const +{ + return (*(_slicingRouting.begin()+index)); +} + + +void HVSlicingNode::restrictDevices() +{ + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + (*it)->restrictDevices(); + } + for (std::vector::iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); it++){ + (*it)->restrictDevices(); + } +} + + +void HVSlicingNode::setVertexRestriction( Net* net, Katana::KatanaEngine* katana ) +{ + cdebug_log(536,1) << "HVSlicingNode::setVertexRestriction(Net*,KatanaEngine*)" << endl; + + this->restrictDevices(); + vector rps; + for ( RoutingPad* rp : net->getRoutingPads() ) rps.push_back( rp ); + for ( RoutingPad* rp : rps ) { + Box rpBb = rp->getBoundingBox(); + Point center = rpBb.getCenter(); + Anabatic::GCell* gcell = katana->getGCellUnder( center ); + + if (not gcell) { + cerr << Error( "Dijkstra::load(): %s of %s is not under any GCell.\n" + " It will be ignored ans the routing will be incomplete." + , getString(rp ).c_str() + , getString(net).c_str() + ) << endl; + continue; + } + + Anabatic::Vertex* vertex = gcell->getObserver(Anabatic::GCell::Observable::Vertex); + // Analog Restrictions + Plug* plug = dynamic_cast(rp->getPlugOccurrence().getEntity()); + Cell* cell = plug->getInstance()->getMasterCell(); + Device* device = dynamic_cast(cell); + + if (device){ + cdebug_log(536,0) << "Underlying device: " << device << endl; + + unsigned int rule = device->getRestrictions2(plug->getMasterNet()); + vertex->clearRestriction(); + + cdebug_log(536,0) << "Restrictions rule: " << rule << endl; + if (rule & WestBlocked ) vertex->setWRestricted(); + if (rule & EastBlocked ) vertex->setERestricted(); + if (rule & SouthBlocked) vertex->setSRestricted(); + if (rule & NorthBlocked) vertex->setNRestricted(); + cdebug_log(536,0) << "Applied restrictions: " << vertex << endl; + } else { + vertex->clearRestriction(); + } + } + + cdebug_tabw(536,-1); +} + + +void HVSlicingNode::estimateChannelsSize() +{ + for (std::vector::iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); it++){ + (*it)->estimateChannelsSize(); + } + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + (*it)->estimateChannelsSize(); + } +} + + +void HVSlicingNode::expandRoutingChannel() +{ + estimateChannelsSize(); + _expandRoutingChannel(); +} + + +void HVSlicingNode::_expandRoutingChannel() +{ + for ( RHVSlicingNode* node : _slicingRouting ) node->_expandRoutingChannel(); + for ( SlicingNode* node : _children ) { + if (node->getType() != RoutingSNode) node->_expandRoutingChannel(); + } + setRoutingEstimated(RoutingEstimated); + if (_parent == NULL) { + for ( SlicingNode* node : _children ) node->adjustBorderChannels(); + } +} + + +void HVSlicingNode::expandRoutingChannel( DbU::Unit height, DbU::Unit width ) +{ + for ( RHVSlicingNode* node : _slicingRouting ) node->expandRoutingChannel( height, width ); + for ( SlicingNode* node : _children ) { + if (node->getType() != RoutingSNode) node->expandRoutingChannel( height, width ); + } + setRoutingEstimated( RoutingEstimated ); + if (_parent == NULL) + for ( SlicingNode* node : _children ) node->adjustBorderChannels(); +} + + +bool HVSlicingNode::isRoutingEstimated() const +{ +//cerr << "bool HVSlicingNode::isRoutingEstimated() const" << endl; + bool estimated = true; + if (_slicingRouting.empty()){ + estimated = false; + } else { + for (std::vector::const_iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); it++){ + estimated &= (*it)->isRoutingEstimated(); + } + } + + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->getType() == HorizontalSNode ) || ((*it)->getType() == VerticalSNode) ){ + estimated &= (*it)->isRoutingEstimated(); + } + } + return estimated; +} + + +void HVSlicingNode::updateGCellPosition() +{ + cdebug_log(535,1) << "HVSlicingNode::updateGCellPosition()" << endl; + + for ( SlicingNode* node : _slicingRouting ) node->updateGCellPosition(); + for ( SlicingNode* node : _children ) node->updateGCellPosition(); + + cdebug_tabw(535,-1); +} + + +void HVSlicingNode::updateGContacts() +{ + cdebug_log(535,1) << "HVSlicingNode::updateGContacts()" << endl; + + for ( SlicingNode* node : _slicingRouting ) node->updateGContacts(); + for ( SlicingNode* node : _children ) node->updateGContacts(); + + cdebug_tabw(535,-1); +} + + +void HVSlicingNode::clearGCells() +{ + for (std::vector::const_iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); it++){ + (*it)->clearGCells(); + } + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + (*it)->clearGCells(); + } + _gcell = NULL; +} + + +int HVSlicingNode::getNbDevices () +{ + int nb = 0; + for ( SlicingNode* node : _children ){ + nb += node->getNbDevices(); + } + return nb; +} + + +string HVSlicingNode::_getString () const +{ + string s = Super::_getString(); + s.insert( s.size()-1, " childs:" + getString(_children.size()) ); + return s; +} + + +string HVSlicingNode::_getTypeName () const +{ return "HVSlicingNode"; } + + +void HVSlicingNode::setSymmetryFlag( unsigned int flag ) +{ + SlicingNode::setSymmetryFlag(flag); + for (std::vector::const_iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); it++){ + (*it)->setSymmetryFlag(flag); + } + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + (*it)->setSymmetryFlag(flag); + } +} + + +void HVSlicingNode::setMaster ( SlicingNode* master ) +{ + _master = master; + int index = 0; + + if ( ((getType() == HorizontalSNode) && (isHSymmetry())) + || ((getType() == VerticalSNode ) && (isVSymmetry())) + ){ + for (vector::reverse_iterator it = _children.rbegin(); it != _children.rend(); it++) { + (*it)->setMaster(master->getChild(index)); + index++; + } + } else { + for (vector::iterator it = _children.begin(); it != _children.end(); it++) { + (*it)->setMaster(master->getChild(index)); + index++; + } + } +} + + +bool HVSlicingNode::isSymmetric( SlicingNode* node, unsigned int symmetryType, unsigned int flags ) const +{ + if ( ( getType() == node->getType() ) + and ( getNbChild() == node->getNbChild() ) + and ( getToleranceBandH() == node->getToleranceBandH() ) + and ( getToleranceBandW() == node->getToleranceBandW() ) ) { + bool isSame = true; + + if ( ((getType() == HorizontalSNode) && (symmetryType == HSymmetry)) + || ((getType() == VerticalSNode ) && (symmetryType == VSymmetry)) + ){ + int i = 0; + for ( int ichild = (int) getNbChild()-1 ; isSame and (ichild > -1) ; --ichild ) { + isSame = getChild(i)->isSymmetric( node->getChild(ichild), symmetryType ); + i++; + } + } else { + for ( int ichild = 0 ; isSame and (ichild < (int) getNbChild()) ; ++ichild ) { + isSame = getChild(ichild)->isSymmetric( node->getChild(ichild), symmetryType ); + } + } + + if (not isSame and (flags & ShowDiff)) + cerr << "HVSlicingNode::isSame() " << this << " and " << node << " differs (childs)." << endl; + + return isSame; + } else { + if (flags & ShowDiff) + cerr << "HVSlicingNode::isSame() " << this << " and " << node << " differs." << endl; + return false; + } +} + + +bool HVSlicingNode::checkSymmetryNet( unsigned int type, Net* net1, Net* net2 ) const +{ +//cerr << "bool HVSlicingNode::checkSymmetryNet( unsigned int type, Net* net1, Net* net2 ) const" << endl; + bool b = false; + for ( vector >::const_iterator it = _netsymmetries.begin(); it != _netsymmetries.end(); ++it) { + if (get<1>((*it)) == net1){ + if (get<2>((*it)) == net2){ + if (get<0>((*it)) == type) { + b = true; + break; + } + } + } + } + return b; +} + + +void HVSlicingNode::addSymmetryNet( unsigned int type, Net* net1, Net* net2 ) +{ +//cerr << "void HVSlicingNode::addSymmetryNet( unsigned int type, Net* net1, Net* net2 )" << endl; + if (!checkSymmetryNet(type, net1, net2)){ + unsigned int ftype = type; + if (type == 1) ftype = NetRoutingState::Vertical; + else if (type == 2) ftype = NetRoutingState::Horizontal; + _netsymmetries.push_back(make_tuple(ftype, net1, net2)); + } else { + cerr << "Warning(void HVSlicingNode::addSymmetryNet( unsigned int type, Net* net1, Net* net2 )): Net symmetry already set." << endl; + } +} + + +void HVSlicingNode::updateNetConstraints() +{ +//cerr << "void void HVSlicingNode::updateNetConstraints()" << endl; + if (_cell != NULL){ + for ( vector >::const_iterator it = _netsymmetries.begin(); it != _netsymmetries.end(); ++it) { + if (get<2>((*it))){ + Net* masterNet = get<1>((*it)); + if (not masterNet) cerr << "void HVSlicingNode::updateNetConstraints() Net \"%s\" not found." << endl; + + NetRoutingState* masterState = NetRoutingExtension::get( masterNet ); + if (not masterState) masterState = NetRoutingExtension::create( masterNet ); + //cerr << "type: " << get<0>((*it)) << endl; + //cerr << "net1: " << get<1>((*it)) << endl; + //cerr << "net2: " << get<2>((*it)) << endl; + + masterState->setFlags ( NetRoutingState::AutomaticGlobalRoute + | NetRoutingState::Symmetric + | NetRoutingState::SymmetricMaster + | get<0>((*it)) ); + /*if (get<0>((*it)) == NetRoutingState::Vertical ) masterState->setSymAxis( getX() + getWidth ()/2 ); + else if (get<0>((*it)) == NetRoutingState::Horizontal) masterState->setSymAxis( getY() + getHeight()/2 ); + else cerr << "void HVSlicingNode::updateNetConstraints(): Wrong axis for Net \"%s\"." << endl;*/ + + Net* slaveNet = get<2>((*it)); + if (not slaveNet) cerr << "void HVSlicingNode::updateNetConstraints() Net \"%s\" not found." << endl; + + NetRoutingState* slaveState = NetRoutingExtension::get( slaveNet ); + if (not slaveState) slaveState = NetRoutingExtension::create( slaveNet ); + + slaveState ->setFlags ( NetRoutingState::AutomaticGlobalRoute + | NetRoutingState::Symmetric + | get<0>((*it)) ); + /*if (get<0>((*it)) == NetRoutingState::Vertical ) slaveState->setSymAxis( getX() + getWidth ()/2 ); + else if (get<0>((*it)) == NetRoutingState::Horizontal) slaveState->setSymAxis( getY() + getHeight()/2 ); + else cerr << "void HVSlicingNode::updateNetConstraints(): Wrong axis for Net \"%s\"." << endl;*/ + slaveState ->setSymNet ( masterNet ); + masterState->setSymNet ( slaveNet ); + + //cerr << "masterState: " << masterState << endl; + //cerr << "slaveState : " << slaveState << endl; + } else { + Net* net = get<1>((*it)); + if (not net) cerr << "void HVSlicingNode::updateNetConstraints() Net \"%s\" not found." << endl; + + NetRoutingState* state = NetRoutingExtension::get( net ); + if (not state) state = NetRoutingExtension::create( net ); + + state->setFlags ( NetRoutingState::AutomaticGlobalRoute + | NetRoutingState::Symmetric + | get<0>((*it)) ); + //cerr << "state: " << state << endl; + /*if (get<0>((*it)) == NetRoutingState::Vertical ) state->setSymAxis( getX() + getWidth ()/2 ); + else if (get<0>((*it)) == NetRoutingState::Horizontal) state->setSymAxis( getY() + getHeight()/2 ); + else cerr << "void HVSlicingNode::updateNetConstraints(): Wrong axis for Net \"%s\"." << endl;*/ + } + } + for (vector::iterator it = _children.begin(); it != _children.end(); ++it){ + if (((*it)->getType() == HorizontalSNode)||((*it)->getType() == VerticalSNode)) (*it)->updateNetConstraints(); + } + } else { + cerr << "Error(void HVSlicingNode::updateNetConstraints()): Cell undefined." << endl; + } +} + + +void HVSlicingNode::updateSymNetAxis() +{ +//cerr << "void HVSlicingNode::updateSymNetAxis()" << endl; + if (_cell != NULL){ + for ( const tuple triplet : _netsymmetries ) { + + + SlicingNode* n1 = getChild(_symmetries.front().first); + SlicingNode* n2 = getChild(_symmetries.front().second); + DbU::Unit xCenter = (n1->getX() + n2->getX() + n2->getWidth())/2; + DbU::Unit yCenter = (n1->getY() + n2->getY() + n2->getHeight())/2; + if (get<2>(triplet)){ + Net* masterNet = get<1>(triplet); + if (not masterNet) cerr << "void HVSlicingNode::updateSymNetAxis() Net \"%s\" not found." << endl; + + NetRoutingState* masterState = NetRoutingExtension::get( masterNet ); + if (not masterState) cerr << "void HVSlicingNode::updateSymNetAxis(): UpdateNetConstraint need to be used first." << endl; + + if (get<0>(triplet) == NetRoutingState::Vertical ) masterState->setSymAxis( xCenter );//getXCenter() ); + else if (get<0>(triplet) == NetRoutingState::Horizontal) masterState->setSymAxis( yCenter );//getYCenter() ); + else cerr << "void HVSlicingNode::updateSymNetAxis(): Unknown NetRoutingState type." << endl; + + Net* slaveNet = get<2>(triplet); + if (not slaveNet) cerr << "void HVSlicingNode::updateSymNetAxis() Net \"%s\" not found." << endl; + + NetRoutingState* slaveState = NetRoutingExtension::get( slaveNet ); + if (not slaveState) cerr << "void HVSlicingNode::updateSymNetAxis(): updateSymNetAxis need to be used first." << endl; + + if (get<0>(triplet) == NetRoutingState::Vertical ) slaveState->setSymAxis( xCenter );//getXCenter() ); + else if (get<0>(triplet) == NetRoutingState::Horizontal) slaveState->setSymAxis( yCenter );//getYCenter() ); + else cerr << "void HVSlicingNode::updateSymNetAxis(): Unknown NetRoutingState type." << endl; + + //cerr << "Master net: " << masterNet << ", state: " << masterState << ", axis: " << DbU::getValueString(masterState->getSymAxis())<< endl; + //cerr << "Slave net: " << slaveNet << ", state: " << slaveState << ", axis: " << DbU::getValueString(slaveState->getSymAxis())<< endl; + } else { + + + /* + if ( getType() == HorizontalSNode ) { + if ( !checkSelfSymH (get<1>(triplet)) ) { + cerr << Error( "SlicingNode::HVSlicingNode::updateSymNetAxis(): Net %s is not self symmetric.", getString(get<1>(triplet)).c_str() ) << endl; + } + } else if ( getType() == VerticalSNode ) { + if ( !checkSelfSymV (get<1>(triplet)) ) { + cerr << Error( "SlicingNode::HVSlicingNode::updateSymNetAxis(): Net %s is not self symmetric.", getString(get<1>(triplet)).c_str() ) << endl; + } + } */ + + Net* net = get<1>(triplet); + if (not net) cerr << "void HVSlicingNode::updateSymNetAxis() Net not found." << endl; + + NetRoutingState* state = NetRoutingExtension::get( net ); + if (not state) cerr << "void HVSlicingNode::updateSymNetAxis(): UpdateNetConstraint need to be used first." << endl; + + if (get<0>(triplet) == NetRoutingState::Vertical ){ + //cerr << "case Vertical" << endl ; + state->setSymAxis( xCenter );//getXCenter() ); + } + else if (get<0>(triplet) == NetRoutingState::Horizontal) { + //cerr << "case Horizontal" << endl ; + state->setSymAxis( yCenter );//getYCenter() ); + } + + + + + else cerr << "void HVSlicingNode::updateSymNetAxis(): Unknown NetRoutingState type." << endl; + //cerr << "Master Only net: " << net << ", state: " << state << ", axis: " << DbU::getValueString(state->getSymAxis())<< endl; + } + } + for ( SlicingNode* child : _children ) { + if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) + child->updateSymNetAxis(); + } + } else { + cerr << "Error(void HVSlicingNode::updateSymNetAxis()): Cell undefined." << endl; + } +} + + +void HVSlicingNode::flattenDigitalNets () +{ + if (_cell != NULL){ + for (vector::iterator it = _children.begin(); it != _children.end(); ++it){ + if (((*it)->getType() == HorizontalSNode)||((*it)->getType() == VerticalSNode)){ + (*it)->flattenDigitalNets(); + } else if ((*it)->getType() == DeviceSNode){ + if ( ((*it)->getGCell() != NULL) && ((*it)->getInstance() != NULL) ){ + if ( (*it)->getGCell()->isMatrix() ) { + //cerr << "FLATTEN NETS: " << (*it)->getInstance() << endl; + _cell->flattenNets( (*it)->getInstance(), Cell::Flags::BuildRings|Cell::Flags::WarnOnUnplacedInstances ); + } + } + } + } + } else { + cerr << "Error(void HVSlicingNode::flattenDigitalNets()): Cell not found." << endl; + } +} + + +void HVSlicingNode::updateWireOccupation ( Anabatic::VertexSet sources ) +{ +//cerr << "void HVSlicingNode::updateWireOccupation ( Anabatic::VertexSet sources )" << endl; + if (_parent == NULL){ + //Anabatic::Vertex* ivertex = NULL; + for ( Anabatic::Vertex* ivertex : sources ) { + Anabatic::GCell* igcell = ivertex->getGCell(); + SlicingNode* snode = findSlicingNode(igcell); + if (snode){ + if((snode->getType() == RoutingSNode)&& ivertex->hasAData()){ + //cerr << "ivertex:" << ivertex << ", min:" << DbU::getPhysical(ivertex->getIMin(), DbU::Micro) << ", max:" << DbU::getPhysical(ivertex->getIMax(), DbU::Micro) << endl; + snode->addWireOccupation( ivertex->getIMin() + , ivertex->getIMax() + ); + } + } + } + } +//cerr << "" << endl; +} + +void HVSlicingNode::resetWireOccupation () +{ + for (std::vector::const_iterator it = _slicingRouting.begin(); it != _slicingRouting.end(); ++it){ + (*it)->resetWireOccupation(); + } + + for (vector::iterator it = _children.begin(); it != _children.end(); ++it){ + if ((*it)->getType() != DeviceSNode) (*it)->resetWireOccupation(); + } +} +// -----------------------------------------------------------------------------------------------// +// Class : HSlicingNode +// -----------------------------------------------------------------------------------------------// + + +int HSlicingNode::_count = 0; +int HSlicingNode::_countAll = 0; + + +HSlicingNode::HSlicingNode( unsigned int type, unsigned int alignment ): HVSlicingNode( type, alignment ){} + + +HSlicingNode::~HSlicingNode(){} + + +HSlicingNode* HSlicingNode::create( unsigned int alignment ) +{ + _count++; + _countAll++; + return new HSlicingNode( HorizontalSNode, alignment ); +} + + +void HSlicingNode::createRouting( DbU::Unit space ) +{ + this->push_back(RHSlicingNode::create( space )); + resetSlicingTree(); +} + + +void HSlicingNode::print() const +{ + cerr << "- Print from Slicing Node - " << endl; + cerr << "SlicingType: Horizontal Node" << endl; + if (this->isAlignLeft ()){ cerr << "Alignment : Left" << endl; } + else if (this->isAlignCenter()){ cerr << "Alignment : Middle" << endl; } + else if (this->isAlignRight ()){ cerr << "Alignment : Right" << endl; } + else { cerr << "Alignment : Unknown" << endl; } + cerr << "Tolerances : RatioH: " << DbU::getPhysical(_toleranceRatioH,DbU::Micro) << ", RatioW: " << DbU::getPhysical(_toleranceRatioW,DbU::Micro) << ", BandH: " << DbU::getPhysical(_toleranceBandH,DbU::Micro) << ", BandW: " << DbU::getPhysical(_toleranceBandW,DbU::Micro) << endl; + HVSlicingNode::print(); +} + + +HSlicingNode* HSlicingNode::clone( unsigned int tr ) +{ + HSlicingNode* node = HSlicingNode::create( this->getAlignment() ); + node->setTolerances( getToleranceRatioH() + , getToleranceRatioW() + , getToleranceBandH() + , getToleranceBandW() + ); + node->setBoxSet ( getBoxSet() ); + node->setNodeSets ( _nodeSets->clone() ); + node->setPreset ( this->getPreset() ); + node->setSet ( this->getSet() ); + node->setPlaced ( this->getPlaced() ); + node->setSymmetries( this->getSymmetries() ); + + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + if (tr == MY){ node->push_front((*it)->clone(tr)); } + else { node->push_back ((*it)->clone(tr)); } + } + return node; +} + + +void HSlicingNode::place( DbU::Unit x, DbU::Unit y ) +{ + if( recursiveCheckSet() ){ + if (!_slicingRouting.empty()) { + this->destroySlicingRouting(); + this->resetSlicingRouting(); + } + this->_place(x,y); + if (_slicingRouting.empty()) { + this->createSlicingRouting(); + } + this->updateCellAbutmentBox(); + } else { cerr << "Error(void HSlicingNode::place( DbU::Unit x, DbU::Unit y )): The SlicingTree is not completely set." << endl; } +} + + +void HSlicingNode::replace( DbU::Unit x, DbU::Unit y ) +{ +// WARNING: This will change GCell edges. + if (recursiveCheckSet()) { + _place( x, y, true ); + updateCellAbutmentBox(); + updateGCellPosition(); + updateGContacts(); + } else { + cerr << Error( "void HSlicingNode::replace(DbU::Unit,DbU::Unit)): The SlicingTree is not completely set." ) << endl; + } +} + + +void HSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace ) +{ + cdebug_log(536,1) << "void HSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace )" << endl; + vector::iterator itspace = _slicingRouting.begin(); + DbU::Unit xref = x; + DbU::Unit yref = y; + + if (isRoutingEstimated()){ + (*itspace)->_place(xref, yref, replace); + yref += (*itspace)->getHeight(); + itspace++; + } + + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->isHorizontal()) || ((*it)->isVertical()) ){ + if ( (*it)->isAlignLeft() ){ + (*it)->setX(xref); + (*it)->setY(yref); + } + else if ( (*it)->isAlignCenter() ){ + (*it)->setX(xref + (this->getWidth()/2) - ((*it)->getWidth()/2)); + (*it)->setY(yref); + } + else if ( (*it)->isAlignRight() ){ + (*it)->setX(xref + this->getWidth() - (*it)->getWidth()); + (*it)->setY(yref); + } + } + + if ( (*it)->isAlignLeft() ) { (*it)->_place(xref , yref, replace); } + else if ( (*it)->isAlignCenter() ) { (*it)->_place(xref + (this->getWidth()/2) - ((*it)->getWidth()/2), yref, replace); } + else if ( (*it)->isAlignRight() ) { (*it)->_place(xref + this->getWidth() - (*it)->getWidth() , yref, replace); } + else if ( (*it)->isRouting() ) { (*it)->_place(xref , yref, replace); } + else { + cerr << "Error(_place( DbU::Unit x, DbU::Unit y )): Unknown Alignment in SlicingTree." << endl ; + (*it)->print(); + } + + xref = x; + yref += (*it)->getHeight(); + if (isRoutingEstimated()){ + (*itspace)->_place(xref, yref, replace); + yref += (*itspace)->getHeight(); + itspace++; + } + } + setPlaced(Placed); + cdebug_tabw(536,-1); +} + + +void HSlicingNode::updateGlobalSize() +{ + cdebug_log(535,1) << "HSlicingNode::updateGlobalsize()" << endl; + + for (vector::iterator it = _children.begin(); it != _children.end(); it++) { + (*it)->updateGlobalSize(); + } + + if (this->getMaster() == NULL) { + if (this->getNbChild() == 1){ + _nodeSets->clear(); + NodeSets* node = _children[0]->getNodeSets(); + for(vector::const_iterator it2 = node->begin(); it2 != node->end(); it2++){ + vector vect = vector(); + vect.push_back((*it2)); + DbU::Unit height = (*it2)->getHeight(); + DbU::Unit width = (*it2)->getWidth(); + _nodeSets->push_back(vect, height, width, HorizontalSNode); + } + } + else if ( (this->hasEmptyChildrenNodeSets() != true) && (_nodeSets->empty() == true) ){ + + HSetState state = HSetState(this); + while( !state.end() ){ state.next(); } + + _nodeSets = state.getNodeSets(); + } + if (_nodeSets->empty()){ cerr << "Error(void HSlicingNode::updateGlobalSize()): No solution has been found. Try to set larger tolerances." << endl; } + } else { + _nodeSets = _master->getNodeSets(); + } + + cdebug_tabw(535,-1); +} + + +void HSlicingNode::preDestroy() +{ + _count--; + HVSlicingNode::preDestroy(); +} + + +void HSlicingNode::destroy() +{ + HSlicingNode::preDestroy(); + delete(this); +} + + +void HSlicingNode::preRecursiveDestroy() +{ + _count--; + HVSlicingNode::preRecursiveDestroy(); +} + + +void HSlicingNode::recursiveDestroy() +{ + HSlicingNode::preRecursiveDestroy(); + delete(this); +} + + +OpenChams::SlicingNode* HSlicingNode::toOpenChams() +{ + OpenChams::SlicingNode* hnode = OpenChams::HSlicingNode::create(); + if ( isAlignLeft() ){ hnode->setAlignment( "AlignLeft" ); } + else if ( isAlignRight() ){ hnode->setAlignment( "AlignRight" ); } + else if ( isAlignCenter() ){ hnode->setAlignment( "AlignCenter" ); } + else if ( isAlignTop() ){ hnode->setAlignment( "AlignTop" ); } + else if ( isAlignBottom() ){ hnode->setAlignment( "AlignBottom" ); } + else { hnode->setAlignment( "UnknownAlignment"); } + + hnode->setToleranceRatioH(_toleranceRatioH); + hnode->setToleranceRatioW(_toleranceRatioW); + hnode->setToleranceBandH(_toleranceBandH); + hnode->setToleranceBandW(_toleranceBandW); + + if (!_symmetries.empty()){ + for (list >::const_iterator it = _symmetries.begin(); it != _symmetries.end(); it++){ + hnode->addSymmetry((*it).first, (*it).second); + } + } + + for (vector::iterator it2 = _children.begin(); it2 != _children.end(); it2++){ + hnode->push_back( (*it2)->toOpenChams() ); + } + + return hnode; +} + + +void HSlicingNode::createSlicingRouting() // Needs to be change in case of not alternative H/V +{ + if (_boxSet){ + int numberChildren = getNbChild(); + vector::iterator it1 = _children.begin(); + DbU::Unit x = this->getX(); + DbU::Unit y = this->getY(); + + DbU::Unit heightValue = 0; + if ( _parent ){ + if ( _parent->getType() == VerticalSNode ){ + if ( (this->getAlignment() == AlignBottom) || (this->getAlignment() == AlignTop) ){ + heightValue = _parent->getHeight() - this->getHeight(); + } else if ( this->getAlignment() == AlignCenter ){ + heightValue = (_parent->getHeight() - this->getHeight())/2; + } + } + } + + DbU::Unit hpitch = _rg->getHorizontalPitch(); + if (heightValue % hpitch) + cerr << Warning( "HSlicingNode::createSlicingRouting(): On %s, height is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(heightValue).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; + + for (int i = 0; i < numberChildren+1; ++i){ + RHSlicingNode* rnode = NULL; + if ( i == 0 ){ + if ( (this->getAlignment() == AlignTop) || (this->getAlignment() == AlignCenter) ){ + rnode = RHSlicingNode::create( heightValue ); + } else { + rnode = RHSlicingNode::create(); + } + } else if ( i == numberChildren ){ + if ( (this->getAlignment() == AlignBottom) || (this->getAlignment() == AlignCenter) ){ + rnode = RHSlicingNode::create( heightValue ); + } else { + rnode = RHSlicingNode::create(); + } + } else { + rnode = RHSlicingNode::create(); + } + rnode->setParent(this); + + if (i == 0){ + if ( this->getAlignment() == AlignBottom ){ + rnode->place(x, y); + } else if ( (this->getAlignment() == AlignCenter) || (this->getAlignment() == AlignTop)) { + rnode->place(x, y-heightValue); + } + } else { + rnode->place(x, y); + } + + if (_master){ + rnode->setMaster(_master->getSlicingRouting(i)); + } + _slicingRouting.push_back(rnode); + + if (i < numberChildren){ + y += (*it1)->getHeight(); + it1++; + } + } + + if (_master){ + if (isHSymmetry()){ + for (size_t i = 0; i < _slicingRouting.size(); i++){ + getSlicingRouting(i)->setMaster(_master->getSlicingRouting(_slicingRouting.size()-1-i)); + } + } else { + for (size_t i = 0; i < _slicingRouting.size(); i++){ + getSlicingRouting(i)->setMaster(_master->getSlicingRouting(i)); + } + } + } else if ((_symmetries.empty() == false)&&(isAlignCenter())){ + for (size_t i = 0; i < (_slicingRouting.size()/2); i++){ + getSlicingRouting(_slicingRouting.size()-1-i)->setMaster(getSlicingRouting(i)); + } + } + + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->isHorizontal()) || ((*it)->isVertical()) ){ + (*it)->createSlicingRouting(); + } + } + + this->setRoutingCreated(RoutingCreated); + } else { + cerr << "Error(void HSlicingNode::createSlicingRouting()): SlicingTree needs to be placed first." << endl; + } +} + + +DbU::Unit HSlicingNode::getHeight () const +{ + DbU::Unit hpitch = _rg->getHorizontalPitch(); + DbU::Unit height = 0; + + if (isRoutingEstimated()){ + for ( SlicingNode* node : _children ) height += node->getHeight(); + for ( RHVSlicingNode* node : _slicingRouting ) height += node->getHeight(); + } else { + if (_boxSet != NULL) height = _boxSet->getHeight(); + } + + if (height % hpitch) + cerr << Warning( "HSlicingNode::getHeight(): On %s, height is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(height).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; + return height; +} + + +DbU::Unit HSlicingNode::getWidth () const +{ +//cdebug_log(536,0) << "DbU::Unit HSlicingNode::getWidth () const " << endl; + + DbU::Unit vpitch = _rg->getVerticalPitch(); + DbU::Unit width = 0; + + if (isRoutingEstimated()) { + SlicingNode* m = NULL; + for ( SlicingNode* node : _children ) { + if ( (node->getType() != RoutingSNode) and (node->getWidth() > width) ) { + width = node->getWidth(); + m = node; + } + } + if (m->isDevice()) width += vpitch*2; + } else { + //cdebug_log(536,0) << "case is routing not estimated" << endl; + if (_boxSet != NULL) width = _boxSet->getWidth(); + } + + if (width % vpitch) + cerr << Warning( "HSlicingNode::getWidth(): On %s, width is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(width).c_str() + , DbU::getValueString(vpitch).c_str() + ) << endl; + return width; +} + + +void HSlicingNode::setGCell ( Anabatic::GCell* gcell ) +{ + Anabatic::GCell* prevGCell = gcell; + Anabatic::GCell* nextGCell = NULL; + vector::const_iterator itc = _children.begin(); + vector::const_iterator its = _slicingRouting.begin(); + cdebug_log(535,1) << "HSlicingNode::setGCell(Anabatic::GCell*), start Y: "<< (*its)->getY() << ", GCell:" << gcell << endl; + int index = 0; + DbU::Unit y = (*its)->getY(); + + while ( not ((itc == _children.end()) and (its+1 == _slicingRouting.end())) ) { + if (index%2 == 0) { + y += (*its)->getHeight(); + nextGCell = prevGCell->hcut( y ); + (*its)->setGCell( prevGCell ); + its++; + } else { + y += (*itc)->getHeight(); + nextGCell = prevGCell->hcut( y ); + (*itc)->setGCell( prevGCell ); + itc++; + } + prevGCell = nextGCell; + index++; + } + (*its)->setGCell( prevGCell ); + + cdebug_tabw(535,-1); +} + + +void HSlicingNode::adjustBorderChannels () +{ + if (_parent){ + if (_parent->getHeight() > getHeight()){ + DbU::Unit space = _parent->getHeight() - getHeight(); + + if ( this->getAlignment() == AlignTop ){ + RHVSlicingNode* ch = (*_slicingRouting.begin()); + ch->setHeight(ch->getHeight()+space); + + + } else if ( this->getAlignment() == AlignCenter ){ + RHVSlicingNode* chf = (*_slicingRouting.begin()); + RHVSlicingNode* chl = (*(_slicingRouting.end()-1)); + chf->setHeight(chf->getHeight()+space/2); + chl->setHeight(chl->getHeight()+space/2); + + } else if ( this->getAlignment() == AlignBottom ){ + RHVSlicingNode* ch = (*(_slicingRouting.end()-1)); + ch->setHeight(ch->getHeight()+space); + + } + } + } + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + (*it)->adjustBorderChannels(); + } +} + + +string HSlicingNode::_getString () const +{ + string s = Super::_getString(); + return s; +} + + +string HSlicingNode::_getTypeName () const +{ return "HSlicingNode"; } + + +// -----------------------------------------------------------------------------------------------// +// Class : VSlicingNode +// -----------------------------------------------------------------------------------------------// + + +int VSlicingNode::_count = 0; +int VSlicingNode::_countAll = 0; + + +VSlicingNode::VSlicingNode( unsigned int type, unsigned int alignment ): HVSlicingNode( type, alignment ){} + + +VSlicingNode::~VSlicingNode(){} + + +VSlicingNode* VSlicingNode::create( unsigned int alignment ) +{ + _count++; + _countAll++; + return new VSlicingNode( VerticalSNode, alignment ); +} + + +void VSlicingNode::createRouting( DbU::Unit space ) +{ + this->push_back(RVSlicingNode::create( space )); + resetSlicingTree(); +} + + +void VSlicingNode::print() const +{ + cerr << "- Print from Slicing Node - " << endl; + cerr << "SlicingType: Vertical Node" << endl; + if (this->isAlignBottom()){ cerr << "Alignment : Bottom" << endl; } + else if (this->isAlignCenter()){ cerr << "Alignment : Middle" << endl; } + else if (this->isAlignTop ()){ cerr << "Alignment : Top" << endl; } + else { cerr << "Alignment : Unknown" << endl; } + cerr << "Tolerances : RatioH: " << DbU::getPhysical(_toleranceRatioH,DbU::Micro) << ", RatioW: " << DbU::getPhysical(_toleranceRatioW,DbU::Micro) << ", BandH: " << DbU::getPhysical(_toleranceBandH,DbU::Micro) << ", BandW: " << DbU::getPhysical(_toleranceBandW,DbU::Micro) << endl; + HVSlicingNode::print(); +} + + +VSlicingNode* VSlicingNode::clone( unsigned int tr ) +{ + VSlicingNode* node = VSlicingNode::create( this->getAlignment() ); + node->setTolerances( getToleranceRatioH() + , getToleranceRatioW() + , getToleranceBandH() + , getToleranceBandW() + ); + node->setBoxSet ( getBoxSet() ); + node->setNodeSets ( _nodeSets->clone() ); + node->setPreset ( this->getPreset() ); + node->setSet ( this->getSet() ); + node->setPlaced ( this->getPlaced() ); + node->setSymmetries( this->getSymmetries() ); + + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + if (tr == MX){ node->push_front((*it)->clone(tr)); } + else { node->push_back ((*it)->clone(tr)); } + } + return node; +} + + +void VSlicingNode::place( DbU::Unit x, DbU::Unit y ) +{ + if (recursiveCheckSet()){ + if (!_slicingRouting.empty()) { + this->destroySlicingRouting(); + this->resetSlicingRouting(); + } + this->_place(x,y); + if (_slicingRouting.empty()) { + this->createSlicingRouting(); + } + this->updateCellAbutmentBox(); + } else { cerr << "Error(void VSlicingNode::place( DbU::Unit x, DbU::Unit y )): The SlicingTree is not completely set." << endl; } +} + + +void VSlicingNode::replace( DbU::Unit x, DbU::Unit y ) +{ +// WARNING: This will change GCell edges. + if (recursiveCheckSet()) { + _place( x, y, true ); + updateCellAbutmentBox(); + updateGCellPosition(); + updateGContacts(); + } else { + cerr << Error( "HVlicingNode::place(DbU::Unit,DbU::Unit)): The SlicingTree is not completely set." ) << endl; + } +} + + +void VSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace ) +{ + cdebug_log(536,1) << "void VSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace )" << endl; +//printLine(); + vector::iterator itspace = _slicingRouting.begin(); + DbU::Unit xref = x; + DbU::Unit yref = y; + + if (isRoutingEstimated()){ + (*itspace)->_place(xref, yref, replace); + xref += (*itspace)->getWidth(); + itspace++; + } + + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + if ( ( (*it)->isHorizontal()) || ((*it)->isVertical()) ){ + if ( (*it)->isAlignBottom() ){ + (*it)->setX(xref); + (*it)->setY(yref); + } + else if ( (*it)->isAlignCenter() ){ + (*it)->setX(xref); + (*it)->setY(yref + (this->getHeight()/2) - ((*it)->getHeight()/2)); + } + else if ( (*it)->isAlignTop() ){ + (*it)->setX(xref); + (*it)->setY(yref + this->getHeight() - (*it)->getHeight()); + } + } + + if ( (*it)->isAlignBottom() ) { (*it)->_place(xref, yref , replace); } + else if ( (*it)->isAlignCenter() ) { (*it)->_place(xref, yref + (this->getHeight()/2) - ((*it)->getHeight()/2), replace); } + else if ( (*it)->isAlignTop() ) { (*it)->_place(xref, yref + this->getHeight() - (*it)->getHeight() , replace); } + else if ( (*it)->isRouting() ) { (*it)->_place(xref, yref , replace); } + else { + cerr << " Error(void place( DbU::Unit x, DbU::Unit y )): Unknown Alignment in SlicingTree." << endl ; + (*it)->print(); + } + + xref += (*it)->getWidth(); + yref = y; + if (isRoutingEstimated()){ + (*itspace)->_place(xref, yref, replace); + xref += (*itspace)->getWidth(); + itspace++; + } + } + setPlaced(Placed); + cdebug_tabw(536,-1); +} + + +void VSlicingNode::updateGlobalSize() +{ + cdebug_log(535,1) << "HSlicingNode::updateGlobalsize()" << endl; + + for (vector::iterator it = _children.begin(); it != _children.end(); it++) { + (*it)->updateGlobalSize(); + } + + if (this->getMaster() == NULL) { + if (this->getNbChild() == 1){ + _nodeSets->clear(); + NodeSets* node = _children[0]->getNodeSets(); + for(vector::const_iterator it2 = node->begin(); it2 != node->end(); it2++){ + vector vect = vector(); + vect.push_back((*it2)); + DbU::Unit height = (*it2)->getHeight(); + DbU::Unit width = (*it2)->getWidth(); + _nodeSets->push_back(vect, height, width, VerticalSNode); + } + } + else if ( (this->hasEmptyChildrenNodeSets() != true) && (_nodeSets->empty() == true) ){ + + VSetState state = VSetState(this); + while( !state.end() ){ state.next(); } + + _nodeSets = state.getNodeSets(); + } + if (_nodeSets->empty()) { cerr << "Error(void VSlicingNode::updateGlobalSize()): No solution has been found. Try to set larger tolerances." << endl; } + } else { + _nodeSets = _master->getNodeSets(); + } + + cdebug_tabw(535,-1); +} + + +void VSlicingNode::preDestroy() +{ + _count--; + HVSlicingNode::preDestroy(); +} + + +void VSlicingNode::destroy() +{ + VSlicingNode::preDestroy(); + delete(this); +} + + +void VSlicingNode::preRecursiveDestroy() +{ + _count--; + HVSlicingNode::preRecursiveDestroy(); +} + + +void VSlicingNode::recursiveDestroy() +{ + VSlicingNode::preRecursiveDestroy(); + delete(this); +} + + +OpenChams::SlicingNode* VSlicingNode::toOpenChams() +{ + OpenChams::SlicingNode* vnode = OpenChams::VSlicingNode::create(); + if ( isAlignLeft() ){ vnode->setAlignment( "AlignLeft" ); } + else if ( isAlignRight() ){ vnode->setAlignment( "AlignRight" ); } + else if ( isAlignCenter() ){ vnode->setAlignment( "AlignCenter" ); } + else if ( isAlignTop() ){ vnode->setAlignment( "AlignTop" ); } + else if ( isAlignBottom() ){ vnode->setAlignment( "AlignBottom" ); } + else { vnode->setAlignment( "UnknownAlignment"); } + + vnode->setToleranceRatioH(_toleranceRatioH); + vnode->setToleranceRatioW(_toleranceRatioW); + vnode->setToleranceBandH(_toleranceBandH); + vnode->setToleranceBandW(_toleranceBandW); + + if (!_symmetries.empty()){ + for (list >::const_iterator it = _symmetries.begin(); it != _symmetries.end(); it++){ + vnode->addSymmetry((*it).first, (*it).second); + } + } + + for (vector::iterator it2 = _children.begin(); it2 != _children.end(); it2++){ + vnode->push_back( (*it2)->toOpenChams() ); + } + + return vnode; +} + + +void VSlicingNode::createSlicingRouting() // Needs to be change in case of not alternative H/V +{ + if ( isPlaced() ){ + int numberChildren = getNbChild(); + vector::iterator it1 = _children.begin(); + DbU::Unit x = this->getX(); + DbU::Unit y = this->getY(); + + + DbU::Unit widthValue = 0; + if (_parent){ + if ( _parent->getType() == HorizontalSNode ){ + if ( (this->getAlignment() == AlignLeft) || (this->getAlignment() == AlignRight) ){ + widthValue = _parent->getWidth() - this->getWidth(); + } else if ( this->getAlignment() == AlignCenter ){ + widthValue = (_parent->getWidth() - this->getWidth())/2; + } + } + } + + DbU::Unit vpitch = _rg->getVerticalPitch(); + if (widthValue % vpitch) + cerr << Warning( "VSlicingNode::createSlicingRouting(): On %s, width is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(widthValue).c_str() + , DbU::getValueString(vpitch).c_str() + ) << endl; + + for (int i = 0; i < numberChildren+1; ++i){ + RVSlicingNode* rnode = NULL; + if ( i == 0 ){ + if ( (this->getAlignment() == AlignRight) || (this->getAlignment() == AlignCenter) ){ + rnode = RVSlicingNode::create( widthValue ); + } else { + rnode = RVSlicingNode::create(); + } + } else if ( i == numberChildren ){ + if ( (this->getAlignment() == AlignLeft) || (this->getAlignment() == AlignCenter) ){ + rnode = RVSlicingNode::create( widthValue ); + } else { + rnode = RVSlicingNode::create(); + } + } else { + rnode = RVSlicingNode::create(); + } + rnode->setParent(this); + + if (i == 0){ + if ( this->getAlignment() == AlignLeft ){ + rnode->place(x, y); + } else if ( (this->getAlignment() == AlignCenter) || (this->getAlignment() == AlignRight)) { + rnode->place(x-widthValue, y); + } + } else { + rnode->place(x, y); + } + _slicingRouting.push_back(rnode); + + if (i < numberChildren){ + x += (*it1)->getWidth(); + it1++; + } + } + + if (_master){ + if (isVSymmetry()){ + for (size_t i = 0; i < _slicingRouting.size(); i++){ + getSlicingRouting(i)->setMaster(_master->getSlicingRouting(_slicingRouting.size()-1-i)); + } + } else { + for (size_t i = 0; i < _slicingRouting.size(); i++){ + getSlicingRouting(i)->setMaster(_master->getSlicingRouting(i)); + } + } + } else if ((_symmetries.empty() == false)&&(isAlignCenter())){ + for (size_t i = 0; i < (_slicingRouting.size()/2); i++){ + getSlicingRouting(_slicingRouting.size()-1-i)->setMaster(getSlicingRouting(i)); + } + } + + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->isHorizontal()) || ((*it)->isVertical()) ){ + (*it)->createSlicingRouting(); + } + } + this->setRoutingCreated(RoutingCreated); + } +} + + +DbU::Unit VSlicingNode::getWidth () const +{ + DbU::Unit vpitch = _rg->getVerticalPitch(); + DbU::Unit width = 0; + + if (isRoutingEstimated()){ + for ( SlicingNode* node : _children ) width += node->getWidth(); + for ( RHVSlicingNode* node : _slicingRouting ) width += node->getWidth(); + } else { + if (_boxSet != NULL) width = _boxSet->getWidth(); + } + + if (width % vpitch) + cerr << Warning( "VSlicingNode::getWidth(): On %s, width is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(width).c_str() + , DbU::getValueString(vpitch).c_str() + ) << endl; + return width; +} + + +DbU::Unit VSlicingNode::getHeight () const +{ + DbU::Unit hpitch = _rg->getHorizontalPitch(); + DbU::Unit height = 0; + + if (isRoutingEstimated()) { + SlicingNode* m = NULL; + for ( SlicingNode* node : _children ) { + if (node->getType() != RoutingSNode) { + if (node->getHeight() > height) { + height = node->getHeight(); + m = node; + } + } + } + if (m->isDevice()) height += hpitch*2; + } else { + if (_boxSet != NULL) height = _boxSet->getHeight(); + } + + if (height % hpitch) + cerr << Warning( "VSlicingNode::getHeight(): On %s, height is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(height).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; + return height; +} + + +void VSlicingNode::setGCell ( Anabatic::GCell* gcell ) +{ + cdebug_log(535,1) << "VSlicingNode::setGCell(Anabatic::GCell*) " << gcell << endl; + + Anabatic::GCell* prevGCell = gcell; + Anabatic::GCell* nextGCell = NULL; + vector::const_iterator itc = _children.begin(); + vector::const_iterator its = _slicingRouting.begin(); + int index = 0; + DbU::Unit x = (*its)->getX(); + + while ( not ((itc == _children.end()) and (its+1 == _slicingRouting.end())) ) { + if (index%2 == 0) { + x += (*its)->getWidth(); + nextGCell = prevGCell->vcut( x ); + (*its)->setGCell( prevGCell ); + its++; + } else { + x += (*itc)->getWidth(); + nextGCell = prevGCell->vcut( x ); + (*itc)->setGCell( prevGCell ); + itc++; + } + prevGCell = nextGCell; + index++; + } + (*its)->setGCell( prevGCell ); + + cdebug_tabw(535,-1); +} + + + +void VSlicingNode::adjustBorderChannels () +{ + if (_parent){ + DbU::Unit space = _parent->getWidth() - getWidth(); + + if ( this->getAlignment() == AlignRight ){ + RHVSlicingNode* ch = (*_slicingRouting.begin()); + ch->setWidth(ch->getWidth()+space); + + + } else if ( this->getAlignment() == AlignCenter ){ + RHVSlicingNode* chf = (*_slicingRouting.begin()); + RHVSlicingNode* chl = (*(_slicingRouting.end()-1)); + chf->setWidth(chf->getWidth()+space/2); + chl->setWidth(chl->getWidth()+space/2); + + } else if ( this->getAlignment() == AlignLeft ){ + RHVSlicingNode* ch = (*(_slicingRouting.end()-1)); + ch->setWidth(ch->getWidth()+space); + + } + } + for (vector::iterator it = _children.begin(); it != _children.end(); it++){ + (*it)->adjustBorderChannels(); + } +} + + +string VSlicingNode::_getString () const +{ + string s = Super::_getString(); + return s; +} + + +string VSlicingNode::_getTypeName () const +{ return "VSlicingNode"; } + +// -----------------------------------------------------------------------------------------------// +// Class : DSlicingNode +// -----------------------------------------------------------------------------------------------// + +int DSlicingNode::_count = 0; +int DSlicingNode::_countAll = 0; + + +DSlicingNode::DSlicingNode( unsigned int type + , NodeSets* nodeSets + , unsigned int alignment + , Instance* instance + , BoxSet* boxSet + ): SlicingNode( type, nodeSets, alignment, boxSet ) + , _instance(instance) +{} + + +DSlicingNode::~DSlicingNode(){} + + +DSlicingNode* DSlicingNode::create( NodeSets* nodeSets + , unsigned int alignment + , Instance* instance + , BoxSet* boxSet + ) +{ + _count++; + _countAll++; + return new DSlicingNode( DeviceSNode, nodeSets, alignment, instance, boxSet ); +} + + +void DSlicingNode::print() const +{ + cerr << "- Print from Slicing Node - " << endl; + cerr << "SlicingType: Device Node" << endl; + if (this->isAlignLeft ()){ cerr << "Alignment : Left" << endl; } + else if (this->isAlignCenter()){ cerr << "Alignment : Middle" << endl; } + else if (this->isAlignRight ()){ cerr << "Alignment : Right" << endl; } + else if (this->isAlignTop ()){ cerr << "Alignment : Top" << endl; } + else if (this->isAlignBottom()){ cerr << "Alignment : Bottom" << endl; } + else { cerr << "Alignment : Unknown" << endl; } + cerr << "NFingers : " << getNFing() << endl; + if (_instance != NULL){ + cerr << "Instance : " << _instance << endl; + } else { + cerr << "Instance : None" << endl; + } + SlicingNode::print(); +} + + +DSlicingNode* DSlicingNode::clone( unsigned int tr ) +{ + DSlicingNode* node = DSlicingNode::create( _nodeSets->clone() + , this->getAlignment() + , this->getInstance() + , this->getBoxSet() + ); + node->setPreset(this->getPreset()); + node->setSet (this->getSet() ); + node->setPlaced(this->getPlaced()); + return node; +} + + +void DSlicingNode::setNFing( int nfing ) +{ + if (_nodeSets->find(nfing) != _nodeSets->end()){ + _boxSet = (*_nodeSets->find(nfing)); + } else { + _boxSet = (*_nodeSets->begin()); + } +} + + +int DSlicingNode::getNFing() const +{ + if (_boxSet != NULL) { return _boxSet->getNFing(); } + else { return 1; } +} + + +double DSlicingNode::getStartParameter() const +{ + return _nodeSets->getStartParameter(); +} + + +double DSlicingNode::getStepParameter() const +{ + return _nodeSets->getStepParameter(); +} + + +double DSlicingNode::getCountParameter() const +{ + return _nodeSets->getCountParameter(); +} + + +void DSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace ) +{ + cdebug_log(536,1) << "void DSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace )" << endl; + if (replace){ + SlicingNode::place(x,y); + if (_instance != NULL){ + Cell* model = _instance->getMasterCell(); + _instance->setTransformation(Transformation( _x - model->getAbutmentBox().getXMin(), _y - model->getAbutmentBox().getYMin())); + _instance->setPlacementStatus(Instance::PlacementStatus::PLACED); + } + } else { + if (isSet()){ + SlicingNode::place(x,y); + + if (_instance != NULL){ + Cell* model = _instance->getMasterCell(); + Device* dev = dynamic_cast(model); + + if (dev) { + TransistorFamily* tf = dynamic_cast(dev); + if (tf) { + tf->setNfing( this->getNFing() ); + FormFactorParameter* pff = NULL; + if ( (pff = dynamic_cast(tf->getParameter("M"))) != NULL ) { + pff->setValue( tf->getNfing() ); + } + shared_ptr layoutGenerator ( new LayoutGenerator() ); + layoutGenerator->setDevice(dev); + layoutGenerator->drawLayout(); + } + } + _instance->setTransformation(Transformation( _x - model->getAbutmentBox().getXMin(), _y - model->getAbutmentBox().getYMin())); + _instance->setPlacementStatus(Instance::PlacementStatus::PLACED); + + } + } + } + cdebug_tabw(536,-1); +} + + +void DSlicingNode::place( DbU::Unit x, DbU::Unit y ) +{ + DSlicingNode::_place(x, y); +} + + +void DSlicingNode::preDestroy() +{ + _count--; + SlicingNode::preDestroy(); +} + + +void DSlicingNode::destroy() +{ + DSlicingNode::preDestroy(); + delete(this); +} + + +void DSlicingNode::preRecursiveDestroy() +{ + _count--; + SlicingNode::preRecursiveDestroy(); +} + + +void DSlicingNode::recursiveDestroy() +{ + DSlicingNode::preRecursiveDestroy(); + delete(this); +} + + +OpenChams::SlicingNode* DSlicingNode::toOpenChams() +{ + OpenChams::SlicingNode* dnode = OpenChams::DSlicingNode::create(_instance->getName()._getString()); + if ( isAlignLeft() ){ dnode->setAlignment("AlignLeft" ); } + else if ( isAlignRight() ){ dnode->setAlignment("AlignRight" ); } + else if ( isAlignCenter() ){ dnode->setAlignment("AlignCenter" ); } + else if ( isAlignTop() ){ dnode->setAlignment("AlignTop" ); } + else if ( isAlignBottom() ){ dnode->setAlignment("AlignBottom" ); } + else { dnode->setAlignment("UnknownAlignment"); } + + string strue = "true"; + string sfalse = "false"; + if( isPreset() ){ dnode->setPreset( strue ); } + else { dnode->setPreset( sfalse ); } + dnode->setX ( _x ); + dnode->setY ( _y ); + dnode->setNFing ( getNFing() ); + dnode->setStart ( getStartParameter() ); + dnode->setStep ( getStepParameter() ); + dnode->setCount ( getCountParameter() ); + + return dnode; +} + + +bool DSlicingNode::checkInitialPlacement ( int& cpt ) const +{ +// -----------------------------------------------------------------------------------------------// +// Notes:: Initial placement criteria is having at least 2 devices placed at (x, y) = (0, 0) +// -----------------------------------------------------------------------------------------------// + bool initialPlacement = false; + if ( cpt < 2 ){ + if ( (_x == 0) && (_y == 0) ){ + cpt++; + if ( cpt < 2 ) { initialPlacement = true; } + } + else { initialPlacement = true; } + } + return initialPlacement; +} + + +void DSlicingNode::setGCell( Anabatic::GCell* gcell ) +{ + cdebug_log(535,0) << "DSlicingNode::setGCell(Anabatic::GCell*) " << gcell << endl; + + if (getParent() != NULL) { + if (getParent()->getType() == HorizontalSNode) { + if (getAlignment() == AlignLeft) { + Anabatic::GCell* rightc = gcell->vcut( getX() + getWidth() ); + _gcell = gcell; + rightc->setType( Anabatic::Flags::StrutGCell ); + } else if (getAlignment() == AlignCenter) { + _gcell = gcell->vcut( getX() ); + Anabatic::GCell* rightc = _gcell->vcut( this->getX() + this->getWidth() ); + gcell->setType ( Anabatic::Flags::StrutGCell ); + rightc->setType( Anabatic::Flags::StrutGCell ); + } else if (getAlignment() == AlignRight ){ + _gcell = gcell->vcut( getX() ); + gcell->setType( Anabatic::Flags::StrutGCell ); + } + } else if (getParent()->getType() == VerticalSNode) { + if (getAlignment() == AlignBottom){ + Anabatic::GCell* topc = gcell->hcut(this->getY()+this->getHeight()); + _gcell = gcell; + topc->setType( Anabatic::Flags::StrutGCell ); + } else if (getAlignment() == AlignCenter) { + _gcell = gcell->hcut( getY() ); + Anabatic::GCell* topc = _gcell->hcut( getY() + getHeight() ); + gcell->setType( Anabatic::Flags::StrutGCell ); + topc->setType ( Anabatic::Flags::StrutGCell ); + } else if (getAlignment() == AlignTop) { + _gcell = gcell->hcut( this->getY() ); + gcell->setType( Anabatic::Flags::StrutGCell ); + } + } else { + _gcell = gcell; + } + } else { + _gcell = gcell; + } + if (_gcell) { + if (dynamic_cast(_instance->getMasterCell())){ + _gcell->setType( Anabatic::Flags::DeviceGCell ); + } else { + _gcell->setType( Anabatic::Flags::MatrixGCell ); + if( (_gcell->getWidth() > Anabatic::Session::getSliceHeight()) + and(_gcell->getHeight() > Anabatic::Session::getSliceHeight()) ) { + _gcell->doGrid(); + } + } + } + + cdebug_log(535,0) << "> Device:" << _instance << endl; + cdebug_log(535,0) << "> GCell: " << _gcell << endl; +} + + +bool DSlicingNode::isSame ( SlicingNode* node, unsigned int flags ) const +{ + bool isSame = _nodeSets->compare( node->getNodeSets(), flags ); + if (not isSame and (flags & ShowDiff)) + cerr << "DSlicingNode::isSame() Check " << this << " vs. " << node << endl; + return isSame; +} + + +bool DSlicingNode::isSymmetric( SlicingNode* node, unsigned int symmetryType, unsigned int flags ) const +{ + bool isSame = _nodeSets->compare( node->getNodeSets(), flags ); + if (not isSame and (flags & ShowDiff)) + cerr << "[WARNING] DSlicingNode::isSymmetric(): Different nodesets Check " << this << " vs. " << node << endl; + if (_instance != NULL){ + Cell* model1 = _instance->getMasterCell(); + Cell* model2 = node->getInstance()->getMasterCell(); + + Device* dev1 = dynamic_cast(model1); + Device* dev2 = dynamic_cast(model2); + if ((dev1 != NULL) && (dev2 !=NULL)){ + CommonSourcePair* csp1 = dynamic_cast(model1); + DifferentialPair* dp1 = dynamic_cast(model1); + Transistor* ts1 = dynamic_cast(model1); + + CommonSourcePair* csp2 = dynamic_cast(model2); + DifferentialPair* dp2 = dynamic_cast(model2); + Transistor* ts2 = dynamic_cast(model2); + + if ((csp1 != NULL) && (csp2 != NULL)) isSame = csp1->isSame(csp2); + else if ((dp1 != NULL) && (dp2 != NULL)) isSame = dp1->isSame(dp2); + else if ((ts1 != NULL) && (ts2 != NULL)) isSame = ts1->isSame(ts2); + else isSame = false; + } + if (not(isSame)) cerr << "[WARNING] DSlicingNode::isSymmetric(): Different devices. Check " << this << " vs. " << node << endl; + } + return isSame; +} + + +void DSlicingNode::updateMatrixGCellPosition() +{ + DbU::Unit tx = getX()-_gcell->getXMin(); + DbU::Unit ty = getY()-_gcell->getYMin(); + Anabatic::GCell* ygcell = _gcell; + Anabatic::GCell* xgcell = ygcell; + while (ygcell){ + while(xgcell){ + xgcell->setSouthWestCorner( xgcell->getXMin()+tx, xgcell->getYMin()+ty ); + if (xgcell->getEast()->isMatrix()) xgcell = xgcell->getEast(); + else xgcell = NULL; + } + if (ygcell->getNorth()->isMatrix()) ygcell = ygcell->getNorth(); + else ygcell = NULL; + xgcell = ygcell; + } +} + + +void DSlicingNode::updateMatrixGContacts() +{ + Anabatic::GCell* ygcell = _gcell; + Anabatic::GCell* xgcell = ygcell; + while (ygcell){ + while(xgcell){ + xgcell->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + if (xgcell->getEast()->isMatrix()) xgcell = xgcell->getEast(); + else xgcell = NULL; + } + if (ygcell->getNorth()->isMatrix()) ygcell = ygcell->getNorth(); + else ygcell = NULL; + xgcell = ygcell; + } +} + + +void DSlicingNode::updateGCellPosition() +{ + cdebug_log(535,0) << "DSlicingNode::updateGCellPosition() " << _gcell << endl; + + if (_gcell) { + if (_parent) { + if (_parent->getType() == HorizontalSNode) { + DbU::Unit hpitch = _rg->getHorizontalPitch(); + + if (getAlignment() == AlignLeft) { + _gcell->getEastNMatrix()->setSouthWestCorner( getX()+getWidth(), getY() ); + _gcell->getEastNMatrix()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/hpitch) + , floor(getHeight()/hpitch) + ); + } else if (getAlignment() == AlignCenter) { + _gcell->getWest()->setSouthWestCorner( _parent->getX(), getY() ); + _gcell->getWest()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/(2*hpitch)) + , floor(getHeight()/(2*hpitch)) + ); + + _gcell->getEastNMatrix()->setSouthWestCorner( getX()+getWidth(), getY() ); + _gcell->getEastNMatrix()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/(2*hpitch)) + , floor(getHeight()/(2*hpitch)) + ); + } else if (getAlignment() == AlignRight) { + _gcell->getWest()->setSouthWestCorner( _parent->getX(), getY() ); + _gcell->getWest()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/hpitch) + , floor(getHeight()/hpitch) + ); + + } + } else if (_parent->getType() == VerticalSNode) { + DbU::Unit vpitch = _rg->getVerticalPitch(); + + if (getAlignment() == AlignBottom) { + _gcell->getNorthNMatrix()->setSouthWestCorner( getX(), getY()+getHeight() ); + _gcell->getNorthNMatrix()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/vpitch) + , floor(getWidth()/vpitch) + ); + } else if (getAlignment() == AlignCenter) { + _gcell->getSouth()->setSouthWestCorner( getX(), _parent->getY() ); + _gcell->getSouth()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/(2*vpitch)) + , floor(getWidth()/(2*vpitch)) + ); + + _gcell->getNorthNMatrix()->setSouthWestCorner( getX(), getY()+getHeight() ); + _gcell->getNorthNMatrix()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/(2*vpitch)) + , floor(getWidth()/(2*vpitch)) + ); + } else if (getAlignment() == AlignTop) { + _gcell->getSouth()->setSouthWestCorner( getX(), _parent->getY() ); + _gcell->getSouth()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/vpitch) + , floor(getWidth()/vpitch) + ); + } + } + } + if (_gcell->isMatrix()) this->updateMatrixGCellPosition(); + else _gcell->setSouthWestCorner( getX(), getY() ); + cdebug_log(535,0) << "| Updated:" << _gcell << endl; + } +} + + + +void DSlicingNode::updateGContacts() +{ + cdebug_log(535,0) << "DSlicingNode::updateGContacts() " << _gcell << endl; + + if (_gcell) { + if (_parent) { + if (_parent->getType() == HorizontalSNode) { + + if (getAlignment() == AlignLeft) { + _gcell->getEastNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + + } else if (getAlignment() == AlignCenter) { + _gcell->getWest()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + _gcell->getEastNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + + } else if (getAlignment() == AlignRight) { + _gcell->getWest()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + + } + } else if (_parent->getType() == VerticalSNode) { + + if (getAlignment() == AlignBottom) { + _gcell->getNorthNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + } else if (getAlignment() == AlignCenter) { + _gcell->getSouth()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + _gcell->getNorthNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + + } else if (getAlignment() == AlignTop) { + _gcell->getSouth()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + } + } + } + if (_gcell->isMatrix()) this->updateMatrixGContacts(); + else _gcell->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal ); + cdebug_log(535,0) << "| Updated:" << _gcell << endl; + } +} + + +void DSlicingNode::restrictDevices() +{ + if (_gcell){ + Anabatic::Vertex* vertex = _gcell->getObserver< Anabatic::Vertex>( Anabatic::GCell::Observable::Vertex); + vertex->setRestricted(); + + if (!vertex->hasValidStamp()){ + if ((_gcell->getWidth() > _gcell->getHeight())||(_gcell->getWidth() == _gcell->getHeight())) { + vertex->unsetFlags(Anabatic::Vertex::iVertical); + vertex->setFlags(Anabatic::Vertex::iHorizontal); + } else { + vertex->unsetFlags(Anabatic::Vertex::iHorizontal); + vertex->setFlags(Anabatic::Vertex::iVertical ); + } + } + } + +} + + +void DSlicingNode::printLine() const +{ + cerr << "Instance: " << _instance << ", " ; + SlicingNode::printLine(); +} + + +string DSlicingNode::_getString () const +{ + string s = Super::_getString(); + s.insert( s.size()-1, " "+getString(_instance->getName())); + return s; +} + + +string DSlicingNode::_getTypeName () const +{ return "DSlicingNode"; } + + +bool DSlicingNode::isAnalog () const +{ + if (_instance){ + Cell* model = _instance->getMasterCell(); + Device* dev = dynamic_cast(model); + if (dev) return true; + else return false; + } else return false; +} + + +bool DSlicingNode::isDigital () const +{ + return (not (isAnalog())); +} + + +bool DSlicingNode::checkCellInstances ( Cell* cell ){ + if (_instance){ + if (cell->getInstance(_instance->getName())) return true; + else return false; + } else return false; +} +// -----------------------------------------------------------------------------------------------// +// Class : RHVSlicingNode +// -----------------------------------------------------------------------------------------------// + +int RHVSlicingNode::_count = 0; +int RHVSlicingNode::_countAll = 0; + + +RHVSlicingNode::RHVSlicingNode(): SlicingNode( RoutingSNode, NodeSets::create(), UnknownAlignment, NULL ) + , _railInstance(NULL) +{ + this->setPreset(Preset); + this->setSet (Set ); + this->setOverCell(OverCell); + _wireOccupation = ChannelRouting::create(); +} + + +RHVSlicingNode::~RHVSlicingNode(){} + + +void RHVSlicingNode::print() const +{ + cerr << "- Print from Slicing Node - " << endl; + if (_railInstance) cerr << "RailInstace: " << _railInstance << endl; + SlicingNode::print(); +} + + +void RHVSlicingNode::_setGlobalSize ( DbU::Unit height, DbU::Unit width ){} + + +void RHVSlicingNode::preDestroy() +{ + _count--; + SlicingNode::preDestroy(); + if(_wireOccupation) _wireOccupation->destroy(); +} + + +void RHVSlicingNode::destroy() +{ + RHVSlicingNode::preDestroy(); + delete(this); +} + + +void RHVSlicingNode::preRecursiveDestroy() +{ + _count--; + SlicingNode::preRecursiveDestroy(); +} + + +void RHVSlicingNode::recursiveDestroy() +{ + RHVSlicingNode::preRecursiveDestroy(); + delete(this); +} + + +void RHVSlicingNode::resetSize() +{ + _boxSet->setHeight( _minHeight ); + _boxSet->setWidth ( _minWidth ); +} + + +bool RHVSlicingNode::isSame( SlicingNode* node, unsigned int flags ) const +{ + return ( (this->getHeight() == node->getHeight())&& (this->getWidth() == node->getWidth()) ); +} + + +bool RHVSlicingNode::isSymmetric( SlicingNode* node, unsigned int symmetryType, unsigned int flags ) const +{ + return ( (this->getHeight() == node->getHeight())&& (this->getWidth() == node->getWidth()) ); +} + + +void RHVSlicingNode::setRailInstance(Hurricane::Instance* i) +{ + _railInstance = i; +} + + +void RHVSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace ) +{ + SlicingNode::_place(x,y,replace); + if (_railInstance){ + Net* net = NULL; + int t = 0; + for (Net* n : _railInstance->getMasterCell()->getNets()) { + net = n; + t++; + } + if (t != 1) cerr << "Error(void RHVSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace )): Several Nets in Rail Instance Cell." << endl; + Component* component = NULL; + t = 0; + for (Component* c : net->getComponents()){ + component = c; + t++; + } + if (t != 1) cerr << "Error(void RHVSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace )): Several Components in Rail Instance Cell." << endl; + + Horizontal* h = dynamic_cast(component); + Vertical* v = dynamic_cast (component); + UpdateSession::open(); + if (h){ + h->setDxSource(0); + h->setDxTarget(getRootWidth()); + _railInstance->getMasterCell()->setAbutmentBox(Box( 0, 0, getRootWidth(), getHeight() )); + _railInstance->setTransformation(Transformation( _cell->getAbutmentBox().getXMin(), getY() ) ); + } else if (v){ + v->setDySource(0); + v->setDyTarget(getRootHeight()); + _railInstance->getMasterCell()->setAbutmentBox(Box( 0, 0, getWidth(), getRootHeight() )); + _railInstance->setTransformation(Transformation( getX(), _cell->getAbutmentBox().getYMin() ) ); + } else { + cerr << "Error(void RHVSlicingNode::_place( DbU::Unit x = 0, DbU::Unit y = 0, bool replace = false )): Unknown segment type." << endl; + } + _railInstance->setPlacementStatus(Instance::PlacementStatus::PLACED); + UpdateSession::close(); + } +} + + +void RHVSlicingNode::addWireOccupation( DbU::Unit min, DbU::Unit max ) +{ +//cerr << "addWireOccupation min:" << DbU::getPhysical(min, DbU::Micro) << ", max:" << DbU::getPhysical(max, DbU::Micro) << ", MaxCount: " << _wireOccupation->getMaxCount() << endl; + if (_wireOccupation) { + if (min == max){/* + RHSlicingNode* h = dynamic_cast(this); + RVSlicingNode* v = dynamic_cast(this); + if (h) { + _wireOccupation->insertChannel(getX(), getX()+getWidth()); + } else if (v) { + _wireOccupation->insertChannel(getY(), getY()+getHeight()); + }*/ + } else { + _wireOccupation->insertChannel(min, max); + } + } +//cerr << "NewMaxCount:" << _wireOccupation->getMaxCount() << endl; +//_wireOccupation->print(); +//printLine(); +} + + +void RHVSlicingNode::resetWireOccupation() +{ + if (_wireOccupation) _wireOccupation->reset(); +} + + +int RHVSlicingNode::getMaxWireOccupation() +{ + if (_wireOccupation) return _wireOccupation->getMaxCount()+1; + else return 0; +} + + +// Error Message Methods +unsigned int RHVSlicingNode::getAlignment() const +{ + cerr << " Error(unsigned int getAlignment () const): Routing does not have centering type." << endl; + return UnknownAlignment; +} + + +NodeSets* RHVSlicingNode::getNodeSets() const +{ + cerr << " Error(NodeSets* getNodeSets() const): Routing does not have different dimensions." << endl; + return NULL; +} + + +BoxSet* RHVSlicingNode::getPairH( DbU::Unit height ) const +{ + cerr << " Error(BoxSet* getPairH ( DbU::Unit height ) const): Routing does not have different dimensions." << endl; + return _boxSet; +} + + +BoxSet* RHVSlicingNode::getPairHW( DbU::Unit height, DbU::Unit width ) const +{ + cerr << " Error(BoxSet* RHVSlicingNode::getPairHW( DbU::Unit height, DbU::Unit width ) const): Routing does not have different dimensions." << endl; + return _boxSet; +} + + +void RHVSlicingNode::setPairH( DbU::Unit height ) +{ + cerr << " Error(void setPairH ( DbU::Unit height )): Routing does not have different dimensions." << endl; +} + + +void RHVSlicingNode::setPairHW( DbU::Unit height, DbU::Unit width ) +{ + cerr << " Error(void setPairHW ( DbU::Unit height, DbU::Unit width )): Routing does not have different dimensions." << endl; +} + + +// -----------------------------------------------------------------------------------------------// +// Class : RHSlicingNode +// -----------------------------------------------------------------------------------------------// + + +RHSlicingNode::RHSlicingNode( DbU::Unit height ): RHVSlicingNode() +{ + RHBoxSet* node = RHBoxSet::create(height); + _nodeSets->push_back(node); + _boxSet = node; + _minHeight = height; + if (_parent != NULL){ + _minWidth = _parent->getWidth(); + } else { + _minWidth = 0; + } + + DbU::Unit hpitch = _rg->getHorizontalPitch(); + if (height % hpitch) + cerr << Warning( "RHSlicingNode::RHSlicingNode(): On %s, height is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(height).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; +} + + +RHSlicingNode::RHSlicingNode( Hurricane::Instance* i ): RHVSlicingNode() +{ + RHBoxSet* node = RHBoxSet::create(i->getMasterCell()->getAbutmentBox().getHeight()); + _nodeSets->push_back(node); + _boxSet = node; + _minHeight = i->getMasterCell()->getAbutmentBox().getHeight(); + setRailInstance(i); + if (_parent != NULL){ + _minWidth = _parent->getWidth(); + } else { + _minWidth = 0; + } +} + + +RHSlicingNode::~RHSlicingNode(){}; + + +RHSlicingNode* RHSlicingNode::create( DbU::Unit height ) +{ + _count++; + _countAll++; + + return new RHSlicingNode(height); +} + + +RHSlicingNode* RHSlicingNode::create( Hurricane::Net* net,Hurricane::Layer* layer, int npitch, string cname, string iname ) +{ +//cerr << "RHSlicingNode::Create (Layer and co)" << endl; + Cell* cell = Hurricane::Cell::create(Hurricane::DataBase::getDB()->getRootLibrary(), cname); + Net* subnet = Hurricane::Net::create(cell, net->getName()); + DbU::Unit height = CRL::AllianceFramework::get()->getRoutingGauge()->getHorizontalPitch()* npitch; + subnet->setExternal(true); + Hurricane::Horizontal* h = Hurricane::Horizontal::create( subnet, layer, height/2, height ); + NetExternalComponents::setExternal( h ); + Hurricane::Instance* instance = Hurricane::Instance::create(_cell, iname, cell); + instance->getPlug(subnet)->setNet(net); + cell->setAbutmentBox(Box(0, 0, 0, height)); + SlicingNode::addRailSegments(h); + return new RHSlicingNode(instance); +} + + +RHSlicingNode* RHSlicingNode::clone( unsigned int tr ) +{ + RHSlicingNode* node = RHSlicingNode::create(this->getHeight()); + return node; +} + + +DbU::Unit RHSlicingNode::getWidth () const +{ +//cerr << "DbU::Unit RHSlicingNode::getWidth () const" << endl; + if ( (_parent) ){ + return _parent->getWidth(); + } else { + return 0; + } +} + + +void RHSlicingNode::setHeight( DbU::Unit height ) +{ + _boxSet->setHeight( height ); + + DbU::Unit hpitch = _rg->getHorizontalPitch(); + if (height % hpitch) + cerr << Warning( "RHSlicingNode::getHeight(): On %s, height is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(height).c_str() + , DbU::getValueString(hpitch).c_str() + ) << endl; +} + + +OpenChams::SlicingNode* RHSlicingNode::toOpenChams() +{ + OpenChams::SlicingNode* rnode = OpenChams::RSlicingNode::create(this->getHeight()); + return rnode; +} + + +void RHSlicingNode:: estimateChannelsSize() +{ + if (getRailInstance() == NULL){ + if (_gcell){ + /*ChannelRouting* c = ChannelRouting::create(); + for ( Contact* contact : _gcell->getGContacts() ) { + DbU::Unit xmin = contact->getX(); + DbU::Unit xmax = contact->getX(); + NetRoutingState* state = NetRoutingExtension::get( contact->getNet() ); + DbU::Unit wpitch = 1; + if (state) wpitch = state->getWPitch(); + for ( Component* comp: contact->getSlaveComponents() ){ + Vertical* v = dynamic_cast(comp); + Horizontal* h = dynamic_cast(comp); + if (v){ + if (xmin > v->getX()) xmin = v->getX(); + if (xmax < v->getX()) xmax = v->getX(); + + if (xmin < getX()) xmin = getX(); + if (xmax > getX()+getWidth()) xmax = getX()+getWidth(); + + } else if (h){ + xmin = getX(); + xmax = getX()+getWidth(); + } + } + c->insertChannel(xmin, xmax, wpitch); + }*/ + + /*if (_rg){ + DbU::Unit hpitch = _rg->getHorizontalPitch(); + + if ( c->getMaxCount() > 0 ){ + int occupancyH = c->getMaxCount()+1; //+1 for having enough space + if (occupancyH%2 != 0) occupancyH++; + this->updateMasterSize( occupancyH*hpitch ); + } else this->updateMasterSize( 2*hpitch ); + this->setRoutingEstimated(RoutingEstimated); + } else { + cerr << "Error(void RHSlicingNode::estimateChannelsSize()): Technology missing." << endl; + }*/ + if (_rg){ + DbU::Unit hpitch = _rg->getHorizontalPitch(); + if ( getMaxWireOccupation()> 0 ){ + int occupancyH = getMaxWireOccupation (); //+1 for having enough space + if (occupancyH%2 != 0) occupancyH++; + this->updateMasterSize( occupancyH*hpitch ); + } else this->updateMasterSize( 2*hpitch ); + this->setRoutingEstimated(RoutingEstimated); + } else { + cerr << "Error(void RHSlicingNode::estimateChannelsSize()): Technology missing." << endl; + } + } + } +} + + +void RHSlicingNode::_expandRoutingChannel () +{ + SlicingNode* master = this; + while ( master->getMaster() != NULL ) master = master->getMaster(); + + // cerr << "RHSlicingNode::_expandRoutingChannel() " << this + // << " to " << DbU::getValueString( master->getHeight() ) << endl; + + setHeight( master->getHeight() ); + setRoutingEstimated( RoutingEstimated ); +} + + +void RHSlicingNode::expandRoutingChannel ( DbU::Unit height, DbU::Unit width ) +{ + // cerr << "RHSlicingNode::expandRoutingChannel(DbU::Unit h, DbU::Unit w) " << this + // << " to " << DbU::getValueString( height ) << endl; + + setHeight( height ); + setRoutingEstimated( RoutingEstimated ); +} + + +void RHSlicingNode::updateMasterSize( DbU::Unit size ) +{ + SlicingNode* master = this; + while(master->getMaster() != NULL) master = master->getMaster(); + if (master->getHeight() < size) master->setHeight(size); +} + + +void RHSlicingNode::setGCell( Anabatic::GCell* gcell ) +{ + _gcell = gcell; + if (_gcell) { + if (_railInstance) _gcell->setType( Anabatic::Flags::HRailGCell ); + else _gcell->setType( Anabatic::Flags::HChannelGCell ); + } + + cdebug_log(535,0) << "RHSlicingNode::setGCell() " << _gcell << endl; +} + +// Error Methods +void RHSlicingNode::setWidth( DbU::Unit width ) +{ + cerr << "Error(void RHSlicingNode::setWidth( DbU::Unit width )): Routing does not have width." << endl; +} + + +string RHSlicingNode::_getTypeName () const +{ return "RHSlicingNode"; } + + +// -----------------------------------------------------------------------------------------------// +// Class : RVSlicingNode +// -----------------------------------------------------------------------------------------------// + + +RVSlicingNode::RVSlicingNode( DbU::Unit width ): RHVSlicingNode() +{ + RVBoxSet* node = RVBoxSet::create(width); + _nodeSets->push_back(node); + _boxSet = node; + _minWidth = width; + if (_parent != NULL){ + _minHeight = _parent->getHeight(); + } else { + _minHeight = 0; + } + + DbU::Unit vpitch = _rg->getVerticalPitch(); + if (width % vpitch) + cerr << Warning( "RVSlicingNode::RVSlicingNode(): On %s, width is not pitched (%s, pitch:%s)." + , getString(this).c_str() + , DbU::getValueString(width).c_str() + , DbU::getValueString(vpitch).c_str() + ) << endl; +} + + +RVSlicingNode::RVSlicingNode( Hurricane::Instance* i ): RHVSlicingNode() +{ + RVBoxSet* node = RVBoxSet::create(i->getMasterCell()->getAbutmentBox().getWidth()); + _nodeSets->push_back(node); + _boxSet = node; + _minHeight = i->getMasterCell()->getAbutmentBox().getWidth(); + setRailInstance(i); + if (_parent != NULL){ + _minWidth = _parent->getWidth(); + } else { + _minWidth = 0; + } +} + + +RVSlicingNode::~RVSlicingNode(){}; + + +RVSlicingNode* RVSlicingNode::create( DbU::Unit width ) +{ + _count++; + _countAll++; + return new RVSlicingNode(width); +} + + +RVSlicingNode* RVSlicingNode::create( Hurricane::Net* net, Hurricane::Layer* layer, int npitch, string cname, string iname ) +{ +//cerr << "RVSlicingNode::Create (Layer and co)" << endl; + Cell* cell = Hurricane::Cell::create(Hurricane::DataBase::getDB()->getRootLibrary(), cname); + Net* subnet = Hurricane::Net::create(cell, net->getName()); + + DbU::Unit width = CRL::AllianceFramework::get()->getRoutingGauge()->getVerticalPitch()* npitch; + subnet->setExternal(true); + Hurricane::Vertical* v = Hurricane::Vertical::create( subnet, layer, width/2, width ); + NetExternalComponents::setExternal( v ); + Hurricane::Instance* instance = Hurricane::Instance::create(_cell, iname, cell); + instance->getPlug(subnet)->setNet(net); + cell->setAbutmentBox(Box(0, 0, width, 0)); + SlicingNode::addRailSegments(v); + return new RVSlicingNode(instance); +} + + +RVSlicingNode* RVSlicingNode::clone( unsigned int tr ) +{ + RVSlicingNode* node = RVSlicingNode::create(this->getWidth()); + return node; +} + + +DbU::Unit RVSlicingNode::getHeight () const +{ +//cerr << "DbU::Unit RVSlicingNode::getHeight () const" << endl; + if ( (_parent) ){ + return _parent->getHeight(); + } else { + return 0; + } +} + + +void RVSlicingNode::setWidth( DbU::Unit width ) +{ + _boxSet->setWidth( width ); +} + + +OpenChams::SlicingNode* RVSlicingNode::toOpenChams() +{ + OpenChams::SlicingNode* rnode = OpenChams::RSlicingNode::create(this->getWidth()); + return rnode; +} + +void RVSlicingNode::estimateChannelsSize() +{ + if (getRailInstance() == NULL){ + if (_gcell){ + /*ChannelRouting* c = ChannelRouting::create(); + for ( Contact* contact : _gcell->getGContacts() ) { + DbU::Unit ymin = contact->getY(); + DbU::Unit ymax = contact->getY(); + NetRoutingState* state = NetRoutingExtension::get( contact->getNet() ); + DbU::Unit wpitch = 1; + if (state) wpitch = state->getWPitch(); + for ( Component* comp: contact->getSlaveComponents() ){ + Vertical* v = dynamic_cast(comp); + Horizontal* h = dynamic_cast(comp); + if (h){ + if (ymin > h->getY()) ymin = h->getY(); + if (ymax < h->getY()) ymax = h->getY(); + + if (ymin < getY()) ymin = getY(); + if (ymax > getY()+getHeight()) ymax = getY()+getHeight(); + + } else if (v){ + ymin = getY(); + ymax = getY()+getHeight(); + } + } + c->insertChannel(ymin, ymax, wpitch); + } + + if (_rg){ + DbU::Unit vpitch = _rg->getVerticalPitch(); + + if ( c->getMaxCount() > 0 ){ + int occupancyV = c->getMaxCount()+1; //+1 for having enough space + if (occupancyV%2 != 0) occupancyV++; + this->updateMasterSize(occupancyV*vpitch); + //this->setWidth(occupancyV*vpitch); + } else this->updateMasterSize(2*vpitch); + this->setRoutingEstimated(RoutingEstimated); + } else { + cerr << "Error(void RHSlicingNode::estimateChannelsSize ()): Technology missing." << endl; + }*/ + + + if (_rg){ + DbU::Unit vpitch = _rg->getVerticalPitch(); + + if ( getMaxWireOccupation() > 0 ){ + int occupancyV = getMaxWireOccupation(); //+1 for having enough space + if (occupancyV%2 != 0) occupancyV++; + this->updateMasterSize(occupancyV*vpitch); + //this->setWidth(occupancyV*vpitch); + } else this->updateMasterSize(2*vpitch); + this->setRoutingEstimated(RoutingEstimated); + } else { + cerr << "Error(void RHSlicingNode::estimateChannelsSize ()): Technology missing." << endl; + } + } + } +} + + +void RVSlicingNode::_expandRoutingChannel () +{ + SlicingNode* master = this; + while(master->getMaster() != NULL) master = master->getMaster(); + this->setWidth(master->getWidth()); + this->setRoutingEstimated(RoutingEstimated); +} + + +void RVSlicingNode::expandRoutingChannel( DbU::Unit height, DbU::Unit width ) +{ + this->setWidth(width); + this->setRoutingEstimated(RoutingEstimated); +} + + +void RVSlicingNode::setGCell( Anabatic::GCell* gcell ) +{ + _gcell = gcell; + if (_gcell) { + if (_railInstance) _gcell->setType( Anabatic::Flags::VRailGCell ); + else _gcell->setType( Anabatic::Flags::VChannelGCell ); + } + + cdebug_log(535,0) << "RVSlicingNode::setGCell() " << _gcell << endl; +} + + +void RVSlicingNode::updateMasterSize( DbU::Unit size ) +{ + SlicingNode* master = this; + while(master->getMaster() != NULL) master = master->getMaster(); + if (master->getWidth() < size) master->setWidth(size); +} + + +// Error Methods +void RVSlicingNode::setHeight( DbU::Unit height ) +{ + cerr << "Error(void RVSlicingNode::setHeight( DbU::Unit height )): Routing does not have height." << endl; +} + + +string RVSlicingNode::_getTypeName () const +{ return "RVSlicingNode"; } + + +// -----------------------------------------------------------------------------------------------// +// Class : HVSetState +// -----------------------------------------------------------------------------------------------// + + +HVSetState::HVSetState( HVSlicingNode* node ): _HVSnode( node ) +{ + _currentSet = vector (); + _nextSet = vector (); + _nodeSets = NodeSets::create(); + _counter = 1; + initSet(); + initModulos(); +} + + +HVSetState::~HVSetState(){} + + +NodeSets* HVSetState::getNodeSets() +{ + _nodeSets->sort(); + return _nodeSets; +} + + +void HVSetState::print() +{ + int index = 0; + cerr << "currentSet:" << endl; + vector::iterator it2 = _currentSet.begin(); + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + NodeSets* node = (*it)->getNodeSets(); + cerr << index << ": H = " << node->at((*it2))->getHeight() << ", W = " << node->at((*it2))->getWidth() << endl; + it2++; + index++; + } + cerr << "counter = " << _counter << endl; + cerr << "end counter = " << _modulos.back()<< endl; + cerr << "modulos:" << endl; + index = 0; + for (vector::iterator it = _modulos.begin(); it != _modulos.end(); it++) + { + cerr << index << ": modulo = " << (*it) << endl; + index++; + } + _nodeSets->print(); +} + + +void HVSetState::initSet() +{ + _nextSet.clear(); + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + if ( (*it)->isPreset() ) + { _nextSet.push_back((*it)->getNodeSets()->findIndex((*it)->getHeight(), (*it)->getWidth())); } + else + { _nextSet.push_back(0); } + } + _currentSet = _nextSet; +} + + +void HVSetState::initModulos() +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Considering a horizontal/vertical node with X children and each children has N possibilities: +// child 0: N0 possibilities, +// child 1: N1 possibilities, +// . +// . +// . +// child X: NX possibilities. +// If a child is preset then, it only has 1 possibility and N = 1. So we have: +// number of possibilities to be studied = N0 * N1 * ... * NX. +// Children are seen like a and modulos are used to know when a child needs to choose its next possibility. +// It starts like this: +// - child 0 goes through its N0 possibilities +// - when child 0 was at its last possibility, it goes back to its first one and child 1 pick its second possibility. +// - and we keep going . . . +// -----------------------------------------------------------------------------------------------// + + int modulo = 1; + int index = 0; + + _modulos.clear(); + _modulos.push_back(1); + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + + if ( it != _HVSnode->getChildren().begin() ) { _modulos.push_back(modulo); } + if ( (!isSymmetry(index)) && (!(*it)->isPreset()) ){ modulo *= (*it)->getNodeSets()->size(); } + index++; + } + _modulos.push_back(modulo); +} + + +void HVSetState::next() +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Set the next combination. See notes above. +// -----------------------------------------------------------------------------------------------// + + int index = 0; + pair symmetry = pair(); + vector::iterator itpair = _nextSet.begin(); + + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + + if ( this->isSymmetry(index, symmetry) ) + { (*itpair) = _nextSet[symmetry.first]; } + else { + if ( (((_counter-1)%_modulos[index]) == _modulos[index]-1) && (!(*it)->isPreset()) ) { + if ( (*itpair)+1 != (*it)->getNodeSets()->size() ) { (*itpair)++ ; } + else { (*itpair) = 0; } + } + } + index++; + itpair++; + } + _counter += 1; + _currentSet = _nextSet; +} + + +// -----------------------------------------------------------------------------------------------// +// Class : HSetState +// -----------------------------------------------------------------------------------------------// + + +HSetState::HSetState( HSlicingNode* node ):HVSetState(node) {} + + +HSetState::~HSetState(){} + + +pair HSetState::getCurrentWs() +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Calculate the min and max width of the current combination +// Routing nodes need to be taken into account to not calculate a wrong width. +// -----------------------------------------------------------------------------------------------// + + DbU::Unit wmin = 0; + DbU::Unit wmax = 0; + if (!_currentSet.empty()) { + vector< size_t >::const_iterator it2 = _currentSet.begin(); + vector::const_iterator it = _HVSnode->getChildren().begin(); + + while( (wmin == 0) && (it != _HVSnode->getChildren().end()) ){ + NodeSets* node = (*it)->getNodeSets(); + if ( node->at((*it2))->getWidth() != 0 ) + { wmin = node->at((*it2))->getWidth(); } + it++; + it2++; + } + + it2 = _currentSet.begin(); + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + NodeSets* node = (*it)->getNodeSets(); + if ( (node->at((*it2))->getWidth() < wmin)&&(node->at((*it2))->getWidth() != 0) ) + { wmin = node->at((*it2))->getWidth(); } + if (node->at((*it2))->getWidth() > wmax) + { wmax = node->at((*it2))->getWidth(); } + it2++; + } + } + return pair (wmin, wmax); +} + + +DbU::Unit HSetState::getCurrentH() +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Calculate the height of the current combination +// Routing nodes need to be taken into account to not calculate a wrong height. +// -----------------------------------------------------------------------------------------------// + + DbU::Unit currentH = 0; + vector< size_t >::const_iterator it2 = _currentSet.begin(); + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + NodeSets* node = (*it)->getNodeSets(); + currentH += node->at((*it2))->getHeight(); + it2++; + } + return currentH; +} + + +DbU::Unit HSetState::getCurrentW() +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Calculate the width of the current combination +// Routing nodes need to be taken into account to not calculate a wrong width. +// -----------------------------------------------------------------------------------------------// + + DbU::Unit currentW = 0; + vector< size_t >::const_iterator it2 = _currentSet.begin(); + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + NodeSets* node = (*it)->getNodeSets(); + if (node->at((*it2))->getWidth() > currentW) + { currentW = node->at((*it2))->getWidth(); } + it2++; + } + return currentW; +} + + +void HSetState::print() +{ + HVSetState::print(); + cerr << "currentH = " << getCurrentH() << endl; + cerr << "currentW = " << getCurrentW() << endl; + cerr << endl; +} + + +void HSetState::next() +{ + push_back(); + HVSetState::next(); +} + + +void HSetState::push_back() +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Check if conditions on tolerance are filled. +// If yes, add the current set to the NodeSets +// -----------------------------------------------------------------------------------------------// + + pair paireWidths = getCurrentWs(); + DbU::Unit width = paireWidths.second; + DbU::Unit wmin = paireWidths.first; + DbU::Unit height = 0; + if ( width - wmin <= _HVSnode->getToleranceBandW() ){ + vector vect = vector(); + vector::iterator it2 = _currentSet.begin(); + + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + NodeSets* node = (*it)->getNodeSets(); + vect.push_back(node->at((*it2))); + height += node->at((*it2))->getHeight(); + it2++; + } + + _nodeSets->push_back(vect, height, width, HorizontalSNode); // create the BoxSet of the current accepted set + } +} + + +// -----------------------------------------------------------------------------------------------// +// Class : VSetState +// -----------------------------------------------------------------------------------------------// + + +VSetState::VSetState( VSlicingNode* node ):HVSetState(node) {} + + +VSetState::~VSetState(){} + + +pair VSetState::getCurrentHs () +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Same as HSetState but for Vertical Node. See notes above. +// -----------------------------------------------------------------------------------------------// + + DbU::Unit hmin = 0; + DbU::Unit hmax = 0; + if (!_currentSet.empty()) { + vector::const_iterator it2 = _currentSet.begin(); + vector::const_iterator it = _HVSnode->getChildren().begin(); + + while( (hmin == 0) && (it != _HVSnode->getChildren().end()) ){ + NodeSets* node = (*it)->getNodeSets(); + if ( node->at((*it2))->getHeight() != 0 ) + { hmin = node->at((*it2))->getHeight(); } + it++; + it2++; + } + + it2 = _currentSet.begin(); + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + NodeSets* node = (*it)->getNodeSets(); + if ( (node->at((*it2))->getHeight() < hmin)&&(node->at((*it2))->getHeight() != 0) ) + { hmin = node->at((*it2))->getHeight(); } + + if (node->at((*it2))->getHeight() > hmax) + { hmax = node->at((*it2))->getHeight(); } + it2++; + } + } + return pair (hmin, hmax); +} + + +DbU::Unit VSetState::getCurrentH() +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Same as HSetState but for Vertical Node. See notes above. +// -----------------------------------------------------------------------------------------------// + DbU::Unit currentH = 0; + vector< size_t >::const_iterator it2 = _currentSet.begin(); + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + NodeSets* node = (*it)->getNodeSets(); + if (node->at((*it2))->getHeight() > currentH) + { currentH = node->at((*it2))->getHeight(); } + it2++; + } + + return currentH; +} + + +DbU::Unit VSetState::getCurrentW() +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Same as HSetState but for Vertical Node. See notes above. +// -----------------------------------------------------------------------------------------------// + DbU::Unit currentW = 0; + vector< size_t >::const_iterator it2 = _currentSet.begin(); + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + NodeSets* node = (*it)->getNodeSets(); + currentW += node->at((*it2))->getWidth(); + it2++; + } + return currentW; +} + + +void VSetState::print() +{ + HVSetState::print(); + cerr << "currentH = " << getCurrentH() << endl; + cerr << "currentW = " << getCurrentW() << endl; + cerr << endl; +} + + +void VSetState::next() +{ + push_back(); + HVSetState::next(); +} + + +void VSetState::push_back() +{ +// -----------------------------------------------------------------------------------------------// +// Notes: Same as HSetState but for Vertical Node. See notes above. +// -----------------------------------------------------------------------------------------------// + + pair paireHeights = getCurrentHs(); + DbU::Unit height = paireHeights.second; + DbU::Unit hmin = paireHeights.first; + DbU::Unit width = 0; + + if (height - hmin <= _HVSnode->getToleranceBandH()){ + vector vect = vector(); + vector::iterator it2 = _currentSet.begin(); + + for (vector::const_iterator it = _HVSnode->getChildren().begin(); it != _HVSnode->getChildren().end(); it++){ + NodeSets* node = (*it)->getNodeSets(); + vect.push_back(node->at((*it2))); + width += node->at((*it2))->getWidth(); + it2++; + } + _nodeSets->push_back(vect, height, width, VerticalSNode); + } +} + + +// -----------------------------------------------------------------------------------------------// +// Class : ChannelRouting +// -----------------------------------------------------------------------------------------------// + +ChannelRouting::ChannelRouting(){} + + +ChannelRouting::~ChannelRouting(){} + + +ChannelRouting* ChannelRouting::create() +{ + return new ChannelRouting(); +} + + +void ChannelRouting::destroy() +{ + delete this; +} + + +void ChannelRouting::reset() +{ + _limits.clear(); + _counts.clear(); +} + + +int ChannelRouting::getMaxCount() const +{ + int count = 0; + for (vector::const_iterator it = _counts.begin(); it != _counts.end(); it++){ + count = max( (*it), count ); + } + return count; +} + + +void pvectF(vector vec) +{ + for (vector::const_iterator it = vec.begin(); it != vec.end(); it++){ + cerr << (*it) << " - "; + } + cerr << endl; +} + + +void pvectI(vector vec) +{ + for (vector::const_iterator it = vec.begin(); it != vec.end(); it++){ + cerr << (*it) << " - "; + } + cerr << endl; +} + + +void ChannelRouting::insertChannel( DbU::Unit xy1, DbU::Unit xy2, unsigned int w ) +{ + for (unsigned int i = 0; i < w; ++i){ + insertChannel(xy1, xy2); + } +} + + +void ChannelRouting::insertChannel( DbU::Unit xy1, DbU::Unit xy2 ) +{ + DbU::Unit min = xy1; + DbU::Unit max = xy2; + ; + if (_limits.empty()){ + _limits.push_back(min); + _limits.push_back(max); + _counts.push_back(1); + } else { + if (max < _limits.front()){ + _limits.insert(_limits.begin(), max); + _limits.insert(_limits.begin(), min); + _counts.insert(_counts.begin(), 0); + _counts.insert(_counts.begin(), 1); + } else if (min > _limits.back ()){ + _limits.push_back(min); + _limits.push_back(max); + _counts.push_back(0); + _counts.push_back(1); + } else { + int index = 0; + vector::iterator itL = _limits.begin(); + vector::iterator itC = _counts.begin(); + + if (min < (*itL)){ + _limits.insert(itL, min); + _counts.insert(itC, 1 ); + } else { + while( ((*itL) < min) && (itL != _limits.end()) ){ + itL++; + index++; + if (itC != _counts.end()) itC++; + } + + if ((*itL) != min){ + _limits.insert(itL, min); + _counts.insert(itC, *(itC-1) ); + itL = _limits.begin()+index; + itC = _counts.begin()+index; + } + itL = _limits.begin()+index; + itC = _counts.begin()+index; + + + while( ((*itL) < max) && (itL != _limits.end()) ){ + itL++; + index++; + if (itC != _counts.end()) { + (*itC) += 1; + itC++; + } + } + if ( itL != _limits.end() ){ + if ((*(itL)) > max){ + _limits.insert(itL, max); + _counts.insert(itC, *(itC-1)-1 ); + } + } else { + if ((*(itL-1)) != max){ + _limits.push_back(max); + _counts.push_back(1); + } + } + } + + } + } +} + + +void ChannelRouting::print() const +{ + cerr << "limits: "; + for (vector::const_iterator it = _limits.begin(); it != _limits.end(); it++){ + cerr << DbU::getPhysical((*it), DbU::Micro) << " - "; + } + cerr << endl; + cerr << "count: "; + for (vector::const_iterator it = _counts.begin(); it != _counts.end(); it++){ + cerr << (*it) << " - "; + } + cerr << endl; +} diff --git a/bora/src/attic/SlicingNode-full.h b/bora/src/attic/SlicingNode-full.h new file mode 100644 index 00000000..a16d017d --- /dev/null +++ b/bora/src/attic/SlicingNode-full.h @@ -0,0 +1,1451 @@ +// -*- C++ -*- +// +// This file is part of the Chams Software. +// Copyright (c) UPMC 2012-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C H A M S | +// | H o r u s - S l i c i n g T r e e V i e w e r | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricaneAMS/layout/SlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef DEF_SLICINGNODE +#define DEF_SLICINGNODE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hurricane/Cell.h" +#include "hurricane/Net.h" +#include "hurricane/Contact.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Occurrence.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/Name.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/DbU.h" +#include "hurricane/Property.h" + +#include "hurricaneAMS/technology/AnalogTechnology.h" +#include "hurricaneAMS/analogic/LayoutGenerator.h" +#include "hurricaneAMS/analogic/Device.h" +#include "hurricaneAMS/devices/TransistorFamily.h" +#include "hurricaneAMS/devices/Transistor.h" +#include "hurricaneAMS/devices/SimpleCurrentMirror.h" +#include "hurricaneAMS/devices/DifferentialPair.h" +#include "hurricaneAMS/devices/CommonSourcePair.h" + +#include "anabatic/Session.h" +#include "anabatic/GCell.h" +#include "anabatic/Dijkstra.h" +#include "anabatic/Matrix.h" +#include "crlcore/RoutingGauge.h" +#include "katana/KatanaEngine.h" +#include "vlsisapd/openChams/SlicingTree.h" + + + + +const unsigned int presetMask = 0x1; +const unsigned int setMask = 0x2; +const unsigned int placedMask = 0x4; +const unsigned int alignmentMask = 0x1F8; +const unsigned int slicingTypeMask = 0x3E00; +const unsigned int overCellMask = 0x8000; +const unsigned int routingEstimatedMask = 0x10000; +const unsigned int routingCreatedMask = 0x20000; +const unsigned int symmetricMask = 0xC0000; + +enum Flags { Preset = 1 << 0 + , Set = 1 << 1 + , Placed = 1 << 2 + , UnknownAlignment = 1 << 3 + + , AlignLeft = 1 << 4 + , AlignRight = 1 << 5 + , AlignCenter = 1 << 6 + , AlignTop = 1 << 7 + + , AlignBottom = 1 << 8 + , UnknownType = 1 << 9 + , HorizontalSNode = 1 << 10 + , VerticalSNode = 1 << 11 + + , DeviceSNode = 1 << 12 + , RoutingSNode = 1 << 13 + , None = 1 << 14 + , MX = 1 << 15 + + , MY = 1 << 16 + , FixedRoutingSNode = 1 << 17 + , OverCell = 1 << 19 + + , RoutingEstimated = 1 << 20 + , RoutingCreated = 1 << 21 + + , HSymmetry = 1 << 23 + , VSymmetry = 1 << 24 + +}; + +const unsigned int sideMask = 0x1F; +const unsigned int targetMask = 0x20; +const unsigned int notPassableMask = 0x3C0; // North - South - East - West +const unsigned int notPassableNMask = 0x40; // North +const unsigned int notPassableSMask = 0x80; // South +const unsigned int notPassableEMask = 0x100; // East +const unsigned int notPassableWMask = 0x200; // West + +enum FunctionFlags { NoFlags = 0 + , ShowDiff = (1<<0) + }; + +// Make sure these restrictions are the same than in the class Device +enum Restriction { NorthBlocked = (1<<0) + , SouthBlocked = (1<<1) + , EastBlocked = (1<<2) + , WestBlocked = (1<<3) + , AllBlocked = NorthBlocked|SouthBlocked|EastBlocked|WestBlocked +}; +// -----------------------------------------------------------------------------------------------// +// Class : BoxSet +// Description: +// A dimension defined by a width and a height for slicing nodes. +// - HBoxSet are used for HSlicingNode: +// -> width = max(children's widths), height = sum(children's heights) +// - VBoxSet are used for VSlicingNode: +// -> width = sum(children's widths), height = max(children's heights) +// - DBoxSet are used for DSlicingNode: +// -> width = device's width, height = device's height +// - RHBoxSet are used for RHSlicingNode: +// -> height = routing space's height +// - RVBoxSet are used for RVSlicingNode: +// -> width = routing space's width +// -----------------------------------------------------------------------------------------------// + + +class ChannelRouting +{ + private: + ChannelRouting(); + ~ChannelRouting(); + + public: + static ChannelRouting* create (); + void destroy (); + int getMaxCount () const; + void insertChannel( DbU::Unit xy1, DbU::Unit xy2 ); + void insertChannel( DbU::Unit xy1, DbU::Unit xy2, unsigned int w ); + void reset (); + void print () const; + + private: + std::vector _limits; + std::vector _counts; + +}; + + +class BoxSet +{ + public: + BoxSet ( DbU::Unit height = 0, DbU::Unit width = 0 ); + BoxSet ( BoxSet* boxSet ); + virtual ~BoxSet (); + + inline DbU::Unit getHeight () const; + inline DbU::Unit getWidth () const; + inline unsigned int getCpt () const; + inline void incrementCpt (); + virtual BoxSet* clone () = 0; + inline double getRatio (); + inline double getArea (); + + void preDestroy (){} + virtual void destroy (); + + virtual inline unsigned int getType () const; + virtual inline double getOccupationArea () const; + virtual const std::vector& getSet () const; + virtual int getNFing () const; + virtual void print () const; + virtual double getDevicesArea () const = 0; + + virtual void setHeight ( DbU::Unit height ){}; + virtual void setWidth ( DbU::Unit width ){}; + protected: + DbU::Unit _height; + DbU::Unit _width; + unsigned int _cpt; + +}; + +inline DbU::Unit BoxSet::getHeight () const { return _height; } +inline DbU::Unit BoxSet::getWidth () const { return _width ; } +inline unsigned int BoxSet::getCpt () const { return _cpt; } +inline void BoxSet::incrementCpt () { _cpt++; } +inline double BoxSet::getRatio () { return _width/_height; } +inline double BoxSet::getArea () { return _width*_height; } + + +inline unsigned int BoxSet::getType () const { return UnknownType; } +inline double BoxSet::getOccupationArea () const { return 100; } + + +// -----------------------------------------------------------------------------------------------// +// Class : HVBoxSet +// -----------------------------------------------------------------------------------------------// + + +class HVBoxSet: public BoxSet +{ + protected: + HVBoxSet ( std::vector dimensionSet, DbU::Unit height = 0, DbU::Unit width = 0 ); + HVBoxSet ( HVBoxSet* boxSet ); + virtual ~HVBoxSet (); + + inline const std::vector& getSet () const; + inline double getOccupationArea () const; + double getDevicesArea () const; + + virtual inline void calculateHeight () = 0; + virtual inline void calculateWidth () = 0; + + protected: + std::vector _dimensionSet; +}; + +inline const std::vector& HVBoxSet::getSet () const { return _dimensionSet; } +inline double HVBoxSet::getOccupationArea () const { return getDevicesArea()/(_height * _width)*100; } + + +// -----------------------------------------------------------------------------------------------// +// Class : HBoxSet +// -----------------------------------------------------------------------------------------------// + + +class HBoxSet: public HVBoxSet +{ + protected: + HBoxSet ( std::vector dimensionSet, DbU::Unit height = 0, DbU::Unit width = 0 ); + HBoxSet ( HBoxSet* boxSet ); + ~HBoxSet (); + + public: + static HBoxSet* create ( std::vector dimensionSet, DbU::Unit height = 0, DbU::Unit width = 0 ); + HBoxSet* clone (); + inline unsigned int getType () const; + void calculateHeight (); + void calculateWidth (); + + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void destroy (); + + private: + static int _count; + static int _countAll; +}; + +inline unsigned int HBoxSet::getType () const { return HorizontalSNode; } +inline int HBoxSet::getCount () { return _count ; } +inline void HBoxSet::printCount () { std::cerr << "HBoxSet::Count = " << _count << std::endl; } +inline void HBoxSet::printCountAll () { std::cerr << "HBoxSet::CountAll = " << _countAll << std::endl; } + + +// -----------------------------------------------------------------------------------------------// +// Class : VBoxSet +// -----------------------------------------------------------------------------------------------// + + +class VBoxSet: public HVBoxSet +{ + protected: + VBoxSet ( std::vector dimensionSet, DbU::Unit height = 0, DbU::Unit width = 0 ); + VBoxSet ( VBoxSet* boxSet ); + ~VBoxSet (); + + public: + static VBoxSet* create ( std::vector dimensionSet, DbU::Unit height = 0, DbU::Unit width = 0 ); + VBoxSet* clone (); + inline unsigned int getType () const; + void calculateHeight (); + void calculateWidth (); + + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void destroy (); + + private: + static int _count; + static int _countAll; +}; + +inline unsigned int VBoxSet::getType () const { return VerticalSNode; } +inline int VBoxSet::getCount () { return _count ; } +inline void VBoxSet::printCount () { std::cerr << "VBoxSet::Count = " << _count << std::endl; } +inline void VBoxSet::printCountAll () { std::cerr << "VBoxSet::CountAll = " << _countAll << std::endl; } + + +// -----------------------------------------------------------------------------------------------// +// Class : DBoxSet +// -----------------------------------------------------------------------------------------------// + + +class DBoxSet: public BoxSet +{ + protected: + DBoxSet ( DbU::Unit height, DbU::Unit width, int nfing = 1 ); + DBoxSet ( DBoxSet* boxSet ); + ~DBoxSet (); + + public: + static DBoxSet* create ( DbU::Unit height, DbU::Unit width, int nfing = 1 ); + DBoxSet* clone (); + inline unsigned int getType () const; + inline double getDevicesArea () const; + + inline int getNFing () const; + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void destroy (); + + private: + int _nfing; + static int _count; + static int _countAll; +}; + +inline unsigned int DBoxSet::getType () const { return DeviceSNode ; } +inline double DBoxSet::getDevicesArea () const { return _height*_width; } +inline int DBoxSet::getNFing () const { return _nfing ; } +inline int DBoxSet::getCount () { return _count ; } +inline void DBoxSet::printCount () { std::cerr << "DBoxSet::Count = " << _count << std::endl; } +inline void DBoxSet::printCountAll () { std::cerr << "DBoxSet::CountAll = " << _countAll << std::endl; } + + +// -----------------------------------------------------------------------------------------------// +// Class : RHVBoxSet +// -----------------------------------------------------------------------------------------------// + + +class RHVBoxSet: public BoxSet +{ + public: + RHVBoxSet ( DbU::Unit height = 0, DbU::Unit width = 0); + RHVBoxSet ( RHVBoxSet* boxSet ); + ~RHVBoxSet (); + + inline DbU::Unit getHeight () const; + inline DbU::Unit getWidth () const; + inline unsigned int getType () const; + inline double getDevicesArea () const; + + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void destroy (); + virtual void setHeight ( DbU::Unit height ){ _height = 0; }; + virtual void setWidth ( DbU::Unit width ){ _width = 0; }; + + void print () const; + + protected: + static int _count; + static int _countAll; +}; + +inline DbU::Unit RHVBoxSet::getHeight () const { return _height ; } +inline DbU::Unit RHVBoxSet::getWidth () const { return _width ; } +inline unsigned int RHVBoxSet::getType () const { return RoutingSNode; } +inline double RHVBoxSet::getDevicesArea () const { return 0 ; } +inline int RHVBoxSet::getCount () { return _count ; } +inline void RHVBoxSet::printCount () { std::cerr << "RHVBoxSet::Count = " << _count << std::endl; } +inline void RHVBoxSet::printCountAll () { std::cerr << "RHVBoxSet::CountAll = " << _countAll << std::endl; } + + +// -----------------------------------------------------------------------------------------------// +// Class : RHBoxSet +// -----------------------------------------------------------------------------------------------// + + +class RHBoxSet: public RHVBoxSet +{ + protected: + RHBoxSet ( DbU::Unit height = 0 ); + RHBoxSet ( RHBoxSet* boxSet ); + ~RHBoxSet (); + + public: + static RHBoxSet* create ( DbU::Unit height ); + RHBoxSet* clone (); + inline void setHeight ( DbU::Unit height ); +}; + +inline void RHBoxSet::setHeight ( DbU::Unit height ){ _height = height; } + + +// -----------------------------------------------------------------------------------------------// +// Class : RVBoxSet +// -----------------------------------------------------------------------------------------------// + +class RVBoxSet: public RHVBoxSet +{ + protected: + RVBoxSet ( DbU::Unit width = 0 ); + RVBoxSet ( RVBoxSet* boxSet ); + ~RVBoxSet (); + + public: + static RVBoxSet* create ( DbU::Unit width ); + RVBoxSet* clone (); + inline void setWidth ( DbU::Unit width ); +}; + +inline void RVBoxSet::setWidth ( DbU::Unit width ){ _width = width; } + + +// -----------------------------------------------------------------------------------------------// +// Class : NodeSets +// Description: +// Contains all the possible dimensions (BoxSet) for a SlicingNode +// -----------------------------------------------------------------------------------------------// + +// To compare BoxSets +class compBoxSet +{ + public: + bool operator() ( const BoxSet* lhs, const BoxSet* rhs) { + return ( (lhs->getHeight() < rhs->getHeight()) || + ( (lhs->getHeight() == rhs->getHeight()) && (lhs->getWidth() < rhs->getWidth())) + ); + } +}; + + +class NodeSets +{ + public: + NodeSets ( double start = 0, double step = 0, double count = 0 ); + NodeSets ( const NodeSets* other ); + ~NodeSets (); + + static NodeSets* create( Cell* cell, double start, double step, double count, CRL::RoutingGauge* rg = NULL ); + static NodeSets* create(); + + BoxSet* operator[] (size_t i); + BoxSet* at (size_t i); + + inline std::vector::iterator begin (); + inline std::vector::iterator end (); + inline std::vector getNodeSets () const; + inline size_t size () const; + inline bool empty () const; + void clear (); + inline void sort (); + + BoxSet* getPairH ( DbU::Unit height ) const; + BoxSet* getPairHW ( DbU::Unit height, DbU::Unit width ) const; + BoxSet* getPairHW ( unsigned int index ) const; + int findIndex ( DbU::Unit height, DbU::Unit width ) const; + std::vector::iterator find ( DbU::Unit height, DbU::Unit width ); + std::vector::iterator find ( BoxSet* boxSet ); + std::vector::iterator find ( int nfing ); + + void print () const; + bool compare ( NodeSets nodeSets2, unsigned int flags=NoFlags ) const; + void push_back ( BoxSet* boxSet ); + void push_back ( std::vector vect, DbU::Unit height, DbU::Unit width, unsigned int type ); + void push_back ( DbU::Unit height, DbU::Unit width ); + NodeSets* clone (); + + inline double getStartParameter () const; + inline double getStepParameter () const; + inline double getCountParameter () const; + + + private: + std::vector _nodeSets; + int _start; + int _step; + int _count; +}; + +inline std::vector::iterator NodeSets::begin () { return _nodeSets.begin(); } +inline std::vector::iterator NodeSets::end () { return _nodeSets.end (); } +inline std::vector NodeSets::getNodeSets () const { return _nodeSets; } +inline size_t NodeSets::size () const { return _nodeSets.size() ; } +inline bool NodeSets::empty () const { return _nodeSets.empty(); } +inline void NodeSets::sort () { std::sort( _nodeSets.begin(),_nodeSets.end(), compBoxSet() ); } +inline double NodeSets::getStartParameter () const { return _start; } +inline double NodeSets::getStepParameter () const { return _step ; } +inline double NodeSets::getCountParameter () const { return _count; } + + +// -----------------------------------------------------------------------------------------------// +// Class : SlicingNode +// Description: +// Node used for building a slicing tree used for device's placement. +// Step 1: Build - build the slicing tree +// Step 2: Update - possible dimensions (updateGlobalSize) +// Step 3: Select - select the desired dimension (setGlobalSize) +// -----------------------------------------------------------------------------------------------// + + +class SlicingNode +{ + protected: + SlicingNode ( unsigned int type + , NodeSets* nodeSets = NodeSets::create() + , unsigned int alignment = UnknownAlignment + , BoxSet* boxSet = NULL + ); + virtual ~SlicingNode (); + + public: + inline bool isPreset () const; + inline bool isSet () const; + inline bool isPlaced () const; + inline bool isAlignLeft () const; + inline bool isAlignRight () const; + inline bool isAlignCenter () const; + inline bool isAlignTop () const; + inline bool isAlignBottom () const; + inline bool isHorizontal () const; + inline bool isVertical () const; + inline bool isDevice () const; + inline bool isRouting () const; + bool isSameSize ( BoxSet* boxSet ) const; + bool isSameSize ( DbU::Unit height, DbU::Unit width ) const; + bool isEmpty () const; + inline bool isOverCell () const; + inline bool isRoutingCreated () const; + virtual inline bool isRoutingEstimated () const; + bool isHSymmetry () const; + bool isVSymmetry () const; + virtual inline bool isAnalog () const; + virtual inline bool isDigital () const; + + inline unsigned int getPreset () const; + inline unsigned int getSet () const; + inline unsigned int getPlaced () const; + inline unsigned int getAlignment () const; + inline unsigned int getType () const; + virtual DbU::Unit getHeight () const; + virtual DbU::Unit getWidth () const; + DbU::Unit getRootHeight () const; + DbU::Unit getRootWidth () const; + inline BoxSet* getBoxSet () const; + inline DbU::Unit getX () const; + inline DbU::Unit getY () const; + DbU::Unit getRootX () const; + DbU::Unit getRootY () const; + inline DbU::Unit getXCenter () const; + inline DbU::Unit getYCenter () const; + inline NodeSets* getNodeSets () const; + inline SlicingNode* getParent () const; + inline BoxSet* getPairH ( DbU::Unit h ) const; + inline BoxSet* getPairHW ( DbU::Unit height, DbU::Unit width ) const; + inline BoxSet* getPairHW ( int index ) const; + SlicingNode* getRoot (); + int getCpt (); + double getRatio (); + double getArea (); + static inline AnalogTechnology* getTechnology (); + static inline Cell* getCell (); + inline Anabatic::GCell* getGCell () const; + inline CRL::RoutingGauge* getRoutingGauge () const; + inline SlicingNode* getMaster () const; + DbU::Unit getVPitch (); + DbU::Unit getHPitch (); + + inline void setPreset ( unsigned int preset ); + inline void setSet ( unsigned int set ); + virtual inline void setPlaced ( unsigned int placed ); + inline void setAlignment ( unsigned int alignment ); + inline void setType ( unsigned int type ); + void setBoxSet ( BoxSet* boxSet ); + void setBoxSet ( DbU::Unit height, DbU::Unit width ); + void setBoxSet ( size_t index ); + void _setBoxSet ( BoxSet* boxSet ); + void setX ( DbU::Unit x ); + void setY ( DbU::Unit y ); + inline void setNodeSets ( NodeSets* nodeSets ); + inline void setParent ( SlicingNode* parent ); + inline void setPairH ( DbU::Unit height ); + inline void setPairHW ( DbU::Unit height, DbU::Unit width ); + + inline void setOverCell ( unsigned int overCell ); + inline void setRoutingCreated ( unsigned int routingCreated ); + inline void setRoutingEstimated ( unsigned int RoutingEstimated ); + static void setRoutingGauge ( CRL::RoutingGauge* rg ); + void setCell ( Cell* cell ); + void setKatana ( Katana::KatanaEngine* katana ); + virtual inline void setSymmetryFlag ( unsigned int flag ); + virtual inline void setMaster ( SlicingNode* master ); + virtual void setHeight ( DbU::Unit height ){}; + virtual void setWidth ( DbU::Unit width ){}; + + inline void clearNodeSets (); + void clearParentsNodeSets (); + inline void removeParent (); + virtual void resetSlicingTree (); // see notes in .cpp + virtual void _resetSlicingTree (); + + virtual void print () const; + virtual void printLine () const; + virtual void printParent () const; + void printBoxSet () const; + virtual void place ( DbU::Unit x = 0 , DbU::Unit y = 0 ); + virtual void replace ( DbU::Unit x = 0 , DbU::Unit y = 0 ); + virtual void _place ( DbU::Unit x = 0 , DbU::Unit y = 0, bool replace = false ); + virtual void updateGlobalSize (){}; + virtual void setGlobalSize ( DbU::Unit height, DbU::Unit width ); + virtual void setGlobalSize ( size_t index ); + virtual void _setGlobalSize ( BoxSet* boxSet ); + virtual inline bool recursiveCheckPreset () const; + virtual inline bool recursiveCheckSet () const; + virtual inline bool recursiveCheckPlaced () const; + virtual inline int getLeafNumber () const; + virtual void preDestroy (); + virtual void destroy (); + virtual void preRecursiveDestroy (); + virtual void recursiveDestroy (); + + virtual OpenChams::SlicingNode* toOpenChams (){ return NULL; }; + virtual std::list getLeaves () const; + virtual bool checkInitialPlacement( int& cpt ) const; // see notes in .cpp + void updateCellAbutmentBox(); + virtual void setGCell ( Anabatic::GCell* gcell ); + virtual bool isSymmetric ( SlicingNode* node, unsigned int symmetryType, unsigned int flags=NoFlags ) const = 0; + virtual bool isSame ( SlicingNode* node, unsigned int flags=NoFlags ) const = 0; + + static void createRoutingPads (); + static void clearRoutingPads (); + virtual void restrictDevices (); + virtual void setVertexRestriction ( Net* net, Katana::KatanaEngine* katana ); + virtual void estimateChannelsSize (); + virtual void expandRoutingChannel (); + virtual void _expandRoutingChannel(); + virtual void expandRoutingChannel ( DbU::Unit height, DbU::Unit width ); + virtual void clearGlobalRouting (); + virtual void clearGCells (); + virtual void adjustBorderChannels (){}; + + bool containAxis ( DbU::Unit axis, unsigned int symmetryType ); + virtual void updateMasterSize ( DbU::Unit size ) {} + + + // Error Methods + virtual DbU::Unit getToleranceRatioH () const; + virtual DbU::Unit getToleranceRatioW () const; + virtual void setToleranceRatioH ( DbU::Unit tolerance ); + virtual void setToleranceRatioW ( DbU::Unit tolerance ); + virtual DbU::Unit getToleranceBandH () const; + virtual DbU::Unit getToleranceBandW () const; + virtual void setToleranceBandH ( DbU::Unit tolerance ); + virtual void setToleranceBandW ( DbU::Unit tolerance ); + virtual void recursiveSetToleranceRatioH ( DbU::Unit tolerance ); + virtual void recursiveSetToleranceRatioW ( DbU::Unit tolerance ); + virtual void recursiveSetToleranceBandH ( DbU::Unit tolerance ); + virtual void recursiveSetToleranceBandW ( DbU::Unit tolerance ); + virtual void _recursiveSetToleranceRatioH ( DbU::Unit tolerance ); + virtual void _recursiveSetToleranceRatioW ( DbU::Unit tolerance ); + virtual void _recursiveSetToleranceBandH ( DbU::Unit tolerance ); + virtual void _recursiveSetToleranceBandW ( DbU::Unit tolerance ); + virtual void setTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ); + virtual void recursiveSetTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ); + virtual void _recursiveSetTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ); + + virtual bool hasEmptyChildrenNodeSets () const; + virtual const std::vector& getChildren () const; + virtual SlicingNode* getChild ( int index ) const; + virtual int getChildIndex ( SlicingNode* node ) const; + virtual size_t getNbChild () const; + virtual void createChild ( unsigned int type, unsigned int alignment ); + virtual void createChild ( NodeSets* nodeSets + , unsigned int alignment = UnknownAlignment + , Instance* instance = NULL + , BoxSet* boxSet = NULL + ); + virtual void createChild ( int childIndex, int copyIndex, unsigned int tr ); + virtual void createRouting ( DbU::Unit space ); + virtual void insertNode ( SlicingNode* node, int index ); + virtual void push_back ( SlicingNode* node, bool reset = false ); + virtual void push_front ( SlicingNode* node ); + virtual void removeNode ( SlicingNode* node ); + virtual void removeAllNodes (); + + virtual std::list > getSymmetries () const; + virtual void setSymmetries ( std::list > sym ); + virtual bool isSymmetry ( int index, std::pair& symmetry ); + virtual bool isSymmetry ( int index ); + virtual void addSymmetry ( int childIndex, int copyIndex, bool reset = true ); + virtual void removeSymmetry ( int index ); + virtual void normalizeSymmetries (); + + virtual void printChildren () const; + virtual void printChildrenLine () const; + virtual SlicingNode* clone ( unsigned int tr = None ) = 0; + virtual double getDevicesArea () const = 0; + virtual double getOccupationArea () const; + virtual void setNFing ( int nfing ); + virtual int getNFing () const; + virtual double getStartParameter () const; + virtual double getStepParameter () const; + virtual double getCountParameter () const; + virtual Instance* getInstance () const; + virtual void setInstance ( Instance* instance ); + + virtual bool checkCellInstances ( Cell* cell ); + virtual SlicingNode* findInstance ( Instance* instance ); + virtual SlicingNode* findSlicingNode ( Anabatic::GCell* gcell ); + virtual void updateGCellPosition (); + virtual void updateGContacts (); + virtual void updateMatrixGCellPosition(); + virtual void updateMatrixGContacts (); + virtual int getNbDevices (); + + // Methods to be tested + virtual void createSlicingRouting (); + virtual void resetSlicingRouting (); + virtual void destroySlicingRouting (); + + virtual int getRoutingIndex ( SlicingNode* node ) const; + virtual SlicingNode* getSlicingRouting ( int index ) const; + SlicingNode* findHorizontalParent () const; + SlicingNode* findVerticalParent () const; + int getIndexInHorizontalParent() const; + int getIndexInVerticalParent () const; + + + virtual bool checkSymmetryNet ( unsigned int type, Net* net1, Net* net2 = NULL ) const; + virtual void addSymmetryNet ( unsigned int type, Net* net1, Net* net2 = NULL ); + virtual void updateNetConstraints (); + virtual void updateSymNetAxis (); + + virtual string _getString () const; + virtual string _getTypeName () const; + static void addRailSegments ( Hurricane::Segment* s ); + static bool isRailSegments ( Hurricane::Segment* s ); + static bool isRailSegments ( Hurricane::Plug* p ); + void createRailCell (); + virtual void flattenDigitalNets(); + + virtual void updateWireOccupation ( Anabatic::VertexSet ); + virtual void resetWireOccupation (); + virtual void addWireOccupation ( DbU::Unit min, DbU::Unit max ); + virtual int getMaxWireOccupation (); + protected: + static CRL::RoutingGauge* _rg; + static Cell* _cell; + static Katana::KatanaEngine* _katana; + //static Cell* _railCell; + static vector _railSegments; + + SlicingNode* _parent; + unsigned int _flags; + NodeSets* _nodeSets; + DbU::Unit _x; + DbU::Unit _y; + BoxSet* _boxSet; + Anabatic::GCell* _gcell; + SlicingNode* _master; +}; + +inline bool SlicingNode::isPreset () const { return (_flags & Preset) ; } +inline bool SlicingNode::isSet () const { return (_flags & Set) ; } +inline bool SlicingNode::isPlaced () const { return (_flags & Placed) ; } +inline bool SlicingNode::isAlignLeft () const { return (_flags & AlignLeft) ; } +inline bool SlicingNode::isAlignRight () const { return (_flags & AlignRight) ; } +inline bool SlicingNode::isAlignCenter () const { return (_flags & AlignCenter); } +inline bool SlicingNode::isAlignTop () const { return (_flags & AlignTop) ; } +inline bool SlicingNode::isAlignBottom () const { return (_flags & AlignBottom); } +inline bool SlicingNode::isHorizontal () const { return (_flags & HorizontalSNode) ; } +inline bool SlicingNode::isVertical () const { return (_flags & VerticalSNode) ; } +inline bool SlicingNode::isDevice () const { return (_flags & DeviceSNode) ; } +inline bool SlicingNode::isRouting () const { return (_flags & RoutingSNode) ; } + +inline bool SlicingNode::isHSymmetry () const { return (_flags & HSymmetry); } +inline bool SlicingNode::isVSymmetry () const { return (_flags & VSymmetry); } + +inline bool SlicingNode::isOverCell () const { return (_flags & OverCell ); } +inline bool SlicingNode::isRoutingCreated () const { return (_flags & RoutingCreated ); } +inline bool SlicingNode::isRoutingEstimated () const { return true; } + +inline bool SlicingNode::isAnalog () const { return false; } +inline bool SlicingNode::isDigital () const { return false; } + +inline unsigned int SlicingNode::getPreset () const { return (_flags & presetMask ); } +inline unsigned int SlicingNode::getSet () const { return (_flags & setMask ); } +inline unsigned int SlicingNode::getPlaced () const { return (_flags & placedMask ); } +inline unsigned int SlicingNode::getAlignment () const { return (_flags & alignmentMask ); } +inline unsigned int SlicingNode::getType () const { return (_flags & slicingTypeMask); } +inline BoxSet* SlicingNode::getBoxSet () const { return _boxSet; } +inline DbU::Unit SlicingNode::getX () const { return _x; } +inline DbU::Unit SlicingNode::getY () const { return _y; } +inline DbU::Unit SlicingNode::getXCenter () const { return getX() + getWidth()/2; } +inline DbU::Unit SlicingNode::getYCenter () const { return getY() + getHeight()/2; } +inline NodeSets* SlicingNode::getNodeSets () const { return _nodeSets; } +inline SlicingNode* SlicingNode::getParent () const { return _parent; } +inline Cell* SlicingNode::getCell () { return _cell; } +inline Anabatic::GCell* SlicingNode::getGCell () const { return _gcell; } +inline CRL::RoutingGauge* SlicingNode::getRoutingGauge() const { return _rg; } +inline SlicingNode* SlicingNode::getMaster () const { return _master; } + +inline BoxSet* SlicingNode::getPairH ( DbU::Unit height ) const { return _nodeSets->getPairH(height); } +inline BoxSet* SlicingNode::getPairHW ( DbU::Unit height, DbU::Unit width ) const { return _nodeSets->getPairHW(height, width); } +inline BoxSet* SlicingNode::getPairHW ( int index ) const { return _nodeSets->getPairHW(index); } +inline void SlicingNode::setPreset ( unsigned int preset ) { _flags = ((_flags & ~(presetMask) ) | preset ); } +inline void SlicingNode::setSet ( unsigned int set ) { _flags = ((_flags & ~(setMask) ) | set ); } +inline void SlicingNode::setPlaced ( unsigned int placed ) { _flags = ((_flags & ~(placedMask) ) | placed ); } +inline void SlicingNode::setAlignment ( unsigned int alignment ) { _flags = ((_flags & ~(alignmentMask) ) | alignment); } +inline void SlicingNode::setType ( unsigned int type ) { _flags = ((_flags & ~(slicingTypeMask) ) | type ); } +inline void SlicingNode::setNodeSets ( NodeSets* nodeSets ) { _nodeSets = nodeSets; } +inline void SlicingNode::setParent ( SlicingNode* parent ) { _parent = parent; } +inline void SlicingNode::setPairH ( DbU::Unit height ) { _boxSet = this->getPairH(height); } +inline void SlicingNode::setPairHW ( DbU::Unit height, DbU::Unit width ) { _boxSet = this->getPairHW(height, width); } +//inline void SlicingNode::setRoutingGauge ( CRL::RoutingGauge* rg ) { _rg = rg; } +inline void SlicingNode::setSymmetryFlag ( unsigned int flag ) { _flags = ((_flags & ~(symmetricMask) ) | flag ); } +inline void SlicingNode::setMaster ( SlicingNode* master ) { _master = master; } + +inline void SlicingNode::setOverCell ( unsigned int overCell ) { _flags = ((_flags & ~(overCellMask )) | overCell) ; } +inline void SlicingNode::setRoutingCreated ( unsigned int routingCreated ){ _flags = ((_flags & ~(routingCreatedMask )) | routingCreated ); } +inline void SlicingNode::setRoutingEstimated ( unsigned int routingEstimated ){ _flags = ((_flags & ~(routingEstimatedMask)) | routingEstimated); } + +inline void SlicingNode::clearNodeSets () { _nodeSets->clear(); } +inline void SlicingNode::removeParent () { _parent = NULL; } + +inline bool SlicingNode::recursiveCheckPreset () const { return isPreset(); } +inline bool SlicingNode::recursiveCheckSet () const { return isSet (); } +inline bool SlicingNode::recursiveCheckPlaced () const { return isPlaced(); } +inline int SlicingNode::getLeafNumber () const { return 1 ; } + + +// -----------------------------------------------------------------------------------------------// +// Class : HVSlicingNode +// -----------------------------------------------------------------------------------------------// + +class RHVSlicingNode; + +class HVSlicingNode: public SlicingNode +{ + public: + typedef SlicingNode Super; + protected: + HVSlicingNode ( unsigned int type, unsigned int alignment = AlignLeft ); + virtual ~HVSlicingNode (); + + public: + inline DbU::Unit getToleranceRatioH () const; + inline DbU::Unit getToleranceRatioW () const; + void setToleranceRatioH ( DbU::Unit tolerance ); + void setToleranceRatioW ( DbU::Unit tolerance ); + inline DbU::Unit getToleranceBandH () const; + inline DbU::Unit getToleranceBandW () const; + void setToleranceBandH ( DbU::Unit tolerance ); + void setToleranceBandW ( DbU::Unit tolerance ); + void recursiveSetToleranceRatioH ( DbU::Unit tolerance ); + void recursiveSetToleranceRatioW ( DbU::Unit tolerance ); + void recursiveSetToleranceBandH ( DbU::Unit tolerance ); + void recursiveSetToleranceBandW ( DbU::Unit tolerance ); + + void _recursiveSetToleranceRatioH ( DbU::Unit tolerance ); + void _recursiveSetToleranceRatioW ( DbU::Unit tolerance ); + void _recursiveSetToleranceBandH ( DbU::Unit tolerance ); + void _recursiveSetToleranceBandW ( DbU::Unit tolerance ); + void setTolerances ( DbU::Unit trh + , DbU::Unit trw + , DbU::Unit tbh + , DbU::Unit tbw + ); + void recursiveSetTolerances ( DbU::Unit trh + , DbU::Unit trw + , DbU::Unit tbh + , DbU::Unit tbw + ); + void _recursiveSetTolerances ( DbU::Unit trh + , DbU::Unit trw + , DbU::Unit tbh + , DbU::Unit tbw + ); + + bool hasEmptyChildrenNodeSets () const; + inline const std::vector& getChildren () const; + inline SlicingNode* getChild ( int index ) const; + int getChildIndex ( SlicingNode* node ) const; + inline size_t getNbChild () const; + void createChild ( unsigned int type, unsigned int alignment ); + void createChild ( NodeSets* nodeSets + , unsigned int alignment = UnknownAlignment + , Instance* instance = NULL + , BoxSet* boxSet = NULL + ); + void createChild ( int childIndex, int copyIndex, unsigned int tr ); + void insertNode ( SlicingNode* node, int index ); + void push_back ( SlicingNode* node, bool reset = true ); + void push_front ( SlicingNode* node ); + void removeNode ( SlicingNode* node ); + inline void removeAllNodes (); + + inline std::list > getSymmetries () const; + inline void setSymmetries ( std::list > sym ); + bool isSymmetry ( int index, std::pair& symmetry ); + bool isSymmetry ( int index ); + void addSymmetry ( int childIndex, int copyIndex, bool reset = true ); + void removeSymmetry ( int index ); + void normalizeSymmetries (); // see notes in .cpp + + void preDestroy (); + void destroy (); + void preRecursiveDestroy (); + void recursiveDestroy (); + + void _resetSlicingTree (); + void print () const; + void printChildren () const; + void printLine () const; + void printChildrenLine () const; + bool recursiveCheckPreset () const; + bool recursiveCheckSet () const; + bool recursiveCheckPlaced () const; + int getLeafNumber () const; + double getDevicesArea () const; + double getOccupationArea () const; + void setGlobalSize ( DbU::Unit height, DbU::Unit width ); + void setGlobalSize ( size_t index ); + void _setGlobalSize ( BoxSet* boxSet ); + std::list getLeaves () const; + bool checkInitialPlacement ( int& cpt ) const; // see notes in .cpp + + bool isSymmetric ( SlicingNode* node, unsigned int symmetryType, unsigned int flags=NoFlags ) const; + bool isSame ( SlicingNode* node, unsigned int flags=NoFlags ) const; + void restrictDevices (); + void setVertexRestriction ( Net* net, Katana::KatanaEngine* katana ); + void estimateChannelsSize (); + void expandRoutingChannel (); + void _expandRoutingChannel (); + void expandRoutingChannel ( DbU::Unit height, DbU::Unit width ); + bool isRoutingEstimated () const; + + void updateGCellPosition (); + void updateGContacts (); + int getNbDevices (); + virtual string _getString () const; + virtual string _getTypeName () const; + void setSymmetryFlag ( unsigned int flag ); + void setMaster ( SlicingNode* master ); + + // Start here + bool checkCellInstances ( Cell* cell ); + SlicingNode* findInstance ( Instance* instance ); + SlicingNode* findSlicingNode ( Anabatic::GCell* gcell ); + + void resetSlicingRouting (); + void destroySlicingRouting (); + + int getRoutingIndex ( SlicingNode* node ) const; + SlicingNode* getSlicingRouting ( int index ) const; + void clearGCells (); + bool checkSymmetryNet ( unsigned int type, Net* net1, Net* net2 = NULL ) const; + void addSymmetryNet ( unsigned int type, Net* net1, Net* net2 = NULL ); + void updateNetConstraints (); + void updateSymNetAxis (); + void flattenDigitalNets (); + + void updateWireOccupation ( Anabatic::VertexSet ); + void resetWireOccupation (); + + protected: + std::vector _children; + DbU::Unit _toleranceRatioH; + DbU::Unit _toleranceRatioW; + DbU::Unit _toleranceBandH; + DbU::Unit _toleranceBandW; + std::list > _symmetries; + std::vector _slicingRouting; + std::vector > _netsymmetries; +}; + +inline DbU::Unit HVSlicingNode::getToleranceRatioH () const { return _toleranceRatioH; } +inline DbU::Unit HVSlicingNode::getToleranceRatioW () const { return _toleranceRatioW; } +inline DbU::Unit HVSlicingNode::getToleranceBandH () const { return _toleranceBandH; } +inline DbU::Unit HVSlicingNode::getToleranceBandW () const { return _toleranceBandW; } + +inline const std::vector& HVSlicingNode::getChildren () const { return _children; } +inline SlicingNode* HVSlicingNode::getChild ( int index ) const { return _children[index]; } +inline size_t HVSlicingNode::getNbChild () const { return _children.size(); } +inline void HVSlicingNode::removeAllNodes () { _children.clear(); } + +inline std::list > HVSlicingNode::getSymmetries () const { return _symmetries; } +inline void HVSlicingNode::setSymmetries ( std::list > sym ) { _symmetries = sym; } + +// -----------------------------------------------------------------------------------------------// +// Class : HSlicingNode +// -----------------------------------------------------------------------------------------------// + + +class HSlicingNode: public HVSlicingNode +{ + public: + typedef HVSlicingNode Super; + private: + HSlicingNode ( unsigned int type, unsigned int alignment = UnknownAlignment ); + ~HSlicingNode (); + + public: + static HSlicingNode* create ( unsigned int alignment = AlignLeft ); + void createRouting ( DbU::Unit space ); + + void print () const; + HSlicingNode* clone ( unsigned int tr = None ); + void place ( DbU::Unit x = 0, DbU::Unit y = 0 ); + void replace ( DbU::Unit x = 0, DbU::Unit y = 0 ); + void _place ( DbU::Unit x = 0, DbU::Unit y = 0, bool replace = false ); + void updateGlobalSize (); + + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void preDestroy (); + void destroy (); + void preRecursiveDestroy (); + void recursiveDestroy (); + + OpenChams::SlicingNode* toOpenChams (); + + DbU::Unit getHeight () const; + DbU::Unit getWidth () const; + + void createSlicingRouting (); + void setGCell ( Anabatic::GCell* gcell ); + void adjustBorderChannels (); + virtual string _getString () const; + virtual string _getTypeName () const; + + private: + static int _count; + static int _countAll; +}; + +inline int HSlicingNode::getCount () { return _count; } +inline void HSlicingNode::printCount () { std::cerr << "HSlicingNode::Count = " << _count << std::endl; } +inline void HSlicingNode::printCountAll () { std::cerr << "HSlicingNode::CountAll = " << _countAll << std::endl; } + + +// -----------------------------------------------------------------------------------------------// +// Class : VSlicingNode +// -----------------------------------------------------------------------------------------------// + + +class VSlicingNode: public HVSlicingNode +{ + public: + typedef HVSlicingNode Super; + private: + VSlicingNode ( unsigned int type, unsigned int alignment = UnknownAlignment); + ~VSlicingNode (); + + public: + static VSlicingNode* create ( unsigned int alignment = AlignBottom ); + void createRouting ( DbU::Unit space ); + + void print () const; + VSlicingNode* clone ( unsigned int tr = None ); + void place ( DbU::Unit x = 0, DbU::Unit y = 0 ); + void replace ( DbU::Unit x = 0, DbU::Unit y = 0 ); + void _place ( DbU::Unit x = 0, DbU::Unit y = 0, bool replace = false ); + void updateGlobalSize (); + + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void preDestroy (); + void destroy (); + void preRecursiveDestroy (); + void recursiveDestroy (); + + OpenChams::SlicingNode* toOpenChams (); + DbU::Unit getHeight () const; + DbU::Unit getWidth () const; + + void createSlicingRouting (); + void setGCell ( Anabatic::GCell* gcell ); + void adjustBorderChannels (); + virtual string _getString () const; + virtual string _getTypeName () const; + + + private: + static int _count; + static int _countAll; +}; + +inline int VSlicingNode::getCount () { return _count; } +inline void VSlicingNode::printCount () { std::cerr << "VSlicingNode::Count = " << _count << std::endl; } +inline void VSlicingNode::printCountAll () { std::cerr << "VSlicingNode::CountAll = " << _countAll << std::endl; } + + +// -----------------------------------------------------------------------------------------------// +// Class : DSlicingNode +// -----------------------------------------------------------------------------------------------// + + +class DSlicingNode: public SlicingNode +{ + public: + typedef SlicingNode Super; + private: + DSlicingNode ( unsigned int type + , NodeSets* nodeSets + , unsigned int alignment = UnknownAlignment + , Instance* instance = NULL + , BoxSet* boxSet = NULL + ); + ~DSlicingNode (); + + public: + static DSlicingNode* create ( NodeSets* nodeSets + , unsigned int alignment = UnknownAlignment + , Instance* instance = NULL + , BoxSet* boxSet = NULL + ); + void print () const; + DSlicingNode* clone ( unsigned int tr = None ); + inline double getDevicesArea () const; + void setNFing ( int nfing ); + int getNFing () const; + inline Instance* getInstance () const; + inline void setInstance ( Instance* instance ); + void place ( DbU::Unit x = 0, DbU::Unit y = 0 ); + void _place ( DbU::Unit x = 0, DbU::Unit y = 0, bool replace = false ); + + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void preDestroy (); + void destroy (); + void preRecursiveDestroy (); + void recursiveDestroy (); + + OpenChams::SlicingNode* toOpenChams (); + double getStartParameter () const; + double getStepParameter () const; + double getCountParameter () const; + bool checkInitialPlacement ( int& cpt ) const;// see notes in .cpp + + void setGCell ( Anabatic::GCell* gcell ); + bool isSame ( SlicingNode* node ) const; + bool isSymmetric ( SlicingNode* node, unsigned int symmetryType, unsigned int flags=NoFlags ) const; + bool isSame ( SlicingNode* node, unsigned int glags=NoFlags ) const; + + void updateGCellPosition (); + void updateGContacts (); + void updateMatrixGCellPosition(); + void updateMatrixGContacts (); + void restrictDevices (); + void printLine () const; + bool isAnalog () const; + bool isDigital () const; + bool checkCellInstances ( Cell* cell ); + + virtual string _getString () const; + virtual string _getTypeName () const; + + private: + Instance* _instance; + static int _count; + static int _countAll; +}; + +inline double DSlicingNode::getDevicesArea () const { return this->getHeight()*this->getWidth(); } +inline Instance* DSlicingNode::getInstance () const { return _instance; } +inline void DSlicingNode::setInstance ( Instance* instance ) { _instance = instance; } +inline int DSlicingNode::getCount () { return _count ; } +inline void DSlicingNode::printCount () { std::cerr << "DSlicingNode::Count = " << _count << std::endl; } +inline void DSlicingNode::printCountAll () { std::cerr << "DSlicingNode::CountAll = " << _countAll << std::endl; } + + +// -----------------------------------------------------------------------------------------------// +// Class : RHVSlicingNode +// -----------------------------------------------------------------------------------------------// + + +class RHVSlicingNode: public SlicingNode +{ + protected: + RHVSlicingNode (); + ~RHVSlicingNode (); + + public: + void print () const; + void _setGlobalSize ( DbU::Unit height, DbU::Unit width = 0 ); + inline double getDevicesArea () const; + inline bool isRoutingEstimated () const; + + // Error Message Methods + unsigned int getAlignment () const; + NodeSets* getNodeSets () const; + BoxSet* getPairH ( DbU::Unit height ) const; + BoxSet* getPairHW ( DbU::Unit height, DbU::Unit width ) const; + void setPairH ( DbU::Unit height ); + void setPairHW ( DbU::Unit height, DbU::Unit width ); + + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void preDestroy (); + void destroy (); + void preRecursiveDestroy (); + void recursiveDestroy (); + + void resetSize (); + void setHeight ( DbU::Unit height ){}; + void setWidth ( DbU::Unit width ){}; + + bool isSame ( SlicingNode* node, unsigned int flags=NoFlags ) const; + bool isSymmetric ( SlicingNode* node, unsigned int symmetryType, unsigned int flags=NoFlags ) const; + void estimateChannelsSize (){} + void _expandRoutingChannel(){}; + void expandRoutingChannel ( DbU::Unit height, DbU::Unit width ){} + + void _place ( DbU::Unit x = 0, DbU::Unit y = 0, bool replace = false ); + + void setRailInstance ( Hurricane::Instance* i ); + inline Hurricane::Instance* getRailInstance () const ; + + void addWireOccupation ( DbU::Unit min, DbU::Unit max ); + void resetWireOccupation (); + int getMaxWireOccupation (); + + protected: + Hurricane::Instance* _railInstance; + static int _count; + static int _countAll; + DbU::Unit _minHeight; + DbU::Unit _minWidth; + ChannelRouting* _wireOccupation; + +}; + +inline double RHVSlicingNode::getDevicesArea () const { return 0; } +inline int RHVSlicingNode::getCount () { return _count; } +inline void RHVSlicingNode::printCount () { std::cerr << "RHVSlicingNode::Count = " << _count << std::endl; } +inline void RHVSlicingNode::printCountAll () { std::cerr << "RHVSlicingNode::CountAll = " << _countAll << std::endl; } +inline bool RHVSlicingNode::isRoutingEstimated() const { return (_flags & RoutingEstimated); } +//inline void RHVSlicingNode::setSegment(Hurricane::Segment* s) { _segment = s; } +inline Hurricane::Instance* RHVSlicingNode::getRailInstance () const { return _railInstance; } + +// -----------------------------------------------------------------------------------------------// +// Class : RHSlicingNode +// -----------------------------------------------------------------------------------------------// + + +class RHSlicingNode: public RHVSlicingNode +{ + private: + RHSlicingNode ( DbU::Unit height = 0 ); + //RHSlicingNode ( Hurricane::Horizontal* h ); + RHSlicingNode ( Hurricane::Instance* i ); + ~RHSlicingNode (); + + public: + static RHSlicingNode* create ( DbU::Unit height = DbU::Unit(0) ); + //static RHSlicingNode* create ( Hurricane::Horizontal* h ); + static RHSlicingNode* create ( Hurricane::Net* net + , Hurricane::Layer* layer + , int npitch + , string cname + , string iname + ); + //static RHSlicingNode* create ( OpenChams::SlicingNode* ocSlicingTree, CRL::RoutingGauge* rg ); + RHSlicingNode* clone ( unsigned int tr = None ); + + OpenChams::SlicingNode* toOpenChams(); + DbU::Unit getWidth () const; + void setHeight ( DbU::Unit height ); + + void estimateChannelsSize (); + void _expandRoutingChannel(); + void expandRoutingChannel ( DbU::Unit height, DbU::Unit width ); + void setGCell ( Anabatic::GCell* gcell ); + void updateMasterSize ( DbU::Unit size ); + virtual string _getTypeName () const; + + // Error Message Methods + void setWidth ( DbU::Unit width ); +}; + + +// -----------------------------------------------------------------------------------------------// +// Class : RVSlicingNode +// -----------------------------------------------------------------------------------------------// + + +class RVSlicingNode: public RHVSlicingNode +{ + private: + RVSlicingNode ( DbU::Unit width = 0 ); + //RVSlicingNode ( Hurricane::Vertical* v ); + RVSlicingNode ( Hurricane::Instance* i ); + ~RVSlicingNode (); + + public: + static RVSlicingNode* create ( DbU::Unit width = DbU::Unit(0) ); + static RVSlicingNode* create ( Hurricane::Vertical* v ); + static RVSlicingNode* create ( Hurricane::Net* net + , Hurricane::Layer* layer + , int npitch + , string cname + , string iname + ); + //static RVSlicingNode* create ( OpenChams::SlicingNode* ocSlicingTree, CRL::RoutingGauge* rg ); + RVSlicingNode* clone ( unsigned int tr = None ); + + OpenChams::SlicingNode* toOpenChams(); + DbU::Unit getHeight () const; + void setWidth ( DbU::Unit width ); + + void estimateChannelsSize (); + void _expandRoutingChannel(); + void expandRoutingChannel ( DbU::Unit height, DbU::Unit width ); + void setGCell ( Anabatic::GCell* gcell ); + void updateMasterSize ( DbU::Unit size ); + virtual string _getTypeName () const; + + // Error Message Methods + void setHeight ( DbU::Unit height ); +}; + + +// -----------------------------------------------------------------------------------------------// +// Class : HVSetState +// Description: +// HVSetState, HSetState and VSetState are classes used in the algorithm to determine the possible +// dimensions for a slicing tree. They are not part of the slicing tree, they only help during the +// use of updateGlobalSize. At the end of the algorithm, it should provide the resulting NodeSets. +// +// In a horizontal/vertical slicing node, the number of possible dimensions (EndCounter) to study is: +// EndCounter = N(child0) * N(child1) * ... * N(childn) +// We call a "state" a dimension for the horizontal/vertical slicing node. "EndCounter" states needs +// to be studied. +// For each states, we check if these conditions are filled: +// - Horizontal case: toleranceBandW <= max(children's width )-min(children's width ) +// - Vertical case: toleranceBandH <= max(children's height)-min(children's height) +// When the condition is filled, we add the dimensions to the NodeSets and we proceed to the next combinations. +// -----------------------------------------------------------------------------------------------// + +class HVSetState +{ + protected: + HVSetState ( HVSlicingNode* node ); + virtual ~HVSetState (); + + public: + virtual DbU::Unit getCurrentH () = 0; + virtual DbU::Unit getCurrentW () = 0; + inline bool end (); + inline int getEndCounter (); + NodeSets* getNodeSets (); + bool isSymmetry ( int index, std::pair& symmetry ); + bool isSymmetry ( int index ); + + virtual void print (); + void initSet (); + void initModulos (); // see notes in .cpp + void next (); // see notes in .cpp + virtual void push_back () = 0; + + protected: + HVSlicingNode* _HVSnode; + int _counter; + std::vector _modulos; + std::vector _currentSet; + std::vector _nextSet; + NodeSets* _nodeSets; +}; + +inline bool HVSetState::end () { return (_counter == _modulos.back()+1); } +inline int HVSetState::getEndCounter () { return _modulos.back()+1; } +inline bool HVSetState::isSymmetry ( int index, std::pair& symmetry ) { return _HVSnode->isSymmetry(index, symmetry); } +inline bool HVSetState::isSymmetry ( int index ) { return _HVSnode->isSymmetry(index); } + + +// -----------------------------------------------------------------------------------------------// +// Class : HSetState +// -----------------------------------------------------------------------------------------------// + + +class HSetState: public HVSetState +{ + public: + HSetState ( HSlicingNode* node ); + ~HSetState (); + + std::pair getCurrentWs (); // see notes in .cpp + DbU::Unit getCurrentH (); // see notes in .cpp + DbU::Unit getCurrentW (); // see notes in .cpp + void print (); + void next (); + void push_back (); // see notes in .cpp +}; + + +// -----------------------------------------------------------------------------------------------// +// Class : VSetState +// -----------------------------------------------------------------------------------------------// + + +class VSetState: public HVSetState +{ + public: + VSetState ( VSlicingNode* node ); + ~VSetState (); + + std::pair getCurrentHs (); // see notes in .cpp + DbU::Unit getCurrentH (); // see notes in .cpp + DbU::Unit getCurrentW (); // see notes in .cpp + void print (); + void next (); + void push_back (); // see notes in .cpp +}; + + + + +GETSTRING_POINTER_SUPPORT(SlicingNode) +GETSTRING_POINTER_SUPPORT(HSlicingNode) +GETSTRING_POINTER_SUPPORT(VSlicingNode) +GETSTRING_POINTER_SUPPORT(DSlicingNode) +GETSTRING_POINTER_SUPPORT(RHSlicingNode) +GETSTRING_POINTER_SUPPORT(RVSlicingNode) +IOSTREAM_POINTER_SUPPORT(SlicingNode) +IOSTREAM_POINTER_SUPPORT(HSlicingNode) +IOSTREAM_POINTER_SUPPORT(VSlicingNode) +IOSTREAM_POINTER_SUPPORT(DSlicingNode) +IOSTREAM_POINTER_SUPPORT(RHSlicingNode) +IOSTREAM_POINTER_SUPPORT(RVSlicingNode) + +#endif + diff --git a/bora/src/bora/AnalogDistance.h b/bora/src/bora/AnalogDistance.h new file mode 100644 index 00000000..62bde52e --- /dev/null +++ b/bora/src/bora/AnalogDistance.h @@ -0,0 +1,302 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/AnalogDistance.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_ANALOG_DISTANCE_H +#define BORA_ANALOG_DISTANCE_H + +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Cell.h" +#include "anabatic/Dijkstra.h" +#include "anabatic/GCell.h" + + +namespace Bora { + + using Hurricane::DbU; + using Hurricane::Net; + using Hurricane::Point; + using Hurricane::Component; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::RoutingPad; + using Anabatic::Edge; + using Anabatic::Vertex; + using Anabatic::GCell; + using Anabatic::Dijkstra; + using Anabatic::IntervalC; + + + class AnalogDistance { + public: + AnalogDistance ( Cell*, DbU::Unit, DbU::Unit ); + inline Net* getNet () const; + inline void setNet ( Net* ); + DbU::Unit operator() ( const Vertex*, const Vertex*, const Edge* ) const; + DbU::Unit addCost ( const Vertex*, const Vertex*, DbU::Unit ) const; + DbU::Unit getPenality ( const DbU::Unit ) const; + inline double getReferenceDistance () const; + bool isXUnion ( const GCell*, const GCell* ) const; + bool isYUnion ( const GCell*, const GCell* ) const; + bool isXUnion ( DbU::Unit, DbU::Unit, const GCell* ) const; + bool isYUnion ( DbU::Unit, DbU::Unit, const GCell* ) const; + DbU::Unit calcDistance ( const Point p1, const Point p2 ) const; + private: + Cell* _cell; + DbU::Unit _hpitch; + DbU::Unit _vpitch; + static Net* _net; + }; + + + Net* AnalogDistance::_net = NULL; + + + AnalogDistance::AnalogDistance ( Cell* cell, DbU::Unit h, DbU::Unit v ) + : _cell (cell) + , _hpitch(h) + , _vpitch(v) + { } + + + inline void AnalogDistance::setNet ( Net* net ) { _net = net; } + inline Net* AnalogDistance::getNet () const { return _net; } + inline double AnalogDistance::getReferenceDistance () const { return std::max(_cell->getAbutmentBox().getHeight(),_cell->getAbutmentBox().getWidth() ); } + + + DbU::Unit AnalogDistance::operator() ( const Vertex* vcurr, const Vertex* vnext, const Edge* e ) const + { + cdebug_log(112,1) << "Calcul _distance: "<< _net << endl; + + DbU::Unit distance = vcurr->getDistance(); + DbU::Unit addedDistance = 0; + + if (Vertex::isRestricted(vcurr, vnext, e, _hpitch, _vpitch, _net)) { + distance = Vertex::unreachable; + } else { + if ( (vcurr->getGCell()->isMatrix()) and (vnext->getGCell()->isMatrix()) ) { + cdebug_tabw(112,-1); + return distance + e->getDistance(); + } else { + Point pcurrent = vcurr->getStartPathPoint( vnext ); + Point pneighbour = vcurr->getNextPathPoint ( pcurrent, vnext ); + + addedDistance = std::abs( pneighbour.getX() - pcurrent.getX()) + std::abs(pneighbour.getY() - pcurrent.getY() ); + cdebug_log(112,0) << "Pcurrent : X:" << DbU::getValueString(pcurrent.getX()) << ", Y:" << DbU::getValueString(pcurrent.getY()) << endl; + cdebug_log(112,0) << "Pneighbour: X:" << DbU::getValueString(pneighbour.getX()) << ", Y:" << DbU::getValueString(pneighbour.getY()) << endl; + addedDistance += addCost(vcurr, vnext, addedDistance); + distance += addedDistance; + } + } + + cdebug_tabw(112,-1); + return distance; + } + + + DbU::Unit AnalogDistance::addCost ( const Vertex* vcurr, const Vertex* vnext, DbU::Unit aDistance ) const + { + cdebug_log(112,1) << "AnalogDistance::addCost(const Vertex* vcurr,const Vertex* vnext): aDistance: " + << DbU::getValueString(aDistance) << endl; + + double addedDistance = aDistance; + DbU::Unit supDist = 0; + Vertex* vprev = NULL; + GCell* gcurr = vcurr->getGCell(); + GCell* gnext = vnext->getGCell(); + GCell* gprev = vcurr->getGPrev(Vertex::From2Mode); + if (gprev) vprev = gprev->getObserver(GCell::Observable::Vertex); + + // Case: Device, only simple turn case possible + if (vcurr->getRpCount()) { + RoutingPad* rp = NULL; + for ( Component* component : _cell->getComponentsUnder(gcurr->getBoundingBox()) ) { + rp = dynamic_cast( component ); + if (rp) break; + } + if (rp) { + Horizontal* h = dynamic_cast( rp->_getEntityAsSegment() ); + Vertical* v = dynamic_cast( rp->_getEntityAsSegment() ); + cdebug_log(112,0) << "Current: isDevice, "; + if (h) { + cdebug_log(112,0) << " rp: Horizontal and "; + if ( (gcurr->isNorth(gnext)) or (gcurr->isSouth(gnext)) ) { + cdebug_log(112,0) << "COST." << endl; + supDist += getPenality(addedDistance)*1; + } else + cdebug_log(112,0) << "FREE." << endl; + } else if (v) { + cdebug_log(112,0) << " rp: Vertical and "; + if ( (gcurr->isWest(gnext)) or (gcurr->isEast(gnext)) ) { + cdebug_log(112,0) << "COST." << endl; + supDist += getPenality(addedDistance)*1; + } else + cdebug_log(112,0) << "FREE." << endl; + } else + cdebug_log(112,0) << "IS UNKNOWN.1" << endl; + } + } else { + IntervalC intervfrom = vcurr->getIntervFrom( Vertex::From2Mode ); + + cdebug_log(112,0) << "Case: vcurr is NOT a source nor a device " << endl; + cdebug_log(112,0) << "(gprev->isEast (gcurr):" << gprev->isWest (gcurr) << endl; + cdebug_log(112,0) << "(gcurr->isEast (gnext):" << gcurr->isWest (gnext) << endl; + cdebug_log(112,0) << "isXUnion(gprev, gnext):" << isXUnion(gprev, gnext) << endl; + cdebug_log(112,0) << "isYUnion(gprev, gnext):" << isYUnion(gprev, gnext) << endl; + + if (vcurr->areSameSide(vprev,vnext)) { + cdebug_log(112,0) << "Case: Turn around" << endl; + supDist += getPenality(addedDistance)*4; + } else if ( ( (gcurr->isNorth(gprev) or gcurr->isSouth(gprev)) + and (gcurr->isEast (gnext) or gcurr->isWest (gnext)) ) + or ( (gcurr->isEast (gprev) or gcurr->isWest (gprev)) + and (gcurr->isNorth(gnext) or gcurr->isSouth(gnext)) ) ) { + cdebug_log(112,0) << "Case: Simple turn" << endl; + supDist += getPenality( addedDistance ); + } else if (vprev->isH()) { + cdebug_log(112,0) << "Case: vprev is horizontal" << endl; + if ( ( ( (gcurr->isSouth(gprev) and gcurr->isNorth(gnext)) + or (gcurr->isNorth(gprev) and gcurr->isSouth(gnext)) ) + and (not isXUnion(intervfrom.getMin(), intervfrom.getMax(), gnext)) ) + or ( ( (gcurr->isWest (gprev) and gcurr->isEast (gnext)) + or (gcurr->isEast (gprev) and gcurr->isWest (gnext)) ) + and ( (intervfrom.getAxis() < gnext->getYMin()) + or (intervfrom.getAxis() > gnext->getYMax()) ) ) ) { + cdebug_log(112,0) << "Case: Double turn1" << endl; + cdebug_log(112,0) << "((gcurr->isSouth(gprev)) && (gcurr->isNorth(gnext))) : " << ((gcurr->isSouth(gprev)) && (gcurr->isNorth(gnext))) << endl; + cdebug_log(112,0) << "((gcurr->isNorth(gprev)) && (gcurr->isSouth(gnext))) : " << ((gcurr->isNorth(gprev)) && (gcurr->isSouth(gnext))) << endl; + cdebug_log(112,0) << "(!isXUnion(intervfrom.getMin(), intervfrom.getMax(), gnext)): " << (!isXUnion(intervfrom.getMin(), intervfrom.getMax(), gnext)) << endl; + supDist += getPenality( addedDistance )*1; + } else + cdebug_log(112,0) << "Case: No cost" << endl; + } else if (vprev->isV()) { + cdebug_log(112,0) << "Case: vprev is vertical" << endl; + if ( ( ( (gcurr->isWest(gprev) and gcurr->isEast (gnext)) + or (gcurr->isEast(gprev) and gcurr->isWest (gnext)) ) + and (not isYUnion(intervfrom.getMin(), intervfrom.getMax(), gnext)) ) + or ( ( (gcurr->isSouth(gprev) and gcurr->isNorth(gnext)) + or (gcurr->isNorth(gprev) and gcurr->isSouth(gnext)) ) + and ( (intervfrom.getAxis() < gnext->getXMin()) + or (intervfrom.getAxis() > gnext->getXMax()) ) ) ) { + cdebug_log(112,0) << "Case: Double turn2" << endl; + cdebug_log(112,0) << "((gcurr->isWest(gprev)) && (gcurr->isEast(gnext))) :" << ((gcurr->isWest(gprev)) && (gcurr->isEast(gnext))) << endl; + cdebug_log(112,0) << "((gcurr->isEast(gprev)) && (gcurr->isWest(gnext))) :" << ((gcurr->isEast(gprev)) && (gcurr->isWest(gnext))) << endl; + cdebug_log(112,0) << "(!isYUnion(intervfrom.getMin(), intervfrom.getMax(), gnext)): " << (!isYUnion(intervfrom.getMin(), intervfrom.getMax(), gnext)) << endl; + supDist += getPenality( addedDistance )*1; + } else + cdebug_log(112,0) << "Case: No cost" << endl; + } else cdebug_log(112,0) << "Case: No cost" << endl; + } + + // Case: Next is Device, add cost to arrive to RP + if (vcurr->getRpCount()) { + RoutingPad* rp = NULL; + for ( Component* component : _cell->getComponentsUnder(gnext->getBoundingBox()) ) { + rp = dynamic_cast( component ); + if (rp) break; + } + if (rp) { + cdebug_log(112,0) << "Case: Next is a Device and "; + Horizontal* h = dynamic_cast( rp->_getEntityAsSegment() ); + Vertical* v = dynamic_cast( rp->_getEntityAsSegment() ); + if (h) { + if (gcurr->isNorth(gnext) or gcurr->isSouth(gnext)) { + cdebug_log(112,0) << "COST." << endl; + supDist += getPenality( addedDistance )*1; + } else + cdebug_log(112,0) << "FREE." << endl; + } else if (v) { + if (gcurr->isWest(gnext) or gcurr->isEast(gnext)) { + cdebug_log(112,0) << "COST." << endl; + supDist += getPenality( addedDistance )*1; + } else + cdebug_log(112,0) << "FREE." << endl; + } + } + } + + cdebug_log(112,0) << "supDist = " << DbU::getValueString(supDist) << endl; + cdebug_tabw(112,-1); + + return supDist; + } + + + inline DbU::Unit AnalogDistance::getPenality ( const DbU::Unit addedDistance ) const + { + double refcost = std::max( _hpitch, _vpitch )*1; + double refdist = getReferenceDistance(); + DbU::Unit pen = refcost; + + if (addedDistance < refdist) pen = ( (refdist - addedDistance) / refdist) * refcost; + return pen; + } + + + bool AnalogDistance::isXUnion( const GCell* prev, const GCell* next ) const + { + if ( not prev or not next) return false; + + if ( (prev->getXMin() > next->getXMax()) + or (prev->getXMax() < next->getXMin()) ) return false; + + return true; + } + + + bool AnalogDistance::isXUnion ( DbU::Unit xmin, DbU::Unit xmax, const GCell* next ) const + { + if (not next) return false; + + if ( (xmin > next->getXMax()) + or (xmax < next->getXMin()) ) return false; + + return true; + } + + + bool AnalogDistance::isYUnion ( const GCell* prev, const GCell* next ) const + { + if (not prev or not next) return false; + + if ( (prev->getYMin() > next->getYMax()) + or (prev->getYMax() < next->getYMin()) ) return false; + + return true; + } + + + bool AnalogDistance::isYUnion ( DbU::Unit ymin, DbU::Unit ymax, const GCell* next ) const + { + if (not next) return false; + + if ( (ymin > next->getYMax()) + or (ymax < next->getYMin()) ) return false; + + return true; + } + + + DbU::Unit AnalogDistance::calcDistance ( const Point p1, const Point p2 ) const + { + return abs( p1.getX() - p2.getX() ) + abs( p1.getY() - p2.getY() ); + } + + +} // Bora namespace. + +#endif // BORA_ANALOG_DISTANCE_H diff --git a/bora/src/bora/BoraEngine.h b/bora/src/bora/BoraEngine.h new file mode 100644 index 00000000..a130fa4c --- /dev/null +++ b/bora/src/bora/BoraEngine.h @@ -0,0 +1,85 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/BoraEngine.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_BORA_ENGINE_H +#define BORA_BORA_ENGINE_H + +#include +#include "hurricane/viewer/CellViewer.h" +namespace Hurricane { + class Cell; + class CellWidget; +} +#include "crlcore/ToolEngine.h" + + +namespace Bora { + + using Hurricane::Name; + using Hurricane::DbU; + using Hurricane::Cell; + using Hurricane::CellWidget; + using Hurricane::CellViewer; + class SlicingPlotWidget; + class BoxSet; + + + class BoraEngine : public CRL::ToolEngine { + public: + typedef CRL::ToolEngine Super; + public: + static const Name& staticGetName (); + static BoraEngine* get ( const Cell* ); + static BoraEngine* create ( Cell* ); + virtual const Name& getName () const; + inline CellViewer* getViewer () const; + void setViewer ( CellViewer* ); + void updateSlicingTree (); + void updatePlacement ( size_t index ); + void updatePlacement ( DbU::Unit width, DbU::Unit height ); + void updatePlacement ( BoxSet* ); + void setToleranceRatio ( DbU::Unit, DbU::Unit ); + void setToleranceBand ( DbU::Unit, DbU::Unit ); + void showPareto (); + inline CellWidget* getCellWidget (); + inline void emitCellPreModificated (); + inline void emitCellPostModificated (); + void resetPlacement (); + DbU::Unit getToleranceRatioH () const; + DbU::Unit getToleranceRatioW () const; + DbU::Unit getToleranceBandH () const; + DbU::Unit getToleranceBandW () const; + protected: + BoraEngine ( Cell* ); + virtual ~BoraEngine (); + virtual void _postCreate (); + virtual void _preDestroy (); + + private: + static Hurricane::Name _toolName; + Hurricane::CellViewer* _viewer; + }; + + + inline Hurricane::CellWidget* BoraEngine::getCellWidget () { return (_viewer) ? _viewer->getCellWidget() : NULL; } + inline void BoraEngine::emitCellPreModificated () { if (_viewer) _viewer->emitCellPreModificated() ; } + inline void BoraEngine::emitCellPostModificated () { if (_viewer) _viewer->emitCellPostModificated(); } + inline Hurricane::CellViewer* BoraEngine::getViewer () const { return _viewer; } + + +} // Bora namespace. + +#endif // BORA_BORA_ENGINE_H diff --git a/bora/src/bora/BoxSet.h b/bora/src/bora/BoxSet.h new file mode 100644 index 00000000..59f912c3 --- /dev/null +++ b/bora/src/bora/BoxSet.h @@ -0,0 +1,306 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/BoxSet.h" | +// +-----------------------------------------------------------------+ +// +// A dimension defined by a width and a height for slicing nodes. +// - HBoxSet are used for HSlicingNode: +// -> width = max(children's widths), height = sum(children's heights) +// - VBoxSet are used for VSlicingNode: +// -> width = sum(children's widths), height = max(children's heights) +// - DBoxSet are used for DSlicingNode: +// -> width = device's width, height = device's height +// - RHBoxSet are used for RHSlicingNode: +// -> height = routing space's height +// - RVBoxSet are used for RVSlicingNode: +// -> width = routing space's width + + +#ifndef BORA_BOX_SET_H +#define BORA_BOX_SET_H + +#include +#include +#include "hurricane/DbU.h" +#include "bora/Constants.h" + +namespace Bora { + + using Hurricane::DbU; + + +// ------------------------------------------------------------------- +// Class : "Bora::BoxSet". + + + class BoxSet + { + public: + BoxSet ( DbU::Unit height=0, DbU::Unit width=0 ); + BoxSet ( BoxSet* boxSet ); + virtual ~BoxSet (); + inline DbU::Unit getHeight () const; + inline DbU::Unit getWidth () const; + inline unsigned int getCpt () const; + inline void incrementCpt (); + virtual BoxSet* clone () = 0; + inline double getRatio (); + inline double getArea (); + void preDestroy (); + virtual void destroy (); + virtual unsigned int getType () const; + virtual double getOccupationArea () const; + virtual const std::vector& getSet () const; + virtual int getNFing () const; + virtual void print () const; + virtual double getDevicesArea () const = 0; + virtual void setHeight ( DbU::Unit ); + virtual void setWidth ( DbU::Unit ); + protected: + DbU::Unit _height; + DbU::Unit _width; + unsigned int _cpt; + }; + + + inline DbU::Unit BoxSet::getHeight () const { return _height; } + inline DbU::Unit BoxSet::getWidth () const { return _width; } + inline unsigned int BoxSet::getCpt () const { return _cpt; } + inline void BoxSet::incrementCpt () { _cpt++; } + inline double BoxSet::getRatio () { return _width/_height; } + inline double BoxSet::getArea () { return _width*_height; } + inline unsigned int BoxSet::getType () const { return UnknownType; } + inline double BoxSet::getOccupationArea () const { return 100; } + + +// ------------------------------------------------------------------- +// Class : "Bora::HVBoxSet". + + + class HVBoxSet: public BoxSet + { + protected: + HVBoxSet ( const std::vector& , DbU::Unit height=0, DbU::Unit width=0 ); + HVBoxSet ( HVBoxSet* ); + virtual ~HVBoxSet (); + inline const std::vector& getSet () const; + inline double getOccupationArea () const; + double getDevicesArea () const; + virtual inline void calculateHeight () = 0; + virtual inline void calculateWidth () = 0; + + protected: + std::vector _dimensionSet; + }; + + + inline const std::vector& HVBoxSet::getSet () const { return _dimensionSet; } + inline double HVBoxSet::getOccupationArea () const { return getDevicesArea()/(_height * _width)*100; } + + +// ------------------------------------------------------------------- +// Class : "Bora::HBoxSet". + + + class HBoxSet: public HVBoxSet + { + protected: + HBoxSet ( const std::vector& , DbU::Unit height, DbU::Unit width ); + HBoxSet ( HBoxSet* boxSet ); + ~HBoxSet (); + public: + static HBoxSet* create ( const std::vector& , DbU::Unit height=0, DbU::Unit width=0 ); + HBoxSet* clone (); + inline unsigned int getType () const; + void calculateHeight (); + void calculateWidth (); + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void destroy (); + private: + static int _count; + static int _countAll; + }; + + + inline unsigned int HBoxSet::getType () const { return HorizontalSNode; } + inline int HBoxSet::getCount () { return _count; } + inline void HBoxSet::printCount () { std::cerr << "HBoxSet::Count = " << _count << std::endl; } + inline void HBoxSet::printCountAll () { std::cerr << "HBoxSet::CountAll = " << _countAll << std::endl; } + + +// ------------------------------------------------------------------- +// Class : "Bora::VBoxSet". + + + class VBoxSet: public HVBoxSet + { + protected: + VBoxSet ( const std::vector& , DbU::Unit height, DbU::Unit width ); + VBoxSet ( VBoxSet* boxSet ); + ~VBoxSet (); + public: + static VBoxSet* create ( const std::vector& , DbU::Unit height=0, DbU::Unit width=0 ); + VBoxSet* clone (); + inline unsigned int getType () const; + void calculateHeight (); + void calculateWidth (); + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void destroy (); + private: + static int _count; + static int _countAll; + }; + + + inline unsigned int VBoxSet::getType () const { return VerticalSNode; } + inline int VBoxSet::getCount () { return _count; } + inline void VBoxSet::printCount () { std::cerr << "VBoxSet::Count = " << _count << std::endl; } + inline void VBoxSet::printCountAll () { std::cerr << "VBoxSet::CountAll = " << _countAll << std::endl; } + + +// ------------------------------------------------------------------- +// Class : "Bora::DBoxSet". + + + class DBoxSet: public BoxSet + { + protected: + DBoxSet ( DbU::Unit height, DbU::Unit width, int nfing ); + DBoxSet ( DBoxSet* boxSet ); + ~DBoxSet (); + public: + static DBoxSet* create ( DbU::Unit height, DbU::Unit width, int nfing=1 ); + DBoxSet* clone (); + inline unsigned int getType () const; + inline double getDevicesArea () const; + inline int getNFing () const; + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void destroy (); + private: + int _nfing; + static int _count; + static int _countAll; + }; + + + inline unsigned int DBoxSet::getType () const { return DeviceSNode; } + inline double DBoxSet::getDevicesArea () const { return _height*_width; } + inline int DBoxSet::getNFing () const { return _nfing; } + inline int DBoxSet::getCount () { return _count; } + inline void DBoxSet::printCount () { std::cerr << "DBoxSet::Count = " << _count << std::endl; } + inline void DBoxSet::printCountAll () { std::cerr << "DBoxSet::CountAll = " << _countAll << std::endl; } + + +// ------------------------------------------------------------------- +// Class : "Bora::RHVBoxSet". + + + class RHVBoxSet: public BoxSet + { + public: + RHVBoxSet ( DbU::Unit height=0, DbU::Unit width=0 ); + RHVBoxSet ( RHVBoxSet* boxSet ); + ~RHVBoxSet (); + inline DbU::Unit getHeight () const; + inline DbU::Unit getWidth () const; + inline unsigned int getType () const; + inline double getDevicesArea () const; + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void destroy (); + virtual void setHeight ( DbU::Unit height ) { _height = 0; }; + virtual void setWidth ( DbU::Unit width ) { _width = 0; }; + void print () const; + protected: + static int _count; + static int _countAll; + }; + + + inline DbU::Unit RHVBoxSet::getHeight () const { return _height; } + inline DbU::Unit RHVBoxSet::getWidth () const { return _width; } + inline unsigned int RHVBoxSet::getType () const { return RoutingSNode; } + inline double RHVBoxSet::getDevicesArea () const { return 0; } + inline int RHVBoxSet::getCount () { return _count; } + inline void RHVBoxSet::printCount () { std::cerr << "RHVBoxSet::Count = " << _count << std::endl; } + inline void RHVBoxSet::printCountAll () { std::cerr << "RHVBoxSet::CountAll = " << _countAll << std::endl; } + + +// ------------------------------------------------------------------- +// Class : "Bora::RHBoxSet". + + + class RHBoxSet: public RHVBoxSet + { + protected: + RHBoxSet ( DbU::Unit height=0 ); + RHBoxSet ( RHBoxSet* ); + ~RHBoxSet (); + public: + static RHBoxSet* create ( DbU::Unit height ); + RHBoxSet* clone (); + inline void setHeight ( DbU::Unit height ); + }; + + + inline void RHBoxSet::setHeight ( DbU::Unit height ) { _height = height; } + + +// ------------------------------------------------------------------- +// Class : "Bora::RVBoxSet". + + + class RVBoxSet: public RHVBoxSet + { + protected: + RVBoxSet ( DbU::Unit width=0 ); + RVBoxSet ( RVBoxSet* boxSet ); + ~RVBoxSet (); + public: + static RVBoxSet* create ( DbU::Unit width ); + RVBoxSet* clone (); + inline void setWidth ( DbU::Unit width ); + }; + + + inline void RVBoxSet::setWidth ( DbU::Unit width ) { _width = width; } + + +// ------------------------------------------------------------------- +// Class : "Bora::compBoxSet". + + + class compBoxSet + { + public: + inline bool operator() ( const BoxSet* lhs, const BoxSet* rhs ) const; + }; + + + inline bool compBoxSet::operator() ( const BoxSet* lhs, const BoxSet* rhs ) const + { + return ( (lhs->getHeight() < rhs->getHeight()) or + ( (lhs->getHeight() == rhs->getHeight()) and (lhs->getWidth() < rhs->getWidth())) ); + } + + +} // Bora namespace. + +#endif // BORA_BOX_SET_H diff --git a/bora/src/bora/ChannelRouting.h b/bora/src/bora/ChannelRouting.h new file mode 100644 index 00000000..c19be6e8 --- /dev/null +++ b/bora/src/bora/ChannelRouting.h @@ -0,0 +1,61 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/ChannelRouting.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_CHANNEL_ROUTING_H +#define BORA_CHANNEL_ROUTING_H + + +#include "hurricane/IntervalTree.h" +namespace Hurricane { + class Net; +} + +namespace Bora { + + using Hurricane::DbU; + using Hurricane::IntervalData; + using Hurricane::IntervalTree; + using Hurricane::Net; + + +// ------------------------------------------------------------------- +// Class : "Bora::ChannelRouting". + + + class ChannelRouting + { + private: + typedef IntervalData WireInterval; + typedef IntervalTree WireIntervals; + private: + ChannelRouting (); + ~ChannelRouting (); + public: + static ChannelRouting* create (); + void destroy (); + int getMaxCount () const; + void insertChannel ( DbU::Unit xy1, DbU::Unit xy2, Net* ); + void insertChannel ( DbU::Unit xy1, DbU::Unit xy2, unsigned int w ); + void reset (); + void print () const; + private: + WireIntervals _wireIntervals; + }; + + +} // Bora namespace. + +#endif // BORA_CHANNEL_ROUTING_H diff --git a/bora/src/bora/Constants.h b/bora/src/bora/Constants.h new file mode 100644 index 00000000..ba29a4c4 --- /dev/null +++ b/bora/src/bora/Constants.h @@ -0,0 +1,103 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/Constants.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_CONSTANTS_H +#define BORA_CONSTANTS_H + +#include +#include +#include + + +namespace Bora { + + + const unsigned int presetMask = 0x1; + const unsigned int setMask = 0x2; + const unsigned int placedMask = 0x4; + const unsigned int alignmentMask = 0x1F8; + const unsigned int slicingTypeMask = 0x3E00; + const unsigned int overCellMask = 0x8000; + const unsigned int routingEstimatedMask = 0x10000; + const unsigned int routingCreatedMask = 0x20000; + const unsigned int symmetricMask = 0xC0000; + + enum Flags { Preset = 1 << 0 + , Set = 1 << 1 + , Placed = 1 << 2 + , UnknownAlignment = 1 << 3 + , AlignLeft = 1 << 4 + , AlignRight = 1 << 5 + , AlignCenter = 1 << 6 + , AlignTop = 1 << 7 + , AlignBottom = 1 << 8 + , UnknownType = 1 << 9 + , HorizontalSNode = 1 << 10 + , VerticalSNode = 1 << 11 + , DeviceSNode = 1 << 12 + , RoutingSNode = 1 << 13 + , None = 1 << 14 + , MX = 1 << 15 + , MY = 1 << 16 + , FixedRoutingSNode = 1 << 17 + , OverCell = 1 << 19 + , RoutingEstimated = 1 << 20 + , RoutingCreated = 1 << 21 + , HSymmetry = 1 << 23 + , VSymmetry = 1 << 24 + }; + + const unsigned int sideMask = 0x1F; + const unsigned int targetMask = 0x20; + const unsigned int notPassableMask = 0x3C0; // North - South - East - West + const unsigned int notPassableNMask = 0x40; // North + const unsigned int notPassableSMask = 0x80; // South + const unsigned int notPassableEMask = 0x100; // East + const unsigned int notPassableWMask = 0x200; // West + + enum FunctionFlags { NoFlags = 0 + , ShowDiff = (1<<0) + }; + +// Make sure these restrictions are the same than in the class Device + enum Restriction { NorthBlocked = (1<<0) + , SouthBlocked = (1<<1) + , EastBlocked = (1<<2) + , WestBlocked = (1<<3) + , AllBlocked = NorthBlocked|SouthBlocked|EastBlocked|WestBlocked + }; + + + class BoxSet; + class NodeSets; + class ChannelRouting; + class SlicingNode; + class HVSlicingNode; + class HSlicingNode; + class VSlicingNode; + class RHVSlicingNode; + class RHSlicingNode; + class RVSlicingNode; + + typedef std::pair Symmetry; + typedef std::list LSymmetries; + typedef std::list LSlicingNodes; + typedef std::vector VSlicingNodes; + + +} // Bora namespace. + +#endif // BORA_CONSTANTS_H diff --git a/bora/src/bora/DSlicingNode.h b/bora/src/bora/DSlicingNode.h new file mode 100644 index 00000000..7c31c094 --- /dev/null +++ b/bora/src/bora/DSlicingNode.h @@ -0,0 +1,109 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/DSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_D_SLICING_NODE_H +#define BORA_D_SLICING_NODE_H + +#include "bora/SlicingNode.h" + + +namespace Bora { + + +// ------------------------------------------------------------------- +// Class : "Bora::DSlicingNode". + + + class DSlicingNode: public SlicingNode + { + public: + typedef SlicingNode Super; + private: + DSlicingNode ( unsigned int type + , NodeSets* nodeSets + , unsigned int alignment + , Instance* instance + , BoxSet* boxSet + ); + ~DSlicingNode (); + + public: + static DSlicingNode* create ( NodeSets* nodeSets + , unsigned int alignment = UnknownAlignment + , Instance* instance = NULL + , BoxSet* boxSet = NULL + ); + void print () const; + DSlicingNode* clone ( unsigned int tr=None ); + inline double getDevicesArea () const; + void setNFing ( int ); + int getNFing () const; + inline Instance* getInstance () const; + inline void setInstance ( Instance* ); + void place ( DbU::Unit x=0, DbU::Unit y=0 ); + void _place ( DbU::Unit x=0, DbU::Unit y=0, bool replace=false ); + + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void preDestroy (); + void destroy (); + void preRecursiveDestroy (); + void recursiveDestroy (); + double getStartParameter () const; + double getStepParameter () const; + double getCountParameter () const; + bool checkInitialPlacement ( int& cpt ) const;// see notes in .cpp + void setGCell ( Anabatic::GCell* ); + bool isSame ( SlicingNode* ) const; + bool isSymmetric ( SlicingNode* , unsigned int symmetryType, unsigned int flags=NoFlags ) const; + bool isSame ( SlicingNode* , unsigned int glags=NoFlags ) const; + void updateGCellPosition (); + void updateGContacts (); + void updateMatrixGCellPosition (); + void updateMatrixGContacts (); + void restrictDevices (); + void printLine () const; + bool isAnalog () const; + bool isDigital () const; + bool checkCellInstances ( Cell* cell ); + virtual void resetWireOccupation (); + virtual std::string _getString () const; + virtual std::string _getTypeName () const; + private: + static int _count; + static int _countAll; + Instance* _instance; + }; + + + inline double DSlicingNode::getDevicesArea () const { return getHeight()*getWidth(); } + inline Instance* DSlicingNode::getInstance () const { return _instance; } + inline void DSlicingNode::setInstance ( Instance* instance ) { _instance = instance; } + inline int DSlicingNode::getCount () { return _count ; } + inline void DSlicingNode::printCount () { std::cerr << "DSlicingNode::Count = " << _count << std::endl; } + inline void DSlicingNode::printCountAll () { std::cerr << "DSlicingNode::CountAll = " << _countAll << std::endl; } + + + + +} // Bora namespace. + + +GETSTRING_POINTER_SUPPORT(Bora::DSlicingNode) +IOSTREAM_POINTER_SUPPORT(Bora::DSlicingNode) + +#endif // BORA_D_SLICING_NODE_H diff --git a/bora/src/bora/GraphicBoraEngine.h b/bora/src/bora/GraphicBoraEngine.h new file mode 100644 index 00000000..168d25e2 --- /dev/null +++ b/bora/src/bora/GraphicBoraEngine.h @@ -0,0 +1,94 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul Chaput, Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/GraphicBoraEngine.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_GRAPHIC_BORA_ENGINE_H +#define BORA_GRAPHIC_BORA_ENGINE_H + +#include +#include +#include +#include +#include + +#include "hurricane/DbU.h" +namespace Hurricane { + class Go; + class BasicLayer; + class Transformation; + class CellWidget; + class CellViewer; +} +#include "crlcore/GraphicToolEngine.h" +#include "bora/BoraEngine.h" + + +namespace Bora { + + using Hurricane::Go; + using Hurricane::Box; + using Hurricane::BasicLayer; + using Hurricane::Transformation; + using Hurricane::Cell; + using Hurricane::CellWidget; + using Hurricane::CellViewer; + using CRL::GraphicTool; + + class SlicingPlotWidget; + class SlicingDataWidget; + class SlicingWidget; + + +// ------------------------------------------------------------------- +// Class : "Bora::GraphicBoraEngine". + + + class GraphicBoraEngine : public GraphicTool { + Q_OBJECT; + public: + enum Flags { NoFlags=0x0000, CreateEngine=0x0001 }; + public: + BoraEngine* createEngine (); + BoraEngine* getForFramework ( unsigned int flags ); + static GraphicBoraEngine* grab (); + virtual const Name& getName () const; + Cell* getCell (); + virtual size_t release (); + virtual void addToMenu ( CellViewer* ); + void updateSlicingTree (); + void setToleranceRatio (); + void setToleranceBand (); + void showPareto (); + inline SlicingWidget* getSlicingWidget (); + public slots: + void updatePlacementST ( BoxSet* ); + void updatePlacementST ( size_t index ); + protected: + static size_t _references; + static GraphicBoraEngine* _singleton; + CellViewer* _viewer; + SlicingWidget* _slicingWidget; + protected: + GraphicBoraEngine (); + virtual ~GraphicBoraEngine (); + }; + + + inline SlicingWidget* GraphicBoraEngine::getSlicingWidget () { return _slicingWidget; } + + +} // Bora namespace. + +#endif // BORA_GRAPHIC_BORA_ENGINE_H diff --git a/bora/src/bora/HSlicingNode.h b/bora/src/bora/HSlicingNode.h new file mode 100644 index 00000000..c5fde8a7 --- /dev/null +++ b/bora/src/bora/HSlicingNode.h @@ -0,0 +1,76 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/HSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_H_SLICING_NODE_H +#define BORA_H_SLICING_NODE_H + +#include "bora/HVSlicingNode.h" + + +namespace Bora { + + +// ------------------------------------------------------------------- +// Class : "Bora::HSlicingNode". + + class HSlicingNode: public HVSlicingNode + { + public: + typedef HVSlicingNode Super; + private: + HSlicingNode ( unsigned int type, unsigned int alignment=UnknownAlignment ); + ~HSlicingNode (); + public: + static HSlicingNode* create ( unsigned int alignment = AlignLeft ); + void createRouting ( DbU::Unit space ); + void print () const; + HSlicingNode* clone ( unsigned int tr=None ); + void place ( DbU::Unit x=0, DbU::Unit y=0 ); + void replace ( DbU::Unit x=0, DbU::Unit y=0 ); + void _place ( DbU::Unit x=0, DbU::Unit y=0, bool replace=false ); + void updateGlobalSize (); + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void preDestroy (); + void destroy (); + void preRecursiveDestroy (); + void recursiveDestroy (); + DbU::Unit getHeight () const; + DbU::Unit getWidth () const; + void createSlicingRouting (); + void setGCell ( Anabatic::GCell* gcell ); + void adjustBorderChannels (); + virtual std::string _getString () const; + virtual std::string _getTypeName () const; + private: + static int _count; + static int _countAll; + }; + + + inline int HSlicingNode::getCount () { return _count; } + inline void HSlicingNode::printCount () { std::cerr << "HSlicingNode::Count = " << _count << std::endl; } + inline void HSlicingNode::printCountAll () { std::cerr << "HSlicingNode::CountAll = " << _countAll << std::endl; } + + +} // Bora namespace. + + +GETSTRING_POINTER_SUPPORT(Bora::HSlicingNode) +IOSTREAM_POINTER_SUPPORT(Bora::HSlicingNode) + +#endif // BORA_H_SLICING_NODE_H diff --git a/bora/src/bora/HVSetState.h b/bora/src/bora/HVSetState.h new file mode 100644 index 00000000..d5027eb3 --- /dev/null +++ b/bora/src/bora/HVSetState.h @@ -0,0 +1,136 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/HVSetState.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_HV_SETSTATE_H +#define BORA_HV_SETSTATE_H + + +#include "hurricane/DbU.h" +#include "bora/Constants.h" +#include "bora/HVSlicingNode.h" + + +namespace Bora { + + using Hurricane::DbU; + class NodeSets; + class HSlicingNode; + class VSlicingNode; + + +// ------------------------------------------------------------------- +// Class : "Bora::HVSetState". +// +// Description: +// +// HVSetState, HSetState and VSetState are classes used in the algorithm to +// determine the possible dimensions for a slicing tree. They are not part of +// the slicing tree, they only help during the use of updateGlobalSize. At the +// end of the algorithm, it should provide the resulting NodeSets. +// +// In a horizontal/vertical slicing node, the number of possible dimensions +// (EndCounter) to study is: +// +// EndCounter = N(child0) * N(child1) * ... * N(childn) +// +// We call a "state" a dimension for the horizontal/vertical slicing +// node. "EndCounter" states needs to be studied. +// +// For each states, we check if these conditions are filled: +// +// - Horizontal case: toleranceBandW <= max(children's width )-min(children's width ) +// - Vertical case: toleranceBandH <= max(children's height)-min(children's height) +// +// When the condition is filled, we add the dimensions to the NodeSets and we +// proceed to the next combinations. + + + class HVSetState + { + protected: + HVSetState ( HVSlicingNode* ); + virtual ~HVSetState (); + + public: + virtual DbU::Unit getCurrentH () = 0; + virtual DbU::Unit getCurrentW () = 0; + inline bool end (); + inline int getEndCounter (); + NodeSets* getNodeSets (); + bool isSymmetry ( size_t index, Symmetry& symmetry ); + bool isSymmetry ( size_t index ); + + virtual void print (); + void initSet (); + void initModulos (); // see notes in .cpp + void next (); // see notes in .cpp + virtual void push_back () = 0; + + protected: + HVSlicingNode* _HVSnode; + size_t _counter; + std::vector _modulos; + std::vector _currentSet; + std::vector _nextSet; + NodeSets* _nodeSets; + }; + + + inline bool HVSetState::end () { return (_counter == _modulos.back()+1); } + inline int HVSetState::getEndCounter () { return _modulos.back()+1; } + inline bool HVSetState::isSymmetry ( size_t index, Symmetry& symmetry ) { return _HVSnode->isSymmetry(index,symmetry); } + inline bool HVSetState::isSymmetry ( size_t index ) { return _HVSnode->isSymmetry(index); } + + +// ------------------------------------------------------------------- +// Class : "Bora::HSetState". + + + class HSetState: public HVSetState + { + public: + HSetState ( HSlicingNode* ); + ~HSetState (); + std::pair getCurrentWs (); // See notes in .cpp + virtual DbU::Unit getCurrentH (); // See notes in .cpp + virtual DbU::Unit getCurrentW (); // See notes in .cpp + void print (); + void next (); + void push_back (); // See notes in .cpp + }; + + +// ------------------------------------------------------------------- +// Class : "Bora::HSetState". + + + class VSetState: public HVSetState + { + public: + VSetState ( VSlicingNode* ); + ~VSetState (); + std::pair getCurrentHs (); // See notes in .cpp + virtual DbU::Unit getCurrentH (); // See notes in .cpp + virtual DbU::Unit getCurrentW (); // See notes in .cpp + void print (); + void next (); + void push_back (); // See notes in .cpp + }; + + +} // Bora namespace. + +#endif // BORA_HV_SETSTATE_H diff --git a/bora/src/bora/HVSlicingNode.h b/bora/src/bora/HVSlicingNode.h new file mode 100644 index 00000000..bd9d8572 --- /dev/null +++ b/bora/src/bora/HVSlicingNode.h @@ -0,0 +1,175 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/HVSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_HV_SLICING_NODE_H +#define BORA_HV_SLICING_NODE_H + +#include "bora/SlicingNode.h" + + +namespace Bora { + + class RHVSlicingNode; + + +// ------------------------------------------------------------------- +// Class : "Bora::HVSlicingNode". + + + class HVSlicingNode: public SlicingNode + { + public: + typedef SlicingNode Super; + typedef std::tuple NetSymmetry; + typedef std::vector VNetSymmetries; + protected: + HVSlicingNode ( unsigned int type, unsigned int alignment = AlignLeft ); + virtual ~HVSlicingNode (); + public: + DbU::Unit getToleranceRatioH () const; + DbU::Unit getToleranceRatioW () const; + void setToleranceRatioH ( DbU::Unit ); + void setToleranceRatioW ( DbU::Unit ); + DbU::Unit getToleranceBandH () const; + DbU::Unit getToleranceBandW () const; + void setToleranceBandH ( DbU::Unit ); + void setToleranceBandW ( DbU::Unit ); + void recursiveSetToleranceRatioH ( DbU::Unit ); + void recursiveSetToleranceRatioW ( DbU::Unit ); + void recursiveSetToleranceBandH ( DbU::Unit ); + void recursiveSetToleranceBandW ( DbU::Unit ); + + void _recursiveSetToleranceRatioH ( DbU::Unit ); + void _recursiveSetToleranceRatioW ( DbU::Unit ); + void _recursiveSetToleranceBandH ( DbU::Unit ); + void _recursiveSetToleranceBandW ( DbU::Unit ); + void setTolerances ( DbU::Unit trh + , DbU::Unit trw + , DbU::Unit tbh + , DbU::Unit tbw + ); + void recursiveSetTolerances ( DbU::Unit trh + , DbU::Unit trw + , DbU::Unit tbh + , DbU::Unit tbw + ); + void _recursiveSetTolerances ( DbU::Unit trh + , DbU::Unit trw + , DbU::Unit tbh + , DbU::Unit tbw + ); + bool hasEmptyChildrenNodeSets () const; + inline const VSlicingNodes& getChildren () const; + SlicingNode* getChild ( size_t index ) const; + size_t getChildIndex ( SlicingNode* node ) const; + inline size_t getNbChild () const; + void createChild ( unsigned int type, unsigned int alignment ); + void createChild ( NodeSets* nodeSets + , unsigned int alignment = UnknownAlignment + , Instance* instance = NULL + , BoxSet* boxSet = NULL + ); + void createChild ( size_t childIndex, size_t copyIndex, unsigned int tr ); + void insertNode ( SlicingNode* , size_t index ); + void push_back ( SlicingNode* , bool reset = true ); + void push_front ( SlicingNode* ); + void removeNode ( SlicingNode* ); + inline void removeAllNodes (); + inline const LSymmetries& getSymmetries () const; + inline void setSymmetries ( const LSymmetries& sym ); + bool isSymmetry ( size_t index, Symmetry& ); + bool isSymmetry ( size_t index ); + void addSymmetry ( size_t childIndex, size_t copyIndex, bool reset = true ); + void removeSymmetry ( size_t index ); + void normalizeSymmetries (); // see notes in .cpp + void preDestroy (); + void destroy (); + void preRecursiveDestroy (); + void recursiveDestroy (); + void _resetSlicingTree (); + void print () const; + void printChildren () const; + void printLine () const; + void printChildrenLine () const; + bool recursiveCheckPreset () const; + bool recursiveCheckSet () const; + bool recursiveCheckPlaced () const; + int getLeafNumber () const; + double getDevicesArea () const; + double getOccupationArea () const; + void setGlobalSize ( DbU::Unit height, DbU::Unit width ); + void setGlobalSize ( size_t index ); + void _setGlobalSize ( BoxSet* boxSet ); + LSlicingNodes getLeaves (); + bool checkInitialPlacement ( int& cpt ) const; // see notes in .cpp + bool isSymmetric ( SlicingNode* , unsigned int symmetryType, unsigned int flags=NoFlags ) const; + bool isSame ( SlicingNode* , unsigned int flags=NoFlags ) const; + void restrictDevices (); + void setVertexRestriction ( Net* , Katana::KatanaEngine* ); + void estimateChannelsSize (); + void expandRoutingChannel (); + void _expandRoutingChannel (); + void expandRoutingChannel ( DbU::Unit height, DbU::Unit width ); + bool isRoutingEstimated () const; + void updateGCellPosition (); + void updateGContacts (); + int getNbDevices (); + virtual std::string _getString () const; + virtual std::string _getTypeName () const; + void setSymmetryFlag ( unsigned int flag ); + void setMaster ( SlicingNode* ); + bool checkCellInstances ( Cell* ); + SlicingNode* findInstance ( Instance* ); + SlicingNode* findSlicingNode ( Anabatic::GCell* ); + void resetSlicingRouting (); + void destroySlicingRouting (); + size_t getRoutingIndex ( SlicingNode* ) const; + SlicingNode* getSlicingRouting ( size_t index ) const; + void clearGCells (); + bool checkSymmetryNet ( unsigned int type, Net* net1, Net* net2 = NULL ) const; + void addSymmetryNet ( unsigned int type, Net* net1, Net* net2 = NULL ); + void updateNetConstraints (); + void updateSymNetAxis (); + void flattenDigitalNets (); + + void updateWireOccupation ( Anabatic::Dijkstra* ); + void resetWireOccupation (); + protected: + VSlicingNodes _children; + DbU::Unit _toleranceRatioH; + DbU::Unit _toleranceRatioW; + DbU::Unit _toleranceBandH; + DbU::Unit _toleranceBandW; + LSymmetries _symmetries; + std::vector _slicingRouting; + VNetSymmetries _netSymmetries; + }; + + + inline const VSlicingNodes& HVSlicingNode::getChildren () const { return _children; } + inline size_t HVSlicingNode::getNbChild () const { return _children.size(); } + inline void HVSlicingNode::removeAllNodes () { _children.clear(); } + inline const LSymmetries& HVSlicingNode::getSymmetries () const { return _symmetries; } + inline void HVSlicingNode::setSymmetries ( const LSymmetries& syms ) { _symmetries = syms; } + + +} // Bora namespace. + + +GETSTRING_POINTER_SUPPORT(Bora::HVSlicingNode) +IOSTREAM_POINTER_SUPPORT(Bora::HVSlicingNode) + +#endif // BORA_HV_SLICING_NODE_H diff --git a/bora/src/bora/NodeSets.h b/bora/src/bora/NodeSets.h new file mode 100644 index 00000000..e83543c0 --- /dev/null +++ b/bora/src/bora/NodeSets.h @@ -0,0 +1,107 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/NodeSets.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_NODE_SETS_H +#define BORA_NODE_SETS_H + +#include +#include +#include "BoxSet.h" + +namespace Hurricane { + class Cell; +} + +namespace CRL { + class RoutingGauge; +} + +namespace Bora { + + using std::size_t; + using Hurricane::Cell; + using CRL::RoutingGauge; + + +// ------------------------------------------------------------------- +// Class : "Bora::NodeSets". +// +// Contains all the possible dimensions (BoxSet) for a SlicingNode + + + class NodeSets + { + public: + //static const size_t NotFound = std::numeric_limits()::max; + static const size_t NotFound = (size_t)-1L; + public: + NodeSets ( double start, double step, double count ); + NodeSets ( const NodeSets* other ); + ~NodeSets (); + static NodeSets* create ( Cell* cell =NULL + , double start=0.0 + , double step =0.0 + , double count=0.0 + , CRL::RoutingGauge* rg =NULL ); + BoxSet* operator[] ( size_t ); + BoxSet* at ( size_t ); + inline std::vector::iterator begin (); + inline std::vector::iterator end (); + inline const std::vector& getBoxSets () const; + inline std::vector& getBoxSets (); + inline size_t size () const; + inline bool empty () const; + void clear (); + inline void sort (); + BoxSet* getPairH ( DbU::Unit height ) const; + BoxSet* getPairHW ( DbU::Unit height, DbU::Unit width ) const; + BoxSet* getPairHW ( unsigned int index ) const; + size_t findIndex ( DbU::Unit height, DbU::Unit width ) const; + BoxSet* find ( DbU::Unit height, DbU::Unit width ); + BoxSet* find ( BoxSet* boxSet ); + BoxSet* find ( int nfing ); + void print () const; + bool compare ( NodeSets nodeSets2, unsigned int flags=NoFlags ) const; + void push_back ( BoxSet* boxSet ); + void push_back ( std::vector vect, DbU::Unit height, DbU::Unit width, unsigned int type ); + void push_back ( DbU::Unit height, DbU::Unit width ); + NodeSets* clone (); + inline double getStartParameter () const; + inline double getStepParameter () const; + inline double getCountParameter () const; + private: + std::vector _boxSets; + int _start; + int _step; + int _count; + }; + + + inline std::vector::iterator NodeSets::begin () { return _boxSets.begin(); } + inline std::vector::iterator NodeSets::end () { return _boxSets.end (); } + inline const std::vector& NodeSets::getBoxSets () const { return _boxSets; } + inline std::vector& NodeSets::getBoxSets () { return _boxSets; } + inline size_t NodeSets::size () const { return _boxSets.size() ; } + inline bool NodeSets::empty () const { return _boxSets.empty(); } + inline void NodeSets::sort () { std::sort( _boxSets.begin(),_boxSets.end(), compBoxSet() ); } + inline double NodeSets::getStartParameter () const { return _start; } + inline double NodeSets::getStepParameter () const { return _step ; } + inline double NodeSets::getCountParameter () const { return _count; } + + +} // Bora namespace. + +#endif // BORA_NODE_SET_H diff --git a/bora/src/bora/Pareto.h b/bora/src/bora/Pareto.h new file mode 100644 index 00000000..f676781d --- /dev/null +++ b/bora/src/bora/Pareto.h @@ -0,0 +1,54 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/Pareto.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_PARETO_H +#define BORA_PARETO_H + + +namespace Bora { + + class Pareto { + public: + Pareto (); + ~Pareto (); + void mergePoint ( double x, double y ); + inline int size () const; + inline int capacity () const; + inline const double* xs () const; + inline const double* ys () const; + void clear (); + void dump (); + private: + void _resize ( int newsize ); + void _insert ( int index, double x, double y ); + void _remove ( int index ); + void _restoreMonotonic (); + private: + int _capacity; + int _size; + double* _xs; + double* _ys; + }; + + + inline int Pareto::capacity () const { return _size; } + inline int Pareto::size () const { return _size; } + inline const double* Pareto::xs () const { return _xs; } + inline const double* Pareto::ys () const { return _ys; } + +} // Bora namespace. + +#endif // BORA_PARETO_H diff --git a/bora/src/bora/PyBoraEngine.h b/bora/src/bora/PyBoraEngine.h new file mode 100644 index 00000000..c145e860 --- /dev/null +++ b/bora/src/bora/PyBoraEngine.h @@ -0,0 +1,61 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/PyBoraEngine.h" | +// +-----------------------------------------------------------------+ + + +#ifndef PY_BORA_ENGINE_H +#define PY_BORA_ENGINE_H + +#include "hurricane/isobar/PyHurricane.h" +#include "crlcore/PyToolEngine.h" +#include "bora/BoraEngine.h" + + +namespace Bora { + + using Bora::BoraEngine; + + +extern "C" { + + +// ------------------------------------------------------------------- +// Python Object : "PyBoraEngine". + + typedef struct { + CRL::PyToolEngine _baseObject; + } PyBoraEngine; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyBora.ccp". + + extern PyTypeObject PyTypeBoraEngine; + extern PyMethodDef PyBoraEngine_Methods[]; + + extern PyObject* PyBoraEngine_Link ( BoraEngine* ); + extern void PyBoraEngine_LinkPyType (); + extern void PyBoraEngine_postModuleInit (); + + +#define IsPyBoraEngine(v) ( (v)->ob_type == &PyTypeBoraEngine ) +#define PYBORAENGINE(v) ( (PyBoraEngine*)(v) ) +#define PYBORAENGINE_O(v) ( PYBORAENGINE(v)->_baseObject._object ) + + +} // extern "C". + +} // Bora namespace. + +#endif // PY_BORA_ENGINE_H diff --git a/bora/src/bora/PyDSlicingNode.h b/bora/src/bora/PyDSlicingNode.h new file mode 100644 index 00000000..5c253af5 --- /dev/null +++ b/bora/src/bora/PyDSlicingNode.h @@ -0,0 +1,55 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/PyDSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_PY_DSLICING_NODE_H +#define BORA_PY_DSLICING_NODE_H + +#include "bora/PySlicingNode.h" +#include "bora/DSlicingNode.h" + + +namespace Bora { + +extern "C" { + +// ------------------------------------------------------------------- +// Python Object : "PyDSlicingNode". + + typedef struct { + PySlicingNode _baseObject; + } PyDSlicingNode; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyBora.cpp". + + extern PyTypeObject PyTypeDSlicingNode; + extern PyMethodDef PyDSlicingNode_Methods[]; + + extern PyObject* PyDSlicingNode_NEW ( DSlicingNode* node ); + extern void PyDSlicingNode_LinkPyType (); + + +#define IsPyDSlicingNode(v) ( (v)->ob_type == &PyTypeDSlicingNode ) +#define PYDSLICINGNODE(v) ( (PyDSlicingNode*)(v) ) +#define PYDSLICINGNODE_O(v) ( dynamic_cast(PYDSLICINGNODE(v)->_baseObject._object) ) + + +} // extern "C". + +} // Bora namespace. + +#endif // BORA_PY_DSLICING_NODE_H diff --git a/bora/src/bora/PyGraphicBoraEngine.h b/bora/src/bora/PyGraphicBoraEngine.h new file mode 100644 index 00000000..53d5edb4 --- /dev/null +++ b/bora/src/bora/PyGraphicBoraEngine.h @@ -0,0 +1,55 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/PyGraphicBoraEngine.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_PY_GRAPHIC_BORA_ENGINE_H +#define BORA_PY_GRAPHIC_BORA_ENGINE_H + +#include "crlcore/PyGraphicToolEngine.h" +#include "bora/GraphicBoraEngine.h" + + +namespace Bora { + +extern "C" { + + +// ------------------------------------------------------------------- +// Python Object : "PyGraphicBoraEngine". + + typedef struct { + CRL::PyGraphicTool _baseObject; + } PyGraphicBoraEngine; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyBora.ccp". + + extern PyTypeObject PyTypeGraphicBoraEngine; + extern PyMethodDef PyGraphicBoraEngine_Methods[]; + + extern void PyGraphicBoraEngine_LinkPyType (); + + +#define IsPyGraphicBoraEngine(v) ( (v)->ob_type == &PyTypeGraphicBoraEngine ) +#define PY_GRAPHIC_BORA_ENGINE(v) ( (PyGraphicBoraEngine*)(v) ) +#define PY_GRAPHIC_BORA_ENGINE_O(v) ( PY_GRAPHIC_BORA_ENGINE(v)->_baseObject._object ) + + +} // extern "C". + +} // Bora namespace. + +#endif // BORA_PY_GRAPHIC_BORA_ENGINE_H diff --git a/bora/src/bora/PyHSlicingNode.h b/bora/src/bora/PyHSlicingNode.h new file mode 100644 index 00000000..724420bd --- /dev/null +++ b/bora/src/bora/PyHSlicingNode.h @@ -0,0 +1,55 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/PyHSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_PY_HSLICING_NODE_H +#define BORA_PY_HSLICING_NODE_H + +#include "bora/PySlicingNode.h" +#include "bora/HSlicingNode.h" + + +namespace Bora { + +extern "C" { + +// ------------------------------------------------------------------- +// Python Object : "PyHSlicingNode". + + typedef struct { + PySlicingNode _baseObject; + } PyHSlicingNode; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyHurricaneAMS.cpp". + + extern PyTypeObject PyTypeHSlicingNode; + extern PyMethodDef PyHSlicingNode_Methods[]; + + extern PyObject* PyHSlicingNode_NEW ( HSlicingNode* node ); + extern void PyHSlicingNode_LinkPyType (); + + +#define IsPyHSlicingNode(v) ( (v)->ob_type == &PyTypeHSlicingNode ) +#define PYHSLICINGNODE(v) ( (PyHSlicingNode*)(v) ) +#define PYHSLICINGNODE_O(v) ( dynamic_cast(PYHSLICINGNODE(v)->_baseObject._object) ) + + +} // extern "C". + +} // Bora namespace. + +#endif // BORA_PY_HSLICING_NODE_H diff --git a/bora/src/bora/PyRHSlicingNode.h b/bora/src/bora/PyRHSlicingNode.h new file mode 100644 index 00000000..b255bd8e --- /dev/null +++ b/bora/src/bora/PyRHSlicingNode.h @@ -0,0 +1,55 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/PyRHSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_PY_RHSLICING_NODE_H +#define BORA_PY_RHSLICING_NODE_H + +#include "bora/PySlicingNode.h" +#include "bora/RHSlicingNode.h" + + +namespace Bora { + +extern "C" { + +// ------------------------------------------------------------------- +// Python Object : "PyRHSlicingNode". + + typedef struct { + PySlicingNode _baseObject; + } PyRHSlicingNode; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyHurricaneAMS.cpp". + + extern PyTypeObject PyTypeRHSlicingNode; + extern PyMethodDef PyRHSlicingNode_Methods[]; + + extern PyObject* PyRHSlicingNode_NEW ( RHSlicingNode* node ); + extern void PyRHSlicingNode_LinkPyType (); + + +#define IsPyRHSlicingNode(v) ( (v)->ob_type == &PyTypeRHSlicingNode ) +#define PYRHSLICINGNODE(v) ( (PyRHSlicingNode*)(v) ) +#define PYRHSLICINGNODE_O(v) ( dynamic_cast(PYRHSLICINGNODE(v)->_baseObject._object) ) + + +} // extern "C". + +} // Bora namespace. + +#endif // BORA_PY_RHSLICING_NODE_H diff --git a/bora/src/bora/PyRVSlicingNode.h b/bora/src/bora/PyRVSlicingNode.h new file mode 100644 index 00000000..008f3f3a --- /dev/null +++ b/bora/src/bora/PyRVSlicingNode.h @@ -0,0 +1,55 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/PyRVSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_PY_RVSLICING_NODE_H +#define BORA_PY_RVSLICING_NODE_H + +#include "bora/PySlicingNode.h" +#include "bora/RVSlicingNode.h" + + +namespace Bora { + +extern "C" { + +// ------------------------------------------------------------------- +// Python Object : "PyRVSlicingNode". + + typedef struct { + PySlicingNode _baseObject; + } PyRVSlicingNode; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyHurricaneAMS.cpp". + + extern PyTypeObject PyTypeRVSlicingNode; + extern PyMethodDef PyRVSlicingNode_Methods[]; + + extern PyObject* PyRVSlicingNode_NEW ( RVSlicingNode* node ); + extern void PyRVSlicingNode_LinkPyType (); + + +#define IsPyRVSlicingNode(v) ( (v)->ob_type == &PyTypeRVSlicingNode ) +#define PYRVSLICINGNODE(v) ( (PyRVSlicingNode*)(v) ) +#define PYRVSLICINGNODE_O(v) ( dynamic_cast(PYRVSLICINGNODE(v)->_baseObject._object) ) + + +} // extern "C". + +} // Bora namespace. + +#endif // BORA_PY_RVSLICING_NODE_H diff --git a/bora/src/bora/PySlicingNode.h b/bora/src/bora/PySlicingNode.h new file mode 100644 index 00000000..c489f330 --- /dev/null +++ b/bora/src/bora/PySlicingNode.h @@ -0,0 +1,65 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/PySlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_PY_SLICING_NODE_H +#define BORA_PY_SLICING_NODE_H + +#include "hurricane/isobar/PyHurricane.h" +#include "bora/SlicingNode.h" + + +namespace Bora { + + extern "C" { + + +// ------------------------------------------------------------------- +// Python Object : "PySlicingNode". + + typedef struct { + PyObject_HEAD + SlicingNode* _object; + } PySlicingNode; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyBora.ccp". + + extern PyObject* PySlicingNode_NEW ( SlicingNode* node ); + extern void PySlicingNode_LinkPyType (); + extern void PySlicingNode_postModuleInit (); + + extern PyTypeObject PyTypeSlicingNode; + extern PyMethodDef PySlicingNode_Methods[]; + + +#define IsPySlicingNode(v) ( (v)->ob_type == &PyTypeSlicingNode ) +#define PYSLICINGNODE(v) ( (PySlicingNode*)(v) ) +#define PYSLICINGNODE_O(v) ( PYSLICINGNODE(v)->_object ) + + // Vector of DrawingGroups. + declareVectorObject(SlicingNode); + + + } // extern "C". + + + SlicingNode* SlicingNodeCast ( PyObject* derivedObject ); + + +} // Bora namespace. + +#endif // BORA_PY_SLICING_NODE_H diff --git a/bora/src/bora/PyVSlicingNode.h b/bora/src/bora/PyVSlicingNode.h new file mode 100644 index 00000000..ec2b1287 --- /dev/null +++ b/bora/src/bora/PyVSlicingNode.h @@ -0,0 +1,55 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/PyVSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_PY_VSLICING_NODE_H +#define BORA_PY_VSLICING_NODE_H + +#include "bora/PySlicingNode.h" +#include "bora/VSlicingNode.h" + + +namespace Bora { + +extern "C" { + +// ------------------------------------------------------------------- +// Python Object : "PyVSlicingNode". + + typedef struct { + PySlicingNode _baseObject; + } PyVSlicingNode; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyBora.cpp". + + extern PyTypeObject PyTypeVSlicingNode; + extern PyMethodDef PyVSlicingNode_Methods[]; + + extern PyObject* PyVSlicingNode_NEW ( VSlicingNode* node ); + extern void PyVSlicingNode_LinkPyType (); + + +#define IsPyVSlicingNode(v) ( (v)->ob_type == &PyTypeVSlicingNode ) +#define PYVSLICINGNODE(v) ( (PyVSlicingNode*)(v) ) +#define PYVSLICINGNODE_O(v) ( dynamic_cast(PYVSLICINGNODE(v)->_baseObject._object) ) + + +} // extern "C". + +} // Bora namespace. + +#endif // BORA_PY_VSLICING_NODE_H diff --git a/bora/src/bora/RHSlicingNode.h b/bora/src/bora/RHSlicingNode.h new file mode 100644 index 00000000..32f71e9e --- /dev/null +++ b/bora/src/bora/RHSlicingNode.h @@ -0,0 +1,65 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/RHSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_RH_SLICING_NODE_H +#define BORA_RH_SLICING_NODE_H + +#include "bora/RHVSlicingNode.h" + + +namespace Bora { + + +// ------------------------------------------------------------------- +// Class : "Bora::RHSlicingNode". + + + class RHSlicingNode: public RHVSlicingNode + { + private: + RHSlicingNode ( DbU::Unit height ); + RHSlicingNode ( Hurricane::Instance* ); + ~RHSlicingNode (); + public: + static RHSlicingNode* create ( DbU::Unit height=DbU::Unit(0) ); + static RHSlicingNode* create ( Hurricane::Net* net + , Hurricane::Layer* layer + , int npitch + , std::string cname + , std::string iname + ); + RHSlicingNode* clone ( unsigned int tr=None ); + + DbU::Unit getWidth () const; + void setHeight ( DbU::Unit ); + + void estimateChannelsSize (); + void _expandRoutingChannel (); + void expandRoutingChannel ( DbU::Unit height, DbU::Unit width ); + void setGCell ( Anabatic::GCell* ); + void updateMasterSize ( DbU::Unit size ); + virtual std::string _getTypeName () const; + void setWidth ( DbU::Unit width ); + }; + + +} // Bora namespace. + + +GETSTRING_POINTER_SUPPORT(Bora::RHSlicingNode) +IOSTREAM_POINTER_SUPPORT(Bora::RHSlicingNode) + +#endif // BORA_RH_SLICING_NODE_H diff --git a/bora/src/bora/RHVSlicingNode.h b/bora/src/bora/RHVSlicingNode.h new file mode 100644 index 00000000..6072931a --- /dev/null +++ b/bora/src/bora/RHVSlicingNode.h @@ -0,0 +1,87 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/RHVSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_RHV_SLICING_NODE_H +#define BORA_RHV_SLICING_NODE_H + +#include "SlicingNode.h" + + +namespace Bora { + + +// ------------------------------------------------------------------- +// Class : "Bora::RHVSlicingNode". + + + class RHVSlicingNode: public SlicingNode + { + protected: + RHVSlicingNode (); + ~RHVSlicingNode (); + public: + void print () const; + void _setGlobalSize ( DbU::Unit height, DbU::Unit width = 0 ); + inline double getDevicesArea () const; + inline bool isRoutingEstimated () const; + unsigned int getAlignment () const; + NodeSets* getNodeSets () const; + BoxSet* getPairH ( DbU::Unit height ) const; + BoxSet* getPairHW ( DbU::Unit height, DbU::Unit width ) const; + void setPairH ( DbU::Unit height ); + void setPairHW ( DbU::Unit height, DbU::Unit width ); + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void preDestroy (); + void destroy (); + void preRecursiveDestroy (); + void recursiveDestroy (); + void resetSize (); + bool isSame ( SlicingNode* , unsigned int flags=NoFlags ) const; + bool isSymmetric ( SlicingNode* , unsigned int symmetryType, unsigned int flags=NoFlags ) const; + void _place ( DbU::Unit x=0, DbU::Unit y=0, bool replace=false ); + void setRailInstance ( Hurricane::Instance* i ); + inline Hurricane::Instance* getRailInstance () const ; + void addWireOccupation ( DbU::Unit min, DbU::Unit max, Net* ); + void resetWireOccupation (); + int getMaxWireOccupation (); + protected: + static int _count; + static int _countAll; + Hurricane::Instance* _railInstance; + DbU::Unit _minHeight; + DbU::Unit _minWidth; + ChannelRouting* _wireOccupation; + + }; + + + inline double RHVSlicingNode::getDevicesArea () const { return 0; } + inline int RHVSlicingNode::getCount () { return _count; } + inline void RHVSlicingNode::printCount () { std::cerr << "RHVSlicingNode::Count = " << _count << std::endl; } + inline void RHVSlicingNode::printCountAll () { std::cerr << "RHVSlicingNode::CountAll = " << _countAll << std::endl; } + inline bool RHVSlicingNode::isRoutingEstimated () const { return (_flags & RoutingEstimated); } + inline Hurricane::Instance* RHVSlicingNode::getRailInstance () const { return _railInstance; } + + +} // Bora namespace. + + +GETSTRING_POINTER_SUPPORT(Bora::RHVSlicingNode) +IOSTREAM_POINTER_SUPPORT(Bora::RHVSlicingNode) + +#endif // BORA_RHV_SLICING_NODE_H diff --git a/bora/src/bora/RVSlicingNode.h b/bora/src/bora/RVSlicingNode.h new file mode 100644 index 00000000..784051df --- /dev/null +++ b/bora/src/bora/RVSlicingNode.h @@ -0,0 +1,64 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/RVSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_RV_SLICING_NODE_H +#define BORA_RV_SLICING_NODE_H + +#include "bora/RHVSlicingNode.h" + + +namespace Bora { + + +// ------------------------------------------------------------------- +// Class : "Bora::RVSlicingNode". + + + class RVSlicingNode: public RHVSlicingNode + { + private: + RVSlicingNode ( DbU::Unit width ); + RVSlicingNode ( Hurricane::Instance* ); + ~RVSlicingNode (); + public: + static RVSlicingNode* create ( DbU::Unit width=DbU::Unit(0) ); + static RVSlicingNode* create ( Hurricane::Vertical* ); + static RVSlicingNode* create ( Hurricane::Net* net + , Hurricane::Layer* layer + , int npitch + , std::string cname + , std::string iname + ); + RVSlicingNode* clone ( unsigned int tr = None ); + DbU::Unit getHeight () const; + void setWidth ( DbU::Unit width ); + void estimateChannelsSize (); + void _expandRoutingChannel (); + void expandRoutingChannel ( DbU::Unit height, DbU::Unit width ); + void setGCell ( Anabatic::GCell* ); + void updateMasterSize ( DbU::Unit size ); + virtual std::string _getTypeName () const; + void setHeight ( DbU::Unit ); + }; + + +} // Bora namespace. + + +GETSTRING_POINTER_SUPPORT(Bora::RVSlicingNode) +IOSTREAM_POINTER_SUPPORT(Bora::RVSlicingNode) + +#endif // BORA_RV_SLICING_NODE_H diff --git a/bora/src/bora/SlicingDataModel.h b/bora/src/bora/SlicingDataModel.h new file mode 100644 index 00000000..7b77a007 --- /dev/null +++ b/bora/src/bora/SlicingDataModel.h @@ -0,0 +1,52 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/SlicingDataModel.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_SLICING_DATA_MODEL_H +#define BORA_SLICING_DATA_MODEL_H + +#include +#include +namespace Hurricane { + class Cell; +} +#include "bora/SlicingNode.h" + + +namespace Bora { + + using Hurricane::Cell; + + + class SlicingDataModel : public QAbstractTableModel { + Q_OBJECT; + public: + SlicingDataModel ( QObject* parent=NULL ); + ~SlicingDataModel (); + void setCell ( Cell* cell ); + int rowCount ( const QModelIndex& parent=QModelIndex() ) const; + int columnCount ( const QModelIndex& parent=QModelIndex() ) const; + QVariant data ( const QModelIndex& index, int role=Qt::DisplayRole ) const; + QVariant headerData ( int section, Qt::Orientation orientation, int role=Qt::DisplayRole ) const; + BoxSet* getBoxSet ( int index ); + void updateContents (); + private: + Cell* _cell; + }; + + +} // Bora namespace. + +#endif // BORA_SLICING_DATA_MODEL_H diff --git a/bora/src/bora/SlicingDataWidget.h b/bora/src/bora/SlicingDataWidget.h new file mode 100644 index 00000000..7b25a9fd --- /dev/null +++ b/bora/src/bora/SlicingDataWidget.h @@ -0,0 +1,63 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul Chaput, Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/SlicingDataWidget.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_SLICING_DATAS_WIDGET_H +#define BORA_SLICING_DATAS_WIDGET_H + +#include +#include +class QTableView; +class QSortFilterProxyModel; +namespace Hurricane { + class CellViewer; +} +#include "bora/SlicingNode.h" + + +namespace Bora { + + using Hurricane::CellViewer; + class SlicingDataModel; + + + class SlicingDataWidget : public QWidget { + Q_OBJECT; + public: + SlicingDataWidget ( QWidget* parent=NULL ); + ~SlicingDataWidget (); + void setViewer ( CellViewer* ); + bool eventFilter ( QObject*, QEvent* ); + void updateContents (); + BoxSet* getBoxSet ( int index ); + public slots: + void columnPressed ( int column ); + void cellClicked ( const QModelIndex& index ); + void updateSelectedRow ( double x, double y ); + signals: + void updatePlacement ( BoxSet* boxSet ); + void updateSelectedPoint ( double x, double y ); + private: + CellViewer* _viewer; + SlicingDataModel* _baseModel; + QSortFilterProxyModel* _sortModel; + QTableView* _view; + int _rowHeight; + }; + + +} // Bora namespace. + +#endif // BORA_SLICING_DATAS_WIDGET_H diff --git a/bora/src/bora/SlicingNode.h b/bora/src/bora/SlicingNode.h new file mode 100644 index 00000000..77c1ca67 --- /dev/null +++ b/bora/src/bora/SlicingNode.h @@ -0,0 +1,391 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/SlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_SLICING_NODE_H +#define BORA_SLICING_NODE_H + +#include "hurricane/DbU.h" +#include "hurricane/analog/AnalogCellExtension.h" +namespace Hurricane { + class Technology; + class Net; + class Segment; + class Plug; + class Instance; +} +namespace CRL { + class RoutingGauge; +} +#include "anabatic/Dijkstra.h" +namespace Katana { + class KatanaEngine; +} +#include "bora/Constants.h" +#include "bora/NodeSets.h" + + +namespace Bora { + + using Hurricane::DbU; + using Hurricane::Technology; + using Hurricane::Net; + using Hurricane::Plug; + using Hurricane::Segment; + using Hurricane::Cell; + using Hurricane::Instance; + using Analog::AnalogData; + using CRL::RoutingGauge; + using Anabatic::GCell; + using Katana::KatanaEngine; + + +// ------------------------------------------------------------------- +// Class : "Bora::SlicingNode". +// +// Description: +// Node used for building a slicing tree used for device's placement. +// Step 1: Build - build the slicing tree +// Step 2: Update - possible dimensions (updateGlobalSize) +// Step 3: Select - select the desired dimension (setGlobalSize) + + + class SlicingNode : public AnalogData + { + public: + typedef AnalogData Super; + protected: + SlicingNode ( unsigned int type ); + SlicingNode ( unsigned int type + , NodeSets* nodeSets + , unsigned int alignment = UnknownAlignment + , BoxSet* boxSet = NULL + ); + virtual ~SlicingNode (); + public: + // Predicates. + inline bool isPreset () const; + inline bool isSet () const; + inline bool isPlaced () const; + inline bool isAlignLeft () const; + inline bool isAlignRight () const; + inline bool isAlignCenter () const; + inline bool isAlignTop () const; + inline bool isAlignBottom () const; + inline bool isHorizontal () const; + inline bool isVertical () const; + inline bool isDevice () const; + inline bool isRouting () const; + bool isSameSize ( BoxSet* ) const; + bool isSameSize ( DbU::Unit height, DbU::Unit width ) const; + bool isEmpty () const; + inline bool isOverCell () const; + inline bool isRoutingCreated () const; + virtual inline bool isRoutingEstimated () const; + bool isHSymmetry () const; + bool isVSymmetry () const; + virtual inline bool isAnalog () const; + virtual inline bool isDigital () const; + // Accessors. + inline size_t getId () const; + inline unsigned int getPreset () const; + inline unsigned int getSet () const; + inline unsigned int getPlaced () const; + inline unsigned int getAlignment () const; + inline unsigned int getType () const; + virtual DbU::Unit getHeight () const; + virtual DbU::Unit getWidth () const; + DbU::Unit getRootHeight () const; + DbU::Unit getRootWidth () const; + inline BoxSet* getBoxSet () const; + inline DbU::Unit getX () const; + inline DbU::Unit getY () const; + DbU::Unit getRootX () const; + DbU::Unit getRootY () const; + inline DbU::Unit getXCenter () const; + inline DbU::Unit getYCenter () const; + inline NodeSets* getNodeSets () const; + inline SlicingNode* getParent () const; + inline BoxSet* getPairH ( DbU::Unit height ) const; + inline BoxSet* getPairHW ( DbU::Unit height, DbU::Unit width ) const; + inline BoxSet* getPairHW ( int index ) const; + inline SlicingNode* getRoot () const; + int getCpt (); + double getRatio (); + double getArea (); + static inline Technology* getTechnology (); + static inline Cell* getCell (); + inline Anabatic::GCell* getGCell () const; + inline CRL::RoutingGauge* getRoutingGauge () const; + inline SlicingNode* getMaster () const; + DbU::Unit getVPitch (); + DbU::Unit getHPitch (); + // Mutators. + inline void setPreset ( unsigned int ); + inline void setSet ( unsigned int ); + virtual inline void setPlaced ( unsigned int ); + inline void setAlignment ( unsigned int ); + inline void setType ( unsigned int ); + void setBoxSet ( BoxSet* ); + void setBoxSet ( DbU::Unit height, DbU::Unit width ); + void setBoxSet ( size_t index ); + void _setBoxSet ( BoxSet* boxSet ); + void setX ( DbU::Unit x ); + void setY ( DbU::Unit y ); + inline void setNodeSets ( NodeSets* ); + inline void setParent ( SlicingNode* ); + inline void setPairH ( DbU::Unit height ); + inline void setPairHW ( DbU::Unit height, DbU::Unit width ); + inline void setOverCell ( unsigned int overCell ); + inline void setRoutingCreated ( unsigned int ); + inline void setRoutingEstimated ( unsigned int ); + static void setRoutingGauge ( CRL::RoutingGauge* ); + void setCell ( Cell* ); + void setKatana ( Katana::KatanaEngine* ); + virtual inline void setSymmetryFlag ( unsigned int ); + virtual inline void setMaster ( SlicingNode* ); + virtual void setHeight ( DbU::Unit ); + virtual void setWidth ( DbU::Unit ); + inline void clearNodeSets (); + void clearParentsNodeSets (); + inline void removeParent (); + virtual void resetSlicingTree (); // see notes in .cpp + virtual void _resetSlicingTree (); + virtual void print () const; + virtual void printLine () const; + virtual void printParent () const; + void printBoxSet () const; + virtual void place ( DbU::Unit x=0 , DbU::Unit y=0 ); + virtual void replace ( DbU::Unit x=0 , DbU::Unit y=0 ); + virtual void _place ( DbU::Unit x=0 , DbU::Unit y=0, bool replace=false ); + virtual void updateGlobalSize () { }; + virtual void setGlobalSize ( DbU::Unit height, DbU::Unit width ); + virtual void setGlobalSize ( size_t index ); + virtual void _setGlobalSize ( BoxSet* ); + virtual inline bool recursiveCheckPreset () const; + virtual inline bool recursiveCheckSet () const; + virtual inline bool recursiveCheckPlaced () const; + virtual inline int getLeafNumber () const; + virtual void preDestroy (); + virtual void destroy (); + virtual void preRecursiveDestroy (); + virtual void recursiveDestroy (); + virtual LSlicingNodes getLeaves (); + virtual bool checkInitialPlacement ( int& cpt ) const; // see notes in .cpp + void updateCellAbutmentBox (); + virtual void setGCell ( Anabatic::GCell* ); + virtual bool isSymmetric ( SlicingNode* , unsigned int symmetryType, unsigned int flags=NoFlags ) const; + virtual bool isSame ( SlicingNode* , unsigned int flags=NoFlags ) const; + static void createRoutingPads (); + static void clearRoutingPads (); + virtual void restrictDevices (); + virtual void setVertexRestriction ( Net* , Katana::KatanaEngine* ); + virtual void estimateChannelsSize (); + virtual void expandRoutingChannel (); + virtual void _expandRoutingChannel (); + virtual void expandRoutingChannel ( DbU::Unit height, DbU::Unit width ); + virtual void clearGlobalRouting (); + virtual void clearGCells (); + virtual void adjustBorderChannels () {}; + bool containAxis ( DbU::Unit axis, unsigned int symmetryType ); + virtual void updateMasterSize ( DbU::Unit size ) { } + // Error Methods + virtual DbU::Unit getToleranceRatioH () const; + virtual DbU::Unit getToleranceRatioW () const; + virtual void setToleranceRatioH ( DbU::Unit ); + virtual void setToleranceRatioW ( DbU::Unit ); + virtual DbU::Unit getToleranceBandH () const; + virtual DbU::Unit getToleranceBandW () const; + virtual void setToleranceBandH ( DbU::Unit ); + virtual void setToleranceBandW ( DbU::Unit ); + virtual void recursiveSetToleranceRatioH ( DbU::Unit ); + virtual void recursiveSetToleranceRatioW ( DbU::Unit ); + virtual void recursiveSetToleranceBandH ( DbU::Unit ); + virtual void recursiveSetToleranceBandW ( DbU::Unit ); + virtual void _recursiveSetToleranceRatioH ( DbU::Unit ); + virtual void _recursiveSetToleranceRatioW ( DbU::Unit ); + virtual void _recursiveSetToleranceBandH ( DbU::Unit ); + virtual void _recursiveSetToleranceBandW ( DbU::Unit ); + virtual void setTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ); + virtual void recursiveSetTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ); + virtual void _recursiveSetTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw ); + virtual bool hasEmptyChildrenNodeSets () const ; + virtual const VSlicingNodes& getChildren () const ; + virtual SlicingNode* getChild ( size_t ) const ; + virtual size_t getChildIndex ( SlicingNode* ) const; + virtual size_t getNbChild () const ; + virtual void createChild ( unsigned int type, unsigned int alignment ); + virtual void createChild ( NodeSets* nodeSets + , unsigned int alignment = UnknownAlignment + , Instance* instance = NULL + , BoxSet* boxSet = NULL + ); + virtual void createChild ( size_t childIndex, size_t copyIndex, unsigned int tr ); + virtual void createRouting ( DbU::Unit ); + virtual void insertNode ( SlicingNode* , size_t index ); + virtual void push_back ( SlicingNode* , bool reset=false ); + virtual void push_front ( SlicingNode* ); + virtual void removeNode ( SlicingNode* ); + virtual void removeAllNodes (); + virtual const LSymmetries& getSymmetries () const; + virtual void setSymmetries ( const LSymmetries& ); + virtual bool isSymmetry ( size_t index, Symmetry& ); + virtual bool isSymmetry ( size_t index ); + virtual void addSymmetry ( size_t childIndex, size_t copyIndex, bool reset=true ); + virtual void removeSymmetry ( size_t index ); + virtual void normalizeSymmetries (); + virtual void printChildren () const; + virtual void printChildrenLine () const; + virtual SlicingNode* clone ( unsigned int tr=None ); + virtual double getDevicesArea () const; + virtual double getOccupationArea () const; + virtual void setNFing ( int ); + virtual int getNFing () const; + virtual double getStartParameter () const; + virtual double getStepParameter () const; + virtual double getCountParameter () const; + virtual Instance* getInstance () const; + virtual void setInstance ( Instance* ); + virtual bool checkCellInstances ( Cell* ); + virtual SlicingNode* findInstance ( Instance* ); + virtual SlicingNode* findSlicingNode ( Anabatic::GCell* ); + virtual void updateGCellPosition (); + virtual void updateGContacts (); + virtual void updateMatrixGCellPosition (); + virtual void updateMatrixGContacts (); + virtual int getNbDevices (); + // Methods to be tested. + virtual void createSlicingRouting (); + virtual void resetSlicingRouting (); + virtual void destroySlicingRouting (); + virtual size_t getRoutingIndex ( SlicingNode* ) const; + virtual SlicingNode* getSlicingRouting ( size_t index ) const; + SlicingNode* findHorizontalParent () const; + SlicingNode* findVerticalParent () const; + size_t getIndexInHorizontalParent () const; + size_t getIndexInVerticalParent () const; + virtual bool checkSymmetryNet ( unsigned int type, Net* net1, Net* net2=NULL ) const; + virtual void addSymmetryNet ( unsigned int type, Net* net1, Net* net2=NULL ); + virtual void updateNetConstraints (); + virtual void updateSymNetAxis (); + virtual std::string _getString () const; + virtual std::string _getTypeName () const; + static void addRailSegments ( Hurricane::Segment* ); + static bool isRailSegments ( Hurricane::Segment* ); + static bool isRailSegments ( Hurricane::Plug* ); + void createRailCell (); + virtual void flattenDigitalNets (); + virtual void updateWireOccupation ( Anabatic::Dijkstra* ); + virtual void resetWireOccupation (); + virtual void addWireOccupation ( DbU::Unit min, DbU::Unit max, Net* ); + virtual int getMaxWireOccupation (); + protected: + static CRL::RoutingGauge* _rg; + static Cell* _cell; + static Katana::KatanaEngine* _katana; + static std::vector _railSegments; + static size_t _idCounter; + size_t _id; + SlicingNode* _parent; + unsigned int _flags; + NodeSets* _nodeSets; + DbU::Unit _x; + DbU::Unit _y; + BoxSet* _boxSet; + Anabatic::GCell* _gcell; + SlicingNode* _master; + }; + + + inline bool SlicingNode::isPreset () const { return (_flags & Preset); } + inline bool SlicingNode::isSet () const { return (_flags & Set); } + inline bool SlicingNode::isPlaced () const { return (_flags & Placed); } + inline bool SlicingNode::isAlignLeft () const { return (_flags & AlignLeft); } + inline bool SlicingNode::isAlignRight () const { return (_flags & AlignRight); } + inline bool SlicingNode::isAlignCenter () const { return (_flags & AlignCenter); } + inline bool SlicingNode::isAlignTop () const { return (_flags & AlignTop); } + inline bool SlicingNode::isAlignBottom () const { return (_flags & AlignBottom); } + inline bool SlicingNode::isHorizontal () const { return (_flags & HorizontalSNode); } + inline bool SlicingNode::isVertical () const { return (_flags & VerticalSNode); } + inline bool SlicingNode::isDevice () const { return (_flags & DeviceSNode); } + inline bool SlicingNode::isRouting () const { return (_flags & RoutingSNode); } + inline bool SlicingNode::isHSymmetry () const { return (_flags & HSymmetry); } + inline bool SlicingNode::isVSymmetry () const { return (_flags & VSymmetry); } + inline bool SlicingNode::isOverCell () const { return (_flags & OverCell); } + inline bool SlicingNode::isRoutingCreated () const { return (_flags & RoutingCreated); } + inline bool SlicingNode::isRoutingEstimated () const { return true; } + inline bool SlicingNode::isAnalog () const { return false; } + inline bool SlicingNode::isDigital () const { return false; } + + inline size_t SlicingNode::getId () const { return _id; } + inline unsigned int SlicingNode::getPreset () const { return (_flags & presetMask); } + inline unsigned int SlicingNode::getSet () const { return (_flags & setMask); } + inline unsigned int SlicingNode::getPlaced () const { return (_flags & placedMask); } + inline unsigned int SlicingNode::getAlignment () const { return (_flags & alignmentMask); } + inline unsigned int SlicingNode::getType () const { return (_flags & slicingTypeMask); } + inline BoxSet* SlicingNode::getBoxSet () const { return _boxSet; } + inline DbU::Unit SlicingNode::getX () const { return _x; } + inline DbU::Unit SlicingNode::getY () const { return _y; } + inline DbU::Unit SlicingNode::getXCenter () const { return getX() + getWidth()/2; } + inline DbU::Unit SlicingNode::getYCenter () const { return getY() + getHeight()/2; } + inline NodeSets* SlicingNode::getNodeSets () const { return _nodeSets; } + inline SlicingNode* SlicingNode::getParent () const { return _parent; } + inline Cell* SlicingNode::getCell () { return _cell; } + inline Anabatic::GCell* SlicingNode::getGCell () const { return _gcell; } + inline CRL::RoutingGauge* SlicingNode::getRoutingGauge () const { return _rg; } + inline SlicingNode* SlicingNode::getMaster () const { return _master; } + + inline BoxSet* SlicingNode::getPairH ( DbU::Unit height ) const { return _nodeSets->getPairH(height); } + inline BoxSet* SlicingNode::getPairHW ( DbU::Unit height, DbU::Unit width ) const { return _nodeSets->getPairHW(height, width); } + inline BoxSet* SlicingNode::getPairHW ( int index ) const { return _nodeSets->getPairHW(index); } + inline void SlicingNode::setPreset ( unsigned int preset ) { _flags = ((_flags & ~presetMask ) | preset ); } + inline void SlicingNode::setSet ( unsigned int set ) { _flags = ((_flags & ~setMask ) | set ); } + inline void SlicingNode::setPlaced ( unsigned int placed ) { _flags = ((_flags & ~placedMask ) | placed ); } + inline void SlicingNode::setAlignment ( unsigned int alignment ) { _flags = ((_flags & ~alignmentMask ) | alignment); } + inline void SlicingNode::setType ( unsigned int type ) { _flags = ((_flags & ~slicingTypeMask ) | type ); } + inline void SlicingNode::setNodeSets ( NodeSets* nodeSets ) { _nodeSets = nodeSets; } + inline void SlicingNode::setParent ( SlicingNode* parent ) { _parent = parent; } + inline void SlicingNode::setPairH ( DbU::Unit height ) { _boxSet = getPairH(height); } + inline void SlicingNode::setPairHW ( DbU::Unit height, DbU::Unit width ) { _boxSet = getPairHW(height, width); } + inline void SlicingNode::setSymmetryFlag ( unsigned int flag ) { _flags = ((_flags & ~(symmetricMask) ) | flag ); } + inline void SlicingNode::setMaster ( SlicingNode* master ) { _master = master; } + + inline void SlicingNode::setOverCell ( unsigned int overCell ) { _flags = ((_flags & ~(overCellMask )) | overCell) ; } + inline void SlicingNode::setRoutingCreated ( unsigned int routingCreated ) { _flags = ((_flags & ~(routingCreatedMask )) | routingCreated ); } + inline void SlicingNode::setRoutingEstimated ( unsigned int routingEstimated ) { _flags = ((_flags & ~(routingEstimatedMask)) | routingEstimated); } + + inline void SlicingNode::clearNodeSets () { _nodeSets->clear(); } + inline void SlicingNode::removeParent () { _parent = NULL; } + + inline bool SlicingNode::recursiveCheckPreset () const { return isPreset(); } + inline bool SlicingNode::recursiveCheckSet () const { return isSet (); } + inline bool SlicingNode::recursiveCheckPlaced () const { return isPlaced(); } + inline int SlicingNode::getLeafNumber () const { return 1; } + + inline SlicingNode* SlicingNode::getRoot() const + { + SlicingNode* parent = const_cast( this ); + while ( parent->getParent() ) parent = parent->getParent(); + return parent; + } + + +} // Bora namespace. + + +GETSTRING_POINTER_SUPPORT(Bora::SlicingNode) +IOSTREAM_POINTER_SUPPORT(Bora::SlicingNode) + +#endif // BORA_SLICING_NODE_H diff --git a/bora/src/bora/SlicingPlotWidget.h b/bora/src/bora/SlicingPlotWidget.h new file mode 100644 index 00000000..bd91c9de --- /dev/null +++ b/bora/src/bora/SlicingPlotWidget.h @@ -0,0 +1,76 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul Chaput, Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/DSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_SLICING_PLOT_WIDGET_H +#define BORA_SLICING_PLOT_WIDGET_H + +#include +#include +#include +#include +class QHBoxLayout; +class QGridLayout; +class QwtPlotCurve; +class QwtPlotPicker; +#include +namespace Hurricane { + class DynamicLabel; + class CellViewer; +} +#include "bora/SlicingNode.h" +#include "bora/Pareto.h" + + +namespace Bora { + + using Hurricane::CellViewer; + class GraphicBoraEngine; + + + class SlicingPlotWidget : public QWidget { + Q_OBJECT; + public: + SlicingPlotWidget ( QWidget* parent=NULL ); + virtual ~SlicingPlotWidget (); + Cell* getCell (); + void setViewer ( CellViewer* ); + void setDatas (); + public slots: + void onPointSelect ( const QPointF& ); + void updateSelectedPoint ( double x, double y ); + signals: + void updatePlacement ( BoxSet* ); + void updateSelectedRow ( double x, double y ); + private: + CellViewer* _viewer; + QwtPlot* _plot; + QwtPlotPicker* _picker; + QGridLayout* _gridDisplay; + std::vector _gridLabel; + double* _widths; + double* _heights; + double* _widthSelected; + double* _heightSelected; + Pareto _pareto; + QwtPlotCurve* _STreeCurve; + QwtPlotCurve* _paretoCurve; + QwtPlotCurve* _selectedPoint; + } ; + + +} // Bora namespace. + +#endif // BORA_SLICING_PLOT_WIDGET_H diff --git a/bora/src/bora/SlicingWidget.h b/bora/src/bora/SlicingWidget.h new file mode 100644 index 00000000..ee82afc6 --- /dev/null +++ b/bora/src/bora/SlicingWidget.h @@ -0,0 +1,135 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Jean-Paul Chaput, Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/SlicingWidget.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_SLICING_WIDGET_H +#define BORA_SLICING_WIDGET_H + +#include +namespace Hurricane { + class Cell; + class CellViewer; +} +#include "bora/SlicingNode.h" + + +namespace Bora { + + using Hurricane::Cell; + using Hurricane::CellViewer; + class BoraEngine; + class SlicingPlotWidget; + class SlicingDataWidget; + + +// ------------------------------------------------------------------- +// Class : "Bora::SlicingTab". + + + class SlicingTab : public QWidget { + Q_OBJECT; + public: + SlicingTab ( QWidget* parent=NULL ); + inline CellViewer* getViewer (); + public slots: + virtual void setViewer ( CellViewer* ); + virtual void cellPreModificate (); + virtual void cellPostModificate (); + private: + CellViewer* _viewer; + }; + + inline CellViewer* SlicingTab::getViewer () { return _viewer; } + + +// ------------------------------------------------------------------- +// Class : "Bora::TabPlot". + + + class TabPlot : public SlicingTab { + Q_OBJECT; + public: + TabPlot ( QWidget* parent=NULL ); + inline SlicingPlotWidget* getPlot (); + void setDatas (); + public slots: + void setViewer ( CellViewer* ); + signals: + void updateSelectedRow ( double x, double y ); + private: + SlicingPlotWidget* _plot; + }; + + inline SlicingPlotWidget* TabPlot::getPlot () { return _plot; } + + +// ------------------------------------------------------------------- +// Class : "Bora::TabDatas". + + + class TabDatas : public SlicingTab { + Q_OBJECT; + public: + TabDatas ( QWidget* parent=NULL ); + inline SlicingDataWidget* getDatas (); + void updateContents (); + public slots: + void setViewer ( CellViewer* ); + signals: + void updateSelectedPoint ( double x, double y ); + private: + SlicingDataWidget* _datas; + }; + + inline SlicingDataWidget* TabDatas::getDatas () { return _datas; } + + +// ------------------------------------------------------------------- +// Class : "Bora::SlicingWidget". + + + class SlicingWidget : public QTabWidget { + Q_OBJECT; + public: + SlicingWidget ( QWidget* parent=NULL ); + inline CellViewer* getViewer (); + inline SlicingPlotWidget* getPlotWidget (); + inline SlicingDataWidget* getDataWidget (); + void setViewer ( CellViewer* ); + void setCell ( Cell* ); + void updateContents(); + signals: + void updatePlacement ( BoxSet* ); + + public slots: + void cellPreModificate (); + void cellPostModificate (); + void cellChanged ( Cell* ); + void toggleShow (); + private: + Cell* _cell; + CellViewer* _viewer; + TabPlot* _tabPlot; + TabDatas* _tabDatas; + }; + + + inline SlicingPlotWidget* SlicingWidget::getPlotWidget () { return _tabPlot->getPlot(); } + inline SlicingDataWidget* SlicingWidget::getDataWidget () { return _tabDatas->getDatas(); } + + +} // Bora namespace. + +#endif // BORA_SLICING_WIDGET_H diff --git a/bora/src/bora/VSlicingNode.h b/bora/src/bora/VSlicingNode.h new file mode 100644 index 00000000..9f600fc6 --- /dev/null +++ b/bora/src/bora/VSlicingNode.h @@ -0,0 +1,78 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | B o r a - A n a l o g S l i c i n g T r e e | +// | | +// | Authors : Eric LAO | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./bora/VSlicingNode.h" | +// +-----------------------------------------------------------------+ + + +#ifndef BORA_V_SLICING_NODE_H +#define BORA_V_SLICING_NODE_H + +#include "bora/HVSlicingNode.h" + + +namespace Bora { + + +// ------------------------------------------------------------------- +// Class : "Bora::VSlicingNode". + + + class VSlicingNode: public HVSlicingNode + { + public: + typedef HVSlicingNode Super; + private: + VSlicingNode ( unsigned int type, unsigned int alignment=UnknownAlignment); + ~VSlicingNode (); + public: + static VSlicingNode* create ( unsigned int alignment=AlignBottom ); + void createRouting ( DbU::Unit space ); + + void print () const; + VSlicingNode* clone ( unsigned int tr=None ); + void place ( DbU::Unit x=0, DbU::Unit y=0 ); + void replace ( DbU::Unit x=0, DbU::Unit y=0 ); + void _place ( DbU::Unit x=0, DbU::Unit y=0, bool replace=false ); + void updateGlobalSize (); + static inline int getCount (); + static inline void printCount (); + static inline void printCountAll (); + void preDestroy (); + void destroy (); + void preRecursiveDestroy (); + void recursiveDestroy (); + DbU::Unit getHeight () const; + DbU::Unit getWidth () const; + void createSlicingRouting (); + void setGCell ( Anabatic::GCell* ); + void adjustBorderChannels (); + virtual std::string _getString () const; + virtual std::string _getTypeName () const; + private: + static int _count; + static int _countAll; +}; + + + inline int VSlicingNode::getCount () { return _count; } + inline void VSlicingNode::printCount () { std::cerr << "VSlicingNode::Count = " << _count << std::endl; } + inline void VSlicingNode::printCountAll () { std::cerr << "VSlicingNode::CountAll = " << _countAll << std::endl; } + + +} // Bora namespace. + + +GETSTRING_POINTER_SUPPORT(Bora::VSlicingNode) +IOSTREAM_POINTER_SUPPORT(Bora::VSlicingNode) + +#endif // BORA_V_SLICING_NODE_H diff --git a/bora/src/cpps b/bora/src/cpps new file mode 100644 index 00000000..64badc21 --- /dev/null +++ b/bora/src/cpps @@ -0,0 +1,58 @@ +bora/AnalogGlobalRoute.h +bora/BoraEngine.h +bora/BoxSet.h +bora/ChannelRouting.h +bora/DSlicingNode.h +bora/GraphicBoraEngine.h +bora/HSlicingNode.h +bora/HVSetState.h +bora/HVSlicingNode.h +bora/NodeSets.h +bora/Pareto.h +bora/RHSlicingNode.h +bora/RHVSlicingNode.h +bora/RVSlicingNode.h +bora/SlicingDataModel.h +bora/SlicingDataWidget.h +bora/SlicingNode-full.h +bora/SlicingNode.h +bora/SlicingPlotWidget.h +bora/SlicingWidget.h +bora/VSlicingNode.h +BoraEngine.cpp +BoxSet.cpp +ChannelRouting.cpp +DSlicingNode.cpp +GraphicBoraEngine.cpp +HSlicingNode.cpp +HVSetState.cpp +HVSlicingNode.cpp +NodeSets.cpp +Pareto.cpp +RHSlicingNode.cpp +RHVSlicingNode.cpp +RVSlicingNode.cpp +SlicingDataModel.cpp +SlicingDataWidget.cpp +SlicingNode.cpp +SlicingNode-full.cpp +SlicingPlotWidget.cpp +SlicingWidget.cpp +VSlicingNode.cpp +PyBora.cpp +PyBoraEngine.cpp +PyDSlicingNode.cpp +PyGraphicBoraEngine.cpp +PyHSlicingNode.cpp +PyRHSlicingNode.cpp +PyRVSlicingNode.cpp +PySlicingNode.cpp +PyVSlicingNode.cpp +bora/PyBoraEngine.h +bora/PyDSlicingNode.h +bora/PyGraphicBoraEngine.h +bora/PyHSlicingNode.h +bora/PyRHSlicingNode.h +bora/PyRVSlicingNode.h +bora/PySlicingNode.h +bora/PyVSlicingNode.h diff --git a/crlcore/doc/crlcore/html/AcmSigda_8h_source.html b/crlcore/doc/crlcore/html/AcmSigda_8h_source.html index 3bd49a3f..c9e82b04 100644 --- a/crlcore/doc/crlcore/html/AcmSigda_8h_source.html +++ b/crlcore/doc/crlcore/html/AcmSigda_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 
-
2 // -*- C++ -*-
-
3 //
-
4 // This file is part of the Coriolis Software.
-
5 // Copyright (c) UPMC/LIP6 2010-2012, All Rights Reserved
-
6 //
-
7 // +-----------------------------------------------------------------+
-
8 // | C O R I O L I S |
-
9 // | ACM/SIGDA ISCAS 89 Benchmarks |
-
10 // | |
-
11 // | Author : Jean-Paul CHAPUT |
-
12 // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
-
13 // | =============================================================== |
-
14 // | C++ Header : "./crlcore/AcmSigda.h" |
-
15 // +-----------------------------------------------------------------+
-
16 
-
17 
-
18 #ifndef __CRL_ACM_SIGDA__
-
19 #define __CRL_ACM_SIGDA__
-
20 
-
21 #include <string>
-
22 
-
23 namespace Hurricane {
-
24  class Cell;
-
25 }
-
26 
-
27 
-
28 namespace CRL {
-
29 
-
30  using Hurricane::Cell;
-
31 
-
32 
-
33  class AcmSigda {
-
34  public:
-
35  static Cell* load ( std::string benchmark );
-
36  };
-
37 
-
38 
-
39 } // End of CRL namespace.
-
40 
-
41 
-
42 #endif // __CRL_ACM_SIGDA__
-
43 
- +
1 
2 // -*- C++ -*-
3 //
4 // This file is part of the Coriolis Software.
5 // Copyright (c) UPMC/LIP6 2010-2012, All Rights Reserved
6 //
7 // +-----------------------------------------------------------------+
8 // | C O R I O L I S |
9 // | ACM/SIGDA ISCAS 89 Benchmarks |
10 // | |
11 // | Author : Jean-Paul CHAPUT |
12 // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
13 // | =============================================================== |
14 // | C++ Header : "./crlcore/AcmSigda.h" |
15 // +-----------------------------------------------------------------+
16 
17 
18 #ifndef __CRL_ACM_SIGDA__
19 #define __CRL_ACM_SIGDA__
20 
21 #include <string>
22 
23 namespace Hurricane {
24  class Cell;
25 }
26 
27 
28 namespace CRL {
29 
30  using Hurricane::Cell;
31 
32 
33  class AcmSigda {
34  public:
35  static Cell* load ( std::string benchmark );
36  };
37 
38 
39 } // End of CRL namespace.
40 
41 
42 #endif // __CRL_ACM_SIGDA__
43 
static Cell * load(std::string benchmark)
A Parser of ACM/Sigda 89&#39; benchmarks.
Definition: AcmSigda.h:33
+ +
The namespace of Coriolis Core.
Definition: Environment.h:26


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/AllianceFramework_8h_source.html b/crlcore/doc/crlcore/html/AllianceFramework_8h_source.html index 4e85bf5d..87ce4f41 100644 --- a/crlcore/doc/crlcore/html/AllianceFramework_8h_source.html +++ b/crlcore/doc/crlcore/html/AllianceFramework_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 // -*- C++ -*-
-
2 //
-
3 // This file is part of the Coriolis Software.
-
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
-
5 //
-
6 // +-----------------------------------------------------------------+
-
7 // | C O R I O L I S |
-
8 // | Alliance / Hurricane Interface |
-
9 // | |
-
10 // | Author : Jean-Paul CHAPUT |
-
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
-
12 // | =============================================================== |
-
13 // | C++ Header : "./crlcore/AllianceFramework.h" |
-
14 // +-----------------------------------------------------------------+
-
15 
-
16 
-
17 #ifndef CRL_ALLIANCE_FRAMEWORK_H
-
18 #define CRL_ALLIANCE_FRAMEWORK_H
-
19 
-
20 #include <map>
-
21 #include <limits>
-
22 #include "hurricane/Cell.h"
-
23 #include "crlcore/Environment.h"
-
24 #include "crlcore/AllianceLibrary.h"
-
25 #include "crlcore/Catalog.h"
-
26 #include "crlcore/ParsersDrivers.h"
-
27 
-
28 
-
29 namespace CRL {
-
30 
-
31  using Hurricane::Observable;
-
32  using Hurricane::BaseObserver;
- - -
35  using Hurricane::Cell;
-
36  using Hurricane::Net;
-
37  class RoutingGauge;
-
38  class CellGauge;
-
39 
-
40 
- -
42  public:
-
43  enum FunctionsFlags { NoFlags = 0
-
44  , NoPythonInit = (1<<0)
-
45  };
- -
47  , IgnoreFeeds = (1<<1)
-
48  };
-
49  enum LibraryFlags { CreateLibrary = (1<<0)
-
50  , AppendLibrary = (1<<1)
-
51  , HasCatalog = (1<<2)
-
52  };
-
53  enum NotifyFlags { AddedLibrary = (1<<0)
-
54  , RemovedLibrary = (1<<1)
-
55  , ConfigChanged = (1<<2)
-
56  };
-
57  public:
-
58  // Constructors.
-
59  static AllianceFramework* create ( unsigned long flags=NoFlags );
-
60  // Destructors.
-
61  void destroy ();
-
62  // Accessors.
-
63  static AllianceFramework* get ();
-
64  string getPrint () const;
-
65  // Predicates.
-
66  Catalog::State* isInCatalog ( const Name& );
-
67  Catalog::State* isInCatalog ( string );
-
68  inline bool isPOWER ( const char* name );
-
69  inline bool isPOWER ( const string& name );
-
70  inline bool isPOWER ( const Name& name );
-
71  inline bool isGROUND ( const char* name );
-
72  inline bool isGROUND ( const string& name );
-
73  inline bool isGROUND ( const Name& name );
-
74  inline bool isCLOCK ( const char* name );
-
75  inline bool isCLOCK ( const string& name );
-
76  inline bool isCLOCK ( const Name& name );
-
77  inline bool isBLOCKAGE ( const char* name );
-
78  inline bool isBLOCKAGE ( const string& name );
-
79  inline bool isBLOCKAGE ( const Name& name );
-
80  inline bool isBLOCKAGE ( const Net* net );
-
81  inline bool isPad ( const char* name );
-
82  inline bool isPad ( const string& name );
-
83  inline bool isPad ( const Name& name );
-
84  inline bool isPad ( const Cell* );
-
85  // Accessors.
-
86  inline Environment* getEnvironment ();
-
87  inline Catalog* getCatalog ();
-
88  inline const Name& getParentLibraryName () const;
-
89  inline Library* getParentLibrary ();
-
90  Library* getLibrary ( unsigned int index );
-
91  Library* getLibrary ( const Name& libName );
-
92  AllianceLibrary* getAllianceLibrary ( unsigned int index );
-
93  AllianceLibrary* getAllianceLibrary ( const Name& libName, unsigned int flags );
- -
95  AllianceLibrary* createLibrary ( const string& path, unsigned int flags, string libName="" );
-
96  inline const AllianceLibraries& getAllianceLibraries () const;
-
97  void saveLibrary ( Library* );
-
98  void saveLibrary ( AllianceLibrary* );
-
99  RoutingGauge* getRoutingGauge ( const Name& name="" );
-
100  CellGauge* getCellGauge ( const Name& name="" );
-
101  inline const Name getDefaultCGPinLayerName () const;
-
102  // Modifiers.
-
103  RoutingGauge* setRoutingGauge ( const Name& name="" );
-
104  CellGauge* setCellGauge ( const Name& name="" );
-
105  void addRoutingGauge ( RoutingGauge* );
-
106  void addCellGauge ( CellGauge* );
-
107  void addObserver ( BaseObserver* );
-
108  void removeObserver ( BaseObserver* );
-
109  void notify ( unsigned int flags );
-
110  // Cell Management.
-
111  Cell* cellLoader ( const string& rpath );
-
112  Cell* getCell ( const string& name
-
113  , unsigned int mode
-
114  , unsigned int depth=(unsigned int)-1 );
-
115  Cell* createCell ( const string& name, AllianceLibrary* library=NULL );
-
116  void saveCell ( Cell* , unsigned int mode );
-
117  unsigned int loadLibraryCells ( Library* );
-
118  unsigned int loadLibraryCells ( const Name& );
-
119  static size_t getInstancesCount ( Cell*, unsigned int flags );
-
120  // Hurricane Managment.
-
121  void toJson ( JsonWriter* ) const;
-
122  inline string _getTypeName () const;
-
123  string _getString () const;
-
124  Record* _getRecord () const;
-
125 
-
126  // Internals - Attributes.
-
127  protected:
-
128  static const Name _parentLibraryName;
-
129  static AllianceFramework* _singleton;
-
130  Observable _observers;
-
131  Environment _environment;
-
132  ParsersMap _parsers;
-
133  DriversMap _drivers;
-
134  Catalog _catalog;
-
135  AllianceLibraries _libraries;
-
136  Library* _parentLibrary;
-
137  map<Name,RoutingGauge*> _routingGauges;
-
138  RoutingGauge* _defaultRoutingGauge;
-
139  map<Name,CellGauge*> _cellGauges;
-
140  CellGauge* _defaultCellGauge;
-
141 
-
142  // Internals - Constructors.
- - -
145  AllianceFramework& operator= ( const AllianceFramework& );
-
146  // Internals - Destructors.
-
147  ~AllianceFramework ();
-
148  // Internals - Methods.
-
149  bool _readLocate ( const string& file, unsigned int mode, bool isLib=false );
-
150  bool _writeLocate ( const string& file, unsigned int mode, bool isLib=false );
-
151  AllianceLibrary* _createLibrary ( const string& path, bool& hasCatalog );
-
152  void _bindLibraries ();
-
153  };
-
154 
-
155  inline bool AllianceFramework::isPOWER ( const char* name ) { return _environment.isPOWER(name); }
-
156  inline bool AllianceFramework::isPOWER ( const string& name ) { return isPOWER(name.c_str()); }
-
157  inline bool AllianceFramework::isPOWER ( const Name& name ) { return isPOWER(getString(name)); }
-
158  inline bool AllianceFramework::isGROUND ( const char* name ) { return _environment.isGROUND(name); }
-
159  inline bool AllianceFramework::isGROUND ( const string& name ) { return isGROUND(name.c_str()); }
-
160  inline bool AllianceFramework::isGROUND ( const Name& name ) { return isGROUND(getString(name)); }
-
161  inline bool AllianceFramework::isCLOCK ( const char* name ) { return _environment.isCLOCK(name); }
-
162  inline bool AllianceFramework::isCLOCK ( const string& name ) { return isCLOCK(name.c_str()); }
-
163  inline bool AllianceFramework::isCLOCK ( const Name& name ) { return isCLOCK(getString(name)); }
-
164  inline bool AllianceFramework::isBLOCKAGE ( const char* name ) { return _environment.isBLOCKAGE(name); }
-
165  inline bool AllianceFramework::isBLOCKAGE ( const string& name ) { return isBLOCKAGE(name.c_str()); }
-
166  inline bool AllianceFramework::isBLOCKAGE ( const Name& name ) { return isBLOCKAGE(getString(name)); }
-
167  inline bool AllianceFramework::isBLOCKAGE ( const Net* net ) { return isBLOCKAGE(net->getName()); }
-
168  inline bool AllianceFramework::isPad ( const char* name ) { return _environment.isPad(name); }
-
169  inline bool AllianceFramework::isPad ( const string& name ) { return isPad(name.c_str()); }
-
170  inline bool AllianceFramework::isPad ( const Name& name ) { return isPad(getString(name)); }
-
171  inline bool AllianceFramework::isPad ( const Cell* cell ) { return isPad(cell->getName()); }
-
172  inline Environment* AllianceFramework::getEnvironment () { return &_environment; }
-
173  inline Catalog* AllianceFramework::getCatalog () { return &_catalog; }
- -
175  () const { return _parentLibraryName; }
-
176  inline Library* AllianceFramework::getParentLibrary () { return _parentLibrary; }
-
177  inline const AllianceLibraries&
-
178  AllianceFramework::getAllianceLibraries () const { return _libraries; }
-
179 // TEMPORARY.
- -
181  () const { return "CALU1"; }
-
182  inline string AllianceFramework::_getTypeName () const { return "AllianceFramework"; }
-
183 
-
184 
-
185  class JsonAllianceFramework : public JsonObject {
-
186  public:
-
187  static void initialize ();
-
188  JsonAllianceFramework( unsigned long );
-
189  virtual ~JsonAllianceFramework();
-
190  virtual string getTypeName () const;
-
191  virtual JsonAllianceFramework* clone ( unsigned long ) const;
-
192  virtual void toData ( JsonStack& );
-
193  private:
-
194  std::string _defaultRoutingGauge;
-
195  std::string _defaultCellGauge;
-
196  };
-
197 
-
198 
-
199 } // CRL namespace.
-
200 
-
201 
-
202 INSPECTOR_P_SUPPORT(CRL::AllianceFramework);
-
203 
-
204 #endif // CRL_ALLIANCE_FRAMEWORK_H
-
A small wrapper around Hurricane::Library.
Definition: AllianceLibrary.h:44
-
bool isPOWER(const char *name) const
+
1 // -*- C++ -*-
2 //
3 // This file is part of the Coriolis Software.
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
5 //
6 // +-----------------------------------------------------------------+
7 // | C O R I O L I S |
8 // | Alliance / Hurricane Interface |
9 // | |
10 // | Author : Jean-Paul CHAPUT |
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
12 // | =============================================================== |
13 // | C++ Header : "./crlcore/AllianceFramework.h" |
14 // +-----------------------------------------------------------------+
15 
16 
17 #ifndef CRL_ALLIANCE_FRAMEWORK_H
18 #define CRL_ALLIANCE_FRAMEWORK_H
19 
20 #include <map>
21 #include <limits>
22 #include "hurricane/Cell.h"
23 #include "crlcore/Environment.h"
24 #include "crlcore/AllianceLibrary.h"
25 #include "crlcore/Catalog.h"
26 #include "crlcore/ParsersDrivers.h"
27 
28 
29 namespace CRL {
30 
31  using Hurricane::Observable;
32  using Hurricane::BaseObserver;
35  using Hurricane::Cell;
36  using Hurricane::Net;
37  class RoutingGauge;
38  class CellGauge;
39 
40 
42  public:
43  enum FunctionsFlags { NoFlags = 0
44  , NoPythonInit = (1<<0)
45  };
47  , IgnoreFeeds = (1<<1)
48  };
49  enum LibraryFlags { CreateLibrary = (1<<0)
50  , AppendLibrary = (1<<1)
51  , HasCatalog = (1<<2)
52  };
53  enum NotifyFlags { AddedLibrary = (1<<0)
54  , RemovedLibrary = (1<<1)
55  , ConfigChanged = (1<<2)
56  };
57  public:
58  // Constructors.
59  static AllianceFramework* create ( unsigned long flags=NoFlags );
60  // Destructors.
61  void destroy ();
62  // Accessors.
63  static AllianceFramework* get ();
64  string getPrint () const;
65  // Predicates.
66  Catalog::State* isInCatalog ( const Name& );
67  Catalog::State* isInCatalog ( string );
68  inline bool isPOWER ( const char* name );
69  inline bool isPOWER ( const string& name );
70  inline bool isPOWER ( const Name& name );
71  inline bool isGROUND ( const char* name );
72  inline bool isGROUND ( const string& name );
73  inline bool isGROUND ( const Name& name );
74  inline bool isCLOCK ( const char* name );
75  inline bool isCLOCK ( const string& name );
76  inline bool isCLOCK ( const Name& name );
77  inline bool isBLOCKAGE ( const char* name );
78  inline bool isBLOCKAGE ( const string& name );
79  inline bool isBLOCKAGE ( const Name& name );
80  inline bool isBLOCKAGE ( const Net* net );
81  inline bool isPad ( const char* name );
82  inline bool isPad ( const string& name );
83  inline bool isPad ( const Name& name );
84  inline bool isPad ( const Cell* );
85  // Accessors.
86  inline Environment* getEnvironment ();
87  inline Catalog* getCatalog ();
88  inline const Name& getParentLibraryName () const;
89  inline Library* getParentLibrary ();
90  Library* getLibrary ( unsigned int index );
91  Library* getLibrary ( const Name& libName );
92  AllianceLibrary* getAllianceLibrary ( unsigned int index );
93  AllianceLibrary* getAllianceLibrary ( const Name& libName, unsigned int flags );
94  AllianceLibrary* getAllianceLibrary ( Library* );
95  AllianceLibrary* createLibrary ( const string& path, unsigned int flags, string libName="" );
96  inline const AllianceLibraries& getAllianceLibraries () const;
97  void saveLibrary ( Library* );
98  void saveLibrary ( AllianceLibrary* );
99  RoutingGauge* getRoutingGauge ( const Name& name="" );
100  CellGauge* getCellGauge ( const Name& name="" );
101  inline const Name getDefaultCGPinLayerName () const;
102  // Modifiers.
103  RoutingGauge* setRoutingGauge ( const Name& name="" );
104  CellGauge* setCellGauge ( const Name& name="" );
105  void addRoutingGauge ( RoutingGauge* );
106  void addCellGauge ( CellGauge* );
107  void addObserver ( BaseObserver* );
108  void removeObserver ( BaseObserver* );
109  void notify ( unsigned int flags );
110  // Cell Management.
111  Cell* cellLoader ( const string& rpath );
112  Cell* getCell ( const string& name
113  , unsigned int mode
114  , unsigned int depth=(unsigned int)-1 );
115  Cell* createCell ( const string& name, AllianceLibrary* library=NULL );
116  void saveCell ( Cell* , unsigned int mode );
117  unsigned int loadLibraryCells ( Library* );
118  unsigned int loadLibraryCells ( const Name& );
119  static size_t getInstancesCount ( Cell*, unsigned int flags );
120  // Hurricane Managment.
121  void toJson ( JsonWriter* ) const;
122  inline string _getTypeName () const;
123  string _getString () const;
124  Record* _getRecord () const;
125 
126  // Internals - Attributes.
127  protected:
128  static const Name _parentLibraryName;
129  static AllianceFramework* _singleton;
130  Observable _observers;
131  Environment _environment;
132  ParsersMap _parsers;
133  DriversMap _drivers;
134  Catalog _catalog;
135  AllianceLibraries _libraries;
136  Library* _parentLibrary;
137  map<Name,RoutingGauge*> _routingGauges;
138  RoutingGauge* _defaultRoutingGauge;
139  map<Name,CellGauge*> _cellGauges;
140  CellGauge* _defaultCellGauge;
141 
142  // Internals - Constructors.
143  AllianceFramework ();
144  AllianceFramework ( const AllianceFramework& );
145  AllianceFramework& operator= ( const AllianceFramework& );
146  // Internals - Destructors.
147  ~AllianceFramework ();
148  // Internals - Methods.
149  bool _readLocate ( const string& file, unsigned int mode, bool isLib=false );
150  bool _writeLocate ( const string& file, unsigned int mode, bool isLib=false );
151  AllianceLibrary* _createLibrary ( const string& path, bool& hasCatalog );
152  void _bindLibraries ();
153  };
154 
155  inline bool AllianceFramework::isPOWER ( const char* name ) { return _environment.isPOWER(name); }
156  inline bool AllianceFramework::isPOWER ( const string& name ) { return isPOWER(name.c_str()); }
157  inline bool AllianceFramework::isPOWER ( const Name& name ) { return isPOWER(getString(name)); }
158  inline bool AllianceFramework::isGROUND ( const char* name ) { return _environment.isGROUND(name); }
159  inline bool AllianceFramework::isGROUND ( const string& name ) { return isGROUND(name.c_str()); }
160  inline bool AllianceFramework::isGROUND ( const Name& name ) { return isGROUND(getString(name)); }
161  inline bool AllianceFramework::isCLOCK ( const char* name ) { return _environment.isCLOCK(name); }
162  inline bool AllianceFramework::isCLOCK ( const string& name ) { return isCLOCK(name.c_str()); }
163  inline bool AllianceFramework::isCLOCK ( const Name& name ) { return isCLOCK(getString(name)); }
164  inline bool AllianceFramework::isBLOCKAGE ( const char* name ) { return _environment.isBLOCKAGE(name); }
165  inline bool AllianceFramework::isBLOCKAGE ( const string& name ) { return isBLOCKAGE(name.c_str()); }
166  inline bool AllianceFramework::isBLOCKAGE ( const Name& name ) { return isBLOCKAGE(getString(name)); }
167  inline bool AllianceFramework::isBLOCKAGE ( const Net* net ) { return isBLOCKAGE(net->getName()); }
168  inline bool AllianceFramework::isPad ( const char* name ) { return _environment.isPad(name); }
169  inline bool AllianceFramework::isPad ( const string& name ) { return isPad(name.c_str()); }
170  inline bool AllianceFramework::isPad ( const Name& name ) { return isPad(getString(name)); }
171  inline bool AllianceFramework::isPad ( const Cell* cell ) { return isPad(cell->getName()); }
172  inline Environment* AllianceFramework::getEnvironment () { return &_environment; }
173  inline Catalog* AllianceFramework::getCatalog () { return &_catalog; }
175  () const { return _parentLibraryName; }
176  inline Library* AllianceFramework::getParentLibrary () { return _parentLibrary; }
177  inline const AllianceLibraries&
178  AllianceFramework::getAllianceLibraries () const { return _libraries; }
179 // TEMPORARY.
181  () const { return "CALU1"; }
182  inline string AllianceFramework::_getTypeName () const { return "AllianceFramework"; }
183 
184 
185  class JsonAllianceFramework : public JsonObject {
186  public:
187  static void initialize ();
188  JsonAllianceFramework( unsigned long );
189  virtual ~JsonAllianceFramework();
190  virtual string getTypeName () const;
191  virtual JsonAllianceFramework* clone ( unsigned long ) const;
192  virtual void toData ( JsonStack& );
193  private:
194  std::string _defaultRoutingGauge;
195  std::string _defaultCellGauge;
196  };
197 
198 
199 } // CRL namespace.
200 
201 
202 INSPECTOR_P_SUPPORT(CRL::AllianceFramework);
203 
204 #endif // CRL_ALLIANCE_FRAMEWORK_H
bool isBLOCKAGE(const char *name) const
Library * getParentLibrary()
Definition: AllianceFramework.h:176
-
An entry to store the Cell State in the Catalog.
Definition: Catalog.h:76
+
bool isCLOCK(const char *name) const
A Framework to work with Alliance formats.
Definition: AllianceFramework.h:41
+
const Name getDefaultCGPinLayerName() const
Definition: AllianceFramework.h:181
+
bool isPOWER(const char *name) const
void addCellGauge(CellGauge *)
-
const Name & getParentLibraryName() const
Definition: AllianceFramework.h:175
InstancesCountFlags
Definition: AllianceFramework.h:46
-
bool isBLOCKAGE(const char *name) const
+
static size_t getInstancesCount(Cell *, unsigned int flags)
void saveCell(Cell *, unsigned int mode)
-
Gauge for the detailed routing.
Definition: RoutingGauge.h:48
AllianceLibrary * createLibrary(const string &path, unsigned int flags, string libName="")
LibraryFlags
Definition: AllianceFramework.h:49
-
bool isCLOCK(const char *name) const
+
bool isPad(const char *name) const
-
bool isGROUND(const char *name) const
-
const Name getDefaultCGPinLayerName() const
Definition: AllianceFramework.h:181
+
bool isGROUND(const char *name) const
Definition: AllianceFramework.h:46
Library * getLibrary(unsigned int index)
-
Cell * getCell(const string &name, unsigned int mode, unsigned int depth=(unsigned int)-1)
+
const Name & getParentLibraryName() const
Definition: AllianceFramework.h:175
void addRoutingGauge(RoutingGauge *)
-
bool isPad(const char *name) const
Definition: AllianceFramework.h:49
-
string getPrint() const
unsigned int loadLibraryCells(Library *)
Cell * createCell(const string &name, AllianceLibrary *library=NULL)
Catalog * getCatalog()
Definition: AllianceFramework.h:173
@@ -292,16 +79,18 @@
AllianceLibrary * getAllianceLibrary(unsigned int index)
Definition: AllianceFramework.h:51
Holds all the Alliance environment variables.
Definition: Environment.h:35
-
Environment * getEnvironment()
Definition: AllianceFramework.h:172
+
string getPrint() const
void saveLibrary(Library *)
+
Cell * getCell(const string &name, unsigned int mode, unsigned int depth=(unsigned int) -1)
static AllianceFramework * create(unsigned long flags=NoFlags)
+
The namespace of Coriolis Core.
Definition: Environment.h:26


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/AllianceLibrary_8h_source.html b/crlcore/doc/crlcore/html/AllianceLibrary_8h_source.html index c6dc3fc4..bec4924a 100644 --- a/crlcore/doc/crlcore/html/AllianceLibrary_8h_source.html +++ b/crlcore/doc/crlcore/html/AllianceLibrary_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 // -*- C++ -*-
-
2 //
-
3 // This file is part of the Coriolis Software.
-
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
-
5 //
-
6 // +-----------------------------------------------------------------+
-
7 // | C O R I O L I S |
-
8 // | Alliance / Hurricane Interface |
-
9 // | |
-
10 // | Author : Jean-Paul CHAPUT |
-
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
-
12 // | =============================================================== |
-
13 // | C++ Header : "./crlcore/AllianceLibrary.h" |
-
14 // +-----------------------------------------------------------------+
-
15 
-
16 
-
17 #ifndef CRL_ALLIANCE_LIBRARY_H
-
18 #define CRL_ALLIANCE_LIBRARY_H
-
19 
-
20 #include <string>
-
21 #include <vector>
-
22 #include "hurricane/Name.h"
-
23 #include "hurricane/Slot.h"
-
24 
-
25 namespace Hurricane {
-
26  class Library;
-
27 }
-
28 
-
29 
-
30 namespace CRL {
-
31 
-
32  using std::vector;
- - -
35  using Hurricane::Name;
-
36  using Hurricane::Library;
-
37  using Hurricane::Record;
-
38  using Hurricane::_TName;
-
39 
-
40 
-
41 // -------------------------------------------------------------------
-
42 // Class : "CRL::AllianceLibrary".
-
43 
- -
45 
-
46  public:
-
47  // Constructors.
-
48  AllianceLibrary ();
-
49  AllianceLibrary ( const Name& path, Library* library=NULL );
-
50  // Operators
-
51  AllianceLibrary& operator= ( const AllianceLibrary& directory );
-
52  AllianceLibrary& operator= ( const std::string& path );
-
53  // Accessors
-
54  inline const Name& getPath () const;
-
55  inline Library* getLibrary () const;
-
56  // Hurricane management.
-
57  void toJson ( JsonWriter* ) const;
-
58  inline std::string _getTypeName () const;
-
59  std::string _getString () const;
-
60  Record* _getRecord () const;
-
61 
-
62  protected:
-
63  // Internal - Attributes.
-
64  Name _path;
-
65  Library* _library;
-
66 
-
67  };
-
68 
-
69 
-
70  typedef vector<AllianceLibrary*> AllianceLibraries;
-
71 
-
72 
-
73 // Inline Functions.
-
74  inline const Name& AllianceLibrary::getPath () const { return _path; }
-
75  inline Library* AllianceLibrary::getLibrary () const { return _library; }
-
76  inline std::string AllianceLibrary::_getTypeName () const { return _TName("AllianceLibrary"); }
-
77 
-
78 
-
79 // -------------------------------------------------------------------
-
80 // Class : "JsonAllianceLibrary".
-
81 
-
82  class JsonAllianceLibrary : public JsonObject {
-
83  public:
-
84  static void initialize ();
-
85  JsonAllianceLibrary ( unsigned long flags );
-
86  virtual std::string getTypeName () const;
-
87  virtual JsonAllianceLibrary* clone ( unsigned long flags ) const;
-
88  virtual void toData ( JsonStack& );
-
89  };
-
90 
-
91 
-
92 } // CRL namespace.
-
93 
-
94 
-
95 INSPECTOR_P_SUPPORT(CRL::AllianceLibrary);
-
96 
-
97 #endif // CRL_ALLIANCE_LIBRARY_H
-
A small wrapper around Hurricane::Library.
Definition: AllianceLibrary.h:44
+
1 // -*- C++ -*-
2 //
3 // This file is part of the Coriolis Software.
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
5 //
6 // +-----------------------------------------------------------------+
7 // | C O R I O L I S |
8 // | Alliance / Hurricane Interface |
9 // | |
10 // | Author : Jean-Paul CHAPUT |
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
12 // | =============================================================== |
13 // | C++ Header : "./crlcore/AllianceLibrary.h" |
14 // +-----------------------------------------------------------------+
15 
16 
17 #ifndef CRL_ALLIANCE_LIBRARY_H
18 #define CRL_ALLIANCE_LIBRARY_H
19 
20 #include <string>
21 #include <vector>
22 #include "hurricane/Name.h"
23 #include "hurricane/Slot.h"
24 
25 namespace Hurricane {
26  class Library;
27 }
28 
29 
30 namespace CRL {
31 
32  using std::vector;
35  using Hurricane::Name;
36  using Hurricane::Library;
37  using Hurricane::Record;
38  using Hurricane::_TName;
39 
40 
41 // -------------------------------------------------------------------
42 // Class : "CRL::AllianceLibrary".
43 
45 
46  public:
47  // Constructors.
48  AllianceLibrary ();
49  AllianceLibrary ( const Name& path, Library* library=NULL );
50  // Operators
51  AllianceLibrary& operator= ( const AllianceLibrary& directory );
52  AllianceLibrary& operator= ( const std::string& path );
53  // Accessors
54  inline const Name& getPath () const;
55  inline Library* getLibrary () const;
56  // Hurricane management.
57  void toJson ( JsonWriter* ) const;
58  inline std::string _getTypeName () const;
59  std::string _getString () const;
60  Record* _getRecord () const;
61 
62  protected:
63  // Internal - Attributes.
64  Name _path;
65  Library* _library;
66 
67  };
68 
69 
70  typedef vector<AllianceLibrary*> AllianceLibraries;
71 
72 
73 // Inline Functions.
74  inline const Name& AllianceLibrary::getPath () const { return _path; }
75  inline Library* AllianceLibrary::getLibrary () const { return _library; }
76  inline std::string AllianceLibrary::_getTypeName () const { return _TName("AllianceLibrary"); }
77 
78 
79 // -------------------------------------------------------------------
80 // Class : "JsonAllianceLibrary".
81 
82  class JsonAllianceLibrary : public JsonObject {
83  public:
84  static void initialize ();
85  JsonAllianceLibrary ( unsigned long flags );
86  virtual std::string getTypeName () const;
87  virtual JsonAllianceLibrary* clone ( unsigned long flags ) const;
88  virtual void toData ( JsonStack& );
89  };
90 
91 
92 } // CRL namespace.
93 
94 
95 INSPECTOR_P_SUPPORT(CRL::AllianceLibrary);
96 
97 #endif // CRL_ALLIANCE_LIBRARY_H
A small wrapper around Hurricane::Library.
Definition: AllianceLibrary.h:44
-
Library * getLibrary() const
Definition: AllianceLibrary.h:75
-
const Name & getPath() const
Definition: AllianceLibrary.h:74
+
const Name & getPath() const
Definition: AllianceLibrary.h:74
+ +
Library * getLibrary() const
Definition: AllianceLibrary.h:75
+
The namespace of Coriolis Core.
Definition: Environment.h:26


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/Banner_8h_source.html b/crlcore/doc/crlcore/html/Banner_8h_source.html index 7caa8beb..68d6192d 100644 --- a/crlcore/doc/crlcore/html/Banner_8h_source.html +++ b/crlcore/doc/crlcore/html/Banner_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 // -*- C++ -*-
-
2 //
-
3 // This file is part of the Coriolis Software.
-
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
-
5 //
-
6 // +-----------------------------------------------------------------+
-
7 // | C O R I O L I S |
-
8 // | Alliance / Hurricane Interface |
-
9 // | |
-
10 // | Author : Jean-Paul CHAPUT |
-
11 // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
-
12 // | =============================================================== |
-
13 // | C++ Header : "./crlcore/Banner.h" |
-
14 // +-----------------------------------------------------------------+
-
15 
-
16 
-
17 #ifndef CRL_BANNER_H
-
18 #define CRL_BANNER_H
-
19 
-
20 #include <map>
-
21 #include <string>
-
22 #include <vector>
-
23 #include <ostream>
-
24 #include <sstream>
-
25 
-
26 #ifdef __CCORE_INTERNAL__
-
27 # include "hurricane/CConfig.h"
-
28 #endif
-
29 #include "crlcore/Utilities.h"
-
30 
-
31 
-
32 namespace CRL {
-
33 
-
34  using std::string;
-
35  using std::map;
-
36  using std::vector;
-
37  using std::ostream;
-
38  using std::ostringstream;
-
39 
-
40 
-
41 // -------------------------------------------------------------------
-
42 // Class : "CRL::BannerFont".
-
43 
-
44 
-
45  class BannerFont {
-
46 
-
47  public:
-
48  // BigChar subclass.
-
49  class BigChar {
-
50  public:
-
51  // Constructor & Destructor.
-
52  BigChar ( char c, int height, const char* lines[], const BannerFont* font );
-
53  ~BigChar ();
-
54  // Methods.
-
55  inline int getHeight () const;
-
56  inline const BannerFont* getFont () const;
-
57  string _getPrint () const;
-
58  const char* operator[] ( int line ) const;
-
59 
-
60  private:
-
61  // Internal: Attributes.
-
62  char _character;
-
63  int _height;
-
64  const char** _lines;
-
65  const BannerFont* _font;
-
66 
-
67  // Internal: Constructors.
-
68  BigChar& operator= ( const BigChar& );
-
69  BigChar ( const BigChar& );
-
70  };
-
71 
-
72  // Static Methods.
-
73  static const BannerFont* getBannerFont ( const string& name );
-
74  // Constructor & Destructor.
-
75  inline BannerFont ( const string& name );
-
76  // Methods.
-
77  inline void addChar ( char character, int height, const char *lines[] );
-
78  inline int getHeight () const;
-
79  inline const BigChar& operator[] ( char character ) const;
-
80 
-
81  private:
-
82  // Internal: FontMap subclass.
-
83  class FontMap : public map<const string,const BannerFont*> {
-
84  public:
-
85  FontMap ();
-
86  ~FontMap ();
-
87  const BannerFont* operator[] ( const string& name ) const;
-
88  };
-
89 
-
90  // Internal: Types.
-
91  typedef map<char,BigChar*> CharMap;
-
92 
-
93  // Internal: Static Attributes.
-
94  static FontMap _fontMap;
-
95  // Internal: Attributes.
-
96  CharMap _table;
-
97  string _name;
-
98  int _height;
-
99 
-
100  // Internal: Constructors.
-
101  BannerFont ( const BannerFont& );
-
102  ~BannerFont ();
-
103  inline BannerFont& operator= ( const BannerFont& );
-
104 
-
105  };
-
106 
-
107 
-
108 
-
109 
-
110 // -------------------------------------------------------------------
-
111 // Class : "CRL::Banner".
-
112 
-
113 
-
114  class Banner {
-
115  public:
-
116  // Constructor & Destructor.
-
117  Banner ( string name=""
-
118  , string version=""
-
119  , string purpose=""
-
120  , string date=""
-
121  , string authors=""
-
122  , string contributors="" );
-
123  virtual ~Banner ();
-
124  // Accessors.
-
125  inline const BannerFont* getFont () const;
-
126  inline const string& getName () const;
-
127  inline const string& getVersion () const;
-
128  inline const string& getPurpose () const;
-
129  inline const string& getDate () const;
-
130  inline const string& getAuthors () const;
-
131  inline const string& getContributors () const;
-
132  inline unsigned int getScreenWidth () const;
-
133  // Modifiers.
-
134  void setFont ( BannerFont* font );
-
135  void setName ( string name );
-
136  void setVersion ( string version );
-
137  void setPurpose ( string purpose );
-
138  void setDate ( string date );
-
139  void setAuthors ( string authors );
-
140  void setContributors ( string contributors );
-
141  void setScreenWidth ( unsigned screenWidth );
-
142  // Hurricane Management.
-
143  virtual const string _getPrint () const { return ( _banner.str() ); };
-
144 
-
145  // Internal: Attributes.
-
146  private:
-
147  string _name;
-
148  string _version;
-
149  string _purpose;
-
150  string _date;
-
151  string _authors;
-
152  string _contributors;
-
153  unsigned int _screenWidth;
-
154  size_t _cartoucheWidth;
-
155  const BannerFont* _font;
-
156  string* _lines;
-
157  ostringstream _banner;
-
158 
-
159  // Internal: Constructors.
-
160  Banner ( const Banner & );
-
161  Banner& operator= ( const Banner & );
-
162  // Internal: Methods.
-
163  void _redraw ();
-
164  };
-
165 
-
166 
-
167 // Inline Functions.
-
168  inline int BannerFont::BigChar::getHeight () const { return _height; }
-
169  inline const BannerFont* BannerFont::BigChar::getFont () const { return _font; }
-
170  inline BannerFont::BannerFont ( const string& name ): _table(), _name(name) {}
-
171  inline int BannerFont::getHeight () const { return _height; }
-
172  inline const BannerFont* Banner::getFont () const { return _font; }
-
173  inline const string& Banner::getName () const { return _name; }
-
174  inline const string& Banner::getVersion () const { return _version; }
-
175  inline const string& Banner::getPurpose () const { return _purpose; }
-
176  inline const string& Banner::getDate () const { return _date; }
-
177  inline const string& Banner::getAuthors () const { return _authors; }
-
178  inline const string& Banner::getContributors () const { return _contributors; }
-
179  inline unsigned int Banner::getScreenWidth () const { return _screenWidth; }
-
180 
-
181 
-
182 } // CRL namespace.
-
183 
-
184 
-
185 // Hurricane Management.
-
186 
-
187 inline std::string getPrint ( const CRL::BannerFont::BigChar& c ) { return c._getPrint(); }
-
188 inline std::string getPrint ( const CRL::Banner& b ) { return b._getPrint(); }
-
189 inline std::ostream& operator<< ( std::ostream& o, const CRL::BannerFont::BigChar& c ) { return o << getPrint(c); }
-
190 inline std::ostream& operator<< ( std::ostream& o, const CRL::Banner& b ) { return o << getPrint(b); }
-
191 
-
192 MSTREAM_R_SUPPORT(CRL::Banner);
-
193 
-
194 
-
195 #endif // CRL_BANNER_H
-
const string & getPurpose() const
Definition: Banner.h:175
+
1 // -*- C++ -*-
2 //
3 // This file is part of the Coriolis Software.
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
5 //
6 // +-----------------------------------------------------------------+
7 // | C O R I O L I S |
8 // | Alliance / Hurricane Interface |
9 // | |
10 // | Author : Jean-Paul CHAPUT |
11 // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
12 // | =============================================================== |
13 // | C++ Header : "./crlcore/Banner.h" |
14 // +-----------------------------------------------------------------+
15 
16 
17 #ifndef CRL_BANNER_H
18 #define CRL_BANNER_H
19 
20 #include <map>
21 #include <string>
22 #include <vector>
23 #include <ostream>
24 #include <sstream>
25 
26 #ifdef __CCORE_INTERNAL__
27 # include "hurricane/CConfig.h"
28 #endif
29 #include "crlcore/Utilities.h"
30 
31 
32 namespace CRL {
33 
34  using std::string;
35  using std::map;
36  using std::vector;
37  using std::ostream;
38  using std::ostringstream;
39 
40 
41 // -------------------------------------------------------------------
42 // Class : "CRL::BannerFont".
43 
44 
45  class BannerFont {
46 
47  public:
48  // BigChar subclass.
49  class BigChar {
50  public:
51  // Constructor & Destructor.
52  BigChar ( char c, int height, const char* lines[], const BannerFont* font );
53  ~BigChar ();
54  // Methods.
55  inline int getHeight () const;
56  inline const BannerFont* getFont () const;
57  string _getPrint () const;
58  const char* operator[] ( int line ) const;
59 
60  private:
61  // Internal: Attributes.
62  char _character;
63  int _height;
64  const char** _lines;
65  const BannerFont* _font;
66 
67  // Internal: Constructors.
68  BigChar& operator= ( const BigChar& );
69  BigChar ( const BigChar& );
70  };
71 
72  // Static Methods.
73  static const BannerFont* getBannerFont ( const string& name );
74  // Constructor & Destructor.
75  inline BannerFont ( const string& name );
76  // Methods.
77  inline void addChar ( char character, int height, const char *lines[] );
78  inline int getHeight () const;
79  inline const BigChar& operator[] ( char character ) const;
80 
81  private:
82  // Internal: FontMap subclass.
83  class FontMap : public map<const string,const BannerFont*> {
84  public:
85  FontMap ();
86  ~FontMap ();
87  const BannerFont* operator[] ( const string& name ) const;
88  };
89 
90  // Internal: Types.
91  typedef map<char,BigChar*> CharMap;
92 
93  // Internal: Static Attributes.
94  static FontMap _fontMap;
95  // Internal: Attributes.
96  CharMap _table;
97  string _name;
98  int _height;
99 
100  // Internal: Constructors.
101  BannerFont ( const BannerFont& );
102  ~BannerFont ();
103  inline BannerFont& operator= ( const BannerFont& );
104 
105  };
106 
107 
108 
109 
110 // -------------------------------------------------------------------
111 // Class : "CRL::Banner".
112 
113 
114  class Banner {
115  public:
116  // Constructor & Destructor.
117  Banner ( string name=""
118  , string version=""
119  , string purpose=""
120  , string date=""
121  , string authors=""
122  , string contributors="" );
123  virtual ~Banner ();
124  // Accessors.
125  inline const BannerFont* getFont () const;
126  inline const string& getName () const;
127  inline const string& getVersion () const;
128  inline const string& getPurpose () const;
129  inline const string& getDate () const;
130  inline const string& getAuthors () const;
131  inline const string& getContributors () const;
132  inline unsigned int getScreenWidth () const;
133  // Modifiers.
134  void setFont ( BannerFont* font );
135  void setName ( string name );
136  void setVersion ( string version );
137  void setPurpose ( string purpose );
138  void setDate ( string date );
139  void setAuthors ( string authors );
140  void setContributors ( string contributors );
141  void setScreenWidth ( unsigned screenWidth );
142  // Hurricane Management.
143  virtual const string _getPrint () const { return ( _banner.str() ); };
144 
145  // Internal: Attributes.
146  private:
147  string _name;
148  string _version;
149  string _purpose;
150  string _date;
151  string _authors;
152  string _contributors;
153  unsigned int _screenWidth;
154  size_t _cartoucheWidth;
155  const BannerFont* _font;
156  string* _lines;
157  ostringstream _banner;
158 
159  // Internal: Constructors.
160  Banner ( const Banner & );
161  Banner& operator= ( const Banner & );
162  // Internal: Methods.
163  void _redraw ();
164  };
165 
166 
167 // Inline Functions.
168  inline int BannerFont::BigChar::getHeight () const { return _height; }
169  inline const BannerFont* BannerFont::BigChar::getFont () const { return _font; }
170  inline BannerFont::BannerFont ( const string& name ): _table(), _name(name) {}
171  inline int BannerFont::getHeight () const { return _height; }
172  inline const BannerFont* Banner::getFont () const { return _font; }
173  inline const string& Banner::getName () const { return _name; }
174  inline const string& Banner::getVersion () const { return _version; }
175  inline const string& Banner::getPurpose () const { return _purpose; }
176  inline const string& Banner::getDate () const { return _date; }
177  inline const string& Banner::getAuthors () const { return _authors; }
178  inline const string& Banner::getContributors () const { return _contributors; }
179  inline unsigned int Banner::getScreenWidth () const { return _screenWidth; }
180 
181 
182 } // CRL namespace.
183 
184 
185 // Hurricane Management.
186 
187 inline std::string getPrint ( const CRL::BannerFont::BigChar& c ) { return c._getPrint(); }
188 inline std::string getPrint ( const CRL::Banner& b ) { return b._getPrint(); }
189 inline std::ostream& operator<< ( std::ostream& o, const CRL::BannerFont::BigChar& c ) { return o << getPrint(c); }
190 inline std::ostream& operator<< ( std::ostream& o, const CRL::Banner& b ) { return o << getPrint(b); }
191 
192 MSTREAM_R_SUPPORT(CRL::Banner);
193 
194 
195 #endif // CRL_BANNER_H
unsigned int getScreenWidth() const
Definition: Banner.h:179
void setScreenWidth(unsigned screenWidth)
-
const string & getDate() const
Definition: Banner.h:176
-
const string & getContributors() const
Definition: Banner.h:178
+
const string & getDate() const
Definition: Banner.h:176
void setVersion(string version)
-
const string & getName() const
Definition: Banner.h:173
void setAuthors(string authors)
void setDate(string date)
+
const string & getPurpose() const
Definition: Banner.h:175
Banner(string name="", string version="", string purpose="", string date="", string authors="", string contributors="")
void setContributors(string contributors)
-
const string & getVersion() const
Definition: Banner.h:174
void setName(string name)
-
const string & getAuthors() const
Definition: Banner.h:177
-
unsigned int getScreenWidth() const
Definition: Banner.h:179
+
const string & getVersion() const
Definition: Banner.h:174
+
const string & getContributors() const
Definition: Banner.h:178
+
const string & getAuthors() const
Definition: Banner.h:177
Print Formatted Banners (on ttys).
Definition: Banner.h:114
+
const string & getName() const
Definition: Banner.h:173
+
The namespace of Coriolis Core.
Definition: Environment.h:26
void setPurpose(string purpose)


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/Catalog_8h_source.html b/crlcore/doc/crlcore/html/Catalog_8h_source.html index 6916e19b..222c436a 100644 --- a/crlcore/doc/crlcore/html/Catalog_8h_source.html +++ b/crlcore/doc/crlcore/html/Catalog_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 // -*- C++ -*-
-
2 //
-
3 // This file is part of the Coriolis Software.
-
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
-
5 //
-
6 // +-----------------------------------------------------------------+
-
7 // | C O R I O L I S |
-
8 // | Alliance / Hurricane Interface |
-
9 // | |
-
10 // | Author : Jean-Paul CHAPUT |
-
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
-
12 // | =============================================================== |
-
13 // | C++ Header : "./crlcore/Catalog.h" |
-
14 // +-----------------------------------------------------------------+
-
15 
-
16 
-
17 #ifndef CRL_CATALOG_H
-
18 #define CRL_CATALOG_H
-
19 
-
20 #include <string>
-
21 #include <map>
-
22 #include "hurricane/Name.h"
-
23 #include "hurricane/Property.h"
-
24 #include "hurricane/Slot.h"
-
25 
-
26 namespace Hurricane {
-
27  class Cell;
-
28  class Library;
-
29 }
-
30 
-
31 
-
32 namespace CRL {
-
33 
-
34 
-
35  using std::string;
-
36  using std::map;
- - -
39  using Hurricane::_TName;
-
40  using Hurricane::Name;
-
41  using Hurricane::Record;
- -
43  using Hurricane::DBo;
-
44  using Hurricane::Cell;
-
45  using Hurricane::Library;
-
46  using Hurricane::Property;
-
47 
-
48 
-
49  extern const char* MissingStateProperty;
-
50 
-
51 
-
52 // -------------------------------------------------------------------
-
53 // Class : "CRL::Catalog".
-
54 
-
55 
-
56  class Catalog {
-
57 
-
58  public:
-
59  class State;
-
60  public:
-
61  inline Catalog ();
-
62  ~Catalog ();
-
63  State* getState ( const Name& name, bool add=false );
-
64  void mergeState ( const Name& name, const State& other );
-
65  bool deleteState ( const Name& name );
-
66  void clear ();
-
67  bool loadFromFile ( const string& path, Library* library );
-
68  inline map<Name,State*>* getStates ();
-
69  string _getPrint () const;
-
70  inline string _getTypeName () const;
-
71  string _getString () const;
-
72  Record* _getRecord () const;
-
73 
-
74  public:
-
75  // Sub-Class: State.
-
76  class State {
-
77  public:
-
78  // Flags Constants.
-
79  enum Flags { FlattenLeaf = 1 << 0
-
80  , Feed = 1 << 1
-
81  , Pad = 1 << 2
-
82  , GDS = 1 << 3
-
83  , Delete = 1 << 4
-
84  , Logical = 1 << 5
-
85  , Physical = 1 << 6
-
86  , InMemory = 1 << 7
-
87  , Foreign = 1 << 8
- -
89  };
-
90  // Constructors.
-
91  inline State ();
-
92  ~State ();
-
93  // Predicates.
-
94  inline bool isFlattenLeaf () const;
-
95  inline bool isFeed () const;
-
96  inline bool isPad () const;
-
97  inline bool isGds () const;
-
98  inline bool isDelete () const;
-
99  inline bool isPhysical () const;
-
100  inline bool isLogical () const;
-
101  inline bool isInMemory () const;
-
102  // Flags management.
-
103  inline unsigned int getFlags ( unsigned int mask=(unsigned int)-1 ) const;
-
104  inline bool setFlags ( unsigned int mask, bool value );
-
105  inline bool setFlattenLeaf ( bool value );
-
106  inline bool setFeed ( bool value );
-
107  inline bool setPad ( bool value );
-
108  inline bool setGds ( bool value );
-
109  inline bool setDelete ( bool value );
-
110  inline bool setPhysical ( bool value );
-
111  inline bool setLogical ( bool value );
-
112  inline bool setInMemory ( bool value );
-
113  // Accessors.
-
114  inline Cell* getCell () const;
-
115  inline Library* getLibrary () const;
-
116  inline unsigned int getDepth () const;
-
117  // Modifiers.
-
118  inline void merge ( const State& other );
-
119  Cell* setCell ( Cell* cell );
-
120  inline Library* setLibrary ( Library* library );
-
121  inline void setDepth ( unsigned int depth );
-
122  // Hurricane Management.
-
123  void toJson ( JsonWriter* w ) const;
-
124  inline string _getTypeName () const;
-
125  string _getString () const;
-
126  Record* _getRecord () const;
-
127 
-
128  private:
-
129  // Internal - Attributes.
-
130  unsigned int _flags;
-
131  unsigned int _depth;
-
132  Cell* _cell;
-
133  Library* _library;
-
134 
-
135  // Json Property.
-
136  public:
-
137  class JsonState : public JsonObject {
-
138  public:
-
139  static void initialize ();
-
140  JsonState ( unsigned long flags );
-
141  virtual string getTypeName () const;
-
142  virtual JsonState* clone ( unsigned long ) const;
-
143  virtual void toData ( JsonStack& );
-
144  };
-
145  };
-
146 
-
147  private:
-
148  // Attributes.
-
149  map<Name,State*> _states;
-
150 
-
151  private:
-
152  Catalog ( const Catalog& );
-
153  static bool readLine ( const string& s, string& name, State* state );
-
154 
-
155  };
-
156 
-
157 
-
158 // -------------------------------------------------------------------
-
159 // Class : "CRL::CatalogProperty".
-
160 
-
161  class CatalogProperty : public PrivateProperty {
-
162 
-
163  public:
-
164  static Name _name;
-
165  public:
-
166  static CatalogProperty* create ( Catalog::State* state );
-
167  static Name getPropertyName ();
-
168  virtual Name getName () const;
-
169  inline Catalog::State* getState () const;
-
170  inline void setState ( Catalog::State* state );
-
171  virtual void onReleasedBy ( DBo* owner );
-
172  virtual bool hasJson () const;
-
173  virtual void toJson ( JsonWriter* w, const DBo* ) const;
-
174  virtual string _getTypeName () const;
-
175  virtual string _getString () const;
-
176  virtual Record* _getRecord () const;
-
177 
-
178  protected:
-
179  // Attributes.
-
180  Catalog::State* _state;
-
181 
-
182  protected:
-
183  // Constructor.
-
184  inline CatalogProperty ( Catalog::State* state );
-
185  };
-
186 
-
187 
-
188 // -------------------------------------------------------------------
-
189 // Class : "CRL::JsonCatalogProperty".
-
190 
-
191  class JsonCatalogProperty : public JsonObject {
-
192  public:
-
193  static void initialize ();
-
194  JsonCatalogProperty ( unsigned long );
-
195  virtual string getTypeName () const;
-
196  virtual JsonCatalogProperty* clone ( unsigned long ) const;
-
197  virtual void toData ( JsonStack& );
-
198  };
-
199 
-
200 
-
201 // -------------------------------------------------------------------
-
202 // Inline Functions.
-
203 
-
204  inline Catalog::State::State () : _flags(0), _depth(1), _cell(NULL), _library(NULL) { }
-
205  inline bool Catalog::State::isFlattenLeaf () const { return (_flags&FlattenLeaf)?1:0; }
-
206  inline bool Catalog::State::isFeed () const { return (_flags&Feed )?1:0; }
-
207  inline bool Catalog::State::isPad () const { return (_flags&Pad )?1:0; }
-
208  inline bool Catalog::State::isGds () const { return (_flags&GDS )?1:0; }
-
209  inline bool Catalog::State::isDelete () const { return (_flags&Delete )?1:0; }
-
210  inline bool Catalog::State::isPhysical () const { return (_flags&Physical )?1:0; }
-
211  inline bool Catalog::State::isLogical () const { return (_flags&Logical )?1:0; }
-
212  inline bool Catalog::State::isInMemory () const { return (_flags&InMemory )?1:0; }
-
213  inline unsigned int Catalog::State::getFlags ( unsigned int mask ) const { return ( _flags & mask ); }
-
214  inline bool Catalog::State::setFlags ( unsigned int mask, bool value ) {
-
215  if (value) { _flags |= mask; }
-
216  else { _flags &= ~mask; }
-
217  return ((_flags&mask) ? true : false);
-
218  }
-
219  inline bool Catalog::State::setFlattenLeaf ( bool value ) { return setFlags(FlattenLeaf,value); }
-
220  inline bool Catalog::State::setFeed ( bool value ) { return setFlags(Feed ,value); }
-
221  inline bool Catalog::State::setPad ( bool value ) { return setFlags(Pad ,value); }
-
222  inline bool Catalog::State::setGds ( bool value ) { return setFlags(GDS ,value); }
-
223  inline bool Catalog::State::setDelete ( bool value ) { return setFlags(Delete ,value); }
-
224  inline bool Catalog::State::setPhysical ( bool value ) { return setFlags(Physical ,value); }
-
225  inline bool Catalog::State::setLogical ( bool value ) { return setFlags(Logical ,value); }
-
226  inline bool Catalog::State::setInMemory ( bool value ) { return setFlags(InMemory ,value); }
-
227  inline Library* Catalog::State::setLibrary ( Library* library ) { return _library = library; }
-
228  inline void Catalog::State::setDepth ( unsigned int depth ) { _depth = depth; }
-
229  inline Cell* Catalog::State::getCell () const { return _cell; }
-
230  inline Library* Catalog::State::getLibrary () const { return _library; }
-
231  inline unsigned int Catalog::State::getDepth () const { return _depth; }
-
232  inline string Catalog::State::_getTypeName () const { return _TName("Catalog::State"); }
-
233 
-
234  inline Catalog::Catalog () : _states() {}
-
235  inline map<Name,Catalog::State*>*
-
236  Catalog::getStates () { return &_states; }
-
237  inline string Catalog::_getTypeName () const { return _TName("Catalog"); }
-
238 
-
239  inline CatalogProperty::CatalogProperty ( Catalog::State* state ) : PrivateProperty(), _state(state) {}
-
240  inline Catalog::State* CatalogProperty::getState () const { return _state; }
-
241  inline void CatalogProperty::setState ( Catalog::State* state ) { _state = state; }
-
242 
-
243 
-
244 // -------------------------------------------------------------------
-
245 // Class : "CRL::CatalogExtension".
-
246 
-
247 
- -
249  public:
-
250  static Catalog::State* get ( const Cell* );
-
251  public:
-
252  static inline bool isFlattenLeaf ( const Cell* );
-
253  static inline bool isFeed ( const Cell* );
-
254  static inline bool isPad ( const Cell* );
-
255  static inline bool isGds ( const Cell* );
-
256  static inline bool isDelete ( const Cell* );
-
257  static inline bool isPhysical ( const Cell* );
-
258  static inline bool isLogical ( const Cell* );
-
259  // Flags management.
-
260  static inline unsigned int getFlags ( const Cell*, unsigned int mask=(unsigned int)-1 );
-
261  static inline bool setFlags ( const Cell*, unsigned int mask, bool value );
-
262  static inline bool setFlattenLeaf ( const Cell*, bool value );
-
263  static inline bool setFeed ( const Cell*, bool value );
-
264  static inline bool setPad ( const Cell*, bool value );
-
265  static inline bool setGds ( const Cell*, bool value );
-
266  static inline bool setDelete ( const Cell*, bool value );
-
267  static inline bool setPhysical ( const Cell*, bool value );
-
268  static inline bool setLogical ( const Cell*, bool value );
-
269  // Accessors.
-
270  static inline Library* getLibrary ( const Cell* );
-
271  static inline unsigned int getDepth ( const Cell* );
-
272  // Modifiers.
-
273  static inline Library* setLibrary ( const Cell*, Library* library );
-
274  static inline void setDepth ( const Cell*, unsigned int depth );
-
275  private:
-
276  static const Cell* _owner;
-
277  static Catalog::State* _cache;
-
278  };
-
279 
-
280 
-
281  inline bool CatalogExtension::isFlattenLeaf ( const Cell* cell )
-
282  {
-
283  Catalog::State* state = get(cell);
-
284  return (state == NULL) ? false : state->isFlattenLeaf();
-
285  }
-
286 
-
287 
-
288  inline bool CatalogExtension::isFeed ( const Cell* cell )
-
289  {
-
290  Catalog::State* state = get(cell);
-
291  return (state == NULL) ? false : state->isFeed();
-
292  }
-
293 
-
294 
-
295  inline bool CatalogExtension::isGds ( const Cell* cell )
-
296  {
-
297  Catalog::State* state = get(cell);
-
298  return (state == NULL) ? false : state->isGds();
-
299  }
-
300 
-
301 
-
302  inline bool CatalogExtension::isPad ( const Cell* cell )
-
303  {
-
304  Catalog::State* state = get(cell);
-
305  return (state == NULL) ? false : state->isPad();
-
306  }
-
307 
-
308 
-
309  inline bool CatalogExtension::isDelete ( const Cell* cell )
-
310  {
-
311  Catalog::State* state = get(cell);
-
312  return (state == NULL) ? false : state->isDelete();
-
313  }
-
314 
-
315 
-
316  inline bool CatalogExtension::isPhysical ( const Cell* cell )
-
317  {
-
318  Catalog::State* state = get(cell);
-
319  return (state == NULL) ? false : state->isPhysical();
-
320  }
-
321 
-
322 
-
323  inline bool CatalogExtension::isLogical ( const Cell* cell )
-
324  {
-
325  Catalog::State* state = get(cell);
-
326  return (state == NULL) ? false : state->isLogical();
-
327  }
-
328 
-
329 
-
330  inline unsigned int CatalogExtension::getFlags ( const Cell* cell, unsigned int mask )
-
331  {
-
332  Catalog::State* state = get(cell);
-
333  return (state == NULL) ? 0 : state->getFlags();
-
334  }
-
335 
-
336 
-
337  inline bool CatalogExtension::setFlags ( const Cell* cell, unsigned int mask, bool value )
-
338  {
-
339  Catalog::State* state = get(cell);
-
340  return (state == NULL) ? false : state->setFlags(mask,value);
-
341  }
-
342 
-
343 
-
344  inline bool CatalogExtension::setFlattenLeaf ( const Cell* cell, bool value )
-
345  {
-
346  Catalog::State* state = get(cell);
-
347  return (state == NULL) ? false : state->setFlattenLeaf(value);
-
348  }
-
349 
-
350 
-
351  inline bool CatalogExtension::setFeed ( const Cell* cell, bool value )
-
352  {
-
353  Catalog::State* state = get(cell);
-
354  return (state == NULL) ? false : state->setFeed(value);
-
355  }
-
356 
-
357 
-
358  inline bool CatalogExtension::setPad ( const Cell* cell, bool value )
-
359  {
-
360  Catalog::State* state = get(cell);
-
361  return (state == NULL) ? false : state->setPad(value);
-
362  }
-
363 
-
364 
-
365  inline bool CatalogExtension::setGds ( const Cell* cell, bool value )
-
366  {
-
367  Catalog::State* state = get(cell);
-
368  return (state == NULL) ? false : state->setGds(value);
-
369  }
-
370 
-
371 
-
372  inline bool CatalogExtension::setDelete ( const Cell* cell, bool value )
-
373  {
-
374  Catalog::State* state = get(cell);
-
375  return (state == NULL) ? false : state->setDelete(value);
-
376  }
-
377 
-
378 
-
379  inline bool CatalogExtension::setPhysical ( const Cell* cell, bool value )
-
380  {
-
381  Catalog::State* state = get(cell);
-
382  return (state == NULL) ? false : state->setPhysical(value);
-
383  }
-
384 
-
385 
-
386  inline bool CatalogExtension::setLogical ( const Cell* cell, bool value )
-
387  {
-
388  Catalog::State* state = get(cell);
-
389  return (state == NULL) ? false : state->setLogical(value);
-
390  }
-
391 
-
392 
-
393  inline Library* CatalogExtension::getLibrary ( const Cell* cell )
-
394  {
-
395  Catalog::State* state = get(cell);
-
396  return (state == NULL) ? NULL : state->getLibrary();
-
397  }
-
398 
-
399 
-
400  inline unsigned int CatalogExtension::getDepth ( const Cell* cell )
-
401  {
-
402  Catalog::State* state = get(cell);
-
403  return (state == NULL) ? 0 : state->getDepth();
-
404  }
-
405 
-
406 
-
407  inline Library* CatalogExtension::setLibrary ( const Cell* cell, Library* library )
-
408  {
-
409  Catalog::State* state = get(cell);
-
410  return (state == NULL) ? NULL : state->setLibrary(library);
-
411  }
-
412 
-
413 
-
414  inline void CatalogExtension::setDepth ( const Cell* cell, unsigned int depth )
-
415  {
-
416  Catalog::State* state = get(cell);
-
417  if ( state == NULL ) state->setDepth(depth);
-
418  }
-
419 
-
420 
-
421 } // End of CRL namespace.
-
422 
-
423 
-
424 
-
425 
-
426 // x-----------------------------------------------------------------x
-
427 // | Functions Overload for Hurricane Management |
-
428 // x-----------------------------------------------------------------x
-
429 
-
430 
-
431 inline std::string getPrint ( const CRL::Catalog &CATAL ) { return CATAL._getPrint(); }
-
432 
-
433 INSPECTOR_P_SUPPORT(CRL::Catalog);
-
434 INSPECTOR_P_SUPPORT(CRL::Catalog::State);
-
435 
-
436 
-
437 #endif // CRL_CATALOG_H
+
1 // -*- C++ -*-
2 //
3 // This file is part of the Coriolis Software.
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
5 //
6 // +-----------------------------------------------------------------+
7 // | C O R I O L I S |
8 // | Alliance / Hurricane Interface |
9 // | |
10 // | Author : Jean-Paul CHAPUT |
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
12 // | =============================================================== |
13 // | C++ Header : "./crlcore/Catalog.h" |
14 // +-----------------------------------------------------------------+
15 
16 
17 #ifndef CRL_CATALOG_H
18 #define CRL_CATALOG_H
19 
20 #include <string>
21 #include <map>
22 #include "hurricane/Name.h"
23 #include "hurricane/Property.h"
24 #include "hurricane/Slot.h"
25 
26 namespace Hurricane {
27  class Cell;
28  class Library;
29 }
30 
31 
32 namespace CRL {
33 
34 
35  using std::string;
36  using std::map;
39  using Hurricane::_TName;
40  using Hurricane::Name;
41  using Hurricane::Record;
43  using Hurricane::DBo;
44  using Hurricane::Cell;
45  using Hurricane::Library;
46  using Hurricane::Property;
47 
48 
49  extern const char* MissingStateProperty;
50 
51 
52 // -------------------------------------------------------------------
53 // Class : "CRL::Catalog".
54 
55 
56  class Catalog {
57 
58  public:
59  class State;
60  public:
61  inline Catalog ();
62  ~Catalog ();
63  State* getState ( const Name& name, bool add=false );
64  void mergeState ( const Name& name, const State& other );
65  bool deleteState ( const Name& name );
66  void clear ();
67  bool loadFromFile ( const string& path, Library* library );
68  inline map<Name,State*>* getStates ();
69  string _getPrint () const;
70  inline string _getTypeName () const;
71  string _getString () const;
72  Record* _getRecord () const;
73 
74  public:
75  // Sub-Class: State.
76  class State {
77  public:
78  // Flags Constants.
79  enum Flags { FlattenLeaf = 1 << 0
80  , Feed = 1 << 1
81  , Pad = 1 << 2
82  , GDS = 1 << 3
83  , Delete = 1 << 4
84  , Logical = 1 << 5
85  , Physical = 1 << 6
86  , InMemory = 1 << 7
87  , Foreign = 1 << 8
89  };
90  // Constructors.
91  inline State ();
92  ~State ();
93  // Predicates.
94  inline bool isFlattenLeaf () const;
95  inline bool isFeed () const;
96  inline bool isPad () const;
97  inline bool isGds () const;
98  inline bool isDelete () const;
99  inline bool isPhysical () const;
100  inline bool isLogical () const;
101  inline bool isInMemory () const;
102  // Flags management.
103  inline unsigned int getFlags ( unsigned int mask=(unsigned int)-1 ) const;
104  inline bool setFlags ( unsigned int mask, bool value );
105  inline bool setFlattenLeaf ( bool value );
106  inline bool setFeed ( bool value );
107  inline bool setPad ( bool value );
108  inline bool setGds ( bool value );
109  inline bool setDelete ( bool value );
110  inline bool setPhysical ( bool value );
111  inline bool setLogical ( bool value );
112  inline bool setInMemory ( bool value );
113  // Accessors.
114  inline Cell* getCell () const;
115  inline Library* getLibrary () const;
116  inline unsigned int getDepth () const;
117  // Modifiers.
118  inline void merge ( const State& other );
119  Cell* setCell ( Cell* cell );
120  inline Library* setLibrary ( Library* library );
121  inline void setDepth ( unsigned int depth );
122  // Hurricane Management.
123  void toJson ( JsonWriter* w ) const;
124  inline string _getTypeName () const;
125  string _getString () const;
126  Record* _getRecord () const;
127 
128  private:
129  // Internal - Attributes.
130  unsigned int _flags;
131  unsigned int _depth;
132  Cell* _cell;
133  Library* _library;
134 
135  // Json Property.
136  public:
137  class JsonState : public JsonObject {
138  public:
139  static void initialize ();
140  JsonState ( unsigned long flags );
141  virtual string getTypeName () const;
142  virtual JsonState* clone ( unsigned long ) const;
143  virtual void toData ( JsonStack& );
144  };
145  };
146 
147  private:
148  // Attributes.
149  map<Name,State*> _states;
150 
151  private:
152  Catalog ( const Catalog& );
153  static bool readLine ( const string& s, string& name, State* state );
154 
155  };
156 
157 
158 // -------------------------------------------------------------------
159 // Class : "CRL::CatalogProperty".
160 
161  class CatalogProperty : public PrivateProperty {
162 
163  public:
164  static Name _name;
165  public:
166  static CatalogProperty* create ( Catalog::State* state );
167  static Name getPropertyName ();
168  virtual Name getName () const;
169  inline Catalog::State* getState () const;
170  inline void setState ( Catalog::State* state );
171  virtual void onReleasedBy ( DBo* owner );
172  virtual bool hasJson () const;
173  virtual void toJson ( JsonWriter* w, const DBo* ) const;
174  virtual string _getTypeName () const;
175  virtual string _getString () const;
176  virtual Record* _getRecord () const;
177 
178  protected:
179  // Attributes.
180  Catalog::State* _state;
181 
182  protected:
183  // Constructor.
184  inline CatalogProperty ( Catalog::State* state );
185  };
186 
187 
188 // -------------------------------------------------------------------
189 // Class : "CRL::JsonCatalogProperty".
190 
191  class JsonCatalogProperty : public JsonObject {
192  public:
193  static void initialize ();
194  JsonCatalogProperty ( unsigned long );
195  virtual string getTypeName () const;
196  virtual JsonCatalogProperty* clone ( unsigned long ) const;
197  virtual void toData ( JsonStack& );
198  };
199 
200 
201 // -------------------------------------------------------------------
202 // Inline Functions.
203 
204  inline Catalog::State::State () : _flags(0), _depth(1), _cell(NULL), _library(NULL) { }
205  inline bool Catalog::State::isFlattenLeaf () const { return (_flags&FlattenLeaf)?1:0; }
206  inline bool Catalog::State::isFeed () const { return (_flags&Feed )?1:0; }
207  inline bool Catalog::State::isPad () const { return (_flags&Pad )?1:0; }
208  inline bool Catalog::State::isGds () const { return (_flags&GDS )?1:0; }
209  inline bool Catalog::State::isDelete () const { return (_flags&Delete )?1:0; }
210  inline bool Catalog::State::isPhysical () const { return (_flags&Physical )?1:0; }
211  inline bool Catalog::State::isLogical () const { return (_flags&Logical )?1:0; }
212  inline bool Catalog::State::isInMemory () const { return (_flags&InMemory )?1:0; }
213  inline unsigned int Catalog::State::getFlags ( unsigned int mask ) const { return ( _flags & mask ); }
214  inline bool Catalog::State::setFlags ( unsigned int mask, bool value ) {
215  if (value) { _flags |= mask; }
216  else { _flags &= ~mask; }
217  return ((_flags&mask) ? true : false);
218  }
219  inline bool Catalog::State::setFlattenLeaf ( bool value ) { return setFlags(FlattenLeaf,value); }
220  inline bool Catalog::State::setFeed ( bool value ) { return setFlags(Feed ,value); }
221  inline bool Catalog::State::setPad ( bool value ) { return setFlags(Pad ,value); }
222  inline bool Catalog::State::setGds ( bool value ) { return setFlags(GDS ,value); }
223  inline bool Catalog::State::setDelete ( bool value ) { return setFlags(Delete ,value); }
224  inline bool Catalog::State::setPhysical ( bool value ) { return setFlags(Physical ,value); }
225  inline bool Catalog::State::setLogical ( bool value ) { return setFlags(Logical ,value); }
226  inline bool Catalog::State::setInMemory ( bool value ) { return setFlags(InMemory ,value); }
227  inline Library* Catalog::State::setLibrary ( Library* library ) { return _library = library; }
228  inline void Catalog::State::setDepth ( unsigned int depth ) { _depth = depth; }
229  inline Cell* Catalog::State::getCell () const { return _cell; }
230  inline Library* Catalog::State::getLibrary () const { return _library; }
231  inline unsigned int Catalog::State::getDepth () const { return _depth; }
232  inline string Catalog::State::_getTypeName () const { return _TName("Catalog::State"); }
233 
234  inline Catalog::Catalog () : _states() {}
235  inline map<Name,Catalog::State*>*
236  Catalog::getStates () { return &_states; }
237  inline string Catalog::_getTypeName () const { return _TName("Catalog"); }
238 
239  inline CatalogProperty::CatalogProperty ( Catalog::State* state ) : PrivateProperty(), _state(state) {}
240  inline Catalog::State* CatalogProperty::getState () const { return _state; }
241  inline void CatalogProperty::setState ( Catalog::State* state ) { _state = state; }
242 
243 
244 // -------------------------------------------------------------------
245 // Class : "CRL::CatalogExtension".
246 
247 
249  public:
250  static Catalog::State* get ( const Cell* );
251  public:
252  static inline bool isFlattenLeaf ( const Cell* );
253  static inline bool isFeed ( const Cell* );
254  static inline bool isPad ( const Cell* );
255  static inline bool isGds ( const Cell* );
256  static inline bool isDelete ( const Cell* );
257  static inline bool isPhysical ( const Cell* );
258  static inline bool isLogical ( const Cell* );
259  // Flags management.
260  static inline unsigned int getFlags ( const Cell*, unsigned int mask=(unsigned int)-1 );
261  static inline bool setFlags ( const Cell*, unsigned int mask, bool value );
262  static inline bool setFlattenLeaf ( const Cell*, bool value );
263  static inline bool setFeed ( const Cell*, bool value );
264  static inline bool setPad ( const Cell*, bool value );
265  static inline bool setGds ( const Cell*, bool value );
266  static inline bool setDelete ( const Cell*, bool value );
267  static inline bool setPhysical ( const Cell*, bool value );
268  static inline bool setLogical ( const Cell*, bool value );
269  // Accessors.
270  static inline Library* getLibrary ( const Cell* );
271  static inline unsigned int getDepth ( const Cell* );
272  // Modifiers.
273  static inline Library* setLibrary ( const Cell*, Library* library );
274  static inline void setDepth ( const Cell*, unsigned int depth );
275  private:
276  static const Cell* _owner;
277  static Catalog::State* _cache;
278  };
279 
280 
281  inline bool CatalogExtension::isFlattenLeaf ( const Cell* cell )
282  {
283  Catalog::State* state = get(cell);
284  return (state == NULL) ? false : state->isFlattenLeaf();
285  }
286 
287 
288  inline bool CatalogExtension::isFeed ( const Cell* cell )
289  {
290  Catalog::State* state = get(cell);
291  return (state == NULL) ? false : state->isFeed();
292  }
293 
294 
295  inline bool CatalogExtension::isGds ( const Cell* cell )
296  {
297  Catalog::State* state = get(cell);
298  return (state == NULL) ? false : state->isGds();
299  }
300 
301 
302  inline bool CatalogExtension::isPad ( const Cell* cell )
303  {
304  Catalog::State* state = get(cell);
305  return (state == NULL) ? false : state->isPad();
306  }
307 
308 
309  inline bool CatalogExtension::isDelete ( const Cell* cell )
310  {
311  Catalog::State* state = get(cell);
312  return (state == NULL) ? false : state->isDelete();
313  }
314 
315 
316  inline bool CatalogExtension::isPhysical ( const Cell* cell )
317  {
318  Catalog::State* state = get(cell);
319  return (state == NULL) ? false : state->isPhysical();
320  }
321 
322 
323  inline bool CatalogExtension::isLogical ( const Cell* cell )
324  {
325  Catalog::State* state = get(cell);
326  return (state == NULL) ? false : state->isLogical();
327  }
328 
329 
330  inline unsigned int CatalogExtension::getFlags ( const Cell* cell, unsigned int mask )
331  {
332  Catalog::State* state = get(cell);
333  return (state == NULL) ? 0 : state->getFlags();
334  }
335 
336 
337  inline bool CatalogExtension::setFlags ( const Cell* cell, unsigned int mask, bool value )
338  {
339  Catalog::State* state = get(cell);
340  return (state == NULL) ? false : state->setFlags(mask,value);
341  }
342 
343 
344  inline bool CatalogExtension::setFlattenLeaf ( const Cell* cell, bool value )
345  {
346  Catalog::State* state = get(cell);
347  return (state == NULL) ? false : state->setFlattenLeaf(value);
348  }
349 
350 
351  inline bool CatalogExtension::setFeed ( const Cell* cell, bool value )
352  {
353  Catalog::State* state = get(cell);
354  return (state == NULL) ? false : state->setFeed(value);
355  }
356 
357 
358  inline bool CatalogExtension::setPad ( const Cell* cell, bool value )
359  {
360  Catalog::State* state = get(cell);
361  return (state == NULL) ? false : state->setPad(value);
362  }
363 
364 
365  inline bool CatalogExtension::setGds ( const Cell* cell, bool value )
366  {
367  Catalog::State* state = get(cell);
368  return (state == NULL) ? false : state->setGds(value);
369  }
370 
371 
372  inline bool CatalogExtension::setDelete ( const Cell* cell, bool value )
373  {
374  Catalog::State* state = get(cell);
375  return (state == NULL) ? false : state->setDelete(value);
376  }
377 
378 
379  inline bool CatalogExtension::setPhysical ( const Cell* cell, bool value )
380  {
381  Catalog::State* state = get(cell);
382  return (state == NULL) ? false : state->setPhysical(value);
383  }
384 
385 
386  inline bool CatalogExtension::setLogical ( const Cell* cell, bool value )
387  {
388  Catalog::State* state = get(cell);
389  return (state == NULL) ? false : state->setLogical(value);
390  }
391 
392 
393  inline Library* CatalogExtension::getLibrary ( const Cell* cell )
394  {
395  Catalog::State* state = get(cell);
396  return (state == NULL) ? NULL : state->getLibrary();
397  }
398 
399 
400  inline unsigned int CatalogExtension::getDepth ( const Cell* cell )
401  {
402  Catalog::State* state = get(cell);
403  return (state == NULL) ? 0 : state->getDepth();
404  }
405 
406 
407  inline Library* CatalogExtension::setLibrary ( const Cell* cell, Library* library )
408  {
409  Catalog::State* state = get(cell);
410  return (state == NULL) ? NULL : state->setLibrary(library);
411  }
412 
413 
414  inline void CatalogExtension::setDepth ( const Cell* cell, unsigned int depth )
415  {
416  Catalog::State* state = get(cell);
417  if ( state == NULL ) state->setDepth(depth);
418  }
419 
420 
421 } // End of CRL namespace.
422 
423 
424 
425 
426 // x-----------------------------------------------------------------x
427 // | Functions Overload for Hurricane Management |
428 // x-----------------------------------------------------------------x
429 
430 
431 inline std::string getPrint ( const CRL::Catalog &CATAL ) { return CATAL._getPrint(); }
432 
433 INSPECTOR_P_SUPPORT(CRL::Catalog);
434 INSPECTOR_P_SUPPORT(CRL::Catalog::State);
435 
436 
437 #endif // CRL_CATALOG_H
unsigned int getFlags(unsigned int mask=(unsigned int) -1) const
Definition: Catalog.h:213
static bool setPad(const Cell *, bool value)
Definition: Catalog.h:358
@@ -496,26 +55,23 @@
bool setPad(bool value)
Definition: Catalog.h:221
-
Cell * getCell() const
Definition: Catalog.h:229
static bool isGds(const Cell *)
Definition: Catalog.h:295
bool setGds(bool value)
Definition: Catalog.h:222
Cell * setCell(Cell *cell)
Catalog()
Definition: Catalog.h:234
-
bool isFlattenLeaf() const
Definition: Catalog.h:205
static bool isDelete(const Cell *)
Definition: Catalog.h:309
-
bool isFeed() const
Definition: Catalog.h:206
static bool isLogical(const Cell *)
Definition: Catalog.h:323
static bool setFeed(const Cell *, bool value)
Definition: Catalog.h:351
static bool setFlattenLeaf(const Cell *, bool value)
Definition: Catalog.h:344
+
bool isLogical() const
Definition: Catalog.h:211
void merge(const State &other)
-
bool isPad() const
Definition: Catalog.h:207
-
unsigned int getDepth() const
Definition: Catalog.h:231
-
bool isDelete() const
Definition: Catalog.h:209
-
bool isLogical() const
Definition: Catalog.h:211
+
bool isPhysical() const
Definition: Catalog.h:210
+
bool isDelete() const
Definition: Catalog.h:209
+
static unsigned int getFlags(const Cell *, unsigned int mask=(unsigned int) -1)
Definition: Catalog.h:330
Library * setLibrary(Library *library)
Definition: Catalog.h:227
Definition: Catalog.h:85
Definition: Catalog.h:88
@@ -526,44 +82,48 @@
void mergeState(const Name &name, const State &other)
bool setFeed(bool value)
Definition: Catalog.h:220
+
Library * getLibrary() const
Definition: Catalog.h:230
Definition: Catalog.h:80
+
Cell * getCell() const
Definition: Catalog.h:229
bool setFlags(unsigned int mask, bool value)
Definition: Catalog.h:214
map< Name, State * > * getStates()
Definition: Catalog.h:236
static bool isFeed(const Cell *)
Definition: Catalog.h:288
Definition: Catalog.h:81
-
bool isGds() const
Definition: Catalog.h:208
static Library * getLibrary(const Cell *)
Definition: Catalog.h:393
-
static unsigned int getFlags(const Cell *, unsigned int mask=(unsigned int)-1)
Definition: Catalog.h:330
State * getState(const Name &name, bool add=false)
State()
Definition: Catalog.h:204
-
Library * getLibrary() const
Definition: Catalog.h:230
bool setFlattenLeaf(bool value)
Definition: Catalog.h:219
static bool isPad(const Cell *)
Definition: Catalog.h:302
bool loadFromFile(const string &path, Library *library)
+
bool isFeed() const
Definition: Catalog.h:206
bool setDelete(bool value)
Definition: Catalog.h:223
static Library * setLibrary(const Cell *, Library *library)
Definition: Catalog.h:407
static bool setPhysical(const Cell *, bool value)
Definition: Catalog.h:379
+
Definition: Catalog.h:84
-
unsigned int getFlags(unsigned int mask=(unsigned int)-1) const
Definition: Catalog.h:213
+
bool isPad() const
Definition: Catalog.h:207
+
bool isFlattenLeaf() const
Definition: Catalog.h:205
A Registry to store Alliance Cell metadatas.
Definition: Catalog.h:56
-
bool isPhysical() const
Definition: Catalog.h:210
Definition: Catalog.h:82
static bool setDelete(const Cell *, bool value)
Definition: Catalog.h:372
Wrapper to access a Hurricane::Cell Catalog::State.
Definition: Catalog.h:248
bool setPhysical(bool value)
Definition: Catalog.h:224
+
bool isGds() const
Definition: Catalog.h:208
static bool isPhysical(const Cell *)
Definition: Catalog.h:316
static unsigned int getDepth(const Cell *)
Definition: Catalog.h:400
Flags
Definition: Catalog.h:79
static bool isFlattenLeaf(const Cell *)
Definition: Catalog.h:281
+
The namespace of Coriolis Core.
Definition: Environment.h:26
+
unsigned int getDepth() const
Definition: Catalog.h:231
static bool setFlags(const Cell *, unsigned int mask, bool value)
Definition: Catalog.h:337


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/Environment_8h_source.html b/crlcore/doc/crlcore/html/Environment_8h_source.html index 369d8ad6..aae11660 100644 --- a/crlcore/doc/crlcore/html/Environment_8h_source.html +++ b/crlcore/doc/crlcore/html/Environment_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 // -*- C++ -*-
-
2 //
-
3 // This file is part of the Coriolis Software.
-
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
-
5 //
-
6 // +-----------------------------------------------------------------+
-
7 // | C O R I O L I S |
-
8 // | Alliance / Hurricane Interface |
-
9 // | |
-
10 // | Author : Jean-Paul CHAPUT |
-
11 // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
-
12 // | =============================================================== |
-
13 // | C++ Header : "./crlcore/Environment.h" |
-
14 // +-----------------------------------------------------------------+
-
15 
-
16 
-
17 #ifndef CRL_ENVIRONMENT_H
-
18 #define CRL_ENVIRONMENT_H
-
19 
-
20 #include <regex.h>
-
21 #include <string>
-
22 #include "hurricane/Commons.h"
-
23 #include "crlcore/SearchPath.h"
-
24 
-
25 
-
26 namespace CRL {
-
27 
- - -
30 
-
31 
-
32 // -------------------------------------------------------------------
-
33 // Class : "Environment".
-
34 
-
35  class Environment {
-
36  public:
-
37  enum AddMode { Append=1, Prepend=2, Replace=3 };
-
38  public:
-
39  // Internal: Static Methods.
-
40  static const char* getEnv ( const char* variable, const char* defaultValue );
-
41  // Constructors & destructors.
-
42  Environment ();
-
43  ~Environment ();
-
44  // Accessors.
-
45  inline const std::string& getCORIOLIS_TOP () const;
-
46  inline const std::string& getDisplayStyle () const;
-
47  inline long getSCALE_X () const;
-
48  inline const std::string& getDISPLAY () const;
-
49  inline const std::string& getIN_LO () const;
-
50  inline const std::string& getIN_PH () const;
-
51  inline const std::string& getOUT_LO () const;
-
52  inline const std::string& getOUT_PH () const;
-
53  inline const std::string& getPOWER () const;
-
54  inline const std::string& getGROUND () const;
-
55  inline const std::string& getCLOCK () const;
-
56  inline const std::string& getBLOCKAGE () const;
-
57  inline const std::string& getPad () const;
-
58  inline const std::string& getCATALOG () const;
-
59  inline SearchPath& getLIBRARIES ();
-
60  std::string getLIBRARYPath ( size_t i );
-
61  // Predicates.
-
62  bool isPOWER ( const char* name ) const;
-
63  bool isGROUND ( const char* name ) const;
-
64  bool isCLOCK ( const char* name ) const;
-
65  bool isBLOCKAGE ( const char* name ) const;
-
66  bool isPad ( const char* name ) const;
-
67  // Modifiers.
-
68  void validate () const;
-
69  inline void setDisplayStyle ( const char* );
-
70  inline void setSCALE_X ( long value );
-
71  inline void setDISPLAY ( const char* value );
-
72  inline void setIN_LO ( const char* value );
-
73  inline void setIN_PH ( const char* value );
-
74  inline void setOUT_LO ( const char* value );
-
75  inline void setOUT_PH ( const char* value );
-
76  void setPOWER ( const char* value );
-
77  void setGROUND ( const char* value );
-
78  void setCLOCK ( const char* value );
-
79  void setBLOCKAGE ( const char* value );
-
80  void setPad ( const char* value );
-
81  inline void setCATALOG ( const char* value );
-
82  inline void setWORKING_LIBRARY ( const char* value );
-
83  void addSYSTEM_LIBRARY ( const char* value, const char* libName, unsigned int mode=Append );
-
84  // Methods.
-
85  std::string getPrint () const;
-
86  void toJson ( JsonWriter* ) const;
-
87  inline std::string _getTypeName () const;
-
88  std::string _getString () const;
-
89  Record* _getRecord () const;
-
90  protected:
-
91  // Internal: Attributes.
-
92  std::string _CORIOLIS_TOP;
-
93  std::string _displayStyle;
-
94  long _SCALE_X;
-
95  std::string _DISPLAY;
-
96  std::string _IN_LO;
-
97  std::string _IN_PH;
-
98  std::string _OUT_LO;
-
99  std::string _OUT_PH;
-
100  std::string _POWER;
-
101  std::string _GROUND;
-
102  std::string _CLOCK;
-
103  std::string _BLOCKAGE;
-
104  std::string _pad;
-
105  std::string _CATALOG;
-
106  SearchPath _LIBRARIES;
-
107  regex_t _PowerRegex;
-
108  regex_t _GroundRegex;
-
109  regex_t _ClockRegex;
-
110  regex_t _BlockageRegex;
-
111  regex_t _padRegex;
-
112  bool _inConstructor;
-
113  private:
-
114  void _setRegex ( regex_t* regex, const std::string& pattern, const char* name );
-
115  };
-
116 
-
117 
-
118  // Inline Member Functions.
-
119  inline const std::string& Environment::getCORIOLIS_TOP () const { return _CORIOLIS_TOP; }
-
120  inline const std::string& Environment::getDisplayStyle () const { return _displayStyle; }
-
121  inline long Environment::getSCALE_X () const { return _SCALE_X; }
-
122  inline const std::string& Environment::getIN_LO () const { return _IN_LO; }
-
123  inline const std::string& Environment::getIN_PH () const { return _IN_PH; }
-
124  inline const std::string& Environment::getOUT_LO () const { return _OUT_LO; }
-
125  inline const std::string& Environment::getOUT_PH () const { return _OUT_PH; }
-
126  inline const std::string& Environment::getPOWER () const { return _POWER; }
-
127  inline const std::string& Environment::getGROUND () const { return _GROUND; }
-
128  inline const std::string& Environment::getCLOCK () const { return _CLOCK; }
-
129  inline const std::string& Environment::getBLOCKAGE () const { return _BLOCKAGE; }
-
130  inline const std::string& Environment::getPad () const { return _pad; }
-
131  inline const std::string& Environment::getCATALOG () const { return _CATALOG; }
-
132  inline SearchPath& Environment::getLIBRARIES () { return _LIBRARIES; }
-
133 
-
134  inline void Environment::setDisplayStyle ( const char* value ) { _displayStyle = value; }
-
135  inline void Environment::setSCALE_X ( long value ) { _SCALE_X = value; }
-
136  inline void Environment::setIN_LO ( const char* value ) { _IN_LO = value; }
-
137  inline void Environment::setIN_PH ( const char* value ) { _IN_PH = value; }
-
138  inline void Environment::setOUT_LO ( const char* value ) { _OUT_LO = value; }
-
139  inline void Environment::setOUT_PH ( const char* value ) { _OUT_PH = value; }
-
140  inline void Environment::setCATALOG ( const char* value ) { _CATALOG = value; }
-
141  inline void Environment::setWORKING_LIBRARY ( const char* value ) { _LIBRARIES.replace(value,"working",0); }
-
142  inline std::string Environment::_getTypeName () const { return "Environment"; }
-
143 
-
144 
-
145 // -------------------------------------------------------------------
-
146 // Class : "JsonEnvironment".
-
147 
-
148  class JsonEnvironment : public JsonObject {
-
149  public:
-
150  static void initialize ();
-
151  JsonEnvironment ( unsigned long flags );
-
152  virtual std::string getTypeName () const;
-
153  virtual JsonEnvironment* clone ( unsigned long flags ) const;
-
154  virtual void toData ( JsonStack& );
-
155  };
-
156 
-
157 
-
158 } // CRL namespace.
-
159 
-
160 
-
161 INSPECTOR_P_SUPPORT(CRL::Environment);
-
162 
-
163 
-
164 #endif // CRL_ENVIRONMENT_H
-
void setCATALOG(const char *value)
Definition: Environment.h:140
+
1 // -*- C++ -*-
2 //
3 // This file is part of the Coriolis Software.
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
5 //
6 // +-----------------------------------------------------------------+
7 // | C O R I O L I S |
8 // | Alliance / Hurricane Interface |
9 // | |
10 // | Author : Jean-Paul CHAPUT |
11 // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
12 // | =============================================================== |
13 // | C++ Header : "./crlcore/Environment.h" |
14 // +-----------------------------------------------------------------+
15 
16 
17 #ifndef CRL_ENVIRONMENT_H
18 #define CRL_ENVIRONMENT_H
19 
20 #include <regex.h>
21 #include <string>
22 #include "hurricane/Commons.h"
23 #include "crlcore/SearchPath.h"
24 
25 
26 namespace CRL {
27 
30 
31 
32 // -------------------------------------------------------------------
33 // Class : "Environment".
34 
35  class Environment {
36  public:
37  enum AddMode { Append=1, Prepend=2, Replace=3 };
38  public:
39  // Internal: Static Methods.
40  static const char* getEnv ( const char* variable, const char* defaultValue );
41  // Constructors & destructors.
42  Environment ();
43  ~Environment ();
44  // Accessors.
45  inline const std::string& getCORIOLIS_TOP () const;
46  inline const std::string& getDisplayStyle () const;
47  inline long getSCALE_X () const;
48  inline const std::string& getDISPLAY () const;
49  inline const std::string& getIN_LO () const;
50  inline const std::string& getIN_PH () const;
51  inline const std::string& getOUT_LO () const;
52  inline const std::string& getOUT_PH () const;
53  inline const std::string& getPOWER () const;
54  inline const std::string& getGROUND () const;
55  inline const std::string& getCLOCK () const;
56  inline const std::string& getBLOCKAGE () const;
57  inline const std::string& getPad () const;
58  inline const std::string& getCATALOG () const;
59  inline SearchPath& getLIBRARIES ();
60  std::string getLIBRARYPath ( size_t i );
61  // Predicates.
62  bool isPOWER ( const char* name ) const;
63  bool isGROUND ( const char* name ) const;
64  bool isCLOCK ( const char* name ) const;
65  bool isBLOCKAGE ( const char* name ) const;
66  bool isPad ( const char* name ) const;
67  // Modifiers.
68  void validate () const;
69  inline void setDisplayStyle ( const char* );
70  inline void setSCALE_X ( long value );
71  inline void setDISPLAY ( const char* value );
72  inline void setIN_LO ( const char* value );
73  inline void setIN_PH ( const char* value );
74  inline void setOUT_LO ( const char* value );
75  inline void setOUT_PH ( const char* value );
76  void setPOWER ( const char* value );
77  void setGROUND ( const char* value );
78  void setCLOCK ( const char* value );
79  void setBLOCKAGE ( const char* value );
80  void setPad ( const char* value );
81  inline void setCATALOG ( const char* value );
82  inline void setWORKING_LIBRARY ( const char* value );
83  void addSYSTEM_LIBRARY ( const char* value, const char* libName, unsigned int mode=Append );
84  // Methods.
85  std::string getPrint () const;
86  void toJson ( JsonWriter* ) const;
87  inline std::string _getTypeName () const;
88  std::string _getString () const;
89  Record* _getRecord () const;
90  protected:
91  // Internal: Attributes.
92  std::string _CORIOLIS_TOP;
93  std::string _displayStyle;
94  long _SCALE_X;
95  std::string _DISPLAY;
96  std::string _IN_LO;
97  std::string _IN_PH;
98  std::string _OUT_LO;
99  std::string _OUT_PH;
100  std::string _POWER;
101  std::string _GROUND;
102  std::string _CLOCK;
103  std::string _BLOCKAGE;
104  std::string _pad;
105  std::string _CATALOG;
106  SearchPath _LIBRARIES;
107  regex_t _PowerRegex;
108  regex_t _GroundRegex;
109  regex_t _ClockRegex;
110  regex_t _BlockageRegex;
111  regex_t _padRegex;
112  bool _inConstructor;
113  private:
114  void _setRegex ( regex_t* regex, const std::string& pattern, const char* name );
115  };
116 
117 
118  // Inline Member Functions.
119  inline const std::string& Environment::getCORIOLIS_TOP () const { return _CORIOLIS_TOP; }
120  inline const std::string& Environment::getDisplayStyle () const { return _displayStyle; }
121  inline long Environment::getSCALE_X () const { return _SCALE_X; }
122  inline const std::string& Environment::getIN_LO () const { return _IN_LO; }
123  inline const std::string& Environment::getIN_PH () const { return _IN_PH; }
124  inline const std::string& Environment::getOUT_LO () const { return _OUT_LO; }
125  inline const std::string& Environment::getOUT_PH () const { return _OUT_PH; }
126  inline const std::string& Environment::getPOWER () const { return _POWER; }
127  inline const std::string& Environment::getGROUND () const { return _GROUND; }
128  inline const std::string& Environment::getCLOCK () const { return _CLOCK; }
129  inline const std::string& Environment::getBLOCKAGE () const { return _BLOCKAGE; }
130  inline const std::string& Environment::getPad () const { return _pad; }
131  inline const std::string& Environment::getCATALOG () const { return _CATALOG; }
132  inline SearchPath& Environment::getLIBRARIES () { return _LIBRARIES; }
133 
134  inline void Environment::setDisplayStyle ( const char* value ) { _displayStyle = value; }
135  inline void Environment::setSCALE_X ( long value ) { _SCALE_X = value; }
136  inline void Environment::setIN_LO ( const char* value ) { _IN_LO = value; }
137  inline void Environment::setIN_PH ( const char* value ) { _IN_PH = value; }
138  inline void Environment::setOUT_LO ( const char* value ) { _OUT_LO = value; }
139  inline void Environment::setOUT_PH ( const char* value ) { _OUT_PH = value; }
140  inline void Environment::setCATALOG ( const char* value ) { _CATALOG = value; }
141  inline void Environment::setWORKING_LIBRARY ( const char* value ) { _LIBRARIES.replace(value,"working",0); }
142  inline std::string Environment::_getTypeName () const { return "Environment"; }
143 
144 
145 // -------------------------------------------------------------------
146 // Class : "JsonEnvironment".
147 
148  class JsonEnvironment : public JsonObject {
149  public:
150  static void initialize ();
151  JsonEnvironment ( unsigned long flags );
152  virtual std::string getTypeName () const;
153  virtual JsonEnvironment* clone ( unsigned long flags ) const;
154  virtual void toData ( JsonStack& );
155  };
156 
157 
158 } // CRL namespace.
159 
160 
161 INSPECTOR_P_SUPPORT(CRL::Environment);
162 
163 
164 #endif // CRL_ENVIRONMENT_H
void setCATALOG(const char *value)
Definition: Environment.h:140
+
bool isBLOCKAGE(const char *name) const
Definition: Environment.h:37
void setSCALE_X(long value)
Definition: Environment.h:135
-
long getSCALE_X() const
Definition: Environment.h:121
void setBLOCKAGE(const char *value)
-
bool isPOWER(const char *name) const
-
const std::string & getCLOCK() const
Definition: Environment.h:128
+
bool isCLOCK(const char *name) const
+
bool isPOWER(const char *name) const
+
const std::string & getCATALOG() const
Definition: Environment.h:131
SearchPath & getLIBRARIES()
Definition: Environment.h:132
void setGROUND(const char *value)
-
std::string getPrint() const
+
const std::string & getIN_PH() const
Definition: Environment.h:123
+
const std::string & getPad() const
Definition: Environment.h:130
void setWORKING_LIBRARY(const char *value)
Definition: Environment.h:141
-
const std::string & getDisplayStyle() const
Definition: Environment.h:120
-
const std::string & getCORIOLIS_TOP() const
Definition: Environment.h:119
+
std::string getPrint() const
+
void validate() const
Definition: Environment.h:37
-
bool isBLOCKAGE(const char *name) const
-
const std::string & getOUT_PH() const
Definition: Environment.h:125
-
const std::string & getPOWER() const
Definition: Environment.h:126
Definition: Environment.h:37
void setPad(const char *value)
-
const std::string & getGROUND() const
Definition: Environment.h:127
+
const std::string & getOUT_LO() const
Definition: Environment.h:124
+
const std::string & getDISPLAY() const
void addSYSTEM_LIBRARY(const char *value, const char *libName, unsigned int mode=Append)
-
void validate() const
void setOUT_LO(const char *value)
Definition: Environment.h:138
+
const std::string & getGROUND() const
Definition: Environment.h:127
+
bool isPad(const char *name) const
+
const std::string & getOUT_PH() const
Definition: Environment.h:125
void setPOWER(const char *value)
void setIN_PH(const char *value)
Definition: Environment.h:137
-
bool isCLOCK(const char *name) const
-
bool isGROUND(const char *name) const
-
const std::string & getPad() const
Definition: Environment.h:130
-
const std::string & getDISPLAY() const
+
bool isGROUND(const char *name) const
+
const std::string & getBLOCKAGE() const
Definition: Environment.h:129
+
const std::string & getCORIOLIS_TOP() const
Definition: Environment.h:119
void setIN_LO(const char *value)
Definition: Environment.h:136
-
bool isPad(const char *name) const
+
const std::string & getPOWER() const
Definition: Environment.h:126
An ordered list of search pathes.
Definition: SearchPath.h:32
-
const std::string & getIN_LO() const
Definition: Environment.h:122
-
const std::string & getOUT_LO() const
Definition: Environment.h:124
+
const std::string & getCLOCK() const
Definition: Environment.h:128
+
long getSCALE_X() const
Definition: Environment.h:121
+
const std::string & getDisplayStyle() const
Definition: Environment.h:120
void setOUT_PH(const char *value)
Definition: Environment.h:139
-
const std::string & getIN_PH() const
Definition: Environment.h:123
+
const std::string & getIN_LO() const
Definition: Environment.h:122
AddMode
Definition: Environment.h:37
-
const std::string & getBLOCKAGE() const
Definition: Environment.h:129
Holds all the Alliance environment variables.
Definition: Environment.h:35
-
const std::string & getCATALOG() const
Definition: Environment.h:131
std::string getLIBRARYPath(size_t i)
void setCLOCK(const char *value)
void setDisplayStyle(const char *)
Definition: Environment.h:134
+
The namespace of Coriolis Core.
Definition: Environment.h:26
void replace(const std::string &path, const std::string &, size_t index)
void setDISPLAY(const char *value)
@@ -267,7 +99,7 @@
- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/GraphicToolEngine_8h_source.html b/crlcore/doc/crlcore/html/GraphicToolEngine_8h_source.html index f5b6e8d4..e6a3b757 100644 --- a/crlcore/doc/crlcore/html/GraphicToolEngine_8h_source.html +++ b/crlcore/doc/crlcore/html/GraphicToolEngine_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 // -*- C++ -*-
-
2 //
-
3 // This file is part of the Coriolis Software.
-
4 // Copyright (c) UPMC/LIP6 2008-2018, All Rights Reserved
-
5 //
-
6 // +-----------------------------------------------------------------+
-
7 // | C O R I O L I S |
-
8 // | Alliance / Hurricane Interface |
-
9 // | |
-
10 // | Author : Jean-Paul Chaput |
-
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
-
12 // | =============================================================== |
-
13 // | C++ Header : "./crlcore/GraphicToolEngine.h" |
-
14 // +-----------------------------------------------------------------+
-
15 
-
16 
-
17 #ifndef CRL_GRAPHIC_TOOL_H
-
18 #define CRL_GRAPHIC_TOOL_H
-
19 
-
20 #include <string>
-
21 #include <map>
-
22 #include <functional>
-
23 #include <QObject>
-
24 
-
25 class QMenu;
-
26 
-
27 #include "hurricane/Error.h"
-
28 #include "hurricane/viewer/CellWidget.h"
-
29 #include "hurricane/viewer/ExceptionWidget.h"
-
30 
-
31 
-
32 namespace Hurricane {
-
33  class Name;
-
34  class Cell;
-
35  class CellViewer;
-
36 }
-
37 
-
38 
-
39 namespace CRL {
-
40 
-
41  using std::string;
-
42  using std::map;
-
43  using Hurricane::Error;
- -
45  using Hurricane::Name;
-
46  using Hurricane::Cell;
- - -
49  using Hurricane::ExceptionWidget;
-
50 
-
51 
-
52 // -------------------------------------------------------------------
-
53 // Class : "CRL::GraphicTool".
-
54 
-
55  class GraphicTool : public QObject {
-
56  Q_OBJECT;
-
57 
-
58  public:
-
59  class DrawGoFunctions {
-
60  private:
-
61  CellWidget::InitExtensionGo_t* _init;
-
62  CellWidget::DrawExtensionGo_t* _draw;
-
63  public:
-
64  inline DrawGoFunctions ( CellWidget::InitExtensionGo_t*
-
65  , CellWidget::DrawExtensionGo_t*
-
66  );
-
67  inline CellWidget::DrawExtensionGo_t* getDraw () const;
-
68  inline CellWidget::InitExtensionGo_t* getInit () const;
-
69  };
-
70  public:
-
71  typedef map<Name,DrawGoFunctions> DrawGoMap;
-
72  public:
-
73  void addDrawGo ( const Name&
-
74  , CellWidget::InitExtensionGo_t*
-
75  , CellWidget::DrawExtensionGo_t*
-
76  );
-
77  DrawGoFunctions* getDrawGo ( const Name& );
-
78  inline const DrawGoMap& getDrawGos () const;
-
79  virtual void addToMenu ( CellViewer* ) = 0;
-
80  virtual const Name& getName () const = 0;
-
81  virtual size_t release () = 0;
-
82  protected:
-
83  map<Name,DrawGoFunctions> _drawGoMap;
-
84  protected:
-
85  GraphicTool ();
-
86  virtual ~GraphicTool ();
-
87  protected:
-
88  };
-
89 
-
90 
-
91 // Inline Functions.
-
92  inline GraphicTool::DrawGoFunctions::DrawGoFunctions ( CellWidget::InitExtensionGo_t* init
-
93  , CellWidget::DrawExtensionGo_t* draw
-
94  )
-
95  : _init(init)
-
96  , _draw(draw)
-
97  { }
-
98 
-
99  inline CellWidget::DrawExtensionGo_t* GraphicTool::DrawGoFunctions::getDraw () const
-
100  { return _draw; }
-
101 
-
102  inline CellWidget::InitExtensionGo_t* GraphicTool::DrawGoFunctions::getInit () const
-
103  { return _init; }
-
104 
-
105  inline const GraphicTool::DrawGoMap& GraphicTool::getDrawGos () const
-
106  { return _drawGoMap; }
-
107 
-
108 
-
109 } // CRL namespace.
-
110 
-
111 #endif // CRL_GRAPHIC_TOOL_H
- +
1 // -*- C++ -*-
2 //
3 // This file is part of the Coriolis Software.
4 // Copyright (c) UPMC/LIP6 2008-2018, All Rights Reserved
5 //
6 // +-----------------------------------------------------------------+
7 // | C O R I O L I S |
8 // | Alliance / Hurricane Interface |
9 // | |
10 // | Author : Jean-Paul Chaput |
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
12 // | =============================================================== |
13 // | C++ Header : "./crlcore/GraphicToolEngine.h" |
14 // +-----------------------------------------------------------------+
15 
16 
17 #ifndef CRL_GRAPHIC_TOOL_H
18 #define CRL_GRAPHIC_TOOL_H
19 
20 #include <string>
21 #include <map>
22 #include <functional>
23 #include <QObject>
24 
25 class QMenu;
26 
27 #include "hurricane/Error.h"
28 #include "hurricane/viewer/CellWidget.h"
29 #include "hurricane/viewer/ExceptionWidget.h"
30 
31 
32 namespace Hurricane {
33  class Name;
34  class Cell;
35  class CellViewer;
36 }
37 
38 
39 namespace CRL {
40 
41  using std::string;
42  using std::map;
43  using Hurricane::Error;
45  using Hurricane::Name;
46  using Hurricane::Cell;
49  using Hurricane::ExceptionWidget;
50 
51 
52 // -------------------------------------------------------------------
53 // Class : "CRL::GraphicTool".
54 
55  class GraphicTool : public QObject {
56  Q_OBJECT;
57 
58  public:
59  class DrawGoFunctions {
60  private:
61  CellWidget::InitExtensionGo_t* _init;
62  CellWidget::DrawExtensionGo_t* _draw;
63  public:
64  inline DrawGoFunctions ( CellWidget::InitExtensionGo_t*
65  , CellWidget::DrawExtensionGo_t*
66  );
67  inline CellWidget::DrawExtensionGo_t* getDraw () const;
68  inline CellWidget::InitExtensionGo_t* getInit () const;
69  };
70  public:
71  typedef map<Name,DrawGoFunctions> DrawGoMap;
72  public:
73  void addDrawGo ( const Name&
74  , CellWidget::InitExtensionGo_t*
75  , CellWidget::DrawExtensionGo_t*
76  );
77  DrawGoFunctions* getDrawGo ( const Name& );
78  inline const DrawGoMap& getDrawGos () const;
79  virtual void addToMenu ( CellViewer* ) = 0;
80  virtual const Name& getName () const = 0;
81  virtual size_t release () = 0;
82  protected:
83  map<Name,DrawGoFunctions> _drawGoMap;
84  protected:
85  GraphicTool ();
86  virtual ~GraphicTool ();
87  protected:
88  };
89 
90 
91 // Inline Functions.
92  inline GraphicTool::DrawGoFunctions::DrawGoFunctions ( CellWidget::InitExtensionGo_t* init
93  , CellWidget::DrawExtensionGo_t* draw
94  )
95  : _init(init)
96  , _draw(draw)
97  { }
98 
99  inline CellWidget::DrawExtensionGo_t* GraphicTool::DrawGoFunctions::getDraw () const
100  { return _draw; }
101 
102  inline CellWidget::InitExtensionGo_t* GraphicTool::DrawGoFunctions::getInit () const
103  { return _init; }
104 
105  inline const GraphicTool::DrawGoMap& GraphicTool::getDrawGos () const
106  { return _drawGoMap; }
107 
108 
109 } // CRL namespace.
110 
111 #endif // CRL_GRAPHIC_TOOL_H
Base Class to Hook ToolEngines into the CellViewer.
Definition: GraphicToolEngine.h:55
@@ -168,13 +52,15 @@
virtual const Name & getName() const =0
virtual void addToMenu(CellViewer *)=0
+ +
The namespace of Coriolis Core.
Definition: Environment.h:26


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/RoutingGauge_8h_source.html b/crlcore/doc/crlcore/html/RoutingGauge_8h_source.html index 9f2c6dd4..d344ac0c 100644 --- a/crlcore/doc/crlcore/html/RoutingGauge_8h_source.html +++ b/crlcore/doc/crlcore/html/RoutingGauge_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 // -*- C++ -*-
-
2 //
-
3 // This file is part of the Coriolis Software.
-
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
-
5 //
-
6 // +-----------------------------------------------------------------+
-
7 // | C O R I O L I S |
-
8 // | Alliance / Hurricane Interface |
-
9 // | |
-
10 // | Author : Jean-Paul CHAPUT |
-
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
-
12 // | =============================================================== |
-
13 // | C++ Header : "./crlcore/RoutingGauge.h" |
-
14 // +-----------------------------------------------------------------+
-
15 
-
16 
-
17 #ifndef CRL_ROUTING_GAUGE_H
-
18 #define CRL_ROUTING_GAUGE_H
-
19 
-
20 #include <string>
-
21 #include <vector>
-
22 #include "hurricane/Name.h"
-
23 #include "hurricane/Slot.h"
-
24 
-
25 namespace Hurricane {
-
26  class Layer;
-
27  class Technology;
-
28 }
-
29 
-
30 #include "crlcore/RoutingLayerGauge.h"
-
31 
-
32 namespace CRL {
-
33 
-
34  using std::string;
-
35  using std::vector;
- - - -
39  using Hurricane::Name;
-
40  using Hurricane::Record;
-
41  using Hurricane::Layer;
- -
43 
-
44 
-
45 // -------------------------------------------------------------------
-
46 // Class : "RoutingGauge".
-
47 
-
48  class RoutingGauge {
-
49 
-
50  public:
-
51  // Constants.
-
52  static const size_t nlayerdepth;
-
53  // Constructors & Destructors.
-
54  static RoutingGauge* create ( const char* name );
-
55  virtual void destroy ();
-
56  // Predicates.
-
57  inline bool isSymbolic () const;
-
58  inline bool isTwoMetals () const;
-
59  inline bool isHV () const;
-
60  inline bool isVH () const;
-
61  // Accessors.
-
62  RoutingGauge* getClone () const;
-
63  inline const Name getName () const;
-
64  inline Technology* getTechnology () const;
-
65  inline size_t getDepth () const;
-
66  inline DbU::Unit getHorizontalPitch () const;
-
67  inline DbU::Unit getVerticalPitch () const;
-
68  RoutingLayerGauge* getHorizontalGauge () const;
-
69  RoutingLayerGauge* getVerticalGauge () const;
-
70  RoutingLayerGauge* getLayerGauge ( const Layer* ) const;
-
71  size_t getViaDepth ( const Layer* ) const;
-
72  size_t getLayerDepth ( const Layer* ) const;
-
73  unsigned int getLayerType ( const Layer* ) const;
-
74  unsigned int getLayerDirection ( const Layer* ) const;
-
75  RoutingLayerGauge* getLayerGauge ( size_t depth ) const;
-
76  inline unsigned int getLayerDirection ( size_t depth ) const;
-
77  inline unsigned int getLayerType ( size_t depth ) const;
-
78  inline DbU::Unit getLayerPitch ( size_t depth ) const;
-
79  inline DbU::Unit getLayerOffset ( size_t depth ) const;
-
80  inline DbU::Unit getLayerWireWidth ( size_t depth ) const;
-
81  inline DbU::Unit getViaWidth ( size_t depth ) const;
-
82  const Layer* getRoutingLayer ( size_t depth ) const;
-
83  Layer* getContactLayer ( size_t depth ) const;
-
84  const vector<RoutingLayerGauge*>&
-
85  getLayerGauges () const;
-
86  // Methods.
-
87  void addLayerGauge ( RoutingLayerGauge* layerGauge );
-
88  void checkConnexity () const;
-
89  inline void setSymbolic ( bool );
-
90  // Hurricane Managment.
-
91  void toJson ( JsonWriter* ) const;
-
92  virtual Record* _getRecord ( Record* record=NULL ) const;
-
93  virtual string _getString () const;
-
94  virtual string _getTypeName () const;
-
95 
-
96  protected:
-
97  // Internal - Attributes.
-
98  Name _name;
-
99  vector<RoutingLayerGauge*> _layerGauges;
-
100  vector<Layer*> _viaLayers;
-
101  Technology* _technology;
-
102  bool _isSymbolic;
-
103 
-
104  // Internal - Constructors & Destructors.
-
105  RoutingGauge ( const char* name );
-
106  RoutingGauge ( const RoutingGauge& );
-
107  virtual ~RoutingGauge ();
-
108  virtual void _preDestroy ();
-
109  RoutingGauge& operator= ( const RoutingGauge& );
-
110  };
-
111 
-
112 
-
113  inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; }
-
114  inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); }
-
115  inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); }
-
116  inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); }
-
117  inline const Name RoutingGauge::getName () const { return _name; }
-
118  inline size_t RoutingGauge::getDepth () const { return _layerGauges.size(); }
-
119  inline Technology* RoutingGauge::getTechnology () const { return _technology; }
-
120  inline DbU::Unit RoutingGauge::getHorizontalPitch () const { return getHorizontalGauge()->getPitch(); }
-
121  inline DbU::Unit RoutingGauge::getVerticalPitch () const { return getVerticalGauge ()->getPitch(); }
-
122  inline unsigned int RoutingGauge::getLayerType ( size_t depth ) const { return getLayerGauge(depth)->getType(); }
-
123  inline unsigned int RoutingGauge::getLayerDirection ( size_t depth ) const { return getLayerGauge(depth)->getDirection(); }
-
124  inline DbU::Unit RoutingGauge::getLayerPitch ( size_t depth ) const { return getLayerGauge(depth)->getPitch(); }
-
125  inline DbU::Unit RoutingGauge::getLayerOffset ( size_t depth ) const { return getLayerGauge(depth)->getOffset(); }
-
126  inline DbU::Unit RoutingGauge::getLayerWireWidth ( size_t depth ) const { return getLayerGauge(depth)->getWireWidth(); }
-
127  inline DbU::Unit RoutingGauge::getViaWidth ( size_t depth ) const { return getLayerGauge(depth)->getViaWidth(); }
-
128  inline void RoutingGauge::setSymbolic ( bool state ) { _isSymbolic=state; }
-
129 
-
130 
-
131 // -------------------------------------------------------------------
-
132 // Class : "JsonRoutingGauge".
-
133 
-
134  class JsonRoutingGauge : public JsonObject {
-
135  public:
-
136  static void initialize ();
-
137  JsonRoutingGauge ( unsigned long flags );
-
138  virtual string getTypeName () const;
-
139  virtual JsonRoutingGauge* clone ( unsigned long flags ) const;
-
140  virtual void toData ( JsonStack& );
-
141  };
-
142 
-
143 
-
144 } // CRL namespace.
-
145 
-
146 INSPECTOR_P_SUPPORT(CRL::RoutingGauge);
-
147 
-
148 #endif
-
Technology * getTechnology() const
Definition: RoutingGauge.h:119
-
DbU::Unit getOffset() const
Definition: RoutingLayerGauge.h:177
-
const Layer * getRoutingLayer(size_t depth) const
+
1 // -*- C++ -*-
2 //
3 // This file is part of the Coriolis Software.
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
5 //
6 // +-----------------------------------------------------------------+
7 // | C O R I O L I S |
8 // | Alliance / Hurricane Interface |
9 // | |
10 // | Author : Jean-Paul CHAPUT |
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
12 // | =============================================================== |
13 // | C++ Header : "./crlcore/RoutingGauge.h" |
14 // +-----------------------------------------------------------------+
15 
16 
17 #ifndef CRL_ROUTING_GAUGE_H
18 #define CRL_ROUTING_GAUGE_H
19 
20 #include <string>
21 #include <vector>
22 #include "hurricane/Name.h"
23 #include "hurricane/Slot.h"
24 
25 namespace Hurricane {
26  class Layer;
27  class Technology;
28 }
29 
30 #include "crlcore/RoutingLayerGauge.h"
31 
32 namespace CRL {
33 
34  using std::string;
35  using std::vector;
39  using Hurricane::Name;
40  using Hurricane::Record;
41  using Hurricane::Layer;
43 
44 
45 // -------------------------------------------------------------------
46 // Class : "RoutingGauge".
47 
48  class RoutingGauge {
49 
50  public:
51  // Constants.
52  static const size_t nlayerdepth;
53  // Constructors & Destructors.
54  static RoutingGauge* create ( const char* name );
55  virtual void destroy ();
56  // Predicates.
57  inline bool isSymbolic () const;
58  inline bool isTwoMetals () const;
59  inline bool isHV () const;
60  inline bool isVH () const;
61  // Accessors.
62  RoutingGauge* getClone () const;
63  inline const Name getName () const;
64  inline Technology* getTechnology () const;
65  inline size_t getDepth () const;
66  inline DbU::Unit getHorizontalPitch () const;
67  inline DbU::Unit getVerticalPitch () const;
68  RoutingLayerGauge* getHorizontalGauge () const;
69  RoutingLayerGauge* getVerticalGauge () const;
70  RoutingLayerGauge* getLayerGauge ( const Layer* ) const;
71  size_t getViaDepth ( const Layer* ) const;
72  size_t getLayerDepth ( const Layer* ) const;
73  unsigned int getLayerType ( const Layer* ) const;
74  unsigned int getLayerDirection ( const Layer* ) const;
75  RoutingLayerGauge* getLayerGauge ( size_t depth ) const;
76  inline unsigned int getLayerDirection ( size_t depth ) const;
77  inline unsigned int getLayerType ( size_t depth ) const;
78  inline DbU::Unit getLayerPitch ( size_t depth ) const;
79  inline DbU::Unit getLayerOffset ( size_t depth ) const;
80  inline DbU::Unit getLayerWireWidth ( size_t depth ) const;
81  inline DbU::Unit getViaWidth ( size_t depth ) const;
82  const Layer* getRoutingLayer ( size_t depth ) const;
83  Layer* getContactLayer ( size_t depth ) const;
84  const vector<RoutingLayerGauge*>&
85  getLayerGauges () const;
86  // Methods.
87  void addLayerGauge ( RoutingLayerGauge* layerGauge );
88  void checkConnexity () const;
89  inline void setSymbolic ( bool );
90  // Hurricane Managment.
91  void toJson ( JsonWriter* ) const;
92  virtual Record* _getRecord ( Record* record=NULL ) const;
93  virtual string _getString () const;
94  virtual string _getTypeName () const;
95 
96  protected:
97  // Internal - Attributes.
98  Name _name;
99  vector<RoutingLayerGauge*> _layerGauges;
100  vector<Layer*> _viaLayers;
101  Technology* _technology;
102  bool _isSymbolic;
103 
104  // Internal - Constructors & Destructors.
105  RoutingGauge ( const char* name );
106  RoutingGauge ( const RoutingGauge& );
107  virtual ~RoutingGauge ();
108  virtual void _preDestroy ();
109  RoutingGauge& operator= ( const RoutingGauge& );
110  };
111 
112 
113  inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; }
114  inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); }
115  inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); }
116  inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); }
117  inline const Name RoutingGauge::getName () const { return _name; }
118  inline size_t RoutingGauge::getDepth () const { return _layerGauges.size(); }
119  inline Technology* RoutingGauge::getTechnology () const { return _technology; }
120  inline DbU::Unit RoutingGauge::getHorizontalPitch () const { return getHorizontalGauge()->getPitch(); }
121  inline DbU::Unit RoutingGauge::getVerticalPitch () const { return getVerticalGauge ()->getPitch(); }
122  inline unsigned int RoutingGauge::getLayerType ( size_t depth ) const { return getLayerGauge(depth)->getType(); }
123  inline unsigned int RoutingGauge::getLayerDirection ( size_t depth ) const { return getLayerGauge(depth)->getDirection(); }
124  inline DbU::Unit RoutingGauge::getLayerPitch ( size_t depth ) const { return getLayerGauge(depth)->getPitch(); }
125  inline DbU::Unit RoutingGauge::getLayerOffset ( size_t depth ) const { return getLayerGauge(depth)->getOffset(); }
126  inline DbU::Unit RoutingGauge::getLayerWireWidth ( size_t depth ) const { return getLayerGauge(depth)->getWireWidth(); }
127  inline DbU::Unit RoutingGauge::getViaWidth ( size_t depth ) const { return getLayerGauge(depth)->getViaWidth(); }
128  inline void RoutingGauge::setSymbolic ( bool state ) { _isSymbolic=state; }
129 
130 
131 // -------------------------------------------------------------------
132 // Class : "JsonRoutingGauge".
133 
134  class JsonRoutingGauge : public JsonObject {
135  public:
136  static void initialize ();
137  JsonRoutingGauge ( unsigned long flags );
138  virtual string getTypeName () const;
139  virtual JsonRoutingGauge* clone ( unsigned long flags ) const;
140  virtual void toData ( JsonStack& );
141  };
142 
143 
144 } // CRL namespace.
145 
146 INSPECTOR_P_SUPPORT(CRL::RoutingGauge);
147 
148 #endif
DbU::Unit getViaWidth() const
Definition: RoutingLayerGauge.h:182
+
DbU::Unit getPitch() const
Definition: RoutingLayerGauge.h:178
-
const vector< RoutingLayerGauge * > & getLayerGauges() const
-
Constant::Direction getDirection() const
Definition: RoutingLayerGauge.h:173
+
DbU::Unit getWireWidth() const
Definition: RoutingLayerGauge.h:180
std::int64_t Unit
virtual void destroy()
Gauge for the detailed routing.
Definition: RoutingGauge.h:48
-
Constant::LayerGaugeType getType() const
Definition: RoutingLayerGauge.h:174
+
RoutingGauge * getClone() const
+
Constant::Direction getDirection() const
Definition: RoutingLayerGauge.h:173
+
Technology * getTechnology() const
Definition: RoutingGauge.h:119
-
DbU::Unit getViaWidth() const
Definition: RoutingLayerGauge.h:182
-
size_t getLayerDepth(const Layer *) const
+
const Name getName() const
Definition: RoutingGauge.h:117
+
DbU::Unit getOffset() const
Definition: RoutingLayerGauge.h:177
+
size_t getDepth() const
Definition: RoutingGauge.h:118
+
Constant::LayerGaugeType getType() const
Definition: RoutingLayerGauge.h:174
+
RoutingLayerGauge * getLayerGauge(const Layer *) const
void addLayerGauge(RoutingLayerGauge *layerGauge)
static RoutingGauge * create(const char *name)
-
void checkConnexity() const
-
DbU::Unit getWireWidth() const
Definition: RoutingLayerGauge.h:180
+
const vector< RoutingLayerGauge * > & getLayerGauges() const
-
unsigned int getLayerDirection(const Layer *) const
-
const Name getName() const
Definition: RoutingGauge.h:117
-
RoutingLayerGauge * getLayerGauge(const Layer *) const
-
Layer * getContactLayer(size_t depth) const
+
Layer * getContactLayer(size_t depth) const
+
const Layer * getRoutingLayer(size_t depth) const
+ +
void checkConnexity() const
+
size_t getLayerDepth(const Layer *) const
-
RoutingGauge * getClone() const
-
size_t getDepth() const
Definition: RoutingGauge.h:118
Gauge of a Layer for the detailed routing.
Definition: RoutingLayerGauge.h:77
-
DbU::Unit getPitch() const
Definition: RoutingLayerGauge.h:178
+
unsigned int getLayerDirection(const Layer *) const
+
The namespace of Coriolis Core.
Definition: Environment.h:26


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/RoutingLayerGauge_8h_source.html b/crlcore/doc/crlcore/html/RoutingLayerGauge_8h_source.html index 6be72a19..0964fb6a 100644 --- a/crlcore/doc/crlcore/html/RoutingLayerGauge_8h_source.html +++ b/crlcore/doc/crlcore/html/RoutingLayerGauge_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 // -*- C++ -*-
-
2 //
-
3 // This file is part of the Coriolis Software.
-
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
-
5 //
-
6 // +-----------------------------------------------------------------+
-
7 // | C O R I O L I S |
-
8 // | C o r e L i b r a r y |
-
9 // | |
-
10 // | Author : Jean-Paul CHAPUT |
-
11 // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
-
12 // | =============================================================== |
-
13 // | C++ Header : "./RoutingLayerGauge.h" |
-
14 // +-----------------------------------------------------------------+
-
15 
-
16 
-
17 #ifndef CRL_ROUTING_LAYER_GAUGE_H
-
18 #define CRL_ROUTING_LAYER_GAUGE_H
-
19 
-
20 
-
21 #include <map>
-
22 #include "hurricane/Commons.h"
-
23 #include "hurricane/Error.h"
-
24 #include "hurricane/DbU.h"
-
25 #include "hurricane/Collection.h"
-
26 #include "hurricane/Slot.h"
-
27 #include "crlcore/Utilities.h"
-
28 
-
29 namespace Hurricane {
-
30  class Layer;
-
31 }
-
32 
-
33 
-
34 namespace Constant {
-
35 
-
36  enum Direction { Horizontal = (1<<0)
-
37  , Vertical = (1<<1)
-
38  };
-
39 
-
40  enum LayerGaugeType { Default = (1<<0)
-
41  , PinOnly = (1<<1)
-
42  };
-
43 
-
44  enum Round { Superior = (1<<2)
-
45  , Inferior = (1<<3)
-
46  , Nearest = (1<<4)
-
47  , Exact = (1<<5)
-
48  };
-
49 
-
50  Direction perpandicular ( unsigned int );
-
51 
-
52 }
-
53 
-
54 
-
55 
-
56 namespace CRL {
-
57 
-
58  using std::map;
- - - - - - -
65  using Hurricane::Record;
-
66  using Hurricane::DbU;
-
67  using Hurricane::Layer;
-
68 
-
69 
-
70  class RoutingGauge;
-
71 
-
72 
-
73 // -------------------------------------------------------------------
-
74 // Class : "RoutingLayerGauge".
-
75 
-
76 
- -
78 
-
79  public:
-
80  // Constructors & Destructors.
-
81  static RoutingLayerGauge* create ( const Layer* layer
-
82  , Constant::Direction direction
- -
84  , unsigned int depth
-
85  , double density
-
86  , DbU::Unit offset
-
87  , DbU::Unit pitch
-
88  , DbU::Unit wireWidth
-
89  , DbU::Unit viaWidth
-
90  , DbU::Unit obsDw );
-
91  virtual void destroy ();
-
92  // Accessors.
-
93  inline bool isHorizontal () const;
-
94  inline bool isVertical () const;
-
95  inline const Layer* getLayer () const;
-
96  inline const Layer* getBlockageLayer () const;
-
97  inline unsigned int getDepth () const;
-
98  inline Constant::Direction getDirection () const;
-
99  inline Constant::LayerGaugeType getType () const;
-
100  inline double getDensity () const;
-
101  inline DbU::Unit getOffset () const;
-
102  inline DbU::Unit getPitch () const;
-
103  inline DbU::Unit getHalfPitch () const;
-
104  inline DbU::Unit getWireWidth () const;
-
105  inline DbU::Unit getHalfWireWidth () const;
-
106  inline DbU::Unit getViaWidth () const;
-
107  inline DbU::Unit getHalfViaWidth () const;
-
108  inline DbU::Unit getObstacleDw () const;
-
109  void divide ( DbU::Unit dividend, long& quotient, long& modulo ) const;
-
110  unsigned int getTrackNumber ( DbU::Unit start, DbU::Unit stop ) const;
-
111  unsigned int getTrackIndex ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const;
-
112  inline DbU::Unit getTrackPosition ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const;
-
113  DbU::Unit getTrackPosition ( DbU::Unit start, unsigned depth ) const;
-
114  // Hurricane Managment.
-
115  void toJson ( JsonWriter* ) const;
-
116  virtual string _getTypeName () const;
-
117  virtual string _getString () const;
-
118  virtual Record* _getRecord () const;
-
119 
-
120  protected:
-
121  // Internal - Attributes.
-
122  const Layer* _layer;
-
123  const Layer* _blockageLayer;
-
124  Constant::Direction _direction;
- -
126  unsigned int _depth;
-
127  double _density;
-
128  DbU::Unit _offset;
-
129  DbU::Unit _pitch;
-
130  DbU::Unit _wireWidth;
-
131  DbU::Unit _viaWidth;
-
132  DbU::Unit _obstacleDw;
-
133 
-
134  // Internal - Constructors & Destructors.
-
135  RoutingLayerGauge ( const Layer* layer
-
136  , Constant::Direction direction
- -
138  , unsigned int depth
-
139  , double density
-
140  , DbU::Unit offset
-
141  , DbU::Unit pitch
-
142  , DbU::Unit wireWidth
-
143  , DbU::Unit viaWidth
-
144  , DbU::Unit obsDw );
-
145  virtual ~RoutingLayerGauge ();
-
146  virtual void _preDestroy();
-
147  RoutingLayerGauge& operator= ( const RoutingLayerGauge& );
-
148 
-
149  // Friends.
-
150  friend class RoutingGauge;
-
151  };
-
152 
-
153 
-
154  // New Types.
-
155  typedef map<Layer*,RoutingLayerGauge*> RoutingLayerGaugeMap;
-
156 
-
157 
-
158 // -------------------------------------------------------------------
-
159 // Collection : "RoutingLayerGauges".
-
160 
- - - -
164 
-
165 
-
166 // -------------------------------------------------------------------
-
167 // Inline Functions.
-
168 
-
169  inline bool RoutingLayerGauge::isHorizontal () const { return (_direction == Constant::Direction::Horizontal); }
-
170  inline bool RoutingLayerGauge::isVertical () const { return (_direction == Constant::Direction::Vertical); }
-
171  inline const Layer* RoutingLayerGauge::getLayer () const { return _layer; }
-
172  inline const Layer* RoutingLayerGauge::getBlockageLayer () const { return _blockageLayer; }
-
173  inline Constant::Direction RoutingLayerGauge::getDirection () const { return _direction; }
-
174  inline Constant::LayerGaugeType RoutingLayerGauge::getType () const { return _type; }
-
175  inline unsigned int RoutingLayerGauge::getDepth () const { return _depth; }
-
176  inline double RoutingLayerGauge::getDensity () const { return _density; }
-
177  inline DbU::Unit RoutingLayerGauge::getOffset () const { return _offset; }
-
178  inline DbU::Unit RoutingLayerGauge::getPitch () const { return _pitch; }
-
179  inline DbU::Unit RoutingLayerGauge::getHalfPitch () const { return _pitch>>1; }
-
180  inline DbU::Unit RoutingLayerGauge::getWireWidth () const { return _wireWidth; }
-
181  inline DbU::Unit RoutingLayerGauge::getHalfWireWidth () const { return _wireWidth>>1; }
-
182  inline DbU::Unit RoutingLayerGauge::getViaWidth () const { return _viaWidth; }
-
183  inline DbU::Unit RoutingLayerGauge::getHalfViaWidth () const { return _viaWidth>>1; }
-
184  inline DbU::Unit RoutingLayerGauge::getObstacleDw () const { return _obstacleDw; }
-
185  inline DbU::Unit RoutingLayerGauge::getTrackPosition ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const
-
186  { return getTrackPosition( start, getTrackIndex(start,stop,position,mode) ); }
-
187 
-
188 
-
189 // -------------------------------------------------------------------
-
190 // Class : "JsonRoutingLayerGauge".
-
191 
-
192  class JsonRoutingLayerGauge : public JsonObject {
-
193  public:
-
194  static void initialize ();
-
195  JsonRoutingLayerGauge ( unsigned long flags );
-
196  virtual string getTypeName () const;
-
197  virtual JsonRoutingLayerGauge* clone ( unsigned long flags ) const;
-
198  virtual void toData ( JsonStack& );
-
199  };
-
200 
-
201 
-
202 } // CRL namespace.
-
203 
-
204 
-
205 INSPECTOR_P_SUPPORT(CRL::RoutingLayerGauge);
-
206 
-
207 
-
208 // -------------------------------------------------------------------
-
209 // Inspector Support for : "const ::Constant::Direction*".
-
210 
-
211 
-
212 inline void from ( Constant::Direction& direction, const std::string& s )
-
213 {
-
214  if (s == "Vertical") direction = Constant::Vertical;
-
215  else {
-
216  if (s != "Horizontal")
-
217  std::cerr << Hurricane::Error( "::from(Direction&,string&): Unknown value \"%s\"."
-
218  , s.c_str() ) << std::endl;
-
219  direction = Constant::Horizontal;
-
220  }
-
221 }
-
222 
-
223 
-
224 template<>
-
225 inline std::string getString<const Constant::Direction*>
-
226  ( const Constant::Direction* direction )
-
227 {
-
228  switch ( *direction ) {
-
229  case Constant::Horizontal: return "Horizontal";
-
230  case Constant::Vertical: return "Vertical";
-
231  }
-
232  return "Unknown Constant::Direction";
-
233 }
-
234 
-
235 
-
236 template<>
-
237 inline std::string getString<Constant::Direction>
-
238  ( Constant::Direction direction )
-
239 {
-
240  switch ( direction ) {
-
241  case Constant::Horizontal: return "Horizontal";
-
242  case Constant::Vertical: return "Vertical";
-
243  }
-
244  return "Unknown Constant::Direction";
-
245 }
-
246 
-
247 
-
248 IOSTREAM_POINTER_SUPPORT(Constant::Direction);
-
249 
-
250 
-
251 // -------------------------------------------------------------------
-
252 // Inspector Support for : "const Constant::LayerGaugeType*".
-
253 
-
254 
-
255 inline void from ( Constant::LayerGaugeType& type, const std::string& s )
-
256 {
-
257  if (s == "PinOnly") type = Constant::PinOnly;
-
258  else {
-
259  if (s != "Default")
-
260  std::cerr << Hurricane::Error( "::from(LayerGaugeType&,string&): Unknown value \"%s\"."
-
261  , s.c_str() ) << std::endl;
-
262  type = Constant::Default;
-
263  }
-
264 }
-
265 
-
266 
-
267 template<>
-
268 inline std::string getString<const Constant::LayerGaugeType*>
-
269  ( const Constant::LayerGaugeType* layerGaugeType )
-
270 {
-
271  switch ( *layerGaugeType ) {
-
272  case Constant::Default: return "Default";
-
273  case Constant::PinOnly: return "PinOnly";
-
274  }
-
275  return "Unknown Constant::LayerGaugeType";
-
276 }
-
277 
-
278 
-
279 template<>
-
280 inline std::string getString<Constant::LayerGaugeType*>
-
281  ( Constant::LayerGaugeType* layerGaugeType )
-
282 { return getString<const Constant::LayerGaugeType*>(layerGaugeType); }
-
283 
-
284 
-
285 template<>
-
286 inline std::string getString<const Constant::LayerGaugeType>
-
287  ( const Constant::LayerGaugeType layerGaugeType )
-
288 {
-
289  switch ( layerGaugeType ) {
-
290  case Constant::Default: return "Default";
-
291  case Constant::PinOnly: return "PinOnly";
-
292  }
-
293  return "Unknown Constant::LayerGaugeType";
-
294 }
-
295 
-
296 
-
297 template<>
-
298 inline std::string getString<Constant::LayerGaugeType>
-
299  ( Constant::LayerGaugeType layerGaugeType )
-
300 { return getString<const Constant::LayerGaugeType>(layerGaugeType); }
-
301 
-
302 
-
303 IOSTREAM_POINTER_SUPPORT(Constant::LayerGaugeType);
-
304 
-
305 
-
306 #endif // CRL_ROUTING_LAYER_GAUGE_H
-
DbU::Unit getHalfWireWidth() const
Definition: RoutingLayerGauge.h:181
+
1 // -*- C++ -*-
2 //
3 // This file is part of the Coriolis Software.
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
5 //
6 // +-----------------------------------------------------------------+
7 // | C O R I O L I S |
8 // | C o r e L i b r a r y |
9 // | |
10 // | Author : Jean-Paul CHAPUT |
11 // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
12 // | =============================================================== |
13 // | C++ Header : "./RoutingLayerGauge.h" |
14 // +-----------------------------------------------------------------+
15 
16 
17 #ifndef CRL_ROUTING_LAYER_GAUGE_H
18 #define CRL_ROUTING_LAYER_GAUGE_H
19 
20 
21 #include <map>
22 #include "hurricane/Commons.h"
23 #include "hurricane/Error.h"
24 #include "hurricane/DbU.h"
25 #include "hurricane/Collection.h"
26 #include "hurricane/Slot.h"
27 #include "crlcore/Utilities.h"
28 
29 namespace Hurricane {
30  class Layer;
31 }
32 
33 
34 namespace Constant {
35 
36  enum Direction { Horizontal = (1<<0)
37  , Vertical = (1<<1)
38  };
39 
40  enum LayerGaugeType { Default = (1<<0)
41  , PinOnly = (1<<1)
42  };
43 
44  enum Round { Superior = (1<<2)
45  , Inferior = (1<<3)
46  , Nearest = (1<<4)
47  , Exact = (1<<5)
48  };
49 
50  Direction perpandicular ( unsigned int );
51 
52 }
53 
54 
55 
56 namespace CRL {
57 
58  using std::map;
65  using Hurricane::Record;
66  using Hurricane::DbU;
67  using Hurricane::Layer;
68 
69 
70  class RoutingGauge;
71 
72 
73 // -------------------------------------------------------------------
74 // Class : "RoutingLayerGauge".
75 
76 
78 
79  public:
80  // Constructors & Destructors.
81  static RoutingLayerGauge* create ( const Layer* layer
82  , Constant::Direction direction
84  , unsigned int depth
85  , double density
86  , DbU::Unit offset
87  , DbU::Unit pitch
88  , DbU::Unit wireWidth
89  , DbU::Unit viaWidth
90  , DbU::Unit obsDw );
91  virtual void destroy ();
92  // Accessors.
93  inline bool isHorizontal () const;
94  inline bool isVertical () const;
95  inline const Layer* getLayer () const;
96  inline const Layer* getBlockageLayer () const;
97  inline unsigned int getDepth () const;
98  inline Constant::Direction getDirection () const;
99  inline Constant::LayerGaugeType getType () const;
100  inline double getDensity () const;
101  inline DbU::Unit getOffset () const;
102  inline DbU::Unit getPitch () const;
103  inline DbU::Unit getHalfPitch () const;
104  inline DbU::Unit getWireWidth () const;
105  inline DbU::Unit getHalfWireWidth () const;
106  inline DbU::Unit getViaWidth () const;
107  inline DbU::Unit getHalfViaWidth () const;
108  inline DbU::Unit getObstacleDw () const;
109  void divide ( DbU::Unit dividend, long& quotient, long& modulo ) const;
110  unsigned int getTrackNumber ( DbU::Unit start, DbU::Unit stop ) const;
111  unsigned int getTrackIndex ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const;
112  inline DbU::Unit getTrackPosition ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const;
113  DbU::Unit getTrackPosition ( DbU::Unit start, unsigned depth ) const;
114  // Hurricane Managment.
115  void toJson ( JsonWriter* ) const;
116  virtual string _getTypeName () const;
117  virtual string _getString () const;
118  virtual Record* _getRecord () const;
119 
120  protected:
121  // Internal - Attributes.
122  const Layer* _layer;
123  const Layer* _blockageLayer;
124  Constant::Direction _direction;
126  unsigned int _depth;
127  double _density;
128  DbU::Unit _offset;
129  DbU::Unit _pitch;
130  DbU::Unit _wireWidth;
131  DbU::Unit _viaWidth;
132  DbU::Unit _obstacleDw;
133 
134  // Internal - Constructors & Destructors.
135  RoutingLayerGauge ( const Layer* layer
136  , Constant::Direction direction
138  , unsigned int depth
139  , double density
140  , DbU::Unit offset
141  , DbU::Unit pitch
142  , DbU::Unit wireWidth
143  , DbU::Unit viaWidth
144  , DbU::Unit obsDw );
145  virtual ~RoutingLayerGauge ();
146  virtual void _preDestroy();
147  RoutingLayerGauge& operator= ( const RoutingLayerGauge& );
148 
149  // Friends.
150  friend class RoutingGauge;
151  };
152 
153 
154  // New Types.
155  typedef map<Layer*,RoutingLayerGauge*> RoutingLayerGaugeMap;
156 
157 
158 // -------------------------------------------------------------------
159 // Collection : "RoutingLayerGauges".
160 
164 
165 
166 // -------------------------------------------------------------------
167 // Inline Functions.
168 
169  inline bool RoutingLayerGauge::isHorizontal () const { return (_direction == Constant::Direction::Horizontal); }
170  inline bool RoutingLayerGauge::isVertical () const { return (_direction == Constant::Direction::Vertical); }
171  inline const Layer* RoutingLayerGauge::getLayer () const { return _layer; }
172  inline const Layer* RoutingLayerGauge::getBlockageLayer () const { return _blockageLayer; }
173  inline Constant::Direction RoutingLayerGauge::getDirection () const { return _direction; }
174  inline Constant::LayerGaugeType RoutingLayerGauge::getType () const { return _type; }
175  inline unsigned int RoutingLayerGauge::getDepth () const { return _depth; }
176  inline double RoutingLayerGauge::getDensity () const { return _density; }
177  inline DbU::Unit RoutingLayerGauge::getOffset () const { return _offset; }
178  inline DbU::Unit RoutingLayerGauge::getPitch () const { return _pitch; }
179  inline DbU::Unit RoutingLayerGauge::getHalfPitch () const { return _pitch>>1; }
180  inline DbU::Unit RoutingLayerGauge::getWireWidth () const { return _wireWidth; }
181  inline DbU::Unit RoutingLayerGauge::getHalfWireWidth () const { return _wireWidth>>1; }
182  inline DbU::Unit RoutingLayerGauge::getViaWidth () const { return _viaWidth; }
183  inline DbU::Unit RoutingLayerGauge::getHalfViaWidth () const { return _viaWidth>>1; }
184  inline DbU::Unit RoutingLayerGauge::getObstacleDw () const { return _obstacleDw; }
185  inline DbU::Unit RoutingLayerGauge::getTrackPosition ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const
186  { return getTrackPosition( start, getTrackIndex(start,stop,position,mode) ); }
187 
188 
189 // -------------------------------------------------------------------
190 // Class : "JsonRoutingLayerGauge".
191 
192  class JsonRoutingLayerGauge : public JsonObject {
193  public:
194  static void initialize ();
195  JsonRoutingLayerGauge ( unsigned long flags );
196  virtual string getTypeName () const;
197  virtual JsonRoutingLayerGauge* clone ( unsigned long flags ) const;
198  virtual void toData ( JsonStack& );
199  };
200 
201 
202 } // CRL namespace.
203 
204 
205 INSPECTOR_P_SUPPORT(CRL::RoutingLayerGauge);
206 
207 
208 // -------------------------------------------------------------------
209 // Inspector Support for : "const ::Constant::Direction*".
210 
211 
212 inline void from ( Constant::Direction& direction, const std::string& s )
213 {
214  if (s == "Vertical") direction = Constant::Vertical;
215  else {
216  if (s != "Horizontal")
217  std::cerr << Hurricane::Error( "::from(Direction&,string&): Unknown value \"%s\"."
218  , s.c_str() ) << std::endl;
219  direction = Constant::Horizontal;
220  }
221 }
222 
223 
224 template<>
225 inline std::string getString<const Constant::Direction*>
226  ( const Constant::Direction* direction )
227 {
228  switch ( *direction ) {
229  case Constant::Horizontal: return "Horizontal";
230  case Constant::Vertical: return "Vertical";
231  }
232  return "Unknown Constant::Direction";
233 }
234 
235 
236 template<>
237 inline std::string getString<Constant::Direction>
238  ( Constant::Direction direction )
239 {
240  switch ( direction ) {
241  case Constant::Horizontal: return "Horizontal";
242  case Constant::Vertical: return "Vertical";
243  }
244  return "Unknown Constant::Direction";
245 }
246 
247 
248 IOSTREAM_POINTER_SUPPORT(Constant::Direction);
249 
250 
251 // -------------------------------------------------------------------
252 // Inspector Support for : "const Constant::LayerGaugeType*".
253 
254 
255 inline void from ( Constant::LayerGaugeType& type, const std::string& s )
256 {
257  if (s == "PinOnly") type = Constant::PinOnly;
258  else {
259  if (s != "Default")
260  std::cerr << Hurricane::Error( "::from(LayerGaugeType&,string&): Unknown value \"%s\"."
261  , s.c_str() ) << std::endl;
262  type = Constant::Default;
263  }
264 }
265 
266 
267 template<>
268 inline std::string getString<const Constant::LayerGaugeType*>
269  ( const Constant::LayerGaugeType* layerGaugeType )
270 {
271  switch ( *layerGaugeType ) {
272  case Constant::Default: return "Default";
273  case Constant::PinOnly: return "PinOnly";
274  }
275  return "Unknown Constant::LayerGaugeType";
276 }
277 
278 
279 template<>
280 inline std::string getString<Constant::LayerGaugeType*>
281  ( Constant::LayerGaugeType* layerGaugeType )
282 { return getString<const Constant::LayerGaugeType*>(layerGaugeType); }
283 
284 
285 template<>
286 inline std::string getString<const Constant::LayerGaugeType>
287  ( const Constant::LayerGaugeType layerGaugeType )
288 {
289  switch ( layerGaugeType ) {
290  case Constant::Default: return "Default";
291  case Constant::PinOnly: return "PinOnly";
292  }
293  return "Unknown Constant::LayerGaugeType";
294 }
295 
296 
297 template<>
298 inline std::string getString<Constant::LayerGaugeType>
299  ( Constant::LayerGaugeType layerGaugeType )
300 { return getString<const Constant::LayerGaugeType>(layerGaugeType); }
301 
302 
303 IOSTREAM_POINTER_SUPPORT(Constant::LayerGaugeType);
304 
305 
306 #endif // CRL_ROUTING_LAYER_GAUGE_H
Store various constants.
Definition: RoutingLayerGauge.h:34
+
DbU::Unit getViaWidth() const
Definition: RoutingLayerGauge.h:182
virtual void destroy()
-
const Layer * getLayer() const
Definition: RoutingLayerGauge.h:171
-
DbU::Unit getOffset() const
Definition: RoutingLayerGauge.h:177
+
const Layer * getLayer() const
Definition: RoutingLayerGauge.h:171
Round
Definition: RoutingLayerGauge.h:44
-
unsigned int getDepth() const
Definition: RoutingLayerGauge.h:175
+
DbU::Unit getPitch() const
Definition: RoutingLayerGauge.h:178
+
unsigned int getTrackIndex(DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode) const
-
Constant::Direction getDirection() const
Definition: RoutingLayerGauge.h:173
-
unsigned int getTrackNumber(DbU::Unit start, DbU::Unit stop) const
-
const Layer * getBlockageLayer() const
Definition: RoutingLayerGauge.h:172
+
DbU::Unit getWireWidth() const
Definition: RoutingLayerGauge.h:180
std::int64_t Unit
-
double getDensity() const
Definition: RoutingLayerGauge.h:176
+
unsigned int getTrackNumber(DbU::Unit start, DbU::Unit stop) const
Direction
Definition: RoutingLayerGauge.h:36
Gauge for the detailed routing.
Definition: RoutingGauge.h:48
-
Constant::LayerGaugeType getType() const
Definition: RoutingLayerGauge.h:174
+
Constant::Direction getDirection() const
Definition: RoutingLayerGauge.h:173
Definition: RoutingLayerGauge.h:41
Definition: RoutingLayerGauge.h:46
Definition: RoutingLayerGauge.h:40
static RoutingLayerGauge * create(const Layer *layer, Constant::Direction direction, Constant::LayerGaugeType type, unsigned int depth, double density, DbU::Unit offset, DbU::Unit pitch, DbU::Unit wireWidth, DbU::Unit viaWidth, DbU::Unit obsDw)
+
unsigned int getDepth() const
Definition: RoutingLayerGauge.h:175
-
DbU::Unit getViaWidth() const
Definition: RoutingLayerGauge.h:182
-
unsigned int getTrackIndex(DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode) const
+
DbU::Unit getOffset() const
Definition: RoutingLayerGauge.h:177
+
Constant::LayerGaugeType getType() const
Definition: RoutingLayerGauge.h:174
+
const Layer * getBlockageLayer() const
Definition: RoutingLayerGauge.h:172
-
DbU::Unit getHalfViaWidth() const
Definition: RoutingLayerGauge.h:183
Definition: RoutingLayerGauge.h:45
LayerGaugeType
Definition: RoutingLayerGauge.h:40
-
DbU::Unit getWireWidth() const
Definition: RoutingLayerGauge.h:180
-
void divide(DbU::Unit dividend, long &quotient, long &modulo) const
+
DbU::Unit getHalfViaWidth() const
Definition: RoutingLayerGauge.h:183
+
DbU::Unit getHalfWireWidth() const
Definition: RoutingLayerGauge.h:181
+
void divide(DbU::Unit dividend, long &quotient, long &modulo) const
+
double getDensity() const
Definition: RoutingLayerGauge.h:176
+ +
DbU::Unit getHalfPitch() const
Definition: RoutingLayerGauge.h:179
Definition: RoutingLayerGauge.h:44
-
DbU::Unit getHalfPitch() const
Definition: RoutingLayerGauge.h:179
Definition: RoutingLayerGauge.h:37
Definition: RoutingLayerGauge.h:36
Gauge of a Layer for the detailed routing.
Definition: RoutingLayerGauge.h:77
Definition: RoutingLayerGauge.h:47
-
DbU::Unit getPitch() const
Definition: RoutingLayerGauge.h:178
+
The namespace of Coriolis Core.
Definition: Environment.h:26


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/SearchPath_8h_source.html b/crlcore/doc/crlcore/html/SearchPath_8h_source.html index 4fc3a0cd..c6719954 100644 --- a/crlcore/doc/crlcore/html/SearchPath_8h_source.html +++ b/crlcore/doc/crlcore/html/SearchPath_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 // -*- C++ -*-
-
2 //
-
3 // This file is part of the Coriolis Software.
-
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
-
5 //
-
6 // +-----------------------------------------------------------------+
-
7 // | C O R I O L I S |
-
8 // | Alliance / Hurricane Interface |
-
9 // | |
-
10 // | Author : Jean-Paul CHAPUT |
-
11 // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
-
12 // | =============================================================== |
-
13 // | C++ Header : "./crlcore/SearchPath.h" |
-
14 // +-----------------------------------------------------------------+
-
15 
-
16 
-
17 #ifndef CRL_SEARCH_PATH_H
-
18 #define CRL_SEARCH_PATH_H
-
19 
-
20 #include <string>
-
21 #include <vector>
-
22 #include "hurricane/Commons.h"
-
23 #include "hurricane/Slot.h"
-
24 
-
25 
-
26 namespace CRL {
-
27 
-
28  using Hurricane::Record;
-
29  using Hurricane::_TName;
-
30 
-
31 
-
32  class SearchPath {
-
33  public:
-
34  class Element {
-
35  public:
-
36  inline Element ( const std::string& path="", const std::string& name="" );
-
37  inline bool empty () const;
-
38  inline const std::string& getPath () const;
-
39  inline const std::string& getName () const;
-
40  inline std::string _getTypeName () const;
-
41  std::string _getString () const;
-
42  Record* _getRecord () const;
-
43  private:
-
44  std::string _path;
-
45  std::string _name;
-
46  };
-
47  public:
-
48  static const size_t npos;
-
49  static std::string extractLibName ( const std::string& );
-
50  SearchPath ();
-
51  public:
-
52  inline void reset ();
-
53  inline void append ( const std::string& path, const std::string& name="" );
-
54  void prepend ( const std::string& path, const std::string& name="");
-
55  void replace ( const std::string& path, const std::string&, size_t index );
-
56  void remove ( size_t index );
-
57  size_t locate ( const std::string& file
-
58  , std::ios::openmode mode =std::ios::in
-
59  , int first=0
-
60  , int last =64 );
-
61  void select ( const std::string& );
-
62  inline size_t getSize () const;
-
63  inline const std::string& getSelected () const;
-
64  inline size_t getIndex () const;
-
65  inline bool hasSelected () const;
-
66  size_t hasLib ( const std::string& name ) const;
-
67  size_t hasPath ( const std::string& path ) const;
-
68  const Element& operator[] ( size_t index ) const;
-
69  private:
-
70  static const std::string _selectFailed;
-
71  std::vector<Element> _paths;
-
72  size_t _index;
-
73  std::string _selected;
-
74  private:
-
75  SearchPath ( const SearchPath& );
-
76  bool _canOpen ( const Element& directory
-
77  , const std::string& file
-
78  , std::ios::openmode mode
-
79  );
-
80  public:
-
81  inline std::string _getTypeName () const;
-
82  std::string _getString () const;
-
83  Record* _getRecord () const;
-
84  };
-
85 
-
86 
-
87  // Inline Functions.
-
88  inline void SearchPath::reset () { _paths.resize(1); }
-
89  inline size_t SearchPath::getSize () const { return _paths.size(); }
-
90  inline const std::string& SearchPath::getSelected () const { return _selected; }
-
91  inline size_t SearchPath::getIndex () const { return _index; }
-
92  inline bool SearchPath::hasSelected () const { return _index != npos; }
-
93  inline std::string SearchPath::_getTypeName () const { return _TName("SearchPath"); }
-
94 
-
95  inline void SearchPath::append ( const std::string& path, const std::string& name ) {
-
96  _paths.push_back ( Element ( path, name.empty()?extractLibName(path):name ) );
-
97  }
-
98 
-
99  inline SearchPath::Element::Element ( const std::string& path, const std::string& name )
-
100  : _path(path)
-
101  , _name(name.empty()?SearchPath::extractLibName(path):name)
-
102  { }
-
103 
-
104  inline bool SearchPath::Element::empty () const { return _path.empty() and _name.empty(); }
-
105  inline const std::string& SearchPath::Element::getPath () const { return _path; }
-
106  inline const std::string& SearchPath::Element::getName () const { return _name; }
-
107  inline std::string SearchPath::Element::_getTypeName () const { return "SearchPath::Element"; }
-
108 
-
109 
-
110 } // CRL namespace.
-
111 
-
112 
-
113 INSPECTOR_P_SUPPORT(CRL::SearchPath);
-
114 INSPECTOR_V_SUPPORT(CRL::SearchPath::Element);
-
115 
-
116 
-
117 #endif // CRL_SEARCH_PATH_H
+
1 // -*- C++ -*-
2 //
3 // This file is part of the Coriolis Software.
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
5 //
6 // +-----------------------------------------------------------------+
7 // | C O R I O L I S |
8 // | Alliance / Hurricane Interface |
9 // | |
10 // | Author : Jean-Paul CHAPUT |
11 // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
12 // | =============================================================== |
13 // | C++ Header : "./crlcore/SearchPath.h" |
14 // +-----------------------------------------------------------------+
15 
16 
17 #ifndef CRL_SEARCH_PATH_H
18 #define CRL_SEARCH_PATH_H
19 
20 #include <string>
21 #include <vector>
22 #include "hurricane/Commons.h"
23 #include "hurricane/Slot.h"
24 
25 
26 namespace CRL {
27 
28  using Hurricane::Record;
29  using Hurricane::_TName;
30 
31 
32  class SearchPath {
33  public:
34  class Element {
35  public:
36  inline Element ( const std::string& path="", const std::string& name="" );
37  inline bool empty () const;
38  inline const std::string& getPath () const;
39  inline const std::string& getName () const;
40  inline std::string _getTypeName () const;
41  std::string _getString () const;
42  Record* _getRecord () const;
43  private:
44  std::string _path;
45  std::string _name;
46  };
47  public:
48  static const size_t npos;
49  static std::string extractLibName ( const std::string& );
50  SearchPath ();
51  public:
52  inline void reset ();
53  inline void append ( const std::string& path, const std::string& name="" );
54  void prepend ( const std::string& path, const std::string& name="");
55  void replace ( const std::string& path, const std::string&, size_t index );
56  void remove ( size_t index );
57  size_t locate ( const std::string& file
58  , std::ios::openmode mode =std::ios::in
59  , int first=0
60  , int last =64 );
61  void select ( const std::string& );
62  inline size_t getSize () const;
63  inline const std::string& getSelected () const;
64  inline size_t getIndex () const;
65  inline bool hasSelected () const;
66  size_t hasLib ( const std::string& name ) const;
67  size_t hasPath ( const std::string& path ) const;
68  const Element& operator[] ( size_t index ) const;
69  private:
70  static const std::string _selectFailed;
71  std::vector<Element> _paths;
72  size_t _index;
73  std::string _selected;
74  private:
75  SearchPath ( const SearchPath& );
76  bool _canOpen ( const Element& directory
77  , const std::string& file
78  , std::ios::openmode mode
79  );
80  public:
81  inline std::string _getTypeName () const;
82  std::string _getString () const;
83  Record* _getRecord () const;
84  };
85 
86 
87  // Inline Functions.
88  inline void SearchPath::reset () { _paths.resize(1); }
89  inline size_t SearchPath::getSize () const { return _paths.size(); }
90  inline const std::string& SearchPath::getSelected () const { return _selected; }
91  inline size_t SearchPath::getIndex () const { return _index; }
92  inline bool SearchPath::hasSelected () const { return _index != npos; }
93  inline std::string SearchPath::_getTypeName () const { return _TName("SearchPath"); }
94 
95  inline void SearchPath::append ( const std::string& path, const std::string& name ) {
96  _paths.push_back ( Element ( path, name.empty()?extractLibName(path):name ) );
97  }
98 
99  inline SearchPath::Element::Element ( const std::string& path, const std::string& name )
100  : _path(path)
101  , _name(name.empty()?SearchPath::extractLibName(path):name)
102  { }
103 
104  inline bool SearchPath::Element::empty () const { return _path.empty() and _name.empty(); }
105  inline const std::string& SearchPath::Element::getPath () const { return _path; }
106  inline const std::string& SearchPath::Element::getName () const { return _name; }
107  inline std::string SearchPath::Element::_getTypeName () const { return "SearchPath::Element"; }
108 
109 
110 } // CRL namespace.
111 
112 
113 INSPECTOR_P_SUPPORT(CRL::SearchPath);
114 INSPECTOR_V_SUPPORT(CRL::SearchPath::Element);
115 
116 
117 #endif // CRL_SEARCH_PATH_H
const std::string & getSelected() const
Definition: SearchPath.h:90
void reset()
Definition: SearchPath.h:88
static std::string extractLibName(const std::string &)
-
bool empty() const
Definition: SearchPath.h:104
-
const std::string & getPath() const
Definition: SearchPath.h:105
-
size_t getSize() const
Definition: SearchPath.h:89
-
const std::string & getName() const
Definition: SearchPath.h:106
-
size_t hasPath(const std::string &path) const
+
size_t getIndex() const
Definition: SearchPath.h:91
+
bool hasSelected() const
Definition: SearchPath.h:92
size_t locate(const std::string &file, std::ios::openmode mode=std::ios::in, int first=0, int last=64)
An element of the search path (mapping a directory).
Definition: SearchPath.h:34
-
const std::string & getSelected() const
Definition: SearchPath.h:90
+
size_t getSize() const
Definition: SearchPath.h:89
+
size_t hasPath(const std::string &path) const
An ordered list of search pathes.
Definition: SearchPath.h:32
-
bool hasSelected() const
Definition: SearchPath.h:92
-
const Element & operator[](size_t index) const
void prepend(const std::string &path, const std::string &name="")
-
size_t getIndex() const
Definition: SearchPath.h:91
+
bool empty() const
Definition: SearchPath.h:104
+
const std::string & getPath() const
Definition: SearchPath.h:105
+
const std::string & getName() const
Definition: SearchPath.h:106
+
The namespace of Coriolis Core.
Definition: Environment.h:26
void replace(const std::string &path, const std::string &, size_t index)
Element(const std::string &path="", const std::string &name="")
Definition: SearchPath.h:99
void append(const std::string &path, const std::string &name="")
Definition: SearchPath.h:95
+
const Element & operator[](size_t index) const


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/ToolEngine_8h_source.html b/crlcore/doc/crlcore/html/ToolEngine_8h_source.html index b397897e..a5e8b2ac 100644 --- a/crlcore/doc/crlcore/html/ToolEngine_8h_source.html +++ b/crlcore/doc/crlcore/html/ToolEngine_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 // -*- C++ -*-
-
2 //
-
3 // This file is part of the Coriolis Software.
-
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
-
5 //
-
6 // +-----------------------------------------------------------------+
-
7 // | C O R I O L I S |
-
8 // | Alliance / Hurricane Interface |
-
9 // | |
-
10 // | Author : Jean-Paul Chaput |
-
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
-
12 // | =============================================================== |
-
13 // | C++ Header : "./crlcore/ToolEngine.h" |
-
14 // +-----------------------------------------------------------------+
-
15 
-
16 
-
17 
-
18 #ifndef CRL_TOOL_ENGINE_H
-
19 #define CRL_TOOL_ENGINE_H
-
20 
-
21 #include <string>
-
22 #include <vector>
-
23 #include "hurricane/Commons.h"
-
24 #include "hurricane/Timer.h"
-
25 #include "hurricane/DBo.h"
-
26 #include "hurricane/Slot.h"
-
27 
-
28 namespace Hurricane {
-
29  class Name;
-
30  class Cell;
-
31 }
-
32 
-
33 #include "crlcore/ToolEngines.h"
-
34 
-
35 
-
36 namespace CRL {
-
37 
-
38  using std::string;
-
39  using std::vector;
-
40  using Hurricane::Timer;
-
41  using Hurricane::Record;
-
42  using Hurricane::Name;
-
43  using Hurricane::DBo;
-
44  using Hurricane::Cell;
-
45 
-
46 
-
47 // -------------------------------------------------------------------
-
48 // Class : "CRL::ToolEngine".
-
49 
-
50  class ToolEngine : public DBo {
-
51  public:
-
52  typedef DBo Super;
-
53  public:
-
54  static ToolEngines get ( const Cell* cell );
-
55  static ToolEngine* get ( const Cell* cell, const Name& name );
-
56  static void destroyAll ();
-
57  static bool inDestroyAll ();
-
58  public:
-
59  virtual const Name& getName () const = 0;
-
60  inline Cell* getCell () const;
-
61  bool placementModificationFlagHasChanged ();
-
62  bool routingModificationFlagHasChanged ();
-
63  inline void setInRelationDestroy ( bool );
-
64  inline const Timer& getTimer () const;
-
65  void startMeasures ();
-
66  void stopMeasures ();
-
67  void suspendMeasures ();
-
68  void resumeMeasures ();
-
69  void printMeasures () const;
-
70  virtual string _getTypeName () const;
-
71  virtual string _getString () const;
-
72  virtual Record* _getRecord () const;
-
73  private:
-
74  static bool _inDestroyAll;
-
75  protected:
-
76  Cell* _cell;
-
77  private:
-
78  unsigned int _placementModificationFlag;
-
79  unsigned int _routingModificationFlag;
-
80  bool _inRelationDestroy;
-
81  Timer _timer;
-
82  protected:
-
83  ToolEngine ( Cell* cell );
-
84  virtual void _postCreate ();
-
85  virtual void _preDestroy ();
-
86  protected:
-
87  void grabPlacementModificationFlag ();
-
88  void getPlacementModificationFlag ();
-
89  void grabRoutingModificationFlag ();
-
90  void getRoutingModificationFlag ();
-
91  };
-
92 
-
93 
-
94 // -------------------------------------------------------------------
-
95 // Inline Functions.
-
96 
-
97 
-
98  inline Cell* ToolEngine::getCell () const { return _cell; }
-
99  inline void ToolEngine::setInRelationDestroy ( bool state ) { _inRelationDestroy = state; }
-
100  inline const Timer& ToolEngine::getTimer () const { return _timer; }
-
101 
-
102 
-
103 } // CRL namespace.
-
104 
-
105 #endif // CRL_TOOL_ENGINE_H
-
virtual const Name & getName() const =0
+
1 // -*- C++ -*-
2 //
3 // This file is part of the Coriolis Software.
4 // Copyright (c) UPMC 2008-2018, All Rights Reserved
5 //
6 // +-----------------------------------------------------------------+
7 // | C O R I O L I S |
8 // | Alliance / Hurricane Interface |
9 // | |
10 // | Author : Jean-Paul Chaput |
11 // | E-mail : Jean-Paul.Chaput@lip6.fr |
12 // | =============================================================== |
13 // | C++ Header : "./crlcore/ToolEngine.h" |
14 // +-----------------------------------------------------------------+
15 
16 
17 
18 #ifndef CRL_TOOL_ENGINE_H
19 #define CRL_TOOL_ENGINE_H
20 
21 #include <string>
22 #include <vector>
23 #include "hurricane/Commons.h"
24 #include "hurricane/Timer.h"
25 #include "hurricane/DBo.h"
26 #include "hurricane/Slot.h"
27 
28 namespace Hurricane {
29  class Name;
30  class Cell;
31 }
32 
33 #include "crlcore/ToolEngines.h"
34 
35 
36 namespace CRL {
37 
38  using std::string;
39  using std::vector;
40  using Hurricane::Timer;
41  using Hurricane::Record;
42  using Hurricane::Name;
43  using Hurricane::DBo;
44  using Hurricane::Cell;
45 
46 
47 // -------------------------------------------------------------------
48 // Class : "CRL::ToolEngine".
49 
50  class ToolEngine : public DBo {
51  public:
52  typedef DBo Super;
53  public:
54  static ToolEngines get ( const Cell* cell );
55  static ToolEngine* get ( const Cell* cell, const Name& name );
56  static void destroyAll ();
57  static bool inDestroyAll ();
58  public:
59  virtual const Name& getName () const = 0;
60  inline Cell* getCell () const;
61  bool placementModificationFlagHasChanged ();
62  bool routingModificationFlagHasChanged ();
63  inline void setInRelationDestroy ( bool );
64  inline const Timer& getTimer () const;
65  void startMeasures ();
66  void stopMeasures ();
67  void suspendMeasures ();
68  void resumeMeasures ();
69  void printMeasures () const;
70  virtual string _getTypeName () const;
71  virtual string _getString () const;
72  virtual Record* _getRecord () const;
73  private:
74  static bool _inDestroyAll;
75  protected:
76  Cell* _cell;
77  private:
78  unsigned int _placementModificationFlag;
79  unsigned int _routingModificationFlag;
80  bool _inRelationDestroy;
81  Timer _timer;
82  protected:
83  ToolEngine ( Cell* cell );
84  virtual void _postCreate ();
85  virtual void _preDestroy ();
86  protected:
87  void grabPlacementModificationFlag ();
88  void getPlacementModificationFlag ();
89  void grabRoutingModificationFlag ();
90  void getRoutingModificationFlag ();
91  };
92 
93 
94 // -------------------------------------------------------------------
95 // Inline Functions.
96 
97 
98  inline Cell* ToolEngine::getCell () const { return _cell; }
99  inline void ToolEngine::setInRelationDestroy ( bool state ) { _inRelationDestroy = state; }
100  inline const Timer& ToolEngine::getTimer () const { return _timer; }
101 
102 
103 } // CRL namespace.
104 
105 #endif // CRL_TOOL_ENGINE_H
virtual const Name & getName() const =0
static void destroyAll()
Base Class of all Coriolis Tools.
Definition: ToolEngine.h:50
+ +
The namespace of Coriolis Core.
Definition: Environment.h:26


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/ToolEngines_8h_source.html b/crlcore/doc/crlcore/html/ToolEngines_8h_source.html index bf4ea18f..6e2d975c 100644 --- a/crlcore/doc/crlcore/html/ToolEngines_8h_source.html +++ b/crlcore/doc/crlcore/html/ToolEngines_8h_source.html @@ -24,21 +24,16 @@ -->
- - - + + + + +
-
1 
-
2 
-
3 // This file is part of the Coriolis Project.
-
4 // Copyright (C) Laboratoire LIP6 - Departement ASIM
-
5 // Universite Pierre et Marie Curie
-
6 //
-
7 // Main contributors :
-
8 // Christophe Alexandre <Christophe.Alexandre@lip6.fr>
-
9 // Sophie Belloeil <Sophie.Belloeil@lip6.fr>
-
10 // Hugo Clment <Hugo.Clement@lip6.fr>
-
11 // Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
-
12 // Damien Dupuis <Damien.Dupuis@lip6.fr>
-
13 // Christian Masson <Christian.Masson@lip6.fr>
-
14 // Marek Sroka <Marek.Sroka@lip6.fr>
-
15 //
-
16 // The Coriolis Project is free software; you can redistribute it
-
17 // and/or modify it under the terms of the GNU General Public License
-
18 // as published by the Free Software Foundation; either version 2 of
-
19 // the License, or (at your option) any later version.
-
20 //
-
21 // The Coriolis Project is distributed in the hope that it will be
-
22 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-
23 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-
24 // GNU General Public License for more details.
-
25 //
-
26 // You should have received a copy of the GNU General Public License
-
27 // along with the Coriolis Project; if not, write to the Free Software
-
28 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-
29 // USA
-
30 //
-
31 // License-Tag
-
32 // Authors-Tag
-
33 // ===================================================================
-
34 
-
35 
-
36 # ifndef __CRL_TOOL_ENGINES_H__
-
37 # define __CRL_TOOL_ENGINES_H__
-
38 
-
39 # include "hurricane/Collection.h"
-
40 
-
41 
-
42 namespace CRL {
-
43 
-
44 
- - - -
48 
-
49 
-
50  class ToolEngine;
-
51 
-
52 
- - - -
56 
-
57 # define for_each_toolengine(toolEngine, toolEngines) { \
-
58  ToolEngineLocator _locator = toolEngines.getLocator(); \
-
59  while ( _locator.isValid() ) { \
-
60  ToolEngine* toolEngine = _locator.getElement(); \
-
61  _locator.progress();
-
62 
-
63 }
-
64 
-
65 
-
66 #endif // __CENGINES_H
- +
1 
2 
3 // This file is part of the Coriolis Project.
4 // Copyright (C) Laboratoire LIP6 - Departement ASIM
5 // Universite Pierre et Marie Curie
6 //
7 // Main contributors :
8 // Christophe Alexandre <Christophe.Alexandre@lip6.fr>
9 // Sophie Belloeil <Sophie.Belloeil@lip6.fr>
10 // Hugo Clment <Hugo.Clement@lip6.fr>
11 // Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
12 // Damien Dupuis <Damien.Dupuis@lip6.fr>
13 // Christian Masson <Christian.Masson@lip6.fr>
14 // Marek Sroka <Marek.Sroka@lip6.fr>
15 //
16 // The Coriolis Project is free software; you can redistribute it
17 // and/or modify it under the terms of the GNU General Public License
18 // as published by the Free Software Foundation; either version 2 of
19 // the License, or (at your option) any later version.
20 //
21 // The Coriolis Project is distributed in the hope that it will be
22 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
23 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 // GNU General Public License for more details.
25 //
26 // You should have received a copy of the GNU General Public License
27 // along with the Coriolis Project; if not, write to the Free Software
28 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
29 // USA
30 //
31 // License-Tag
32 // Authors-Tag
33 // ===================================================================
34 
35 
36 # ifndef __CRL_TOOL_ENGINES_H__
37 # define __CRL_TOOL_ENGINES_H__
38 
39 # include "hurricane/Collection.h"
40 
41 
42 namespace CRL {
43 
44 
48 
49 
50  class ToolEngine;
51 
52 
56 
57 # define for_each_toolengine(toolEngine, toolEngines) { \
58  ToolEngineLocator _locator = toolEngines.getLocator(); \
59  while ( _locator.isValid() ) { \
60  ToolEngine* toolEngine = _locator.getElement(); \
61  _locator.progress();
62 
63 }
64 
65 
66 #endif // __CENGINES_H
Base Class of all Coriolis Tools.
Definition: ToolEngine.h:50
GenericLocator< ToolEngine * > ToolEngineLocator
Definition: ToolEngines.h:54
GenericFilter< ToolEngine * > ToolEngineFilter
Definition: ToolEngines.h:55
GenericCollection< ToolEngine * > ToolEngines
Definition: ToolEngines.h:50
+
The namespace of Coriolis Core.
Definition: Environment.h:26


- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/annotated.html b/crlcore/doc/crlcore/html/annotated.html index 06ec7312..50a90693 100644 --- a/crlcore/doc/crlcore/html/annotated.html +++ b/crlcore/doc/crlcore/html/annotated.html @@ -24,24 +24,16 @@ -->
- - - + + + + +
@@ -50,22 +42,21 @@
Here are the classes, structs, unions and interfaces with brief descriptions:
[detail level 123]
- - - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
oNConstantStore various constants
\NCRLThe namespace of Coriolis Core
 oCEnvironmentHolds all the Alliance environment variables
 oCBannerPrint Formatted Banners (on ttys)
 oCCatalogA Registry to store Alliance Cell metadatas
 |\CStateAn entry to store the Cell State in the Catalog
 oCCatalogExtensionWrapper to access a Hurricane::Cell Catalog::State
 oCSearchPathAn ordered list of search pathes
 |\CElementAn element of the search path (mapping a directory)
 oCAllianceLibraryA small wrapper around Hurricane::Library
 oCRoutingLayerGaugeGauge of a Layer for the detailed routing
 oCRoutingGaugeGauge for the detailed routing
 oCAllianceFrameworkA Framework to work with Alliance formats
 oCAcmSigdaA Parser of ACM/Sigda 89' benchmarks
 oCToolEngineBase Class of all Coriolis Tools
 \CGraphicToolBase Class to Hook ToolEngines into the CellViewer
 NCRLThe namespace of Coriolis Core
 CAcmSigdaA Parser of ACM/Sigda 89' benchmarks
 CAllianceFrameworkA Framework to work with Alliance formats
 CAllianceLibraryA small wrapper around Hurricane::Library
 CBannerPrint Formatted Banners (on ttys)
 CCatalogA Registry to store Alliance Cell metadatas
 CStateAn entry to store the Cell State in the Catalog
 CCatalogExtensionWrapper to access a Hurricane::Cell Catalog::State
 CEnvironmentHolds all the Alliance environment variables
 CGraphicToolBase Class to Hook ToolEngines into the CellViewer
 CRoutingGaugeGauge for the detailed routing
 CRoutingLayerGaugeGauge of a Layer for the detailed routing
 CSearchPathAn ordered list of search pathes
 CElementAn element of the search path (mapping a directory)
 CToolEngineBase Class of all Coriolis Tools
@@ -73,7 +64,7 @@
- +
Generated by doxygen 1.8.5 on Sat Aug 18 2018Generated by doxygen 1.8.14 on Thu Oct 18 2018 Return to top of page
diff --git a/crlcore/doc/crlcore/html/classCRL_1_1AcmSigda-members.html b/crlcore/doc/crlcore/html/classCRL_1_1AcmSigda-members.html index fa9c75a4..b270d2c5 100644 --- a/crlcore/doc/crlcore/html/classCRL_1_1AcmSigda-members.html +++ b/crlcore/doc/crlcore/html/classCRL_1_1AcmSigda-members.html @@ -24,24 +24,16 @@ -->
- - - + + + + +