Anabatic transient commit 7. More Dijkstra bugs correcteds.
* Bug: In Anabatic: - Activate the searchArea to limit the area explored by the Dijkstra. Uses the bounding boxes of the vertexes/gcells instead of the ones the RoutingPads. - Always detach contacts from the rings in load(), even if the vertex is already marked as target. - On reaching a target (non-negative connexId), do not forget to update the distance to source. - In Edges locator, added support for side selection (needed by the monotonic feature). * New: In Anabatic: - Hide the atomic Dijkstra methods (made private). - Implementation of the monotonic mode in Dijkstra (for bipoints only). - Added a separate function for distance computation between two vertexes, now take account of the VIAs costs.
This commit is contained in:
parent
23d6ae55fd
commit
c5a9e0b617
|
@ -21,6 +21,7 @@
|
||||||
#include "hurricane/Horizontal.h"
|
#include "hurricane/Horizontal.h"
|
||||||
#include "hurricane/Vertical.h"
|
#include "hurricane/Vertical.h"
|
||||||
#include "hurricane/UpdateSession.h"
|
#include "hurricane/UpdateSession.h"
|
||||||
|
#include "hurricane/DebugSession.h"
|
||||||
#include "anabatic/AnabaticEngine.h"
|
#include "anabatic/AnabaticEngine.h"
|
||||||
#include "anabatic/Dijkstra.h"
|
#include "anabatic/Dijkstra.h"
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ namespace Anabatic {
|
||||||
using Hurricane::Vertical;
|
using Hurricane::Vertical;
|
||||||
using Hurricane::RoutingPad;
|
using Hurricane::RoutingPad;
|
||||||
using Hurricane::UpdateSession;
|
using Hurricane::UpdateSession;
|
||||||
|
using Hurricane::DebugSession;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -81,9 +83,40 @@ namespace Anabatic {
|
||||||
// Class : "Anabatic::Dijkstra".
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float Dijkstra::getDistance ( const Vertex* a, const Vertex* b, const Edge* e )
|
||||||
|
{
|
||||||
|
float distance = a->getDistance() + e->getDistance();
|
||||||
|
|
||||||
|
Edge* aFrom = a->getFrom();
|
||||||
|
if (aFrom) {
|
||||||
|
distance += (aFrom->isHorizontal() xor e->isHorizontal()) ? 3.0 : 0.0;
|
||||||
|
}
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Dijkstra::Dijkstra ( AnabaticEngine* anabatic )
|
Dijkstra::Dijkstra ( AnabaticEngine* anabatic )
|
||||||
: _anabatic (anabatic)
|
: _anabatic (anabatic)
|
||||||
, _vertexes ()
|
, _vertexes ()
|
||||||
|
, _mode (Mode::Standart)
|
||||||
, _net (NULL)
|
, _net (NULL)
|
||||||
, _stamp (-1)
|
, _stamp (-1)
|
||||||
, _sources ()
|
, _sources ()
|
||||||
|
@ -109,8 +142,8 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
_net = net;
|
_net = net;
|
||||||
|
|
||||||
|
DebugSession::open( _net, 110, 120 );
|
||||||
cdebug.log(111,1) << "Dijkstra::load() " << _net << endl;
|
cdebug.log(111,1) << "Dijkstra::load() " << _net << endl;
|
||||||
UpdateSession::open();
|
|
||||||
|
|
||||||
_sources.clear();
|
_sources.clear();
|
||||||
_targets.clear();
|
_targets.clear();
|
||||||
|
@ -133,58 +166,83 @@ namespace Anabatic {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_searchArea.merge( rpBb );
|
_searchArea.merge( gcell->getBoundingBox() );
|
||||||
|
|
||||||
Vertex* vertex = gcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
Vertex* vertex = gcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||||
if (vertex->getConnexId() < 0) {
|
if (vertex->getConnexId() < 0) {
|
||||||
vertex->setStamp ( _stamp );
|
vertex->setStamp ( _stamp );
|
||||||
vertex->setConnexId( _targets.size() );
|
vertex->setConnexId( _targets.size() );
|
||||||
vertex->setFrom ( NULL );
|
vertex->setFrom ( NULL );
|
||||||
Contact* gcontact = vertex->getGContact( _net );
|
|
||||||
rp->getBodyHook()->detach();
|
|
||||||
rp->getBodyHook()->attach( gcontact->getBodyHook() );
|
|
||||||
_targets.insert( vertex );
|
_targets.insert( vertex );
|
||||||
|
|
||||||
cdebug.log(111) << "Add Vertex: " << vertex << endl;
|
cdebug.log(111) << "Add Vertex: " << vertex << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Contact* gcontact = vertex->getGContact( _net );
|
||||||
|
rp->getBodyHook()->detach();
|
||||||
|
rp->getBodyHook()->attach( gcontact->getBodyHook() );
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateSession::close();
|
cdebug.log(111) << "Search area: " << _searchArea << endl;
|
||||||
cdebug.tabw(111,-1);
|
cdebug.tabw(111,-1);
|
||||||
|
DebugSession::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Dijkstra::selectFirstSource ()
|
void Dijkstra::_selectFirstSource ()
|
||||||
{
|
{
|
||||||
if (_targets.empty()) {
|
if (_targets.empty()) {
|
||||||
cerr << Error( "Dijkstra::selectFirstSource(): %s has no vertexes to route, ignored."
|
cerr << Error( "Dijkstra::_selectFirstSource(): %s has no vertexes to route, ignored."
|
||||||
, getString(_net).c_str()
|
, getString(_net).c_str()
|
||||||
) << endl;
|
) << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Point areaCenter = _searchArea.getCenter();
|
|
||||||
auto ivertex = _targets.begin();
|
|
||||||
Vertex* firstSource = *ivertex++;
|
|
||||||
DbU::Unit minDistance = areaCenter.manhattanDistance( firstSource->getCenter() );
|
|
||||||
|
|
||||||
for ( ; ivertex != _targets.end() ; ++ivertex ) {
|
Vertex* firstSource = NULL;
|
||||||
DbU::Unit distance = areaCenter.manhattanDistance( (*ivertex)->getCenter() );
|
|
||||||
if (distance < minDistance) {
|
if (_mode & Mode::Monotonic) {
|
||||||
minDistance = distance;
|
if (_targets.size() == 2) {
|
||||||
firstSource = *ivertex;
|
auto ivertex = _targets.begin();
|
||||||
|
Vertex* v1 = *ivertex;
|
||||||
|
Vertex* v2 = *(++ivertex);
|
||||||
|
|
||||||
|
firstSource = (v1->getCenter().getX() <= v2->getCenter().getY()) ? v1 : v2;
|
||||||
|
} else {
|
||||||
|
cerr << Error( "Dijkstra::_selectFirstSource(): %s cannot be routed in monotonic mode.\n"
|
||||||
|
" Must have exactly two terminals (%u), revert to Standart."
|
||||||
|
, getString(_net).c_str()
|
||||||
|
, _targets.size()
|
||||||
|
) << endl;
|
||||||
|
_mode = Mode::Standart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not firstSource) {
|
||||||
|
// Standart routing.
|
||||||
|
Point areaCenter = _searchArea.getCenter();
|
||||||
|
auto ivertex = _targets.begin();
|
||||||
|
|
||||||
|
firstSource = *ivertex++;
|
||||||
|
DbU::Unit minDistance = areaCenter.manhattanDistance( firstSource->getCenter() );
|
||||||
|
|
||||||
|
for ( ; ivertex != _targets.end() ; ++ivertex ) {
|
||||||
|
DbU::Unit distance = areaCenter.manhattanDistance( (*ivertex)->getCenter() );
|
||||||
|
if (distance < minDistance) {
|
||||||
|
minDistance = distance;
|
||||||
|
firstSource = *ivertex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_targets.erase ( firstSource );
|
_targets.erase ( firstSource );
|
||||||
_sources.insert( firstSource );
|
_sources.insert( firstSource );
|
||||||
|
|
||||||
cdebug.log(111) << "Dijkstra::selectFirstSource() " << *_sources.begin() << endl;
|
cdebug.log(111) << "Dijkstra::_selectFirstSource() " << *_sources.begin() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Dijkstra::propagate ()
|
bool Dijkstra::_propagate ( Flags enabledSides )
|
||||||
{
|
{
|
||||||
cdebug.log(111,1) << "Dijkstra::propagate() " << _net << endl;
|
cdebug.log(111,1) << "Dijkstra::_propagate() " << _net << endl;
|
||||||
|
|
||||||
while ( not _queue.empty() ) {
|
while ( not _queue.empty() ) {
|
||||||
_queue.dump();
|
_queue.dump();
|
||||||
|
@ -192,8 +250,6 @@ namespace Anabatic {
|
||||||
Vertex* current = _queue.top();
|
Vertex* current = _queue.top();
|
||||||
_queue.pop();
|
_queue.pop();
|
||||||
|
|
||||||
cdebug.log(111) << "Pop: (size:" << _queue.size() << ") " << current << endl;
|
|
||||||
|
|
||||||
if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) {
|
if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) {
|
||||||
for ( Edge* edge : current->getGCell()->getEdges() ) {
|
for ( Edge* edge : current->getGCell()->getEdges() ) {
|
||||||
|
|
||||||
|
@ -202,26 +258,34 @@ namespace Anabatic {
|
||||||
GCell* gneighbor = edge->getOpposite(current->getGCell());
|
GCell* gneighbor = edge->getOpposite(current->getGCell());
|
||||||
Vertex* vneighbor = gneighbor->getObserver<Vertex>(GCell::Observable::Vertex);
|
Vertex* vneighbor = gneighbor->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||||
|
|
||||||
|
if (not _searchArea.contains(vneighbor->getCenter())) continue;
|
||||||
|
|
||||||
cdebug.log(111) << "| Edge " << edge << endl;
|
cdebug.log(111) << "| Edge " << edge << endl;
|
||||||
cdebug.log(111) << "+ Neighbor: " << vneighbor << endl;
|
cdebug.log(111) << "+ Neighbor: " << vneighbor << endl;
|
||||||
|
|
||||||
|
float distance = getDistance( current, vneighbor, edge );
|
||||||
|
|
||||||
if (vneighbor->getConnexId() == _connectedsId) continue;
|
if (vneighbor->getConnexId() == _connectedsId) continue;
|
||||||
if (vneighbor->getConnexId() >= 0) {
|
if (vneighbor->getConnexId() >= 0) {
|
||||||
vneighbor->setFrom( edge );
|
vneighbor->setFrom ( edge );
|
||||||
|
vneighbor->setDistance( distance );
|
||||||
|
cdebug.log(111) << "Push (before): (size:" << _queue.size() << ")" << endl;
|
||||||
_queue.push( vneighbor );
|
_queue.push( vneighbor );
|
||||||
|
|
||||||
cdebug.log(111) << "Push (target): (size:" << _queue.size() << ") " << vneighbor << endl;
|
cdebug.log(111) << "Push (target): (size:" << _queue.size() << ") " << vneighbor << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float distance = current->getDistance() + edge->getDistance();
|
|
||||||
|
|
||||||
if (distance < vneighbor->getDistance()) {
|
if (distance < vneighbor->getDistance()) {
|
||||||
if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor );
|
cdebug.log(111) << "Push (before erase): (size:" << _queue.size() << ") " << vneighbor << endl;
|
||||||
else {
|
if (vneighbor->getDistance() != Vertex::unreached) {
|
||||||
|
_queue.erase( vneighbor );
|
||||||
|
_queue.dump();
|
||||||
|
} else {
|
||||||
vneighbor->setStamp ( _stamp );
|
vneighbor->setStamp ( _stamp );
|
||||||
vneighbor->setConnexId( -1 );
|
vneighbor->setConnexId( -1 );
|
||||||
}
|
}
|
||||||
|
cdebug.log(111) << "Push (after erase): (size:" << _queue.size() << ")" << endl;
|
||||||
|
|
||||||
vneighbor->setDistance( distance );
|
vneighbor->setDistance( distance );
|
||||||
vneighbor->setFrom ( edge );
|
vneighbor->setFrom ( edge );
|
||||||
|
@ -263,18 +327,27 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Dijkstra::run ()
|
void Dijkstra::run ( Dijkstra::Mode mode )
|
||||||
{
|
{
|
||||||
cdebug.log(111,1) << "Dijkstra::run() on " << _net << endl;
|
DebugSession::open( _net, 110, 120 );
|
||||||
|
|
||||||
selectFirstSource();
|
cdebug.log(111,1) << "Dijkstra::run() on " << _net << " mode:" << mode << endl;
|
||||||
|
_mode = mode;
|
||||||
|
|
||||||
|
_selectFirstSource();
|
||||||
if (_sources.empty()) {
|
if (_sources.empty()) {
|
||||||
cdebug.log(111) << "No source to start, not routed." << endl;
|
cdebug.log(111) << "No source to start, not routed." << endl;
|
||||||
cdebug.tabw(111,-1);
|
cdebug.tabw(111,-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateSession::open();
|
Flags enabledEdges = Flags::AllSides;
|
||||||
|
if (_mode & Mode::Monotonic) {
|
||||||
|
if ((*_sources.begin())->getCenter().getY() <= (*_targets.begin())->getCenter().getY())
|
||||||
|
enabledEdges = Flags::EastSide | Flags::NorthSide;
|
||||||
|
else
|
||||||
|
enabledEdges = Flags::EastSide | Flags::SouthSide;
|
||||||
|
}
|
||||||
|
|
||||||
Vertex* source = *_sources.begin();
|
Vertex* source = *_sources.begin();
|
||||||
_queue.clear();
|
_queue.clear();
|
||||||
|
@ -286,17 +359,17 @@ namespace Anabatic {
|
||||||
<< source
|
<< source
|
||||||
<< " _connectedsId:" << _connectedsId << endl;
|
<< " _connectedsId:" << _connectedsId << endl;
|
||||||
|
|
||||||
while ( not _targets.empty() and propagate() );
|
while ( not _targets.empty() and _propagate(enabledEdges) );
|
||||||
|
|
||||||
toWires();
|
_toWires();
|
||||||
_queue.clear();
|
_queue.clear();
|
||||||
|
|
||||||
UpdateSession::close();
|
|
||||||
cdebug.tabw(111,-1);
|
cdebug.tabw(111,-1);
|
||||||
|
DebugSession::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Dijkstra::toWires ()
|
void Dijkstra::_toWires ()
|
||||||
{
|
{
|
||||||
cdebug.log(111,1) << "Dijkstra::toWires() " << _net << endl;
|
cdebug.log(111,1) << "Dijkstra::toWires() " << _net << endl;
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,15 @@ namespace Anabatic {
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Class : "Anabatic::GCell_Edges".
|
// Class : "Anabatic::GCell_Edges".
|
||||||
|
|
||||||
GCell_Edges::Locator::Locator ( const GCell* gcell )
|
GCell_Edges::Locator::Locator ( const GCell* gcell, Flags filterFlags )
|
||||||
: EdgesHL()
|
: EdgesHL()
|
||||||
, _gcell(gcell)
|
, _gcell (gcell)
|
||||||
, _flags(Flags::EastSide)
|
, _stateFlags (Flags::EastSide)
|
||||||
, _iedge(0)
|
, _filterFlags(filterFlags)
|
||||||
|
, _iedge (0)
|
||||||
{
|
{
|
||||||
// cdebug.log(110) << "GCell_Edges::Locator::Locator() " << isValid() << endl;
|
// cdebug.log(110) << "GCell_Edges::Locator::Locator() " << isValid() << endl;
|
||||||
if (_gcell->getEastEdges().empty()) progress();
|
if (_gcell->getEastEdges().empty() or not _filterFlags.contains(Flags::EastSide)) progress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,21 +47,21 @@ namespace Anabatic {
|
||||||
|
|
||||||
Edge* GCell_Edges::Locator::getElement () const
|
Edge* GCell_Edges::Locator::getElement () const
|
||||||
{
|
{
|
||||||
if (_flags.contains(Flags::EastSide )) return _gcell->getEastEdges ()[_iedge];
|
if (_stateFlags.contains(Flags::EastSide )) return _gcell->getEastEdges ()[_iedge];
|
||||||
if (_flags.contains(Flags::NorthSide)) return _gcell->getNorthEdges()[_iedge];
|
if (_stateFlags.contains(Flags::NorthSide)) return _gcell->getNorthEdges()[_iedge];
|
||||||
if (_flags.contains(Flags::WestSide )) return _gcell->getWestEdges ()[_iedge];
|
if (_stateFlags.contains(Flags::WestSide )) return _gcell->getWestEdges ()[_iedge];
|
||||||
if (_flags.contains(Flags::SouthSide)) return _gcell->getSouthEdges()[_iedge];
|
if (_stateFlags.contains(Flags::SouthSide)) return _gcell->getSouthEdges()[_iedge];
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GCell_Edges::Locator::isValid () const
|
bool GCell_Edges::Locator::isValid () const
|
||||||
{ return _flags; }
|
{ return _stateFlags; }
|
||||||
|
|
||||||
|
|
||||||
void GCell_Edges::Locator::progress ()
|
void GCell_Edges::Locator::progress ()
|
||||||
{
|
{
|
||||||
// cdebug.log(110) << "GCell_Edges::Locator::progress() [from] " << _flags << " iedge:" << _iedge << endl;
|
// cdebug.log(110) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl;
|
||||||
// cdebug.log(110) << " East:" << _gcell->getEastEdges().size()
|
// cdebug.log(110) << " East:" << _gcell->getEastEdges().size()
|
||||||
// << " North:" << _gcell->getNorthEdges().size()
|
// << " North:" << _gcell->getNorthEdges().size()
|
||||||
// << " West:" << _gcell->getWestEdges().size()
|
// << " West:" << _gcell->getWestEdges().size()
|
||||||
|
@ -68,51 +69,51 @@ namespace Anabatic {
|
||||||
// cdebug.log(110) << this << endl;
|
// cdebug.log(110) << this << endl;
|
||||||
|
|
||||||
++_iedge;
|
++_iedge;
|
||||||
while (_flags) {
|
while (_stateFlags) {
|
||||||
if (_flags.contains(Flags::EastSide)) {
|
if ((_stateFlags & _filterFlags).contains(Flags::EastSide)) {
|
||||||
if (_iedge < _gcell->getEastEdges().size()) break;
|
if (_iedge < _gcell->getEastEdges().size()) break;
|
||||||
// cdebug.log(110) << "Switching to North side." << endl;
|
// cdebug.log(110) << "Switching to North side." << endl;
|
||||||
_flags = Flags::NorthSide;
|
_stateFlags = Flags::NorthSide;
|
||||||
_iedge = 0;
|
_iedge = 0;
|
||||||
// cdebug.log(110) << this << endl;
|
// cdebug.log(110) << this << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_flags.contains(Flags::NorthSide)) {
|
if ((_stateFlags & _filterFlags).contains(Flags::NorthSide)) {
|
||||||
if (_iedge < _gcell->getNorthEdges().size()) break;
|
if (_iedge < _gcell->getNorthEdges().size()) break;
|
||||||
// cdebug.log(110) << "Switching to West side." << endl;
|
// cdebug.log(110) << "Switching to West side." << endl;
|
||||||
_flags = Flags::WestSide;
|
_stateFlags = Flags::WestSide;
|
||||||
_iedge = 0;
|
_iedge = 0;
|
||||||
// cdebug.log(110) << this << endl;
|
// cdebug.log(110) << this << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_flags.contains(Flags::WestSide)) {
|
if ((_stateFlags & _filterFlags).contains(Flags::WestSide)) {
|
||||||
if (_iedge < _gcell->getWestEdges().size()) break;
|
if (_iedge < _gcell->getWestEdges().size()) break;
|
||||||
// cdebug.log(110) << "Switching to South side." << endl;
|
// cdebug.log(110) << "Switching to South side." << endl;
|
||||||
_flags = Flags::SouthSide;
|
_stateFlags = Flags::SouthSide;
|
||||||
_iedge = 0;
|
_iedge = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_flags.contains(Flags::SouthSide)) {
|
if ((_stateFlags & _filterFlags).contains(Flags::SouthSide)) {
|
||||||
if (_iedge < _gcell->getSouthEdges().size()) break;
|
if (_iedge < _gcell->getSouthEdges().size()) break;
|
||||||
// cdebug.log(110) << "All edges done." << endl;
|
// cdebug.log(110) << "All edges done." << endl;
|
||||||
_flags = 0;
|
_stateFlags = 0;
|
||||||
_iedge = 0;
|
_iedge = 0;
|
||||||
break;;
|
break;;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _flags << " iedge:" << _iedge << endl;
|
cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _stateFlags << " iedge:" << _iedge << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string GCell_Edges::Locator::_getString () const
|
string GCell_Edges::Locator::_getString () const
|
||||||
{
|
{
|
||||||
string s = "<GCell_Edges::Locator";
|
string s = "<GCell_Edges::Locator";
|
||||||
if (_flags.contains(Flags::EastSide )) s += " East[" + getString(_iedge) + "]";
|
if (_stateFlags.contains(Flags::EastSide )) s += " East[" + getString(_iedge) + "]";
|
||||||
if (_flags.contains(Flags::NorthSide)) s += " North[" + getString(_iedge) + "]";
|
if (_stateFlags.contains(Flags::NorthSide)) s += " North[" + getString(_iedge) + "]";
|
||||||
if (_flags.contains(Flags::WestSide )) s += " West[" + getString(_iedge) + "]";
|
if (_stateFlags.contains(Flags::WestSide )) s += " West[" + getString(_iedge) + "]";
|
||||||
if (_flags.contains(Flags::SouthSide)) s += " South[" + getString(_iedge) + "]";
|
if (_stateFlags.contains(Flags::SouthSide)) s += " South[" + getString(_iedge) + "]";
|
||||||
if (_flags == 0) s += " invalid";
|
if (_stateFlags == 0) s += " invalid";
|
||||||
s += ">";
|
s += ">";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -123,7 +124,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
|
|
||||||
EdgesHL* GCell_Edges::getLocator () const
|
EdgesHL* GCell_Edges::getLocator () const
|
||||||
{ return new Locator (_gcell); }
|
{ return new Locator (_gcell,_filterFlags); }
|
||||||
|
|
||||||
|
|
||||||
string GCell_Edges::_getString () const
|
string GCell_Edges::_getString () const
|
||||||
|
|
|
@ -395,7 +395,7 @@ namespace Anabatic {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateSession::open();
|
//UpdateSession::open();
|
||||||
|
|
||||||
GCell* row = this;
|
GCell* row = this;
|
||||||
GCell* column = NULL;
|
GCell* column = NULL;
|
||||||
|
@ -414,7 +414,7 @@ namespace Anabatic {
|
||||||
column = column->vcut( xcut );
|
column = column->vcut( xcut );
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateSession::close();
|
//UpdateSession::close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,31 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void anabaticTest_5 ( AnabaticEngine* engine )
|
||||||
|
{
|
||||||
|
Cell* cell = engine->getCell();
|
||||||
|
|
||||||
|
|
||||||
|
cell->flattenNets( Cell::Flags::BuildRings );
|
||||||
|
cell->createRoutingPadRings( Cell::Flags::BuildRings );
|
||||||
|
|
||||||
|
//DebugSession::addToTrace( cell->getNet("alu_out(3)") );
|
||||||
|
DebugSession::addToTrace( cell->getNet("imuxe.not_aux2") );
|
||||||
|
|
||||||
|
UpdateSession::open();
|
||||||
|
engine->getSouthWestGCell()->doGrid();
|
||||||
|
|
||||||
|
Dijkstra* dijkstra = new Dijkstra ( engine );
|
||||||
|
for ( Net* net : cell->getNets() ) {
|
||||||
|
if (net->isPower() or net->isClock()) continue;
|
||||||
|
dijkstra->load( net );
|
||||||
|
dijkstra->run();
|
||||||
|
}
|
||||||
|
delete dijkstra;
|
||||||
|
UpdateSession::close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Class : "Anabatic::GraphicAnabaticEngine".
|
// Class : "Anabatic::GraphicAnabaticEngine".
|
||||||
|
|
||||||
|
@ -304,7 +329,8 @@ namespace Anabatic {
|
||||||
//anabaticTest_1( engine );
|
//anabaticTest_1( engine );
|
||||||
//anabaticTest_2( engine );
|
//anabaticTest_2( engine );
|
||||||
//anabaticTest_3( engine );
|
//anabaticTest_3( engine );
|
||||||
anabaticTest_4( engine );
|
//anabaticTest_4( engine );
|
||||||
|
anabaticTest_5( engine );
|
||||||
|
|
||||||
if (_viewer) _viewer->emitCellChanged();
|
if (_viewer) _viewer->emitCellChanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace Anabatic {
|
||||||
static void notify ( Vertex*, unsigned flags );
|
static void notify ( Vertex*, unsigned flags );
|
||||||
public:
|
public:
|
||||||
inline Vertex ( GCell* );
|
inline Vertex ( GCell* );
|
||||||
inline Vertex ( size_t id );
|
//inline Vertex ( size_t id );
|
||||||
inline ~Vertex ();
|
inline ~Vertex ();
|
||||||
inline unsigned int getId () const;
|
inline unsigned int getId () const;
|
||||||
inline GCell* getGCell () const;
|
inline GCell* getGCell () const;
|
||||||
|
@ -92,19 +92,18 @@ namespace Anabatic {
|
||||||
, _distance(unreached)
|
, _distance(unreached)
|
||||||
, _from (NULL)
|
, _from (NULL)
|
||||||
{
|
{
|
||||||
//gcell->setLookup<Vertex>( this );
|
|
||||||
gcell->setObserver( GCell::Observable::Vertex, &_observer );
|
gcell->setObserver( GCell::Observable::Vertex, &_observer );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Vertex::Vertex ( size_t id )
|
// inline Vertex::Vertex ( size_t id )
|
||||||
: _id (id)
|
// : _id (id)
|
||||||
, _gcell (NULL)
|
// , _gcell (NULL)
|
||||||
, _observer((Vertex*)0x1) // To trick the NULL detection.
|
// , _observer((Vertex*)0x1) // To trick the NULL detection.
|
||||||
, _connexId(-1)
|
// , _connexId(-1)
|
||||||
, _stamp (-1)
|
// , _stamp (-1)
|
||||||
, _distance(unreached)
|
// , _distance(unreached)
|
||||||
, _from (NULL)
|
// , _from (NULL)
|
||||||
{ }
|
// { }
|
||||||
|
|
||||||
inline Vertex::~Vertex () { }
|
inline Vertex::~Vertex () { }
|
||||||
inline unsigned int Vertex::getId () const { return _id; }
|
inline unsigned int Vertex::getId () const { return _id; }
|
||||||
|
@ -165,11 +164,22 @@ namespace Anabatic {
|
||||||
inline bool PriorityQueue::empty () const { return _queue.empty(); }
|
inline bool PriorityQueue::empty () const { return _queue.empty(); }
|
||||||
inline size_t PriorityQueue::size () const { return _queue.size(); }
|
inline size_t PriorityQueue::size () const { return _queue.size(); }
|
||||||
inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); }
|
inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); }
|
||||||
inline void PriorityQueue::erase ( Vertex* v ) { _queue.erase(v); }
|
|
||||||
inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); }
|
inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); }
|
||||||
inline void PriorityQueue::pop () { _queue.erase(_queue.begin()); }
|
|
||||||
inline void PriorityQueue::clear () { _queue.clear(); }
|
inline void PriorityQueue::clear () { _queue.clear(); }
|
||||||
|
|
||||||
|
inline void PriorityQueue::pop ()
|
||||||
|
{
|
||||||
|
cdebug.log(111) << "Pop: (size:" << _queue.size() << ") " << *_queue.begin() << std::endl;
|
||||||
|
_queue.erase(_queue.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PriorityQueue::erase ( Vertex* v )
|
||||||
|
{
|
||||||
|
for ( auto ivertex = _queue.begin() ; ivertex != _queue.end() ; ++ivertex ) {
|
||||||
|
if (*ivertex == v) { _queue.erase( ivertex ); break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void PriorityQueue::dump () const
|
inline void PriorityQueue::dump () const
|
||||||
{
|
{
|
||||||
if (cdebug.enabled(111)) {
|
if (cdebug.enabled(111)) {
|
||||||
|
@ -187,20 +197,40 @@ namespace Anabatic {
|
||||||
|
|
||||||
class Dijkstra {
|
class Dijkstra {
|
||||||
public:
|
public:
|
||||||
Dijkstra ( AnabaticEngine* );
|
// Mode sub-classe.
|
||||||
~Dijkstra ();
|
class Mode : public Hurricane::BaseFlags {
|
||||||
|
public:
|
||||||
|
enum Flag { NoMode = 0
|
||||||
|
, Standart = (1<<0)
|
||||||
|
, Monotonic = (1<<1)
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
inline Mode ( unsigned int flags=NoMode );
|
||||||
|
inline Mode ( BaseFlags );
|
||||||
|
virtual ~Mode ();
|
||||||
|
virtual std::string _getTypeName () const;
|
||||||
|
virtual std::string _getString () const;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void load ( Net* );
|
float getDistance ( const Vertex*, const Vertex*, const Edge* );
|
||||||
void run ();
|
public:
|
||||||
bool propagate ();
|
Dijkstra ( AnabaticEngine* );
|
||||||
void selectFirstSource ();
|
~Dijkstra ();
|
||||||
void toWires ();
|
public:
|
||||||
|
inline bool isBipoint () const;
|
||||||
|
void load ( Net* );
|
||||||
|
void run ( Mode mode=Mode::Standart );
|
||||||
private:
|
private:
|
||||||
Dijkstra ( const Dijkstra& );
|
Dijkstra ( const Dijkstra& );
|
||||||
Dijkstra& operator= ( const Dijkstra& );
|
Dijkstra& operator= ( const Dijkstra& );
|
||||||
|
bool _propagate ( Flags enabledSides );
|
||||||
|
void _selectFirstSource ();
|
||||||
|
void _toWires ();
|
||||||
private:
|
private:
|
||||||
AnabaticEngine* _anabatic;
|
AnabaticEngine* _anabatic;
|
||||||
vector<Vertex*> _vertexes;
|
vector<Vertex*> _vertexes;
|
||||||
|
Mode _mode;
|
||||||
Net* _net;
|
Net* _net;
|
||||||
int _stamp;
|
int _stamp;
|
||||||
VertexSet _sources;
|
VertexSet _sources;
|
||||||
|
@ -211,10 +241,17 @@ namespace Anabatic {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline Dijkstra::Mode::Mode ( unsigned int flags ) : BaseFlags(flags) { }
|
||||||
|
inline Dijkstra::Mode::Mode ( BaseFlags base ) : BaseFlags(base) { }
|
||||||
|
|
||||||
|
inline bool Dijkstra::isBipoint () const { return _net and (_targets.size()+_sources.size() == 2); }
|
||||||
|
|
||||||
|
|
||||||
} // Anabatic namespace.
|
} // Anabatic namespace.
|
||||||
|
|
||||||
|
|
||||||
GETSTRING_POINTER_SUPPORT(Anabatic::Vertex);
|
GETSTRING_POINTER_SUPPORT(Anabatic::Vertex);
|
||||||
IOSTREAM_POINTER_SUPPORT(Anabatic::Vertex);
|
IOSTREAM_POINTER_SUPPORT(Anabatic::Vertex);
|
||||||
|
INSPECTOR_PV_SUPPORT(Anabatic::Dijkstra::Mode);
|
||||||
|
|
||||||
#endif // ANABATIC_DIJKSTRA_H
|
#endif // ANABATIC_DIJKSTRA_H
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace Anabatic {
|
||||||
// Sub-Class: Locator.
|
// Sub-Class: Locator.
|
||||||
class Locator : public EdgesHL {
|
class Locator : public EdgesHL {
|
||||||
public:
|
public:
|
||||||
Locator ( const GCell* gcell );
|
Locator ( const GCell* gcell, Flags filterFlags );
|
||||||
inline Locator ( const Locator& );
|
inline Locator ( const Locator& );
|
||||||
virtual Edge* getElement () const;
|
virtual Edge* getElement () const;
|
||||||
virtual EdgesHL* getClone () const;
|
virtual EdgesHL* getClone () const;
|
||||||
|
@ -67,41 +67,46 @@ namespace Anabatic {
|
||||||
virtual string _getString () const;
|
virtual string _getString () const;
|
||||||
protected:
|
protected:
|
||||||
const GCell* _gcell;
|
const GCell* _gcell;
|
||||||
Flags _flags;
|
Flags _stateFlags;
|
||||||
|
Flags _filterFlags;
|
||||||
size_t _iedge;
|
size_t _iedge;
|
||||||
};
|
};
|
||||||
|
|
||||||
// GCell_Edges.
|
// GCell_Edges.
|
||||||
public:
|
public:
|
||||||
inline GCell_Edges ( const GCell* gcell );
|
inline GCell_Edges ( const GCell* gcell, Flags filterFlags=Flags::AllSides );
|
||||||
inline GCell_Edges ( const GCell_Edges& );
|
inline GCell_Edges ( const GCell_Edges& );
|
||||||
virtual EdgesHC* getClone () const;
|
virtual EdgesHC* getClone () const;
|
||||||
virtual EdgesHL* getLocator () const;
|
virtual EdgesHL* getLocator () const;
|
||||||
virtual string _getString () const;
|
virtual string _getString () const;
|
||||||
protected:
|
protected:
|
||||||
const GCell* _gcell;
|
const GCell* _gcell;
|
||||||
|
Flags _filterFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline GCell_Edges::Locator::Locator ( const Locator &locator )
|
inline GCell_Edges::Locator::Locator ( const Locator &locator )
|
||||||
: EdgesHL()
|
: EdgesHL()
|
||||||
, _gcell(locator._gcell)
|
, _gcell (locator._gcell)
|
||||||
, _flags(locator._flags)
|
, _stateFlags (locator._stateFlags)
|
||||||
, _iedge(locator._iedge)
|
, _filterFlags(locator._filterFlags)
|
||||||
|
, _iedge (locator._iedge)
|
||||||
{
|
{
|
||||||
// cdebug.log(110) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl;
|
// cdebug.log(110) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline GCell_Edges::GCell_Edges ( const GCell* gcell )
|
inline GCell_Edges::GCell_Edges ( const GCell* gcell, Flags filterFlags )
|
||||||
: EdgesHC()
|
: EdgesHC()
|
||||||
, _gcell(gcell)
|
, _gcell (gcell)
|
||||||
|
, _filterFlags(filterFlags)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
inline GCell_Edges::GCell_Edges ( const GCell_Edges& edges )
|
inline GCell_Edges::GCell_Edges ( const GCell_Edges& edges )
|
||||||
: EdgesHC()
|
: EdgesHC()
|
||||||
, _gcell(edges._gcell)
|
, _gcell (edges._gcell)
|
||||||
|
, _filterFlags(edges._filterFlags)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue