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:
parent
379effd92c
commit
abf58190eb
|
@ -18,6 +18,8 @@
|
|||
#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 "crlcore/RoutingGauge.h"
|
||||
|
@ -33,6 +35,9 @@ namespace Anabatic {
|
|||
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 CRL::RoutingGauge;
|
||||
|
@ -63,6 +68,7 @@ namespace Anabatic {
|
|||
, _configuration (new ConfigurationConcrete())
|
||||
, _matrix ()
|
||||
, _gcells ()
|
||||
, _ovEdges ()
|
||||
, _viewer (NULL)
|
||||
, _flags (Flags::NoFlags)
|
||||
, _stamp (-1)
|
||||
|
@ -114,6 +120,7 @@ namespace Anabatic {
|
|||
for ( GCell* gcell : _gcells ) gcell->_destroyEdges();
|
||||
for ( GCell* gcell : _gcells ) gcell->destroy();
|
||||
_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 ()
|
||||
{
|
||||
_timer.resetIncrease();
|
||||
|
|
|
@ -32,6 +32,7 @@ endif ( CHECK_DETERMINISM )
|
|||
Edges.cpp
|
||||
GCell.cpp
|
||||
AnabaticEngine.cpp
|
||||
GlobalRoute.cpp
|
||||
GraphicAnabaticEngine.cpp
|
||||
Dijkstra.cpp
|
||||
)
|
||||
|
|
|
@ -75,6 +75,8 @@ namespace Anabatic {
|
|||
, _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt()))
|
||||
, _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH", 9.0)->asDouble())
|
||||
, _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK",-10.0)->asDouble())
|
||||
, _hEdgeLocal (Cfg::getParamInt("kite.hTracksReservedLocal",0)->asInt())
|
||||
, _vEdgeLocal (Cfg::getParamInt("kite.vTracksReservedLocal",0)->asInt())
|
||||
{
|
||||
if (cg == NULL) cg = AllianceFramework::get()->getCellGauge();
|
||||
if (rg == NULL) rg = AllianceFramework::get()->getRoutingGauge();
|
||||
|
@ -288,6 +290,14 @@ namespace Anabatic {
|
|||
{ return _edgeWidth; }
|
||||
|
||||
|
||||
size_t ConfigurationConcrete::getHEdgeLocal () const
|
||||
{ return _hEdgeLocal; }
|
||||
|
||||
|
||||
size_t ConfigurationConcrete::getVEdgeLocal () const
|
||||
{ return _vEdgeLocal; }
|
||||
|
||||
|
||||
float ConfigurationConcrete::getEdgeCostH () const
|
||||
{ return _edgeCostH; }
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace Anabatic {
|
|||
using Hurricane::ForEachIterator;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::Segment;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::RoutingPad;
|
||||
|
@ -63,7 +64,7 @@ namespace Anabatic {
|
|||
string s = "<Vertex " + getString(_id)
|
||||
+ " @(" + DbU::getValueString(_gcell->getXMin())
|
||||
+ "," + DbU::getValueString(_gcell->getYMin()) + ")"
|
||||
+ " connexId:" + getString(_connexId)
|
||||
+ " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None")
|
||||
+ " d:" + ((_distance == unreached) ? "unreached" : DbU::getValueString(_distance) )
|
||||
+ "+" + getString(_branchId)
|
||||
+ " stamp:" + (hasValidStamp() ? "valid" : "outdated")
|
||||
|
@ -143,27 +144,45 @@ namespace Anabatic {
|
|||
|
||||
void Dijkstra::load ( Net* net )
|
||||
{
|
||||
_net = net;
|
||||
_cleanup();
|
||||
|
||||
const Layer* gcontactLayer = _anabatic->getConfiguration()->getGContactLayer();
|
||||
|
||||
_net = net;
|
||||
_stamp = _anabatic->incStamp();
|
||||
|
||||
DebugSession::open( _net, 112, 120 );
|
||||
cdebug_log(112,1) << "Dijkstra::load() " << _net << endl;
|
||||
|
||||
_sources.clear();
|
||||
_targets.clear();
|
||||
_searchArea.makeEmpty();
|
||||
_stamp = _anabatic->incStamp();
|
||||
vector< std::pair<Component*,bool> > components;
|
||||
for ( Component* component : _net->getComponents() ) {
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( component );
|
||||
if (rp) { components.push_back( make_pair(rp,true) ); continue; }
|
||||
|
||||
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 );
|
||||
Contact* gcontact = dynamic_cast<Contact*>( component );
|
||||
if (gcontact and (gcontact->getLayer() == gcontactLayer))
|
||||
components.push_back( make_pair(gcontact,false) );
|
||||
}
|
||||
|
||||
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) {
|
||||
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()
|
||||
" It will be ignored so the routing may be incomplete."
|
||||
, getString(element.first).c_str()
|
||||
, getString(_net).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
|
@ -175,22 +194,76 @@ namespace Anabatic {
|
|||
if (vertex->getConnexId() < 0) {
|
||||
vertex->setDistance( Vertex::unreached );
|
||||
vertex->setStamp ( _stamp );
|
||||
vertex->setConnexId( _targets.size() );
|
||||
vertex->setConnexId( _connectedsId );
|
||||
vertex->setBranchId( 0 );
|
||||
vertex->setFrom ( NULL );
|
||||
_targets.insert( vertex );
|
||||
cdebug_log(112,0) << "Add Vertex: " << vertex << endl;
|
||||
}
|
||||
|
||||
Contact* gcontact = vertex->getGContact( _net );
|
||||
rp->getBodyHook()->detach();
|
||||
rp->getBodyHook()->attach( gcontact->getBodyHook() );
|
||||
if (gcontact) {
|
||||
for ( Component* slave : gcontact->getSlaveComponents() ) {
|
||||
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_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Dijkstra::_selectFirstSource ()
|
||||
|
@ -240,13 +313,35 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
_targets.erase ( firstSource );
|
||||
_sources.insert( firstSource );
|
||||
for ( auto ivertex = _targets.begin() ; ivertex != _targets.end() ; ) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
cdebug_log(112,1) << "Dijkstra::_propagate() " << _net << endl;
|
||||
|
@ -301,6 +396,7 @@ namespace Anabatic {
|
|||
// We did reach another target (different <connexId>).
|
||||
// Tag back the path, with a higher <branchId>.
|
||||
_traceback( current );
|
||||
cdebug_tabw(112,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -345,21 +441,23 @@ namespace Anabatic {
|
|||
Contact* sourceContact = source->getGContact( _net );
|
||||
Contact* targetContact = target->getGContact( _net );
|
||||
|
||||
Segment* segment = NULL;
|
||||
if (from->isHorizontal()) {
|
||||
Horizontal::create( sourceContact
|
||||
, targetContact
|
||||
, _anabatic->getConfiguration()->getGHorizontalLayer()
|
||||
, from->getAxis()
|
||||
, DbU::fromLambda(2.0)
|
||||
);
|
||||
segment = 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)
|
||||
);
|
||||
segment = Vertical::create( sourceContact
|
||||
, targetContact
|
||||
, _anabatic->getConfiguration()->getGVerticalLayer()
|
||||
, from->getAxis()
|
||||
, DbU::fromLambda(2.0)
|
||||
);
|
||||
}
|
||||
from->setSegment( segment );
|
||||
}
|
||||
|
||||
cdebug_tabw(112,-1);
|
||||
|
@ -388,15 +486,16 @@ namespace Anabatic {
|
|||
enabledEdges = Flags::EastSide | Flags::SouthSide;
|
||||
}
|
||||
|
||||
Vertex* source = *_sources.begin();
|
||||
_queue.clear();
|
||||
_queue.push( source );
|
||||
_connectedsId = source->getConnexId();
|
||||
source->setDistance( 0.0 );
|
||||
_connectedsId = (*_sources.begin())->getConnexId();
|
||||
for ( Vertex* source : _sources ) {
|
||||
_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) );
|
||||
|
||||
|
@ -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.
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <iostream>
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Segment.h"
|
||||
#include "anabatic/Edge.h"
|
||||
#include "anabatic/GCell.h"
|
||||
#include "anabatic/AnabaticEngine.h"
|
||||
|
@ -41,6 +42,7 @@ namespace Anabatic {
|
|||
, _source (source)
|
||||
, _target (target)
|
||||
, _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 )
|
||||
{
|
||||
if (source == _target)
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace Anabatic {
|
|||
|
||||
|
||||
Edge* GCell_Edges::Locator::getElement () const
|
||||
{
|
||||
{
|
||||
if (_stateFlags.contains(Flags::EastSide )) return _gcell->getEastEdges ()[_iedge];
|
||||
if (_stateFlags.contains(Flags::NorthSide)) return _gcell->getNorthEdges()[_iedge];
|
||||
if (_stateFlags.contains(Flags::WestSide )) return _gcell->getWestEdges ()[_iedge];
|
||||
|
@ -61,40 +61,45 @@ namespace Anabatic {
|
|||
|
||||
void GCell_Edges::Locator::progress ()
|
||||
{
|
||||
// cdebug_log(110,0) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl;
|
||||
// cdebug_log(110,0) << " East:" << _gcell->getEastEdges().size()
|
||||
// << " North:" << _gcell->getNorthEdges().size()
|
||||
// << " West:" << _gcell->getWestEdges().size()
|
||||
// << " South:" << _gcell->getSouthEdges().size() << endl;
|
||||
// cdebug_log(110,0) << this << endl;
|
||||
cdebug_log(110,0) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl;
|
||||
cdebug_log(110,0) << " _filterFlags:" << _filterFlags << endl;
|
||||
cdebug_log(110,0) << " East:" << _gcell->getEastEdges().size()
|
||||
<< " North:" << _gcell->getNorthEdges().size()
|
||||
<< " West:" << _gcell->getWestEdges().size()
|
||||
<< " South:" << _gcell->getSouthEdges().size() << endl;
|
||||
cdebug_log(110,0) << this << endl;
|
||||
|
||||
++_iedge;
|
||||
while (_stateFlags) {
|
||||
if ((_stateFlags & _filterFlags).contains(Flags::EastSide)) {
|
||||
if (_iedge < _gcell->getEastEdges().size()) break;
|
||||
if (_stateFlags.contains(Flags::EastSide)) {
|
||||
if ( (_iedge < _gcell->getEastEdges().size())
|
||||
and _filterFlags.contains(Flags::EastSide)) break;
|
||||
// cdebug_log(110,0) << "Switching to North side." << endl;
|
||||
_stateFlags = Flags::NorthSide;
|
||||
_iedge = 0;
|
||||
// cdebug_log(110,0) << this << endl;
|
||||
continue;
|
||||
}
|
||||
if ((_stateFlags & _filterFlags).contains(Flags::NorthSide)) {
|
||||
if (_iedge < _gcell->getNorthEdges().size()) break;
|
||||
if (_stateFlags.contains(Flags::NorthSide)) {
|
||||
if ( (_iedge < _gcell->getNorthEdges().size())
|
||||
and _filterFlags.contains(Flags::NorthSide)) break;
|
||||
// cdebug_log(110,0) << "Switching to West side." << endl;
|
||||
_stateFlags = Flags::WestSide;
|
||||
_iedge = 0;
|
||||
// cdebug_log(110,0) << this << endl;
|
||||
continue;
|
||||
}
|
||||
if ((_stateFlags & _filterFlags).contains(Flags::WestSide)) {
|
||||
if (_iedge < _gcell->getWestEdges().size()) break;
|
||||
if (_stateFlags.contains(Flags::WestSide)) {
|
||||
if ( (_iedge < _gcell->getWestEdges().size())
|
||||
and _filterFlags.contains(Flags::WestSide)) break;
|
||||
// cdebug_log(110,0) << "Switching to South side." << endl;
|
||||
_stateFlags = Flags::SouthSide;
|
||||
_iedge = 0;
|
||||
continue;
|
||||
}
|
||||
if ((_stateFlags & _filterFlags).contains(Flags::SouthSide)) {
|
||||
if (_iedge < _gcell->getSouthEdges().size()) break;
|
||||
if (_stateFlags.contains(Flags::SouthSide)) {
|
||||
if ( (_iedge < _gcell->getSouthEdges().size())
|
||||
and _filterFlags.contains(Flags::SouthSide)) break;
|
||||
// cdebug_log(110,0) << "All edges done." << endl;
|
||||
_stateFlags = 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
for ( Edge* edge : _westEdges ) {
|
||||
|
@ -372,7 +390,9 @@ namespace Anabatic {
|
|||
|
||||
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 vspan = getSide( Flags::Vertical );
|
||||
|
@ -414,6 +434,15 @@ namespace Anabatic {
|
|||
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();
|
||||
|
||||
return true;
|
||||
|
@ -549,11 +578,32 @@ namespace Anabatic {
|
|||
, DbU::fromLambda(2.0)
|
||||
, DbU::fromLambda(2.0)
|
||||
);
|
||||
_contacts.push_back( contact );
|
||||
cdebug_log(111,0) << "GCell::getGContact(): " << contact << endl;
|
||||
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
|
||||
{ return _extensionName; }
|
||||
|
||||
|
|
|
@ -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.
|
|
@ -200,8 +200,9 @@ namespace Anabatic {
|
|||
|
||||
//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("ialu.not_aux104") );
|
||||
//DebugSession::addToTrace( cell->getNet("r(0)") );
|
||||
//DebugSession::addToTrace( cell->getNet("ialu.not_aux104") );
|
||||
DebugSession::addToTrace( cell->getNet("mips_r3000_1m_dp_shift32_rshift_se_muxoutput(159)") );
|
||||
|
||||
engine->startMeasures();
|
||||
|
||||
|
@ -226,11 +227,33 @@ namespace Anabatic {
|
|||
dijkstra->load( net );
|
||||
dijkstra->run();
|
||||
}
|
||||
delete dijkstra;
|
||||
UpdateSession::close();
|
||||
|
||||
engine->stopMeasures();
|
||||
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 )
|
||||
{
|
||||
assert( _viewer == NULL );
|
||||
|
||||
_viewer = viewer;
|
||||
|
||||
if (_viewer->hasMenuAction("placeAndRoute.anabatic")) {
|
||||
if (_viewer->hasMenuAction("placeAndRoute.anabatic.globalRoute")) {
|
||||
cerr << Warning( "GraphicAnabaticEngine::addToMenu() - Anabatic engine already hooked in." ) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
_viewer->addToMenu( "placeAndRoute.anabatic"
|
||||
_viewer->addMenu ( "placeAndRoute.anabatic", "Anabatic" );
|
||||
_viewer->addToMenu( "placeAndRoute.anabatic.runTest"
|
||||
, "Anabatic - &Test Run"
|
||||
, "Perform a test run of Anabatic on the design"
|
||||
, std::bind(&GraphicAnabaticEngine::_runTest,this)
|
||||
);
|
||||
_viewer->addToMenu( "placeAndRoute.anabatic.globalRoute"
|
||||
, "Anabatic - &Global Route"
|
||||
, "Global Route"
|
||||
, std::bind(&GraphicAnabaticEngine::_globalRoute,this)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "hurricane/Timer.h"
|
||||
namespace Hurricane {
|
||||
class Name;
|
||||
class Net;
|
||||
class Cell;
|
||||
class Instance;
|
||||
class CellViewer;
|
||||
|
@ -47,6 +49,9 @@ namespace Anabatic {
|
|||
using CRL::ToolEngine;
|
||||
|
||||
|
||||
typedef std::set<Net*,Entity::CompareById> NetSet;
|
||||
|
||||
|
||||
class AnabaticEngine : public ToolEngine {
|
||||
public:
|
||||
typedef ToolEngine Super;
|
||||
|
@ -60,13 +65,19 @@ namespace Anabatic {
|
|||
inline void setViewer ( CellViewer* );
|
||||
inline const Matrix* getMatrix () const;
|
||||
inline const vector<GCell*>& getGCells () const;
|
||||
inline const vector<Edge*>& getOvEdges () const;
|
||||
inline GCell* getSouthWestGCell () const;
|
||||
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
|
||||
inline GCell* getGCellUnder ( Point ) const;
|
||||
int getCapacity ( Interval, Flags ) const;
|
||||
size_t getNetsFromEdge ( const Edge*, NetSet& );
|
||||
inline void addOv ( Edge* );
|
||||
inline void removeOv ( Edge* );
|
||||
// Dijkstra related functions.
|
||||
inline int getStamp () const;
|
||||
inline int incStamp ();
|
||||
// Global routing related functions.
|
||||
void globalRoute ();
|
||||
// Misc. functions.
|
||||
inline const Flags& flags () const;
|
||||
inline Flags& flags ();
|
||||
|
@ -97,6 +108,7 @@ namespace Anabatic {
|
|||
Configuration* _configuration;
|
||||
Matrix _matrix;
|
||||
vector<GCell*> _gcells;
|
||||
vector<Edge*> _ovEdges;
|
||||
CellViewer* _viewer;
|
||||
Flags _flags;
|
||||
int _stamp;
|
||||
|
@ -107,6 +119,7 @@ namespace Anabatic {
|
|||
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
|
||||
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
|
||||
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::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
|
||||
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::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.
|
||||
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ namespace Anabatic {
|
|||
virtual DbU::Unit getEdgeWidth () const = 0;
|
||||
virtual float getEdgeCostH () 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 Record* _getRecord () const = 0;
|
||||
virtual string _getString () const = 0;
|
||||
|
@ -143,6 +145,8 @@ namespace Anabatic {
|
|||
virtual DbU::Unit getEdgeWidth () const;
|
||||
virtual float getEdgeCostH () const;
|
||||
virtual float getEdgeCostK () const;
|
||||
virtual size_t getHEdgeLocal () const;
|
||||
virtual size_t getVEdgeLocal () const;
|
||||
virtual void print ( Cell* ) const;
|
||||
virtual Record* _getRecord () const;
|
||||
virtual string _getString () const;
|
||||
|
@ -160,6 +164,8 @@ namespace Anabatic {
|
|||
DbU::Unit _edgeWidth;
|
||||
float _edgeCostH;
|
||||
float _edgeCostK;
|
||||
size_t _hEdgeLocal;
|
||||
size_t _vEdgeLocal;
|
||||
private:
|
||||
ConfigurationConcrete ( const ConfigurationConcrete& );
|
||||
ConfigurationConcrete& operator= ( const ConfigurationConcrete& );
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace Anabatic {
|
|||
public:
|
||||
class CompareById {
|
||||
public:
|
||||
inline bool operator() ( const Vertex* lhs, const Vertex* rhs );
|
||||
inline bool operator() ( const Vertex* lhs, const Vertex* rhs ) const;
|
||||
};
|
||||
public:
|
||||
static DbU::Unit unreached;
|
||||
|
@ -125,7 +125,7 @@ namespace Anabatic {
|
|||
inline Vertex* Vertex::getPredecessor () const
|
||||
{ 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(); }
|
||||
|
||||
|
||||
|
@ -224,16 +224,23 @@ namespace Anabatic {
|
|||
~Dijkstra ();
|
||||
public:
|
||||
inline bool isBipoint () const;
|
||||
inline bool isSourceVertex ( Vertex* ) const;
|
||||
inline bool isTargetVertex ( Vertex* ) const;
|
||||
inline void setDistance ( distance_t );
|
||||
void load ( Net* );
|
||||
void run ( Mode mode=Mode::Standart );
|
||||
void ripup ( Edge* );
|
||||
private:
|
||||
Dijkstra ( const Dijkstra& );
|
||||
Dijkstra& operator= ( const Dijkstra& );
|
||||
static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* );
|
||||
void _cleanup ();
|
||||
bool _propagate ( Flags enabledSides );
|
||||
void _traceback ( Vertex* );
|
||||
void _selectFirstSource ();
|
||||
Vertex* _propagateRipup ( Vertex* );
|
||||
void _tagConnecteds ( Vertex*, int connexId );
|
||||
void _checkEdges () const;
|
||||
private:
|
||||
AnabaticEngine* _anabatic;
|
||||
vector<Vertex*> _vertexes;
|
||||
|
@ -252,8 +259,10 @@ 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); }
|
||||
inline void Dijkstra::setDistance ( distance_t cb ) { _distanceCb = cb; }
|
||||
inline bool Dijkstra::isBipoint () const { return _net and (_targets.size()+_sources.size() == 2); }
|
||||
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.
|
||||
|
|
|
@ -22,10 +22,14 @@
|
|||
#include "hurricane/Interval.h"
|
||||
#include "hurricane/Box.h"
|
||||
#include "hurricane/ExtensionGo.h"
|
||||
namespace Hurricane {
|
||||
class Segment;
|
||||
}
|
||||
#include "anabatic/Constants.h"
|
||||
#include "anabatic/Edges.h"
|
||||
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::string;
|
||||
|
@ -34,6 +38,7 @@ namespace Anabatic {
|
|||
using Hurricane::DbU;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Segment;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::ExtensionGo;
|
||||
|
||||
|
@ -63,7 +68,11 @@ namespace Anabatic {
|
|||
inline DbU::Unit getAxis () const;
|
||||
DbU::Unit getAxisMin () 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 Flags& flags ();
|
||||
inline void invalidate ();
|
||||
|
@ -80,17 +89,17 @@ namespace Anabatic {
|
|||
virtual Box getBoundingBox () const;
|
||||
public:
|
||||
// Inspector support.
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
protected:
|
||||
Edge ( GCell* source, GCell* target, Flags flags );
|
||||
virtual ~Edge ();
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
private:
|
||||
Edge ( const Edge& );
|
||||
Edge& operator= ( const Edge& );
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
protected:
|
||||
Edge ( GCell* source, GCell* target, Flags flags );
|
||||
virtual ~Edge ();
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
private:
|
||||
Edge ( const Edge& );
|
||||
Edge& operator= ( const Edge& );
|
||||
private:
|
||||
static Name _extensionName;
|
||||
Flags _flags;
|
||||
|
@ -100,6 +109,7 @@ namespace Anabatic {
|
|||
GCell* _source;
|
||||
GCell* _target;
|
||||
DbU::Unit _axis;
|
||||
Segment* _segment;
|
||||
};
|
||||
|
||||
|
||||
|
@ -112,7 +122,9 @@ namespace Anabatic {
|
|||
inline GCell* Edge::getSource () const { return _source; }
|
||||
inline GCell* Edge::getTarget () const { return _target; }
|
||||
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 Flags& Edge::flags () { return _flags; }
|
||||
inline void Edge::invalidate () { _flags |= Flags::Invalidated; }
|
||||
|
|
|
@ -68,74 +68,78 @@ namespace Anabatic {
|
|||
Observable& operator= ( const StaticObservable& );
|
||||
};
|
||||
public:
|
||||
static Box getBorder ( const GCell*, const GCell* );
|
||||
public:
|
||||
static GCell* create ( AnabaticEngine* );
|
||||
public:
|
||||
inline bool isHFlat () const;
|
||||
inline bool isVFlat () const;
|
||||
inline bool isFlat () const;
|
||||
inline bool isDevice () const;
|
||||
inline bool isChannel () const;
|
||||
inline bool isStrut () const;
|
||||
inline bool isMatrix () const;
|
||||
inline AnabaticEngine* getAnabatic () const;
|
||||
inline DbU::Unit getXMin () const;
|
||||
inline DbU::Unit getYMin () const;
|
||||
inline DbU::Unit getXMax ( int shrink=0 ) const;
|
||||
inline DbU::Unit getYMax ( int shrink=0 ) const;
|
||||
inline Interval getSide ( Flags direction ) const;
|
||||
inline Point getCenter () const;
|
||||
inline const vector<Edge*>& getWestEdges () const;
|
||||
inline const vector<Edge*>& getEastEdges () const;
|
||||
inline const vector<Edge*>& getNorthEdges () const;
|
||||
inline const vector<Edge*>& getSouthEdges () const;
|
||||
inline Edges getEdges () const;
|
||||
inline GCell* getWest () const;
|
||||
inline GCell* getEast () const;
|
||||
inline GCell* getSouth () const;
|
||||
inline GCell* getNorth () const;
|
||||
GCell* getWest ( DbU::Unit y ) const;
|
||||
GCell* getEast ( DbU::Unit y ) const;
|
||||
GCell* getSouth ( DbU::Unit x ) const;
|
||||
GCell* getNorth ( DbU::Unit x ) const;
|
||||
GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const;
|
||||
inline GCell* getUnder ( Point p ) const;
|
||||
GCell* hcut ( DbU::Unit y );
|
||||
GCell* vcut ( DbU::Unit x );
|
||||
bool doGrid ();
|
||||
Contact* getGContact ( Net* );
|
||||
static Box getBorder ( const GCell*, const GCell* );
|
||||
public:
|
||||
static GCell* create ( AnabaticEngine* );
|
||||
public:
|
||||
inline bool isHFlat () const;
|
||||
inline bool isVFlat () const;
|
||||
inline bool isFlat () const;
|
||||
inline bool isDevice () const;
|
||||
inline bool isChannel () const;
|
||||
inline bool isStrut () const;
|
||||
inline bool isMatrix () const;
|
||||
bool hasGContact ( const Contact* ) const;
|
||||
inline AnabaticEngine* getAnabatic () const;
|
||||
inline DbU::Unit getXMin () const;
|
||||
inline DbU::Unit getYMin () const;
|
||||
inline DbU::Unit getXMax ( int shrink=0 ) const;
|
||||
inline DbU::Unit getYMax ( int shrink=0 ) const;
|
||||
inline Interval getSide ( Flags direction ) const;
|
||||
inline Point getCenter () const;
|
||||
inline const vector<Edge*>& getWestEdges () const;
|
||||
inline const vector<Edge*>& getEastEdges () const;
|
||||
inline const vector<Edge*>& getNorthEdges () const;
|
||||
inline const vector<Edge*>& getSouthEdges () const;
|
||||
Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const;
|
||||
inline Edges getEdges ( Flags sides=Flags::AllSides ) const;
|
||||
inline GCell* getWest () const;
|
||||
inline GCell* getEast () const;
|
||||
inline GCell* getSouth () const;
|
||||
inline GCell* getNorth () const;
|
||||
GCell* getWest ( DbU::Unit y ) const;
|
||||
GCell* getEast ( DbU::Unit y ) const;
|
||||
GCell* getSouth ( DbU::Unit x ) const;
|
||||
GCell* getNorth ( DbU::Unit x ) const;
|
||||
GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const;
|
||||
inline GCell* getUnder ( Point p ) const;
|
||||
GCell* hcut ( DbU::Unit y );
|
||||
GCell* vcut ( DbU::Unit x );
|
||||
bool doGrid ();
|
||||
Contact* getGContact ( Net* );
|
||||
inline const vector<Contact*>& getGContacts () const;
|
||||
bool unrefContact ( Contact* );
|
||||
// Misc. functions.
|
||||
inline const Flags& flags () const;
|
||||
inline Flags& flags ();
|
||||
void _add ( Edge* edge, Flags side );
|
||||
void _remove ( Edge* edge, Flags side=Flags::AllSides );
|
||||
void _destroyEdges ();
|
||||
private:
|
||||
void _revalidate ();
|
||||
void _moveEdges ( GCell* dest, size_t ibegin, Flags flags );
|
||||
public:
|
||||
// Observers.
|
||||
inline void setObserver ( size_t slot, BaseObserver* );
|
||||
template<typename OwnerT>
|
||||
inline OwnerT* getObserver ( size_t slot );
|
||||
inline void notify ( unsigned int flags );
|
||||
// ExtensionGo support.
|
||||
inline const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual void translate ( const DbU::Unit&, const DbU::Unit& );
|
||||
virtual Box getBoundingBox () const;
|
||||
public:
|
||||
// Inspector support.
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
protected:
|
||||
GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual ~GCell ();
|
||||
GCell* _create ( DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
inline const Flags& flags () const;
|
||||
inline Flags& flags ();
|
||||
void _add ( Edge* edge, Flags side );
|
||||
void _remove ( Edge* edge, Flags side=Flags::AllSides );
|
||||
void _destroyEdges ();
|
||||
private:
|
||||
void _revalidate ();
|
||||
void _moveEdges ( GCell* dest, size_t ibegin, Flags flags );
|
||||
public:
|
||||
// Observers.
|
||||
inline void setObserver ( size_t slot, BaseObserver* );
|
||||
template<typename OwnerT>
|
||||
inline OwnerT* getObserver ( size_t slot );
|
||||
inline void notify ( unsigned int flags );
|
||||
// ExtensionGo support.
|
||||
inline const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual void translate ( const DbU::Unit&, const DbU::Unit& );
|
||||
virtual Box getBoundingBox () const;
|
||||
public:
|
||||
// Inspector support.
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
protected:
|
||||
GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual ~GCell ();
|
||||
GCell* _create ( DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
private:
|
||||
GCell ( const GCell& );
|
||||
GCell& operator= ( const GCell& );
|
||||
|
@ -154,28 +158,29 @@ namespace Anabatic {
|
|||
};
|
||||
|
||||
|
||||
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
|
||||
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
|
||||
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
|
||||
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
|
||||
inline bool GCell::isChannel () const { return _flags & Flags::ChannelGCell; }
|
||||
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
|
||||
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
|
||||
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
|
||||
inline DbU::Unit GCell::getXMin () const { return _xmin; }
|
||||
inline DbU::Unit GCell::getYMin () const { return _ymin; }
|
||||
inline Edges GCell::getEdges () const { return new GCell_Edges(this); }
|
||||
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
|
||||
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
|
||||
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
|
||||
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::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::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
|
||||
inline const Flags& GCell::flags () const { return _flags; }
|
||||
inline Flags& GCell::flags () { return _flags; }
|
||||
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
|
||||
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
|
||||
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
|
||||
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
|
||||
inline bool GCell::isChannel () const { return _flags & Flags::ChannelGCell; }
|
||||
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
|
||||
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
|
||||
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
|
||||
inline DbU::Unit GCell::getXMin () const { return _xmin; }
|
||||
inline DbU::Unit GCell::getYMin () const { return _ymin; }
|
||||
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::getEastEdges () const { return _eastEdges; }
|
||||
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
|
||||
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::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::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
|
||||
inline const vector<Contact*>& GCell::getGContacts () const { return _contacts; }
|
||||
inline const Flags& GCell::flags () const { return _flags; }
|
||||
inline Flags& GCell::flags () { return _flags; }
|
||||
|
||||
inline DbU::Unit GCell::getXMax ( int shrink ) const
|
||||
{ return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink
|
||||
|
|
|
@ -82,6 +82,7 @@ namespace Anabatic {
|
|||
GraphicAnabaticEngine ();
|
||||
virtual ~GraphicAnabaticEngine ();
|
||||
void _runTest ();
|
||||
void _globalRoute ();
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue