diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 409bf669..c8715c17 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -31,6 +31,7 @@ #include "anabatic/GCell.h" #include "anabatic/NetBuilderM2.h" #include "anabatic/NetBuilderHV.h" +#include "anabatic/NetBuilderVH.h" #include "anabatic/AnabaticEngine.h" @@ -725,7 +726,7 @@ namespace Anabatic { void AnabaticEngine::_loadGrByNet () { - cmess1 << " o Building detailed routing from global." << endl; + cmess1 << " o Building detailed routing from global. " << endl; startMeasures(); openSession(); @@ -735,16 +736,16 @@ namespace Anabatic { if (getConfiguration()->isHV ()) gaugeKind = 1; if (getConfiguration()->isVH ()) gaugeKind = 2; - if (gaugeKind < 2) { + if (gaugeKind < 3) { for ( Net* net : getCell()->getNets() ) { if (NetRoutingExtension::isAutomaticGlobalRoute(net)) { - DebugSession::open( net, 144, 160 ); + DebugSession::open( net, 145, 150 ); AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) ); switch ( gaugeKind ) { case 0: NetBuilder::load( this, net ); break; case 1: NetBuilder::load( this, net ); break; - //case 2: NetBuilder::load( this, net ); break; + case 2: NetBuilder::load( this, net ); break; } Session::revalidate(); @@ -761,7 +762,7 @@ namespace Anabatic { Session::close(); stopMeasures(); - if (gaugeKind > 1) { + if (gaugeKind > 2) { throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing gauge \"%s\"." , getString(getConfiguration()->getRoutingGauge()->getName()).c_str() ); } diff --git a/anabatic/src/AutoContact.cpp b/anabatic/src/AutoContact.cpp index ebe47f6f..5443a25d 100644 --- a/anabatic/src/AutoContact.cpp +++ b/anabatic/src/AutoContact.cpp @@ -459,7 +459,8 @@ namespace Anabatic { setCBXMax ( box.getXMax() ); setCBYMin ( box.getYMin() ); setCBYMax ( box.getYMax() ); - cdebug_log(149,0) << "setConstraintBox() - " << this << " " << getConstraintBox() << endl; + cdebug_log(149,0) << "setConstraintBox() - " << this << " " << getConstraintBox() + << " from:" << box << endl; cdebug_log(149,0) << "* " << _gcell << endl; } diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index 3a234fac..d9356a62 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -46,6 +46,7 @@ namespace Anabatic { using Hurricane::DebugSession; using Hurricane::Transformation; using Hurricane::Entity; + using Hurricane::Occurrence; // ------------------------------------------------------------------- @@ -60,7 +61,7 @@ namespace Anabatic { , DbU::Unit height ) { - cdebug_log(145,1) << "AutoContactTerminal::create(... Point, ...)" << endl; + cdebug_log(145,1) << "AutoContactTerminal::create(... Point, ...) " << endl; cdebug_log(145,0) << "@" << point << endl; anchor->getBodyHook()->detach(); @@ -85,7 +86,7 @@ namespace Anabatic { , const DbU::Unit height ) { - cdebug_log(145,0) << "AutoContactTerminal::create(... x, y, ...)" << endl; + cdebug_log(145,0) << "AutoContactTerminal::create(... x, y, ...) " << endl; cdebug_log(145,0) << "@ x:" << DbU::getValueString(x) << " y:" << DbU::getValueString(y) << endl; _preCreate( gcell, anchor->getNet(), layer ); @@ -195,6 +196,26 @@ namespace Anabatic { xMin = xMax = vertical->getTargetPosition().getX(); } else if ( (routingPad = dynamic_cast(component)) ) { + Occurrence occurrence = routingPad->getOccurrence(); + Transformation transformation = occurrence.getPath().getTransformation(); + Segment* segment = dynamic_cast( occurrence.getEntity() ); + + cdebug_log(145,0) << "Anchor: " << occurrence.getEntity() << endl; + cdebug_log(145,0) << "transf: " << transformation << endl; + + if (segment) { + Box bb = segment->getBoundingBox(); + transformation.applyOn( bb ); + xMin = bb.getXMin(); + yMin = bb.getYMin(); + xMax = bb.getXMax(); + yMax = bb.getYMax(); + } else { + xMin = xMax = component->getPosition().getX(); + yMin = yMax = component->getPosition().getY(); + } + +#if FOR_SYMBOLIC_LAYERS Entity* entity = routingPad->getOccurrence().getEntity(); Transformation transf = routingPad->getOccurrence().getPath().getTransformation(); cdebug_log(145,0) << "Anchor: " << routingPad << endl; @@ -238,6 +259,7 @@ namespace Anabatic { yMin = yMax = routingPad->getPosition().getY(); break; } +#endif } else { xMin = xMax = component->getPosition().getX(); yMin = yMax = component->getPosition().getY(); @@ -255,7 +277,7 @@ namespace Anabatic { cdebug_log(145,0) << "| Using (y): " << DbU::getValueString(bb.getYMin()) << " " - << DbU::getValueString(bb.getYMax()) << endl; + << DbU::getValueString(bb.getYMax()) << " " << bb << endl; cdebug_tabw(145,-1); return bb; @@ -398,7 +420,7 @@ namespace Anabatic { if (not getUConstraints(Flags::Horizontal).contains(axis)) { cdebug_log(145,0) << "Cached: " << _segment << endl; - message << "Terminal vertical segment X" << DbU::getValueString(axis) + message << "Terminal vertical segment X " << DbU::getValueString(axis) << " axis is outside RoutingPad " << getUConstraints(Flags::Horizontal) << "."; Flags flags = Flags::NoFlags; diff --git a/anabatic/src/AutoContactTurn.cpp b/anabatic/src/AutoContactTurn.cpp index 045758b3..f06241ce 100644 --- a/anabatic/src/AutoContactTurn.cpp +++ b/anabatic/src/AutoContactTurn.cpp @@ -251,15 +251,16 @@ namespace Anabatic { if (_horizontal1->isInvalidatedLayer()) { //_horizontal1 = static_cast( _horizontal1->makeDogleg(this) ); _horizontal1->makeDogleg(this); - depthH1 = rg->getLayerDepth( _horizontal1->getLayer() ); cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl; } else /*if (_vertical1->isInvalidatedLayer())*/ { //_vertical1 = static_cast( _vertical1->makeDogleg(this) ); _vertical1->makeDogleg(this); - depthV1 = rg->getLayerDepth( _vertical1->getLayer() ); cdebug_log(145,0) << "Update v1: " << _vertical1 << endl; } - delta = abssub ( depthH1, depthV1 ); + depthH1 = rg->getLayerDepth( _horizontal1->getLayer() ); + depthV1 = rg->getLayerDepth( _vertical1->getLayer() ); + depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1; + delta = abssub ( depthH1, depthV1 ); } setLayer ( (delta == 0) ? rg->getRoutingLayer(depthContact) : rg->getContactLayer(depthContact) ); diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index 8f5ba626..707b8e62 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -466,6 +466,9 @@ namespace Anabatic { DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap(); if ( _sourcePosition != sourcePosition ) { + cerr << "extensionCap: " << DbU::getValueString(getExtensionCap()) << endl; + cerr << "ppitch: " << DbU::getValueString(getPPitch()) << endl; + cerr << "via width: " << DbU::getValueString(Session::getViaWidth(getLayer())) << endl; cerr << Error ( "%s\n Source position incoherency: " "shadow: %s, real: %s." , _getString().c_str() diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 22df115c..3f9b8485 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -549,7 +549,7 @@ namespace Anabatic { unsetFlags( SegSourceTop|SegSourceBottom ); if (contactLayer->getMask() != segmentLayer->getMask()) - setFlags( (segmentLayer == contactLayer->getTop()) ? SegSourceBottom : SegSourceTop ); + setFlags( (segmentLayer->getMask() == contactLayer->getTop()->getMask()) ? SegSourceBottom : SegSourceTop ); if (source->isTurn() and source->getPerpandicular(this)->isReduced()) incReduceds(); } @@ -562,7 +562,7 @@ namespace Anabatic { unsetFlags( SegTargetTop|SegTargetBottom ); if (contactLayer->getMask() != segmentLayer->getMask()) - setFlags( (segmentLayer == contactLayer->getTop()) ? SegTargetBottom : SegTargetTop ); + setFlags( (segmentLayer->getMask() == contactLayer->getTop()->getMask()) ? SegTargetBottom : SegTargetTop ); if (target->isTurn() and target->getPerpandicular(this)->isReduced()) incReduceds(); } @@ -601,7 +601,7 @@ namespace Anabatic { DbU::Unit AutoSegment::getPPitch () const { unsigned int depth = getDepth(); - DbU::Unit topPPitch = Session::getPitch( depth + ( ((_flags & SegSpinTop) and (depth+1 < Session::getDepth())) ? 1 : 0) ); + DbU::Unit topPPitch = Session::getPitch( depth + ( ((_flags & SegSpinTop ) and (depth+1 < Session::getDepth())) ? 1 : 0) ); DbU::Unit bottomPPitch = Session::getPitch( depth - ( ((_flags & SegSpinBottom) and (depth > 0))? 1 : 0) ); return std::max( topPPitch, bottomPPitch ); @@ -613,6 +613,10 @@ namespace Anabatic { DbU::Unit mWidth = std::max( Session::getWireWidth(getLayer()), Session::getViaWidth(getLayer()) ); if (getWidth() <= mWidth) return Session::getExtensionCap( getLayer() ); return getWidth() / 2; +#if NEW_WAY + if (getWidth() <= mWidth) return mWidth/2 + getPitch()/2; + return getWidth()/2 + getPitch()/2; +#endif } @@ -730,15 +734,23 @@ namespace Anabatic { const Layer* sourceLayer = getAutoSource()->getLayer(); const Layer* targetLayer = getAutoTarget()->getLayer(); - if ( (_flags & SegSourceTop) and (sourceLayer->getBottom() != getLayer()) ) { - cerr << Error("%s\n" - " Source is not going above, connected to *top* of %s." + if ( (_flags & SegSourceTop) + and (sourceLayer->getBottom()->getMask() != getLayer()->getMask()) ) { + cerr << Error( "%s\n" + " Source is not going above, connected to *top* of %s.\n" + " bottom:%s mask:%s\n" + " layer:%s mask:%s\n" , getString(this).c_str() , getString(getAutoSource()).c_str() + , getString(sourceLayer->getBottom()).c_str() + , getString(sourceLayer->getBottom()->getMask()).c_str() + , getString(getLayer()).c_str() + , getString(getLayer()->getMask()).c_str() ) << endl; valid = false; } - if ( (_flags & SegSourceBottom) and (sourceLayer->getTop() != getLayer()) ) { + if ( (_flags & SegSourceBottom) + and (sourceLayer->getTop()->getMask() != getLayer()->getMask()) ) { cerr << Error("%s\n" " Source is not going below, connected to *bottom* of %s." , getString(this).c_str() @@ -746,7 +758,8 @@ namespace Anabatic { ) << endl; valid = false; } - if ( (_flags & SegTargetTop) and (targetLayer->getBottom() != getLayer()) ) { + if ( (_flags & SegTargetTop) + and (targetLayer->getBottom()->getMask() != getLayer()->getMask()) ) { cerr << Error("%s\n" " Target is not going above connected to *top* of %s." , getString(this).c_str() @@ -754,7 +767,8 @@ namespace Anabatic { ) << endl; valid = false; } - if ( (_flags & SegTargetBottom) and (targetLayer->getTop() != getLayer()) ) { + if ( (_flags & SegTargetBottom) + and (targetLayer->getTop()->getMask() != getLayer()->getMask()) ) { cerr << Error("%s\n" " Target is not going below, connected to *bottom* of %s." , getString(this).c_str() @@ -1439,13 +1453,12 @@ namespace Anabatic { const Layer* newLayer = Session::getRoutingGauge()->getRoutingLayer(depth); if (getLayer() != newLayer) { setLayer( newLayer ); - getAutoSource()->invalidate( Flags::Topology|Flags::NoCheckLayer ); getAutoTarget()->invalidate( Flags::Topology|Flags::NoCheckLayer ); } if (not (flags & Flags::WithNeighbors)) { - cdebug_tabw(149,-1); + cdebug_tabw(159,-1); return; } @@ -1771,9 +1784,14 @@ namespace Anabatic { return false; } - source->setLayer( Session::getRoutingLayer(perpandicularDepth) ); - target->setLayer( Session::getRoutingLayer(perpandicularDepth) ); - setLayer( Session::getRoutingLayer(perpandicularDepth) ); + const Layer* layer = Session::getRoutingLayer(perpandicularDepth); + DbU::Unit side = Session::getWireWidth (perpandicularDepth); + + source->setLayer( layer ); + target->setLayer( layer ); + setLayer( layer ); + source->setSizes( side, side ); + target->setSizes( side, side ); return true; } @@ -2097,20 +2115,21 @@ namespace Anabatic { string AutoSegment::_getStringFlags () const { string state; - state += isFixed () ?" F":" -"; - state += isUnsetAxis () ? "u": "-"; - state += isStrap () ? "S": "-"; - state += isCanonical () ? "C": "-"; - state += isGlobal () ? "G": "-"; - state += isWeakGlobal () ? "g": "-"; - state += isLongLocal () ? "L": "-"; - state += isStrongTerminal() ? "T": "-"; - state += isWeakTerminal1 () ? "W": "-"; - state += isWeakTerminal2 () ? "w": "-"; - state += isNotAligned () ? "A": "-"; - state += isSlackened () ? "S": "-"; - state += isReduced () ? "r": "-"; - state += isInvalidated () ? "i": "-"; + state += isFixed () ?" F":" -"; + state += isUnsetAxis () ? "u": "-"; + state += isStrap () ? "S": "-"; + state += isCanonical () ? "C": "-"; + state += isGlobal () ? "G": "-"; + state += isWeakGlobal () ? "g": "-"; + state += isLongLocal () ? "L": "-"; + state += isStrongTerminal () ? "T": "-"; + state += isWeakTerminal1 () ? "W": "-"; + state += isWeakTerminal2 () ? "w": "-"; + state += isNotAligned () ? "A": "-"; + state += isSlackened () ? "S": "-"; + state += isReduced () ? "r": "-"; + state += isInvalidated () ? "i": "-"; + state += isInvalidatedLayer() ? "l": "-"; if (_flags & SegSourceTop) state += 't'; else if (_flags & SegSourceBottom) state += 'b'; diff --git a/anabatic/src/CMakeLists.txt b/anabatic/src/CMakeLists.txt index f9660907..6c675be3 100644 --- a/anabatic/src/CMakeLists.txt +++ b/anabatic/src/CMakeLists.txt @@ -32,6 +32,7 @@ endif ( CHECK_DETERMINISM ) anabatic/NetBuilder.h anabatic/NetBuilderM2.h anabatic/NetBuilderHV.h + anabatic/NetBuilderVH.h anabatic/ChipTools.h ) set( pyIncludes ) @@ -56,6 +57,7 @@ endif ( CHECK_DETERMINISM ) NetBuilder.cpp NetBuilderM2.cpp NetBuilderHV.cpp + NetBuilderVH.cpp ChipTools.cpp LayerAssign.cpp PreRouteds.cpp diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 211f335e..39a48e61 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -22,7 +22,10 @@ #include "hurricane/Error.h" #include "hurricane/Technology.h" #include "hurricane/DataBase.h" +#include "hurricane/BasicLayer.h" #include "hurricane/RegularLayer.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/NetExternalComponents.h" #include "hurricane/Cell.h" #include "crlcore/Utilities.h" #include "crlcore/CellGauge.h" @@ -46,9 +49,16 @@ namespace Anabatic { using Hurricane::tab; using Hurricane::Warning; using Hurricane::Error; + using Hurricane::Transformation; using Hurricane::Technology; using Hurricane::DataBase; + using Hurricane::BasicLayer; using Hurricane::RegularLayer; + using Hurricane::Segment; + using Hurricane::Plug; + using Hurricane::Path; + using Hurricane::Occurrence; + using Hurricane::NetExternalComponents; using CRL::AllianceFramework; using CRL::RoutingGauge; using CRL::RoutingLayerGauge; @@ -125,12 +135,17 @@ namespace Anabatic { if (regularLayer) _extensionCaps.push_back( regularLayer->getExtentionCap() ); else { - _extensionCaps.push_back( 0 ); - cerr << Warning( "Routing layer at depth %d is *not* a RegularLayer, cannot guess extension cap.\n" - " (%s)" - , depth - , getString(layerGauges[depth]->getLayer()).c_str() - ) << endl; + const BasicLayer* basicLayer = dynamic_cast( layerGauges[depth]->getLayer() ); + if (basicLayer) { + _extensionCaps.push_back( layerGauges[depth]->getHalfWireWidth() ); + } else { + _extensionCaps.push_back( 0 ); + cerr << Warning( "Routing layer at depth %d is *not* a RegularLayer, cannot guess extension cap.\n" + " (%s)" + , depth + , getString(layerGauges[depth]->getLayer()).c_str() + ) << endl; + } } } } @@ -364,6 +379,102 @@ namespace Anabatic { { return _edgeHInc; } + DbU::Unit Configuration::isOnRoutingGrid ( RoutingPad* rp ) const + { + Box ab = rp->getCell()->getBoundingBox(); + Box bb = rp->getBoundingBox(); + Point center = rp->getCenter(); + + RoutingLayerGauge* gauge = getLayerGauge( 1 ); + if (gauge->isHorizontal()) return 0; + + DbU::Unit nearestX = gauge->getTrackPosition( ab.getXMin(), ab.getXMax(), center.getX(), Constant::Nearest ); + if ( (nearestX >= bb.getXMin()) and (nearestX <= bb.getXMax()) ) return 0; + + return nearestX; + } + + + bool Configuration::selectRpComponent ( RoutingPad* rp ) const + { + cdebug_log(145,1) << "selectRpComponent(): " << rp << endl; + + Box ab = rp->getCell()->getBoundingBox(); + const Layer* metal1 = getLayerGauge( 0 )->getLayer(); + RoutingLayerGauge* gauge = getLayerGauge( 1 ); + Occurrence occurrence = rp->getPlugOccurrence(); + Plug* plug = dynamic_cast( occurrence.getEntity() ); + Net* masterNet = plug->getMasterNet(); + Path path = Path( occurrence.getPath(), plug->getInstance() ); + Transformation transformation = path.getTransformation(); + + Segment* current = dynamic_cast( rp->getOccurrence().getEntity() ); + if (current and (current->getLayer()->getMask() != metal1->getMask())) { + cdebug_log(145,0) << "> using default non-metal1 segment." << endl; + cdebug_tabw(145,-1); + return true; + } + + DbU::Unit bestSpan = 0; + Component* bestComponent = NULL; + + for ( Component* component : masterNet->getComponents() ) { + cdebug_log(145,0) << "@ " << component << endl; + if (not NetExternalComponents::isExternal(component)) continue; + + Segment* segment = dynamic_cast(component); + if (not segment) continue; + if (segment->getLayer()->getMask() != metal1->getMask()) continue; + + Box bb = transformation.getBox( component->getBoundingBox() ); + DbU::Unit trackPos = 0; + DbU::Unit minPos = DbU::Max; + DbU::Unit maxPos = DbU::Min; + + if (gauge->isVertical()) { + trackPos = gauge->getTrackPosition( ab.getXMin() + , ab.getXMax() + , bb.getCenter().getX() + , Constant::Nearest ); + minPos = bb.getXMin(); + maxPos = bb.getXMax(); + } else { + trackPos = gauge->getTrackPosition( ab.getYMin() + , ab.getYMax() + , bb.getCenter().getY() + , Constant::Nearest ); + minPos = bb.getYMin(); + maxPos = bb.getYMax(); + } + + cdebug_log(145,0) << "| " << occurrence.getPath() << endl; + cdebug_log(145,0) << "| " << transformation << endl; + cdebug_log(145,0) << "| " << bb << " of:" << segment << endl; + cdebug_log(145,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl; + + if ( (trackPos >= minPos) and (trackPos <= maxPos) ) { + if (not bestComponent) bestComponent = component; + else { + if (bestSpan < maxPos-minPos) { + bestComponent = component; + bestSpan = maxPos - minPos; + } + } + } + } + + if (bestComponent) { + rp->setExternalComponent( bestComponent ); + cdebug_log(145,0) << "Using best candidate:" << bestComponent << endl; + cdebug_tabw(145,-1); + return true; + } + + cdebug_tabw(145,-1); + return false; + } + + void Configuration::print ( Cell* cell ) const { if (not cmess1.enabled()) return; diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index df8b3a8b..769f2000 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -17,6 +17,7 @@ #include #include #include "hurricane/Error.h" +#include "hurricane/Warning.h" #include "hurricane/Net.h" #include "hurricane/RoutingPad.h" #include "hurricane/Horizontal.h" @@ -39,6 +40,7 @@ namespace Anabatic { using std::numeric_limits; using Hurricane::ForEachIterator; using Hurricane::Error; + using Hurricane::Warning; using Hurricane::Component; using Hurricane::Segment; using Hurricane::Horizontal; @@ -1293,9 +1295,6 @@ namespace Anabatic { } } -//////////////////////////////////////////////////////////////////// - - string Vertex::_getString () const { @@ -1303,11 +1302,11 @@ namespace Anabatic { string s = ""; return s; } - string s = "getXMin()) - + "-" + DbU::getValueString(_gcell->getYMin()) - + "-" + DbU::getValueString(_gcell->getXMax()) - + "-" + DbU::getValueString(_gcell->getYMax()) + ")" + string s = "getXMin()) + + " " + DbU::getValueString(_gcell->getYMin()) + + " " + DbU::getValueString(_gcell->getXMax()) + + " " + DbU::getValueString(_gcell->getYMax()) + "]" //+ " rps:" + getString(_rpCount) //+ " deg:" + getString(_degree) + " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None") @@ -1466,17 +1465,24 @@ namespace Anabatic { if (rp) { if (_attachSymContactsHook(rp)) continue; // ANALOG - cdebug_log(112,0) << "| frp:" << rp << endl; + cdebug_log(112,0) << "@ frp:" << rp << endl; rps.push_back( rp ); continue; } } for ( auto rp : rps ) { - cdebug_log(112,0) << "| rp: " << rp << ", getCenter(): " << rp->getBoundingBox().getCenter() << endl; + if (not _anabatic->getConfiguration()->selectRpComponent(rp)) + cerr << Warning( "Dijktra::load(): %s has no components on grid.", getString(rp).c_str() ) << endl; + + cdebug_log(112,0) << "@ rp: " << rp << ", getCenter(): " << rp->getBoundingBox().getCenter() << endl; Point center = rp->getBoundingBox().getCenter(); GCell* gcell = _anabatic->getGCellUnder( center ); - + Box bb = rp->getBoundingBox(); + + cdebug_log(112,0) << bb.getXMin() << " " << bb.getXMax() << endl; + cdebug_log(112,0) << "center X:" << center.getX() << " gcell Xmax:" << gcell->getXMax() << endl; + _limitSymSearchArea(rp); // ANALOG if (not gcell) { @@ -1490,29 +1496,22 @@ namespace Anabatic { continue; } - - - - cdebug_log(112,0) << "Merge search area: " << _searchArea << ", gcell: " << gcell << endl; _searchArea.merge( gcell->getBoundingBox() ); // TO CHANGE - //if (_net->getCell()->getName() == "gmchamla") _searchArea.merge( _net->getCell()->getAbutmentBox() ); // TO CHANGE - cdebug_log(112,0) << "Search area: " << _searchArea << endl; + cdebug_log(112,0) << "| Merged search area: " << _searchArea << ", gcell: " << gcell << endl; - Vertex* seed = gcell->getObserver(GCell::Observable::Vertex); - GCell* gseed = seed->getGCell(); + Vertex* seed = gcell->getObserver(GCell::Observable::Vertex); + GCell* gseed = seed->getGCell(); if (gseed->isAnalog()) _setSourcesGRAData( seed, rp ); // ANALOG - cdebug_log(112,0) << "seed isH(): " << seed->isH() << endl; - cdebug_log(112,0) << "seed isV(): " << seed->isV() << endl; + cdebug_log(112,0) << "| seed->isH(): " << seed->isH() + << " seed->isV(): " << seed->isV() << endl; if (seed->getConnexId() < 0) { - cdebug_log(112,0) << "(seed->getConnexId() < 0)"<< endl; VertexSet connecteds; _getConnecteds( seed, connecteds ); ++_connectedsId; for ( Vertex* vertex : connecteds ) { - cdebug_log(112,0) << "| Current: " << vertex << endl; vertex->setDistance ( Vertex::unreached ); vertex->setStamp ( _stamp ); vertex->setConnexId ( _connectedsId ); @@ -1530,9 +1529,7 @@ namespace Anabatic { } } - cdebug_log(112,0) << "seed->incRpCount();" << endl; seed->incRpCount(); - cdebug_log(112,0) << "Contact* vcontact = seed->getGContact( _net );" << endl; Contact* vcontact = seed->getGContact( _net ); rp->getBodyHook()->detach(); rp->getBodyHook()->attach( vcontact->getBodyHook() ); @@ -1766,8 +1763,8 @@ namespace Anabatic { Vertex* current = _queue.top(); GCell* gcurrent = current->getGCell(); - cdebug_log(111,0) << "Current:" << current << endl; - cdebug_log(111,0) << "isAxisTarget():" << current->isAxisTarget() << endl; + cdebug_log(111,1) << "Current:" << current << endl; + //cdebug_log(111,0) << "isAxisTarget():" << current->isAxisTarget() << endl; _queue.pop(); @@ -1776,61 +1773,58 @@ namespace Anabatic { cdebug_log(111,0) << "Looking for neighbors:" << endl; for ( Edge* edge : current->getGCell()->getEdges() ) { - cdebug_log(111,0) << "[Current]: " << current << endl; cdebug_log(111,0) << "@ Edge " << edge << endl; if (edge == current->getFrom()) { - cdebug_log(111,0) << "| Reject: edge == current->getFrom()" << endl; + cdebug_log(111,0) << "> Reject: edge == current->getFrom()" << endl; continue; } if ((gcurrent->isAnalog()) and _checkFrom2(edge, current)) { - cdebug_log(111,0) << "| Reject: _checkFrom2()" << endl; + cdebug_log(111,0) << "> Reject: _checkFrom2()" << endl; continue; } - GCell* gneighbor = edge->getOpposite(current->getGCell()); - Vertex* vneighbor = gneighbor->getObserver( GCell::Observable::Vertex ); - if (gneighbor->isAnalog()) vneighbor->createAData(); + Vertex* vneighbor = current->getNeighbor( edge ); + if (vneighbor->isAnalog()) vneighbor->createAData(); - cdebug_log(111,0) << "+ Neighbor:" << vneighbor << endl; + cdebug_log(111,0) << "| Neighbor:" << vneighbor << endl; if (vneighbor->getConnexId() == _connectedsId) { - cdebug_log(111,0) << "| Reject: Neighbor already reached (has connectedsId)" << endl; + cdebug_log(111,0) << "> Reject: Neighbor already reached (has connectedsId)" << endl; continue; } - if (not _searchArea.intersect(gneighbor->getBoundingBox())) { - cdebug_log(111,0) << "| Reject: not in _searchArea: " << _searchArea << ", gneighbor area: " << gneighbor->getBoundingBox() << endl; + if (not _searchArea.intersect(vneighbor->getBoundingBox())) { + cdebug_log(111,0) << "> Reject: not in _searchArea: " << _searchArea << ", vneighbor area: " << vneighbor->getBoundingBox() << endl; continue; } ////////////////////////////////////// DEBUG ////////////////////////////////////// - if (current->getFrom()) { - cdebug_log(111,0) << "| From: " << current->getFrom()->getOpposite(gcurrent) << endl; - //current->getIntervFrom().print(); - } - if (gcurrent->isAnalog() and current->getFrom2()) { - cdebug_log(111,0) << "| From2: " << current->getFrom2()->getOpposite(gcurrent) << endl; - current->getIntervFrom2().print(); - } - if ( (vneighbor->getFrom() != NULL) and (vneighbor->hasValidStamp()) ) { - cdebug_log(111,0) << "| Neighbor GETFROM:" << vneighbor->getFrom()->getOpposite( gneighbor ) << endl; - cdebug_log(111,0) << "Distance prev : " << DbU::getValueString(vneighbor->getDistance()) << endl; - } + //if (current->getFrom()) { + // cdebug_log(111,0) << "| From: " << current->getFrom()->getOpposite(gcurrent) << endl; + ////current->getIntervFrom().print(); + //} + //if (gcurrent->isAnalog() and current->getFrom2()) { + // cdebug_log(111,0) << "| From2: " << current->getFrom2()->getOpposite(gcurrent) << endl; + // current->getIntervFrom2().print(); + //} + //if ( (vneighbor->getFrom() != NULL) and (vneighbor->hasValidStamp()) ) { + // cdebug_log(111,0) << "| Neighbor GETFROM:" << vneighbor->getFrom()->getOpposite( gneighbor ) << endl; + // cdebug_log(111,0) << "Distance prev : " << DbU::getValueString(vneighbor->getDistance()) << endl; + //} /////////////////////////////////////////////////////////////////////////////////// DbU::Unit distance = _distanceCb( current, vneighbor, edge ); - cdebug_log(111,0) << "distance:" << Vertex::getValueString(distance) << endl; + cdebug_log(111,0) << "| Distance:" << Vertex::getValueString(distance) << endl; bool isDistance2shorter = false; - if (gcurrent->isAnalog() and gneighbor->isAnalog()) + if (gcurrent->isAnalog() and vneighbor->isAnalog()) isDistance2shorter = _isDistance2Shorter ( distance, current, vneighbor, edge ); - /* ------------------------------------------------------------------- */ bool push = false; if (distance != Vertex::unreachable){ if (not vneighbor->hasValidStamp()) { - cdebug_log(111,0) << "Vertex reached for the first time" << endl; + cdebug_log(111,0) << "> Vertex reached for the first time" << endl; vneighbor->setConnexId( -1 ); vneighbor->setStamp ( _stamp ); vneighbor->setDegree ( 1 ); @@ -1840,42 +1834,41 @@ namespace Anabatic { push = true; } else { if ( (distance == vneighbor->getDistance()) - and (gneighbor->isAnalog()) + and (vneighbor->isAnalog()) and (vneighbor->getFrom2() == NULL) ) { _pushEqualDistance( distance, isDistance2shorter, current, vneighbor, edge ); // ANALOG } else if (distance < vneighbor->getDistance()) { if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor ); - cdebug_log(111,0) << "Vertex reached through a shorter path" << endl; + cdebug_log(111,0) << "> Vertex reached through a shorter path (prev: " + << DbU::getValueString(vneighbor->getDistance()) << ")" << endl; push = true; } else { - cdebug_log(111,0) << "Reject: Vertex reached through a *longer* path or unreachable:" + cdebug_log(111,0) << "> Reject: Vertex reached through a *longer* path or unreachable:" << boolalpha << (distance == Vertex::unreachable) << endl; } } } else { - cdebug_log(111,0) << "Reject: Vertex unreachable" << endl; + cdebug_log(111,0) << "> Reject: Vertex unreachable" << endl; } if (push){ - if (gneighbor->isAnalog()) // Gneighbor only not current gcell + if (vneighbor->isAnalog()) // Vneighbor only not current gcell _updateGRAData( vneighbor, isDistance2shorter, current ); vneighbor->setBranchId( current->getBranchId() ); vneighbor->setDistance( distance ); - cdebug_log(111,0) << "setFrom1: " << vneighbor << endl; + cdebug_log(111,0) << "| setFrom1: " << vneighbor << endl; vneighbor->setFrom ( edge ); _queue.push( vneighbor ); - cdebug_log(111,0) << "Push: (size:" << _queue.size() << ") " << vneighbor << ", isFromFrom2: " << vneighbor->isFromFrom2() << endl; + cdebug_log(111,0) << "| Push: (size:" << _queue.size() << ") " << vneighbor << ", isFromFrom2: " << vneighbor->isFromFrom2() << endl; } } + + /* ------------------------------------------------------------------- */ - - - - /*if ( (distance == vneighbor->getDistance()) and gcurrent->isAnalog() and gneighbor->isAnalog() @@ -1938,9 +1931,12 @@ namespace Anabatic { } } }*/ + + cdebug_tabw(111,-1); continue; } + cdebug_tabw(111,-1); // We did reach another target (different ). // Tag back the path, with a higher . _traceback( current ); @@ -1971,79 +1967,39 @@ namespace Anabatic { bool isfirst = true; bool useFrom2 = false; - //<<<<<<< HEAD - //if (!current->getGCell()->isMatrix()){ - /*_initiateUpdateIntervals ( current ); // ANALOG - - cdebug_log(112,0) << "[Start WHILE]" << endl; - Edge* from = NULL; - while ( current ) { - cdebug_log(112,0) << endl; - cdebug_log(112,0) << "| " << current << " | " << endl; - if (current->getFrom()) cdebug_log(112,0) << " | From :" << current->getFrom()->getOpposite(current->getGCell()) << " | " << endl; - if (current->getFrom2()) cdebug_log(112,0) << " | From2:" << current->getFrom2()->getOpposite(current->getGCell()) << " | " << endl; - - //if (!current->getGCell()->isMatrix()){ - //////////////////////////////////////////////////////////////////////////////////////////// ANALOG - if (_updateIntervals ( isfirst, current, useFrom2, branchId, from )) break; - Vertex* next = NULL; - next = current->getPredecessor(); - - if( current->isFromFrom2()) { - cdebug_log(112,0) << "ISFROMFROM2: " << current << endl; - useFrom2 = true; - current->unsetFlags(Vertex::UseFromFrom2);*/ - /*=======*/ - if (current->getGCell()->isAnalog()) { + if (current->isAnalog()) { _initiateUpdateIntervals( current ); } else { current = current->getPredecessor(); isfirst = false; } - //cdebug_log(112,0) << "[Start WHILE]" << endl; - Edge* from = NULL; while ( current ) { cdebug_log(112,0) << "+ " << current << endl; - //if (current->getFrom()) cdebug_log(112,0) << "| From:" << current->getFrom()->getOpposite(current->getGCell()) << endl; - - if (current->getGCell()->isAnalog()) { - //if (current->getFrom2()) cdebug_log(112,0) << "| From2:" << current->getFrom2()->getOpposite(current->getGCell()) << endl; + if (current->isAnalog()) { if (_updateIntervals( isfirst, current, useFrom2, branchId, from )) break; Vertex* next = NULL; next = current->getPredecessor(); if (current == next){ - cdebug_log(112,0) << "[ERROR]: Current's predecessor is current." << endl; + cdebug_log(112,0) << "[ERROR] Current's predecessor is current." << endl; break; } - if (current->isFromFrom2()) { - //cdebug_log(112,0) << "| isFromFrom2:true (" << current << ")" << endl; useFrom2 = true; current->unsetFlags( Vertex::UseFromFrom2 ); } else { - //cdebug_log(112,0) << "| isFromFrom2:false" << endl; useFrom2 = false; } - //cdebug_log(112,0) << "| Next: " << next << endl; current = next; - //>>>>>>> 987289653831df12933bd4490d9559415e61f220 - /*} else { - cdebug_log(112,0) << "ISNOT FROMFROM2" << endl; - useFrom2 = false; - } - cdebug_log(112,0) << "next: " << next << endl; - current = next;*/ - //////////////////////////////////////////////////////////////////////////////////////////// } else { current->incDegree(); if (current->getConnexId() == _connectedsId) break; - from = current->getFrom(); + from = current->getFrom(); if (not from) break; current->setDistance( 0.0 ); @@ -2077,7 +2033,7 @@ namespace Anabatic { Vertex* source = startVertex; while ( source ) { - cdebug_log(112,0) << "* " << source << endl; + cdebug_log(112,0) << "@ " << source << endl; bool isAnalog = source->getGCell()->isAnalog(); if (isAnalog) source->resetIntervals(); @@ -2090,10 +2046,10 @@ namespace Anabatic { Interval constraint = from->getSide(); source->setFrom( NULL ); - cdebug_log(112,0) << "+ " << target << endl; + cdebug_log(112,0) << "| " << target << endl; if (target->getConnexId() < 0) { - cdebug_log(112,0) << "| " << "break (abort: false start)." << endl; + cdebug_log(112,0) << "> " << "break (abort: false start)." << endl; break; } @@ -2134,15 +2090,14 @@ namespace Anabatic { else targetContact = target->breakGoThrough( _net ); } - cdebug_log(112,0) << "| aligneds.front():" << aligneds.front() + cdebug_log(112,0) << "> aligneds.front():" << aligneds.front() << " isHorizontal():" << aligneds.front()->isHorizontal() << endl; if (aligneds.front()->isHorizontal()) { if (sourceContact->getX() > targetContact->getX()) std::swap( sourceContact, targetContact ); - //DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2")); //DbU::fromLambda(2.0); - DbU::Unit width = Session::getGHorizontalPitch(); //DbU::fromLambda(2.0); + DbU::Unit width = Session::getGHorizontalPitch(); if (state) width *= state->getWPitch(); @@ -2152,6 +2107,7 @@ namespace Anabatic { , constraint.getCenter() , width ); + for ( Edge* through : aligneds ) through->add( segment ); if (state) { if (state->isSymmetric()) _createSelfSymSeg ( segment ); @@ -2160,8 +2116,7 @@ namespace Anabatic { if (sourceContact->getY() > targetContact->getY()) std::swap( sourceContact, targetContact ); - //DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL3")); //DbU::fromLambda(2.0); - DbU::Unit width = Session::getGVerticalPitch(); //DbU::fromLambda(2.0); + DbU::Unit width = Session::getGVerticalPitch(); if (state) width *= state->getWPitch(); segment = Vertical::create( sourceContact @@ -2170,6 +2125,7 @@ namespace Anabatic { , constraint.getCenter() , width ); + for ( Edge* through : aligneds ) through->add( segment ); if (state) { if (state->isSymmetric()) _createSelfSymSeg ( segment ); @@ -2177,7 +2133,7 @@ namespace Anabatic { } cdebug_log(112,0) << "| break (U-turn, turn, branch or terminal)." << endl; - cdebug_log(112,0) << "| " << segment << endl; + cdebug_log(112,0) << "+ " << segment << endl; Vertex* prevSource = source; source = (target->getFrom()) ? target : NULL; @@ -2246,32 +2202,30 @@ namespace Anabatic { VertexSet stack; stack.insert( source ); - - cdebug_log(112,0) << "in WHILE" << endl; while ( not stack.empty() ) { - source = *stack.begin(); - stack.erase( source ); + Vertex* current = *stack.begin(); + stack.erase( current ); - cdebug_log(112,0) << "| source:" << source << " stack.size():" << stack.size() << endl; + cdebug_log(112,0) << "@ source:" << current << " stack.size():" << stack.size() << endl; - for ( Edge* edge : source->getGCell()->getEdges() ) { + for ( Edge* edge : current->getEdges() ) { if (not edge->hasNet(_net)) { - cdebug_log(112,0) << " Not connected:" << edge - << " to:" << edge->getOpposite(source->getGCell()) << endl; + cdebug_log(110,0) << "| Not connected:" << edge + << " to:" << (current->getNeighbor(edge)) << endl; continue; } - GCell* gneighbor = edge->getOpposite(source->getGCell()); - cdebug_log(112,0) << "GCell: " << gneighbor<< endl; - Vertex* vneighbor = gneighbor->getObserver(GCell::Observable::Vertex); + Vertex* vneighbor = current->getNeighbor( edge ); + cdebug_log(110,0) << "| connected to: " << vneighbor<< endl; if (not vneighbor->hasValidStamp()) continue; if (vneighbor->getConnexId() == connexId) continue; vneighbor->setConnexId( connexId ); vneighbor->setDistance( 0.0 ); - //vneighbor->setFrom ( edge ); + if (vneighbor != source) vneighbor->setFrom( NULL ); + _targets.erase ( vneighbor ); _sources.insert( vneighbor ); _queue.push( vneighbor ); @@ -2279,7 +2233,6 @@ namespace Anabatic { } } - cdebug_log(112,0) << "Dijkstra::_toSources() END" << endl; cdebug_tabw(112,-1); } @@ -2302,13 +2255,11 @@ namespace Anabatic { for ( Edge* edge : source->getGCell()->getEdges() ) { if (not edge->hasNet(_net)) { - cdebug_log(112,0) << " Not connected:" << edge << endl; + cdebug_log(110,0) << " Not connected:" << edge << endl; continue; } - GCell* gneighbor = edge->getOpposite(source->getGCell()); - Vertex* vneighbor = gneighbor->getObserver(GCell::Observable::Vertex); - + Vertex* vneighbor = source->getNeighbor( edge ); if (connecteds.find(vneighbor) != connecteds.end()) continue; stack.insert( vneighbor ); diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index e75798f6..b10fb552 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -243,14 +243,14 @@ namespace Anabatic { DbU::Unit globalThreshold = Session::getSliceHeight()*3; size_t netCount = 0; - for ( size_t i=0 ; i<_segments.size(); ) { + for ( size_t i=0 ; i<_segments.size() ; ) { if (_segments[i]->getLength() >= globalThreshold) { NetData* netData = anabatic->getNetData( _segments[i]->getNet() ); if (netData->isGlobalRouted()) ++netCount; - anabatic->ripup( _segments[i], Flags::Propagate ); - } else + } else { ++i; + } } return netCount; } diff --git a/anabatic/src/NetBuilder.cpp b/anabatic/src/NetBuilder.cpp index f130fbcd..16ffa2da 100644 --- a/anabatic/src/NetBuilder.cpp +++ b/anabatic/src/NetBuilder.cpp @@ -77,6 +77,139 @@ namespace { " No Contact in GCell.\n"; + +// ------------------------------------------------------------------- +// Class : "NetBuilder::SortRpByX". + + class SortRpByX { + public: + inline SortRpByX ( uint64_t flags ); + inline bool operator() ( RoutingPad* rp1, RoutingPad* rp2 ); + private: + uint64_t _flags; + }; + + + inline SortRpByX::SortRpByX ( uint64_t flags ) + : _flags(flags) + { } + + + inline bool SortRpByX::operator() ( RoutingPad* rp1, RoutingPad* rp2 ) + { + DbU::Unit x1 = rp1->getCenter().getX(); + DbU::Unit x2 = rp2->getCenter().getX(); + + if (x1 == x2) return false; + return (_flags & NetBuilder::SortDecreasing) xor (x1 < x2); + } + + +// ------------------------------------------------------------------- +// Class : "NetBuilder::SortRpByY". + + class SortRpByY { + public: + inline SortRpByY ( uint64_t flags ); + inline bool operator() ( RoutingPad* rp1, RoutingPad* rp2 ); + protected: + uint64_t _flags; + }; + + + inline SortRpByY::SortRpByY ( uint64_t flags ) + : _flags(flags) + { } + + + inline bool SortRpByY::operator() ( RoutingPad* rp1, RoutingPad* rp2 ) + { + DbU::Unit y1 = rp1->getCenter().getY(); + DbU::Unit y2 = rp2->getCenter().getY(); + + if (y1 == y2) return false; + return (_flags & NetBuilder::SortDecreasing) xor (y1 < y2); + } + + +// ------------------------------------------------------------------- +// Class : "NetBuilder::SortHookByX". + + class SortHookByX { + public: + inline SortHookByX ( uint64_t flags ); + inline bool operator() ( Hook* h1, Hook* h2 ); + protected: + uint64_t _flags; + }; + + + inline SortHookByX::SortHookByX ( uint64_t flags ) + : _flags(flags) + { } + + + inline bool SortHookByX::operator() ( Hook* h1, Hook* h2 ) + { + DbU::Unit x1 = 0; + DbU::Unit x2 = 0; + Horizontal* hh1 = dynamic_cast(h1->getComponent()); + Horizontal* hh2 = dynamic_cast(h2->getComponent()); + Vertical* vv1 = dynamic_cast (h1->getComponent()); + Vertical* vv2 = dynamic_cast (h2->getComponent()); + + if (hh1) x1 = std::min( hh1->getSource()->getX(), hh1->getTarget()->getX() ); + else if (vv1) x1 = vv1->getX(); + else x1 = h1->getComponent()->getCenter().getX(); + + if (hh2) x2 = std::min( hh2->getSource()->getX(), hh2->getTarget()->getX() ); + else if (vv2) x2 = vv2->getX(); + else x2 = h2->getComponent()->getCenter().getX(); + + if (x1 == x2) return false; + return (_flags & NetBuilder::SortDecreasing) xor (x1 < x2); + } + + +// ------------------------------------------------------------------- +// Class : "NetBuilder::SortHookByY". + + class SortHookByY { + public: + inline SortHookByY ( uint64_t flags ); + inline bool operator() ( Hook* h1, Hook* h2 ); + protected: + uint64_t _flags; + }; + + + inline SortHookByY::SortHookByY ( uint64_t flags ) + : _flags(flags) + { } + + + inline bool SortHookByY::operator() ( Hook* h1, Hook* h2 ) + { + DbU::Unit y1 = 0; + DbU::Unit y2 = 0; + Horizontal* hh1 = dynamic_cast(h1->getComponent()); + Horizontal* hh2 = dynamic_cast(h2->getComponent()); + Vertical* vv1 = dynamic_cast (h1->getComponent()); + Vertical* vv2 = dynamic_cast (h2->getComponent()); + + if (vv1) y1 = std::min( vv1->getSource()->getY(), vv1->getTarget()->getY() ); + else if (hh1) y1 = hh1->getY(); + else y1 = h1->getComponent()->getCenter().getX(); + + if (vv2) y2 = std::min( vv2->getSource()->getY(), vv2->getTarget()->getY() ); + else if (hh2) y2 = hh2->getY(); + else y2 = h2->getComponent()->getCenter().getY(); + + if (y1 == y2) return false; + return (_flags & NetBuilder::SortDecreasing) xor (y1 < y2); + } + + } // Anonymous namespace. @@ -175,8 +308,25 @@ namespace Anabatic { } + void NetBuilder::sortRpByX ( vector& rps, uint64_t flags ) + { sort( rps.begin(), rps.end(), SortRpByX(flags) ); } + + + void NetBuilder::sortRpByY ( vector& rps, uint64_t flags ) + { sort( rps.begin(), rps.end(), SortRpByY(flags) ); } + + + void NetBuilder::sortHookByX ( vector& hooks, uint64_t flags ) + { sort( hooks.begin(), hooks.end(), SortHookByX(flags) ); } + + + void NetBuilder::sortHookByY ( vector& hooks, uint64_t flags ) + { sort( hooks.begin(), hooks.end(), SortHookByY(flags) ); } + + NetBuilder::NetBuilder () - : _forks () + : _anabatic (NULL) + , _forks () , _connexity () , _topology (0) , _gcell (NULL) @@ -348,7 +498,7 @@ namespace Anabatic { return *this; } - + bool NetBuilder::push ( Hook* toHook, AutoContact* contact, uint64_t flags ) { @@ -767,98 +917,98 @@ namespace Anabatic { bool NetBuilder::_do_xG () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_xG() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_2G () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_2G() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_xG_1Pad () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_xG_1Pad() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_1G_1PinM2 () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_1G_1PinM2() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_1G_1M1 () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_1G_1M1() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_2G_1M1 () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_2G_1M1() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_1G_xM1 () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_1G_xM1() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_xG_xM1_xM3 () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_xG_xM1_xM3() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_xG_1M1_1M2 () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_xG_1M1_1M2() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_4G_1M2 () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_4G_1M2() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_xG_xM2 () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_xG_xM2() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_1G_1M3 () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_1G_1M3() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_xG_xM3 () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_xG_xM3() method *not* reimplemented from base class." << endl; return false; } bool NetBuilder::_do_globalSegment () { - cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl; + cdebug_log(145,0) << getTypeName() << "::_do_globalSegment() method *not* reimplemented from base class." << endl; return false; } @@ -867,8 +1017,8 @@ namespace Anabatic { { cdebug_log(145,1) << "NetBuilder::singleGCell() " << net << endl; - vector rpM1s; - Component* rpM2 = NULL; + vector rpM1s; + Component* rpM2 = NULL; forEach ( RoutingPad*, irp, net->getRoutingPads() ) { if (Session::getRoutingGauge()->getLayerDepth(irp->getLayer()) == 1) @@ -891,18 +1041,18 @@ namespace Anabatic { return; } - sort( rpM1s.begin(), rpM1s.end(), SortRpByX(NetBuilder::NoFlags) ); // increasing X. + sortRpByX( rpM1s, NetBuilder::NoFlags ); // increasing X. GCell* gcell1 = anbt->getGCellUnder( (*rpM1s.begin ())->getCenter() ); GCell* gcell2 = anbt->getGCellUnder( (*rpM1s.rbegin())->getCenter() ); if (not gcell1) { - cerr << Error( "No GCell under %s.", getString(rpM1s[0]).c_str() ) << endl; + cerr << Error( "No GCell under %s.", getString(*(rpM1s.begin())).c_str() ) << endl; cdebug_tabw(145,-1); return; } if (gcell1 != gcell2) { - cerr << Error( "Not under a single GCell %s.", getString(rpM1s[0]).c_str() ) << endl; + cerr << Error( "Not under a single GCell %s.", getString(*(rpM1s.rbegin())).c_str() ) << endl; cdebug_tabw(145,-1); return; } @@ -1081,7 +1231,7 @@ namespace Anabatic { } cdebug_log(145,0) << "Sorted hooks:" << endl; - sort( hooks.begin(), hooks.end(), SortHookByX(NoFlags) ); + sortHookByX( hooks, NoFlags ); if (firsthhook) hooks.insert (hooks.begin(), firsthhook); if (lasthhook ) hooks.push_back(lasthhook ); @@ -1288,7 +1438,7 @@ namespace Anabatic { } cdebug_log(145,0) << "Sorted hooks:" << endl; - sort( hooks.begin(), hooks.end(), SortHookByY(NoFlags) ); + sortHookByY( hooks, NoFlags ); if (firstvhook) hooks.insert (hooks.begin(), firstvhook); if (lastvhook ) hooks.push_back(lastvhook ); @@ -2008,6 +2158,8 @@ namespace Anabatic { cdebug_log(149,0) << "NetBuilder::load( " << net << " )" << endl; cdebug_tabw(145,1); + _anabatic = anabatic; + Hook* sourceHook = NULL; AutoContact* sourceContact = NULL; RoutingPads routingPads = net->getRoutingPads(); diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index 8fa50e5a..d67ba9d3 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -74,6 +74,13 @@ namespace Anabatic { cdebug_log(145,1) << getTypeName() << "::doRp_AutoContacts()" << endl; cdebug_log(145,0) << rp << endl; + RoutingPad* rrp = dynamic_cast( rp ); + if (not rrp) { + cerr << Warning( "%s::doRp_AutoContacts(): %s is *not* a RoutingPad." + , getTypeName().c_str() + , getString(rp).c_str() ) << endl; + } + source = target = NULL; Point sourcePosition; @@ -208,7 +215,7 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::_do_1G_" << (int)getConnexity().fields.M1 << "M1() [Managed Configuration]" << endl; - sort( getRoutingPads().begin(), getRoutingPads().end(), SortRpByX(NoFlags) ); // increasing X. + sortRpByX( getRoutingPads(), NoFlags ); // increasing X. for ( size_t i=1 ; igetLayer() == Session::getRoutingLayer(2)) rpM3 = getRoutingPads()[0]; - sort( getRoutingPads().begin(), getRoutingPads().end(), SortRpByX(NoFlags) ); // increasing X. + sortRpByX( getRoutingPads(), NoFlags ); // increasing X. for ( size_t i=1 ; igetLength() < 2*Session::getSliceHeight()) ) addToFixSegments( globalSegment ); - if (getConnexity().fields.globals < 2) return false; + if (getConnexity().fields.globals < 2) { + cdebug_tabw(145,-1); + return false; + } } else setFromHook( NULL ); @@ -810,6 +820,7 @@ namespace Anabatic { push( north(), getNorthEastContact() ); push( south(), getSouthWestContact() ); + cdebug_tabw(145,-1); return true; } diff --git a/anabatic/src/NetBuilderM2.cpp b/anabatic/src/NetBuilderM2.cpp index 918ae4df..c5665753 100644 --- a/anabatic/src/NetBuilderM2.cpp +++ b/anabatic/src/NetBuilderM2.cpp @@ -237,7 +237,7 @@ namespace Anabatic { vector hooksNS = getNorths(); hooksNS.insert( hooksNS.end(), getSouths().begin(), getSouths().end() ); - sort( hooksNS.begin(), hooksNS.end(), SortHookByX(NoFlags) ); + sortHookByX( hooksNS, NoFlags ); const Layer* viaLayer = Session::getDContactLayer(); AutoContact* contactW = NULL; @@ -321,10 +321,14 @@ namespace Anabatic { if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) ) addToFixSegments( globalSegment ); - if (getConnexity().fields.globals < 2) return false; + if (getConnexity().fields.globals < 2) { + cdebug_tabw(145,-1); + return false; + } } else setFromHook( NULL ); + cdebug_tabw(145,-1); return true; } diff --git a/anabatic/src/NetBuilderVH.cpp b/anabatic/src/NetBuilderVH.cpp new file mode 100644 index 00000000..08e056d9 --- /dev/null +++ b/anabatic/src/NetBuilderVH.cpp @@ -0,0 +1,475 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2018-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./NetBuilderVH.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/Bug.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DebugSession.h" +#include "hurricane/Layer.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" +#include "hurricane/Net.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/NetRoutingProperty.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/RoutingPads.h" +#include "hurricane/Pad.h" +#include "hurricane/Plug.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "crlcore/AllianceFramework.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/Measures.h" +#include "anabatic/AutoContactTerminal.h" +#include "anabatic/AutoContactTurn.h" +#include "anabatic/AutoContactHTee.h" +#include "anabatic/AutoContactVTee.h" +#include "anabatic/AutoSegment.h" +#include "anabatic/NetBuilderVH.h" +#include "anabatic/AnabaticEngine.h" + + +namespace Anabatic { + + using std::swap; + using Hurricane::Transformation; + using Hurricane::Warning; + using Hurricane::Error; + + + NetBuilderVH::NetBuilderVH () + : NetBuilder() + { } + + + NetBuilderVH::~NetBuilderVH () { } + + + void NetBuilderVH::doRp_AutoContacts ( GCell* gcell + , Component* rp + , AutoContact*& source + , AutoContact*& target + , uint64_t flags + ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_AutoContacts()" << endl; + cdebug_log(145,0) << rp << endl; + + source = target = NULL; + + Point sourcePosition; + Point targetPosition; + const Layer* rpLayer = rp->getLayer(); + size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); + Flags direction = Session::getDirection ( rpDepth ); + DbU::Unit viaSide = Session::getViaWidth ( rpDepth ); + DbU::Unit gridPosition = 0; + + getPositions( rp, sourcePosition, targetPosition ); + + if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition ); + if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition ); + + GCell* sourceGCell = Session::getAnabatic()->getGCellUnder( sourcePosition ); + GCell* targetGCell = Session::getAnabatic()->getGCellUnder( targetPosition ); + + if (rpDepth == 0) { + rpLayer = Session::getContactLayer(0); + direction = Flags::Vertical; + viaSide = Session::getViaWidth( rpDepth ); + + RoutingPad* rrp = dynamic_cast( rp ); + if (rrp) { + // if (not getAnabatic()->getConfiguration()->selectRpComponent(rrp)) { + // cerr << Warning( "%s::doRp_AutoContacts(): %s has no components on grid." + // , getTypeName().c_str() + // , getString(rp).c_str() ) << endl; + // } + } else { + cerr << Warning( "%s::doRp_AutoContacts(): %s is *not* a RoutingPad." + , getTypeName().c_str() + , getString(rp).c_str() ) << endl; + } + } + + // Non-M1 terminal or punctual M1 protections. + if ( (rpDepth != 0) or ((sourcePosition == targetPosition) and (gridPosition == 0)) ) { + map::iterator irp = getRpLookup().find( rp ); + if (irp == getRpLookup().end()) { + AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell + , rp + , rpLayer + , sourcePosition + , viaSide, viaSide + ); + AutoContact* targetProtect = AutoContactTerminal::create( targetGCell + , rp + , rpLayer + , targetPosition + , viaSide, viaSide + ); + sourceProtect->setFlags( CntFixed ); + targetProtect->setFlags( CntFixed ); + + AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction ); + segment->setFlags( AutoSegment::SegFixed ); + + getRpLookup().insert( make_pair(rp,segment) ); + } + } + + if (sourcePosition != targetPosition) { + if (flags & DoSourceContact) + source = AutoContactTerminal::create( sourceGCell + , rp + , rpLayer + , sourcePosition + , viaSide, viaSide + ); + if (flags & DoTargetContact) + target = AutoContactTerminal::create( targetGCell + , rp + , rpLayer + , targetPosition + , viaSide, viaSide + ); + } + + if (not source and not target) { + source = target = AutoContactTerminal::create( gcell + , rp + , rpLayer + , rp->getCenter() + , viaSide, viaSide + ); + } + + cdebug_tabw(145,-1); + return; + } + + + AutoContact* NetBuilderVH::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; + + AutoContact* rpContactSource; + AutoContact* rpContactTarget; + + flags |= checkRoutingPadSize( rp ); + + doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags ); + + if (not (flags & (HAccess|HAccessEW))) { + AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); + AutoSegment::create( subContact1, subContact2, Flags::Horizontal ); + rpContactSource = subContact2; + } else { + if (flags & VSmall) { + AutoContact* subContact1 = NULL; + if (flags & HAccessEW) + subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + else + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + + AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); + rpContactSource = subContact1; + } + } + + cdebug_tabw(145,-1); + + return rpContactSource; + } + + + bool NetBuilderVH::_do_1G_1M1 () + { + cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl; + + uint64_t flags = NoFlags; + if (east() ) { flags |= HAccess|VSmall; } + else if (west() ) { flags |= HAccess|VSmall; } + + setBothCornerContacts( doRp_Access(getGCell(),getRoutingPads()[0],flags) ); + + cdebug_tabw(145,-1); + return true; + } + + + bool NetBuilderVH::_do_1G_xM1 () + { + cdebug_log(145,1) << getTypeName() << "::_do_1G_" << (int)getConnexity().fields.M1 << "M1() [Defered Configuration]" << endl; + + _do_xG_xM1_xM3(); + + cdebug_tabw(145,-1); + return true; + } + + + bool NetBuilderVH::_do_2G_1M1 () + { + cdebug_log(145,1) << getTypeName() << "::_do_2G_1M1 [Managed Configuration]" << endl; + cdebug_log(145,0) << "north: " << north() << endl; + cdebug_log(145,0) << "south: " << south() << endl; + cdebug_log(145,0) << "east: " << east() << endl; + cdebug_log(145,0) << "west: " << west() << endl; + + AutoContact* tee = NULL; + + if (east() and west()) { + tee = doRp_Access( getGCell(), getRoutingPads()[0], HAccessEW|VSmall ); + } else { + AutoContact* turn = doRp_Access( getGCell(), getRoutingPads()[0], HAccess|VSmall ); + + if (east() or west()) + tee = AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ); + else + tee = AutoContactVTee::create( getGCell(), getNet(), Session::getDContactLayer() ); + + AutoSegment::create( turn, tee, Flags::Horizontal ); + } + setBothCornerContacts( tee ); + + cdebug_tabw(145,-1); + return true; + } + + + bool NetBuilderVH::_do_xG_xM1_xM3 () + { + cdebug_log(145,1) << getTypeName() + << "::_do_xG_" << (int)getConnexity().fields.M1 + << "M1_" << (int)getConnexity().fields.M3 + << "M3() [G:" << (int)getConnexity().fields.globals << " Managed Configuration]" << endl; + cdebug_log(145,0) << "getConnexity(): " << getConnexity().connexity << endl; + cdebug_log(145,0) << "north: " << north() << endl; + cdebug_log(145,0) << "south: " << south() << endl; + cdebug_log(145,0) << "east: " << east() << endl; + cdebug_log(145,0) << "west: " << west() << endl; + + sortRpByX( getRoutingPads(), NoFlags ); // increasing X. + + size_t iLast = getRoutingPads().size()-1; + AutoContact* leftContact = NULL; + AutoContact* rightContact = NULL; + + if (south() or west()) { + leftContact = doRp_Access( getGCell(), getRoutingPads()[0], HAccessEW|VSmall ); + if (south() and west()) { + setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ) ); + AutoSegment::create( getSouthWestContact(), leftContact, Flags::Horizontal ); + } else { + if (west()) + setSouthWestContact( leftContact ); + else { + setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), Session::getDContactLayer() ) ); + AutoSegment::create( leftContact, getSouthWestContact(), Flags::Horizontal ); + } + } + } else { + leftContact = doRp_Access( getGCell(), getRoutingPads()[0], HAccess|VSmall ); + } + + for ( size_t i=1 ; i( getFromHook()->getComponent() ) + ); + globalSegment->setFlags( (getDegree() == 2) ? AutoSegment::SegBipoint : 0 ); + cdebug_log(145,0) << "Create global segment: " << globalSegment << endl; + + // HARDCODED VALUE. + if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) ) + addToFixSegments( globalSegment ); + + if (getConnexity().fields.globals < 2) { + cdebug_tabw(145,-1); + return false; + } + } else + setFromHook( NULL ); + + push( east (), getNorthEastContact() ); + push( west (), getSouthWestContact() ); + push( north(), getNorthEastContact() ); + push( south(), getSouthWestContact() ); + + cdebug_tabw(145,-1); + return true; + } + + + void NetBuilderVH::singleGCell ( AnabaticEngine* anbt, Net* net ) + { + cdebug_log(145,1) << getTypeName() << "::singleGCell() " << net << endl; + + vector rps; + + for ( RoutingPad* rp : net->getRoutingPads() ) { + if (Session::getRoutingGauge()->getLayerDepth(rp->getLayer()) == 0) { + rps.push_back( rp ); + continue; + } + cerr << Error( "%s::singleGCell(): Non metal1 terminals are not managed yet.\n" + " (%s)" + , getTypeName().c_str() + , getString(rp).c_str() + ) << endl; + cdebug_tabw(145,-1); + return; + } + + if (rps.size() < 2) { + cerr << Error( "%s::singleGCell(): For %s, less than two Plugs/Pins (%d)." + , getTypeName().c_str() + , getString(net).c_str() + , rps.size() ) << endl; + cdebug_tabw(145,-1); + return; + } + + if (rps.empty()) { + cerr << Error( "%s::singleGCell(): No terminals for Net \"%s\"." + , getTypeName().c_str() + , getString(net->getName()).c_str() ) << endl; + cdebug_tabw(145,-1); + return; + } + + sortRpByX( rps, NetBuilder::NoFlags ); // increasing X. + + GCell* gcell1 = anbt->getGCellUnder( (*rps.begin ())->getCenter() ); + GCell* gcell2 = anbt->getGCellUnder( (*rps.rbegin())->getCenter() ); + + if (not gcell1) { + cerr << Error( "%s::singleGCell(): No GCell under %s." + , getTypeName().c_str() + , getString(*(rps.begin())).c_str() ) << endl; + cdebug_tabw(145,-1); + return; + } + if (gcell1 != gcell2) { + cerr << Error( "%s::singleGCell(): Not under a single GCell %s." + , getTypeName().c_str() + , getString(*(rps.rbegin())).c_str() ) << endl; + cdebug_tabw(145,-1); + return; + } + + cdebug_log(145,0) << "singleGCell " << gcell1 << endl; + + AutoContact* source = NULL; + AutoContact* target = NULL; + + for ( size_t irp=1 ; irp0) --_reduceds; } - inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); } + inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; } inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); } inline void AutoSegment::setOptimalMax ( DbU::Unit max ) { _optimalMax = (unsigned int)DbU::getLambda(max-getOrigin()); } inline void AutoSegment::mergeNativeMin ( DbU::Unit min ) { _nativeConstraints.getVMin() = std::max( min, _nativeConstraints.getVMin() ); } diff --git a/anabatic/src/anabatic/Configuration.h b/anabatic/src/anabatic/Configuration.h index 01d08072..b69c353c 100644 --- a/anabatic/src/anabatic/Configuration.h +++ b/anabatic/src/anabatic/Configuration.h @@ -24,6 +24,7 @@ namespace Hurricane { class Layer; class Cell; + class RoutingPad; } namespace CRL { @@ -43,6 +44,7 @@ namespace Anabatic { using Hurricane::Name; using Hurricane::Layer; using Hurricane::DbU; + using Hurricane::RoutingPad; using Hurricane::Cell; using CRL::CellGauge; using CRL::RoutingGauge; @@ -118,6 +120,8 @@ namespace Anabatic { float getEdgeCostH () const; float getEdgeCostK () const; float getEdgeHInc () const; + DbU::Unit isOnRoutingGrid ( RoutingPad* ) const; + bool selectRpComponent ( RoutingPad* ) const; virtual void print ( Cell* ) const; virtual Record* _getRecord () const; virtual string _getString () const; diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index 4cc3fd6e..7e871228 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -200,10 +200,13 @@ namespace Anabatic { inline Vertex ( GCell* ); //inline Vertex ( size_t id ); inline ~Vertex (); + inline bool isAnalog () const; inline bool hasDoneAllRps () const; inline Contact* hasGContact ( Net* ) const; inline unsigned int getId () const; inline GCell* getGCell () const; + inline Box getBoundingBox () const; + inline Edges getEdges ( Flags sides=Flags::AllSides ) const; inline AnabaticEngine* getAnabatic () const; inline Contact* getGContact ( Net* ); bool hasValidStamp () const; @@ -216,6 +219,7 @@ namespace Anabatic { inline int getRpCount () const; Edge* getFrom () const; inline Vertex* getPredecessor () const; + inline Vertex* getNeighbor ( Edge* ) const; inline void setDistance ( DbU::Unit ); inline void setStamp ( int ); inline void setConnexId ( int ); @@ -334,6 +338,9 @@ namespace Anabatic { inline Vertex* Vertex::lookup ( GCell* gcell ) { return gcell->getObserver(GCell::Observable::Vertex); } inline Vertex::~Vertex () { _gcell->setObserver( GCell::Observable::Vertex, NULL ); } + inline bool Vertex::isAnalog () const { return _gcell->isAnalog(); } + inline Box Vertex::getBoundingBox () const { return _gcell->getBoundingBox(); } + inline Edges Vertex::getEdges ( Flags sides ) const { return _gcell->getEdges(sides); } inline Contact* Vertex::hasGContact ( Net* net ) const { return _gcell->hasGContact(net); } inline unsigned int Vertex::getId () const { return _id; } inline GCell* Vertex::getGCell () const { return _gcell; } @@ -361,6 +368,12 @@ namespace Anabatic { inline Vertex* Vertex::getPredecessor () const { return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver(GCell::Observable::Vertex) : NULL; } + inline Vertex* Vertex::getNeighbor ( Edge* edge ) const + { + GCell* gcell = edge->getOpposite( getGCell() ); + return (gcell) ? gcell->getObserver(GCell::Observable::Vertex) : NULL; + } + inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs ) const { return lhs->getId() < rhs->getId(); } diff --git a/anabatic/src/anabatic/NetBuilder.h b/anabatic/src/anabatic/NetBuilder.h index c39761c0..3b66b92f 100644 --- a/anabatic/src/anabatic/NetBuilder.h +++ b/anabatic/src/anabatic/NetBuilder.h @@ -84,19 +84,20 @@ namespace Anabatic { enum FunctionFlags { NoFlags = (1 << 0) , SortDecreasing = (1 << 1) , HAccess = (1 << 2) - , VSmall = (1 << 3) - , HSmall = (1 << 4) - , Punctual = (1 << 5) - , HCollapse = (1 << 6) - , VCollapse = (1 << 7) - , Terminal = (1 << 8) - , DoSourceContact = (1 << 9) - , DoTargetContact = (1 << 10) - , SouthBound = (1 << 11) - , NorthBound = (1 << 12) - , WestBound = (1 << 13) - , EastBound = (1 << 14) - , Middle = (1 << 15) + , HAccessEW = (1 << 3) + , VSmall = (1 << 4) + , HSmall = (1 << 5) + , Punctual = (1 << 6) + , HCollapse = (1 << 7) + , VCollapse = (1 << 8) + , Terminal = (1 << 9) + , DoSourceContact = (1 << 10) + , DoTargetContact = (1 << 11) + , SouthBound = (1 << 12) + , NorthBound = (1 << 13) + , WestBound = (1 << 14) + , EastBound = (1 << 15) + , Middle = (1 << 16) , SouthWest = SouthBound|WestBound , NorthEast = NorthBound|EastBound }; @@ -137,11 +138,16 @@ namespace Anabatic { static uint64_t checkRoutingPadSize ( Component* anchor ); static Hook* getSegmentOppositeHook ( Hook* hook ); static uint64_t getSegmentHookType ( Hook* hook ); + static void sortHookByX ( vector& , uint64_t flags=NoFlags ); + static void sortHookByY ( vector& , uint64_t flags=NoFlags ); + static void sortRpByX ( vector& , uint64_t flags=NoFlags ); + static void sortRpByY ( vector& , uint64_t flags=NoFlags ); public: NetBuilder (); virtual ~NetBuilder (); void clear (); inline bool isTwoMetals () const; + inline AnabaticEngine* getAnabatic () const; inline unsigned int getDegree () const; inline void setDegree ( unsigned int degree ); void fixSegments (); @@ -191,7 +197,6 @@ namespace Anabatic { virtual AutoContact* doRp_AccessAnalog ( GCell*, RoutingPad*, uint64_t flags ); void doRp_StairCaseH ( GCell*, Component* rp1, Component* rp2 ); void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 ); - void singleGCell ( AnabaticEngine*, Net* ); void _load ( AnabaticEngine*, Net* ); private: virtual bool _do_xG (); @@ -208,6 +213,7 @@ namespace Anabatic { virtual bool _do_1G_1M3 (); virtual bool _do_xG_xM3 (); virtual bool _do_globalSegment (); + virtual void singleGCell ( AnabaticEngine*, Net* ); AutoContact* _doHChannel (); AutoContact* _doVChannel (); AutoContact* _doStrut (); @@ -292,6 +298,7 @@ namespace Anabatic { // Attributes. private: + AnabaticEngine* _anabatic; ForkStack _forks; UConnexity _connexity; unsigned int _topology; @@ -313,41 +320,11 @@ namespace Anabatic { // Sort classes. public: - class SortHookByX { - public: - inline SortHookByX ( uint64_t flags ); - inline bool operator() ( Hook* h1, Hook* h2 ); - protected: - uint64_t _flags; - }; - - class SortHookByY { - public: - inline SortHookByY ( uint64_t flags ); - inline bool operator() ( Hook* h1, Hook* h2 ); - protected: - uint64_t _flags; - }; - - class SortRpByX { - public: - inline SortRpByX ( uint64_t flags ); - inline bool operator() ( Component* rp1, Component* rp2 ); - private: - uint64_t _flags; - }; - - class SortRpByY { - public: - inline SortRpByY ( uint64_t flags ); - inline bool operator() ( Component* rp1, Component* rp2 ); - protected: - uint64_t _flags; - }; }; inline bool NetBuilder::isTwoMetals () const { return _isTwoMetals; } + inline AnabaticEngine* NetBuilder::getAnabatic () const { return _anabatic; } inline unsigned int NetBuilder::getDegree () const { return _degree; } inline NetBuilder::UConnexity NetBuilder::getConnexity () const { return _connexity; } inline NetBuilder::UConnexity& NetBuilder::getConnexity () { return _connexity; } @@ -389,102 +366,6 @@ namespace Anabatic { template< typename BuilderT > void NetBuilder::load ( AnabaticEngine* engine, Net* net ) { BuilderT()._load(engine,net); } - -// ------------------------------------------------------------------- -// Class : "NetBuilder::SortRpByX". - - inline NetBuilder::SortRpByX::SortRpByX ( uint64_t flags ) - : _flags(flags) - { } - - - inline bool NetBuilder::SortRpByX::operator() ( Component* rp1, Component* rp2 ) - { - DbU::Unit x1 = rp1->getCenter().getX(); - DbU::Unit x2 = rp2->getCenter().getX(); - - if (x1 == x2) return false; - return (_flags & NetBuilder::SortDecreasing) xor (x1 < x2); - } - - -// ------------------------------------------------------------------- -// Class : "NetBuilder::SortRpByY". - - inline NetBuilder::SortRpByY::SortRpByY ( uint64_t flags ) - : _flags(flags) - { } - - - inline bool NetBuilder::SortRpByY::operator() ( Component* rp1, Component* rp2 ) - { - DbU::Unit y1 = rp1->getCenter().getY(); - DbU::Unit y2 = rp2->getCenter().getY(); - - if (y1 == y2) return false; - return (_flags & NetBuilder::SortDecreasing) xor (y1 < y2); - } - - -// ------------------------------------------------------------------- -// Class : "NetBuilder::SortHookByX". - - inline NetBuilder::SortHookByX::SortHookByX ( uint64_t flags ) - : _flags(flags) - { } - - - inline bool NetBuilder::SortHookByX::operator() ( Hook* h1, Hook* h2 ) - { - DbU::Unit x1 = 0; - DbU::Unit x2 = 0; - Horizontal* hh1 = dynamic_cast(h1->getComponent()); - Horizontal* hh2 = dynamic_cast(h2->getComponent()); - Vertical* vv1 = dynamic_cast (h1->getComponent()); - Vertical* vv2 = dynamic_cast (h2->getComponent()); - - if (hh1) x1 = std::min( hh1->getSource()->getX(), hh1->getTarget()->getX() ); - else if (vv1) x1 = vv1->getX(); - else x1 = h1->getComponent()->getCenter().getX(); - - if (hh2) x2 = std::min( hh2->getSource()->getX(), hh2->getTarget()->getX() ); - else if (vv2) x2 = vv2->getX(); - else x2 = h2->getComponent()->getCenter().getX(); - - if (x1 == x2) return false; - return (_flags & NetBuilder::SortDecreasing) xor (x1 < x2); - } - - -// ------------------------------------------------------------------- -// Class : "NetBuilder::SortHookByY". - - inline NetBuilder::SortHookByY::SortHookByY ( uint64_t flags ) - : _flags(flags) - { } - - - inline bool NetBuilder::SortHookByY::operator() ( Hook* h1, Hook* h2 ) - { - DbU::Unit y1 = 0; - DbU::Unit y2 = 0; - Horizontal* hh1 = dynamic_cast(h1->getComponent()); - Horizontal* hh2 = dynamic_cast(h2->getComponent()); - Vertical* vv1 = dynamic_cast (h1->getComponent()); - Vertical* vv2 = dynamic_cast (h2->getComponent()); - - if (vv1) y1 = std::min( vv1->getSource()->getY(), vv1->getTarget()->getY() ); - else if (hh1) y1 = hh1->getY(); - else y1 = h1->getComponent()->getCenter().getX(); - - if (vv2) y2 = std::min( vv2->getSource()->getY(), vv2->getTarget()->getY() ); - else if (hh2) y2 = hh2->getY(); - else y2 = h2->getComponent()->getCenter().getY(); - - if (y1 == y2) return false; - return (_flags & NetBuilder::SortDecreasing) xor (y1 < y2); - } - } #endif // ANABATIC_NET_BUILDER_H diff --git a/anabatic/src/anabatic/NetBuilderVH.h b/anabatic/src/anabatic/NetBuilderVH.h new file mode 100644 index 00000000..96011517 --- /dev/null +++ b/anabatic/src/anabatic/NetBuilderVH.h @@ -0,0 +1,49 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2017-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./anabatic/NetBuilderVH.h" | +// +-----------------------------------------------------------------+ + +#ifndef ANABATIC_NET_BUILDER_VH_H +#define ANABATIC_NET_BUILDER_VH_H + +#include "anabatic/NetBuilder.h" + + +namespace Anabatic { + + +// ----------------------------------------------------------------- +// Class : "NetBuilderVH". + + class NetBuilderVH : public NetBuilder { + public: + NetBuilderVH (); + virtual ~NetBuilderVH (); + virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); + virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); + private: + virtual bool _do_1G_1M1 (); + virtual bool _do_1G_xM1 (); + virtual bool _do_2G_1M1 (); + virtual bool _do_xG_xM1_xM3 (); + virtual bool _do_xG (); + virtual bool _do_globalSegment (); + virtual void singleGCell ( AnabaticEngine*, Net* ); + public: + virtual string getTypeName () const; + }; + + +} // Anabatic namespace. + +#endif // ANABATIC_NET_BUILDER_VH_H