diff --git a/katabatic/src/GCell.cpp b/katabatic/src/GCell.cpp index c974afed..27894994 100644 --- a/katabatic/src/GCell.cpp +++ b/katabatic/src/GCell.cpp @@ -80,6 +80,18 @@ namespace Katabatic { } +// ------------------------------------------------------------------- +// Class : "Kite::GCell::CompareByKey". +// +// lhs < rhs --> true + + + bool GCell::CompareByKey::operator() ( const GCell* lhs, const GCell* rhs ) + { + return lhs->getKey() < rhs->getKey(); + } + + // ------------------------------------------------------------------- // Class : "Katabatic::GCell". @@ -107,6 +119,7 @@ namespace Katabatic { , _routedSegmentCount(0) , _saturated (false) , _invalid (true) + , _key (0.0,_index) { for ( size_t i=0 ; i<_depth ; i++ ) { _blockages [i] = 0.0; @@ -719,7 +732,7 @@ namespace Katabatic { } - bool GCell::stepDesaturate ( unsigned int depth, set& globalNets ) + bool GCell::stepDesaturate ( unsigned int depth, set& globalNets, AutoSegment*& moved ) { #if defined(CHECK_DETERMINISM) cerr << "Order: stepDesaturate [" << getIndex() << "] depth:" << depth << endl; @@ -761,6 +774,7 @@ namespace Katabatic { #endif //cerr << "Move up " << (*isegment) << endl; (*isegment)->changeDepth ( depth+2, false, false ); + moved = (*isegment); updateDensity (); @@ -976,6 +990,73 @@ namespace Katabatic { } +// ------------------------------------------------------------------- +// Class : "Kite::DyKeyQueue". + + + DyKeyQueue::DyKeyQueue ( unsigned int depth ) + : _depth (depth) + , _map () + , _requests() + { } + + + DyKeyQueue::DyKeyQueue ( unsigned int depth, const vector& gcells ) + : _depth (depth) + , _map () + , _requests() + { + for ( size_t i=0 ; i& DyKeyQueue::getGCells () const + { return _map; } + + + void DyKeyQueue::invalidate ( GCell* gcell ) + { push ( gcell ); } + + + void DyKeyQueue::push ( GCell* gcell ) + { _requests.insert ( gcell ); } + + + void DyKeyQueue::revalidate () + { + std::set::iterator iinserted; + std::set::iterator igcell = _requests.begin(); + for ( ; igcell != _requests.end() ; ++igcell ) { + iinserted = _map.find(*igcell); + if ( iinserted != _map.end() ) { + _map.erase ( iinserted ); + } + (*igcell)->updateKey (_depth); + _map.insert ( *igcell ); + } + _requests.clear (); + } + + + GCell* DyKeyQueue::pop () + { + if ( _map.empty() ) return NULL; + std::set::iterator igcell = _map.begin(); + GCell* gcell = *igcell; + _map.erase ( igcell ); + } + + // ------------------------------------------------------------------- // Utilities. diff --git a/katabatic/src/LayerAssign.cpp b/katabatic/src/LayerAssign.cpp index c499a145..4dbf3eb6 100644 --- a/katabatic/src/LayerAssign.cpp +++ b/katabatic/src/LayerAssign.cpp @@ -88,7 +88,10 @@ namespace Katabatic { } - void KatabaticEngine::_desaturate ( unsigned int depth, set& globalNets ) + void KatabaticEngine::_desaturate ( unsigned int depth + , set& globalNets + , unsigned long& total + , unsigned long& globals ) { if ( depth+2 >= Session::getRoutingGauge()->getDepth() ) { cerr << Warning("Katabatic::_desaturate(): %s, no remaining upper layers." @@ -100,16 +103,43 @@ namespace Katabatic { cmess1 << " o Desaturate layer " << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl; - vector gcells = *(_gcellGrid->getGCellVector()); + //vector gcells = *(_gcellGrid->getGCellVector()); + DyKeyQueue queue ( depth, *(_gcellGrid->getGCellVector()) ); + AutoSegment* segment = NULL; + vector invalidateds; bool optimized = true; while ( optimized ) { optimized = false; - sort ( gcells.begin(), gcells.end(), GCell::CompareByDensity(depth) ); - for ( size_t i=0 ; iisSaturated ( depth ) ) break; + //sort ( gcells.begin(), gcells.end(), GCell::CompareByDensity(depth) ); + queue.revalidate (); + + std::set::const_iterator igcell = queue.getGCells().begin(); + size_t i = 0; + for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) { + if ( not (*igcell)->isSaturated ( depth ) ) { + ltrace(190) << "STOP desaturated: @" << i << " " << *igcell << endl; + for ( ; igcell!=queue.getGCells().end() ; ++igcell ) { + if ( (*igcell)->isSaturated ( depth ) ) { + cerr << "[ERROR] Still saturated: @" << i << " " << *igcell << endl; + break; + } + } + break; + } + + ltrace(190) << "step desaturate @: " << i << " " << *igcell << endl; + + optimized = (*igcell)->stepDesaturate ( depth, globalNets, segment ); + + if ( segment ) { + ++total; ++globals; + segment->getGCells ( invalidateds ); + for ( size_t j=0 ; jstepDesaturate ( depth, globalNets ); if ( optimized ) break; } } @@ -246,8 +276,8 @@ namespace Katabatic { Session::revalidate (); for ( int i=0 ; i < 3 ; i++ ) { - _desaturate ( 1, globalNets ); - _desaturate ( 2, globalNets ); + _desaturate ( 1, globalNets, total, global ); + _desaturate ( 2, globalNets, total, global ); globalNets.clear (); diff --git a/katabatic/src/katabatic/GCell.h b/katabatic/src/katabatic/GCell.h index d87012e8..959049bd 100644 --- a/katabatic/src/katabatic/GCell.h +++ b/katabatic/src/katabatic/GCell.h @@ -79,6 +79,21 @@ namespace Katabatic { private: size_t _depth; }; + class CompareByKey { + public: + bool operator() ( const GCell* lhs, const GCell* rhs ); + }; + class Key { + private: + float _density; + unsigned int _index; + public: + inline Key ( float, unsigned int ); + inline float getDensity () const; + inline unsigned int getIndex () const; + inline void update ( GCell*, unsigned int ); + friend bool operator< ( const Key&, const Key& ); + }; public: // Static Utilities. @@ -130,6 +145,7 @@ namespace Katabatic { AutoSegments getVStopSegments (); inline AutoSegments getStartSegments ( unsigned int direction ); inline AutoSegments getStopSegments ( unsigned int direction ); + inline const Key& getKey () const; size_t checkDensity () const; bool checkEdgeSaturation ( float threshold ) const; // Modifiers. @@ -144,8 +160,9 @@ namespace Katabatic { void removeContact ( AutoContact* ); void updateContacts (); size_t updateDensity (); + inline void updateKey ( unsigned int depth ); void desaturate ( unsigned int depth, set& ); - bool stepDesaturate ( unsigned int depth, set& ); + bool stepDesaturate ( unsigned int depth, set&, AutoSegment*& moved ); inline void invalidate (); // Inspector Management. Record* _getRecord () const; @@ -175,6 +192,7 @@ namespace Katabatic { unsigned int _routedSegmentCount; bool _saturated; bool _invalid; + Key _key; protected: // Constructors & Destructors. @@ -197,7 +215,7 @@ namespace Katabatic { }; -// Inline Functions. +// GCell Inline Functions. inline bool GCell::isSaturated () const { return _saturated; } inline bool GCell::isValid () const { return !_invalid; } inline GCellGrid* GCell::getGCellGrid () const { return _gcellGrid; } @@ -215,6 +233,8 @@ namespace Katabatic { inline unsigned int GCell::getRoutedCount () const { return _routedSegmentCount; } inline string GCell::_getTypeName () const { return _TName("GCell"); } inline void GCell::invalidate () { _invalid = true; } + inline const GCell::Key& GCell::getKey () const { return _key; } + inline void GCell::updateKey ( unsigned int depth ) { _key.update(this,depth); } inline AutoSegments GCell::getStartSegments ( unsigned int direction ) { return (direction&Constant::Horizontal) ? getHStartSegments() : getVStartSegments(); } @@ -238,6 +258,43 @@ namespace Katabatic { { invalidate(); _contacts.push_back(contact); } +// GCell::Key Inline Functions. + inline GCell::Key::Key ( float density, unsigned int index ) : _density(density), _index(index) {} + inline float GCell::Key::getDensity () const { return _density; } + inline unsigned int GCell::Key::getIndex () const { return _index; } + inline void GCell::Key::update ( GCell* gcell, unsigned int depth ) + { _density=gcell->getDensity(depth); _index=gcell->getIndex(); } + + inline bool operator< ( const GCell::Key& lhs, const GCell::Key& rhs ) + { + float difference = Hurricane::roundfp ( lhs._density - rhs._density ); + if ( difference != 0.0 ) return (difference > 0.0); + + return ( lhs._index < rhs._index ); + } + + +// ------------------------------------------------------------------- +// Class : "DyKeyQueue". + + + class DyKeyQueue { + public: + DyKeyQueue ( unsigned int depth ); + DyKeyQueue ( unsigned int depth, const std::vector& ); + ~DyKeyQueue (); + const std::set& getGCells () const; + GCell* pop (); + void push ( GCell* ); + void invalidate ( GCell* ); + void revalidate (); + private: + unsigned int _depth; + std::set _map; + std::set _requests; + }; + + // ------------------------------------------------------------------- // Utilities. diff --git a/katabatic/src/katabatic/KatabaticEngine.h b/katabatic/src/katabatic/KatabaticEngine.h index 055debef..c3a14ab8 100644 --- a/katabatic/src/katabatic/KatabaticEngine.h +++ b/katabatic/src/katabatic/KatabaticEngine.h @@ -163,7 +163,7 @@ namespace Katabatic { void _loadNetGlobalRouting ( Net* ); void _alignate ( Net* ); void _canonize ( Net* ); - void _desaturate ( unsigned int depth, set& ); + void _desaturate ( unsigned int depth, set&, unsigned long& total, unsigned long& globals ); void _layerAssignByLength ( unsigned long& total, unsigned long& global, set& ); void _layerAssignByLength ( Net* , unsigned long& total, unsigned long& global, set& ); void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set& );