From 5b94fe1917e45a7e5685216bc8e29c7329d507c9 Mon Sep 17 00:00:00 2001 From: EricLaoGitHub Date: Tue, 14 Feb 2017 15:47:22 +0100 Subject: [PATCH] In LoadGlobalRouting.cpp: - [Modified] Minor bug fixed in Dijkstra: - [Add]: Global routing for analog circuits is enhanced by intervals definition to estimate more precise wirelengh and wire positions. The distance calculation for analog cases has been moved to the horus tool in AnalogGlobalRoute.h. --- anabatic/src/Dijkstra.cpp | 1230 +++++++++++++++++++++++----- anabatic/src/LoadGlobalRouting.cpp | 13 +- anabatic/src/anabatic/Dijkstra.h | 125 ++- 3 files changed, 1163 insertions(+), 205 deletions(-) diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index fb0fc1bb..76ac44fe 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -15,6 +15,7 @@ #include +#include #include "hurricane/Error.h" #include "hurricane/Net.h" #include "hurricane/RoutingPad.h" @@ -26,6 +27,10 @@ #include "anabatic/AnabaticEngine.h" #include "anabatic/Dijkstra.h" +#include "hurricane/DataBase.h" +#include "hurricane/viewer/CellViewer.h" +#include "hurricane/Technology.h" + namespace Anabatic { @@ -43,6 +48,76 @@ namespace Anabatic { using Hurricane::DebugSession; + +// ------------------------------------------------------------------- +// Class : "Anabatic::IntervalC". + + + IntervalC::IntervalC() + { + _min = Vertex::unreached; + _max = Vertex::unreached; + _axis = Vertex::unreached; + } + + + IntervalC::~IntervalC() {} + + + IntervalC* IntervalC::create() + { + return new IntervalC(); + } + + + void IntervalC::set ( DbU::Unit min, DbU::Unit max, DbU::Unit axis ) + { + _min = min; + _max = max; + _axis = axis; + setiSet(); + } + + + void IntervalC::setRange( DbU::Unit vmin, DbU::Unit vmax ) + { + if (vmin < vmax){ + _min = vmin; + _max = vmax; + setiSet(); + } else { + _min = vmax; + _max = vmin; + setiSet(); + } + } + + + void IntervalC::extendMin( DbU::Unit vmin ) + { + if (_min > vmin) _min = vmin; + } + + + void IntervalC::extendMax( DbU::Unit vmax ) + { + if (_max < vmax) _max = vmax; + } + + void IntervalC::print() const + { + cerr << "[IntervalC]: min: " << DbU::getValueString(_min) << ", max:" << DbU::getValueString(_min) << ", axis:" << DbU::getValueString(_axis) << endl; + } + + + void IntervalC::reset() + { + _min = Vertex::unreached; + _max = Vertex::unreached; + _axis = Vertex::unreached; + _flags &= ~iSet; + } + // ------------------------------------------------------------------- // Class : "Anabatic::Vertex". @@ -55,179 +130,70 @@ namespace Anabatic { { return _stamp == getAnabatic()->getStamp(); } - void Vertex::setPathPoint( DbU::Unit x, DbU::Unit y ) +/*void Vertex::setPathPoint( DbU::Unit x, DbU::Unit y ) { _xpath = x; _ypath = y; - } - - - string Vertex::_getString () const - { - if (not _gcell) { - string s = ""; - return s; - } - - string s = "getXMin()) - + "-" + DbU::getValueString(_gcell->getYMin()) - + "-" + DbU::getValueString(_gcell->getXMax()) - + "-" + DbU::getValueString(_gcell->getYMax()) + ")" - + " rps:" + getString(_rpCount) - + " deg:" + getString(_degree) - + " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None") - + " 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; - } - - - void Vertex::notify ( Vertex* vertex, unsigned int flags ) - { - cdebug_log(111,0) << "Vertex::notify() " << vertex << endl; - // Take into account the GCell modification here. - } - - -// ------------------------------------------------------------------- -// Class : "Anabatic::Dijkstra". - - - Dijkstra::Mode::~Mode () - { } - - - string Dijkstra::Mode::_getTypeName () const - { return "Anabatic::Dijkstra::Mode"; } - - - string Dijkstra::Mode::_getString () const - { - string s = ""; - s += (_flags & Standart ) ? 'S' : '-'; - s += (_flags & Monotonic) ? 'M' : '-'; - - return s; - } - - - DbU::Unit Dijkstra::_distance ( const Vertex* current, const Vertex* vneighbour, const Edge* e ) - { - cdebug_log(112,0) << "Calcul _distance "<< endl; - cdebug_log(112,0) << "current : "<< current->hasRestrictions() << ", " << current << endl; - cdebug_log(112,0) << "vneighbour: "<< vneighbour->hasRestrictions() << ", " << vneighbour << endl; - - DbU::Unit distance = current->getDistance(); - DbU::Unit addedDistance = 0; - - /* - if ((current->getGCell()->isMatrix())&&(vneighbour->getGCell()->isMatrix())) addedDistance = e->getDistance(); - else { - Point pneighbour = _getNextPathPoint( current, vneighbour ); - addedDistance = abs(pneighbour.getX() - current->getXPath()) + abs(pneighbour.getY() - current->getXPath()); }*/ - addedDistance = e->getDistance(); - distance += addedDistance; - if ( (current->hasRestrictions()) || (vneighbour->hasRestrictions()) ) { - if (isRestricted(current, vneighbour)) { - distance = Vertex::unreachable; - } - } - - if ((!current->getGCell()->isMatrix()) || (!vneighbour->getGCell()->isMatrix())){ - if (distance != Vertex::unreachable) { - if (current->getFrom() != NULL){ - GCell* gprevious = current->getFrom()->getOpposite(current->getGCell()); - GCell* gcurrent = current->getGCell(); - GCell* gneighbour = vneighbour->getGCell(); - float cost = 0; - if ( ( gcurrent->isNorth(gprevious) && (!gcurrent->isSouth(gneighbour)) ) - || ( gcurrent->isEast (gprevious) && (!gcurrent->isWest (gneighbour)) ) - || ( gcurrent->isSouth(gprevious) && (!gcurrent->isNorth(gneighbour)) ) - || ( gcurrent->isWest (gprevious) && (!gcurrent->isEast (gneighbour)) ) - ){ - distance += cost * addedDistance; - } + bool Vertex::hasRP( Net* net ) const + { + if (getGCell() != NULL ){ + Cell* cell = getGCell()->getAnabatic()->getCell(); + RoutingPad* rp = NULL; + for ( Component* component : cell->getComponentsUnder(getGCell()->getBoundingBox().inflate(-1)) ){ + rp = dynamic_cast( component ); + if (rp) { + if (rp->getNet() == net) return true; } } - } - // Edge* aFrom = a->getFrom(); - // if (aFrom) { - // distance += (aFrom->isHorizontal() xor e->isHorizontal()) ? 3.0 : 0.0; - // } - return distance; + } + return false; } - Point Dijkstra::_getNextPathPoint( const Vertex* current, const Vertex* next ) + bool Vertex::hasVRP( Net* net ) const { - if ((current == NULL) || (next == NULL)){ - cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unvalid NULL argument."<< endl; - return Point(0,0); - } - - if (next->getGCell()->isMatrix()) return Point(next->getGCell()->getXCenter(), next->getGCell()->getYCenter()); - if (next->getGCell()->isDevice()) return next->getPathPoint(); - - if (next->isNorth(current)){ - if (next->getGCell()->isHChannel()){ - return Point(current->getXPath(), next->getGCell()->getYCenter()); - } else if ( (next->getGCell()->isVChannel()) || (next->getGCell()->isStrut())) { - return Point(current->getXPath(), next->getGCell()->getYMax()); - } else { - cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unknown GCell type."<< endl; - return Point(0,0); + if (getGCell() != NULL){ + Cell* cell = getGCell()->getAnabatic()->getCell(); + RoutingPad* rp = NULL; + for ( Component* component : cell->getComponentsUnder(getGCell()->getBoundingBox().inflate(-1)) ){ + rp = dynamic_cast( component ); + if (rp) { + if (rp->getNet() == net) break; + } } - - } else if (next->isSouth(current)){ - if (next->getGCell()->isHChannel()){ - return Point(current->getXPath(), next->getGCell()->getYCenter()); - } else if ( (next->getGCell()->isVChannel()) || (next->getGCell()->isStrut())) { - return Point(current->getXPath(), next->getGCell()->getYMin()); - } else { - cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unknown GCell type."<< endl; - return Point(0,0); + if (rp) { + Vertical* v = dynamic_cast(rp->_getEntityAsSegment()); + if (v) { return true; } } - - } else if (next->isEast (current)){ - if (next->getGCell()->isHChannel()){ - return Point(next->getGCell()->getXMax(), current->getYPath()); - } else if ( (next->getGCell()->isVChannel()) || (next->getGCell()->isStrut())) { - return Point(next->getGCell()->getXCenter(), current->getYPath()); - } else { - cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unknown GCell type."<< endl; - return Point(0,0); - } - - } else if (next->isWest (current)){ - if (next->getGCell()->isHChannel()){ - return Point(next->getGCell()->getXMin(), current->getYPath()); - } else if ( (next->getGCell()->isVChannel()) || (next->getGCell()->isStrut())) { - return Point(next->getGCell()->getXCenter(), current->getYPath()); - } else { - cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unknown GCell type."<< endl; - return Point(0,0); - } - } else { - cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Vertex are not neighbours."<< endl; - return Point(0,0); - } + } + return false; } - bool Dijkstra::isRestricted ( const Vertex* v1, const Vertex* v2 ) + bool Vertex::hasHRP( Net* net ) const + { + if (getGCell() != NULL){ + Cell* cell = getGCell()->getAnabatic()->getCell(); + RoutingPad* rp = NULL; + for ( Component* component : cell->getComponentsUnder(getGCell()->getBoundingBox().inflate(-1)) ){ + rp = dynamic_cast( component ); + if (rp) { + if (rp->getNet() == net) break; + } + } + if (rp) { + Horizontal* h = dynamic_cast(rp->_getEntityAsSegment()); + if (h) { return true; } + } + } + return false; + } + + + bool Vertex::isRestricted ( const Vertex* v1, const Vertex* v2 ) { bool restricted = true; GCell* c1 = v1->getGCell(); @@ -270,6 +236,756 @@ namespace Anabatic { } + Point Vertex::getNextPathPoint2( const Vertex* vcurr, const Vertex* vnext ) + { + //cdebug_log(112,0) << "Point Dijkstra::getNextPathPoint( const Vertex* current, const Vertex* next )" << endl; + if ((vcurr == NULL) || (vnext == NULL)){ + //cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unvalid NULL argument."<< endl; + return Point(0,0); + } + + if (vnext->getGCell()->isMatrix()) { + cerr << "This is not planned" << endl; + return Point(vnext->getGCell()->getXCenter(), vnext->getGCell()->getYCenter()); + } + + Point pcurr = vcurr->getPathPoint(vnext); + GCell* gnext = vnext->getGCell(); + GCell* gcurr = vcurr->getGCell(); + DbU::Unit x = 0; + DbU::Unit y = 0; + + + if (vnext->isV()){ + //cdebug_log(112,0) << "Case next: Vertical: " << vnext->isiSet() << endl; //", d:" << vnext->getDistance() << endl; + if ((vnext->isiSet())&&(vnext->hasValidStamp())){ + //cdebug_log(112,0) << "Case set" << endl; + x = vnext->getIAxis(); + if (vcurr->isNorth(vnext)) y = vnext->getIMin(); + else if (vcurr->isSouth(vnext)) y = vnext->getIMax(); + else if ((vcurr->isWest(vnext))||(vcurr->isEast(vnext))) { + if ( pcurr.getY() > vnext->getIMax() ) y = vnext->getIMax(); + else if ( pcurr.getY() < vnext->getIMin() ) y = vnext->getIMin(); + else y = pcurr.getY(); + } else cdebug_log(112,0) << "Error(Point Vertex::getNextPathPoint2(...) const: Something is wrong.1" << endl; + } else { + //cdebug_log(112,0) << "Case not set" << endl; + if (vcurr->isNorth(vnext)){ + y = gcurr->getYMax(); + if (pcurr.getX() < gnext->getXMin()) x = gnext->getXMin(); + else if (pcurr.getX() > gnext->getXMax()) x = gnext->getXMax(); + else x = pcurr.getX(); + } else if (vcurr->isSouth(vnext)){ + y = gcurr->getYMin(); + if (pcurr.getX() < gnext->getXMin()) x = gnext->getXMin(); + else if (pcurr.getX() > gnext->getXMax()) x = gnext->getXMax(); + else x = pcurr.getX(); + } else if (vcurr->isWest(vnext)){ + x = gcurr->getXMin(); + if (pcurr.getY() < gnext->getYMin()) y = gnext->getYMin(); + else if (pcurr.getY() > gnext->getYMax()) y = gnext->getYMax(); + else y = pcurr.getY(); + + } else if (vcurr->isEast(vnext)){ + x = gcurr->getXMax(); + if (pcurr.getY() < gnext->getYMin()) y = gnext->getYMin(); + else if (pcurr.getY() > gnext->getYMax()) y = gnext->getYMax(); + else y = pcurr.getY(); + } else cdebug_log(112,0) << "Error(Point Vertex::getNextPathPoint2(...) const: Something is wrong.2" << endl; + } + + } else if (vnext->isH()) { + //cdebug_log(112,0) << "Case next: Horizontal: " << vnext->isiSet() << endl; //", d:" << vnext->getDistance() << endl; + + if ((vnext->isiSet())&&(vnext->hasValidStamp())){ + //cdebug_log(112,0) << "Case set" << endl; + y = vnext->getIAxis(); + if (vcurr->isEast (vnext)) x = vnext->getIMin(); + else if (vcurr->isWest (vnext)) x = vnext->getIMax(); + else if ((vcurr->isNorth(vnext))||(vcurr->isSouth(vnext))) { + if ( pcurr.getX() > vnext->getIMax() ) x = vnext->getIMax(); + else if ( pcurr.getX() < vnext->getIMin() ) x = vnext->getIMin(); + else x = pcurr.getX(); + } else cdebug_log(112,0) << "Error(Point Vertex::getNextPathPoint2(...) const: Something is wrong.3" << endl; + + } else { + //cdebug_log(112,0) << "Case not set" << endl; + if (vcurr->isNorth(vnext)){ + y = gcurr->getYMax(); + if (pcurr.getX() < gnext->getXMin()) x = gnext->getXMin(); + else if (pcurr.getX() > gnext->getXMax()) x = gnext->getXMax(); + else x = pcurr.getX(); + } else if (vcurr->isSouth(vnext)){ + y = gcurr->getYMin(); + if (pcurr.getX() < gnext->getXMin()) x = gnext->getXMin(); + else if (pcurr.getX() > gnext->getXMax()) x = gnext->getXMax(); + else x = pcurr.getX(); + } else if (vcurr->isWest(vnext)){ + x = gcurr->getXMin(); + if (pcurr.getY() < gnext->getYMin()) y = gnext->getYMin(); + else if (pcurr.getY() > gnext->getYMax()) y = gnext->getYMax(); + else y = pcurr.getY(); + + } else if (vcurr->isEast(vnext)){ + x = gcurr->getXMax(); + if (pcurr.getY() < gnext->getYMin()) y = gnext->getYMin(); + else if (pcurr.getY() > gnext->getYMax()) y = gnext->getYMax(); + else y = pcurr.getY(); + } else cdebug_log(112,0) << "Error(Point Vertex::getNextPathPoint2(...) const: Something is wrong.4" << endl; + } + } else { + cdebug_log(112,0) << "Error(Point Vertex::getNextPathPoint2(...) const: Something is wrong.5" << endl; + } + return Point(x,y); + } + +/* + Point Vertex::getNextPathPoint( const Vertex* current, const Vertex* next ) + { + //cdebug_log(112,0) << "Point Dijkstra::getNextPathPoint( const Vertex* current, const Vertex* next )" << endl; + if ((current == NULL) || (next == NULL)){ + //cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unvalid NULL argument."<< endl; + return Point(0,0); + } + + if (next->getGCell()->isMatrix()) return Point(next->getGCell()->getXCenter(), next->getGCell()->getYCenter()); + if (next->getGCell()->isDevice()) return next->getPathPoint(); + + + //cdebug_log(112,0) << "getBranchId() :" << current->getBranchId() << endl; + //cdebug_log(112,0) << "curr hasvalidstamp:" << current->hasValidStamp() << endl; + //cdebug_log(112,0) << "next hasvalidstamp:" << next->hasValidStamp() << endl; + //if ( ((current->getBranchId() != 0))||(current->getDistance() != 0)||(current->getGCell()->isDevice())){ + //cdebug_log(112,0) << "Case: distance > 0 OR isDevice" << endl; + if (current->isNorth(next)) { + //cdebug_log(112,0) << "North" << endl; + if ( current->getXPath() < next->getGCell()->getXMin() ) + return Point(next->getGCell()->getXMin(), next->getGCell()->getYMin()); + else if ( current->getXPath() > next->getGCell()->getXMax() ) + return Point(next->getGCell()->getXMax(), next->getGCell()->getYMin()); + else + return Point(current->getXPath(), next->getGCell()->getYMin()); + + } else if (current->isSouth(next)) { + //cdebug_log(112,0) << "South" << endl; + if ( current->getXPath() < next->getGCell()->getXMin() ) + return Point(next->getGCell()->getXMin(), next->getGCell()->getYMax()); + else if ( current->getXPath() > next->getGCell()->getXMax() ) + return Point(next->getGCell()->getXMax(), next->getGCell()->getYMax()); + else + return Point(current->getXPath(), next->getGCell()->getYMax()); + + } else if (current->isEast (next)) { + //cdebug_log(112,0) << "East" << endl; + if ( current->getYPath() < next->getGCell()->getYMin() ) + return Point(next->getGCell()->getXMin(), next->getGCell()->getYMin()); + else if ( current->getYPath() > next->getGCell()->getYMax() ) + return Point(next->getGCell()->getXMin(), next->getGCell()->getYMax()); + else + return Point(next->getGCell()->getXMin(), current->getYPath()); + + } else if (current->isWest (next)) { + //cdebug_log(112,0) << "West" << endl; + if ( current->getYPath() < next->getGCell()->getYMin() ) + return Point(next->getGCell()->getXMax(), next->getGCell()->getYMin()); + else if ( current->getYPath() > next->getGCell()->getYMax() ) + return Point(next->getGCell()->getXMax(), next->getGCell()->getYMax()); + else + return Point(next->getGCell()->getXMax(), current->getYPath()); + } else { + cdebug_log(112,0) << "Error(Point Vertex::_getNextPathPoint( const Vertex*, const Vertex* )): GCells are not next to each other." << endl; + return Point(0,0); + } + } else { + cdebug_log(112,0) << "Case: distance = 0 AND isNOTDevice" << endl; + if (current->isNorth(next)) { + cdebug_log(112,0) << "North" << endl; + return Point( ( std::max(current->getGCell()->getXMin() + , next->getGCell()->getXMin() + ) + + std::min(current->getGCell()->getXMax() + , next->getGCell()->getXMax() + ) + )/2 + , next->getGCell()->getYMin() + ); + } else if (current->isSouth(next)) { + cdebug_log(112,0) << "South" << endl; + return Point( ( std::max(current->getGCell()->getXMin() + , next->getGCell()->getXMin() ) + + std::min(current->getGCell()->getXMax() + , next->getGCell()->getXMax() ) + )/2 + , next->getGCell()->getYMax() + ); + } else if (current->isEast (next)) { + cdebug_log(112,0) << "East" << endl; + return Point( next->getGCell()->getXMin(), ( std::max(current->getGCell()->getYMin() + , next->getGCell()->getYMin() ) + + std::min(current->getGCell()->getYMax() + , next->getGCell()->getYMax() ) + )/2 + ); + } else if (current->isWest (next)) { + cdebug_log(112,0) << "West" << endl; + return Point( next->getGCell()->getXMin(), ( std::max(current->getGCell()->getYMin() + , next->getGCell()->getYMin() ) + + std::min(current->getGCell()->getYMax() + , next->getGCell()->getYMax() ) + )/2 + ); + } else { + cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): GCells are not next to each other." << endl; + return Point(0,0); + } + } + }*/ + + +/*void Vertex::resetPathPoint( Point ponderedPoint ) + { + DbU::Unit x; + DbU::Unit y; + GCell* g = getGCell(); + + if (ponderedPoint.getX() < g->getXMin()) x = g->getXMin(); + else if (ponderedPoint.getX() > g->getXMax()) x = g->getXMax(); + else x = ponderedPoint.getX(); + if (ponderedPoint.getY() < g->getYMin()) y = g->getYMin(); + else if (ponderedPoint.getY() > g->getYMax()) y = g->getYMax(); + else y = ponderedPoint.getY(); + setPathPoint(x,y); + }*/ + + + Point Vertex::getPathPoint( const Vertex* next ) const + { + //cdebug_log(112,0) << "Point Vertex::getPathPoint( const Vertex* next ) const" << endl; + + GCell* gcurr = getGCell(); + GCell* gnext = next->getGCell(); + DbU::Unit x = 0; + DbU::Unit y = 0; + + + if (gcurr->isDevice ()){ + //cdebug_log(112,0) << "Case device" << endl; + if (isH()){ + //cdebug_log(112,0) << "hinterval: " << DbU::getValueString(_interv->getAxis()) << endl; + y = _interv->getAxis(); + if ((gnext->getXMax() < gcurr->getXMin())||(isWest (next))) { + x = _interv->getMin(); + } + else if ((gnext->getXMin() > gcurr->getXMax())||(isEast (next))) { + x = _interv->getMax(); + } + else { + x = (max(gnext->getXMin(), gcurr->getXMin())+min(gnext->getXMax(), gcurr->getXMax()))/2 ; + } + } else if (isV()){ + //cdebug_log(112,0) << "vinterval" << endl; + x = _interv->getAxis(); + if ((gnext->getYMax() < gcurr->getYMin())||(isSouth(next))) y = _interv->getMin(); + else if ((gnext->getYMin() > gcurr->getYMax())||(isNorth(next))) y = _interv->getMax(); + else y = (max(gnext->getYMin(), gcurr->getYMin())+min(gnext->getYMax(), gcurr->getYMax()))/2 ; + } else { + cdebug_log(112,0) << "Error(Point Vertex::getPathPoint( Vertex * vertex ) const: Something is wrong." << endl; + return Point(0,0); + } + } else if (isH()) { + //cdebug_log(112,0) << "Case horizontal" << endl; + GCell* gprev = getFrom()->getOpposite(gcurr); + Vertex* prev = gprev->getObserver(GCell::Observable::Vertex); + + if (prev->isH()){ + //cdebug_log(112,0) << "prev is H" << endl; + if (isNorth(prev)){ + x = (max(_intervfrom->getMin(), gcurr->getXMin())+min(_intervfrom->getMax(), gcurr->getXMax()))/2 ; + y = gcurr->getYMax(); + } else if (isSouth(prev)){ + x = (max(_intervfrom->getMin(), gcurr->getXMin())+min(_intervfrom->getMax(), gcurr->getXMax()))/2 ; + y = gcurr->getYMin(); + } else if (isWest (prev)){ + x = gcurr->getXMin(); + y = _intervfrom->getAxis(); + } else if (isEast (prev)){ + x = gcurr->getXMax(); + y = _intervfrom->getAxis(); + } else { + cdebug_log(112,0) << "Error(Point Vertex::getPathPoint( Vertex * vertex ) const: Something is wrong." << endl; + return Point(0,0); + } + } else if (prev->isV()){ + //cdebug_log(112,0) << "prev is V" << endl; + if (isNorth(prev)){ + //cdebug_log(112,0) << "1" << endl; + x = _intervfrom->getAxis(); + y = gcurr->getYMax(); + } else if (isSouth(prev)){ + //cdebug_log(112,0) << "2" << endl; + x = _intervfrom->getAxis(); + y = gcurr->getYMin(); + } else if (isWest (prev)){ + //cdebug_log(112,0) << "3" << endl; + x = gcurr->getXMin(); + if ( _intervfrom->getMin() > gcurr->getYMax() ){ + y = gcurr->getYMax(); + } else if ( _intervfrom->getMax() < gcurr->getYMin() ){ + y = gcurr->getYMin(); + } else { + y = (max(_intervfrom->getMin(), gcurr->getYMin())+min(_intervfrom->getMax(), gcurr->getYMax()))/2 ; + } + } else if (isEast (prev)){ + //cdebug_log(112,0) << "4" << endl; + x = gcurr->getXMax(); + if ( _intervfrom->getMin() > gcurr->getYMax() ){ + y = gcurr->getYMax(); + } else if ( _intervfrom->getMax() < gcurr->getYMin() ){ + y = gcurr->getYMin(); + } else { + y = (max(_intervfrom->getMin(), gcurr->getYMin())+min(_intervfrom->getMax(), gcurr->getYMax()))/2 ; + } + } else { + cdebug_log(112,0) << "Error(Point Vertex::getPathPoint( Vertex * vertex ) const: Something is wrong." << endl; + return Point(0,0); + } + //cdebug_log(112,0) << "x: " << DbU::getValueString(x) << ", y:" << DbU::getValueString(y) << endl; + } else { + cdebug_log(112,0) << "Error(Point Vertex::getPathPoint( Vertex * vertex ) const: Something is wrong." << endl; + return Point(0,0); + } + } else if (isV()) { + //cdebug_log(112,0) << "Case V" << endl; + GCell* gprev = getFrom()->getOpposite(gcurr); + Vertex* prev = gprev->getObserver(GCell::Observable::Vertex); + + if (prev->isH()){ + //cdebug_log(112,0) << "prev is H" << endl; + if (isNorth(prev)){ + y = gcurr->getYMax(); + if ( _intervfrom->getMin() > gcurr->getXMax() ){ + x = gcurr->getXMax(); + } else if ( _intervfrom->getMax() < gcurr->getXMin() ){ + x = gcurr->getXMin(); + } else { + x = (max(_intervfrom->getMin(), gcurr->getXMin())+min(_intervfrom->getMax(), gcurr->getXMax()))/2 ; + } + } else if (isSouth(prev)){ + y = gcurr->getYMin(); + if ( _intervfrom->getMin() > gcurr->getXMax() ){ + x = gcurr->getXMax(); + } else if ( _intervfrom->getMax() < gcurr->getXMin() ){ + x = gcurr->getXMin(); + } else { + x = (max(_intervfrom->getMin(), gcurr->getXMin())+min(_intervfrom->getMax(), gcurr->getXMax()))/2 ; + } + } else if (isWest (prev)){ + x = gcurr->getXMin(); + y = _intervfrom->getAxis(); + } else if (isEast (prev)){ + x = gcurr->getXMax(); + y = _intervfrom->getAxis(); + } else { + cdebug_log(112,0) << "Error(Point Vertex::getPathPoint( Vertex * vertex ) const: Something is wrong." << endl; + return Point(0,0); + } + } else if (prev->isV()){ + //cdebug_log(112,0) << "prev is V" << endl; + if (isNorth(prev)){ + x = _intervfrom->getAxis(); + y = gcurr->getYMax(); + } else if (isSouth(prev)){ + x = _intervfrom->getAxis(); + y = gcurr->getYMin(); + } else if (isWest (prev)){ + x = gcurr->getXMin(); + y = (max(_intervfrom->getMin(), gcurr->getYMin())+min(_intervfrom->getMax(), gcurr->getYMax()))/2 ; + } else if (isEast (prev)){ + x = gcurr->getXMax(); + y = (max(_intervfrom->getMin(), gcurr->getYMin())+min(_intervfrom->getMax(), gcurr->getYMax()))/2 ; + } else { + cdebug_log(112,0) << "Error(Point Vertex::getPathPoint( Vertex * vertex ) const: Something is wrong." << endl; + return Point(0,0); + } + } else { + cdebug_log(112,0) << "Error(Point Vertex::getPathPoint( Vertex * vertex ) const: Something is wrong." << endl; + return Point(0,0); + } + } else { + cdebug_log(112,0) << "Error(Point Vertex::getPathPoint( Vertex * vertex ) const: Something is wrong." << endl; + return Point(0,0); + } + return Point(x,y); + } + + + bool Vertex::isH() const + { + GCell* gcell = getGCell(); + if (gcell->isDevice()) return _interv->isH(); + else if (gcell->isHChannel()) return true; + else if (gcell->isStrut()) return gcell->getWidth() > gcell->getHeight(); + else return false; + } + + + bool Vertex::isV() const + { + GCell* gcell = getGCell(); + if (gcell->isDevice()) return _interv->isV(); + else if (gcell->isVChannel()) return true; + else if (gcell->isStrut()) return gcell->getWidth() < gcell->getHeight(); + else return false; + } + + + void Vertex::setIntervals ( Vertex* vcurr ) + { + Point pcurr = vcurr->getPathPoint(this); + Point pnext = Vertex::getNextPathPoint2( vcurr, this ); + cdebug_log(112,0) << "void Vertex::setIntervals ( Vertex* vcurr )" << endl; + cdebug_log(112,0) << "Pcurrent : X:" << DbU::getValueString(pcurr.getX()) << ", Y:" << DbU::getValueString(pcurr.getY()) << endl; + cdebug_log(112,0) << "Pneighbour: X:" << DbU::getValueString(pnext.getX()) << ", Y:" << DbU::getValueString(pnext.getY()) << endl; + DbU::Unit min, max, axis; + + if (vcurr->isH()){ + cdebug_log(112,0) << "case vcurr: Horizontal" << endl; + if ((vcurr->isiSet())&&(vcurr->hasValidStamp())){ + cdebug_log(112,0) << "case set" << endl; + if (vcurr->getIMin() > pnext.getX()) { + min = pnext.getX(); + max = vcurr->getIMax(); + axis = vcurr->getIAxis(); + } else if (vcurr->getIMax() < pnext.getX()) { + min = vcurr->getIMin(); + max = pnext.getX(); + axis = vcurr->getIAxis(); + } else { + min = vcurr->getIMin(); + max = vcurr->getIMax(); + axis = vcurr->getIAxis(); + } + } else { + cdebug_log(112,0) << "case not set" << endl; + axis = pcurr.getY(); + if (pcurr.getX() < pnext.getX()){ + min = pcurr.getX(); + max = pnext.getX(); + } else { + max = pcurr.getX(); + min = pnext.getX(); + } + } + + } else if (vcurr->isV()){ + cdebug_log(112,0) << "case vcurr: Vertical" << endl; + + if ((vcurr->isiSet())&&(vcurr->hasValidStamp())){ + cdebug_log(112,0) << "case set" << endl; + if (vcurr->getIMin() > pnext.getY()) { + min = pnext.getY(); + max = vcurr->getIMax(); + axis = vcurr->getIAxis(); + } else if (vcurr->getIMax() < pnext.getY()) { + min = vcurr->getIMin(); + max = pnext.getY(); + axis = vcurr->getIAxis(); + } else { + min = vcurr->getIMin(); + max = vcurr->getIMax(); + axis = vcurr->getIAxis(); + } + } else { + cdebug_log(112,0) << "case not set" << endl; + axis = pcurr.getX(); + if (pcurr.getY() < pnext.getY()){ + min = pcurr.getY(); + max = pnext.getY(); + } else { + max = pcurr.getY(); + min = pnext.getY(); + } + } + + } else { + cdebug_log(112,0) << "Error(void Vertex::setIntervals(...)): Something is wrong." << endl; + return; + } + cdebug_log(112,0) << "IntervFrom => min: " << DbU::getValueString(min) << ", max: " << DbU::getValueString(max) << ", axis:" << DbU::getValueString(axis) << endl; + + _intervfrom->set( min, max, axis ); + } + + + void Vertex::resetIntervals() + { + _interv->reset(); + _intervfrom->reset(); + } + + + string Vertex::_getString () const + { + if (not _gcell) { + string s = ""; + return s; + } + + string s = "getXMin()) + + "-" + DbU::getValueString(_gcell->getYMin()) + + "-" + DbU::getValueString(_gcell->getXMax()) + + "-" + DbU::getValueString(_gcell->getYMax()) + ")" + /*+ " rps:" + getString(_rpCount) + + " deg:" + getString(_degree) + + " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None")*/ + + " 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; + } + + + void Vertex::notify ( Vertex* vertex, unsigned int flags ) + { + cdebug_log(111,0) << "Vertex::notify() " << vertex << endl; + // Take into account the GCell modification here. + } + + +// ------------------------------------------------------------------- +// Class : "Anabatic::Dijkstra". + + + Dijkstra::Mode::~Mode () + { } + + + string Dijkstra::Mode::_getTypeName () const + { return "Anabatic::Dijkstra::Mode"; } + + + string Dijkstra::Mode::_getString () const + { + string s = ""; + s += (_flags & Standart ) ? 'S' : '-'; + s += (_flags & Monotonic) ? 'M' : '-'; + + return s; + } + + + DbU::Unit Dijkstra::_distance ( const Vertex* current, const Vertex* vneighbour, const Edge* e ) + { + if (Vertex::isRestricted(current, vneighbour)) return Vertex::unreachable; + else return current->getDistance() + e->getDistance(); + } + + + DbU::Unit Dijkstra::_getDistancetoRP( Point p ) + { + + cdebug_log(112,0) << "DbU::Unit Dijkstra::_getDistancetoRP( Point p ): " << p << endl; + RoutingPad* rp = NULL; + DbU::Unit dist = 0; + Cell* cell = _anabatic->getCell(); + int cpt = 0; + + /*for ( Vertex* vertex : _sources ) { + if (vertex->hasRP()){ + for ( Component* component : cell->getComponentsUnder(vertex->getGCell()->getBoundingBox()) ){ + rp = dynamic_cast( component ); + if (rp) break; + } + if (rp) { + cdebug_log(112,0) << "Vertex: " << vertex << endl; + dist += _estimatePtoRP(p, rp, vertex ); + } + } + }*/ + for ( Vertex* vertex : _targets ) { + if (vertex->hasRP(_net)){ + for ( Component* component : cell->getComponentsUnder(vertex->getGCell()->getBoundingBox()) ){ + rp = dynamic_cast( component ); + if (rp) { + if (rp->getNet() == _net) break; + } + } + if (rp) { + DbU::Unit distance = _estimatePtoRP(p, rp, vertex ); + cdebug_log(112,0) << "Dist to Vertex: " << vertex << " IS = " << DbU::getValueString(distance) << endl; + dist += distance; + cpt++; + } + } + } + dist = dist/cpt; + return dist; + } + + + DbU::Unit calcDistance( Point p1, Point p2 ) + { + return abs(p1.getX()-p2.getX()) + abs(p1.getY()-p2.getY()); + } + + + DbU::Unit Dijkstra::_estimatePtoRP( Point p, RoutingPad* rp, Vertex* vertex ) + { + Horizontal* h = dynamic_cast(rp->_getEntityAsSegment()); + Vertical* v = dynamic_cast(rp->_getEntityAsSegment()); + DbU::Unit d = Vertex::unreachable; + GCell* gvertex = vertex->getGCell(); + + if (h) { + cdebug_log(112,0) << "Case: Horizontal: " << endl; + if (p.getX() < rp->getSourceX()){ + cdebug_log(112,0) << "Case: p.getX() < rp->getSourceX()" << endl; + if (p.getY() < gvertex->getYMin()){ + cdebug_log(112,0) << "Case: West South" << endl; + if ( (!vertex->isSRestricted()) + || (!vertex->isWRestricted()) ) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())); + else if (!vertex->isNRestricted()) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())) + (gvertex->getYMax() - rp->getY())*2; + else if (!vertex->isERestricted()) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())); + else d = Vertex::unreachable; + } else if (p.getY() > gvertex->getYMax()){ + cdebug_log(112,0) << "Case: West North" << endl; + if ( (!vertex->isNRestricted()) + || (!vertex->isWRestricted()) ) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())); + else if (!vertex->isSRestricted()) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())) + (rp->getY() - gvertex->getYMin())*2; + else if (!vertex->isERestricted()) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())); + else d = Vertex::unreachable; + } else { + cdebug_log(112,0) << "Case: West" << endl; + if (!vertex->isWRestricted()) d = min(d, calcDistance (p, Point(rp->getSourceX(), rp->getSourceY()))); + if (!vertex->isNRestricted()) d = min(d, calcDistance (p, Point(rp->getSourceX(), rp->getSourceY()))+ (gvertex->getYMax() - rp->getY())*2); + if (!vertex->isSRestricted()) d = min(d, calcDistance (p, Point(rp->getSourceX(), rp->getSourceY()))+ (rp->getY() - gvertex->getYMin())*2); + if (!vertex->isERestricted()) d = min(d, calcDistance (p, Point(rp->getTargetX(), rp->getTargetY()))); + } + } else if (p.getX() > rp->getTargetX()){ + cdebug_log(112,0) << "Case: p.getX() > rp->getTargetX()" << endl; + if (p.getY() < gvertex->getYMin()){ + cdebug_log(112,0) << "Case: East South" << endl; + if ( (!vertex->isSRestricted()) + || (!vertex->isERestricted()) ) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())); + else if (!vertex->isNRestricted()) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())) + (gvertex->getYMax() - rp->getY())*2; + else if (!vertex->isWRestricted()) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())); + else d = Vertex::unreachable; + } else if (p.getY() > gvertex->getYMax()){ + cdebug_log(112,0) << "Case: East North" << endl; + if ( (!vertex->isNRestricted()) + || (!vertex->isERestricted()) ) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())); + else if (!vertex->isSRestricted()) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())) + (rp->getY() - gvertex->getYMin())*2; + else if (!vertex->isWRestricted()) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())); + else d = Vertex::unreachable; + } else { + cdebug_log(112,0) << "Case: East" << endl; + if (!vertex->isERestricted()) d = min(d, calcDistance (p, Point(rp->getTargetX(), rp->getTargetY()))); + if (!vertex->isNRestricted()) d = min(d, calcDistance (p, Point(rp->getTargetX(), rp->getTargetY()))+ (gvertex->getYMax() - rp->getY())*2); + if (!vertex->isSRestricted()) d = min(d, calcDistance (p, Point(rp->getTargetX(), rp->getTargetY()))+ (rp->getY() - gvertex->getYMin())*2); + if (!vertex->isWRestricted()) d = min(d, calcDistance (p, Point(rp->getSourceX(), rp->getSourceY()))); + } + } else if (p.getY() < gvertex->getYMin()){ + cdebug_log(112,0) << "Case: South" << endl; + if (!vertex->isSRestricted()) d = min(d, rp->getY()-p.getY()); + if (!vertex->isERestricted()) d = min(d, rp->getY()-p.getY()+ (gvertex->getXMax()-p.getX())*2); + if (!vertex->isWRestricted()) d = min(d, rp->getY()-p.getY()+ (p.getX()-gvertex->getXMin())*2); + if (!vertex->isNRestricted()) d = min(d, min ( gvertex->getXMax()-p.getX() + gvertex->getYMax()-p.getY() + gvertex->getYMax()-rp->getY() + , p.getX()-gvertex->getXMin() + gvertex->getYMax()-p.getY() + gvertex->getYMax()-rp->getY() + ) + ); + } else if (p.getY() > gvertex->getYMax()){ + cdebug_log(112,0) << "Case: North" << endl; + if (!vertex->isNRestricted()) d = min(d, p.getY()-rp->getY()); + if (!vertex->isERestricted()) d = min(d, p.getY()-rp->getY()+ (gvertex->getXMax()-p.getX())*2); + if (!vertex->isWRestricted()) d = min(d, p.getY()-rp->getY()+ (p.getX()-gvertex->getXMin())*2); + if (!vertex->isSRestricted()) d = min(d, min ( gvertex->getXMax()-p.getX() + p.getY()-gvertex->getYMin() + rp->getY()-gvertex->getYMin() + , p.getX()-gvertex->getXMin() + p.getY()-gvertex->getYMin() + rp->getY()-gvertex->getYMin() + ) + ); + } + } + + if (v) { + cdebug_log(112,0) << "Case: Vertical" << endl; + if (p.getY() < rp->getSourceY()){ + cdebug_log(112,0) << "Case: p.getY() < rp->getSourceY()" << endl; + if (p.getX() < gvertex->getXMin()){ + cdebug_log(112,0) << "Case: South West" << endl; + if ( (!vertex->isSRestricted()) + || (!vertex->isWRestricted()) ) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())); + else if (!vertex->isERestricted()) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())) + (gvertex->getXMax() - rp->getX())*2; + else if (!vertex->isNRestricted()) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())); + else d = Vertex::unreachable; + } else if (p.getX() > gvertex->getXMax()){ + cdebug_log(112,0) << "Case: South East" << endl; + if ( (!vertex->isSRestricted()) + || (!vertex->isERestricted()) ) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())); + else if (!vertex->isWRestricted()) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())) + (rp->getX() - gvertex->getXMin())*2; + else if (!vertex->isNRestricted()) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())); + else d = Vertex::unreachable; + } else { + cdebug_log(112,0) << "Case: South " << endl; + if (!vertex->isSRestricted()) d = min(d, calcDistance (p, Point(rp->getSourceX(), rp->getSourceY()))); + if (!vertex->isWRestricted()) d = min(d, calcDistance (p, Point(rp->getSourceX(), rp->getSourceY()))+ (gvertex->getXMax() - rp->getX())*2); + if (!vertex->isERestricted()) d = min(d, calcDistance (p, Point(rp->getSourceX(), rp->getSourceY()))+ (rp->getX() - gvertex->getXMin())*2); + if (!vertex->isNRestricted()) d = min(d, calcDistance (p, Point(rp->getTargetX(), rp->getTargetY()))); + } + } else if (p.getY() > rp->getTargetY()){ + cdebug_log(112,0) << "Case: p.getY() > rp->getTargetY()" << endl; + if (p.getX() < gvertex->getXMin()){ + cdebug_log(112,0) << "Case: North West" << endl; + if ( (!vertex->isNRestricted()) + || (!vertex->isWRestricted()) ) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())); + else if (!vertex->isERestricted()) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())) + (gvertex->getXMax() - rp->getX())*2; + else if (!vertex->isSRestricted()) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())); + else d = Vertex::unreachable; + } else if (p.getX() > gvertex->getXMax()){ + cdebug_log(112,0) << "Case: North East" << endl; + if ( (!vertex->isNRestricted()) + || (!vertex->isERestricted()) ) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())); + else if (!vertex->isWRestricted()) d = calcDistance (p, Point(rp->getTargetX(), rp->getTargetY())) + (rp->getX() - gvertex->getXMin())*2; + else if (!vertex->isSRestricted()) d = calcDistance (p, Point(rp->getSourceX(), rp->getSourceY())); + else d = Vertex::unreachable; + } else { + cdebug_log(112,0) << "Case: North" << endl; + if (!vertex->isNRestricted()) d = min(d, calcDistance (p, Point(rp->getTargetX(), rp->getTargetY()))); + if (!vertex->isWRestricted()) d = min(d, calcDistance (p, Point(rp->getTargetX(), rp->getTargetY()))+ (gvertex->getXMax() - rp->getX())*2); + if (!vertex->isERestricted()) d = min(d, calcDistance (p, Point(rp->getTargetX(), rp->getTargetY()))+ (rp->getX() - gvertex->getXMin())*2); + if (!vertex->isSRestricted()) d = min(d, calcDistance (p, Point(rp->getSourceX(), rp->getSourceY()))); + } + } else if (p.getX() < gvertex->getXMin()){ + cdebug_log(112,0) << "Case: West" << endl; + if (!vertex->isWRestricted()) d = min(d, rp->getX()-p.getX()); + if (!vertex->isNRestricted()) d = min(d, rp->getX()-p.getX()+ (gvertex->getYMax()-p.getY())*2); + if (!vertex->isSRestricted()) d = min(d, rp->getX()-p.getX()+ (p.getY()-gvertex->getYMin())*2); + if (!vertex->isERestricted()) d = min(d, min ( gvertex->getYMax()-p.getY() + gvertex->getXMax()-p.getX() + gvertex->getXMax()-rp->getX() + , p.getY()-gvertex->getYMin() + gvertex->getXMax()-p.getX() + gvertex->getXMax()-rp->getX() + ) + ); + } else if (p.getX() > gvertex->getXMax()){ + cdebug_log(112,0) << "Case: East" << endl; + if (!vertex->isERestricted()) d = min(d, p.getX()-rp->getX()); + if (!vertex->isNRestricted()) d = min(d, p.getX()-rp->getX()+ (gvertex->getYMax()-p.getY())*2); + if (!vertex->isSRestricted()) d = min(d, p.getX()-rp->getX()+ (p.getY()-gvertex->getYMin())*2); + if (!vertex->isWRestricted()) d = min(d, min ( gvertex->getYMax()-p.getY() + p.getX()-gvertex->getXMin() + rp->getX()-gvertex->getXMin() + , p.getY()-gvertex->getYMin() + p.getX()-gvertex->getXMin() + rp->getX()-gvertex->getXMin() + ) + ); + } + } + return d; + } + + Dijkstra::Dijkstra ( AnabaticEngine* anabatic ) : _anabatic (anabatic) , _vertexes () @@ -298,6 +1014,27 @@ namespace Anabatic { } + Point Dijkstra::_getPonderedPoint() const + { + vector rps; + int cpt = 0; + DbU::Unit x = 0; + DbU::Unit y = 0; + + for ( Component* component : _net->getComponents() ) { + RoutingPad* rp = dynamic_cast( component ); + if (rp) rps.push_back( rp ); + } + + for ( auto rp : rps ) { + x += rp->getBoundingBox().getCenter().getX(); + y += rp->getBoundingBox().getCenter().getY(); + cpt++; + } + return Point(x/cpt, y/cpt); + } + + void Dijkstra::load ( Net* net ) { _cleanup(); @@ -343,8 +1080,20 @@ namespace Anabatic { _searchArea.merge( gcell->getBoundingBox() ); cdebug_log(112,0) << "New Search area: " << _searchArea << endl; - Vertex* seed = gcell->getObserver(GCell::Observable::Vertex); - seed->setPathPoint(rp->getBoundingBox().getCenter().getX(), rp->getBoundingBox().getCenter().getY()); + Vertex* seed = gcell->getObserver(GCell::Observable::Vertex); + Horizontal* h = dynamic_cast(rp->_getEntityAsSegment()); + Vertical* v = dynamic_cast (rp->_getEntityAsSegment()); + if (h) { + seed->setIAsH(); + seed->setInterv(rp->getBoundingBox().getXMin(), rp->getBoundingBox().getXMax(), rp->getBoundingBox().getYCenter()); + seed->printInterval(); + } + if (v) { + seed->setIAsV(); + seed->setInterv(rp->getBoundingBox().getYMin(), rp->getBoundingBox().getYMax(), rp->getBoundingBox().getXCenter()); + seed->printInterval(); + } + if (seed->getConnexId() < 0) { VertexSet connecteds; _getConnecteds( seed, connecteds ); @@ -409,8 +1158,16 @@ namespace Anabatic { if (not firstSource) { // Standart routing. - Point areaCenter = _searchArea.getCenter(); - auto ivertex = _targets.begin(); + bool hasDevice = false; + for ( Vertex* ivertex : _targets ) { + if (ivertex->getGCell()->isDevice()) hasDevice = true; + } + + Point areaCenter; + if (hasDevice) areaCenter = _getPonderedPoint(); + else areaCenter = _searchArea.getCenter(); + + auto ivertex = _targets.begin(); firstSource = *ivertex++; DbU::Unit minDistance = areaCenter.manhattanDistance( firstSource->getCenter() ); @@ -457,51 +1214,91 @@ namespace Anabatic { _queue.dump(); Vertex* current = _queue.top(); + cdebug_log(111,0) << endl; cdebug_log(111,0) << "[Current Vertex]: " << current << endl; _queue.pop(); if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) { for ( Edge* edge : current->getGCell()->getEdges() ) { - if (edge == current->getFrom()) { cdebug_log(111,0) << "edge == current->getFrom()" << endl; continue; } - GCell* gneighbor = edge->getOpposite(current->getGCell()); + GCell* gcurrent = current->getGCell(); Vertex* vneighbor = gneighbor->getObserver(GCell::Observable::Vertex); - //if (not _searchArea.contains(vneighbor->getCenter())) { - if (not _searchArea.intersect(gneighbor->getBoundingBox())) { - cdebug_log(111,0) << "not in _searchArea: " << _searchArea << ", gneighbor area: " << gneighbor->getBoundingBox() << endl; - continue; - } - - cdebug_log(111,0) << "| Edge " << edge << endl; - cdebug_log(111,0) << "+ Neighbor: " << vneighbor << endl; - - DbU::Unit distance = _distanceCb( current, vneighbor, edge ); - cdebug_log(111,0) << "Distance: " << distance << ", unreachable: " << Vertex::unreachable << endl; - - if (vneighbor->getConnexId() == _connectedsId) { cdebug_log(111,0) << "ConnectedsId" << endl; continue; } - if ( ( (distance < vneighbor->getDistance()) - or ( (distance == vneighbor->getDistance()) - and (current->getBranchId() > vneighbor->getBranchId())) - ) - and (distance != Vertex::unreachable) - ){ - cdebug_log(111,0) << "1" << endl; + if (not _searchArea.intersect(gneighbor->getBoundingBox())) { + cdebug_log(111,0) << "not in _searchArea: " << _searchArea << ", gneighbor area: " << gneighbor->getBoundingBox() << endl; + continue; + } + cdebug_log(111,0) << endl << "===================================================================================" << endl << endl; + cdebug_log(111,0) << "| Curr: " << current; + if (current->getFrom()){ + cdebug_log(111,0) << "| From: " << current->getFrom()->getOpposite(gcurrent) << endl; + } else { + cdebug_log(111,0) << endl; + } + cdebug_log(111,0) << "| Edge " << edge << endl; + cdebug_log(111,0) << "+ Neighbor: " << vneighbor << endl; + + + DbU::Unit distance = _distanceCb( current, vneighbor, edge ); + cdebug_log(111,0) << "Distance curr: " << DbU::getValueString(distance) << endl; + cdebug_log(111,0) << "Distance prev: " << DbU::getValueString(vneighbor->getDistance()) << endl; + + if ( (distance == vneighbor->getDistance()) + and ( (!gcurrent->isMatrix())||(!gneighbor->isMatrix()) ) + ){ + cdebug_log(111,0) << "Distance EQUAL" << endl; + cdebug_log(111,0) << "Previous getfrom:" << vneighbor->getFrom()->getOpposite( gneighbor ) << endl; + + GCell* gnext = vneighbor->getGCell(); + GCell* gprev = vneighbor->getFrom()->getOpposite(gnext); + Vertex* vprev = gprev->getObserver(GCell::Observable::Vertex); + + + Point pnext = Vertex::getNextPathPoint2( current, vneighbor ); + Point pprev = Vertex::getNextPathPoint2( vprev, vneighbor ); + Point ppond = _getPonderedPoint(); + DbU::Unit distcurr = this->_getDistancetoRP(pnext); + DbU::Unit distprev = this->_getDistancetoRP(pprev); + + cdebug_log(111,0) << "Pcurrent: X:" << DbU::getValueString(pnext.getX()) << ", Y:" << DbU::getValueString(pnext.getY()) << endl; + cdebug_log(111,0) << "Pprev : X:" << DbU::getValueString(pprev.getX()) << ", Y:" << DbU::getValueString(pprev.getY()) << endl; + + cdebug_log(111,0) << "distToTargets curr: " << DbU::getValueString(distcurr) << endl; + cdebug_log(111,0) << "distToTargets prev: " << DbU::getValueString(distprev) << endl; + + if ( ( distcurr < distprev ) + || ( ( distcurr == distprev ) + && ( calcDistance(ppond, pnext) < calcDistance(ppond, pprev) ) + ) + ){ + cdebug_log(111,0) << "BETTER GetFROM" << endl; + vneighbor->setBranchId( current->getBranchId() ); + vneighbor->setDistance( distance ); + //Point pathPoint = Vertex::getNextPathPoint( current, vneighbor ); + //vneighbor->setPathPoint( pathPoint.getX(), pathPoint.getY() ); + vneighbor->setFrom ( edge ); + _queue.push( vneighbor ); + + vneighbor->setIntervals( current ); + cdebug_log(111,0) << "Push: (size:" << _queue.size() << ") " << vneighbor << endl; + } + } else if ( ( (distance < vneighbor->getDistance()) and (distance != Vertex::unreachable) ) + or ( (distance == vneighbor->getDistance()) and (current->getBranchId() > vneighbor->getBranchId()) ) + ) { if (vneighbor->getDistance() != Vertex::unreached) { - cdebug_log(111,0) << "2" << endl; _queue.erase( vneighbor ); } else { - cdebug_log(111,0) << "3" << endl; if (not vneighbor->hasValidStamp()) { + cdebug_log(111,0) << "Distance FIRST" << endl; vneighbor->setConnexId( -1 ); vneighbor->setStamp ( _stamp ); vneighbor->setDegree ( 1 ); @@ -509,13 +1306,15 @@ namespace Anabatic { } } + cdebug_log(111,0) << "Distance INF" << endl; vneighbor->setBranchId( current->getBranchId() ); vneighbor->setDistance( distance ); - Point pathPoint =_getNextPathPoint( current, vneighbor ); - vneighbor->setPathPoint( pathPoint.getX(), pathPoint.getY() ); + //Point pathPoint = Vertex::getNextPathPoint( current, vneighbor ); + //vneighbor->setPathPoint( pathPoint.getX(), pathPoint.getY() ); vneighbor->setFrom ( edge ); _queue.push( vneighbor ); + vneighbor->setIntervals( current ); cdebug_log(111,0) << "Push: (size:" << _queue.size() << ") " << vneighbor << endl; } } @@ -543,12 +1342,48 @@ namespace Anabatic { { cdebug_log(112,1) << "Dijkstra::_traceback() " << _net << " branchId:" << _sources.size() << endl; - int branchId = _sources.size(); + int branchId = _sources.size(); + Point ponderedpoint = _getPonderedPoint(); _toSources( current, _connectedsId ); + + if (!current->getGCell()->isMatrix()){ + GCell* gcurr = current->getGCell(); + GCell* gprev = current->getFrom()->getOpposite(gcurr); + Vertex* vprev = gprev->getObserver(GCell::Observable::Vertex); + Point pentry = Vertex::getNextPathPoint2( vprev, current ); + + if (current->isH()){ + if (pentry.getX() < current->getIMin()){ + current->setInterv(pentry.getX(), current->getIMax(), current->getIAxis()); + cdebug_log(112,0) << "[Interval update1]: min : " << DbU::getValueString(pentry.getX()); + cdebug_log(112,0) << ", max : " << DbU::getValueString(current->getIMax()); + cdebug_log(112,0) << ", axis: " << DbU::getValueString(current->getIAxis()) << endl; + } else if (pentry.getX() > current->getIMax()){ + current->setInterv(current->getIMin(), pentry.getX(), current->getIAxis()); + cdebug_log(112,0) << "[Interval update2]: min : " << DbU::getValueString(current->getIMin()); + cdebug_log(112,0) << ", max : " << DbU::getValueString(pentry.getX()); + cdebug_log(112,0) << ", axis: " << DbU::getValueString(current->getIAxis()) << endl; + } + } else if (current->isV()){ + if (pentry.getY() < current->getIMin()){ + current->setInterv(pentry.getY(), current->getIMax(), current->getIAxis()); + cdebug_log(112,0) << "[Interval update3]: min : " << DbU::getValueString(pentry.getY()); + cdebug_log(112,0) << ", max : " << DbU::getValueString(current->getIMax()); + cdebug_log(112,0) << ", axis: " << DbU::getValueString(current->getIAxis()) << endl; + } else if (pentry.getY() > current->getIMax()){ + current->setInterv(current->getIMin(), pentry.getY(), current->getIAxis()); + cdebug_log(112,0) << "[Interval update4]: min : " << DbU::getValueString(current->getIMin()); + cdebug_log(112,0) << ", max : " << DbU::getValueString(pentry.getY()); + cdebug_log(112,0) << ", axis: " << DbU::getValueString(current->getIAxis()) << endl; + } + } + } + current = current->getPredecessor(); + while ( current ) { - cdebug_log(112,0) << "| " << current << endl; + cdebug_log(112,0) << "| " << current << " | " << endl; current->incDegree(); if (current->getConnexId() == _connectedsId) break; @@ -557,7 +1392,19 @@ namespace Anabatic { if (not from) break; current->setDistance( 0.0 ); - if (!current->getGCell()->isDevice()) current->setPathPoint( current->getGCell()->getXCenter(), current->getGCell()->getYCenter() ); + if (!current->getGCell()->isMatrix()){ + /*if (!current->getGCell()->isDevice()) { + current->resetPathPoint(ponderedpoint); + }*/ + + if (current->getPredecessor() != NULL){ + cdebug_log(112,0) << "[Interval update]: min : " << DbU::getValueString(current->getPIMin()); + cdebug_log(112,0) << ", max : " << DbU::getValueString(current->getPIMax()); + cdebug_log(112,0) << ", axis: " << DbU::getValueString(current->getPIAxis()) << endl; + current->getPredecessor()->setInterv(current->getPIMin(), current->getPIMax(), current->getPIAxis()); + } + } + current->setConnexId( _connectedsId ); current->setBranchId( branchId ); _sources.insert( current ); @@ -577,6 +1424,7 @@ namespace Anabatic { if (_sources.size() < 2) { cdebug_tabw(112,-1); return; } for ( Vertex* startVertex : _sources ) { + cdebug_log(112,0) << "? " << startVertex << endl; if (not startVertex->getFrom()) continue; @@ -586,6 +1434,10 @@ namespace Anabatic { Vertex* source = startVertex; while ( source ) { + //////////////////////////////////////////// + source->resetIntervals(); + //////////////////////////////////////////// + cdebug_log(112,0) << "* " << source << endl; Edge* from = source->getFrom(); diff --git a/anabatic/src/LoadGlobalRouting.cpp b/anabatic/src/LoadGlobalRouting.cpp index a0b9421e..a18752de 100644 --- a/anabatic/src/LoadGlobalRouting.cpp +++ b/anabatic/src/LoadGlobalRouting.cpp @@ -3020,8 +3020,7 @@ namespace { if ((_north != NULL) && (_south != NULL) && (_east != NULL)){ cdebug_log(145,0) << "Case NSE " << endl; - xtee = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) ); - + xtee = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) ); if (_north->getComponent()->getX() < _south->getComponent()->getX()){ turn->setX(_north->getComponent()->getX()); xtee->setX(_south->getComponent()->getX()); @@ -3059,8 +3058,10 @@ namespace { } else if ((_north != NULL) && (_south != NULL) && (_west != NULL)){ cdebug_log(145,0) << "Case NSW " << endl; xtee = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) ); + cerr << "1" << endl; if (_north->getComponent()->getX() < _south->getComponent()->getX()){ + cerr << "2" << endl; xtee->setX(_north->getComponent()->getX()); turn->setX(_south->getComponent()->getX()); if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), xtee ); @@ -3069,6 +3070,7 @@ namespace { else targetContact = turn; } else { + cerr << "3" << endl; xtee->setX(_south->getComponent()->getX()); turn->setX(_north->getComponent()->getX()); if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), turn ); @@ -3076,9 +3078,10 @@ namespace { if ( _south and (_fromHook != _south) ) forks.push( getSegmentOppositeHook( _south ), xtee ); else targetContact = xtee; } - turn->setY(_east->getComponent()->getY()); - xtee->setY(_east->getComponent()->getY()); - if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), xtee ); + cerr << "4" << endl; + turn->setY(_west->getComponent()->getY()); + xtee->setY(_west->getComponent()->getY()); + if ( _west and (_fromHook != _west) ) forks.push( getSegmentOppositeHook( _west ), xtee ); else targetContact = xtee; cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index 95525405..333147a8 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -38,6 +38,61 @@ namespace Anabatic { class AnabaticEngine; +// ------------------------------------------------------------------- +// Class : "Anabatic::IntervalC". + + class IntervalC + { + public: + enum iFlag { None = 0 + , iHorizontal = (1<<0) + , iVertical = (1<<1) + , iSet = (1<<2) + }; + private: + IntervalC(); + ~IntervalC(); + public: + static IntervalC* create(); + + public: + void set ( DbU::Unit, DbU::Unit, DbU::Unit ); + void setRange ( DbU::Unit, DbU::Unit ); + void extendMin ( DbU::Unit ); + void extendMax ( DbU::Unit ); + void print () const; + inline bool isH () const; + inline bool isV () const; + inline void setAsH (); + inline void setAsV (); + inline DbU::Unit getMin () const; + inline DbU::Unit getMax () const; + inline DbU::Unit getCenter () const; + DbU::Unit getAxis () const; + inline void setAxis ( DbU::Unit ); + inline void setiSet (); + inline bool isiSet () const; + void reset (); + + private: + unsigned int _flags; + DbU::Unit _min; + DbU::Unit _max; + DbU::Unit _axis; + }; + + inline void IntervalC::setAsH () { _flags = ((_flags & ~(0x3)) | iHorizontal); } + inline void IntervalC::setAsV () { _flags = ((_flags & ~(0x3)) | iVertical ); } + inline void IntervalC::setAxis ( DbU::Unit axis ) { _axis = axis; } + inline DbU::Unit IntervalC::getAxis () const { return _axis; } + inline DbU::Unit IntervalC::getCenter() const { return getMin()+getMax(); } + inline DbU::Unit IntervalC::getMin () const { return _min; } + inline DbU::Unit IntervalC::getMax () const { return _max; } + inline void IntervalC::setiSet () { _flags |= iSet; } + inline bool IntervalC::isiSet () const { return _flags & iSet; } + inline bool IntervalC::isH () const { return _flags & iHorizontal; } + inline bool IntervalC::isV () const { return _flags & iVertical ; } + // ------------------------------------------------------------------- // Class : "Anabatic::Vertex". @@ -109,10 +164,38 @@ namespace Anabatic { inline void setERestricted (); inline void setWRestricted (); inline unsigned int getFlags () const; - void setPathPoint ( DbU::Unit, DbU::Unit ); inline DbU::Unit getXPath () const; inline DbU::Unit getYPath () const; - inline Point getPathPoint () const; + bool hasRP ( Net* ) const; + bool hasVRP ( Net* ) const; + bool hasHRP ( Net* ) const; + static bool isRestricted ( const Vertex* v1, const Vertex* v2 ); + static Point getNextPathPoint2( const Vertex*, const Vertex* ); + Point getPathPoint ( const Vertex * ) const; + inline void setIAsH (); + inline void setIAsV (); + inline DbU::Unit getIAxis () const; + inline void setIAxis ( DbU::Unit ) ; + inline DbU::Unit getICenter () const; + inline DbU::Unit getIMax () const; + inline DbU::Unit getIMin () const; + inline void setPIAsH (); + inline void setPIAsV (); + inline DbU::Unit getPIAxis () const; + inline void setPIAxis ( DbU::Unit ) ; + inline DbU::Unit getPICenter () const; + inline DbU::Unit getPIMax () const; + inline DbU::Unit getPIMin () const; + bool isH () const; + bool isV () const; + inline bool isiSet () const; + inline void setInterv ( DbU::Unit, DbU::Unit, DbU::Unit ); + inline void setIRange ( DbU::Unit, DbU::Unit ); + inline void setIRangeFrom ( DbU::Unit, DbU::Unit ); + inline void printInterval () const ; + void setIntervals ( Vertex* ); + void resetIntervals (); + // Inspector support. string _getString () const; @@ -132,8 +215,8 @@ namespace Anabatic { DbU::Unit _distance; Edge* _from; unsigned int _flags; - DbU::Unit _xpath; - DbU::Unit _ypath; + IntervalC* _intervfrom; + IntervalC* _interv; }; @@ -149,8 +232,9 @@ namespace Anabatic { , _distance(unreached) , _from (NULL) , _flags (NoRestriction) - , _xpath (0) - , _ypath (0) + + , _intervfrom(IntervalC::create()) + , _interv (IntervalC::create()) { gcell->setObserver( GCell::Observable::Vertex, &_observer ); } @@ -207,9 +291,27 @@ namespace Anabatic { inline void Vertex::setERestricted () { _flags |= 0x4; } inline void Vertex::setWRestricted () { _flags |= 0x8; } inline unsigned int Vertex::getFlags () const { return _flags; } - inline DbU::Unit Vertex::getXPath () const { return _xpath; } - inline DbU::Unit Vertex::getYPath () const { return _ypath; } - inline Point Vertex::getPathPoint () const { return Point(_xpath, _ypath); } + + inline void Vertex::setIAxis ( DbU::Unit axis ) { _interv->setAxis(axis); } + inline DbU::Unit Vertex::getIAxis () const { return _interv->getAxis(); } + inline void Vertex::setIAsH () { _interv->setAsH(); } + inline void Vertex::setIAsV () { _interv->setAsV(); } + inline DbU::Unit Vertex::getICenter () const { return _interv->getCenter(); } + inline DbU::Unit Vertex::getIMax () const { return _interv->getMax(); } + inline DbU::Unit Vertex::getIMin () const { return _interv->getMin(); } + inline void Vertex::setPIAxis ( DbU::Unit axis ) { _intervfrom->setAxis(axis); } + inline DbU::Unit Vertex::getPIAxis () const { return _intervfrom->getAxis(); } + inline void Vertex::setPIAsH () { _intervfrom->setAsH(); } + inline void Vertex::setPIAsV () { _intervfrom->setAsV(); } + inline DbU::Unit Vertex::getPICenter() const { return _intervfrom->getCenter(); } + inline DbU::Unit Vertex::getPIMax () const { return _intervfrom->getMax(); } + inline DbU::Unit Vertex::getPIMin () const { return _intervfrom->getMin(); } + inline bool Vertex::isiSet () const { return _interv->isiSet(); } + + inline void Vertex::setInterv ( DbU::Unit min, DbU::Unit max, DbU::Unit axis ) { _interv->set(min, max, axis); } + inline void Vertex::setIRange ( DbU::Unit min, DbU::Unit max ) { _interv->setRange(min, max); } + inline void Vertex::setIRangeFrom( DbU::Unit min, DbU::Unit max ) { _intervfrom->setRange(min, max); } + inline void Vertex::printInterval() const { _interv->print(); } // ------------------------------------------------------------------- // Class : "Anabatic::PriorityQueue". @@ -313,7 +415,9 @@ namespace Anabatic { Dijkstra ( const Dijkstra& ); Dijkstra& operator= ( const Dijkstra& ); static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* ); - static Point _getNextPathPoint ( const Vertex*, const Vertex* ); + DbU::Unit _getDistancetoRP ( Point ); + DbU::Unit _estimatePtoRP ( Point, RoutingPad*, Vertex* ); + Point _getPonderedPoint () const; void _cleanup (); bool _propagate ( Flags enabledSides ); void _traceback ( Vertex* ); @@ -322,7 +426,6 @@ namespace Anabatic { void _toSources ( Vertex*, int connexId ); void _getConnecteds ( Vertex*, VertexSet& ); void _checkEdges () const; - static bool isRestricted ( const Vertex* v1, const Vertex* v2 ); private: AnabaticEngine* _anabatic; vector _vertexes;