Anabatic transient commit 10. Ripup & reroute support in Dijsktra.

* New: In Anabatic:
    - In AnabaticEngine, keep track of overflowed edges.
    - In AnabaticEngine, getNetsFromedge() to lookup all nets going
      through an Edge.
    - In Configuration, read the Kite "reserved local" parameter to
      decrease the Edge capacity (it's a guessing of the cost of the
      local routing).
    - In Edge, add an attribute to know if there is an associated
      segment of the current net (set by Dijkstra::_traceback()).
      Transparently manage the overflowed edges.
    - In GCell_Edges, correct a filtering bug when not all sides are
      selecteds.
    - New GCell::getEdgeTo() to find the edge between two adjacent
      GCells.
    - New GCell::unrefContact() to automatically removes global contacts
      no longer used by any global segments (used during the ripup
      step).
    - In Dijkstra::load(), now able to "reload" and already partially
      or completly routed net (look for Contact of "gcontact" layer
      and their attached segments).
    - In Dijkstra, keep the last net loaded until the next one is.
      Put the cleanup operations in an isolated function "_cleanup()".
    - In Dijkstra::_selectFirstsource() and run(), load first source
      component made of multiple vertexes.
    - In Dijkstra::_trackback(), link the Net segments to the Edges.
    - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform
      the ripup of one edge of a Net (must be loaded in Dijkstra first).
      Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes
    - that are connecteds through edges *with* segments.
    - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global
      routing tool with ripup & reroute.
This commit is contained in:
Jean-Paul Chaput 2016-06-26 14:32:32 +02:00
parent 379effd92c
commit abf58190eb
15 changed files with 837 additions and 168 deletions

View File

@ -18,6 +18,8 @@
#include <iostream> #include <iostream>
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "hurricane/RegularLayer.h" #include "hurricane/RegularLayer.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "hurricane/UpdateSession.h" #include "hurricane/UpdateSession.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
@ -33,6 +35,9 @@ namespace Anabatic {
using std::ostringstream; using std::ostringstream;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::RegularLayer; using Hurricane::RegularLayer;
using Hurricane::Component;
using Hurricane::Horizontal;
using Hurricane::Vertical;
using Hurricane::Cell; using Hurricane::Cell;
using Hurricane::UpdateSession; using Hurricane::UpdateSession;
using CRL::RoutingGauge; using CRL::RoutingGauge;
@ -63,6 +68,7 @@ namespace Anabatic {
, _configuration (new ConfigurationConcrete()) , _configuration (new ConfigurationConcrete())
, _matrix () , _matrix ()
, _gcells () , _gcells ()
, _ovEdges ()
, _viewer (NULL) , _viewer (NULL)
, _flags (Flags::NoFlags) , _flags (Flags::NoFlags)
, _stamp (-1) , _stamp (-1)
@ -114,6 +120,7 @@ namespace Anabatic {
for ( GCell* gcell : _gcells ) gcell->_destroyEdges(); for ( GCell* gcell : _gcells ) gcell->_destroyEdges();
for ( GCell* gcell : _gcells ) gcell->destroy(); for ( GCell* gcell : _gcells ) gcell->destroy();
_gcells.clear(); _gcells.clear();
_ovEdges.clear();
} }
@ -164,6 +171,39 @@ namespace Anabatic {
} }
size_t AnabaticEngine::getNetsFromEdge ( const Edge* edge, NetSet& nets )
{
size_t count = 0;
GCell* source = edge->getSource();
GCell* target = edge->getTarget();
const vector<Contact*>& contacts = source->getGContacts();
for ( Contact* contact : contacts ) {
for ( Component* component : contact->getSlaveComponents() ) {
if (edge->isHorizontal()) {
Horizontal* horizontal = dynamic_cast<Horizontal*>( component );
if (horizontal
and (horizontal->getSource() == contact)
and (target->hasGContact(dynamic_cast<Contact*>(horizontal->getTarget())))) {
nets.insert( horizontal->getNet() );
++count;
}
}
if (edge->isVertical()) {
Vertical* vertical = dynamic_cast<Vertical*>( component );
if (vertical
and (vertical->getSource() == contact)
and (target->hasGContact(dynamic_cast<Contact*>(vertical->getTarget())))) {
nets.insert( vertical->getNet() );
++count;
}
}
}
}
return count;
}
void AnabaticEngine::startMeasures () void AnabaticEngine::startMeasures ()
{ {
_timer.resetIncrease(); _timer.resetIncrease();

View File

@ -32,6 +32,7 @@ endif ( CHECK_DETERMINISM )
Edges.cpp Edges.cpp
GCell.cpp GCell.cpp
AnabaticEngine.cpp AnabaticEngine.cpp
GlobalRoute.cpp
GraphicAnabaticEngine.cpp GraphicAnabaticEngine.cpp
Dijkstra.cpp Dijkstra.cpp
) )

View File

@ -75,6 +75,8 @@ namespace Anabatic {
, _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt())) , _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt()))
, _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH", 9.0)->asDouble()) , _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH", 9.0)->asDouble())
, _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK",-10.0)->asDouble()) , _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK",-10.0)->asDouble())
, _hEdgeLocal (Cfg::getParamInt("kite.hTracksReservedLocal",0)->asInt())
, _vEdgeLocal (Cfg::getParamInt("kite.vTracksReservedLocal",0)->asInt())
{ {
if (cg == NULL) cg = AllianceFramework::get()->getCellGauge(); if (cg == NULL) cg = AllianceFramework::get()->getCellGauge();
if (rg == NULL) rg = AllianceFramework::get()->getRoutingGauge(); if (rg == NULL) rg = AllianceFramework::get()->getRoutingGauge();
@ -288,6 +290,14 @@ namespace Anabatic {
{ return _edgeWidth; } { return _edgeWidth; }
size_t ConfigurationConcrete::getHEdgeLocal () const
{ return _hEdgeLocal; }
size_t ConfigurationConcrete::getVEdgeLocal () const
{ return _vEdgeLocal; }
float ConfigurationConcrete::getEdgeCostH () const float ConfigurationConcrete::getEdgeCostH () const
{ return _edgeCostH; } { return _edgeCostH; }

View File

@ -35,6 +35,7 @@ namespace Anabatic {
using Hurricane::ForEachIterator; using Hurricane::ForEachIterator;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::Component; using Hurricane::Component;
using Hurricane::Segment;
using Hurricane::Horizontal; using Hurricane::Horizontal;
using Hurricane::Vertical; using Hurricane::Vertical;
using Hurricane::RoutingPad; using Hurricane::RoutingPad;
@ -63,7 +64,7 @@ namespace Anabatic {
string s = "<Vertex " + getString(_id) string s = "<Vertex " + getString(_id)
+ " @(" + DbU::getValueString(_gcell->getXMin()) + " @(" + DbU::getValueString(_gcell->getXMin())
+ "," + DbU::getValueString(_gcell->getYMin()) + ")" + "," + DbU::getValueString(_gcell->getYMin()) + ")"
+ " connexId:" + getString(_connexId) + " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None")
+ " d:" + ((_distance == unreached) ? "unreached" : DbU::getValueString(_distance) ) + " d:" + ((_distance == unreached) ? "unreached" : DbU::getValueString(_distance) )
+ "+" + getString(_branchId) + "+" + getString(_branchId)
+ " stamp:" + (hasValidStamp() ? "valid" : "outdated") + " stamp:" + (hasValidStamp() ? "valid" : "outdated")
@ -143,27 +144,45 @@ namespace Anabatic {
void Dijkstra::load ( Net* net ) void Dijkstra::load ( Net* net )
{ {
_net = net; _cleanup();
const Layer* gcontactLayer = _anabatic->getConfiguration()->getGContactLayer();
_net = net;
_stamp = _anabatic->incStamp();
DebugSession::open( _net, 112, 120 ); DebugSession::open( _net, 112, 120 );
cdebug_log(112,1) << "Dijkstra::load() " << _net << endl; cdebug_log(112,1) << "Dijkstra::load() " << _net << endl;
_sources.clear(); vector< std::pair<Component*,bool> > components;
_targets.clear(); for ( Component* component : _net->getComponents() ) {
_searchArea.makeEmpty(); RoutingPad* rp = dynamic_cast<RoutingPad*>( component );
_stamp = _anabatic->incStamp(); if (rp) { components.push_back( make_pair(rp,true) ); continue; }
vector<RoutingPad*> rps; Contact* gcontact = dynamic_cast<Contact*>( component );
for ( RoutingPad* rp : _net->getRoutingPads() ) rps.push_back( rp ); if (gcontact and (gcontact->getLayer() == gcontactLayer))
for ( RoutingPad* rp : rps ) { components.push_back( make_pair(gcontact,false) );
Box rpBb = rp->getBoundingBox(); }
Point center = rpBb.getCenter();
GCell* gcell = _anabatic->getGCellUnder( center ); for ( auto element : components ) {
RoutingPad* rp = NULL;
Contact* gcontact = NULL;
Point center;
if (element.second) {
rp = static_cast<RoutingPad*>( element.first );
center = rp->getBoundingBox().getCenter();
} else {
gcontact = static_cast<Contact*>( element.first );
center = gcontact->getCenter();
}
GCell* gcell = _anabatic->getGCellUnder( center );
if (not gcell) { if (not gcell) {
cerr << Error( "Dijkstra::load(): %s of %s is not under any GCell.\n" cerr << Error( "Dijkstra::load(): %s of %s is not under any GCell.\n"
" It will be ignored ans the routing will be incomplete." " It will be ignored so the routing may be incomplete."
, getString(rp ).c_str() , getString(element.first).c_str()
, getString(_net).c_str() , getString(_net).c_str()
) << endl; ) << endl;
continue; continue;
@ -175,16 +194,70 @@ namespace Anabatic {
if (vertex->getConnexId() < 0) { if (vertex->getConnexId() < 0) {
vertex->setDistance( Vertex::unreached ); vertex->setDistance( Vertex::unreached );
vertex->setStamp ( _stamp ); vertex->setStamp ( _stamp );
vertex->setConnexId( _targets.size() ); vertex->setConnexId( _connectedsId );
vertex->setBranchId( 0 ); vertex->setBranchId( 0 );
vertex->setFrom ( NULL ); vertex->setFrom ( NULL );
_targets.insert( vertex ); _targets.insert( vertex );
cdebug_log(112,0) << "Add Vertex: " << vertex << endl; cdebug_log(112,0) << "Add Vertex: " << vertex << endl;
} }
Contact* gcontact = vertex->getGContact( _net ); if (gcontact) {
rp->getBodyHook()->detach(); for ( Component* slave : gcontact->getSlaveComponents() ) {
rp->getBodyHook()->attach( gcontact->getBodyHook() ); Flags sideHint = Flags::NoFlags;
GCell* oppositeGCell = NULL;
Segment* segment = dynamic_cast<Horizontal*>(slave);
if (segment) {
cdebug_log(112,0) << "| " << segment << endl;
if (segment->getSource() == gcontact) {
oppositeGCell = _anabatic->getGCellUnder( segment->getTarget()->getCenter() );
sideHint = Flags::EastSide;
} else
if (segment->getTarget() == gcontact) {
cdebug_log(112,0) << " Connected by target, skipped." << endl;
continue;
}
} else {
segment = dynamic_cast<Vertical*>(slave);
if (segment) {
cdebug_log(112,0) << "| " << segment << endl;
if (segment->getSource() == gcontact) {
oppositeGCell = _anabatic->getGCellUnder( segment->getTarget()->getCenter() );
sideHint = Flags::NorthSide;
} else
if (segment->getTarget() == gcontact) {
cdebug_log(112,0) << " Connected by target, skipped." << endl;
continue;
}
}
}
Edge* edge = gcell->getEdgeTo( oppositeGCell, sideHint );
if (edge) {
cdebug_log(112,0) << "+ Associated to edge." << endl;
edge->setSegment( segment );
} else
cerr << Error( "Dijkstra::load(): Cannot bind segment to any edge:\n"
" %s\n"
" source:%s\n"
" target:%s"
, getString(segment).c_str()
, getString(gcell).c_str()
, getString(oppositeGCell).c_str()
) << endl;
}
}
if (rp) {
Contact* vcontact = vertex->getGContact( _net );
rp->getBodyHook()->detach();
rp->getBodyHook()->attach( vcontact->getBodyHook() );
}
}
for ( Vertex* vertex : _targets ) {
if (vertex->getConnexId() != 0) continue;
_tagConnecteds( vertex, ++_connectedsId );
} }
cdebug_log(112,0) << "Search area: " << _searchArea << endl; cdebug_log(112,0) << "Search area: " << _searchArea << endl;
@ -240,13 +313,35 @@ namespace Anabatic {
} }
} }
_targets.erase ( firstSource ); for ( auto ivertex = _targets.begin() ; ivertex != _targets.end() ; ) {
_sources.insert( firstSource ); auto inext = ivertex; inext++;
if ((*ivertex)->getConnexId() == firstSource->getConnexId()) {
_sources.insert( *ivertex );
_targets.erase ( ivertex );
}
ivertex = inext;
}
cdebug_log(112,0) << "Dijkstra::_selectFirstSource() " << *_sources.begin() << endl; cdebug_log(112,0) << "Dijkstra::_selectFirstSource() " << *_sources.begin() << endl;
} }
void Dijkstra::_cleanup ()
{
for ( Vertex* vertex : _sources ) if (vertex->getFrom()) vertex->getFrom()->setSegment( NULL );
for ( Vertex* vertex : _targets ) if (vertex->getFrom()) vertex->getFrom()->setSegment( NULL );
//_checkEdges();
_sources.clear();
_targets.clear();
_searchArea.makeEmpty();
_connectedsId = 0;
}
bool Dijkstra::_propagate ( Flags enabledSides ) bool Dijkstra::_propagate ( Flags enabledSides )
{ {
cdebug_log(112,1) << "Dijkstra::_propagate() " << _net << endl; cdebug_log(112,1) << "Dijkstra::_propagate() " << _net << endl;
@ -301,6 +396,7 @@ namespace Anabatic {
// We did reach another target (different <connexId>). // We did reach another target (different <connexId>).
// Tag back the path, with a higher <branchId>. // Tag back the path, with a higher <branchId>.
_traceback( current ); _traceback( current );
cdebug_tabw(112,-1);
return true; return true;
} }
@ -345,21 +441,23 @@ namespace Anabatic {
Contact* sourceContact = source->getGContact( _net ); Contact* sourceContact = source->getGContact( _net );
Contact* targetContact = target->getGContact( _net ); Contact* targetContact = target->getGContact( _net );
Segment* segment = NULL;
if (from->isHorizontal()) { if (from->isHorizontal()) {
Horizontal::create( sourceContact segment = Horizontal::create( sourceContact
, targetContact , targetContact
, _anabatic->getConfiguration()->getGHorizontalLayer() , _anabatic->getConfiguration()->getGHorizontalLayer()
, from->getAxis() , from->getAxis()
, DbU::fromLambda(2.0) , DbU::fromLambda(2.0)
); );
} else { } else {
Vertical::create( sourceContact segment = Vertical::create( sourceContact
, targetContact , targetContact
, _anabatic->getConfiguration()->getGVerticalLayer() , _anabatic->getConfiguration()->getGVerticalLayer()
, from->getAxis() , from->getAxis()
, DbU::fromLambda(2.0) , DbU::fromLambda(2.0)
); );
} }
from->setSegment( segment );
} }
cdebug_tabw(112,-1); cdebug_tabw(112,-1);
@ -388,15 +486,16 @@ namespace Anabatic {
enabledEdges = Flags::EastSide | Flags::SouthSide; enabledEdges = Flags::EastSide | Flags::SouthSide;
} }
Vertex* source = *_sources.begin();
_queue.clear(); _queue.clear();
_queue.push( source ); _connectedsId = (*_sources.begin())->getConnexId();
_connectedsId = source->getConnexId(); for ( Vertex* source : _sources ) {
source->setDistance( 0.0 ); _queue.push( source );
source->setDistance( 0.0 );
cdebug_log(112,0) << "Push source: (size:" << _queue.size() << ") "
<< source
<< " _connectedsId:" << _connectedsId << endl;
}
cdebug_log(112,0) << "Push source: (size:" << _queue.size() << ") "
<< source
<< " _connectedsId:" << _connectedsId << endl;
while ( not _targets.empty() and _propagate(enabledEdges) ); while ( not _targets.empty() and _propagate(enabledEdges) );
@ -407,4 +506,157 @@ namespace Anabatic {
} }
void Dijkstra::ripup ( Edge* edge )
{
DebugSession::open( _net, 112, 120 );
cdebug_log(112,1) << "Dijkstra::ripup(): " << edge << endl;
GCell* gsource = edge->getSource();
GCell* gtarget = edge->getTarget();
Vertex* vsource = gsource->getObserver<Vertex>(GCell::Observable::Vertex);
Vertex* vtarget = gtarget->getObserver<Vertex>(GCell::Observable::Vertex);
if ( (not isSourceVertex(vsource) and not isTargetVertex(vsource))
or (not isSourceVertex(vtarget) and not isTargetVertex(vtarget)) ) {
cerr << Error( "Dijkstra::ripup(): %s do *not* belong to %s (ignored)."
, getString(edge).c_str()
, getString(_net).c_str()
) << endl;
cdebug_tabw(112,-1);
DebugSession::close();
return;
}
edge->destroySegment();
// for ( Contact* contact : gsource->getGContacts() ) {
// if (contact->getNet() != _net) continue;
// for ( Component* component : contact->getSlaveComponents() ) {
// Segment* segment = dynamic_cast<Segment*>( component );
// if (segment and (gtarget->hasGContact(dynamic_cast<Contact*>(segment->getTarget())))) {
// segment->destroy();
// break;
// }
// }
// break;
// }
edge->incRealOccupancy( -1 );
_propagateRipup( vsource );
vtarget = _propagateRipup( vtarget );
_tagConnecteds( vtarget, ++_connectedsId );
cdebug_tabw(112,-1);
DebugSession::close();
}
Vertex* Dijkstra::_propagateRipup ( Vertex* end )
{
cdebug_log(112,1) << "Dijkstra::_propagateRipup() from:" << end << endl;
while ( end ) {
cdebug_log(112,0) << "| " << end << endl;
Contact* gcontact = end->getGCell()->getGContact( _net );
if (not gcontact) {
cdebug_log(112,0) << "Exiting on missing GContact." << endl;
cdebug_tabw(112,-1);
return end;
}
Edge* eneighbor = NULL;
for ( Edge* edge : end->getGCell()->getEdges() ) {
if (edge->getSegment()) {
if (not eneighbor) eneighbor = edge;
else {
eneighbor = NULL;
break;
}
}
}
for ( Component* component : gcontact->getSlaveComponents() ) {
if (dynamic_cast<RoutingPad*>(component)) {
eneighbor = NULL;
break;
}
}
if (not eneighbor) {
cdebug_log(112,0) << "Normal exit (fork or RoutingPad)." << endl;
cdebug_tabw(112,-1);
return end;
}
cdebug_log(112,0) << "+ " << eneighbor << endl;
eneighbor->incRealOccupancy( -1 );
eneighbor->destroySegment();
eneighbor->setSegment( NULL );
end->setConnexId( -1 );
end->setDistance( Vertex::unreached );
end = eneighbor->getOpposite(end->getGCell())->getObserver<Vertex>(GCell::Observable::Vertex);;
}
cdebug_log(112,0) << "Exiting on nothing left." << endl;
cdebug_tabw(112,-1);
return NULL;
}
void Dijkstra::_tagConnecteds ( Vertex* source, int connexId )
{
cdebug_log(112,1) << "Dijkstra::_tagConnecteds()" << endl;
source->setConnexId( connexId );
VertexSet stack;
stack.insert( source );
while ( not stack.empty() ) {
source = *stack.begin();
stack.erase( source );
cdebug_log(112,0) << "| source:" << source << " stack.size():" << stack.size() << endl;
for ( Edge* edge : source->getGCell()->getEdges() ) {
if (not edge->getSegment()) {
cdebug_log(112,0) << " Not connected:" << edge << endl;
continue;
}
GCell* gneighbor = edge->getOpposite(source->getGCell());
Vertex* vneighbor = gneighbor->getObserver<Vertex>(GCell::Observable::Vertex);
if (not vneighbor->hasValidStamp()) continue;
if (vneighbor->getConnexId() == connexId) continue;
vneighbor->setConnexId( connexId );
stack.insert( vneighbor );
}
}
cdebug_tabw(112,-1);
}
void Dijkstra::_checkEdges () const
{
cdebug_log(112,1) << "Dijkstra::_checkEdges()" << endl;
for ( Vertex* vertex : _vertexes ) {
for ( Edge* edge : vertex->getGCell()->getEdges(Flags::EastSide|Flags::NorthSide) ) {
if (edge->getSegment()) {
cdebug_log(112,0) << "Not reset:" << edge << edge->getSegment() << endl;
}
}
}
cdebug_tabw(112,-1);
}
} // Anabatic namespace. } // Anabatic namespace.

View File

@ -16,6 +16,7 @@
#include <iostream> #include <iostream>
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "hurricane/Segment.h"
#include "anabatic/Edge.h" #include "anabatic/Edge.h"
#include "anabatic/GCell.h" #include "anabatic/GCell.h"
#include "anabatic/AnabaticEngine.h" #include "anabatic/AnabaticEngine.h"
@ -41,6 +42,7 @@ namespace Anabatic {
, _source (source) , _source (source)
, _target (target) , _target (target)
, _axis (0) , _axis (0)
, _segment (NULL)
{ } { }
@ -170,6 +172,30 @@ namespace Anabatic {
} }
void Edge::incRealOccupancy ( int delta )
{
unsigned int occupancy = 0;
if ((int)_realOccupancy + delta > 0) occupancy = _realOccupancy + delta;
if ((_realOccupancy <= _capacity) and (occupancy > _capacity)) getAnabatic()->addOv ( this );
if ((_realOccupancy > _capacity) and (occupancy <= _capacity)) getAnabatic()->removeOv( this );
_realOccupancy = occupancy;
}
void Edge::destroySegment ()
{
if (not _segment) return;
Contact* csource = dynamic_cast<Contact*>( _segment->getSource() );
Contact* ctarget = dynamic_cast<Contact*>( _segment->getTarget() );
_segment->destroy();
_segment = NULL;
if (csource) getSource()->unrefContact( csource );
if (ctarget) getTarget()->unrefContact( ctarget );
}
void Edge::_setSource ( GCell* source ) void Edge::_setSource ( GCell* source )
{ {
if (source == _target) if (source == _target)

View File

@ -61,40 +61,45 @@ namespace Anabatic {
void GCell_Edges::Locator::progress () void GCell_Edges::Locator::progress ()
{ {
// cdebug_log(110,0) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl; cdebug_log(110,0) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl;
// cdebug_log(110,0) << " East:" << _gcell->getEastEdges().size() cdebug_log(110,0) << " _filterFlags:" << _filterFlags << endl;
// << " North:" << _gcell->getNorthEdges().size() cdebug_log(110,0) << " East:" << _gcell->getEastEdges().size()
// << " West:" << _gcell->getWestEdges().size() << " North:" << _gcell->getNorthEdges().size()
// << " South:" << _gcell->getSouthEdges().size() << endl; << " West:" << _gcell->getWestEdges().size()
// cdebug_log(110,0) << this << endl; << " South:" << _gcell->getSouthEdges().size() << endl;
cdebug_log(110,0) << this << endl;
++_iedge; ++_iedge;
while (_stateFlags) { while (_stateFlags) {
if ((_stateFlags & _filterFlags).contains(Flags::EastSide)) { if (_stateFlags.contains(Flags::EastSide)) {
if (_iedge < _gcell->getEastEdges().size()) break; if ( (_iedge < _gcell->getEastEdges().size())
and _filterFlags.contains(Flags::EastSide)) break;
// cdebug_log(110,0) << "Switching to North side." << endl; // cdebug_log(110,0) << "Switching to North side." << endl;
_stateFlags = Flags::NorthSide; _stateFlags = Flags::NorthSide;
_iedge = 0; _iedge = 0;
// cdebug_log(110,0) << this << endl; // cdebug_log(110,0) << this << endl;
continue; continue;
} }
if ((_stateFlags & _filterFlags).contains(Flags::NorthSide)) { if (_stateFlags.contains(Flags::NorthSide)) {
if (_iedge < _gcell->getNorthEdges().size()) break; if ( (_iedge < _gcell->getNorthEdges().size())
and _filterFlags.contains(Flags::NorthSide)) break;
// cdebug_log(110,0) << "Switching to West side." << endl; // cdebug_log(110,0) << "Switching to West side." << endl;
_stateFlags = Flags::WestSide; _stateFlags = Flags::WestSide;
_iedge = 0; _iedge = 0;
// cdebug_log(110,0) << this << endl; // cdebug_log(110,0) << this << endl;
continue; continue;
} }
if ((_stateFlags & _filterFlags).contains(Flags::WestSide)) { if (_stateFlags.contains(Flags::WestSide)) {
if (_iedge < _gcell->getWestEdges().size()) break; if ( (_iedge < _gcell->getWestEdges().size())
and _filterFlags.contains(Flags::WestSide)) break;
// cdebug_log(110,0) << "Switching to South side." << endl; // cdebug_log(110,0) << "Switching to South side." << endl;
_stateFlags = Flags::SouthSide; _stateFlags = Flags::SouthSide;
_iedge = 0; _iedge = 0;
continue; continue;
} }
if ((_stateFlags & _filterFlags).contains(Flags::SouthSide)) { if (_stateFlags.contains(Flags::SouthSide)) {
if (_iedge < _gcell->getSouthEdges().size()) break; if ( (_iedge < _gcell->getSouthEdges().size())
and _filterFlags.contains(Flags::SouthSide)) break;
// cdebug_log(110,0) << "All edges done." << endl; // cdebug_log(110,0) << "All edges done." << endl;
_stateFlags = 0; _stateFlags = 0;
_iedge = 0; _iedge = 0;
@ -102,7 +107,7 @@ namespace Anabatic {
} }
} }
//cdebug_log(110,0) << "GCell_Edges::Locator::progress() [to] " << _stateFlags << " iedge:" << _iedge << endl; cdebug_log(110,0) << "GCell_Edges::Locator::progress() [to] " << _stateFlags << " iedge:" << _iedge << endl;
} }

View File

@ -164,6 +164,24 @@ namespace Anabatic {
} }
bool GCell::hasGContact ( const Contact* owned ) const
{
for ( Contact* contact : _contacts ) {
if (contact == owned) return true;
}
return false;
}
Edge* GCell::getEdgeTo ( GCell* neighbor, Flags sideHint ) const
{
for ( Edge* edge : getEdges(sideHint) ) {
if (edge->getOpposite(this) == neighbor) return edge;
}
return NULL;
}
GCell* GCell::getWest ( DbU::Unit y ) const GCell* GCell::getWest ( DbU::Unit y ) const
{ {
for ( Edge* edge : _westEdges ) { for ( Edge* edge : _westEdges ) {
@ -372,7 +390,9 @@ namespace Anabatic {
bool GCell::doGrid () bool GCell::doGrid ()
{ {
DbU::Unit side = getAnabatic()->getConfiguration()->getSliceHeight(); const vector<GCell*>& gcells = getAnabatic()->getGCells();
size_t ibegin = gcells.size();
DbU::Unit side = getAnabatic()->getConfiguration()->getSliceHeight();
Interval hspan = getSide( Flags::Horizontal ); Interval hspan = getSide( Flags::Horizontal );
Interval vspan = getSide( Flags::Vertical ); Interval vspan = getSide( Flags::Vertical );
@ -414,6 +434,15 @@ namespace Anabatic {
column = column->vcut( xcut ); column = column->vcut( xcut );
} }
size_t hLocal = - getAnabatic()->getConfiguration()->getHEdgeLocal();
size_t vLocal = - getAnabatic()->getConfiguration()->getVEdgeLocal();
for ( ; ibegin < gcells.size() ; ++ibegin ) {
for ( Edge* edge : gcells[ibegin]->getEdges(Flags::NorthSide|Flags::EastSide) ) {
if (edge->isHorizontal()) edge->incCapacity( hLocal );
else edge->incCapacity( vLocal );
}
}
//UpdateSession::close(); //UpdateSession::close();
return true; return true;
@ -549,11 +578,32 @@ namespace Anabatic {
, DbU::fromLambda(2.0) , DbU::fromLambda(2.0)
, DbU::fromLambda(2.0) , DbU::fromLambda(2.0)
); );
_contacts.push_back( contact );
cdebug_log(111,0) << "GCell::getGContact(): " << contact << endl; cdebug_log(111,0) << "GCell::getGContact(): " << contact << endl;
return contact; return contact;
} }
bool GCell::unrefContact ( Contact* unref )
{
if (_contacts.empty()) return false;
for ( size_t i=0 ; i< _contacts.size() ; ++i ) {
if (_contacts[i] == unref) {
if (_contacts[i]->getSlaveComponents().getLocator()->isValid()) return false;
std::swap( _contacts[i], _contacts[_contacts.size()-1] );
_contacts[ _contacts.size()-1 ]->destroy();
_contacts.pop_back();
return true;
}
}
return false;
}
const Name& GCell::getName () const const Name& GCell::getName () const
{ return _extensionName; } { return _extensionName; }

View File

@ -0,0 +1,195 @@
// -*- C++ -*-
//
// 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 : "./GlobalRoute.cpp" |
// +-----------------------------------------------------------------+
#include <sstream>
#include <iostream>
#include "hurricane/Error.h"
#include "hurricane/RegularLayer.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h"
#include "hurricane/Cell.h"
#include "hurricane/UpdateSession.h"
#include "hurricane/DebugSession.h"
#include "crlcore/RoutingGauge.h"
#include "anabatic/GCell.h"
#include "anabatic/Dijkstra.h"
#include "anabatic/AnabaticEngine.h"
namespace {
using std::cerr;
using std::endl;
using std::setw;
using std::left;
using std::right;
using Hurricane::DbU;
using Anabatic::Edge;
using Anabatic::Vertex;
class DigitalDistance {
public:
inline DigitalDistance ( float h, float k );
DbU::Unit operator() ( const Vertex* source ,const Vertex* target,const Edge* edge ) const;
private:
// For an explanation of h & k parameters, see:
// "KNIK, routeur global pour la plateforme Coriolis", p. 52.
float _h;
float _k;
};
inline DigitalDistance::DigitalDistance ( float h, float k ) : _h(h), _k(k) { }
DbU::Unit DigitalDistance::operator() ( const Vertex* source ,const Vertex* target,const Edge* edge ) const
{
if (edge->getCapacity() <= 0) return Vertex::unreached;
float congestion = (float)edge->getRealOccupancy() / (float)edge->getCapacity();
float congestionCost = 1.0 + _h / (1.0 + std::exp(_k * (congestion - 1.0)));
float distance = (float)source->getDistance() + congestionCost * (float)edge->getDistance();
// Edge* sourceFrom = source->getFrom();
// if (sourceFrom) {
// distance += ((sourceFrom->isHorizontal() xor edge->isHorizontal()) ? 3.0 : 0.0) * (float)Edge::unity;
// }
cdebug_log(112,0) << "cong:" << congestion
<< " ccost:" << congestionCost
<< " digitalDistance:" << DbU::getValueString((DbU::Unit)distance) << endl;
return (DbU::Unit)distance;
}
} // Anonymous namespace.
namespace Anabatic {
using std::cerr;
using std::cout;
using std::endl;
using std::setw;
using std::ostringstream;
using Hurricane::Error;
using Hurricane::RegularLayer;
using Hurricane::Component;
using Hurricane::Horizontal;
using Hurricane::Vertical;
using Hurricane::Cell;
using Hurricane::UpdateSession;
using Hurricane::DebugSession;
using CRL::RoutingGauge;
using CRL::RoutingLayerGauge;
// -------------------------------------------------------------------
// Class : "Anabatic::AnabaticEngine".
//
// Methods dedicateds to complete global routing.
void AnabaticEngine::globalRoute ()
{
Cell* cell = getCell();
cell->flattenNets( Cell::Flags::BuildRings );
cell->createRoutingPadRings( Cell::Flags::BuildRings );
//DebugSession::addToTrace( cell->getNet("alu_out(3)") );
//DebugSession::addToTrace( cell->getNet("imuxe.not_i(1)") );
//DebugSession::addToTrace( cell->getNet("r(0)") );
//DebugSession::addToTrace( cell->getNet("a_from_pads(0)") );
//DebugSession::addToTrace( cell->getNet("ialu.not_aux104") );
//DebugSession::addToTrace( cell->getNet("mips_r3000_1m_dp_shift32_rshift_se_muxoutput(126)") );
startMeasures();
UpdateSession::open();
if (getGCells().size() == 1) {
cmess1 << " o Building regular grid..." << endl;
getSouthWestGCell()->doGrid();
} else {
cmess1 << " o Reusing existing grid." << endl;
}
cmess1 << Dots::asInt(" - GCells" ,getGCells().size()) << endl;
UpdateSession::close();
stopMeasures();
printMeasures( "Anabatic Grid" );
startMeasures();
cmess1 << " o Running global routing..." << endl;
NetSet netsToRoute;
for ( Net* net : cell->getNets() ) {
if (net->isSupply() or net->isClock()) continue;
netsToRoute.insert( net );
}
UpdateSession::open();
Dijkstra* dijkstra = new Dijkstra ( this );
dijkstra->setDistance( DigitalDistance( getConfiguration()->getEdgeCostH()
, getConfiguration()->getEdgeCostK() ) );
size_t iteration = 0;
while ( not netsToRoute.empty() and (iteration < 5) ) {
cmess2 << " [" << setw(3) << iteration << "] nets:"
<< left << setw(6) << netsToRoute.size() << right;
for ( Net* net : netsToRoute ) {
dijkstra->load( net );
dijkstra->run();
}
netsToRoute.clear();
const vector<Edge*>& ovEdges = getOvEdges();
cmess2 << " ovEdges:" << ovEdges.size();
while ( not ovEdges.empty() ) {
Edge* ovEdge = ovEdges[0];
NetSet netsToUnroute;
getNetsFromEdge( ovEdge, netsToUnroute );
for ( Net* net : netsToUnroute ) {
dijkstra->load( net );
dijkstra->ripup( ovEdge );
netsToRoute.insert( net );
}
}
cmess2 << " ripup:" << netsToRoute.size();
stopMeasures();
cmess2 << " " << setw(10) << Timer::getStringTime (_timer.getCombTime())
<< " " << setw( 6) << Timer::getStringMemory(_timer.getIncrease()) << endl;
startMeasures();
++iteration;
}
stopMeasures();
printMeasures( "Dijkstra" );
delete dijkstra;
UpdateSession::close();
}
} // Anabatic namespace.

View File

@ -200,8 +200,9 @@ namespace Anabatic {
//DebugSession::addToTrace( cell->getNet("alu_out(3)") ); //DebugSession::addToTrace( cell->getNet("alu_out(3)") );
//DebugSession::addToTrace( cell->getNet("imuxe.not_i(1)") ); //DebugSession::addToTrace( cell->getNet("imuxe.not_i(1)") );
DebugSession::addToTrace( cell->getNet("r(0)") ); //DebugSession::addToTrace( cell->getNet("r(0)") );
DebugSession::addToTrace( cell->getNet("ialu.not_aux104") ); //DebugSession::addToTrace( cell->getNet("ialu.not_aux104") );
DebugSession::addToTrace( cell->getNet("mips_r3000_1m_dp_shift32_rshift_se_muxoutput(159)") );
engine->startMeasures(); engine->startMeasures();
@ -226,11 +227,33 @@ namespace Anabatic {
dijkstra->load( net ); dijkstra->load( net );
dijkstra->run(); dijkstra->run();
} }
delete dijkstra;
UpdateSession::close(); UpdateSession::close();
engine->stopMeasures(); engine->stopMeasures();
engine->printMeasures( "Dijkstra" ); engine->printMeasures( "Dijkstra" );
const vector<Edge*>& ovEdges = engine->getOvEdges();
if (not ovEdges.empty()) {
size_t count = 0;
cmess1 << " - " << ovEdges.size() << " overloaded edges." << endl;
cmess1 << " " << ovEdges[0] << endl;
NetSet nets;
engine->getNetsFromEdge( ovEdges[0], nets );
for ( Net* net : nets ) {
cmess1 << " [" << setw(2) << count++ << "] " << net << endl;
}
UpdateSession::open();
Net* net = *nets.begin();
dijkstra->load( net );
dijkstra->ripup( ovEdges[0] );
UpdateSession::close();
}
UpdateSession::open();
delete dijkstra;
UpdateSession::close();
} }
@ -401,22 +424,35 @@ namespace Anabatic {
} }
void GraphicAnabaticEngine::_globalRoute ()
{
AnabaticEngine* engine = getForFramework( CreateEngine );
engine->globalRoute();
}
void GraphicAnabaticEngine::addToMenu ( CellViewer* viewer ) void GraphicAnabaticEngine::addToMenu ( CellViewer* viewer )
{ {
assert( _viewer == NULL ); assert( _viewer == NULL );
_viewer = viewer; _viewer = viewer;
if (_viewer->hasMenuAction("placeAndRoute.anabatic")) { if (_viewer->hasMenuAction("placeAndRoute.anabatic.globalRoute")) {
cerr << Warning( "GraphicAnabaticEngine::addToMenu() - Anabatic engine already hooked in." ) << endl; cerr << Warning( "GraphicAnabaticEngine::addToMenu() - Anabatic engine already hooked in." ) << endl;
return; return;
} }
_viewer->addToMenu( "placeAndRoute.anabatic" _viewer->addMenu ( "placeAndRoute.anabatic", "Anabatic" );
_viewer->addToMenu( "placeAndRoute.anabatic.runTest"
, "Anabatic - &Test Run" , "Anabatic - &Test Run"
, "Perform a test run of Anabatic on the design" , "Perform a test run of Anabatic on the design"
, std::bind(&GraphicAnabaticEngine::_runTest,this) , std::bind(&GraphicAnabaticEngine::_runTest,this)
); );
_viewer->addToMenu( "placeAndRoute.anabatic.globalRoute"
, "Anabatic - &Global Route"
, "Global Route"
, std::bind(&GraphicAnabaticEngine::_globalRoute,this)
);
} }

View File

@ -19,10 +19,12 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <set>
#include "hurricane/Timer.h" #include "hurricane/Timer.h"
namespace Hurricane { namespace Hurricane {
class Name; class Name;
class Net;
class Cell; class Cell;
class Instance; class Instance;
class CellViewer; class CellViewer;
@ -47,6 +49,9 @@ namespace Anabatic {
using CRL::ToolEngine; using CRL::ToolEngine;
typedef std::set<Net*,Entity::CompareById> NetSet;
class AnabaticEngine : public ToolEngine { class AnabaticEngine : public ToolEngine {
public: public:
typedef ToolEngine Super; typedef ToolEngine Super;
@ -60,13 +65,19 @@ namespace Anabatic {
inline void setViewer ( CellViewer* ); inline void setViewer ( CellViewer* );
inline const Matrix* getMatrix () const; inline const Matrix* getMatrix () const;
inline const vector<GCell*>& getGCells () const; inline const vector<GCell*>& getGCells () const;
inline const vector<Edge*>& getOvEdges () const;
inline GCell* getSouthWestGCell () const; inline GCell* getSouthWestGCell () const;
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const; inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
inline GCell* getGCellUnder ( Point ) const; inline GCell* getGCellUnder ( Point ) const;
int getCapacity ( Interval, Flags ) const; int getCapacity ( Interval, Flags ) const;
size_t getNetsFromEdge ( const Edge*, NetSet& );
inline void addOv ( Edge* );
inline void removeOv ( Edge* );
// Dijkstra related functions. // Dijkstra related functions.
inline int getStamp () const; inline int getStamp () const;
inline int incStamp (); inline int incStamp ();
// Global routing related functions.
void globalRoute ();
// Misc. functions. // Misc. functions.
inline const Flags& flags () const; inline const Flags& flags () const;
inline Flags& flags (); inline Flags& flags ();
@ -97,6 +108,7 @@ namespace Anabatic {
Configuration* _configuration; Configuration* _configuration;
Matrix _matrix; Matrix _matrix;
vector<GCell*> _gcells; vector<GCell*> _gcells;
vector<Edge*> _ovEdges;
CellViewer* _viewer; CellViewer* _viewer;
Flags _flags; Flags _flags;
int _stamp; int _stamp;
@ -107,6 +119,7 @@ namespace Anabatic {
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; } inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; } inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; }
inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; }
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; } inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; }
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); } inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); } inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
@ -134,6 +147,14 @@ namespace Anabatic {
inline int AnabaticEngine::getStamp () const { return _stamp; } inline int AnabaticEngine::getStamp () const { return _stamp; }
inline int AnabaticEngine::incStamp () { return ++_stamp; } inline int AnabaticEngine::incStamp () { return ++_stamp; }
inline void AnabaticEngine::addOv ( Edge* edge ) { _ovEdges.push_back(edge); }
inline void AnabaticEngine::removeOv ( Edge* edge )
{
for ( auto iedge = _ovEdges.begin() ; iedge != _ovEdges.end() ; ++iedge )
if (*iedge == edge) { _ovEdges.erase(iedge); break; }
}
} // Anabatic namespace. } // Anabatic namespace.

View File

@ -88,6 +88,8 @@ namespace Anabatic {
virtual DbU::Unit getEdgeWidth () const = 0; virtual DbU::Unit getEdgeWidth () const = 0;
virtual float getEdgeCostH () const = 0; virtual float getEdgeCostH () const = 0;
virtual float getEdgeCostK () const = 0; virtual float getEdgeCostK () const = 0;
virtual size_t getHEdgeLocal () const = 0;
virtual size_t getVEdgeLocal () const = 0;
virtual void print ( Cell* ) const = 0; virtual void print ( Cell* ) const = 0;
virtual Record* _getRecord () const = 0; virtual Record* _getRecord () const = 0;
virtual string _getString () const = 0; virtual string _getString () const = 0;
@ -143,6 +145,8 @@ namespace Anabatic {
virtual DbU::Unit getEdgeWidth () const; virtual DbU::Unit getEdgeWidth () const;
virtual float getEdgeCostH () const; virtual float getEdgeCostH () const;
virtual float getEdgeCostK () const; virtual float getEdgeCostK () const;
virtual size_t getHEdgeLocal () const;
virtual size_t getVEdgeLocal () const;
virtual void print ( Cell* ) const; virtual void print ( Cell* ) const;
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
virtual string _getString () const; virtual string _getString () const;
@ -160,6 +164,8 @@ namespace Anabatic {
DbU::Unit _edgeWidth; DbU::Unit _edgeWidth;
float _edgeCostH; float _edgeCostH;
float _edgeCostK; float _edgeCostK;
size_t _hEdgeLocal;
size_t _vEdgeLocal;
private: private:
ConfigurationConcrete ( const ConfigurationConcrete& ); ConfigurationConcrete ( const ConfigurationConcrete& );
ConfigurationConcrete& operator= ( const ConfigurationConcrete& ); ConfigurationConcrete& operator= ( const ConfigurationConcrete& );

View File

@ -44,7 +44,7 @@ namespace Anabatic {
public: public:
class CompareById { class CompareById {
public: public:
inline bool operator() ( const Vertex* lhs, const Vertex* rhs ); inline bool operator() ( const Vertex* lhs, const Vertex* rhs ) const;
}; };
public: public:
static DbU::Unit unreached; static DbU::Unit unreached;
@ -125,7 +125,7 @@ namespace Anabatic {
inline Vertex* Vertex::getPredecessor () const inline Vertex* Vertex::getPredecessor () const
{ return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver<Vertex>(GCell::Observable::Vertex) : NULL; } { return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver<Vertex>(GCell::Observable::Vertex) : NULL; }
inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs ) inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs ) const
{ return lhs->getId() < rhs->getId(); } { return lhs->getId() < rhs->getId(); }
@ -224,16 +224,23 @@ namespace Anabatic {
~Dijkstra (); ~Dijkstra ();
public: public:
inline bool isBipoint () const; inline bool isBipoint () const;
inline bool isSourceVertex ( Vertex* ) const;
inline bool isTargetVertex ( Vertex* ) const;
inline void setDistance ( distance_t ); inline void setDistance ( distance_t );
void load ( Net* ); void load ( Net* );
void run ( Mode mode=Mode::Standart ); void run ( Mode mode=Mode::Standart );
void ripup ( Edge* );
private: private:
Dijkstra ( const Dijkstra& ); Dijkstra ( const Dijkstra& );
Dijkstra& operator= ( const Dijkstra& ); Dijkstra& operator= ( const Dijkstra& );
static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* ); static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* );
void _cleanup ();
bool _propagate ( Flags enabledSides ); bool _propagate ( Flags enabledSides );
void _traceback ( Vertex* ); void _traceback ( Vertex* );
void _selectFirstSource (); void _selectFirstSource ();
Vertex* _propagateRipup ( Vertex* );
void _tagConnecteds ( Vertex*, int connexId );
void _checkEdges () const;
private: private:
AnabaticEngine* _anabatic; AnabaticEngine* _anabatic;
vector<Vertex*> _vertexes; vector<Vertex*> _vertexes;
@ -252,8 +259,10 @@ namespace Anabatic {
inline Dijkstra::Mode::Mode ( unsigned int flags ) : BaseFlags(flags) { } inline Dijkstra::Mode::Mode ( unsigned int flags ) : BaseFlags(flags) { }
inline Dijkstra::Mode::Mode ( BaseFlags base ) : BaseFlags(base) { } inline Dijkstra::Mode::Mode ( BaseFlags base ) : BaseFlags(base) { }
inline bool Dijkstra::isBipoint () const { return _net and (_targets.size()+_sources.size() == 2); } inline bool Dijkstra::isBipoint () const { return _net and (_targets.size()+_sources.size() == 2); }
inline void Dijkstra::setDistance ( distance_t cb ) { _distanceCb = cb; } inline bool Dijkstra::isSourceVertex ( Vertex* v ) const { return (_sources.find(v) != _sources.end()); }
inline bool Dijkstra::isTargetVertex ( Vertex* v ) const { return (_targets.find(v) != _targets.end()); }
inline void Dijkstra::setDistance ( distance_t cb ) { _distanceCb = cb; }
} // Anabatic namespace. } // Anabatic namespace.

View File

@ -22,10 +22,14 @@
#include "hurricane/Interval.h" #include "hurricane/Interval.h"
#include "hurricane/Box.h" #include "hurricane/Box.h"
#include "hurricane/ExtensionGo.h" #include "hurricane/ExtensionGo.h"
namespace Hurricane {
class Segment;
}
#include "anabatic/Constants.h" #include "anabatic/Constants.h"
#include "anabatic/Edges.h" #include "anabatic/Edges.h"
namespace Anabatic { namespace Anabatic {
using std::string; using std::string;
@ -34,6 +38,7 @@ namespace Anabatic {
using Hurricane::DbU; using Hurricane::DbU;
using Hurricane::Interval; using Hurricane::Interval;
using Hurricane::Box; using Hurricane::Box;
using Hurricane::Segment;
using Hurricane::Cell; using Hurricane::Cell;
using Hurricane::ExtensionGo; using Hurricane::ExtensionGo;
@ -63,7 +68,11 @@ namespace Anabatic {
inline DbU::Unit getAxis () const; inline DbU::Unit getAxis () const;
DbU::Unit getAxisMin () const; DbU::Unit getAxisMin () const;
Interval getSide () const; Interval getSide () const;
inline void incRealOccupancy ( unsigned int ); inline Segment* getSegment () const;
inline void incCapacity ( int );
void incRealOccupancy ( int );
inline void setSegment ( Segment* );
void destroySegment ();
inline const Flags& flags () const; inline const Flags& flags () const;
inline Flags& flags (); inline Flags& flags ();
inline void invalidate (); inline void invalidate ();
@ -80,17 +89,17 @@ namespace Anabatic {
virtual Box getBoundingBox () const; virtual Box getBoundingBox () const;
public: public:
// Inspector support. // Inspector support.
virtual string _getTypeName () const; virtual string _getTypeName () const;
virtual string _getString () const; virtual string _getString () const;
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
protected: protected:
Edge ( GCell* source, GCell* target, Flags flags ); Edge ( GCell* source, GCell* target, Flags flags );
virtual ~Edge (); virtual ~Edge ();
virtual void _postCreate (); virtual void _postCreate ();
virtual void _preDestroy (); virtual void _preDestroy ();
private: private:
Edge ( const Edge& ); Edge ( const Edge& );
Edge& operator= ( const Edge& ); Edge& operator= ( const Edge& );
private: private:
static Name _extensionName; static Name _extensionName;
Flags _flags; Flags _flags;
@ -100,6 +109,7 @@ namespace Anabatic {
GCell* _source; GCell* _source;
GCell* _target; GCell* _target;
DbU::Unit _axis; DbU::Unit _axis;
Segment* _segment;
}; };
@ -112,7 +122,9 @@ namespace Anabatic {
inline GCell* Edge::getSource () const { return _source; } inline GCell* Edge::getSource () const { return _source; }
inline GCell* Edge::getTarget () const { return _target; } inline GCell* Edge::getTarget () const { return _target; }
inline DbU::Unit Edge::getAxis () const { return _axis; } inline DbU::Unit Edge::getAxis () const { return _axis; }
inline void Edge::incRealOccupancy ( unsigned int delta ) { _realOccupancy+=delta; } inline Segment* Edge::getSegment () const { return _segment; }
inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; }
inline void Edge::setSegment ( Segment* s ) { _segment=s; }
inline const Flags& Edge::flags () const { return _flags; } inline const Flags& Edge::flags () const { return _flags; }
inline Flags& Edge::flags () { return _flags; } inline Flags& Edge::flags () { return _flags; }
inline void Edge::invalidate () { _flags |= Flags::Invalidated; } inline void Edge::invalidate () { _flags |= Flags::Invalidated; }

View File

@ -68,74 +68,78 @@ namespace Anabatic {
Observable& operator= ( const StaticObservable& ); Observable& operator= ( const StaticObservable& );
}; };
public: public:
static Box getBorder ( const GCell*, const GCell* ); static Box getBorder ( const GCell*, const GCell* );
public: public:
static GCell* create ( AnabaticEngine* ); static GCell* create ( AnabaticEngine* );
public: public:
inline bool isHFlat () const; inline bool isHFlat () const;
inline bool isVFlat () const; inline bool isVFlat () const;
inline bool isFlat () const; inline bool isFlat () const;
inline bool isDevice () const; inline bool isDevice () const;
inline bool isChannel () const; inline bool isChannel () const;
inline bool isStrut () const; inline bool isStrut () const;
inline bool isMatrix () const; inline bool isMatrix () const;
inline AnabaticEngine* getAnabatic () const; bool hasGContact ( const Contact* ) const;
inline DbU::Unit getXMin () const; inline AnabaticEngine* getAnabatic () const;
inline DbU::Unit getYMin () const; inline DbU::Unit getXMin () const;
inline DbU::Unit getXMax ( int shrink=0 ) const; inline DbU::Unit getYMin () const;
inline DbU::Unit getYMax ( int shrink=0 ) const; inline DbU::Unit getXMax ( int shrink=0 ) const;
inline Interval getSide ( Flags direction ) const; inline DbU::Unit getYMax ( int shrink=0 ) const;
inline Point getCenter () const; inline Interval getSide ( Flags direction ) const;
inline const vector<Edge*>& getWestEdges () const; inline Point getCenter () const;
inline const vector<Edge*>& getEastEdges () const; inline const vector<Edge*>& getWestEdges () const;
inline const vector<Edge*>& getNorthEdges () const; inline const vector<Edge*>& getEastEdges () const;
inline const vector<Edge*>& getSouthEdges () const; inline const vector<Edge*>& getNorthEdges () const;
inline Edges getEdges () const; inline const vector<Edge*>& getSouthEdges () const;
inline GCell* getWest () const; Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const;
inline GCell* getEast () const; inline Edges getEdges ( Flags sides=Flags::AllSides ) const;
inline GCell* getSouth () const; inline GCell* getWest () const;
inline GCell* getNorth () const; inline GCell* getEast () const;
GCell* getWest ( DbU::Unit y ) const; inline GCell* getSouth () const;
GCell* getEast ( DbU::Unit y ) const; inline GCell* getNorth () const;
GCell* getSouth ( DbU::Unit x ) const; GCell* getWest ( DbU::Unit y ) const;
GCell* getNorth ( DbU::Unit x ) const; GCell* getEast ( DbU::Unit y ) const;
GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const; GCell* getSouth ( DbU::Unit x ) const;
inline GCell* getUnder ( Point p ) const; GCell* getNorth ( DbU::Unit x ) const;
GCell* hcut ( DbU::Unit y ); GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const;
GCell* vcut ( DbU::Unit x ); inline GCell* getUnder ( Point p ) const;
bool doGrid (); GCell* hcut ( DbU::Unit y );
Contact* getGContact ( Net* ); GCell* vcut ( DbU::Unit x );
bool doGrid ();
Contact* getGContact ( Net* );
inline const vector<Contact*>& getGContacts () const;
bool unrefContact ( Contact* );
// Misc. functions. // Misc. functions.
inline const Flags& flags () const; inline const Flags& flags () const;
inline Flags& flags (); inline Flags& flags ();
void _add ( Edge* edge, Flags side ); void _add ( Edge* edge, Flags side );
void _remove ( Edge* edge, Flags side=Flags::AllSides ); void _remove ( Edge* edge, Flags side=Flags::AllSides );
void _destroyEdges (); void _destroyEdges ();
private: private:
void _revalidate (); void _revalidate ();
void _moveEdges ( GCell* dest, size_t ibegin, Flags flags ); void _moveEdges ( GCell* dest, size_t ibegin, Flags flags );
public: public:
// Observers. // Observers.
inline void setObserver ( size_t slot, BaseObserver* ); inline void setObserver ( size_t slot, BaseObserver* );
template<typename OwnerT> template<typename OwnerT>
inline OwnerT* getObserver ( size_t slot ); inline OwnerT* getObserver ( size_t slot );
inline void notify ( unsigned int flags ); inline void notify ( unsigned int flags );
// ExtensionGo support. // ExtensionGo support.
inline const Name& staticGetName (); inline const Name& staticGetName ();
virtual const Name& getName () const; virtual const Name& getName () const;
virtual void translate ( const DbU::Unit&, const DbU::Unit& ); virtual void translate ( const DbU::Unit&, const DbU::Unit& );
virtual Box getBoundingBox () const; virtual Box getBoundingBox () const;
public: public:
// Inspector support. // Inspector support.
virtual string _getTypeName () const; virtual string _getTypeName () const;
virtual string _getString () const; virtual string _getString () const;
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
protected: protected:
GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin ); GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin );
virtual ~GCell (); virtual ~GCell ();
GCell* _create ( DbU::Unit xmin, DbU::Unit ymin ); GCell* _create ( DbU::Unit xmin, DbU::Unit ymin );
virtual void _postCreate (); virtual void _postCreate ();
virtual void _preDestroy (); virtual void _preDestroy ();
private: private:
GCell ( const GCell& ); GCell ( const GCell& );
GCell& operator= ( const GCell& ); GCell& operator= ( const GCell& );
@ -154,28 +158,29 @@ namespace Anabatic {
}; };
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); } inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); } inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); } inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; } inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
inline bool GCell::isChannel () const { return _flags & Flags::ChannelGCell; } inline bool GCell::isChannel () const { return _flags & Flags::ChannelGCell; }
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; } inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; } inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; } inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
inline DbU::Unit GCell::getXMin () const { return _xmin; } inline DbU::Unit GCell::getXMin () const { return _xmin; }
inline DbU::Unit GCell::getYMin () const { return _ymin; } inline DbU::Unit GCell::getYMin () const { return _ymin; }
inline Edges GCell::getEdges () const { return new GCell_Edges(this); } inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); }
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; } inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; } inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; } inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; } inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; }
inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); } inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); }
inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); } inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); }
inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); } inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); }
inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); } inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); } inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
inline const Flags& GCell::flags () const { return _flags; } inline const vector<Contact*>& GCell::getGContacts () const { return _contacts; }
inline Flags& GCell::flags () { return _flags; } inline const Flags& GCell::flags () const { return _flags; }
inline Flags& GCell::flags () { return _flags; }
inline DbU::Unit GCell::getXMax ( int shrink ) const inline DbU::Unit GCell::getXMax ( int shrink ) const
{ return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink { return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink

View File

@ -82,6 +82,7 @@ namespace Anabatic {
GraphicAnabaticEngine (); GraphicAnabaticEngine ();
virtual ~GraphicAnabaticEngine (); virtual ~GraphicAnabaticEngine ();
void _runTest (); void _runTest ();
void _globalRoute ();
}; };