diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 5c43d07d..130037d8 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -48,6 +48,7 @@ namespace Anabatic { DbU::Unit Vertex::unreached = std::numeric_limits::max(); + DbU::Unit Vertex::unreachable = std::numeric_limits::max()-1; bool Vertex::hasValidStamp () const @@ -65,10 +66,16 @@ namespace Anabatic { + " @(" + DbU::getValueString(_gcell->getXMin()) + "," + DbU::getValueString(_gcell->getYMin()) + ")" + " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None") - + " d:" + ((_distance == unreached) ? "unreached" : DbU::getValueString(_distance) ) + + " d:" + ((_distance == unreached) ? "unreached" + : ((_distance == unreachable) ? "unreachable" + : DbU::getValueString(_distance)) ) + "+" + getString(_branchId) + " stamp:" + (hasValidStamp() ? "valid" : "outdated") + " from:" + ((_from) ? "set" : "NULL") + + " restricted:" + (isNRestricted() ? "N" : "-") + + (isSRestricted() ? "S" : "-") + + (isERestricted() ? "E" : "-") + + (isWRestricted() ? "W" : "-") + ">"; return s; } @@ -108,6 +115,9 @@ namespace Anabatic { { DbU::Unit distance = a->getDistance() + e->getDistance(); + if ( (a->isNotRestricted()) && (b->isNotRestricted()) ) { // A remplacer avec verification sur type IsDevice()?. + if (isRestricted(a, b)) distance = Vertex::unreachable; + } // Edge* aFrom = a->getFrom(); // if (aFrom) { // distance += (aFrom->isHorizontal() xor e->isHorizontal()) ? 3.0 : 0.0; @@ -116,6 +126,49 @@ namespace Anabatic { } + bool Dijkstra::isRestricted ( const Vertex* v1, const Vertex* v2 ) + { + bool restricted = true; + GCell* c1 = v1->getGCell(); + GCell* c2 = v2->getGCell(); + + // Check from GCell 1 + if ( c1->isNorth(c2) ) { + if ( !v1->isNRestricted() ) restricted = false; + } else if ( c1->isSouth(c2) ) { + if ( !v1->isSRestricted() ) restricted = false; + } else if ( c1->isEast (c2) ) { + if ( !v1->isERestricted() ) restricted = false; + } else if ( c1->isWest (c2) ) { + if ( !v1->isWRestricted() ) restricted = false; + } else { + cerr << Error( "GCells are not side by side." ) << endl; + return true; + } + + if (restricted) return true; + else { + // Check from GCell 2 + if ( c2->isNorth(c1) ) { + if ( v2->isNRestricted() ) return true; + else return false; + } else if ( c2->isSouth(c1) ) { + if ( v2->isSRestricted() ) return true; + else return false; + } else if ( c2->isEast (c1) ) { + if ( v2->isERestricted() ) return true; + else return false; + } else if ( c2->isWest (c1) ) { + if ( v2->isWRestricted() ) return true; + else return false; + } else { + cerr << Error( "GCells are not side by side." ) << endl; + return true; + } + } + } + + Dijkstra::Dijkstra ( AnabaticEngine* anabatic ) : _anabatic (anabatic) , _vertexes () @@ -198,6 +251,7 @@ namespace Anabatic { vertex->setBranchId( 0 ); vertex->setFrom ( NULL ); _targets.insert( vertex ); + vertex->clearRestriction(); cdebug_log(112,0) << "Add Vertex: " << vertex << endl; } diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index fe1a625b..33c00627 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -623,6 +623,58 @@ namespace Anabatic { } + bool GCell::isNorth ( GCell* c ) const + { + bool found = false; + for (vector::const_iterator it = _northEdges.begin(); it != _northEdges.end(); it++){ + if ( (*it)->getOpposite(this)->getId() == c->getId() ) { + found = true; + break; + } + } + return found; + } + + + bool GCell::isSouth ( GCell* c ) const + { + bool found = false; + for (vector::const_iterator it = _southEdges.begin(); it != _southEdges.end(); it++){ + if ( (*it)->getOpposite(this)->getId() == c->getId() ) { + found = true; + break; + } + } + return found; + } + + + bool GCell::isEast ( GCell* c ) const + { + bool found = false; + for (vector::const_iterator it = _eastEdges.begin(); it != _eastEdges.end(); it++){ + if ( (*it)->getOpposite(this)->getId() == c->getId() ) { + found = true; + break; + } + } + return found; + } + + + bool GCell::isWest ( GCell* c ) const + { + bool found = false; + for (vector::const_iterator it = _westEdges.begin(); it != _westEdges.end(); it++){ + if ( (*it)->getOpposite(this)->getId() == c->getId() ) { + found = true; + break; + } + } + return found; + } + + string GCell::_getTypeName () const { return getString(_extensionName); } diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index dbd56f60..4d62770f 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -34,6 +34,7 @@ namespace Anabatic { using Hurricane::Observer; using Hurricane::Net; using Hurricane::RoutingPad; + using Hurricane::Plug; class AnabaticEngine; @@ -46,8 +47,16 @@ namespace Anabatic { public: inline bool operator() ( const Vertex* lhs, const Vertex* rhs ) const; }; + public: + enum FlagR { NoRestriction = 0 + , NRestricted = (1<<0) + , SRestricted = (1<<1) + , ERestricted = (1<<2) + , WRestricted = (1<<3) + }; public: static DbU::Unit unreached; + static DbU::Unit unreachable; public: static void notify ( Vertex*, unsigned flags ); public: @@ -74,6 +83,25 @@ namespace Anabatic { inline void setFrom ( Edge* ); inline void add ( RoutingPad* ); inline void clearRps (); + + inline bool isNorth ( Vertex* ) const; + inline bool isSouth ( Vertex* ) const; + inline bool isEast ( Vertex* ) const; + inline bool isWest ( Vertex* ) const; + inline bool isNRestricted () const; + inline bool isSRestricted () const; + inline bool isERestricted () const; + inline bool isWRestricted () const; + inline bool isNotRestricted() const; + + inline void setRestricted (); + inline void clearRestriction (); + inline void setNRestricted (); + inline void setSRestricted (); + inline void setERestricted (); + inline void setWRestricted (); + inline unsigned int getFlags () const; + // Inspector support. string _getString () const; private: @@ -88,18 +116,20 @@ namespace Anabatic { int _stamp; DbU::Unit _distance; Edge* _from; + unsigned int _flags; }; inline Vertex::Vertex ( GCell* gcell ) - : _id (gcell->getId()) - , _gcell (gcell) - , _observer (this) - , _connexId (-1) - , _branchId ( 0) - , _stamp (-1) - , _distance (unreached) - , _from (NULL) + : _id (gcell->getId()) + , _gcell (gcell) + , _observer(this) + , _connexId(-1) + , _branchId( 0) + , _stamp (-1) + , _distance(unreached) + , _from (NULL) + , _flags (NoRestriction) { gcell->setObserver( GCell::Observable::Vertex, &_observer ); } @@ -131,6 +161,24 @@ namespace Anabatic { typedef set VertexSet; + inline bool Vertex::isNorth ( Vertex* v ) const { return _gcell->isNorth(v->getGCell()); } + inline bool Vertex::isSouth ( Vertex* v ) const { return _gcell->isSouth(v->getGCell()); } + inline bool Vertex::isEast ( Vertex* v ) const { return _gcell->isEast (v->getGCell()); } + inline bool Vertex::isWest ( Vertex* v ) const { return _gcell->isWest (v->getGCell()); } + inline bool Vertex::isNRestricted () const { return (_flags & NRestricted); } + inline bool Vertex::isSRestricted () const { return (_flags & SRestricted); } + inline bool Vertex::isERestricted () const { return (_flags & ERestricted); } + inline bool Vertex::isWRestricted () const { return (_flags & WRestricted); } + inline bool Vertex::isNotRestricted () const { return ((!_flags) & 0xF); } + + inline void Vertex::setRestricted () { _flags |= 0xF; } + inline void Vertex::clearRestriction () { _flags &= ~(0xF); } + inline void Vertex::setNRestricted () { _flags |= 0x1; } + inline void Vertex::setSRestricted () { _flags |= 0x2; } + inline void Vertex::setERestricted () { _flags |= 0x4; } + inline void Vertex::setWRestricted () { _flags |= 0x8; } + inline unsigned int Vertex::getFlags () const { return _flags; } + // ------------------------------------------------------------------- // Class : "Anabatic::PriorityQueue". @@ -218,7 +266,6 @@ namespace Anabatic { }; public: typedef std::function distance_t; - public: Dijkstra ( AnabaticEngine* ); ~Dijkstra (); @@ -241,6 +288,7 @@ namespace Anabatic { Vertex* _propagateRipup ( Vertex* ); void _tagConnecteds ( Vertex*, int connexId ); void _checkEdges () const; + static bool isRestricted ( const Vertex* v1, const Vertex* v2 ); private: AnabaticEngine* _anabatic; vector _vertexes; diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index f56a0d1a..eb91fcc2 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -79,6 +79,10 @@ namespace Anabatic { inline bool isChannel () const; inline bool isStrut () const; inline bool isMatrix () const; + bool isWest ( GCell* ) const; + bool isEast ( GCell* ) const; + bool isNorth ( GCell* ) const; + bool isSouth ( GCell* ) const; bool hasGContact ( const Contact* ) const; inline AnabaticEngine* getAnabatic () const; inline DbU::Unit getXMin () const; @@ -141,8 +145,8 @@ namespace Anabatic { virtual void _postCreate (); virtual void _preDestroy (); private: - GCell ( const GCell& ); - GCell& operator= ( const GCell& ); + GCell ( const GCell& ); + GCell& operator= ( const GCell& ); private: static Name _extensionName; Observable _observable;