diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index f157ffd3..488eb766 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -16,6 +16,7 @@ #include #include +#include "hurricane/Bug.h" #include "hurricane/Error.h" #include "hurricane/RegularLayer.h" #include "hurricane/Horizontal.h" @@ -35,6 +36,7 @@ namespace Anabatic { using std::cout; using std::endl; using std::ostringstream; + using Hurricane::Bug; using Hurricane::Error; using Hurricane::RegularLayer; using Hurricane::Component; @@ -129,6 +131,27 @@ namespace Anabatic { } +// ------------------------------------------------------------------- +// Class : "Anabatic::NetData". + + NetData::NetData ( Net* net ) + : _net (net) + , _state (NetRoutingExtension::get(net)) + , _searchArea() + , _rpCount (0) + , _sparsity (0) + , _flags () + { + if (_state and _state->isMixedPreRoute()) return; + + for ( RoutingPad* rp : _net->getRoutingPads() ) { + _searchArea.merge( rp->getBoundingBox() ); + ++_rpCount; + } + _update(); + } + + // ------------------------------------------------------------------- // Class : "Anabatic::AnabaticEngine". @@ -156,13 +179,14 @@ namespace Anabatic { , _matrix () , _gcells () , _ovEdges () + , _netOrdering () + , _netDatas () , _viewer (NULL) , _flags (Flags::DestroyBaseContact) , _stamp (-1) , _densityMode (MaxDensity) , _autoSegmentLut () , _autoContactLut () - , _netRoutingStates() , _blockageNet (cell->getNet("blockagenet")) { _matrix.setCell( cell, _configuration->getSliceHeight() ); @@ -197,6 +221,7 @@ namespace Anabatic { AnabaticEngine::~AnabaticEngine () { delete _configuration; + for ( pair data : _netDatas ) delete data.second; } @@ -318,6 +343,23 @@ namespace Anabatic { } + void AnabaticEngine::setupNetDatas () + { + size_t oindex = _netOrdering.size(); + for ( Net* net : _cell->getNets() ) { + if (_netDatas.find(net->getId()) != _netDatas.end()) continue; + _netOrdering.push_back( new NetData(net) ); + } + + for ( ; oindex < _netOrdering.size() ; ++oindex ) { + _netDatas.insert( make_pair( _netOrdering[oindex]->getNet()->getId() + , _netOrdering[oindex] ) ); + } + + sort( _netOrdering.begin(), _netOrdering.end(), SparsityOrder() ); + } + + size_t AnabaticEngine::getNetsFromEdge ( const Edge* edge, NetSet& nets ) { size_t count = 0; @@ -351,31 +393,26 @@ namespace Anabatic { } - NetRoutingState* AnabaticEngine::getRoutingState ( Net* net, unsigned int flags ) + NetData* AnabaticEngine::getNetData ( Net* net, unsigned int flags ) { - NetRoutingState* state = NetRoutingExtension::get( net ); + NetData* data = NULL; + NetDatas::iterator idata = _netDatas.find( net->getId() ); + if (idata == _netDatas.end()) { + data = new NetData( net ); + _netDatas.insert( make_pair(net->getId(),data) ); + _netOrdering.push_back( data ); + // cerr << Bug( "AnabaticEngine::getNetData() - %s is missing in NetDatas table." + // , getString(net->getName()).c_str() + // ) << endl; + // return NULL; + } else + data = idata->second; - if (state) { - NetRoutingStates::iterator istate = _netRoutingStates.find( net->getId() ); - if (istate != _netRoutingStates.end()) { - if (istate->second != state) { - cerr << Error( "AnabaticEngine::getRoutingStates() - %s incoherency between property and LUT:\n" - " Property:%x vs. LUT:%x, re-init LUT from property." - , getString(net->getName()).c_str() - , (void*)state - , (void*)(istate->second)) << endl; - _netRoutingStates.insert( make_pair(net->getId(), state) ); - } - return state; - } - } else { - if (not (flags & Flags::Create)) return NULL; - - state = NetRoutingExtension::create( net ); + if ((flags & Flags::Create) and not data->getNetRoutingState()) { + data->setNetRoutingState( NetRoutingExtension::create(net) ); } - _netRoutingStates.insert( make_pair(net->getId(), state) ); - return state; + return data; } @@ -517,7 +554,9 @@ namespace Anabatic { void AnabaticEngine::ripup ( Segment* seed, Flags flags ) { - DebugSession::open( seed->getNet(), 112, 120 ); + Net* net = seed->getNet(); + + DebugSession::open( net, 112, 120 ); cdebug_log(112,1) << "AnabaticEngine::ripup(): " << seed << endl; Contact* end0 = NULL; @@ -594,6 +633,8 @@ namespace Anabatic { if (end0) unify( end0 ); if (end1) unify( end1 ); + getNetData( net )->setGlobalRouted( false ); + cdebug_tabw(111,-1); DebugSession::close(); } diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 7c402a2c..f6ff0c47 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -556,6 +556,8 @@ namespace Anabatic { _queue.clear(); _materialize(); + _anabatic->getNetData( _net )->setGlobalRouted( true ); + cdebug_tabw(112,-1); DebugSession::close(); } @@ -645,10 +647,10 @@ namespace Anabatic { { cdebug_log(112,1) << "Dijkstra::_checkEdges()" << endl; - for ( Vertex* vertex : _vertexes ) { - for ( Edge* edge : vertex->getGCell()->getEdges(Flags::EastSide|Flags::NorthSide) ) { - } - } + // for ( Vertex* vertex : _vertexes ) { + // for ( Edge* edge : vertex->getGCell()->getEdges(Flags::EastSide|Flags::NorthSide) ) { + // } + // } cdebug_tabw(112,-1); } diff --git a/anabatic/src/GlobalRoute.cpp b/anabatic/src/GlobalRoute.cpp index 298dadcf..e71a7b08 100644 --- a/anabatic/src/GlobalRoute.cpp +++ b/anabatic/src/GlobalRoute.cpp @@ -138,54 +138,50 @@ namespace Anabatic { Session::open( this ); setupSpecialNets(); setupPreRouteds (); + setupNetDatas(); Session::close(); startMeasures(); cmess1 << " o Running global routing..." << endl; - NetSet netsToRoute; - for ( Net* net : cell->getNets() ) { - NetRoutingState* state = getRoutingState( net ); - if (state) { - if (state->isMixedPreRoute()) continue; - } - - netsToRoute.insert( net ); - } - UpdateSession::open(); Dijkstra* dijkstra = new Dijkstra ( this ); dijkstra->setDistance( DigitalDistance( getConfiguration()->getEdgeCostH() , getConfiguration()->getEdgeCostK() ) ); size_t iteration = 0; - while ( not netsToRoute.empty() and (iteration < 5) ) { - cmess2 << " [" << setw(3) << iteration << "] nets:" - << left << setw(6) << netsToRoute.size() << right; + size_t netCount = 0; + do { + cmess2 << " [" << setw(3) << iteration << "] nets:"; - for ( Net* net : netsToRoute ) { - dijkstra->load( net ); + netCount = 0; + for ( NetData* netData : _netOrdering ) { + if (netData->isGlobalRouted()) continue; + + dijkstra->load( netData->getNet() ); dijkstra->run(); + ++netCount; } + cmess2 << left << setw(6) << netCount << right; - netsToRoute.clear(); const vector& ovEdges = getOvEdges(); cmess2 << " ovEdges:" << ovEdges.size(); + netCount = 0; while ( not ovEdges.empty() ) { Edge* ovEdge = ovEdges[0]; - NetSet netsToUnroute; vector segments = ovEdge->getSegments(); for ( Segment* segment : segments ) { - netsToRoute.insert( segment->getNet() ); - cerr << segment->getNet() << endl; + NetData* netData = getNetData( segment->getNet() ); + if (netData->isGlobalRouted()) ++netCount; + ripup( segment, Flags::Propagate ); } } - cmess2 << " ripup:" << netsToRoute.size(); + cmess2 << " ripup:" << netCount; stopMeasures(); cmess2 << " " << setw(10) << Timer::getStringTime (_timer.getCombTime()) @@ -216,7 +212,7 @@ namespace Anabatic { #endif ++iteration; - } + } while ( (netCount > 0) and (iteration < 5) ); stopMeasures(); printMeasures( "Dijkstra" ); diff --git a/anabatic/src/PreRouteds.cpp b/anabatic/src/PreRouteds.cpp index 341929c7..ea9498e0 100644 --- a/anabatic/src/PreRouteds.cpp +++ b/anabatic/src/PreRouteds.cpp @@ -56,8 +56,10 @@ namespace Anabatic { } if (af->isBLOCKAGE(net->getName())) excludedType = "BLOCKAGE"; if (excludedType) { - NetRoutingState* state = getRoutingState( net, Flags::Create ); + NetData* ndata = getNetData( net, Flags::Create ); + NetRoutingState* state = ndata->getNetRoutingState(); state->setFlags( NetRoutingState::Fixed ); + ndata->setGlobalRouted( true ); } } } @@ -138,9 +140,11 @@ namespace Anabatic { } if (isFixed or isPreRouted or (rpCount < 2)) { - NetRoutingState* state = getRoutingState( net, Flags::Create ); + NetData* ndata = getNetData( net, Flags::Create ); + NetRoutingState* state = ndata->getNetRoutingState(); state->unsetFlags( NetRoutingState::AutomaticGlobalRoute ); state->setFlags ( NetRoutingState::ManualGlobalRoute ); + ndata->setGlobalRouted( true ); if (rpCount < 2) state->setFlags ( NetRoutingState::Unconnected ); diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index 8b1159b9..f5d5be3b 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -51,10 +51,6 @@ namespace Anabatic { using Hurricane::NetRoutingState; using CRL::ToolEngine; - - typedef std::set NetSet; - typedef std::map NetRoutingStates; - class AnabaticEngine; @@ -103,9 +99,73 @@ namespace Anabatic { typedef std::shared_ptr GCellsUnder; +// ------------------------------------------------------------------- +// Class : "Anabatic::NetData". + + class NetData { + public: + NetData ( Net* ); + inline bool isGlobalRouted () const; + inline bool isMixedPreRoute () const; + inline Net* getNet () const; + inline NetRoutingState* getNetRoutingState () const; + inline const Box& getSearchArea () const; + inline DbU::Unit getHalfPerimeter () const; + inline size_t getRpCount () const; + inline DbU::Unit getSparsity () const; + inline void setNetRoutingState ( NetRoutingState* ); + inline void setSearchArea ( Box ); + inline void setGlobalRouted ( bool ); + inline void setRpCount ( size_t ); + private: + NetData ( const NetData& ); + NetData& operator= ( const NetData& ); + inline void _update (); + private: + Net* _net; + NetRoutingState* _state; + Box _searchArea; + size_t _rpCount; + DbU::Unit _sparsity; + Flags _flags; + }; + + + inline bool NetData::isGlobalRouted () const { return _flags & Flags::GlobalRouted; } + inline bool NetData::isMixedPreRoute () const { return (_state) ? _state->isMixedPreRoute() : false; } + inline Net* NetData::getNet () const { return _net; } + inline NetRoutingState* NetData::getNetRoutingState () const { return _state; } + inline const Box& NetData::getSearchArea () const { return _searchArea; } + inline DbU::Unit NetData::getHalfPerimeter () const { return (_searchArea.isEmpty()) ? 0.0 : (_searchArea.getWidth()+_searchArea.getHeight()); } + inline size_t NetData::getRpCount () const { return _rpCount; } + inline void NetData::setNetRoutingState ( NetRoutingState* state ) { _state=state; } + inline DbU::Unit NetData::getSparsity () const { return _sparsity; } + inline void NetData::setGlobalRouted ( bool state ) { _flags.set(Flags::GlobalRouted,state); } + inline void NetData::setRpCount ( size_t count ) { _rpCount=count; _update(); } + + + inline void NetData::_update () + { if (_rpCount) _sparsity=getHalfPerimeter()/_rpCount; else _sparsity=0; } + + + class SparsityOrder { + public: + inline bool operator() ( const NetData* lhs, const NetData* rhs ) const + { + if (lhs->isMixedPreRoute() != rhs->isMixedPreRoute()) return lhs->isMixedPreRoute(); + if (lhs->getSparsity() != rhs->getSparsity() ) return lhs->getSparsity() < rhs->getSparsity(); + return lhs->getNet()->getId() < rhs->getNet()->getId(); + } + }; + + // ------------------------------------------------------------------- // Class : "Anabatic::AnabaticEngine". + typedef std::set NetSet; + typedef std::map NetDatas; + + class AnabaticEngine : public ToolEngine { public: enum DensityMode { AverageHVDensity=1 // Average between all densities. @@ -141,6 +201,9 @@ namespace Anabatic { inline void setDensityMode ( unsigned int ); inline void addOv ( Edge* ); inline void removeOv ( Edge* ); + inline const NetDatas& getNetDatas () const; + NetData* getNetData ( Net*, unsigned int flags=Flags::NoFlags ); + void setupNetDatas (); // Dijkstra related functions. inline int getStamp () const; inline int incStamp (); @@ -162,8 +225,6 @@ namespace Anabatic { inline size_t getSaturateRp () const; inline DbU::Unit getExtensionCap () const; inline Net* getBlockageNet () const; - inline const NetRoutingStates& getNetRoutingStates () const; - NetRoutingState* getRoutingState ( Net*, unsigned int flags=Flags::NoFlags ); void updateDensity (); size_t checkGCellDensities (); inline void setGlobalThreshold ( DbU::Unit ); @@ -233,13 +294,14 @@ namespace Anabatic { Matrix _matrix; vector _gcells; vector _ovEdges; + vector _netOrdering; + NetDatas _netDatas; CellViewer* _viewer; Flags _flags; int _stamp; unsigned int _densityMode; AutoSegmentLut _autoSegmentLut; AutoContactLut _autoContactLut; - NetRoutingStates _netRoutingStates; Net* _blockageNet; }; @@ -274,7 +336,7 @@ namespace Anabatic { inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); } inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; } inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); } - inline const NetRoutingStates& AnabaticEngine::getNetRoutingStates () const { return _netRoutingStates; } + inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; } inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); } inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; } diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 9d98ce18..35a670cc 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -44,6 +44,8 @@ namespace Anabatic { static const unsigned int DestroyGCell = (1 << 7); static const unsigned int DestroyBaseContact = (1 << 8); static const unsigned int DestroyBaseSegment = (1 << 9); + // Flags for NetDatas objects states only. + static const unsigned int GlobalRouted = (1 << 5); // Masks. static const unsigned int WestSide = Horizontal|Target; static const unsigned int EastSide = Horizontal|Source;