From 84dad2249e794f56cde531ad61d6e172f0537cb5 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sat, 30 Jul 2016 12:15:49 +0200 Subject: [PATCH] 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()). --- anabatic/src/AnabaticEngine.cpp | 286 ++++++++++++++++++ anabatic/src/AutoContact.cpp | 60 ++-- anabatic/src/Dijkstra.cpp | 387 +++++++++++-------------- anabatic/src/Edge.cpp | 57 +++- anabatic/src/GCell.cpp | 50 +++- anabatic/src/GlobalRoute.cpp | 36 ++- anabatic/src/GraphicAnabaticEngine.cpp | 6 +- anabatic/src/LoadGlobalRouting.cpp | 29 +- anabatic/src/Matrix.cpp | 12 +- anabatic/src/anabatic/AnabaticEngine.h | 56 ++++ anabatic/src/anabatic/Constants.h | 1 + anabatic/src/anabatic/Dijkstra.h | 58 ++-- anabatic/src/anabatic/Edge.h | 148 +++++----- anabatic/src/anabatic/GCell.h | 5 +- 14 files changed, 802 insertions(+), 389 deletions(-) diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 8cddd236..f157ffd3 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -19,6 +19,7 @@ #include "hurricane/Error.h" #include "hurricane/RegularLayer.h" #include "hurricane/Horizontal.h" +#include "hurricane/RoutingPad.h" #include "hurricane/Vertical.h" #include "hurricane/Cell.h" #include "hurricane/DebugSession.h" @@ -63,6 +64,71 @@ namespace Anabatic { " 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( segment ); + if (horizontal) { + side = Flags::EastSide; + axis = horizontal->getY(); + + if (horizontal->getSourceX() > horizontal->getTargetX()) + std::swap( gsource, gtarget ); + } else { + Vertical* vertical = dynamic_cast( 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". @@ -313,6 +379,226 @@ namespace Anabatic { } + Contact* AnabaticEngine::breakAt ( Segment* segment, GCell* breakGCell ) + { + size_t i = 0; + GCellsUnder gcells ( new RawGCellsUnder(this,segment) ); + for ( ; isize() ; ++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(segment); + if (horizontal) { + splitted = Horizontal::create( breakContact + , targetContact + , getConfiguration()->getGHorizontalLayer() + , horizontal->getY() + , DbU::fromLambda(2.0) + ); + } else { + Vertical* vertical = dynamic_cast(segment); + if (vertical) { + splitted = Vertical::create( breakContact + , targetContact + , getConfiguration()->getGVerticalLayer() + , vertical->getX() + , DbU::fromLambda(2.0) + ); + } else + return breakContact; + } + + for ( ; isize()-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( slave ); + if (h) { + if (vCount or (hCount > 1)) return false; + horizontals[hCount++] = h; + } else { + Vertical* v = dynamic_cast( 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 ; isize() ; ++i ) + constraints.intersection( gcells0->gcellAt(i)->getSide(Flags::Vertical) ); + } + + GCellsUnder gcells1 = getGCellsUnder( horizontals[1] ); + if (not gcells1->empty()) { + for ( size_t i=0 ; isize() ; ++i ) { + constraints.intersection( gcells1->gcellAt(i)->getSide(Flags::Vertical) ); + if (constraints.isEmpty()) return false; + } + } + + if (not gcells1->empty()) { + for ( size_t i=0 ; isize()-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 ; isize() ; ++i ) + constraints.intersection( gcells0->gcellAt(i)->getSide(Flags::Horizontal) ); + } + + GCellsUnder gcells1 = getGCellsUnder( verticals[1] ); + if (not gcells1->empty()) { + for ( size_t i=0 ; isize() ; ++i ) { + constraints.intersection( gcells1->gcellAt(i)->getSide(Flags::Horizontal) ); + if (constraints.isEmpty()) return false; + } + } + + if (not gcells1->empty()) { + for ( size_t i=0 ; isize()-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 ripups; + ripups.push_back( seed ); + + vector< pair > 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( 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(linked)) { ++slaveCount; continue; } + + connected = dynamic_cast( 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 ; isize()-1 ; ++i ) + gcells->edgeAt(i)->remove( segment ); + } + + Contact* source = dynamic_cast( segment->getSource() ); + Contact* target = dynamic_cast( 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 () { UpdateSession::open(); diff --git a/anabatic/src/AutoContact.cpp b/anabatic/src/AutoContact.cpp index f4bd4731..1ca8e040 100644 --- a/anabatic/src/AutoContact.cpp +++ b/anabatic/src/AutoContact.cpp @@ -122,8 +122,8 @@ namespace Anabatic { message << "Base contact still have slaves components, cancelled.\n" << " on: " << this; - forEach ( Component*, icomponent, _contact->getSlaveComponents() ) { - message << "\n | " << (*icomponent); + for ( Component* component : _contact->getSlaveComponents() ) { + message << "\n | " << component; } cerr << Error( message.str() ) << endl; @@ -189,12 +189,10 @@ namespace Anabatic { Component* anchor = getAnchor (); if (anchor) { minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); - //cdebug_log(149,0) << "Anchor:" << anchor << endl; } - forEach ( AutoSegment*, isegment, const_cast(this)->getAutoSegments() ) { - minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(isegment->getLayer()) ); - //cdebug_log(149,0) << "Slave:" << *icomponent << endl; + for ( AutoSegment* segment : const_cast(this)->getAutoSegments() ) { + minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) ); } return (unsigned int)minDepth; @@ -207,12 +205,10 @@ namespace Anabatic { Component* anchor = getAnchor (); if ( anchor ) { maxDepth = std::max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); - //cdebug_log(149,0) << "Anchor:" << anchor << endl; } - forEach ( AutoSegment*, isegment, const_cast(this)->getAutoSegments() ) { - maxDepth = std::max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(isegment->getLayer()) ); - //cdebug_log(149,0) << "Slave:" << *icomponent << endl; + for ( AutoSegment* segment : const_cast(this)->getAutoSegments() ) { + maxDepth = std::max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) ); } return (unsigned int)maxDepth; @@ -224,33 +220,33 @@ namespace Anabatic { DbU::Unit hSideLength = getGCell()->getSide( Flags::Horizontal ).getSize(); DbU::Unit vSideLength = getGCell()->getSide( Flags::Vertical ).getSize(); - forEach ( AutoSegment*, isegment, getAutoSegments() ) { - bool isSourceHook = (isegment->getAutoSource() == this); + for ( AutoSegment* segment : getAutoSegments() ) { + bool isSourceHook = (segment->getAutoSource() == this); - if (processeds.find(*isegment) != processeds.end()) continue; - processeds.insert( *isegment ); + if (processeds.find(segment) != processeds.end()) continue; + processeds.insert( segment ); - size_t depth = Session::getRoutingGauge()->getLayerDepth(isegment->getLayer()); + size_t depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer()); DbU::Unit length; - if (isegment->isLocal()) { - length = isegment->getLength(); + if (segment->isLocal()) { + length = segment->getLength(); lengths[depth] += length; - DbU::Unit sideLength = (isegment->isHorizontal()) ? hSideLength : vSideLength; - if ( not isegment->isUnbound() and (abs(length) > sideLength) ) + DbU::Unit sideLength = (segment->isHorizontal()) ? hSideLength : vSideLength; + if ( not segment->isUnbound() and (abs(length) > sideLength) ) cerr << Error("Suspicious length:%.2f of %s." - ,DbU::toLambda(length),getString(*isegment).c_str()) << endl; + ,DbU::toLambda(length),getString(segment).c_str()) << endl; } else { - if ( isegment->isHorizontal() ) { + if (segment->isHorizontal()) { if (isSourceHook) - lengths[depth] += _gcell->getXMax() - isegment->getSourceX(); + lengths[depth] += _gcell->getXMax() - segment->getSourceX(); else - lengths[depth] += isegment->getTargetX() - _gcell->getXMin(); + lengths[depth] += segment->getTargetX() - _gcell->getXMin(); } else { if (isSourceHook) - lengths[depth] += _gcell->getYMax() - isegment->getSourceY(); + lengths[depth] += _gcell->getYMax() - segment->getSourceY(); else - lengths[depth] += isegment->getTargetY() - _gcell->getYMin(); + lengths[depth] += segment->getTargetY() - _gcell->getYMin(); } } } @@ -301,8 +297,6 @@ namespace Anabatic { Session::invalidate( this ); _invalidate( flags ); - //forEach( AutoSegment*, isegment, getAutoSegments() ) - // isegment->invalidate(); getGCell()->invalidate(); cdebug_tabw(145,-1); @@ -349,12 +343,12 @@ namespace Anabatic { anchor = support->getAnchor(); - forEach ( Component*, icomponent, support->getSlaveComponents() ) { - Horizontal* h = dynamic_cast(*icomponent); + for ( Component* component : support->getSlaveComponents() ) { + Horizontal* h = dynamic_cast(component); if (h != NULL) { if (hcount < size) horizontals[hcount++] = h; } else { - Vertical* v = dynamic_cast(*icomponent); + Vertical* v = dynamic_cast(component); if ( (v != NULL) and (vcount < size) ) verticals[vcount++] = v; } } @@ -425,10 +419,10 @@ namespace Anabatic { cdebug_log(149,0) << "| Anchor depth: " << viaDepth << endl; } - forEach ( AutoSegment*, isegment, const_cast(this)->getAutoSegments() ) { - if (*isegment == moved) continue; + for ( AutoSegment* segment : const_cast(this)->getAutoSegments() ) { + if (segment == moved) continue; - size_t depth = rg->getLayerDepth(isegment->getLayer()); + size_t depth = rg->getLayerDepth(segment->getLayer()); if (viaDepth == 100) viaDepth = depth; else if (viaDepth != depth) return false; diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 130037d8..7c402a2c 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -65,6 +65,8 @@ namespace Anabatic { string s = "getXMin()) + "," + DbU::getValueString(_gcell->getYMin()) + ")" + + " rps:" + getString(_rpCount) + + " deg:" + getString(_degree) + " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None") + " d:" + ((_distance == unreached) ? "unreached" : ((_distance == unreachable) ? "unreachable" @@ -199,43 +201,26 @@ namespace Anabatic { { _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; - vector< std::pair > components; + vector rps; for ( Component* component : _net->getComponents() ) { RoutingPad* rp = dynamic_cast( component ); - if (rp) { components.push_back( make_pair(rp,true) ); continue; } - - Contact* gcontact = dynamic_cast( component ); - if (gcontact and (gcontact->getLayer() == gcontactLayer)) - components.push_back( make_pair(gcontact,false) ); + if (rp) { rps.push_back( rp ); continue; } } - for ( auto element : components ) { - RoutingPad* rp = NULL; - Contact* gcontact = NULL; - Point center; - - if (element.second) { - rp = static_cast( element.first ); - center = rp->getBoundingBox().getCenter(); - } else { - gcontact = static_cast( element.first ); - center = gcontact->getCenter(); - } - - GCell* gcell = _anabatic->getGCellUnder( center ); + for ( auto rp : rps ) { + Point center = rp->getBoundingBox().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 so the routing may be incomplete." - , getString(element.first).c_str() + , getString(rp).c_str() , getString(_net).c_str() ) << endl; continue; @@ -243,75 +228,30 @@ namespace Anabatic { _searchArea.merge( gcell->getBoundingBox() ); - Vertex* vertex = gcell->getObserver(GCell::Observable::Vertex); - if (vertex->getConnexId() < 0) { - vertex->setDistance( Vertex::unreached ); - vertex->setStamp ( _stamp ); - vertex->setConnexId( _connectedsId ); - vertex->setBranchId( 0 ); - vertex->setFrom ( NULL ); - _targets.insert( vertex ); - vertex->clearRestriction(); - cdebug_log(112,0) << "Add Vertex: " << vertex << endl; - } + Vertex* seed = gcell->getObserver(GCell::Observable::Vertex); + if (seed->getConnexId() < 0) { + VertexSet connecteds; + _getConnecteds( seed, connecteds ); - if (gcontact) { - for ( Component* slave : gcontact->getSlaveComponents() ) { - Flags sideHint = Flags::NoFlags; - GCell* oppositeGCell = NULL; - - Segment* segment = dynamic_cast(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(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; + ++_connectedsId; + for ( Vertex* vertex : connecteds ) { + vertex->setDistance ( Vertex::unreached ); + vertex->setStamp ( _stamp ); + vertex->setConnexId ( _connectedsId ); + vertex->setBranchId ( 0 ); + vertex->setDegree ( 1 ); + vertex->setRpCount ( 0 ); + vertex->setFrom ( NULL ); + vertex->clearRestriction(); + _targets.insert( vertex ); + cdebug_log(112,0) << "Add Vertex: " << vertex << 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 ); + seed->incRpCount(); + Contact* vcontact = seed->getGContact( _net ); + rp->getBodyHook()->detach(); + rp->getBodyHook()->attach( vcontact->getBodyHook() ); } cdebug_log(112,0) << "Search area: " << _searchArea << endl; @@ -384,11 +324,7 @@ namespace Anabatic { 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(); @@ -432,6 +368,8 @@ namespace Anabatic { if (not vneighbor->hasValidStamp()) { vneighbor->setConnexId( -1 ); 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; int branchId = _sources.size(); - _targets.erase( current ); + _toSources( current, _connectedsId ); + current = current->getPredecessor(); while ( current ) { cdebug_log(112,0) << "| " << current << endl; + + current->incDegree(); if (current->getConnexId() == _connectedsId) break; Edge* from = current->getFrom(); if (not from) break; - from->incRealOccupancy( 1 ); - _sources.insert( current ); current->setDistance( 0.0 ); current->setConnexId( _connectedsId ); current->setBranchId( branchId ); + _sources.insert( current ); _queue.push( current ); - Vertex* source = current; - Vertex* target = source->getPredecessor(); - current = target; + current = current->getPredecessor(); + } - if ( (source->getGCell()->getXMin() > target->getGCell()->getXMin()) - or (source->getGCell()->getYMin() > target->getGCell()->getYMin()) ) - std::swap( source, target ); + cdebug_tabw(112,-1); + } - Contact* sourceContact = source->getGContact( _net ); - Contact* targetContact = target->getGContact( _net ); - Segment* segment = NULL; - if (from->isHorizontal()) { - segment = Horizontal::create( sourceContact + void Dijkstra::_materialize () + { + 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 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 - , _anabatic->getConfiguration()->getGHorizontalLayer() - , from->getAxis() + , _anabatic->getConfiguration()->getGVerticalLayer() + , constraint.getCenter() , DbU::fromLambda(2.0) ); - } else { - segment = Vertical::create( sourceContact - , targetContact - , _anabatic->getConfiguration()->getGVerticalLayer() - , from->getAxis() - , DbU::fromLambda(2.0) - ); + for ( Edge* through : aligneds ) through->add( segment ); + } + + cdebug_log(112,0) << "| " << "break (turn, branch or terminal)." << endl; + source = (target->getFrom()) ? target : NULL; } - from->setSegment( segment ); } cdebug_tabw(112,-1); @@ -554,118 +554,22 @@ namespace Anabatic { while ( not _targets.empty() and _propagate(enabledEdges) ); _queue.clear(); + _materialize(); cdebug_tabw(112,-1); DebugSession::close(); } - void Dijkstra::ripup ( Edge* edge ) + void Dijkstra::_toSources ( Vertex* source, int connexId ) { - 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(GCell::Observable::Vertex); - Vertex* vtarget = gtarget->getObserver(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( component ); - // if (segment and (gtarget->hasGContact(dynamic_cast(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(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(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; + cdebug_log(112,1) << "Dijkstra::_setReacheds()" << endl; source->setConnexId( connexId ); + source->setDistance( 0.0 ); + _targets.erase ( source ); + _sources.insert( source ); + _queue.push( source ); VertexSet stack; stack.insert( source ); @@ -677,7 +581,7 @@ namespace Anabatic { cdebug_log(112,0) << "| source:" << source << " stack.size():" << stack.size() << endl; for ( Edge* edge : source->getGCell()->getEdges() ) { - if (not edge->getSegment()) { + if (not edge->hasNet(_net)) { cdebug_log(112,0) << " Not connected:" << edge << endl; continue; } @@ -689,6 +593,10 @@ namespace Anabatic { if (vneighbor->getConnexId() == connexId) continue; vneighbor->setConnexId( connexId ); + vneighbor->setDistance( 0.0 ); + _targets.erase ( vneighbor ); + _sources.insert( vneighbor ); + _queue.push( 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(GCell::Observable::Vertex); + + if (connecteds.find(vneighbor) != connecteds.end()) continue; + + stack.insert( vneighbor ); + connecteds.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; - } } } diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index 22515424..f3dab89d 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -42,7 +42,7 @@ namespace Anabatic { , _source (source) , _target (target) , _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( _segment->getSource() ); - Contact* ctarget = dynamic_cast( _segment->getTarget() ); - _segment->destroy(); - _segment = NULL; - if (csource) getSource()->unrefContact( csource ); - if (ctarget) getTarget()->unrefContact( ctarget ); + void Edge::add ( Segment* segment ) + { + _segments.push_back( segment ); + 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* record = Super::_getRecord(); - record->add( getSlot("_flags" , _flags ) ); - record->add( getSlot("_capacity" , _capacity ) ); - record->add( getSlot("_realOccupancy" , _realOccupancy ) ); - record->add( getSlot("_estimateOccupancy", _estimateOccupancy) ); - record->add( getSlot("_source" , _source ) ); - record->add( getSlot("_target" , _target ) ); + record->add( getSlot("_flags" , _flags ) ); + record->add( getSlot("_capacity" , _capacity ) ); + record->add( getSlot("_realOccupancy" , _realOccupancy ) ); + record->add( getSlot("_estimateOccupancy", _estimateOccupancy) ); + record->add( getSlot("_source" , _source ) ); + record->add( getSlot("_target" , _target ) ); record->add( DbU::getValueSlot("_axis", &_axis) ); + record->add( getSlot("_segments" , &_segments ) ); return record; } diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index b124abd8..ad5274a7 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -441,12 +441,41 @@ namespace Anabatic { } - bool GCell::hasGContact ( const Contact* owned ) const + Contact* GCell::hasGContact ( const Net* net ) const { 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 { for ( Edge* edge : _westEdges ) { @@ -875,7 +915,6 @@ namespace Anabatic { Contact* GCell::getGContact ( Net* net ) { - for ( Contact* contact : _gcontacts ) { if (contact->getNet() == net) { cdebug_log(111,0) << "GCell::getGContact(): " << contact << endl; @@ -901,10 +940,13 @@ namespace Anabatic { { if (_gcontacts.empty()) return false; + cdebug_log(112,0) << "GCell::unrefContact(): " << unref << endl; + for ( size_t i=0 ; i< _gcontacts.size() ; ++i ) { if (_gcontacts[i] == unref) { if (_gcontacts[i]->getSlaveComponents().getLocator()->isValid()) return false; + cdebug_log(112,0) << " Effective destroy." << endl; std::swap( _gcontacts[i], _gcontacts[_gcontacts.size()-1] ); _gcontacts[ _gcontacts.size()-1 ]->destroy(); _gcontacts.pop_back(); diff --git a/anabatic/src/GlobalRoute.cpp b/anabatic/src/GlobalRoute.cpp index faf82910..298dadcf 100644 --- a/anabatic/src/GlobalRoute.cpp +++ b/anabatic/src/GlobalRoute.cpp @@ -112,12 +112,13 @@ namespace Anabatic { cell->flattenNets( 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("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)") ); + //DebugSession::addToTrace( cell->getNet("mips_r3000_1m_dp_shift32_rshift_se_muxoutput(159)") ); startMeasures(); @@ -175,12 +176,12 @@ namespace Anabatic { 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 ); + vector segments = ovEdge->getSegments(); + for ( Segment* segment : segments ) { + netsToRoute.insert( segment->getNet() ); + cerr << segment->getNet() << endl; + ripup( segment, Flags::Propagate ); } } @@ -191,6 +192,29 @@ namespace Anabatic { << " " << setw( 6) << Timer::getStringMemory(_timer.getIncrease()) << endl; 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( component ); + GCellsUnder gcells = getGCellsUnder( segment ); + Contact* contact = breakAt( segment, gcells->gcellAt(2) ); + cerr << "break:" << contact << endl; + unify( contact ); + //ripup( static_cast(component), Flags::Propagate ); + //iteration = 5; + //netsToRoute.insert( testNet ); + break; + } + } + } + DebugSession::close(); + } +#endif + ++iteration; } diff --git a/anabatic/src/GraphicAnabaticEngine.cpp b/anabatic/src/GraphicAnabaticEngine.cpp index 643ddcaf..35b956d4 100644 --- a/anabatic/src/GraphicAnabaticEngine.cpp +++ b/anabatic/src/GraphicAnabaticEngine.cpp @@ -232,6 +232,7 @@ namespace Anabatic { engine->stopMeasures(); engine->printMeasures( "Dijkstra" ); +#if 0 const vector& ovEdges = engine->getOvEdges(); if (not ovEdges.empty()) { size_t count = 0; @@ -246,10 +247,11 @@ namespace Anabatic { UpdateSession::open(); Net* net = *nets.begin(); - dijkstra->load( net ); - dijkstra->ripup( ovEdges[0] ); + //dijkstra->load( net ); + //dijkstra->ripup( ovEdges[0] ); UpdateSession::close(); } +#endif UpdateSession::open(); delete dijkstra; diff --git a/anabatic/src/LoadGlobalRouting.cpp b/anabatic/src/LoadGlobalRouting.cpp index e6487dd1..0d8acce5 100644 --- a/anabatic/src/LoadGlobalRouting.cpp +++ b/anabatic/src/LoadGlobalRouting.cpp @@ -647,6 +647,7 @@ namespace { static void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 ); private: void _do_xG (); + void _do_2G (); void _do_xG_1Pad (); void _do_1G_1PinM2 (); void _do_1G_1M1 (); @@ -996,11 +997,7 @@ namespace { case Conn_2G_4M3: case Conn_3G_1M3: _do_xG_xM3 (); break; case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break; - case Conn_2G: - if ( (_east and _west) or (_north and _south) ) { - straightLine = true; - break; - } + case Conn_2G: _do_2G (); break; case Conn_3G: case Conn_4G: _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 () { cdebug_log(145,1) << "_do_xG_1Pad() [Managed Configuration - Optimized] " << _topology << endl; diff --git a/anabatic/src/Matrix.cpp b/anabatic/src/Matrix.cpp index 0de852da..13149d6c 100644 --- a/anabatic/src/Matrix.cpp +++ b/anabatic/src/Matrix.cpp @@ -94,15 +94,9 @@ namespace Anabatic { Box gcellBb = gcell->getBoundingBox(); Box updateArea = _area.getIntersection( gcellBb ); - cdebug_log(110,0) << "_side " << _side << endl; - cdebug_log(110,0) << "_area.getXMin() " << _area.getXMin() << endl; - cdebug_log(110,0) << "_area.getYMin() " << _area.getYMin() << 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; + cdebug_log(110,0) << "_side: " << DbU::getValueString(_side) << endl; + cdebug_log(110,0) << "_area: " << _area << endl; + cdebug_log(110,0) << "updateArea: " << updateArea << endl; if (updateArea.isEmpty()) { cerr << Error( "Matrix::updateLookup(): %s is not under area of %s." diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index 011db3ba..8b1159b9 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -17,6 +17,7 @@ #ifndef ANABATIC_ANABATIC_ENGINE_H #define ANABATIC_ANABATIC_ENGINE_H +#include #include #include #include @@ -54,6 +55,56 @@ namespace Anabatic { typedef std::set NetSet; typedef std::map 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& getElements () const; + private: + RawGCellsUnder ( const RawGCellsUnder& ); + RawGCellsUnder& operator= ( const RawGCellsUnder& ); + private: + vector _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::getElements () const { return _elements; } + inline Edge* RawGCellsUnder::edgeAt ( size_t i ) const { return (i GCellsUnder; + + +// ------------------------------------------------------------------- +// Class : "Anabatic::AnabaticEngine". class AnabaticEngine : public ToolEngine { public: @@ -83,6 +134,7 @@ namespace Anabatic { inline GCell* getSouthWestGCell () const; inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const; inline GCell* getGCellUnder ( Point ) const; + inline GCellsUnder getGCellsUnder ( Segment* ) const; int getCapacity ( Interval, Flags ) const; size_t getNetsFromEdge ( const Edge*, NetSet& ); inline void setState ( EngineState state ); @@ -92,6 +144,9 @@ namespace Anabatic { // Dijkstra related functions. inline int getStamp () const; inline int incStamp (); + Contact* breakAt ( Segment*, GCell* ); + void ripup ( Segment*, Flags ); + bool unify ( Contact* ); // Global routing related functions. void globalRoute (); void cleanupGlobal (); @@ -199,6 +254,7 @@ namespace Anabatic { 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); } + inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr( new RawGCellsUnder(this,s) ); } inline unsigned int AnabaticEngine::getDensityMode () const { return _densityMode; } inline void AnabaticEngine::setDensityMode ( unsigned int mode ) { _densityMode=mode; } inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; } diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index ac1cdf26..9d98ce18 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -50,6 +50,7 @@ namespace Anabatic { static const unsigned int SouthSide = Vertical |Target; static const unsigned int NorthSide = Vertical |Source; 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 DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; static const unsigned int GCellTypeMask = DeviceGCell|ChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index abc8255c..845b8dc6 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -64,6 +64,7 @@ namespace Anabatic { //inline Vertex ( size_t id ); inline ~Vertex (); inline bool hasDoneAllRps () const; + inline Contact* hasGContact ( Net* ); inline unsigned int getId () const; inline GCell* getGCell () const; inline AnabaticEngine* getAnabatic () const; @@ -74,15 +75,22 @@ namespace Anabatic { inline int getStamp () const; inline int getBranchId () const; inline int getConnexId () const; + inline int getDegree () const; + inline int getRpCount () const; inline Edge* getFrom () const; inline Vertex* getPredecessor () const; inline void setDistance ( DbU::Unit ); inline void setStamp ( int ); inline void setConnexId ( 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 add ( RoutingPad* ); inline void clearRps (); + inline Contact* breakGoThrough ( Net* ); inline bool isNorth ( Vertex* ) const; inline bool isSouth ( Vertex* ) const; @@ -113,6 +121,8 @@ namespace Anabatic { Observer _observer; int _connexId; int _branchId; + int _degree : 8; + int _rpCount : 8; int _stamp; DbU::Unit _distance; Edge* _from; @@ -126,6 +136,8 @@ namespace Anabatic { , _observer(this) , _connexId(-1) , _branchId( 0) + , _degree ( 0) + , _rpCount ( 0) , _stamp (-1) , _distance(unreached) , _from (NULL) @@ -135,22 +147,30 @@ namespace Anabatic { } - inline Vertex::~Vertex () { } - inline unsigned int Vertex::getId () const { return _id; } - inline GCell* Vertex::getGCell () const { return _gcell; } - inline AnabaticEngine* Vertex::getAnabatic () const { return _gcell->getAnabatic(); } - inline Contact* Vertex::getGContact ( Net* net ) { return _gcell->getGContact(net); } - inline Point Vertex::getCenter () const { return _gcell->getBoundingBox().getCenter(); } - inline DbU::Unit Vertex::getDistance () const { return hasValidStamp() ? _distance : unreached; } - inline int Vertex::getStamp () const { return _stamp; } - inline int Vertex::getConnexId () const { return hasValidStamp() ? _connexId : -1; } - inline int Vertex::getBranchId () const { return hasValidStamp() ? _branchId : 0; } - inline Edge* Vertex::getFrom () const { return _from; } - inline void Vertex::setDistance ( DbU::Unit distance ) { _distance=distance; } - 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 Vertex::~Vertex () { } + inline Contact* Vertex::hasGContact ( Net* net ) { return _gcell->hasGContact(net); } + inline unsigned int Vertex::getId () const { return _id; } + inline GCell* Vertex::getGCell () const { return _gcell; } + inline AnabaticEngine* Vertex::getAnabatic () const { return _gcell->getAnabatic(); } + inline Contact* Vertex::getGContact ( Net* net ) { return _gcell->getGContact(net); } + inline Point Vertex::getCenter () const { return _gcell->getBoundingBox().getCenter(); } + inline DbU::Unit Vertex::getDistance () const { return hasValidStamp() ? _distance : unreached; } + inline int Vertex::getStamp () const { return _stamp; } + inline int Vertex::getConnexId () const { return hasValidStamp() ? _connexId : -1; } + inline int Vertex::getBranchId () const { return hasValidStamp() ? _branchId : 0; } + inline int Vertex::getDegree () const { return hasValidStamp() ? _degree : 0; } + inline int Vertex::getRpCount () const { return hasValidStamp() ? _rpCount : 0; } + inline Edge* Vertex::getFrom () const { return _from; } + inline void Vertex::setDistance ( DbU::Unit distance ) { _distance=distance; } + 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 { return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver(GCell::Observable::Vertex) : NULL; } @@ -276,7 +296,6 @@ namespace Anabatic { 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& ); @@ -284,9 +303,10 @@ namespace Anabatic { void _cleanup (); bool _propagate ( Flags enabledSides ); void _traceback ( Vertex* ); + void _materialize (); void _selectFirstSource (); - Vertex* _propagateRipup ( Vertex* ); - void _tagConnecteds ( Vertex*, int connexId ); + void _toSources ( Vertex*, int connexId ); + void _getConnecteds ( Vertex*, VertexSet& ); void _checkEdges () const; static bool isRestricted ( const Vertex* v1, const Vertex* v2 ); private: diff --git a/anabatic/src/anabatic/Edge.h b/anabatic/src/anabatic/Edge.h index fea678d2..07fb5032 100644 --- a/anabatic/src/anabatic/Edge.h +++ b/anabatic/src/anabatic/Edge.h @@ -39,6 +39,7 @@ namespace Anabatic { using Hurricane::Interval; using Hurricane::Box; using Hurricane::Segment; + using Hurricane::Net; using Hurricane::Cell; using Hurricane::ExtensionGo; @@ -52,82 +53,85 @@ namespace Anabatic { public: static DbU::Unit unity; public: - static Edge* create ( GCell* source, GCell* target, Flags flags=Flags::NoFlags ); - virtual void destroy (); - public: - inline bool isVertical () const; - inline bool isHorizontal () const; - inline unsigned int getCapacity () const; - inline unsigned int getRealOccupancy () const; - inline unsigned int getEstimateOccupancy () const; - DbU::Unit getDistance () const; - inline GCell* getSource () const; - inline GCell* getTarget () const; - GCell* getOpposite ( const GCell* ) const; - AnabaticEngine* getAnabatic () const; - inline DbU::Unit getAxis () const; - DbU::Unit getAxisMin () const; - Interval getSide () const; - 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 revalidate () const; - void _setSource ( GCell* ); - void _setTarget ( GCell* ); - private: - void _invalidate (); - void _revalidate (); - public: - // 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: - Edge ( GCell* source, GCell* target, Flags flags ); - virtual ~Edge (); - virtual void _postCreate (); - virtual void _preDestroy (); - private: - Edge ( const Edge& ); - Edge& operator= ( const Edge& ); + static Edge* create ( GCell* source, GCell* target, Flags flags=Flags::NoFlags ); + virtual void destroy (); + public: + inline bool isVertical () const; + inline bool isHorizontal () const; + inline bool hasNet ( const Net* ) const; + inline unsigned int getCapacity () const; + inline unsigned int getRealOccupancy () const; + inline unsigned int getEstimateOccupancy () const; + DbU::Unit getDistance () const; + inline GCell* getSource () const; + inline GCell* getTarget () const; + GCell* getOpposite ( const GCell* ) const; + AnabaticEngine* getAnabatic () const; + inline DbU::Unit getAxis () const; + DbU::Unit getAxisMin () const; + Interval getSide () const; + Segment* getSegment ( const Net* ) const; + inline const vector& getSegments () const; + inline void incCapacity ( int ); + void incRealOccupancy ( int ); + void add ( Segment* ); + void remove ( Segment* ); + void replace ( Segment* orig, Segment* repl ); + inline const Flags& flags () const; + inline Flags& flags (); + inline void revalidate () const; + void _setSource ( GCell* ); + void _setTarget ( GCell* ); + private: + void _invalidate (); + void _revalidate (); + public: + // 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: + 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; - unsigned int _capacity; - unsigned int _realOccupancy; - float _estimateOccupancy; - GCell* _source; - GCell* _target; - DbU::Unit _axis; - Segment* _segment; + static Name _extensionName; + Flags _flags; + unsigned int _capacity; + unsigned int _realOccupancy; + float _estimateOccupancy; + GCell* _source; + GCell* _target; + DbU::Unit _axis; + vector _segments; }; - inline const Name& Edge::staticGetName () { return _extensionName; } - inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); } - inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); } - inline unsigned int Edge::getCapacity () const { return _capacity; } - inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; } - inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; } - inline GCell* Edge::getSource () const { return _source; } - inline GCell* Edge::getTarget () const { return _target; } - inline DbU::Unit Edge::getAxis () const { return _axis; } - 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::revalidate () const { /*if (_flags&Flags::Invalidated)*/ const_cast(this)->_revalidate(); } + inline const Name& Edge::staticGetName () { return _extensionName; } + inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); } + inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); } + inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); } + inline unsigned int Edge::getCapacity () const { return _capacity; } + inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; } + inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; } + inline GCell* Edge::getSource () const { return _source; } + inline GCell* Edge::getTarget () const { return _target; } + inline DbU::Unit Edge::getAxis () const { return _axis; } + inline const vector& Edge::getSegments () const { return _segments; } + inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; } + inline const Flags& Edge::flags () const { return _flags; } + inline Flags& Edge::flags () { return _flags; } + inline void Edge::revalidate () const { /*if (_flags&Flags::Invalidated)*/ const_cast(this)->_revalidate(); } } // Anabatic namespace. diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index 247b6b04..48c5d0d6 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -139,7 +139,8 @@ namespace Anabatic { bool isEast ( GCell* ) const; bool isNorth ( 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 Flags getType () const; inline DbU::Unit getXMin () const; @@ -153,6 +154,7 @@ namespace Anabatic { inline const vector& getNorthEdges () const; inline const vector& getSouthEdges () 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 GCell* getWest () const; inline GCell* getEast () const; @@ -169,6 +171,7 @@ namespace Anabatic { bool doGrid (); Contact* getGContact ( Net* ); inline const vector& getGContacts () const; + Contact* breakGoThrough ( Net* net ); bool unrefContact ( Contact* ); void setXY ( DbU::Unit x, DbU::Unit y ); void updateContactsPosition ();