From 1a338f620cec33774bac8be0e552ed7552ec92c9 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 16 Apr 2018 12:10:48 +0200 Subject: [PATCH] Corrections in the Dijkstra global routing (ripup) mechanism. * Bug: In Anabatic::Dijkstra, the degree of a vertex (the number of neighbors belonging to the same net) was miscalculated. This was leading, in the materialize step to some feed-through vertexes not being broken. Leading in turn to incomplete transformation of the detailed routing. Also in _trackback(), the degree of the first vertex we were backtracking from was not incremented. * Bug: In Anabatic::Dijkstra::materialize(), systematically use GCell::breakGoThrough() on both source and target. This is needed when we are in the ripup phase as both source and target can be go-through. This was also leading to incomplete detailed routing transformation. * Change: In Anabatic::Edge::ripup(), ripup one third of the segments instead of thoses exeeding the global length threshold. This way we are sure to desaturate an edge. Needs to be further calibrated. * Change: In Aanabatic::GCell::breakGoThrough(), no longer return NULL. Return existing gcontact if any. Break if it is a go-through and create a new gcontact in last resort. Maybe rename this function. * New: In Anabatic::Configuration, new parameters: - anabatic.edgeHScaling, to adjust the length of the horizontal edges relative to the vertical ones (this is a ratio). - anabatic.globalIterations, set the maximum number of ripup passes of the global router. * New: In CRL/etc/*/kite.conf, added new parameters anabatic.edgeHScaling and anabatic.globalIterations. * New: In Katana::GlobalRoute::DigitalDistance, take into account the new edgeHScaling factor. Must be used when the capacity of V-edges differs greatly for H-edges (case of AMS 350nm c35b4 for instance). * Bug: In Katana::GlobalRoute::DigitalDistance, the historic cost is computed for an edge length of "1". Must be multiplicated by the current edge length to have any measurable effect. This bug is finally explaining why the ripup was producing the same solutions over and over, the historical cost was negligible! --- anabatic/src/AnabaticEngine.cpp | 9 +++ anabatic/src/Configuration.cpp | 88 ++++++++++++++---------- anabatic/src/Dijkstra.cpp | 38 +++++++---- anabatic/src/Edge.cpp | 89 ++++++++++++++++++------- anabatic/src/GCell.cpp | 5 +- anabatic/src/anabatic/AnabaticEngine.h | 5 +- anabatic/src/anabatic/Configuration.h | 4 ++ crlcore/etc/180/scn6m_deep_09/kite.conf | 2 + crlcore/etc/45/freepdk_45/kite.conf | 2 + crlcore/etc/symbolic/cmos/kite.conf | 2 + crlcore/etc/symbolic/ispd05/kite.conf | 2 + crlcore/etc/symbolic/vsc200/kite.conf | 2 + katana/src/GlobalRoute.cpp | 25 ++++--- 13 files changed, 190 insertions(+), 83 deletions(-) diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 91ae0653..d1c20413 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -627,6 +627,15 @@ namespace Anabatic { cdebug_log(112,1) << "AnabaticEngine::unify(): " << (void*)contact << endl; cdebug_log(112,0) << contact << endl; + for ( Hook* hook : contact->getBodyHook()->getHooks() ) { + RoutingPad* rp = dynamic_cast( hook->getComponent() ); + if (rp) { + cdebug_log(112,0) << "Cannot unify, there is a RoutingPad in this GCell." << endl; + cdebug_tabw(112,-1); + return false; + } + } + for ( Component* slave : contact->getSlaveComponents() ) { Horizontal* h = dynamic_cast( slave ); if (h) { diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 35fcc903..698b2061 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -69,23 +69,25 @@ namespace Anabatic { Configuration::Configuration ( const CellGauge* cg, const RoutingGauge* rg ) - : _gdepthv (ndepth) - , _gdepthh (ndepth) - , _ddepthv (ndepth) - , _ddepthh (ndepth) - , _ddepthc (ndepth) - , _cg (NULL) - , _rg (NULL) - , _extensionCaps () - , _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble()) - , _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt()) - , _globalThreshold(0) - , _allowedDepth (0) - , _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt())) - , _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt())) - , _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH", 9.0)->asDouble()) - , _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK",-10.0)->asDouble()) - , _edgeHInc (Cfg::getParamDouble("anabatic.edgeHInc" , 1.5)->asDouble()) + : _gdepthv (ndepth) + , _gdepthh (ndepth) + , _ddepthv (ndepth) + , _ddepthh (ndepth) + , _ddepthc (ndepth) + , _cg (NULL) + , _rg (NULL) + , _extensionCaps () + , _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble()) + , _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt()) + , _globalThreshold (0) + , _allowedDepth (0) + , _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt())) + , _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt())) + , _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH" , 9.0)->asDouble()) + , _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK" ,-10.0)->asDouble()) + , _edgeHInc (Cfg::getParamDouble("anabatic.edgeHInc" , 1.5)->asDouble()) + , _edgeHScaling (Cfg::getParamDouble("anabatic.edgeHScaling" , 1.0)->asDouble()) + , _globalIterations(Cfg::getParamInt ("anabatic.globalIterations", 10 )->asInt()) { GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() ); @@ -152,23 +154,25 @@ namespace Anabatic { Configuration::Configuration ( const Configuration& other ) - : _gmetalh (other._gmetalh) - , _gmetalv (other._gmetalv) - , _gcontact (other._gcontact) - , _gdepthv (other._gdepthv) - , _gdepthh (other._gdepthh) - , _ddepthv (other._ddepthv) - , _ddepthh (other._ddepthh) - , _ddepthc (other._ddepthc) - , _cg (NULL) - , _rg (NULL) - , _extensionCaps (other._extensionCaps) - , _saturateRatio (other._saturateRatio) - , _globalThreshold(other._globalThreshold) - , _allowedDepth (other._allowedDepth) - , _edgeCostH (other._edgeCostH) - , _edgeCostK (other._edgeCostK) - , _edgeHInc (other._edgeHInc) + : _gmetalh (other._gmetalh) + , _gmetalv (other._gmetalv) + , _gcontact (other._gcontact) + , _gdepthv (other._gdepthv) + , _gdepthh (other._gdepthh) + , _ddepthv (other._ddepthv) + , _ddepthh (other._ddepthh) + , _ddepthc (other._ddepthc) + , _cg (NULL) + , _rg (NULL) + , _extensionCaps (other._extensionCaps) + , _saturateRatio (other._saturateRatio) + , _globalThreshold (other._globalThreshold) + , _allowedDepth (other._allowedDepth) + , _edgeCostH (other._edgeCostH) + , _edgeCostK (other._edgeCostK) + , _edgeHInc (other._edgeHInc) + , _edgeHScaling (other._edgeHScaling) + , _globalIterations(other._globalIterations) { GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() ); @@ -188,15 +192,19 @@ namespace Anabatic { Configuration* Configuration::clone () const { return new Configuration(*this); } + bool Configuration::isTwoMetals () const { return _rg->isTwoMetals(); } + bool Configuration::isHV () const { return _rg->isHV(); } + bool Configuration::isVH () const { return _rg->isVH(); } + bool Configuration::isGMetal ( const Layer* layer ) const { return (layer and ((layer == _gmetalh) or (layer == _gmetalv))); } @@ -204,15 +212,19 @@ namespace Anabatic { bool Configuration::isGContact ( const Layer* layer ) const { return (layer and (layer == _gcontact)); } + const Layer* Configuration::getGContactLayer () const { return _gcontact; } + const Layer* Configuration::getGHorizontalLayer () const { return _gmetalh; } + const Layer* Configuration::getGVerticalLayer () const { return _gmetalv; } + size_t Configuration::getDepth () const { return _rg->getDepth(); } @@ -379,6 +391,14 @@ namespace Anabatic { { return _edgeHInc; } + float Configuration::getEdgeHScaling () const + { return _edgeHScaling; } + + + int Configuration::getGlobalIterations () const + { return _globalIterations; } + + DbU::Unit Configuration::isOnRoutingGrid ( RoutingPad* rp ) const { Box ab = rp->getCell()->getBoundingBox(); diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 9927622c..3c0f6f3b 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -1308,7 +1308,7 @@ namespace Anabatic { + " " + DbU::getValueString(_gcell->getXMax()) + " " + DbU::getValueString(_gcell->getYMax()) + "]" //+ " rps:" + getString(_rpCount) - //+ " deg:" + getString(_degree) + + " deg:" + getString(_degree) + " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None") + " d:" + ((_distance == unreached) ? "unreached" : ((_distance == unreachable) ? "unreachable" @@ -1515,7 +1515,7 @@ namespace Anabatic { vertex->setStamp ( _stamp ); vertex->setConnexId ( _connectedsId ); vertex->setBranchId ( 0 ); - vertex->setDegree ( 1 ); + vertex->setDegree ( 0 ); vertex->setRpCount ( 0 ); vertex->setFrom ( NULL ); @@ -1524,6 +1524,15 @@ namespace Anabatic { vertex->clearRestriction(); _targets.insert( vertex ); + } + + for ( Vertex* vertex : connecteds ) { + int degree = 0; + for ( Edge* edge : vertex->getGCell()->getEdges() ) { + Vertex* neighbor = vertex->getNeighbor( edge ); + if (vertex->hasValidStamp() and neighbor->hasValidStamp()) ++degree; + } + vertex->setDegree( degree ); cdebug_log(112,0) << "| Add: " << vertex << endl; } } @@ -1960,6 +1969,7 @@ namespace Anabatic { void Dijkstra::_traceback ( Vertex* current ) { cdebug_log(112,1) << "Dijkstra::_traceback() " << _net << " branchId:" << _sources.size() << endl; + cdebug_log(112,0) << "From: " << current << endl; int branchId = _sources.size(); _toSources( current, _connectedsId ); @@ -1970,6 +1980,7 @@ namespace Anabatic { if (current->isAnalog()) { _initiateUpdateIntervals( current ); } else { + current->incDegree(); current = current->getPredecessor(); isfirst = false; } @@ -2023,12 +2034,20 @@ namespace Anabatic { //cerr << "state: " << state << endl; for ( Vertex* startVertex : _sources ) { - if (not startVertex->getFrom()) continue; + cdebug_log(112,0) << "@ " << startVertex << endl; + + if (not startVertex->getFrom()) { + cdebug_log(112,0) << "> skip: no getFrom()." << endl; + continue; + } if ( not startVertex->hasGContact(_net) and not startVertex->getRpCount() and (startVertex->getDegree() < 3) - and not startVertex->isAxisTarget() ) continue; + and not startVertex->isAxisTarget() ) { + cdebug_log(112,0) << "> skip: not a good starting point." << endl; + continue; + } Vertex* source = startVertex; while ( source ) { @@ -2048,7 +2067,7 @@ namespace Anabatic { cdebug_log(112,0) << "| " << target << endl; if (target->getConnexId() < 0) { - cdebug_log(112,0) << "> " << "break (abort: false start)." << endl; + cdebug_log(112,0) << "> break (abort: false start)." << endl; break; } @@ -2080,15 +2099,10 @@ namespace Anabatic { cdebug_log(112,0) << "| " << target << endl; } - Contact* sourceContact = source->getGContact( _net ); - Contact* targetContact = target->hasGContact( _net ); + Contact* sourceContact = source->breakGoThrough( _net ); + Contact* targetContact = target->breakGoThrough( _net ); Segment* segment = NULL; - if (not targetContact) { - if (target->getFrom()) targetContact = target->getGContact( _net ); - else targetContact = target->breakGoThrough( _net ); - } - cdebug_log(112,0) << "> aligneds.front():" << aligneds.front() << " isHorizontal():" << aligneds.front()->isHorizontal() << endl; diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index be0f1f36..ac02747c 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -17,6 +17,7 @@ #include #include "hurricane/Error.h" #include "hurricane/Segment.h" +#include "hurricane/RoutingPad.h" #include "hurricane/DataBase.h" #include "hurricane/Technology.h" #include "anabatic/Edge.h" @@ -53,6 +54,7 @@ namespace Anabatic { using std::cerr; using std::endl; using Hurricane::Error; + using Hurricane::RoutingPad; Name Edge::_extensionName = "Anabatic::Edge"; @@ -233,19 +235,50 @@ namespace Anabatic { cdebug_log(112,0) << "| Tbb " << _target->getBoundingBox() << endl; cdebug_log(112,0) << "| " << segment << endl; - Contact* contact = dynamic_cast( segment->getSource() ); - cdebug_log(112,0) << "| source" << contact << endl; - if (contact) { - if ( (_source->isStdCellRow() and _source->getBoundingBox().contains(contact->getCenter())) - or (_target->isStdCellRow() and _target->getBoundingBox().contains(contact->getCenter())) ) - return true; - } - contact = dynamic_cast( segment->getTarget() ); - cdebug_log(112,0) << "| target" << contact << endl; - if (contact) { - if ( (_source->isStdCellRow() and _source->getBoundingBox().contains(contact->getCenter())) - or (_target->isStdCellRow() and _target->getBoundingBox().contains(contact->getCenter())) ) - return true; + if (Session::getRoutingGauge()->isTwoMetals()) { + Contact* contact = dynamic_cast( segment->getSource() ); + cdebug_log(112,0) << "| source" << contact << endl; + if (contact) { + if ( (_source->isStdCellRow() and _source->getBoundingBox().contains(contact->getCenter())) + or (_target->isStdCellRow() and _target->getBoundingBox().contains(contact->getCenter())) ) + return true; + } + + contact = dynamic_cast( segment->getTarget() ); + cdebug_log(112,0) << "| target" << contact << endl; + if (contact) { + if ( (_source->isStdCellRow() and _source->getBoundingBox().contains(contact->getCenter())) + or (_target->isStdCellRow() and _target->getBoundingBox().contains(contact->getCenter())) ) + return true; + } + } else { + // This part is not used (yet). We don't call isEnding() when running + // in over-the-cell mode. + Contact* contact = dynamic_cast( segment->getSource() ); + cdebug_log(112,0) << "| source" << contact << endl; + if (contact) { + for ( Hook* hook : contact->getBodyHook()->getHooks() ) { + if (dynamic_cast(hook->getComponent())) { + if ( _source->getBoundingBox().contains(contact->getCenter()) + or _target->getBoundingBox().contains(contact->getCenter()) ) + return true; + break; + } + } + } + + contact = dynamic_cast( segment->getTarget() ); + cdebug_log(112,0) << "| target" << contact << endl; + if (contact) { + for ( Hook* hook : contact->getBodyHook()->getHooks() ) { + if (dynamic_cast(hook->getComponent())) { + if ( _source->getBoundingBox().contains(contact->getCenter()) + or _target->getBoundingBox().contains(contact->getCenter()) ) + return true; + break; + } + } + } } return false; } @@ -328,8 +361,8 @@ namespace Anabatic { sort( _segments.begin(), _segments.end(), SortSegmentByLength() ); - for ( size_t i=0 ; i<_segments.size() ; ) { - if (Session::getRoutingGauge()->isTwoMetals()) { + if (Session::getRoutingGauge()->isTwoMetals()) { + for ( size_t i=0 ; i<_segments.size() ; ) { if (not isEnding(_segments[i])) { NetData* netData = anabatic->getNetData( _segments[i]->getNet() ); if (netData->isGlobalRouted()) ++netCount; @@ -337,16 +370,26 @@ namespace Anabatic { continue; } ++i; - } else { - if (_segments[i]->getLength() >= globalThreshold) { - NetData* netData = anabatic->getNetData( _segments[i]->getNet() ); - if (netData->isGlobalRouted()) ++netCount; - anabatic->ripup( _segments[i], Flags::Propagate ); - } else { - ++i; - } } + } else { + size_t truncate = (size_t)( (getCapacity()*2) / 3 ); + while ( _segments.size() > truncate ) { + NetData* netData = anabatic->getNetData( _segments[truncate]->getNet() ); + if (netData->isGlobalRouted()) ++netCount; + anabatic->ripup( _segments[truncate], Flags::Propagate ); + } + + // for ( size_t i=0 ; i<_segments.size() ; ) { + // if (_segments[i]->getLength() >= globalThreshold) { + // NetData* netData = anabatic->getNetData( _segments[i]->getNet() ); + // if (netData->isGlobalRouted()) ++netCount; + // anabatic->ripup( _segments[i], Flags::Propagate ); + // } else { + // ++i; + // } + // } } + return netCount; } diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index fb75ea6e..9275b03f 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -475,6 +475,9 @@ namespace Anabatic { Contact* GCell::breakGoThrough ( Net* net ) { + Contact* gcontact = hasGContact( net ); + if (gcontact) return gcontact; + for ( Edge* edge : _eastEdges ) { for ( Segment* segment : edge->getSegments() ) { if (segment->getNet() == net) @@ -489,7 +492,7 @@ namespace Anabatic { } } - return NULL; + return getGContact( net ); } diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index 2b89e4ef..e6363930 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -381,8 +381,9 @@ namespace Anabatic { inline void AnabaticEngine::removeOv ( Edge* edge ) { - for ( auto iedge = _ovEdges.begin() ; iedge != _ovEdges.end() ; ++iedge ) - if (*iedge == edge) { _ovEdges.erase(iedge); break; } + for ( auto iedge = _ovEdges.begin() ; iedge != _ovEdges.end() ; ++iedge ) { + if (*iedge == edge) { _ovEdges.erase(iedge); return; } + } } diff --git a/anabatic/src/anabatic/Configuration.h b/anabatic/src/anabatic/Configuration.h index ed9bc5dc..a488dea0 100644 --- a/anabatic/src/anabatic/Configuration.h +++ b/anabatic/src/anabatic/Configuration.h @@ -120,6 +120,8 @@ namespace Anabatic { float getEdgeCostH () const; float getEdgeCostK () const; float getEdgeHInc () const; + float getEdgeHScaling () const; + int getGlobalIterations () const; DbU::Unit isOnRoutingGrid ( RoutingPad* ) const; bool selectRpComponent ( RoutingPad* ) const; virtual void print ( Cell* ) const; @@ -148,6 +150,8 @@ namespace Anabatic { float _edgeCostH; float _edgeCostK; float _edgeHInc; + float _edgeHScaling; + int _globalIterations; private: Configuration& operator= ( const Configuration& ) = delete; void _setTopRoutingLayer ( Name name ); diff --git a/crlcore/etc/180/scn6m_deep_09/kite.conf b/crlcore/etc/180/scn6m_deep_09/kite.conf index 7ea03ab9..64ebd8ba 100644 --- a/crlcore/etc/180/scn6m_deep_09/kite.conf +++ b/crlcore/etc/180/scn6m_deep_09/kite.conf @@ -27,6 +27,8 @@ parametersTable = \ , ("anabatic.edgeWidth" ,TypeInt ,4 ) , ("anabatic.edgeCostH" ,TypeDouble ,9.0 ) , ("anabatic.edgeCostK" ,TypeDouble ,-10.0 ) + , ("anabatic.edgeHScaling" ,TypeDouble ,1.0 ) + , ("anabatic.globalIterations" ,TypeInt ,10 , { 'min':1, 'max':100 } ) , ("anabatic.gcell.displayMode" ,TypeEnumerate ,1 , { 'values':( ("Boundary" , 1) , ("Density" , 2) ) } diff --git a/crlcore/etc/45/freepdk_45/kite.conf b/crlcore/etc/45/freepdk_45/kite.conf index 5202f26d..824a1a5c 100644 --- a/crlcore/etc/45/freepdk_45/kite.conf +++ b/crlcore/etc/45/freepdk_45/kite.conf @@ -31,6 +31,8 @@ parametersTable = \ , ("anabatic.edgeWidth" ,TypeInt ,4 ) , ("anabatic.edgeCostH" ,TypeDouble ,9.0 ) , ("anabatic.edgeCostK" ,TypeDouble ,-10.0 ) + , ("anabatic.edgeHScaling" ,TypeDouble ,1.0 ) + , ("anabatic.globalIterations" ,TypeInt ,10 , { 'min':1, 'max':100 } ) , ("anabatic.gcell.displayMode" ,TypeEnumerate ,1 , { 'values':( ("Boundary" , 1) , ("Density" , 2) ) } diff --git a/crlcore/etc/symbolic/cmos/kite.conf b/crlcore/etc/symbolic/cmos/kite.conf index f408cd58..6c6821ed 100644 --- a/crlcore/etc/symbolic/cmos/kite.conf +++ b/crlcore/etc/symbolic/cmos/kite.conf @@ -27,6 +27,8 @@ parametersTable = \ , ("anabatic.edgeWidth" ,TypeInt ,4 ) , ("anabatic.edgeCostH" ,TypeDouble ,9.0 ) , ("anabatic.edgeCostK" ,TypeDouble ,-10.0 ) + , ("anabatic.edgeHScaling" ,TypeDouble ,1.0 ) + , ("anabatic.globalIterations" ,TypeInt ,10 , { 'min':1, 'max':100 } ) , ("anabatic.gcell.displayMode" ,TypeEnumerate ,1 , { 'values':( ("Boundary" , 1) , ("Density" , 2) ) } diff --git a/crlcore/etc/symbolic/ispd05/kite.conf b/crlcore/etc/symbolic/ispd05/kite.conf index 221311bd..1844876a 100644 --- a/crlcore/etc/symbolic/ispd05/kite.conf +++ b/crlcore/etc/symbolic/ispd05/kite.conf @@ -21,6 +21,8 @@ parametersTable = \ , ("kite.localRipupLimit" ,TypeInt ,9 , { 'min':1 } ) , ("kite.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) , ("kite.longGlobalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) + , ("anabatic.edgeHScaling" ,TypeDouble ,1.0 ) + , ("anabatic.globalIterations" ,TypeInt ,10 , { 'min':1, 'max':100 } ) ) diff --git a/crlcore/etc/symbolic/vsc200/kite.conf b/crlcore/etc/symbolic/vsc200/kite.conf index 913b62c4..62bd6b2c 100644 --- a/crlcore/etc/symbolic/vsc200/kite.conf +++ b/crlcore/etc/symbolic/vsc200/kite.conf @@ -21,6 +21,8 @@ parametersTable = \ , ("kite.localRipupLimit" ,TypeInt ,9 , { 'min':1 } ) , ("kite.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) , ("kite.longGlobalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) + , ("anabatic.edgeHScaling" ,TypeDouble ,1.0 ) + , ("anabatic.globalIterations" ,TypeInt ,10 , { 'min':1, 'max':100 } ) ) diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index d8446bc1..fb80e7bc 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -41,7 +41,7 @@ namespace { class DigitalDistance { public: - inline DigitalDistance ( float h, float k ); + inline DigitalDistance ( float h, float k, float hScaling ); inline void setNet ( Net* ); DbU::Unit operator() ( const Vertex* source ,const Vertex* target,const Edge* edge ) const; private: @@ -49,11 +49,12 @@ namespace { // "KNIK, routeur global pour la plateforme Coriolis", p. 52. float _h; float _k; + float _hScaling; Net* _net; }; - inline DigitalDistance::DigitalDistance ( float h, float k ) : _h(h), _k(k), _net(NULL) { } + inline DigitalDistance::DigitalDistance ( float h, float k, float hScaling ) : _h(h), _k(k), _hScaling(hScaling), _net(NULL) { } inline void DigitalDistance::setNet ( Net* net ) { _net = net; } @@ -92,10 +93,10 @@ namespace { or (source->getGCell()->isStdCellRow() and target->getGCell()->isChannelRow()) ) edgeDistance *= 10.0; - float hvDistort = (edge->isHorizontal()) ? 1.0 : 1.0 ; - float distance = (float)source->getDistance() - + (congestionCost + viaCost) * edgeDistance * hvDistort - + edge->getHistoricCost(); + float hvScaling = (edge->isHorizontal()) ? _hScaling : 1.0 ; + float distance + = (float)source->getDistance() + + (congestionCost + viaCost + edge->getHistoricCost()) * edgeDistance * hvScaling; // Edge* sourceFrom = source->getFrom(); // if (sourceFrom) { @@ -198,13 +199,15 @@ namespace Katana { startMeasures(); cmess1 << " o Running global routing." << endl; - float edgeHInc = getConfiguration()->getEdgeHInc(); + float edgeHInc = getConfiguration()->getEdgeHInc(); + size_t globalIterations = getConfiguration()->getGlobalIterations();; openSession(); Dijkstra* dijkstra = new Dijkstra ( this ); DigitalDistance* distance = dijkstra->setDistance( DigitalDistance( getConfiguration()->getEdgeCostH() - , getConfiguration()->getEdgeCostK() )); + , getConfiguration()->getEdgeCostK() + , getConfiguration()->getEdgeHScaling() )); const vector& ovEdges = getOvEdges(); if (isChannelMode()) @@ -234,13 +237,13 @@ namespace Katana { // openSession(); netCount = 0; - if (iteration < 10 - 1) { + if (iteration < globalIterations - 1) { size_t iEdge = 0; while ( iEdge < ovEdges.size() ) { Edge* edge = ovEdges[iEdge]; netCount += edge->ripup(); - if (ovEdges.empty()) break; + if (iEdge >= ovEdges.size()) break; if (ovEdges[iEdge] == edge) { cerr << Error( "AnabaticEngine::globalRoute(): Unable to ripup enough segments of edge:\n" " %s" @@ -260,7 +263,7 @@ namespace Katana { resumeMeasures(); ++iteration; - } while ( (netCount > 0) and (iteration < 10) ); + } while ( (netCount > 0) and (iteration < globalIterations) ); stopMeasures(); printMeasures( "Dijkstra" );