diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 0aa4056c..4deb3ef3 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -49,6 +49,16 @@ namespace Anabatic { { return _stamp == getAnabatic()->getStamp(); } + string Vertex::_getString () const + { + string s = ""; + return s; + } + + // ------------------------------------------------------------------- // Class : "Anabatic::Dijkstra". @@ -79,12 +89,17 @@ namespace Anabatic { void Dijkstra::load ( Net* net ) { + _net = net; + + cdebug.log(111,1) << "Dijkstra::load() " << _net << endl; UpdateSession::open(); + _sources.clear(); + _targets.clear(); _searchArea.makeEmpty(); _stamp = _anabatic->incStamp(); - for ( Component* component : net->getRoutingPads() ) { + for ( Component* component : _net->getRoutingPads() ) { RoutingPad* rp = dynamic_cast( component ); if (rp) { Box rpBb = rp->getBoundingBox(); @@ -94,8 +109,8 @@ namespace Anabatic { 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() + , getString(rp ).c_str() + , getString(_net).c_str() ) << endl; continue; } @@ -104,22 +119,27 @@ namespace Anabatic { Vertex* vertex = gcell->lookup(); if (vertex->getConnexId() < 0) { + cdebug.log(111) << "Add Vertex: " << vertex << endl; + vertex->setStamp ( _stamp ); vertex->setConnexId( _targets.size() ); - vertex->getGContact( _net ); + Contact* gcontact = vertex->getGContact( _net ); + rp->getBodyHook()->detach(); + rp->getBodyHook()->attach( gcontact->getBodyHook() ); _targets.insert( vertex ); } } } UpdateSession::close(); + cdebug.tabw(111,-1); } void Dijkstra::selectFirstSource () { if (_targets.empty()) { - cerr << Error( "Dijkstra::selectFirstSource(): %s has no vertexes to route, ignored.\n" + cerr << Error( "Dijkstra::selectFirstSource(): %s has no vertexes to route, ignored." , getString(_net).c_str() ) << endl; return; @@ -137,75 +157,126 @@ namespace Anabatic { } } - _targets.erase( firstSource ); + _targets.erase ( firstSource ); + _sources.insert( firstSource ); + + cdebug.log(111) << "Dijkstra::selectFirstSource() " << *_sources.begin() << endl; } - void Dijkstra::propagate () + bool Dijkstra::propagate () { + cdebug.log(111,1) << "Dijkstra::propagate() " << _net << endl; + while ( not _queue.empty() ) { + _queue.dump(); + Vertex* current = _queue.top(); _queue.pop(); + cdebug.log(111) << "Pop: (size:" << _queue.size() << ") " << current << endl; + if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) { for ( Edge* edge : current->getGCell()->getEdges() ) { + if (edge == current->getFrom()) continue; GCell* gneighbor = edge->getOpposite(current->getGCell()); Vertex* vneighbor = gneighbor->lookup(); + cdebug.log(111) << "Neighbor: " << vneighbor << endl; + if (vneighbor->getConnexId() == _connectedsId) continue; float distance = current->getDistance() + edge->getDistance(); - if (distance < current->getDistance()) { + + if (distance < vneighbor->getDistance()) { if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor ); else vneighbor->setStamp( _stamp ); vneighbor->setDistance( distance ); + vneighbor->setFrom ( edge ); _queue.push( vneighbor ); + + cdebug.log(111) << "Push: (size:" << _queue.size() << ") " << vneighbor << endl; } } + + continue; } // We did reach another target (different ). // Tag back the path. + cdebug.log(111) << "Trace back" << endl; _targets.erase( current ); while ( current ) { + cdebug.log(111) << "| " << current << endl; + _sources.insert( current ); current->setDistance( 0.0 ); current->setConnexId( _connectedsId ); current = current->getPredecessor(); } - break; + cdebug.tabw(111,-1); + return true; } + + cerr << Error( "Dijkstra::propagate(): %s has unreachable targets." + , getString(_net).c_str() + ) << endl; + + cdebug.tabw(111,-1); + return false; } void Dijkstra::run () { - if (_sources.empty()) return; + cdebug.log(111,1) << "Dijkstra::run() on " << _net << endl; + + selectFirstSource(); + if (_sources.empty()) { + cdebug.log(111) << "No source to start, not routed." << endl; + cdebug.tabw(111,-1); + return; + } UpdateSession::open(); + Vertex* source = *_sources.begin(); _queue.clear(); - _queue.push( *_sources.begin() ); - _connectedsId = (*_sources.begin())->getConnexId(); + _queue.push( source ); + _connectedsId = source->getConnexId(); + source->setDistance( 0.0 ); - while ( not _targets.empty() ) propagate(); + cdebug.log(111) << "Push source: (size:" << _queue.size() << ") " + << source + << " _connectedsId:" << _connectedsId << endl; + + while ( not _targets.empty() and propagate() ); toWires(); + _queue.clear(); UpdateSession::close(); + cdebug.tabw(111,-1); } void Dijkstra::toWires () { + cdebug.log(111,1) << "Dijkstra::toWires() " << _net << endl; + for ( Vertex* vertex : _sources ) { Edge* from = vertex->getFrom(); if (not from) continue; + + cdebug.log(111) << "| " << vertex << endl; + + from->incRealOccupancy( 1 ); + Vertex* source = vertex; Vertex* target = source->getPredecessor(); @@ -214,7 +285,7 @@ namespace Anabatic { std::swap( source, target ); Contact* sourceContact = source->getGContact( _net ); - Contact* targetContact = source->getGContact( _net ); + Contact* targetContact = target->getGContact( _net ); if (from->isHorizontal()) { Horizontal::create( sourceContact @@ -232,6 +303,8 @@ namespace Anabatic { ); } } + + cdebug.tabw(111,-1); } diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index d162fe36..1cfe7bf9 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -190,6 +190,7 @@ namespace Anabatic { _axis = side.getCenter(); _capacity = getAnabatic()->getCapacity( side, _flags ); + Super::invalidate( false ); _flags.reset( Flags::Invalidated ); cdebug.log(110) << "Edge::_revalidate() " << this << endl; } diff --git a/anabatic/src/Edges.cpp b/anabatic/src/Edges.cpp index 1c2c7bef..9c6c9164 100644 --- a/anabatic/src/Edges.cpp +++ b/anabatic/src/Edges.cpp @@ -32,66 +32,87 @@ namespace Anabatic { , _flags(Flags::EastSide) , _iedge(0) { + cdebug.log(110) << "GCell_Edges::Locator::Locator() " << isValid() << endl; if (_gcell->getEastEdges().empty()) progress(); } EdgesHL* GCell_Edges::Locator::getClone () const - { return new Locator (*this); } + { + cdebug.log(110) << "GCell_Edges::Locator::getClone()" << endl; + return new Locator (*this); + } Edge* GCell_Edges::Locator::getElement () const { - if (_flags & Flags::EastSide ) return _gcell->getEastEdges ()[_iedge]; - if (_flags & Flags::NorthSide) return _gcell->getNorthEdges()[_iedge]; - if (_flags & Flags::WestSide ) return _gcell->getWestEdges ()[_iedge]; - if (_flags & Flags::SouthSide) return _gcell->getSouthEdges()[_iedge]; + if (_flags.contains(Flags::EastSide )) return _gcell->getEastEdges ()[_iedge]; + if (_flags.contains(Flags::NorthSide)) return _gcell->getNorthEdges()[_iedge]; + if (_flags.contains(Flags::WestSide )) return _gcell->getWestEdges ()[_iedge]; + if (_flags.contains(Flags::SouthSide)) return _gcell->getSouthEdges()[_iedge]; return NULL; } bool GCell_Edges::Locator::isValid () const - { return not _flags; } + { return _flags; } void GCell_Edges::Locator::progress () { - cdebug.log(110) << "GCell_Edges::Locator::progress()" << endl; + cdebug.log(110) << "GCell_Edges::Locator::progress() [from] " << _flags << " iedge:" << _iedge << endl; + cdebug.log(110) << " East:" << _gcell->getEastEdges().size() + << " North:" << _gcell->getNorthEdges().size() + << " West:" << _gcell->getWestEdges().size() + << " South:" << _gcell->getSouthEdges().size() << endl; + cdebug.log(110) << this << endl; ++_iedge; while (_flags) { - if (_flags & Flags::EastSide) { + if (_flags.contains(Flags::EastSide)) { if (_iedge < _gcell->getEastEdges().size()) break; + cdebug.log(110) << "Switching to North side." << endl; _flags = Flags::NorthSide; _iedge = 0; + cdebug.log(110) << this << endl; + continue; } - if (_flags & Flags::NorthSide) { + if (_flags.contains(Flags::NorthSide)) { if (_iedge < _gcell->getNorthEdges().size()) break; + cdebug.log(110) << "Switching to West side." << endl; _flags = Flags::WestSide; _iedge = 0; + cdebug.log(110) << this << endl; + continue; } - if (_flags & Flags::WestSide) { + if (_flags.contains(Flags::WestSide)) { if (_iedge < _gcell->getWestEdges().size()) break; + cdebug.log(110) << "Switching to South side." << endl; _flags = Flags::SouthSide; _iedge = 0; + continue; } - if (_flags & Flags::SouthSide) { + if (_flags.contains(Flags::SouthSide)) { if (_iedge < _gcell->getSouthEdges().size()) break; + cdebug.log(110) << "All edges done." << endl; _flags = 0; _iedge = 0; + break;; } } + + cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _flags << " iedge:" << _iedge << endl; } string GCell_Edges::Locator::_getString () const { string s = " #include "hurricane/Contact.h" +#include "hurricane/UpdateSession.h" #include "anabatic/GCell.h" #include "anabatic/AnabaticEngine.h" @@ -25,6 +26,7 @@ namespace Anabatic { using std::cerr; using std::endl; using Hurricane::Error; + using Hurricane::UpdateSession; Name GCell::_extensionName = "Anabatic::GCell"; @@ -208,7 +210,6 @@ namespace Anabatic { const GCell* current = this; while ( current ) { - cerr << "current:" << current << endl; if (not current->isFlat() and current->getBoundingBox().contains(x,y)) break; if (x >= current->getXMax()) { current = current->getEast (); continue; } @@ -378,6 +379,8 @@ namespace Anabatic { return false; } + UpdateSession::open(); + GCell* row = this; GCell* column = NULL; DbU::Unit ycut = vspan.getVMin()+side; @@ -395,6 +398,8 @@ namespace Anabatic { column = column->vcut( xcut ); } + UpdateSession::close(); + return true; } @@ -511,18 +516,24 @@ namespace Anabatic { Contact* GCell::getGContact ( Net* net ) { + for ( Contact* contact : _contacts ) { - if (contact->getNet() == net) return contact; + if (contact->getNet() == net) { + cdebug.log(111) << "GCell::getGContact(): " << contact << endl; + return contact; + } } - Point center = getBoundingBox().getCenter(); - return Contact::create( net - , _anabatic->getConfiguration()->getGContactLayer() - , center.getX() - , center.getY() - , DbU::fromLambda(2.0) - , DbU::fromLambda(2.0) - ); + Point center = getBoundingBox().getCenter(); + Contact* contact = Contact::create( net + , _anabatic->getConfiguration()->getGContactLayer() + , center.getX() + , center.getY() + , DbU::fromLambda(2.0) + , DbU::fromLambda(2.0) + ); + cdebug.log(111) << "GCell::getGContact(): " << contact << endl; + return contact; } diff --git a/anabatic/src/GraphicAnabaticEngine.cpp b/anabatic/src/GraphicAnabaticEngine.cpp index 404c34e5..1a51a766 100644 --- a/anabatic/src/GraphicAnabaticEngine.cpp +++ b/anabatic/src/GraphicAnabaticEngine.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,7 @@ namespace Anabatic { using Hurricane::Exception; using Hurricane::Breakpoint; using Hurricane::DebugSession; + using Hurricane::UpdateSession; using Hurricane::Point; using Hurricane::Entity; using Hurricane::Net; @@ -75,6 +77,8 @@ namespace Anabatic { void anabaticTest_2 ( AnabaticEngine* engine ) { + UpdateSession::open(); + GCell* row0 = engine->getSouthWestGCell(); DbU::Unit xcorner = engine->getCell()->getAbutmentBox().getXMin(); DbU::Unit ycorner = engine->getCell()->getAbutmentBox().getYMin(); @@ -106,6 +110,8 @@ namespace Anabatic { cdebug.log(119,1) << "row1+1: " << row1 << endl; cdebug.tabw(119,-1); + + UpdateSession::close(); } @@ -132,13 +138,17 @@ namespace Anabatic { engine->getSouthWestGCell()->doGrid(); - Net* net = cell->getNet( "ialu.inv_x2_3_sig" ); - if (net) { - Dijkstra* dijkstra = new Dijkstra ( engine ); + vector nets; + nets.push_back( cell->getNet( "ialu.inv_x2_3_sig" ) ); + nets.push_back( cell->getNet( "iram.na3_x1_13_sig" ) ); + nets.push_back( cell->getNet( "iram.ram_idx_7(1)" ) ); + + Dijkstra* dijkstra = new Dijkstra ( engine ); + for ( Net* net : nets ) { dijkstra->load( net ); dijkstra->run(); - delete dijkstra; } + delete dijkstra; } diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index 8c435e11..60404cbc 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -18,6 +18,7 @@ #define ANABATIC_DIJKSTRA_H #include +#include namespace Hurricane { class Net; } @@ -27,6 +28,7 @@ namespace Hurricane { namespace Anabatic { using std::set; + using std::multiset; using Hurricane::Net; class AnabaticEngine; @@ -41,29 +43,31 @@ namespace Anabatic { inline bool operator() ( const Vertex* lhs, const Vertex* rhs ); }; public: - static float unreached; - public: - inline Vertex ( GCell* ); - inline Vertex ( size_t id ); - inline ~Vertex (); - inline unsigned int getId () const; - inline GCell* getGCell () const; - inline AnabaticEngine* getAnabatic () const; - inline Contact* getGContact ( Net* ); - bool hasValidStamp () const; - inline Point getCenter () const; - inline float getDistance () const; - inline int getStamp () const; - inline int getConnexId () const; - inline Edge* getFrom () const; - inline Vertex* getPredecessor () const; - inline void setDistance ( float ); - inline void setStamp ( int ); - inline void setConnexId ( int ); - inline void setFrom ( Edge* ); + static float unreached; + public: + inline Vertex ( GCell* ); + inline Vertex ( size_t id ); + inline ~Vertex (); + inline unsigned int getId () const; + inline GCell* getGCell () const; + inline AnabaticEngine* getAnabatic () const; + inline Contact* getGContact ( Net* ); + bool hasValidStamp () const; + inline Point getCenter () const; + inline float getDistance () const; + inline int getStamp () const; + inline int getConnexId () const; + inline Edge* getFrom () const; + inline Vertex* getPredecessor () const; + inline void setDistance ( float ); + inline void setStamp ( int ); + inline void setConnexId ( int ); + inline void setFrom ( Edge* ); + // Inspector support. + string _getString () const; private: - Vertex ( const Vertex& ); - Vertex& operator= ( const Vertex& ); + Vertex ( const Vertex& ); + Vertex& operator= ( const Vertex& ); private: size_t _id; GCell* _gcell; @@ -132,13 +136,14 @@ namespace Anabatic { inline Vertex* top (); inline void pop (); inline void clear (); + inline void dump () const; private: class CompareByDistance { public: inline bool operator() ( const Vertex* lhs, const Vertex* rhs ); }; private: - set _queue; + multiset _queue; }; @@ -146,15 +151,26 @@ namespace Anabatic { { return lhs->getDistance() < rhs->getDistance(); } - inline PriorityQueue::PriorityQueue () : _queue() { } - inline PriorityQueue::~PriorityQueue () { } - inline bool PriorityQueue::empty () const { return _queue.empty(); } - inline size_t PriorityQueue::size () const { return _queue.size(); } - inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); } - inline void PriorityQueue::erase ( Vertex* v ) { _queue.erase(v); } - inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); } - inline void PriorityQueue::pop () { _queue.erase(_queue.begin()); } - inline void PriorityQueue::clear () { _queue.clear(); } + inline PriorityQueue::PriorityQueue () : _queue() { } + inline PriorityQueue::~PriorityQueue () { } + inline bool PriorityQueue::empty () const { return _queue.empty(); } + inline size_t PriorityQueue::size () const { return _queue.size(); } + inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); } + inline void PriorityQueue::erase ( Vertex* v ) { _queue.erase(v); } + inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); } + inline void PriorityQueue::pop () { _queue.erase(_queue.begin()); } + inline void PriorityQueue::clear () { _queue.clear(); } + + inline void PriorityQueue::dump () const + { + if (cdebug.enabled(111)) { + cdebug.log(111,1) << "PriorityQueue::dump() size:" << size() << std::endl; + size_t order = 0; + for ( Vertex* v : _queue ) + cdebug.log(111) << "[" << std::setw(3) << order++ << "] " << v << std::endl; + cdebug.tabw(111,-1); + } + } // ------------------------------------------------------------------- @@ -167,7 +183,7 @@ namespace Anabatic { public: void load ( Net* ); void run (); - void propagate (); + bool propagate (); void selectFirstSource (); void toWires (); private: @@ -188,4 +204,8 @@ namespace Anabatic { } // Anabatic namespace. + +GETSTRING_POINTER_SUPPORT(Anabatic::Vertex); +IOSTREAM_POINTER_SUPPORT(Anabatic::Vertex); + #endif // ANABATIC_DIJKSTRA_H diff --git a/anabatic/src/anabatic/Edge.h b/anabatic/src/anabatic/Edge.h index ba3c55f8..2b9fea30 100644 --- a/anabatic/src/anabatic/Edge.h +++ b/anabatic/src/anabatic/Edge.h @@ -63,6 +63,7 @@ namespace Anabatic { inline DbU::Unit getAxis () const; DbU::Unit getAxisMin () const; Interval getSide () const; + inline void incRealOccupancy ( unsigned int ); inline const Flags& flags () const; inline Flags& flags (); inline void invalidate (); @@ -111,6 +112,7 @@ namespace Anabatic { inline GCell* Edge::getSource () const { return _source; } inline GCell* Edge::getTarget () const { return _target; } inline DbU::Unit Edge::getAxis () const { return _axis; } + inline void Edge::incRealOccupancy ( unsigned int delta ) { _realOccupancy+=delta; } inline const Flags& Edge::flags () const { return _flags; } inline Flags& Edge::flags () { return _flags; } inline void Edge::invalidate () { _flags |= Flags::Invalidated; } diff --git a/anabatic/src/anabatic/Edges.h b/anabatic/src/anabatic/Edges.h index 9f7e48ac..bca4b254 100644 --- a/anabatic/src/anabatic/Edges.h +++ b/anabatic/src/anabatic/Edges.h @@ -88,7 +88,9 @@ namespace Anabatic { , _gcell(locator._gcell) , _flags(locator._flags) , _iedge(locator._iedge) - { } + { + cdebug.log(110) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl; + } inline GCell_Edges::GCell_Edges ( const GCell* gcell ) @@ -103,6 +105,12 @@ namespace Anabatic { { } -} // Anabatic namespace. +} // Anabatic namespace. + + +GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges); +GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator); +IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges); +IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator); #endif // ANABATIC_EDGES_H