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 ();