Anabatic transient commit 14. Change model for long wires.

* Change: In Anabatic:
    - Long wires, going straight accross multiple GCells were splitted
      into a long sequence of segment+contact, one for each gone-through
      GCell. It was memory-consuming and algorithmically inefficient.
      Now there is only one straight wire.
        As a consequence, Edges now store the list of all segments
      going through them. That way we do not need to load a Net into
      Dijkstra before riping up some of it's segment. The ripup mechanims
      can now be implemented right at AnabaticEngine level, without
      dependencies over Dijkstra. Note that long wires are automatically
      broken in two if we need to attach a new branch on it (breakAt()).
      And fused back into one if a branch is removed (unify()).
This commit is contained in:
Jean-Paul Chaput 2016-07-30 12:15:49 +02:00
parent 09004b3a75
commit 84dad2249e
14 changed files with 802 additions and 389 deletions

View File

@ -19,6 +19,7 @@
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "hurricane/RegularLayer.h" #include "hurricane/RegularLayer.h"
#include "hurricane/Horizontal.h" #include "hurricane/Horizontal.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Vertical.h" #include "hurricane/Vertical.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "hurricane/DebugSession.h" #include "hurricane/DebugSession.h"
@ -63,6 +64,71 @@ namespace Anabatic {
" Cannot find AutoSegment associated to %s (internal error).\n"; " Cannot find AutoSegment associated to %s (internal error).\n";
// -------------------------------------------------------------------
// Class : "Anabatic::RawGCellsUnder".
RawGCellsUnder::RawGCellsUnder ( const AnabaticEngine* engine, Segment* segment )
{
cdebug_log(112,1) << "RawGCellsUnder::RawGCellsUnder(): " << segment << endl;
GCell* gsource = engine->getGCellUnder( segment->getSourcePosition() );
GCell* gtarget = engine->getGCellUnder( segment->getTargetPosition() );
if (not gsource) {
cerr << Error( "RawGCellsUnder::RawGCellsUnder(): %s source not over a GCell (ignored)."
, getString(segment).c_str()
) << endl;
cdebug_tabw(112,-1);
DebugSession::close();
return;
}
if (not gtarget) {
cerr << Error( "RawGCellsUnder::RawGCellsUnder(): %s target not over a GCell (ignored)."
, getString(segment).c_str()
) << endl;
cdebug_tabw(112,-1);
DebugSession::close();
return;
}
if (gsource == gtarget) {
_elements.push_back( Element(gsource,NULL) );
cdebug_tabw(112,-1);
DebugSession::close();
return;
}
Flags side = Flags::NoFlags;
DbU::Unit axis = 0;
Horizontal* horizontal = dynamic_cast<Horizontal*>( segment );
if (horizontal) {
side = Flags::EastSide;
axis = horizontal->getY();
if (horizontal->getSourceX() > horizontal->getTargetX())
std::swap( gsource, gtarget );
} else {
Vertical* vertical = dynamic_cast<Vertical*>( segment );
side = Flags::NorthSide;
axis = vertical->getX();
if (vertical->getSourceY() > vertical->getTargetY())
std::swap( gsource, gtarget );
}
Edge* edge = gsource->getEdgeAt( side, axis );
while ( edge ) {
_elements.push_back( Element(edge->getSource(),edge) );
if (edge->getTarget() == gtarget) break;
edge = edge->getTarget()->getEdgeAt( side, axis );
}
_elements.push_back( Element(gtarget,NULL) );
cdebug_tabw(112,-1);
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "Anabatic::AnabaticEngine". // Class : "Anabatic::AnabaticEngine".
@ -313,6 +379,226 @@ namespace Anabatic {
} }
Contact* AnabaticEngine::breakAt ( Segment* segment, GCell* breakGCell )
{
size_t i = 0;
GCellsUnder gcells ( new RawGCellsUnder(this,segment) );
for ( ; i<gcells->size() ; ++i ) {
if (gcells->gcellAt(i) == breakGCell) break;
}
Contact* breakContact = breakGCell->getGContact( segment->getNet() );
if (i == gcells->size()) {
cerr << Error( "AnabaticEngine::breakAt(): %s is *not* over %s."
, getString(segment).c_str()
, getString(breakGCell).c_str()
) << endl;
return breakContact;
}
Component* targetContact = segment->getTarget();
segment->getTargetHook()->detach();
segment->getTargetHook()->attach( breakContact->getBodyHook() );
Segment* splitted = NULL;
Horizontal* horizontal = dynamic_cast<Horizontal*>(segment);
if (horizontal) {
splitted = Horizontal::create( breakContact
, targetContact
, getConfiguration()->getGHorizontalLayer()
, horizontal->getY()
, DbU::fromLambda(2.0)
);
} else {
Vertical* vertical = dynamic_cast<Vertical*>(segment);
if (vertical) {
splitted = Vertical::create( breakContact
, targetContact
, getConfiguration()->getGVerticalLayer()
, vertical->getX()
, DbU::fromLambda(2.0)
);
} else
return breakContact;
}
for ( ; i<gcells->size()-1 ; ++i ) gcells->edgeAt(i)->replace( segment, splitted );
return breakContact;
}
bool AnabaticEngine::unify ( Contact* contact )
{
size_t hCount = 0;
size_t vCount = 0;
Horizontal* horizontals[2];
Vertical* verticals [2];
for ( Component* slave : contact->getSlaveComponents() ) {
Horizontal* h = dynamic_cast<Horizontal*>( slave );
if (h) {
if (vCount or (hCount > 1)) return false;
horizontals[hCount++] = h;
} else {
Vertical* v = dynamic_cast<Vertical*>( slave );
if (v) {
if (hCount or (vCount > 1)) return false;
verticals[vCount++] = v;
} else {
// Something else depends on this contact.
return false;
}
}
}
if (hCount == 2) {
if (horizontals[0]->getTarget() != contact) std::swap( horizontals[0], horizontals[1] );
Interval constraints ( false );
GCellsUnder gcells0 = getGCellsUnder( horizontals[0] );
if (not gcells0->empty()) {
for ( size_t i=0 ; i<gcells0->size() ; ++i )
constraints.intersection( gcells0->gcellAt(i)->getSide(Flags::Vertical) );
}
GCellsUnder gcells1 = getGCellsUnder( horizontals[1] );
if (not gcells1->empty()) {
for ( size_t i=0 ; i<gcells1->size() ; ++i ) {
constraints.intersection( gcells1->gcellAt(i)->getSide(Flags::Vertical) );
if (constraints.isEmpty()) return false;
}
}
if (not gcells1->empty()) {
for ( size_t i=0 ; i<gcells1->size()-1 ; ++i )
gcells1->edgeAt(i)->replace( horizontals[1], horizontals[0] );
}
Component* target = horizontals[1]->getTarget();
horizontals[1]->destroy();
horizontals[0]->getTargetHook()->detach();
horizontals[0]->getTargetHook()->attach( target->getBodyHook() );
}
if (vCount == 2) {
if (verticals[0]->getTarget() != contact) std::swap( verticals[0], verticals[1] );
Interval constraints ( false );
GCellsUnder gcells0 = getGCellsUnder( verticals[0] );
if (not gcells0->empty()) {
for ( size_t i=0 ; i<gcells0->size() ; ++i )
constraints.intersection( gcells0->gcellAt(i)->getSide(Flags::Horizontal) );
}
GCellsUnder gcells1 = getGCellsUnder( verticals[1] );
if (not gcells1->empty()) {
for ( size_t i=0 ; i<gcells1->size() ; ++i ) {
constraints.intersection( gcells1->gcellAt(i)->getSide(Flags::Horizontal) );
if (constraints.isEmpty()) return false;
}
}
if (not gcells1->empty()) {
for ( size_t i=0 ; i<gcells1->size()-1 ; ++i )
gcells1->edgeAt(i)->replace( verticals[1], verticals[0] );
}
Component* target = verticals[1]->getTarget();
verticals[1]->destroy();
verticals[0]->getTargetHook()->detach();
verticals[0]->getTargetHook()->attach( target->getBodyHook() );
}
getGCellUnder( contact->getPosition() )->unrefContact( contact );
return true;
}
void AnabaticEngine::ripup ( Segment* seed, Flags flags )
{
DebugSession::open( seed->getNet(), 112, 120 );
cdebug_log(112,1) << "AnabaticEngine::ripup(): " << seed << endl;
Contact* end0 = NULL;
Contact* end1 = NULL;
vector<Segment*> ripups;
ripups.push_back( seed );
vector< pair<Segment*,Component*> > stack;
if (flags & Flags::Propagate) {
stack.push_back( make_pair(seed,seed->getSource()) );
stack.push_back( make_pair(seed,seed->getTarget()) );
}
while ( not stack.empty() ) {
Contact* contact = dynamic_cast<Contact*>( stack.back().second );
Segment* from = stack.back().first;
stack.pop_back();
if (not contact) continue;
Segment* connected = NULL;
size_t slaveCount = 0;
for ( Hook* hook : contact->getBodyHook()->getHooks() ) {
Component* linked = hook->getComponent();
if ((linked == contact) or (linked == from)) continue;
if (dynamic_cast<RoutingPad*>(linked)) { ++slaveCount; continue; }
connected = dynamic_cast<Segment*>( linked );
if (connected) ++slaveCount;
}
if ((slaveCount == 1) and (connected)) {
stack .push_back( make_pair(connected,connected->getOppositeAnchor(contact)) );
ripups.push_back( connected );
} else {
if (not end0) {
end0 = contact;
cdebug_log(112,0) << "end0:" << contact << endl;
} else {
end1 = contact;
cdebug_log(112,0) << "end1:" << contact << endl;
}
}
}
for ( Segment* segment : ripups ) {
cdebug_log(112,1) << "| Destroy:" << segment << endl;
GCellsUnder gcells = getGCellsUnder( segment );
if (not gcells->empty()) {
for ( size_t i=0 ; i<gcells->size()-1 ; ++i )
gcells->edgeAt(i)->remove( segment );
}
Contact* source = dynamic_cast<Contact*>( segment->getSource() );
Contact* target = dynamic_cast<Contact*>( segment->getTarget() );
segment->destroy();
bool deletedSource = gcells->gcellAt( 0 )->unrefContact( source );
bool deletedTarget = gcells->gcellAt( gcells->size()-1 )->unrefContact( target );
if (deletedSource) {
if (source == end0) end0 = NULL;
if (source == end1) end1 = NULL;
}
if (deletedTarget) {
if (target == end0) end0 = NULL;
if (target == end1) end1 = NULL;
}
cdebug_tabw(112,-1);
}
if (end0) unify( end0 );
if (end1) unify( end1 );
cdebug_tabw(111,-1);
DebugSession::close();
}
void AnabaticEngine::cleanupGlobal () void AnabaticEngine::cleanupGlobal ()
{ {
UpdateSession::open(); UpdateSession::open();

View File

@ -122,8 +122,8 @@ namespace Anabatic {
message << "Base contact still have slaves components, cancelled.\n" message << "Base contact still have slaves components, cancelled.\n"
<< " on: " << this; << " on: " << this;
forEach ( Component*, icomponent, _contact->getSlaveComponents() ) { for ( Component* component : _contact->getSlaveComponents() ) {
message << "\n | " << (*icomponent); message << "\n | " << component;
} }
cerr << Error( message.str() ) << endl; cerr << Error( message.str() ) << endl;
@ -189,12 +189,10 @@ namespace Anabatic {
Component* anchor = getAnchor (); Component* anchor = getAnchor ();
if (anchor) { if (anchor) {
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
//cdebug_log(149,0) << "Anchor:" << anchor << endl;
} }
forEach ( AutoSegment*, isegment, const_cast<AutoContact*>(this)->getAutoSegments() ) { for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) {
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(isegment->getLayer()) ); minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
//cdebug_log(149,0) << "Slave:" << *icomponent << endl;
} }
return (unsigned int)minDepth; return (unsigned int)minDepth;
@ -207,12 +205,10 @@ namespace Anabatic {
Component* anchor = getAnchor (); Component* anchor = getAnchor ();
if ( anchor ) { if ( anchor ) {
maxDepth = std::max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); maxDepth = std::max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
//cdebug_log(149,0) << "Anchor:" << anchor << endl;
} }
forEach ( AutoSegment*, isegment, const_cast<AutoContact*>(this)->getAutoSegments() ) { for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) {
maxDepth = std::max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(isegment->getLayer()) ); maxDepth = std::max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
//cdebug_log(149,0) << "Slave:" << *icomponent << endl;
} }
return (unsigned int)maxDepth; return (unsigned int)maxDepth;
@ -224,33 +220,33 @@ namespace Anabatic {
DbU::Unit hSideLength = getGCell()->getSide( Flags::Horizontal ).getSize(); DbU::Unit hSideLength = getGCell()->getSide( Flags::Horizontal ).getSize();
DbU::Unit vSideLength = getGCell()->getSide( Flags::Vertical ).getSize(); DbU::Unit vSideLength = getGCell()->getSide( Flags::Vertical ).getSize();
forEach ( AutoSegment*, isegment, getAutoSegments() ) { for ( AutoSegment* segment : getAutoSegments() ) {
bool isSourceHook = (isegment->getAutoSource() == this); bool isSourceHook = (segment->getAutoSource() == this);
if (processeds.find(*isegment) != processeds.end()) continue; if (processeds.find(segment) != processeds.end()) continue;
processeds.insert( *isegment ); processeds.insert( segment );
size_t depth = Session::getRoutingGauge()->getLayerDepth(isegment->getLayer()); size_t depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer());
DbU::Unit length; DbU::Unit length;
if (isegment->isLocal()) { if (segment->isLocal()) {
length = isegment->getLength(); length = segment->getLength();
lengths[depth] += length; lengths[depth] += length;
DbU::Unit sideLength = (isegment->isHorizontal()) ? hSideLength : vSideLength; DbU::Unit sideLength = (segment->isHorizontal()) ? hSideLength : vSideLength;
if ( not isegment->isUnbound() and (abs(length) > sideLength) ) if ( not segment->isUnbound() and (abs(length) > sideLength) )
cerr << Error("Suspicious length:%.2f of %s." cerr << Error("Suspicious length:%.2f of %s."
,DbU::toLambda(length),getString(*isegment).c_str()) << endl; ,DbU::toLambda(length),getString(segment).c_str()) << endl;
} else { } else {
if ( isegment->isHorizontal() ) { if (segment->isHorizontal()) {
if (isSourceHook) if (isSourceHook)
lengths[depth] += _gcell->getXMax() - isegment->getSourceX(); lengths[depth] += _gcell->getXMax() - segment->getSourceX();
else else
lengths[depth] += isegment->getTargetX() - _gcell->getXMin(); lengths[depth] += segment->getTargetX() - _gcell->getXMin();
} else { } else {
if (isSourceHook) if (isSourceHook)
lengths[depth] += _gcell->getYMax() - isegment->getSourceY(); lengths[depth] += _gcell->getYMax() - segment->getSourceY();
else else
lengths[depth] += isegment->getTargetY() - _gcell->getYMin(); lengths[depth] += segment->getTargetY() - _gcell->getYMin();
} }
} }
} }
@ -301,8 +297,6 @@ namespace Anabatic {
Session::invalidate( this ); Session::invalidate( this );
_invalidate( flags ); _invalidate( flags );
//forEach( AutoSegment*, isegment, getAutoSegments() )
// isegment->invalidate();
getGCell()->invalidate(); getGCell()->invalidate();
cdebug_tabw(145,-1); cdebug_tabw(145,-1);
@ -349,12 +343,12 @@ namespace Anabatic {
anchor = support->getAnchor(); anchor = support->getAnchor();
forEach ( Component*, icomponent, support->getSlaveComponents() ) { for ( Component* component : support->getSlaveComponents() ) {
Horizontal* h = dynamic_cast<Horizontal*>(*icomponent); Horizontal* h = dynamic_cast<Horizontal*>(component);
if (h != NULL) { if (h != NULL) {
if (hcount < size) horizontals[hcount++] = h; if (hcount < size) horizontals[hcount++] = h;
} else { } else {
Vertical* v = dynamic_cast<Vertical*>(*icomponent); Vertical* v = dynamic_cast<Vertical*>(component);
if ( (v != NULL) and (vcount < size) ) verticals[vcount++] = v; if ( (v != NULL) and (vcount < size) ) verticals[vcount++] = v;
} }
} }
@ -425,10 +419,10 @@ namespace Anabatic {
cdebug_log(149,0) << "| Anchor depth: " << viaDepth << endl; cdebug_log(149,0) << "| Anchor depth: " << viaDepth << endl;
} }
forEach ( AutoSegment*, isegment, const_cast<AutoContact*>(this)->getAutoSegments() ) { for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) {
if (*isegment == moved) continue; if (segment == moved) continue;
size_t depth = rg->getLayerDepth(isegment->getLayer()); size_t depth = rg->getLayerDepth(segment->getLayer());
if (viaDepth == 100) viaDepth = depth; if (viaDepth == 100) viaDepth = depth;
else else
if (viaDepth != depth) return false; if (viaDepth != depth) return false;

View File

@ -65,6 +65,8 @@ 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()) + ")"
+ " rps:" + getString(_rpCount)
+ " deg:" + getString(_degree)
+ " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None") + " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None")
+ " d:" + ((_distance == unreached) ? "unreached" + " d:" + ((_distance == unreached) ? "unreached"
: ((_distance == unreachable) ? "unreachable" : ((_distance == unreachable) ? "unreachable"
@ -199,43 +201,26 @@ namespace Anabatic {
{ {
_cleanup(); _cleanup();
const Layer* gcontactLayer = _anabatic->getConfiguration()->getGContactLayer();
_net = net; _net = net;
_stamp = _anabatic->incStamp(); _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;
vector< std::pair<Component*,bool> > components; vector<RoutingPad*> rps;
for ( Component* component : _net->getComponents() ) { for ( Component* component : _net->getComponents() ) {
RoutingPad* rp = dynamic_cast<RoutingPad*>( component ); RoutingPad* rp = dynamic_cast<RoutingPad*>( component );
if (rp) { components.push_back( make_pair(rp,true) ); continue; } if (rp) { rps.push_back( rp ); continue; }
Contact* gcontact = dynamic_cast<Contact*>( component );
if (gcontact and (gcontact->getLayer() == gcontactLayer))
components.push_back( make_pair(gcontact,false) );
} }
for ( auto element : components ) { for ( auto rp : rps ) {
RoutingPad* rp = NULL; Point center = rp->getBoundingBox().getCenter();
Contact* gcontact = NULL; GCell* gcell = _anabatic->getGCellUnder( center );
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 so the routing may be incomplete." " It will be ignored so the routing may be incomplete."
, getString(element.first).c_str() , getString(rp).c_str()
, getString(_net).c_str() , getString(_net).c_str()
) << endl; ) << endl;
continue; continue;
@ -243,75 +228,30 @@ namespace Anabatic {
_searchArea.merge( gcell->getBoundingBox() ); _searchArea.merge( gcell->getBoundingBox() );
Vertex* vertex = gcell->getObserver<Vertex>(GCell::Observable::Vertex); Vertex* seed = gcell->getObserver<Vertex>(GCell::Observable::Vertex);
if (vertex->getConnexId() < 0) { if (seed->getConnexId() < 0) {
vertex->setDistance( Vertex::unreached ); VertexSet connecteds;
vertex->setStamp ( _stamp ); _getConnecteds( seed, connecteds );
vertex->setConnexId( _connectedsId );
vertex->setBranchId( 0 );
vertex->setFrom ( NULL );
_targets.insert( vertex );
vertex->clearRestriction();
cdebug_log(112,0) << "Add Vertex: " << vertex << endl;
}
if (gcontact) { ++_connectedsId;
for ( Component* slave : gcontact->getSlaveComponents() ) { for ( Vertex* vertex : connecteds ) {
Flags sideHint = Flags::NoFlags; vertex->setDistance ( Vertex::unreached );
GCell* oppositeGCell = NULL; vertex->setStamp ( _stamp );
vertex->setConnexId ( _connectedsId );
Segment* segment = dynamic_cast<Horizontal*>(slave); vertex->setBranchId ( 0 );
if (segment) { vertex->setDegree ( 1 );
cdebug_log(112,0) << "| " << segment << endl; vertex->setRpCount ( 0 );
if (segment->getSource() == gcontact) { vertex->setFrom ( NULL );
oppositeGCell = _anabatic->getGCellUnder( segment->getTarget()->getCenter() ); vertex->clearRestriction();
sideHint = Flags::EastSide; _targets.insert( vertex );
} else cdebug_log(112,0) << "Add Vertex: " << vertex << endl;
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) { seed->incRpCount();
Contact* vcontact = vertex->getGContact( _net ); Contact* vcontact = seed->getGContact( _net );
rp->getBodyHook()->detach(); rp->getBodyHook()->detach();
rp->getBodyHook()->attach( vcontact->getBodyHook() ); 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;
@ -384,11 +324,7 @@ namespace Anabatic {
void Dijkstra::_cleanup () 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(); //_checkEdges();
_sources.clear(); _sources.clear();
_targets.clear(); _targets.clear();
_searchArea.makeEmpty(); _searchArea.makeEmpty();
@ -432,6 +368,8 @@ namespace Anabatic {
if (not vneighbor->hasValidStamp()) { if (not vneighbor->hasValidStamp()) {
vneighbor->setConnexId( -1 ); vneighbor->setConnexId( -1 );
vneighbor->setStamp ( _stamp ); vneighbor->setStamp ( _stamp );
vneighbor->setDegree ( 1 );
vneighbor->setRpCount ( 0 );
} }
} }
@ -468,50 +406,112 @@ namespace Anabatic {
cdebug_log(112,1) << "Dijkstra::_traceback() " << _net << " branchId:" << _sources.size() << endl; cdebug_log(112,1) << "Dijkstra::_traceback() " << _net << " branchId:" << _sources.size() << endl;
int branchId = _sources.size(); int branchId = _sources.size();
_targets.erase( current ); _toSources( current, _connectedsId );
current = current->getPredecessor();
while ( current ) { while ( current ) {
cdebug_log(112,0) << "| " << current << endl; cdebug_log(112,0) << "| " << current << endl;
current->incDegree();
if (current->getConnexId() == _connectedsId) break; if (current->getConnexId() == _connectedsId) break;
Edge* from = current->getFrom(); Edge* from = current->getFrom();
if (not from) break; if (not from) break;
from->incRealOccupancy( 1 );
_sources.insert( current );
current->setDistance( 0.0 ); current->setDistance( 0.0 );
current->setConnexId( _connectedsId ); current->setConnexId( _connectedsId );
current->setBranchId( branchId ); current->setBranchId( branchId );
_sources.insert( current );
_queue.push( current ); _queue.push( current );
Vertex* source = current; current = current->getPredecessor();
Vertex* target = source->getPredecessor(); }
current = target;
if ( (source->getGCell()->getXMin() > target->getGCell()->getXMin()) cdebug_tabw(112,-1);
or (source->getGCell()->getYMin() > target->getGCell()->getYMin()) ) }
std::swap( source, target );
Contact* sourceContact = source->getGContact( _net );
Contact* targetContact = target->getGContact( _net );
Segment* segment = NULL; void Dijkstra::_materialize ()
if (from->isHorizontal()) { {
segment = Horizontal::create( sourceContact cdebug_log(112,1) << "Dijkstra::_materialize() " << _net << " _sources:" << _sources.size() << endl;
if (_sources.size() < 2) { cdebug_tabw(112,-1); return; }
for ( Vertex* startVertex : _sources ) {
cdebug_log(112,0) << "? " << startVertex << endl;
if (not startVertex->getFrom()) continue;
if ( not startVertex->hasGContact(_net)
and not startVertex->getRpCount()
and (startVertex->getDegree() < 3)) continue;
Vertex* source = startVertex;
while ( source ) {
cdebug_log(112,0) << "* " << source << endl;
Edge* from = source->getFrom();
vector<Edge*> aligneds;
aligneds.push_back( from );
Vertex* target = source->getPredecessor();
Interval constraint = from->getSide();
source->setFrom( NULL );
cdebug_log(112,0) << "| " << target << endl;
while ( true ) {
from = target->getFrom();
if ( not from
or (target->hasGContact(_net))
or (target->getRpCount())
or (target->getDegree() > 2)
or (aligneds.back()->isHorizontal() xor from->isHorizontal())
or not constraint.intersect(from->getSide())) break;
aligneds.push_back( from );
constraint.merge( from->getSide() );
Vertex* nextTarget = target->getPredecessor();
target->setFrom( NULL );
target = nextTarget;
cdebug_log(112,0) << "+ " << target << endl;
}
Contact* sourceContact = source->getGContact( _net );
Contact* targetContact = target->hasGContact( _net );
Segment* segment = NULL;
if (not targetContact) {
if (target->getFrom()) targetContact = target->getGContact( _net );
else targetContact = target->breakGoThrough( _net );
}
if ( (source->getGCell()->getXMin() > target->getGCell()->getXMin())
or (source->getGCell()->getYMin() > target->getGCell()->getYMin()) )
std::swap( sourceContact, targetContact );
if (aligneds.front()->isHorizontal()) {
segment = Horizontal::create( sourceContact
, targetContact
, _anabatic->getConfiguration()->getGHorizontalLayer()
, constraint.getCenter()
, DbU::fromLambda(2.0)
);
for ( Edge* through : aligneds ) through->add( segment );
} else {
segment = Vertical::create( sourceContact
, targetContact , targetContact
, _anabatic->getConfiguration()->getGHorizontalLayer() , _anabatic->getConfiguration()->getGVerticalLayer()
, from->getAxis() , constraint.getCenter()
, DbU::fromLambda(2.0) , DbU::fromLambda(2.0)
); );
} else { for ( Edge* through : aligneds ) through->add( segment );
segment = Vertical::create( sourceContact }
, targetContact
, _anabatic->getConfiguration()->getGVerticalLayer() cdebug_log(112,0) << "| " << "break (turn, branch or terminal)." << endl;
, from->getAxis() source = (target->getFrom()) ? target : NULL;
, DbU::fromLambda(2.0)
);
} }
from->setSegment( segment );
} }
cdebug_tabw(112,-1); cdebug_tabw(112,-1);
@ -554,118 +554,22 @@ namespace Anabatic {
while ( not _targets.empty() and _propagate(enabledEdges) ); while ( not _targets.empty() and _propagate(enabledEdges) );
_queue.clear(); _queue.clear();
_materialize();
cdebug_tabw(112,-1); cdebug_tabw(112,-1);
DebugSession::close(); DebugSession::close();
} }
void Dijkstra::ripup ( Edge* edge ) void Dijkstra::_toSources ( Vertex* source, int connexId )
{ {
DebugSession::open( _net, 112, 120 ); cdebug_log(112,1) << "Dijkstra::_setReacheds()" << endl;
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 ); source->setConnexId( connexId );
source->setDistance( 0.0 );
_targets.erase ( source );
_sources.insert( source );
_queue.push( source );
VertexSet stack; VertexSet stack;
stack.insert( source ); stack.insert( source );
@ -677,7 +581,7 @@ namespace Anabatic {
cdebug_log(112,0) << "| source:" << source << " stack.size():" << stack.size() << endl; cdebug_log(112,0) << "| source:" << source << " stack.size():" << stack.size() << endl;
for ( Edge* edge : source->getGCell()->getEdges() ) { for ( Edge* edge : source->getGCell()->getEdges() ) {
if (not edge->getSegment()) { if (not edge->hasNet(_net)) {
cdebug_log(112,0) << " Not connected:" << edge << endl; cdebug_log(112,0) << " Not connected:" << edge << endl;
continue; continue;
} }
@ -689,6 +593,10 @@ namespace Anabatic {
if (vneighbor->getConnexId() == connexId) continue; if (vneighbor->getConnexId() == connexId) continue;
vneighbor->setConnexId( connexId ); vneighbor->setConnexId( connexId );
vneighbor->setDistance( 0.0 );
_targets.erase ( vneighbor );
_sources.insert( vneighbor );
_queue.push( vneighbor );
stack.insert( vneighbor ); stack.insert( vneighbor );
} }
} }
@ -697,15 +605,48 @@ namespace Anabatic {
} }
void Dijkstra::_getConnecteds ( Vertex* source, VertexSet& connecteds )
{
cdebug_log(112,1) << "Dijkstra::_getConnecteds()" << endl;
connecteds.clear();
connecteds.insert( source );
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->hasNet(_net)) {
cdebug_log(112,0) << " Not connected:" << edge << endl;
continue;
}
GCell* gneighbor = edge->getOpposite(source->getGCell());
Vertex* vneighbor = gneighbor->getObserver<Vertex>(GCell::Observable::Vertex);
if (connecteds.find(vneighbor) != connecteds.end()) continue;
stack.insert( vneighbor );
connecteds.insert( vneighbor );
}
}
cdebug_tabw(112,-1);
}
void Dijkstra::_checkEdges () const void Dijkstra::_checkEdges () const
{ {
cdebug_log(112,1) << "Dijkstra::_checkEdges()" << endl; cdebug_log(112,1) << "Dijkstra::_checkEdges()" << endl;
for ( Vertex* vertex : _vertexes ) { for ( Vertex* vertex : _vertexes ) {
for ( Edge* edge : vertex->getGCell()->getEdges(Flags::EastSide|Flags::NorthSide) ) { for ( Edge* edge : vertex->getGCell()->getEdges(Flags::EastSide|Flags::NorthSide) ) {
if (edge->getSegment()) {
cdebug_log(112,0) << "Not reset:" << edge << edge->getSegment() << endl;
}
} }
} }

View File

@ -42,7 +42,7 @@ namespace Anabatic {
, _source (source) , _source (source)
, _target (target) , _target (target)
, _axis (0) , _axis (0)
, _segment (NULL) , _segments ()
{ } { }
@ -182,17 +182,43 @@ namespace Anabatic {
} }
void Edge::destroySegment () Segment* Edge::getSegment ( const Net* owner ) const
{ {
if (not _segment) return; for ( Segment* segment : _segments ) {
if (segment->getNet() == owner) return segment;
}
return NULL;
}
Contact* csource = dynamic_cast<Contact*>( _segment->getSource() );
Contact* ctarget = dynamic_cast<Contact*>( _segment->getTarget() );
_segment->destroy(); void Edge::add ( Segment* segment )
_segment = NULL; {
if (csource) getSource()->unrefContact( csource ); _segments.push_back( segment );
if (ctarget) getTarget()->unrefContact( ctarget ); incRealOccupancy( 1 ); // Need to take the wire width into account.
}
void Edge::remove ( Segment* segment )
{
for ( size_t i=0 ; i<_segments.size() ; ++i ) {
if (_segments[i] == segment) {
std::swap( _segments[i], _segments[_segments.size()-1] );
_segments.pop_back();
incRealOccupancy( -1 ); // Need to take the wire width into account.
return;
}
}
}
void Edge::replace ( Segment* orig, Segment* repl )
{
for ( size_t i=0 ; i<_segments.size() ; ++i ) {
if (_segments[i] == orig) {
_segments[i] = repl;
return;
}
}
} }
@ -281,13 +307,14 @@ namespace Anabatic {
Record* Edge::_getRecord () const Record* Edge::_getRecord () const
{ {
Record* record = Super::_getRecord(); Record* record = Super::_getRecord();
record->add( getSlot("_flags" , _flags ) ); record->add( getSlot("_flags" , _flags ) );
record->add( getSlot("_capacity" , _capacity ) ); record->add( getSlot("_capacity" , _capacity ) );
record->add( getSlot("_realOccupancy" , _realOccupancy ) ); record->add( getSlot("_realOccupancy" , _realOccupancy ) );
record->add( getSlot("_estimateOccupancy", _estimateOccupancy) ); record->add( getSlot("_estimateOccupancy", _estimateOccupancy) );
record->add( getSlot("_source" , _source ) ); record->add( getSlot("_source" , _source ) );
record->add( getSlot("_target" , _target ) ); record->add( getSlot("_target" , _target ) );
record->add( DbU::getValueSlot("_axis", &_axis) ); record->add( DbU::getValueSlot("_axis", &_axis) );
record->add( getSlot("_segments" , &_segments ) );
return record; return record;
} }

View File

@ -441,12 +441,41 @@ namespace Anabatic {
} }
bool GCell::hasGContact ( const Contact* owned ) const Contact* GCell::hasGContact ( const Net* net ) const
{ {
for ( Contact* contact : _gcontacts ) { for ( Contact* contact : _gcontacts ) {
if (contact == owned) return true; if (contact->getNet() == net) return contact;
} }
return false; return NULL;
}
Contact* GCell::hasGContact ( const Contact* owned ) const
{
for ( Contact* contact : _gcontacts ) {
if (contact == owned) return contact;
}
return NULL;
}
Contact* GCell::breakGoThrough ( Net* net )
{
for ( Edge* edge : _eastEdges ) {
for ( Segment* segment : edge->getSegments() ) {
if (segment->getNet() == net)
return getAnabatic()->breakAt( segment, this );
}
}
for ( Edge* edge : _northEdges ) {
for ( Segment* segment : edge->getSegments() ) {
if (segment->getNet() == net)
return getAnabatic()->breakAt( segment, this );
}
}
return NULL;
} }
@ -459,6 +488,17 @@ namespace Anabatic {
} }
Edge* GCell::getEdgeAt ( Flags sideHint, DbU::Unit u ) const
{
for ( Edge* edge : getEdges(sideHint) ) {
GCell* side = edge->getOpposite(this);
if ( (sideHint & (Flags::WestSide |Flags::EastSide )) and (u < side->getYMax()) ) return edge;
if ( (sideHint & (Flags::SouthSide|Flags::NorthSide)) and (u < side->getXMax()) ) 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 ) {
@ -875,7 +915,6 @@ namespace Anabatic {
Contact* GCell::getGContact ( Net* net ) Contact* GCell::getGContact ( Net* net )
{ {
for ( Contact* contact : _gcontacts ) { for ( Contact* contact : _gcontacts ) {
if (contact->getNet() == net) { if (contact->getNet() == net) {
cdebug_log(111,0) << "GCell::getGContact(): " << contact << endl; cdebug_log(111,0) << "GCell::getGContact(): " << contact << endl;
@ -901,10 +940,13 @@ namespace Anabatic {
{ {
if (_gcontacts.empty()) return false; if (_gcontacts.empty()) return false;
cdebug_log(112,0) << "GCell::unrefContact(): " << unref << endl;
for ( size_t i=0 ; i< _gcontacts.size() ; ++i ) { for ( size_t i=0 ; i< _gcontacts.size() ; ++i ) {
if (_gcontacts[i] == unref) { if (_gcontacts[i] == unref) {
if (_gcontacts[i]->getSlaveComponents().getLocator()->isValid()) return false; if (_gcontacts[i]->getSlaveComponents().getLocator()->isValid()) return false;
cdebug_log(112,0) << " Effective destroy." << endl;
std::swap( _gcontacts[i], _gcontacts[_gcontacts.size()-1] ); std::swap( _gcontacts[i], _gcontacts[_gcontacts.size()-1] );
_gcontacts[ _gcontacts.size()-1 ]->destroy(); _gcontacts[ _gcontacts.size()-1 ]->destroy();
_gcontacts.pop_back(); _gcontacts.pop_back();

View File

@ -112,12 +112,13 @@ namespace Anabatic {
cell->flattenNets( Cell::Flags::BuildRings ); cell->flattenNets( Cell::Flags::BuildRings );
cell->createRoutingPadRings( Cell::Flags::BuildRings ); cell->createRoutingPadRings( Cell::Flags::BuildRings );
//DebugSession::addToTrace( cell->getNet("ra(2)") );
//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("a_from_pads(0)") ); //DebugSession::addToTrace( cell->getNet("a_from_pads(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(126)") ); //DebugSession::addToTrace( cell->getNet("mips_r3000_1m_dp_shift32_rshift_se_muxoutput(159)") );
startMeasures(); startMeasures();
@ -175,12 +176,12 @@ namespace Anabatic {
while ( not ovEdges.empty() ) { while ( not ovEdges.empty() ) {
Edge* ovEdge = ovEdges[0]; Edge* ovEdge = ovEdges[0];
NetSet netsToUnroute; NetSet netsToUnroute;
getNetsFromEdge( ovEdge, netsToUnroute );
for ( Net* net : netsToUnroute ) { vector<Segment*> segments = ovEdge->getSegments();
dijkstra->load( net ); for ( Segment* segment : segments ) {
dijkstra->ripup( ovEdge ); netsToRoute.insert( segment->getNet() );
netsToRoute.insert( net ); cerr << segment->getNet() << endl;
ripup( segment, Flags::Propagate );
} }
} }
@ -191,6 +192,29 @@ namespace Anabatic {
<< " " << setw( 6) << Timer::getStringMemory(_timer.getIncrease()) << endl; << " " << setw( 6) << Timer::getStringMemory(_timer.getIncrease()) << endl;
startMeasures(); startMeasures();
#if THIS_IS_A_TEST
if (iteration == 0) {
Net* testNet = getCell()->getNet( "ra(2)" );
DebugSession::open( testNet, 112, 120 );
if (testNet) {
for ( Component* component : testNet->getComponents() ) {
if (component->getId() == 23947) {
Segment* segment = static_cast<Segment*>( component );
GCellsUnder gcells = getGCellsUnder( segment );
Contact* contact = breakAt( segment, gcells->gcellAt(2) );
cerr << "break:" << contact << endl;
unify( contact );
//ripup( static_cast<Segment*>(component), Flags::Propagate );
//iteration = 5;
//netsToRoute.insert( testNet );
break;
}
}
}
DebugSession::close();
}
#endif
++iteration; ++iteration;
} }

View File

@ -232,6 +232,7 @@ namespace Anabatic {
engine->stopMeasures(); engine->stopMeasures();
engine->printMeasures( "Dijkstra" ); engine->printMeasures( "Dijkstra" );
#if 0
const vector<Edge*>& ovEdges = engine->getOvEdges(); const vector<Edge*>& ovEdges = engine->getOvEdges();
if (not ovEdges.empty()) { if (not ovEdges.empty()) {
size_t count = 0; size_t count = 0;
@ -246,10 +247,11 @@ namespace Anabatic {
UpdateSession::open(); UpdateSession::open();
Net* net = *nets.begin(); Net* net = *nets.begin();
dijkstra->load( net ); //dijkstra->load( net );
dijkstra->ripup( ovEdges[0] ); //dijkstra->ripup( ovEdges[0] );
UpdateSession::close(); UpdateSession::close();
} }
#endif
UpdateSession::open(); UpdateSession::open();
delete dijkstra; delete dijkstra;

View File

@ -647,6 +647,7 @@ namespace {
static void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 ); static void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 );
private: private:
void _do_xG (); void _do_xG ();
void _do_2G ();
void _do_xG_1Pad (); void _do_xG_1Pad ();
void _do_1G_1PinM2 (); void _do_1G_1PinM2 ();
void _do_1G_1M1 (); void _do_1G_1M1 ();
@ -996,11 +997,7 @@ namespace {
case Conn_2G_4M3: case Conn_2G_4M3:
case Conn_3G_1M3: _do_xG_xM3 (); break; case Conn_3G_1M3: _do_xG_xM3 (); break;
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break; case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break;
case Conn_2G: case Conn_2G: _do_2G (); break;
if ( (_east and _west) or (_north and _south) ) {
straightLine = true;
break;
}
case Conn_3G: case Conn_3G:
case Conn_4G: case Conn_4G:
_do_xG(); _do_xG();
@ -1490,6 +1487,28 @@ namespace {
} }
void GCellTopology::_do_2G ()
{
cdebug_log(145,1) << "_do_2G()" << endl;
if (_east and _west) {
_southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
_northEastContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( _southWestContact, _northEastContact, Flags::Vertical );
} else if (_south and _north) {
_southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
_northEastContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( _southWestContact, _northEastContact, Flags::Horizontal );
} else {
_southWestContact
= _northEastContact
= AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
}
cdebug_tabw(145,-1);
}
void GCellTopology::_do_xG_1Pad () void GCellTopology::_do_xG_1Pad ()
{ {
cdebug_log(145,1) << "_do_xG_1Pad() [Managed Configuration - Optimized] " << _topology << endl; cdebug_log(145,1) << "_do_xG_1Pad() [Managed Configuration - Optimized] " << _topology << endl;

View File

@ -94,15 +94,9 @@ namespace Anabatic {
Box gcellBb = gcell->getBoundingBox(); Box gcellBb = gcell->getBoundingBox();
Box updateArea = _area.getIntersection( gcellBb ); Box updateArea = _area.getIntersection( gcellBb );
cdebug_log(110,0) << "_side " << _side << endl; cdebug_log(110,0) << "_side: " << DbU::getValueString(_side) << endl;
cdebug_log(110,0) << "_area.getXMin() " << _area.getXMin() << endl; cdebug_log(110,0) << "_area: " << _area << endl;
cdebug_log(110,0) << "_area.getYMin() " << _area.getYMin() << endl; cdebug_log(110,0) << "updateArea: " << updateArea << endl;
cdebug_log(110,0) << "_area.getXMax() " << _area.getXMax() << endl;
cdebug_log(110,0) << "_area.getYMax() " << _area.getYMax() << endl;
cdebug_log(110,0) << "updateArea.getXMin() " << updateArea.getXMin() << endl;
cdebug_log(110,0) << "updateArea.getYMin() " << updateArea.getYMin() << endl;
cdebug_log(110,0) << "updateArea.getXMax() " << updateArea.getXMax() << endl;
cdebug_log(110,0) << "updateArea.getYMax() " << updateArea.getYMax() << endl;
if (updateArea.isEmpty()) { if (updateArea.isEmpty()) {
cerr << Error( "Matrix::updateLookup(): %s is not under area of %s." cerr << Error( "Matrix::updateLookup(): %s is not under area of %s."

View File

@ -17,6 +17,7 @@
#ifndef ANABATIC_ANABATIC_ENGINE_H #ifndef ANABATIC_ANABATIC_ENGINE_H
#define ANABATIC_ANABATIC_ENGINE_H #define ANABATIC_ANABATIC_ENGINE_H
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <set> #include <set>
@ -54,6 +55,56 @@ namespace Anabatic {
typedef std::set<Net*,Entity::CompareById> NetSet; typedef std::set<Net*,Entity::CompareById> NetSet;
typedef std::map<unsigned int,NetRoutingState*> NetRoutingStates; typedef std::map<unsigned int,NetRoutingState*> NetRoutingStates;
class AnabaticEngine;
// -------------------------------------------------------------------
// Class : "Anabatic::RawGCellsUnder".
class RawGCellsUnder {
public:
class Element {
public:
inline Element ( GCell*, Edge* );
inline GCell* gcell () const;
inline Edge* edge () const;
private:
GCell* _gcell;
Edge* _edge;
};
public:
RawGCellsUnder ( const AnabaticEngine*, Segment* );
inline bool empty () const;
inline size_t size () const;
inline GCell* gcellAt ( size_t ) const;
inline GCell* gcellRAt ( size_t ) const;
inline Edge* edgeAt ( size_t ) const;
inline const vector<Element>& getElements () const;
private:
RawGCellsUnder ( const RawGCellsUnder& );
RawGCellsUnder& operator= ( const RawGCellsUnder& );
private:
vector<Element> _elements;
};
inline RawGCellsUnder::Element::Element ( GCell* gcell, Edge* edge ) : _gcell(gcell), _edge(edge) { }
inline GCell* RawGCellsUnder::Element::gcell () const { return _gcell; }
inline Edge* RawGCellsUnder::Element::edge () const { return _edge; }
inline bool RawGCellsUnder::empty () const { return _elements.empty(); }
inline size_t RawGCellsUnder::size () const { return _elements.size(); }
inline const vector<RawGCellsUnder::Element>&
RawGCellsUnder::getElements () const { return _elements; }
inline Edge* RawGCellsUnder::edgeAt ( size_t i ) const { return (i<size()) ? _elements[i].edge () : NULL; }
inline GCell* RawGCellsUnder::gcellAt ( size_t i ) const { return (i<size()) ? _elements[i].gcell() : NULL; }
inline GCell* RawGCellsUnder::gcellRAt ( size_t i ) const { return (i<size()) ? _elements[size()-1-i].gcell() : NULL; }
typedef std::shared_ptr<RawGCellsUnder> GCellsUnder;
// -------------------------------------------------------------------
// Class : "Anabatic::AnabaticEngine".
class AnabaticEngine : public ToolEngine { class AnabaticEngine : public ToolEngine {
public: public:
@ -83,6 +134,7 @@ namespace Anabatic {
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;
inline GCellsUnder getGCellsUnder ( Segment* ) const;
int getCapacity ( Interval, Flags ) const; int getCapacity ( Interval, Flags ) const;
size_t getNetsFromEdge ( const Edge*, NetSet& ); size_t getNetsFromEdge ( const Edge*, NetSet& );
inline void setState ( EngineState state ); inline void setState ( EngineState state );
@ -92,6 +144,9 @@ namespace Anabatic {
// Dijkstra related functions. // Dijkstra related functions.
inline int getStamp () const; inline int getStamp () const;
inline int incStamp (); inline int incStamp ();
Contact* breakAt ( Segment*, GCell* );
void ripup ( Segment*, Flags );
bool unify ( Contact* );
// Global routing related functions. // Global routing related functions.
void globalRoute (); void globalRoute ();
void cleanupGlobal (); void cleanupGlobal ();
@ -199,6 +254,7 @@ namespace Anabatic {
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); }
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
inline unsigned int AnabaticEngine::getDensityMode () const { return _densityMode; } inline unsigned int AnabaticEngine::getDensityMode () const { return _densityMode; }
inline void AnabaticEngine::setDensityMode ( unsigned int mode ) { _densityMode=mode; } inline void AnabaticEngine::setDensityMode ( unsigned int mode ) { _densityMode=mode; }
inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; } inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; }

View File

@ -50,6 +50,7 @@ namespace Anabatic {
static const unsigned int SouthSide = Vertical |Target; static const unsigned int SouthSide = Vertical |Target;
static const unsigned int NorthSide = Vertical |Source; static const unsigned int NorthSide = Vertical |Source;
static const unsigned int AllSides = WestSide|EastSide|SouthSide|NorthSide ; static const unsigned int AllSides = WestSide|EastSide|SouthSide|NorthSide ;
static const unsigned int EndsMask = Source|Target;
static const unsigned int DirectionMask = Horizontal|Vertical; static const unsigned int DirectionMask = Horizontal|Vertical;
static const unsigned int DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; static const unsigned int DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment;
static const unsigned int GCellTypeMask = DeviceGCell|ChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; static const unsigned int GCellTypeMask = DeviceGCell|ChannelGCell|StrutGCell|MatrixGCell|IoPadGCell;

View File

@ -64,6 +64,7 @@ namespace Anabatic {
//inline Vertex ( size_t id ); //inline Vertex ( size_t id );
inline ~Vertex (); inline ~Vertex ();
inline bool hasDoneAllRps () const; inline bool hasDoneAllRps () const;
inline Contact* hasGContact ( Net* );
inline unsigned int getId () const; inline unsigned int getId () const;
inline GCell* getGCell () const; inline GCell* getGCell () const;
inline AnabaticEngine* getAnabatic () const; inline AnabaticEngine* getAnabatic () const;
@ -74,15 +75,22 @@ namespace Anabatic {
inline int getStamp () const; inline int getStamp () const;
inline int getBranchId () const; inline int getBranchId () const;
inline int getConnexId () const; inline int getConnexId () const;
inline int getDegree () const;
inline int getRpCount () const;
inline Edge* getFrom () const; inline Edge* getFrom () const;
inline Vertex* getPredecessor () const; inline Vertex* getPredecessor () const;
inline void setDistance ( DbU::Unit ); inline void setDistance ( DbU::Unit );
inline void setStamp ( int ); inline void setStamp ( int );
inline void setConnexId ( int ); inline void setConnexId ( int );
inline void setBranchId ( int ); inline void setBranchId ( int );
inline void setDegree ( int );
inline void incDegree ( int delta=1 );
inline void setRpCount ( int );
inline void incRpCount ( int delta=1 );
inline void setFrom ( Edge* ); inline void setFrom ( Edge* );
inline void add ( RoutingPad* ); inline void add ( RoutingPad* );
inline void clearRps (); inline void clearRps ();
inline Contact* breakGoThrough ( Net* );
inline bool isNorth ( Vertex* ) const; inline bool isNorth ( Vertex* ) const;
inline bool isSouth ( Vertex* ) const; inline bool isSouth ( Vertex* ) const;
@ -113,6 +121,8 @@ namespace Anabatic {
Observer<Vertex> _observer; Observer<Vertex> _observer;
int _connexId; int _connexId;
int _branchId; int _branchId;
int _degree : 8;
int _rpCount : 8;
int _stamp; int _stamp;
DbU::Unit _distance; DbU::Unit _distance;
Edge* _from; Edge* _from;
@ -126,6 +136,8 @@ namespace Anabatic {
, _observer(this) , _observer(this)
, _connexId(-1) , _connexId(-1)
, _branchId( 0) , _branchId( 0)
, _degree ( 0)
, _rpCount ( 0)
, _stamp (-1) , _stamp (-1)
, _distance(unreached) , _distance(unreached)
, _from (NULL) , _from (NULL)
@ -135,22 +147,30 @@ namespace Anabatic {
} }
inline Vertex::~Vertex () { } inline Vertex::~Vertex () { }
inline unsigned int Vertex::getId () const { return _id; } inline Contact* Vertex::hasGContact ( Net* net ) { return _gcell->hasGContact(net); }
inline GCell* Vertex::getGCell () const { return _gcell; } inline unsigned int Vertex::getId () const { return _id; }
inline AnabaticEngine* Vertex::getAnabatic () const { return _gcell->getAnabatic(); } inline GCell* Vertex::getGCell () const { return _gcell; }
inline Contact* Vertex::getGContact ( Net* net ) { return _gcell->getGContact(net); } inline AnabaticEngine* Vertex::getAnabatic () const { return _gcell->getAnabatic(); }
inline Point Vertex::getCenter () const { return _gcell->getBoundingBox().getCenter(); } inline Contact* Vertex::getGContact ( Net* net ) { return _gcell->getGContact(net); }
inline DbU::Unit Vertex::getDistance () const { return hasValidStamp() ? _distance : unreached; } inline Point Vertex::getCenter () const { return _gcell->getBoundingBox().getCenter(); }
inline int Vertex::getStamp () const { return _stamp; } inline DbU::Unit Vertex::getDistance () const { return hasValidStamp() ? _distance : unreached; }
inline int Vertex::getConnexId () const { return hasValidStamp() ? _connexId : -1; } inline int Vertex::getStamp () const { return _stamp; }
inline int Vertex::getBranchId () const { return hasValidStamp() ? _branchId : 0; } inline int Vertex::getConnexId () const { return hasValidStamp() ? _connexId : -1; }
inline Edge* Vertex::getFrom () const { return _from; } inline int Vertex::getBranchId () const { return hasValidStamp() ? _branchId : 0; }
inline void Vertex::setDistance ( DbU::Unit distance ) { _distance=distance; } inline int Vertex::getDegree () const { return hasValidStamp() ? _degree : 0; }
inline void Vertex::setFrom ( Edge* from ) { _from=from; } inline int Vertex::getRpCount () const { return hasValidStamp() ? _rpCount : 0; }
inline void Vertex::setStamp ( int stamp ) { _stamp=stamp; } inline Edge* Vertex::getFrom () const { return _from; }
inline void Vertex::setConnexId ( int id ) { _connexId=id; } inline void Vertex::setDistance ( DbU::Unit distance ) { _distance=distance; }
inline void Vertex::setBranchId ( int id ) { _branchId=id; } inline void Vertex::setFrom ( Edge* from ) { _from=from; }
inline void Vertex::setStamp ( int stamp ) { _stamp=stamp; }
inline void Vertex::setConnexId ( int id ) { _connexId=id; }
inline void Vertex::setBranchId ( int id ) { _branchId=id; }
inline void Vertex::setDegree ( int degree ) { _degree=degree; }
inline void Vertex::incDegree ( int delta ) { _degree+=delta; }
inline void Vertex::setRpCount ( int count ) { _rpCount=count; }
inline void Vertex::incRpCount ( int delta ) { _rpCount+=delta; }
inline Contact* Vertex::breakGoThrough ( Net* net ) { return _gcell->breakGoThrough(net); }
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; }
@ -276,7 +296,6 @@ namespace Anabatic {
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& );
@ -284,9 +303,10 @@ namespace Anabatic {
void _cleanup (); void _cleanup ();
bool _propagate ( Flags enabledSides ); bool _propagate ( Flags enabledSides );
void _traceback ( Vertex* ); void _traceback ( Vertex* );
void _materialize ();
void _selectFirstSource (); void _selectFirstSource ();
Vertex* _propagateRipup ( Vertex* ); void _toSources ( Vertex*, int connexId );
void _tagConnecteds ( Vertex*, int connexId ); void _getConnecteds ( Vertex*, VertexSet& );
void _checkEdges () const; void _checkEdges () const;
static bool isRestricted ( const Vertex* v1, const Vertex* v2 ); static bool isRestricted ( const Vertex* v1, const Vertex* v2 );
private: private:

View File

@ -39,6 +39,7 @@ namespace Anabatic {
using Hurricane::Interval; using Hurricane::Interval;
using Hurricane::Box; using Hurricane::Box;
using Hurricane::Segment; using Hurricane::Segment;
using Hurricane::Net;
using Hurricane::Cell; using Hurricane::Cell;
using Hurricane::ExtensionGo; using Hurricane::ExtensionGo;
@ -52,82 +53,85 @@ namespace Anabatic {
public: public:
static DbU::Unit unity; static DbU::Unit unity;
public: public:
static Edge* create ( GCell* source, GCell* target, Flags flags=Flags::NoFlags ); static Edge* create ( GCell* source, GCell* target, Flags flags=Flags::NoFlags );
virtual void destroy (); virtual void destroy ();
public: public:
inline bool isVertical () const; inline bool isVertical () const;
inline bool isHorizontal () const; inline bool isHorizontal () const;
inline unsigned int getCapacity () const; inline bool hasNet ( const Net* ) const;
inline unsigned int getRealOccupancy () const; inline unsigned int getCapacity () const;
inline unsigned int getEstimateOccupancy () const; inline unsigned int getRealOccupancy () const;
DbU::Unit getDistance () const; inline unsigned int getEstimateOccupancy () const;
inline GCell* getSource () const; DbU::Unit getDistance () const;
inline GCell* getTarget () const; inline GCell* getSource () const;
GCell* getOpposite ( const GCell* ) const; inline GCell* getTarget () const;
AnabaticEngine* getAnabatic () const; GCell* getOpposite ( const GCell* ) const;
inline DbU::Unit getAxis () const; AnabaticEngine* getAnabatic () const;
DbU::Unit getAxisMin () const; inline DbU::Unit getAxis () const;
Interval getSide () const; DbU::Unit getAxisMin () const;
inline Segment* getSegment () const; Interval getSide () const;
inline void incCapacity ( int ); Segment* getSegment ( const Net* ) const;
void incRealOccupancy ( int ); inline const vector<Segment*>& getSegments () const;
inline void setSegment ( Segment* ); inline void incCapacity ( int );
void destroySegment (); void incRealOccupancy ( int );
inline const Flags& flags () const; void add ( Segment* );
inline Flags& flags (); void remove ( Segment* );
inline void revalidate () const; void replace ( Segment* orig, Segment* repl );
void _setSource ( GCell* ); inline const Flags& flags () const;
void _setTarget ( GCell* ); inline Flags& flags ();
private: inline void revalidate () const;
void _invalidate (); void _setSource ( GCell* );
void _revalidate (); void _setTarget ( GCell* );
public: private:
// ExtensionGo support. void _invalidate ();
inline const Name& staticGetName (); void _revalidate ();
virtual const Name& getName () const; public:
virtual void translate ( const DbU::Unit&, const DbU::Unit& ); // ExtensionGo support.
virtual Box getBoundingBox () const; inline const Name& staticGetName ();
public: virtual const Name& getName () const;
// Inspector support. virtual void translate ( const DbU::Unit&, const DbU::Unit& );
virtual string _getTypeName () const; virtual Box getBoundingBox () const;
virtual string _getString () const; public:
virtual Record* _getRecord () const; // Inspector support.
protected: virtual string _getTypeName () const;
Edge ( GCell* source, GCell* target, Flags flags ); virtual string _getString () const;
virtual ~Edge (); virtual Record* _getRecord () const;
virtual void _postCreate (); protected:
virtual void _preDestroy (); Edge ( GCell* source, GCell* target, Flags flags );
private: virtual ~Edge ();
Edge ( const Edge& ); virtual void _postCreate ();
Edge& operator= ( const Edge& ); virtual void _preDestroy ();
private:
Edge ( const Edge& );
Edge& operator= ( const Edge& );
private: private:
static Name _extensionName; static Name _extensionName;
Flags _flags; Flags _flags;
unsigned int _capacity; unsigned int _capacity;
unsigned int _realOccupancy; unsigned int _realOccupancy;
float _estimateOccupancy; float _estimateOccupancy;
GCell* _source; GCell* _source;
GCell* _target; GCell* _target;
DbU::Unit _axis; DbU::Unit _axis;
Segment* _segment; vector<Segment*> _segments;
}; };
inline const Name& Edge::staticGetName () { return _extensionName; } inline const Name& Edge::staticGetName () { return _extensionName; }
inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); } inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); }
inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); } inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); }
inline unsigned int Edge::getCapacity () const { return _capacity; } inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); }
inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; } inline unsigned int Edge::getCapacity () const { return _capacity; }
inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; } inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; }
inline GCell* Edge::getSource () const { return _source; } inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; }
inline GCell* Edge::getTarget () const { return _target; } inline GCell* Edge::getSource () const { return _source; }
inline DbU::Unit Edge::getAxis () const { return _axis; } inline GCell* Edge::getTarget () const { return _target; }
inline Segment* Edge::getSegment () const { return _segment; } inline DbU::Unit Edge::getAxis () const { return _axis; }
inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; } inline const vector<Segment*>& Edge::getSegments () const { return _segments; }
inline void Edge::setSegment ( Segment* s ) { _segment=s; } inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; }
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::revalidate () const { /*if (_flags&Flags::Invalidated)*/ const_cast<Edge*>(this)->_revalidate(); } inline void Edge::revalidate () const { /*if (_flags&Flags::Invalidated)*/ const_cast<Edge*>(this)->_revalidate(); }
} // Anabatic namespace. } // Anabatic namespace.

View File

@ -139,7 +139,8 @@ namespace Anabatic {
bool isEast ( GCell* ) const; bool isEast ( GCell* ) const;
bool isNorth ( GCell* ) const; bool isNorth ( GCell* ) const;
bool isSouth ( GCell* ) const; bool isSouth ( GCell* ) const;
bool hasGContact ( const Contact* ) const; Contact* hasGContact ( const Contact* ) const;
Contact* hasGContact ( const Net* ) const;
inline AnabaticEngine* getAnabatic () const; inline AnabaticEngine* getAnabatic () const;
inline Flags getType () const; inline Flags getType () const;
inline DbU::Unit getXMin () const; inline DbU::Unit getXMin () const;
@ -153,6 +154,7 @@ namespace Anabatic {
inline const vector<Edge*>& getNorthEdges () const; inline const vector<Edge*>& getNorthEdges () const;
inline const vector<Edge*>& getSouthEdges () const; inline const vector<Edge*>& getSouthEdges () const;
Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const; Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const;
Edge* getEdgeAt ( Flags sideHint, DbU::Unit u ) const;
inline Edges getEdges ( Flags sides=Flags::AllSides ) const; inline Edges getEdges ( Flags sides=Flags::AllSides ) const;
inline GCell* getWest () const; inline GCell* getWest () const;
inline GCell* getEast () const; inline GCell* getEast () const;
@ -169,6 +171,7 @@ namespace Anabatic {
bool doGrid (); bool doGrid ();
Contact* getGContact ( Net* ); Contact* getGContact ( Net* );
inline const vector<Contact*>& getGContacts () const; inline const vector<Contact*>& getGContacts () const;
Contact* breakGoThrough ( Net* net );
bool unrefContact ( Contact* ); bool unrefContact ( Contact* );
void setXY ( DbU::Unit x, DbU::Unit y ); void setXY ( DbU::Unit x, DbU::Unit y );
void updateContactsPosition (); void updateContactsPosition ();