2016-05-30 04:30:29 -05:00
|
|
|
// -*- mode: C++; explicit-buffer-name: "Dijkstra.cpp<anabatic>" -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
|
|
|
// Copyright (c) UPMC 2016-2016, All Rights Reserved
|
|
|
|
//
|
|
|
|
// +-----------------------------------------------------------------+
|
|
|
|
// | C O R I O L I S |
|
|
|
|
// | A n a b a t i c - Global Routing Toolbox |
|
|
|
|
// | |
|
|
|
|
// | Author : Jean-Paul CHAPUT |
|
|
|
|
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
|
|
|
// | =============================================================== |
|
|
|
|
// | C++ Module : "./anabatic/Dijkstra.cpp" |
|
|
|
|
// +-----------------------------------------------------------------+
|
|
|
|
|
|
|
|
|
|
|
|
#include <limits>
|
|
|
|
#include "hurricane/Error.h"
|
|
|
|
#include "hurricane/Net.h"
|
|
|
|
#include "hurricane/RoutingPad.h"
|
|
|
|
#include "hurricane/Horizontal.h"
|
|
|
|
#include "hurricane/Vertical.h"
|
|
|
|
#include "hurricane/UpdateSession.h"
|
|
|
|
#include "anabatic/AnabaticEngine.h"
|
|
|
|
#include "anabatic/Dijkstra.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace Anabatic {
|
|
|
|
|
|
|
|
using std::cerr;
|
|
|
|
using std::endl;
|
|
|
|
using std::numeric_limits;
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
using Hurricane::ForEachIterator;
|
2016-05-30 04:30:29 -05:00
|
|
|
using Hurricane::Error;
|
|
|
|
using Hurricane::Component;
|
|
|
|
using Hurricane::Horizontal;
|
|
|
|
using Hurricane::Vertical;
|
|
|
|
using Hurricane::RoutingPad;
|
|
|
|
using Hurricane::UpdateSession;
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "Anabatic::Vertex".
|
|
|
|
|
|
|
|
|
|
|
|
float Vertex::unreached = numeric_limits<float>::max();
|
|
|
|
|
|
|
|
|
|
|
|
bool Vertex::hasValidStamp () const
|
|
|
|
{ return _stamp == getAnabatic()->getStamp(); }
|
|
|
|
|
|
|
|
|
2016-05-30 11:52:38 -05:00
|
|
|
string Vertex::_getString () const
|
|
|
|
{
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
if (not _gcell) {
|
|
|
|
string s = "<Vertex [key] " + getString(_id) + ">";
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2016-05-30 11:52:38 -05:00
|
|
|
string s = "<Vertex " + getString(_id)
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
+ " @(" + DbU::getValueString(_gcell->getXMin())
|
|
|
|
+ "," + DbU::getValueString(_gcell->getYMin()) + ")"
|
2016-05-30 11:52:38 -05:00
|
|
|
+ " connexId:" + getString(_connexId)
|
|
|
|
+ " d:" + ((_distance == unreached) ? "unreached" : getString(_distance) )
|
2016-06-03 10:29:22 -05:00
|
|
|
+ " stamp:" + (hasValidStamp() ? "valid" : "outdated")
|
|
|
|
+ " from:" + ((_from) ? "set" : "NULL")
|
2016-05-30 11:52:38 -05:00
|
|
|
+ ">";
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-03 10:29:22 -05:00
|
|
|
void Vertex::notify ( Vertex* vertex, unsigned int flags )
|
|
|
|
{
|
|
|
|
//Vertex* vertex = getOwner();
|
|
|
|
cdebug.log(111) << "Vertex::notify() " << vertex << endl;
|
|
|
|
// Take into account the GCell modification here.
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-30 04:30:29 -05:00
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "Anabatic::Dijkstra".
|
|
|
|
|
|
|
|
|
|
|
|
Dijkstra::Dijkstra ( AnabaticEngine* anabatic )
|
|
|
|
: _anabatic (anabatic)
|
|
|
|
, _vertexes ()
|
|
|
|
, _net (NULL)
|
|
|
|
, _stamp (-1)
|
|
|
|
, _sources ()
|
|
|
|
, _targets ()
|
|
|
|
, _searchArea ()
|
|
|
|
, _connectedsId(-1)
|
|
|
|
, _queue ()
|
|
|
|
{
|
|
|
|
const vector<GCell*>& gcells = _anabatic->getGCells();
|
|
|
|
for ( GCell* gcell : gcells ) {
|
|
|
|
_vertexes.push_back( new Vertex (gcell) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Dijkstra::~Dijkstra ()
|
|
|
|
{
|
|
|
|
for ( Vertex* vertex : _vertexes ) delete vertex;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Dijkstra::load ( Net* net )
|
|
|
|
{
|
2016-05-30 11:52:38 -05:00
|
|
|
_net = net;
|
|
|
|
|
|
|
|
cdebug.log(111,1) << "Dijkstra::load() " << _net << endl;
|
2016-05-30 04:30:29 -05:00
|
|
|
UpdateSession::open();
|
|
|
|
|
2016-05-30 11:52:38 -05:00
|
|
|
_sources.clear();
|
|
|
|
_targets.clear();
|
2016-05-30 04:30:29 -05:00
|
|
|
_searchArea.makeEmpty();
|
|
|
|
_stamp = _anabatic->incStamp();
|
|
|
|
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
vector<RoutingPad*> rps;
|
|
|
|
for ( RoutingPad* rp : _net->getRoutingPads() ) rps.push_back( rp );
|
|
|
|
for ( RoutingPad* rp : rps ) {
|
|
|
|
Box rpBb = rp->getBoundingBox();
|
|
|
|
Point center = rpBb.getCenter();
|
|
|
|
GCell* gcell = _anabatic->getGCellUnder( center );
|
2016-05-30 04:30:29 -05:00
|
|
|
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
if (not gcell) {
|
|
|
|
cerr << Error( "Dijkstra::load(): %s of %s is not under any GCell.\n"
|
|
|
|
" It will be ignored ans the routing will be incomplete."
|
|
|
|
, getString(rp ).c_str()
|
|
|
|
, getString(_net).c_str()
|
|
|
|
) << endl;
|
|
|
|
continue;
|
|
|
|
}
|
2016-05-30 04:30:29 -05:00
|
|
|
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
_searchArea.merge( rpBb );
|
2016-05-30 04:30:29 -05:00
|
|
|
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
Vertex* vertex = gcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
|
|
|
if (vertex->getConnexId() < 0) {
|
|
|
|
vertex->setStamp ( _stamp );
|
|
|
|
vertex->setConnexId( _targets.size() );
|
|
|
|
vertex->setFrom ( NULL );
|
|
|
|
Contact* gcontact = vertex->getGContact( _net );
|
|
|
|
rp->getBodyHook()->detach();
|
|
|
|
rp->getBodyHook()->attach( gcontact->getBodyHook() );
|
|
|
|
_targets.insert( vertex );
|
2016-05-30 11:52:38 -05:00
|
|
|
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
cdebug.log(111) << "Add Vertex: " << vertex << endl;
|
2016-05-30 04:30:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateSession::close();
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.tabw(111,-1);
|
2016-05-30 04:30:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Dijkstra::selectFirstSource ()
|
|
|
|
{
|
|
|
|
if (_targets.empty()) {
|
2016-05-30 11:52:38 -05:00
|
|
|
cerr << Error( "Dijkstra::selectFirstSource(): %s has no vertexes to route, ignored."
|
2016-05-30 04:30:29 -05:00
|
|
|
, getString(_net).c_str()
|
|
|
|
) << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Point areaCenter = _searchArea.getCenter();
|
|
|
|
auto ivertex = _targets.begin();
|
|
|
|
Vertex* 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-30 11:52:38 -05:00
|
|
|
_targets.erase ( firstSource );
|
|
|
|
_sources.insert( firstSource );
|
|
|
|
|
|
|
|
cdebug.log(111) << "Dijkstra::selectFirstSource() " << *_sources.begin() << endl;
|
2016-05-30 04:30:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-30 11:52:38 -05:00
|
|
|
bool Dijkstra::propagate ()
|
2016-05-30 04:30:29 -05:00
|
|
|
{
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.log(111,1) << "Dijkstra::propagate() " << _net << endl;
|
|
|
|
|
2016-05-30 04:30:29 -05:00
|
|
|
while ( not _queue.empty() ) {
|
2016-05-30 11:52:38 -05:00
|
|
|
_queue.dump();
|
|
|
|
|
2016-05-30 04:30:29 -05:00
|
|
|
Vertex* current = _queue.top();
|
|
|
|
_queue.pop();
|
|
|
|
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.log(111) << "Pop: (size:" << _queue.size() << ") " << current << endl;
|
|
|
|
|
2016-05-30 04:30:29 -05:00
|
|
|
if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) {
|
|
|
|
for ( Edge* edge : current->getGCell()->getEdges() ) {
|
2016-05-30 11:52:38 -05:00
|
|
|
|
2016-05-30 04:30:29 -05:00
|
|
|
if (edge == current->getFrom()) continue;
|
|
|
|
|
|
|
|
GCell* gneighbor = edge->getOpposite(current->getGCell());
|
2016-06-03 10:29:22 -05:00
|
|
|
Vertex* vneighbor = gneighbor->getObserver<Vertex>(GCell::Observable::Vertex);
|
2016-05-30 04:30:29 -05:00
|
|
|
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
cdebug.log(111) << "| Edge " << edge << endl;
|
|
|
|
cdebug.log(111) << "+ Neighbor: " << vneighbor << endl;
|
2016-05-30 11:52:38 -05:00
|
|
|
|
2016-05-30 04:30:29 -05:00
|
|
|
if (vneighbor->getConnexId() == _connectedsId) continue;
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
if (vneighbor->getConnexId() >= 0) {
|
|
|
|
vneighbor->setFrom( edge );
|
|
|
|
_queue.push( vneighbor );
|
|
|
|
|
|
|
|
cdebug.log(111) << "Push (target): (size:" << _queue.size() << ") " << vneighbor << endl;
|
|
|
|
continue;
|
|
|
|
}
|
2016-05-30 04:30:29 -05:00
|
|
|
|
|
|
|
float distance = current->getDistance() + edge->getDistance();
|
2016-05-30 11:52:38 -05:00
|
|
|
|
|
|
|
if (distance < vneighbor->getDistance()) {
|
2016-05-30 04:30:29 -05:00
|
|
|
if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor );
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
else {
|
|
|
|
vneighbor->setStamp ( _stamp );
|
|
|
|
vneighbor->setConnexId( -1 );
|
|
|
|
}
|
2016-05-30 04:30:29 -05:00
|
|
|
|
|
|
|
vneighbor->setDistance( distance );
|
2016-05-30 11:52:38 -05:00
|
|
|
vneighbor->setFrom ( edge );
|
2016-05-30 04:30:29 -05:00
|
|
|
_queue.push( vneighbor );
|
2016-05-30 11:52:38 -05:00
|
|
|
|
|
|
|
cdebug.log(111) << "Push: (size:" << _queue.size() << ") " << vneighbor << endl;
|
2016-05-30 04:30:29 -05:00
|
|
|
}
|
|
|
|
}
|
2016-05-30 11:52:38 -05:00
|
|
|
|
|
|
|
continue;
|
2016-05-30 04:30:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// We did reach another target (different <connexId>).
|
|
|
|
// Tag back the path.
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.log(111) << "Trace back" << endl;
|
2016-05-30 04:30:29 -05:00
|
|
|
_targets.erase( current );
|
|
|
|
while ( current ) {
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.log(111) << "| " << current << endl;
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
if (current->getConnexId() == _connectedsId) break;
|
2016-06-03 10:29:22 -05:00
|
|
|
|
2016-05-30 04:30:29 -05:00
|
|
|
_sources.insert( current );
|
|
|
|
current->setDistance( 0.0 );
|
|
|
|
current->setConnexId( _connectedsId );
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
_queue.push( current );
|
2016-06-03 10:29:22 -05:00
|
|
|
|
Anabatic transient commit 6 "Somatoline, ca marche!".
* Bug: In Anabatic:
- In Dijktra::load(), do not create Contact while looping over the Net's
components (for RoutingPads).
- In Dijkstra::propagate(), reset the connexId of reached Vertexes
on updating the stamp to avoid using connexId from previous runs.
Push the vertexes on the queue while backtracking (with a distance
of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires()
to know how were the routing is.
- In Edge::getDistance(), convert to float more early so the normalisation
do not always end up in zero.
- In GCell::_add(), when the axis of the new edge is equal to one already
on the given side, adds it *after* the existing edge and not before.
(to be coherent with the way GCells are split in two)
- In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max,
*but* the new chunk is flat. The new chunk is then expected to expand
"below".
- In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in
a small box at the center of it's bounding box. Nothing displayed for
flat GCells, to avoid cluttering.
2016-06-05 11:38:09 -05:00
|
|
|
current = current->getPredecessor();
|
2016-05-30 04:30:29 -05:00
|
|
|
}
|
|
|
|
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.tabw(111,-1);
|
|
|
|
return true;
|
2016-05-30 04:30:29 -05:00
|
|
|
}
|
2016-05-30 11:52:38 -05:00
|
|
|
|
|
|
|
cerr << Error( "Dijkstra::propagate(): %s has unreachable targets."
|
|
|
|
, getString(_net).c_str()
|
|
|
|
) << endl;
|
|
|
|
|
|
|
|
cdebug.tabw(111,-1);
|
|
|
|
return false;
|
2016-05-30 04:30:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Dijkstra::run ()
|
|
|
|
{
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.log(111,1) << "Dijkstra::run() on " << _net << endl;
|
|
|
|
|
|
|
|
selectFirstSource();
|
|
|
|
if (_sources.empty()) {
|
|
|
|
cdebug.log(111) << "No source to start, not routed." << endl;
|
|
|
|
cdebug.tabw(111,-1);
|
|
|
|
return;
|
|
|
|
}
|
2016-05-30 04:30:29 -05:00
|
|
|
|
|
|
|
UpdateSession::open();
|
|
|
|
|
2016-05-30 11:52:38 -05:00
|
|
|
Vertex* source = *_sources.begin();
|
2016-05-30 04:30:29 -05:00
|
|
|
_queue.clear();
|
2016-05-30 11:52:38 -05:00
|
|
|
_queue.push( source );
|
|
|
|
_connectedsId = source->getConnexId();
|
|
|
|
source->setDistance( 0.0 );
|
2016-05-30 04:30:29 -05:00
|
|
|
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.log(111) << "Push source: (size:" << _queue.size() << ") "
|
|
|
|
<< source
|
|
|
|
<< " _connectedsId:" << _connectedsId << endl;
|
|
|
|
|
|
|
|
while ( not _targets.empty() and propagate() );
|
2016-05-30 04:30:29 -05:00
|
|
|
|
|
|
|
toWires();
|
2016-05-30 11:52:38 -05:00
|
|
|
_queue.clear();
|
2016-05-30 04:30:29 -05:00
|
|
|
|
|
|
|
UpdateSession::close();
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.tabw(111,-1);
|
2016-05-30 04:30:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Dijkstra::toWires ()
|
|
|
|
{
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.log(111,1) << "Dijkstra::toWires() " << _net << endl;
|
|
|
|
|
2016-05-30 04:30:29 -05:00
|
|
|
for ( Vertex* vertex : _sources ) {
|
|
|
|
Edge* from = vertex->getFrom();
|
|
|
|
if (not from) continue;
|
|
|
|
|
2016-05-30 11:52:38 -05:00
|
|
|
cdebug.log(111) << "| " << vertex << endl;
|
|
|
|
|
|
|
|
from->incRealOccupancy( 1 );
|
|
|
|
|
2016-05-30 04:30:29 -05:00
|
|
|
Vertex* source = vertex;
|
|
|
|
Vertex* target = source->getPredecessor();
|
|
|
|
|
|
|
|
if ( (source->getGCell()->getXMin() > target->getGCell()->getXMin())
|
|
|
|
or (source->getGCell()->getYMin() > target->getGCell()->getYMin()) )
|
|
|
|
std::swap( source, target );
|
|
|
|
|
|
|
|
Contact* sourceContact = source->getGContact( _net );
|
2016-05-30 11:52:38 -05:00
|
|
|
Contact* targetContact = target->getGContact( _net );
|
2016-05-30 04:30:29 -05:00
|
|
|
|
|
|
|
if (from->isHorizontal()) {
|
|
|
|
Horizontal::create( sourceContact
|
|
|
|
, targetContact
|
|
|
|
, _anabatic->getConfiguration()->getGHorizontalLayer()
|
|
|
|
, from->getAxis()
|
|
|
|
, DbU::fromLambda(2.0)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
Vertical::create( sourceContact
|
|
|
|
, targetContact
|
|
|
|
, _anabatic->getConfiguration()->getGVerticalLayer()
|
|
|
|
, from->getAxis()
|
|
|
|
, DbU::fromLambda(2.0)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2016-05-30 11:52:38 -05:00
|
|
|
|
|
|
|
cdebug.tabw(111,-1);
|
2016-05-30 04:30:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // Anabatic namespace.
|