diff --git a/anabatic/src/AutoContact.cpp b/anabatic/src/AutoContact.cpp index 67af297b..ebe47f6f 100644 --- a/anabatic/src/AutoContact.cpp +++ b/anabatic/src/AutoContact.cpp @@ -171,16 +171,13 @@ namespace Anabatic { } - const Name& AutoContact::getName () const - { return _goName; } - - - AutoSegments AutoContact::getAutoSegments () - { return new AutoSegments_CachedOnContact(this); } - - - AutoSegment* AutoContact::getPerpandicular ( const AutoSegment* ) const - { return NULL; } + const Name& AutoContact::getName () const { return _goName; } + AutoSegments AutoContact::getAutoSegments () { return new AutoSegments_CachedOnContact(this); } + AutoSegment* AutoContact::getPerpandicular ( const AutoSegment* ) const { return NULL; } + AutoHorizontal* AutoContact::getHorizontal1 () const { return NULL; } + AutoHorizontal* AutoContact::getHorizontal2 () const { return NULL; } + AutoVertical* AutoContact::getVertical1 () const { return NULL; } + AutoVertical* AutoContact::getVertical2 () const { return NULL; } void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const @@ -318,6 +315,31 @@ namespace Anabatic { } + void AutoContact::updateSize () + { + if (isInvalidatedWidth()) { + size_t minDepth = 0; + size_t maxDepth = 0; + getDepthSpan( minDepth, maxDepth ); + + if (getVertical1() and getVertical1()->isWide()) { + size_t vdepth = (Session::getLayerDepth(getVertical1()->getLayer()) == maxDepth) ? maxDepth : minDepth; + DbU::Unit width = getVertical1()->getWidth(); + width += Session::getViaWidth(vdepth) - Session::getWireWidth(vdepth); + setWidth( width ); + } + + if (getHorizontal1() and getHorizontal1()->isWide()) { + size_t hdepth = (Session::getLayerDepth(getHorizontal1()->getLayer()) == maxDepth) ? maxDepth : minDepth; + DbU::Unit width = getHorizontal1()->getWidth(); + width += Session::getViaWidth(hdepth) - Session::getWireWidth(hdepth); + setHeight( width ); + } + unsetFlags ( CntInvalidatedWidth ); + } + } + + void AutoContact::_getTopology ( Contact* support, Component*& anchor, Horizontal**& horizontals, Vertical**& verticals, size_t size ) { size_t hcount = 0; diff --git a/anabatic/src/AutoContactHTee.cpp b/anabatic/src/AutoContactHTee.cpp index 324f38ef..430fa887 100644 --- a/anabatic/src/AutoContactHTee.cpp +++ b/anabatic/src/AutoContactHTee.cpp @@ -110,6 +110,11 @@ namespace Anabatic { } + AutoHorizontal* AutoContactHTee::getHorizontal1 () const { return _horizontal1; }; + AutoHorizontal* AutoContactHTee::getHorizontal2 () const { return _horizontal2; }; + AutoVertical* AutoContactHTee::getVertical1 () const { return _vertical1; }; + + void AutoContactHTee::_invalidate ( Flags ) { Flags flags = Flags::Propagate; @@ -258,6 +263,7 @@ namespace Anabatic { if (not hasBadTopology()) { setX( getVertical1 ()->getX() ); setY( getHorizontal1()->getY() ); + updateSize(); } cdebug_tabw(145,-1); diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index fb0aafd8..3a234fac 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -246,12 +246,19 @@ namespace Anabatic { order( xMin, xMax ); order( yMin, yMax ); + Box bb ( xMin, yMin, xMax, yMax ); + + if (_segment and _segment->isWide()) { + if (dynamic_cast(_segment)) bb.inflate( 0, 0, 0, -_segment->getWidth() ); + else bb.inflate( 0, 0, -_segment->getWidth(), 0 ); + } + cdebug_log(145,0) << "| Using (y): " - << DbU::getValueString(yMin) << " " - << DbU::getValueString(yMax) << endl; + << DbU::getValueString(bb.getYMin()) << " " + << DbU::getValueString(bb.getYMax()) << endl; cdebug_tabw(145,-1); - return Box( xMin, yMin, xMax, yMax ); + return bb; } @@ -354,10 +361,20 @@ namespace Anabatic { ostringstream message; if (not hasBadTopology()) { + Box anchorBb = getAnchor()->getBoundingBox(); + anchorBb.inflate( Session::getViaWidth (getAnchor()->getLayer()) + - Session::getWireWidth(getAnchor()->getLayer()) ); + if (_segment->isHorizontal()) { - if (not getUConstraints(Flags::Vertical).contains(_segment->getY())) { + DbU::Unit axis = _segment->getY(); + if (_segment->isWide()) { + axis += (- _segment->getWidth() + Session::getWireWidth(_segment->getLayer())) / 2; + setHeight( _segment->getContactWidth() ); + } + + if (not getUConstraints(Flags::Vertical).contains(axis)) { cdebug_log(145,0) << "Cached: " << _segment << endl; - message << "Terminal horizontal segment Y " << DbU::getValueString(_segment->getY()) + message << "Terminal horizontal segment Y " << DbU::getValueString(axis) << " axis is outside RoutingPad " << getUConstraints(Flags::Vertical) << "."; Interval intv; @@ -370,9 +387,18 @@ namespace Anabatic { } else setY( _segment->getY() ); } else { - if (not getUConstraints(Flags::Horizontal).contains(_segment->getX())) { + DbU::Unit axis = _segment->getX(); + if (_segment->isWide()) { + axis += (- _segment->getWidth() + Session::getWireWidth(_segment->getLayer())) / 2; + setWidth ( _segment->getContactWidth() ); + setHeight( anchorBb.getHeight() ); + + cdebug_log(145,0) << "Contact for wide segment." << endl; + } + + if (not getUConstraints(Flags::Horizontal).contains(axis)) { cdebug_log(145,0) << "Cached: " << _segment << endl; - message << "Terminal vertical segment X" << DbU::getValueString(_segment->getX()) + 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 1f004f71..045758b3 100644 --- a/anabatic/src/AutoContactTurn.cpp +++ b/anabatic/src/AutoContactTurn.cpp @@ -104,6 +104,10 @@ namespace Anabatic { } + AutoHorizontal* AutoContactTurn::getHorizontal1 () const { return _horizontal1; }; + AutoVertical* AutoContactTurn::getVertical1 () const { return _vertical1; }; + + void AutoContactTurn::_invalidate ( Flags flags ) { if (_horizontal1) _horizontal1->invalidate(); @@ -144,6 +148,7 @@ namespace Anabatic { } if (_horizontal1 and _vertical1) unsetFlags( CntInvalidatedCache ); + setFlags( CntInvalidatedWidth ); } @@ -172,8 +177,10 @@ namespace Anabatic { if (not message.empty()) { showTopologyError( message ); setFlags( CntBadTopology ); - } else + } else { unsetFlags( CntInvalidatedCache ); + setFlags ( CntInvalidatedWidth ); + } cdebug_log(145,0) << "h1:" << _horizontal1 << endl; cdebug_log(145,0) << "v1:" << _vertical1 << endl; @@ -201,11 +208,12 @@ namespace Anabatic { } base()->invalidate( false ); - unsetFlags ( CntInvalidated ); + unsetFlags( CntInvalidated ); if (not hasBadTopology()) { setX( getVertical1 ()->getX() ); setY( getHorizontal1()->getY() ); + updateSize(); } cdebug_tabw(145,-1); diff --git a/anabatic/src/AutoContactVTee.cpp b/anabatic/src/AutoContactVTee.cpp index d6ad9744..ff80e650 100644 --- a/anabatic/src/AutoContactVTee.cpp +++ b/anabatic/src/AutoContactVTee.cpp @@ -106,6 +106,11 @@ namespace Anabatic { } + AutoHorizontal* AutoContactVTee::getHorizontal1 () const { return _horizontal1; }; + AutoVertical* AutoContactVTee::getVertical1 () const { return _vertical1; }; + AutoVertical* AutoContactVTee::getVertical2 () const { return _vertical2; }; + + void AutoContactVTee::_invalidate ( Flags ) { Flags flags = Flags::Propagate; @@ -225,6 +230,7 @@ namespace Anabatic { if (not hasBadTopology()) { setX( getVertical1 ()->getX() ); setY( getHorizontal1()->getY() ); + updateSize(); } cdebug_tabw(145,-1); diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index 2af7fb54..395e5c33 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -410,19 +410,19 @@ namespace Anabatic { cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl; _horizontal->invert(); - Flags spinFlags = _flags & SegDepthSpin; + uint64_t spinFlags = _flags & SegDepthSpin; unsetFlags( SegDepthSpin ); if (spinFlags & SegSourceTop ) setFlags( SegTargetTop ); if (spinFlags & SegSourceBottom) setFlags( SegTargetBottom ); if (spinFlags & SegTargetTop ) setFlags( SegSourceTop ); if (spinFlags & SegTargetBottom) setFlags( SegSourceBottom ); - Flags invalidatedFlags = _flags & (SegInvalidatedSource|SegInvalidatedTarget); + uint64_t invalidatedFlags = _flags & (SegInvalidatedSource|SegInvalidatedTarget); unsetFlags( SegInvalidatedSource|SegInvalidatedTarget ); if (invalidatedFlags & SegInvalidatedSource) setFlags( SegInvalidatedTarget ); if (invalidatedFlags & SegInvalidatedTarget) setFlags( SegInvalidatedSource ); - Flags terminalFlags = _flags & SegStrongTerminal; + uint64_t terminalFlags = _flags & SegStrongTerminal; unsetFlags( SegStrongTerminal ); if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal ); if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal ); diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index d448de08..9976d7af 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -539,7 +539,7 @@ namespace Anabatic { updateOrient (); updatePositions(); - uint32_t oldSpinFlags = _flags & SegDepthSpin; + uint64_t oldSpinFlags = _flags & SegDepthSpin; if (_flags & (SegInvalidatedSource|SegCreated)) { AutoContact* source = getAutoSource(); @@ -766,7 +766,7 @@ namespace Anabatic { } - void AutoSegment::setFlagsOnAligneds ( uint32_t flags ) + void AutoSegment::setFlagsOnAligneds ( uint64_t flags ) { setFlags( flags ); if (not isNotAligned()) { @@ -965,7 +965,7 @@ namespace Anabatic { if (not source->isTerminal()) source->setFlags( CntWeakTerminal ); } else { - uint32_t terminalFlag = 0; + uint64_t terminalFlag = 0; switch ( _getFlags() & SegWeakTerminal ) { case 0: break; case SegSourceTerminal|SegTargetTerminal: @@ -2151,10 +2151,21 @@ namespace Anabatic { , Segment* hurricaneSegment ) { - static const Layer* horizontalLayer = Session::getRoutingLayer( 1 ); - static DbU::Unit horizontalWidth = Session::getWireWidth ( 1 ); - static const Layer* verticalLayer = Session::getRoutingLayer( 2 ); - static DbU::Unit verticalWidth = Session::getWireWidth ( 2 ); + const Layer* horizontalLayer = Session::getRoutingLayer( 1 ); + DbU::Unit horizontalWidth = Session::getWireWidth ( 1 ); + const Layer* verticalLayer = Session::getRoutingLayer( 2 ); + DbU::Unit verticalWidth = Session::getWireWidth ( 2 ); + + uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() ); + if (wPitch > 1) { + horizontalWidth += (wPitch-1) * Session::getPitch(1); + verticalWidth += (wPitch-1) * Session::getPitch(2); + } + cdebug_log(149,0) << "wPitch:" << wPitch << " hW:" << DbU::getValueString(horizontalWidth) << endl; + + if (wPitch > 2) { + throw Error( "wPitch %d for \"%s\"", wPitch, getString(source->getNet()->getName()).c_str() ); + } bool reattachSource = false; bool reattachTarget = false; @@ -2259,6 +2270,8 @@ namespace Anabatic { throw Error( badSegment, getString(source).c_str(), getString(target).c_str() ); } + if (wPitch > 1) segment->setFlags( SegWide ); + return segment; } @@ -2274,19 +2287,31 @@ namespace Anabatic { // depth=1 is horizontal | METAL2 // depth=2 is vertical | METAL3 // Should be based on gauge informations. - static const Layer* hLayer = Session::getRoutingLayer( 1 ); - static DbU::Unit hWidth = Session::getWireWidth ( 1 ); - static const Layer* vLayer = Session::getRoutingLayer( 2 ); - static DbU::Unit vWidth = Session::getWireWidth ( 2 ); + const Layer* hLayer = Session::getRoutingLayer( 1 ); + DbU::Unit hWidth = Session::getWireWidth ( 1 ); + const Layer* vLayer = Session::getRoutingLayer( 2 ); + DbU::Unit vWidth = Session::getWireWidth ( 2 ); const Layer* horizontalLayer = hLayer; DbU::Unit horizontalWidth = hWidth; const Layer* verticalLayer = vLayer; DbU::Unit verticalWidth = vWidth; + uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() ); + if (wPitch > 1) { + horizontalWidth = (wPitch-1) * Session::getPitch(1) + hWidth; + verticalWidth = (wPitch-1) * Session::getPitch(2) + vWidth; + } + if (depth != RoutingGauge::nlayerdepth) { horizontalLayer = verticalLayer = Session::getRoutingLayer( depth ); - horizontalWidth = verticalWidth = Session::getWireWidth ( depth ); + + if (wPitch > 1) { + horizontalWidth = verticalWidth = (wPitch-1) * Session::getPitch (depth) + + Session::getWireWidth(depth); + } else { + horizontalWidth = verticalWidth = Session::getWireWidth( depth ); + } } AutoSegment* segment; @@ -2335,6 +2360,8 @@ namespace Anabatic { } else throw Error( badSegment, getString(source).c_str(), getString(target).c_str() ); + if (wPitch > 1) segment->setFlags( SegWide ); + return segment; } diff --git a/anabatic/src/AutoSegments.cpp b/anabatic/src/AutoSegments.cpp index 767c546b..40b32746 100644 --- a/anabatic/src/AutoSegments.cpp +++ b/anabatic/src/AutoSegments.cpp @@ -480,7 +480,7 @@ namespace Anabatic { cdebug_log(144,1) << "AutoSegments_Perpandiculars::Locator::progress()" << endl; if (not _perpandiculars.empty()) _perpandiculars.pop_back(); - if (not _perpandiculars.empty()) return; + if (not _perpandiculars.empty()) { cdebug_tabw(144,-1); return; } while ( not _stack.isEmpty() ) { AutoContact* sourceContact = _stack.getAutoContact(); diff --git a/anabatic/src/LoadGlobalRouting.cpp b/anabatic/src/LoadGlobalRouting.cpp index f3762ff4..faf105fa 100644 --- a/anabatic/src/LoadGlobalRouting.cpp +++ b/anabatic/src/LoadGlobalRouting.cpp @@ -880,7 +880,7 @@ namespace { void GCellTopology::fixSegments () { for ( size_t i=0 ; i<_toFixSegments.size() ; ++i ) - _toFixSegments[i]->setFlags( SegFixed ); + _toFixSegments[i]->setFlags( AutoSegment::SegFixed ); _toFixSegments.clear(); } @@ -1120,7 +1120,7 @@ namespace { , targetContact , static_cast( _fromHook->getComponent() ) ); - globalSegment->setFlags( (_degree == 2) ? SegBipoint : 0 ); + globalSegment->setFlags( (_degree == 2) ? AutoSegment::SegBipoint : 0 ); cdebug_log(145,0) << "Create global segment: " << globalSegment << endl; // HARDCODED VALUE. @@ -1220,7 +1220,7 @@ namespace { const Layer* rpLayer = rp->getLayer(); size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); Flags direction = Session::getDirection ( rpDepth ); - DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); + DbU::Unit viaSide = Session::getViaWidth ( rpDepth ); getPositions( rp, sourcePosition, targetPosition ); @@ -1256,7 +1256,7 @@ namespace { targetProtect->setFlags( CntFixed ); AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction ); - segment->setFlags( SegFixed ); + segment->setFlags( AutoSegment::SegFixed ); __routingPadAutoSegments.insert( make_pair(rp,segment) ); } @@ -1480,7 +1480,7 @@ namespace { const Layer* rpLayer = rp->getLayer(); size_t rpDepth = Session::getLayerDepth( rpLayer ); - DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); + DbU::Unit viaSide = Session::getViaWidth ( rpDepth ); Point position = rp->getCenter(); Point onGrid = Session::getNearestGridPoint( position, gcell->getConstraintBox() ); @@ -2350,19 +2350,10 @@ namespace { { cdebug_log(145,1) << "void GCellTopology::_doHChannel ( ForkStack& forks )" << _gcell << endl; - vector hooks; - Hook* firsthhook = NULL; - Hook* lasthhook = NULL; - static const Layer* hLayer = Session::getRoutingLayer( 1 ); - static DbU::Unit hWidth = Session::getWireWidth ( 1 ); - static const Layer* vLayer = Session::getRoutingLayer( 2 ); - static DbU::Unit vWidth = Session::getWireWidth ( 2 ); - - const Layer* horizontalLayer = hLayer; - DbU::Unit horizontalWidth = hWidth; - const Layer* verticalLayer = vLayer; - DbU::Unit verticalWidth = vWidth; - AutoContact* targetContact = NULL; + vector hooks; + Hook* firsthhook = NULL; + Hook* lasthhook = NULL; + AutoContact* targetContact = NULL; // Save segments only cdebug_log(145,0) << "fromHook: " << _fromHook << endl; @@ -2462,15 +2453,8 @@ namespace { cdebug_log(145,0) << "Chain contacts: " << endl; for (size_t j=1; j < autoContacts.size(); j++){ if (autoContacts[j-1] != autoContacts[j]){ - AutoSegment* globalSegment = - AutoSegment::create( autoContacts[j-1] , autoContacts[j] - , Horizontal::create( autoContacts[j-1]->base() , autoContacts[j]->base() - , horizontalLayer - , autoContacts[j-1]->getY() - , horizontalWidth - ) - ); - cdebug_log(145,0) << "[Create global segment (2)]: " << globalSegment << endl; + AutoSegment* segment = AutoSegment::create( autoContacts[j-1] , autoContacts[j], Flags::Horizontal ); + cdebug_log(145,0) << "[Create global segment (2)]: " << segment << endl; } } // There are only 2 AutoContacts to create @@ -2498,14 +2482,7 @@ namespace { cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl; cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl; - AutoSegment* globalSegment = - AutoSegment::create( source, target - , Horizontal::create( source->base(), target->base() - , horizontalLayer - , source->getY() - , horizontalWidth - ) - ); + AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Horizontal ); cdebug_log(145,0) << "[Create global segment (3)]: " << globalSegment << endl; if (_fromHook->getComponent() == hooks[0]->getComponent()){ @@ -2551,14 +2528,7 @@ namespace { cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl; cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl; - AutoSegment* globalSegment = - AutoSegment::create( source, target - , Vertical::create( source->base(), target->base() - , verticalLayer - , source->getX() - , verticalWidth - ) - ); + AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Vertical ); cdebug_log(145,0) << "[Create global segment (4)]: " << globalSegment << endl; if (_fromHook->getComponent() == hooks[0]->getComponent()){ @@ -2585,19 +2555,10 @@ namespace { cdebug_log(145,1) << "void GCellTopology::_doVChannel ()" << _gcell << endl; - vector hooks; - Hook* firstvhook = NULL; - Hook* lastvhook = NULL; - static const Layer* hLayer = Session::getRoutingLayer( 1 ); - static DbU::Unit hWidth = Session::getWireWidth ( 1 ); - static const Layer* vLayer = Session::getRoutingLayer( 2 ); - static DbU::Unit vWidth = Session::getWireWidth ( 2 ); - - const Layer* horizontalLayer = hLayer; - DbU::Unit horizontalWidth = hWidth; - const Layer* verticalLayer = vLayer; - DbU::Unit verticalWidth = vWidth; - AutoContact* targetContact = NULL; + vector hooks; + Hook* firstvhook = NULL; + Hook* lastvhook = NULL; + AutoContact* targetContact = NULL; // Save segments only cdebug_log(145,0) << "fromHook: " << _fromHook << endl; @@ -2699,16 +2660,9 @@ namespace { cdebug_log(145,0) << "Chain contacts: " << endl; for (size_t j=1; j < autoContacts.size(); j++){ if (autoContacts[j-1] != autoContacts[j]){ - AutoSegment* globalSegment = - AutoSegment::create( autoContacts[j-1] , autoContacts[j] - , Vertical::create( autoContacts[j-1]->base() , autoContacts[j]->base() - , verticalLayer - , autoContacts[j-1]->getX() - , verticalWidth - ) - ); - if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal ); - cdebug_log(145,0) << "[Create global segment (5)]: " << globalSegment << endl; + AutoSegment* segment = AutoSegment::create( autoContacts[j-1] , autoContacts[j], Flags::Vertical ); + if (not segment->isGlobal()) segment->setFlags( AutoSegment::SegLongLocal ); + cdebug_log(145,0) << "[Create global segment (5)]: " << segment << endl; } } // There are only 2 AutoContacts to create @@ -2738,15 +2692,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl; cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl; - AutoSegment* globalSegment = - AutoSegment::create( source, target - , Vertical::create( source->base(), target->base() - , verticalLayer - , source->getX() - , verticalWidth - ) - ); - if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal ); + AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Vertical ); + if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (6)]: " << globalSegment << endl; if (_fromHook->getComponent() == hooks[0]->getComponent()){ @@ -2793,15 +2740,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl; cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl; - AutoSegment* globalSegment = - AutoSegment::create( source, target - , Horizontal::create( source->base(), target->base() - , horizontalLayer - , source->getY() - , horizontalWidth - ) - ); - if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal ); + AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Horizontal ); + if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (7)]: " << globalSegment << endl; if (_fromHook->getComponent() == hooks[0]->getComponent()){ @@ -2853,16 +2793,7 @@ namespace { AutoContact* GCellTopology::_doStrut ( ForkStack& forks ) { cdebug_log(145,1) << "void GCellTopology::_doStrut ()" << _gcell << endl; - - static const Layer* hLayer = Session::getRoutingLayer( 1 ); - static DbU::Unit hWidth = Session::getWireWidth ( 1 ); - static const Layer* vLayer = Session::getRoutingLayer( 2 ); - static DbU::Unit vWidth = Session::getWireWidth ( 2 ); - const Layer* horizontalLayer = hLayer; - DbU::Unit horizontalWidth = hWidth; - const Layer* verticalLayer = vLayer; - DbU::Unit verticalWidth = vWidth; AutoContact* targetContact = NULL; // Contact for fromHook segment cdebug_log(145,0) << "FromHook: " << _fromHook << endl; cdebug_log(145,0) << "North : " << _north << endl; @@ -2948,15 +2879,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact]: " << source << endl; cdebug_log(145,0) << "[Create AutoContact]: " << target << endl; - AutoSegment* globalSegment = - AutoSegment::create( source, target - , Horizontal::create( source->base(), target->base() - , horizontalLayer - , source->getY() - , horizontalWidth - ) - ); - if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal ); + AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Horizontal ); + if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (8)]: " << globalSegment << endl; } else if ((_east != NULL) && (_west != NULL) ) { @@ -2999,15 +2923,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact]: " << source << endl; cdebug_log(145,0) << "[Create AutoContact]: " << target << endl; - AutoSegment* globalSegment = - AutoSegment::create( source, target - , Vertical::create( source->base(), target->base() - , verticalLayer - , source->getX() - , verticalWidth - ) - ); - if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal ); + AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Vertical ); + if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (9)]: " << globalSegment << endl; } else { @@ -3048,15 +2965,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; - AutoSegment* globalSegment = - AutoSegment::create( turn, xtee - , Horizontal::create( turn->base(), xtee->base() - , horizontalLayer - , turn->getY() - , horizontalWidth - ) - ); - if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal ); + AutoSegment* globalSegment = AutoSegment::create( turn, xtee, Flags::Horizontal ); + if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (10)]: " << globalSegment << endl; } else if ((_north != NULL) && (_south != NULL) && (_west != NULL)){ @@ -3086,15 +2996,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; - AutoSegment* globalSegment = - AutoSegment::create( xtee, turn - , Horizontal::create( xtee->base(), turn->base() - , horizontalLayer - , xtee->getY() - , horizontalWidth - ) - ); - if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal ); + AutoSegment* globalSegment = AutoSegment::create( xtee, turn, Flags::Horizontal ); + if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (11)]: " << globalSegment << endl; @@ -3125,15 +3028,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; - AutoSegment* globalSegment = - AutoSegment::create( turn, xtee - , Vertical::create( turn->base(), xtee->base() - , verticalLayer - , turn->getX() - , verticalWidth - ) - ); - if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal ); + AutoSegment* globalSegment = AutoSegment::create( turn, xtee, Flags::Vertical ); + if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (12)]: " << globalSegment << endl; } else if ((_east != NULL) && (_south != NULL) && (_west != NULL)){ @@ -3163,15 +3059,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; - AutoSegment* globalSegment = - AutoSegment::create( xtee, turn - , Vertical::create( xtee->base(), turn->base() - , verticalLayer - , turn->getX() - , verticalWidth - ) - ); - if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal ); + AutoSegment* globalSegment = AutoSegment::create( xtee, turn, Flags::Vertical ); + if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (13)]: " << globalSegment << endl; } else { @@ -3212,22 +3101,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl; cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; - AutoSegment* globalSegment1 = - AutoSegment::create( turn, hteeh - , Horizontal::create( turn->base(), hteeh->base() - , horizontalLayer - , turn->getY() - , horizontalWidth - ) - ); - AutoSegment* globalSegment2 = - AutoSegment::create( turn, hteeh - , Vertical::create( turn->base(), hteeh->base() - , verticalLayer - , turn->getX() - , verticalWidth - ) - ); + AutoSegment* globalSegment1 = AutoSegment::create( turn, hteeh, Flags::Horizontal ); + AutoSegment* globalSegment2 = AutoSegment::create( turn, hteeh, Flags::Vertical ); cdebug_log(145,0) << "[Create global segment (14.1)]: " << globalSegment1 << endl; cdebug_log(145,0) << "[Create global segment (14.2)]: " << globalSegment2 << endl; @@ -3258,22 +3133,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl; cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; - AutoSegment* globalSegment1 = - AutoSegment::create( vteev, hteeh - , Horizontal::create( vteev->base(), hteeh->base() - , horizontalLayer - , vteev->getY() - , horizontalWidth - ) - ); - AutoSegment* globalSegment2 = - AutoSegment::create( vteev, turn - , Vertical::create( vteev->base(), turn->base() - , verticalLayer - , vteev->getX() - , verticalWidth - ) - ); + AutoSegment* globalSegment1 = AutoSegment::create( vteev, hteeh, Flags::Horizontal ); + AutoSegment* globalSegment2 = AutoSegment::create( vteev, turn, Flags::Vertical ); cdebug_log(145,0) << "[Create global segment (15.1)]: " << globalSegment1 << endl; cdebug_log(145,0) << "[Create global segment (15.2)]: " << globalSegment2 << endl; @@ -3304,22 +3165,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl; cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; - AutoSegment* globalSegment1 = - AutoSegment::create( turn, hteeh - , Horizontal::create( turn->base(), hteeh->base() - , horizontalLayer - , turn->getY() - , horizontalWidth - ) - ); - AutoSegment* globalSegment2 = - AutoSegment::create( vteev, hteeh - , Vertical::create( vteev->base(), hteeh->base() - , verticalLayer - , vteev->getX() - , verticalWidth - ) - ); + AutoSegment* globalSegment1 = AutoSegment::create( turn, hteeh, Flags::Horizontal ); + AutoSegment* globalSegment2 = AutoSegment::create( vteev, hteeh, Flags::Vertical ); cdebug_log(145,0) << "[Create global segment (16.1)]: " << globalSegment1 << endl; cdebug_log(145,0) << "[Create global segment (16.2)]: " << globalSegment2 << endl; @@ -3348,22 +3195,8 @@ namespace { cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl; cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; - AutoSegment* globalSegment1 = - AutoSegment::create( turn, hteeh - , Horizontal::create( turn->base(), hteeh->base() - , horizontalLayer - , turn->getY() - , horizontalWidth - ) - ); - AutoSegment* globalSegment2 = - AutoSegment::create( vteev, turn - , Vertical::create( vteev->base(), turn->base() - , verticalLayer - , vteev->getX() - , verticalWidth - ) - ); + AutoSegment* globalSegment1 = AutoSegment::create( turn, hteeh, Flags::Horizontal ); + AutoSegment* globalSegment2 = AutoSegment::create( vteev, turn, Flags::Vertical ); cdebug_log(145,0) << "[Create global segment (17.1)]: " << globalSegment1 << endl; cdebug_log(145,0) << "[Create global segment (17.2)]: " << globalSegment2 << endl; } diff --git a/anabatic/src/PreRouteds.cpp b/anabatic/src/PreRouteds.cpp index 5602792b..648ca481 100644 --- a/anabatic/src/PreRouteds.cpp +++ b/anabatic/src/PreRouteds.cpp @@ -165,7 +165,7 @@ namespace Anabatic { AutoContact* source = Session::lookup( dynamic_cast( isegment->getSource() )); AutoContact* target = Session::lookup( dynamic_cast( isegment->getTarget() )); AutoSegment* autoSegment = AutoSegment::create( source, target, isegment ); - autoSegment->setFlags( SegUserDefined|SegAxisSet ); + autoSegment->setFlags( AutoSegment::SegUserDefined|AutoSegment::SegAxisSet ); } } } diff --git a/anabatic/src/Session.cpp b/anabatic/src/Session.cpp index b5866b07..9e996b53 100644 --- a/anabatic/src/Session.cpp +++ b/anabatic/src/Session.cpp @@ -156,12 +156,12 @@ namespace Anabatic { cdebug_tabw(145,1); - canonical->setFlags( SegCanonical ); + canonical->setFlags( AutoSegment::SegCanonical ); cdebug_log(145,0) << "Canonical: " << canonical << endl; for ( size_t j=0 ; jisGlobal()) aligneds[j]->setFlags ( SegWeakGlobal ); - else aligneds[j]->unsetFlags( SegWeakGlobal ); + if (isWeakGlobal and not aligneds[j]->isGlobal()) aligneds[j]->setFlags ( AutoSegment::SegWeakGlobal ); + else aligneds[j]->unsetFlags( AutoSegment::SegWeakGlobal ); if (aligneds[j] == canonical) continue; if (aligneds[j]->isCanonical()) { @@ -169,13 +169,12 @@ namespace Anabatic { " Segment is no longer the canonical one, this must not happens." ,getString(aligneds[j]).c_str()) << endl; } - aligneds[j]->unsetFlags( SegCanonical ); + aligneds[j]->unsetFlags( AutoSegment::SegCanonical ); cdebug_log(145,0) << "Secondary: " << aligneds[j] << endl; } - if (aligneds.empty()) canonical->setFlags( SegNotAligned ); + if (aligneds.empty()) canonical->setFlags( AutoSegment::SegNotAligned ); - cdebug_log(149,0) << "Align @" << DbU::getValueString(canonical->getAxis()) - << " on " << canonical << endl; + cdebug_log(149,0) << "Align on canonical:" << canonical << endl; //canonical->setAxis( canonical->getAxis(), Flags::Realignate ); if (canonical->isUnsetAxis()) canonical->toOptimalAxis( Flags::Realignate|Flags::Propagate ); diff --git a/anabatic/src/anabatic/AutoContact.h b/anabatic/src/anabatic/AutoContact.h index 3797c772..9d93b114 100644 --- a/anabatic/src/anabatic/AutoContact.h +++ b/anabatic/src/anabatic/AutoContact.h @@ -61,11 +61,12 @@ namespace Anabatic { , CntVTee = (1 << 4) , CntInvalidated = (1 << 6) , CntInvalidatedCache = (1 << 7) - , CntInCreationStage = (1 << 8) - , CntBadTopology = (1 << 9) - , CntIgnoreAnchor = (1 << 10) - , CntWeakTerminal = (1 << 11) - , CntUserNativeConstraints = (1 << 12) + , CntInvalidatedWidth = (1 << 8) + , CntInCreationStage = (1 << 9) + , CntBadTopology = (1 << 10) + , CntIgnoreAnchor = (1 << 11) + , CntWeakTerminal = (1 << 12) + , CntUserNativeConstraints = (1 << 13) }; class AutoContact { @@ -106,6 +107,7 @@ namespace Anabatic { inline bool isInCreationStage () const; inline bool isInvalidated () const; inline bool isInvalidatedCache () const; + inline bool isInvalidatedWidth () const; inline bool isTerminal () const; inline bool isTurn () const; bool isTee ( Flags direction ) const; @@ -127,6 +129,10 @@ namespace Anabatic { virtual AutoSegment* getOpposite ( const AutoSegment* ) const = 0; virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const = 0; virtual AutoSegment* getSegment ( unsigned int ) const = 0; + virtual AutoHorizontal* getHorizontal1 () const; + virtual AutoHorizontal* getHorizontal2 () const; + virtual AutoVertical* getVertical1 () const; + virtual AutoVertical* getVertical2 () const; void getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const; inline unsigned int getMinDepth () const; inline unsigned int getMaxDepth () const; @@ -147,6 +153,7 @@ namespace Anabatic { virtual void cacheDetach ( AutoSegment* ) = 0; virtual void cacheAttach ( AutoSegment* ) = 0; virtual void updateCache () = 0; + void updateSize (); virtual void updateGeometry () = 0; virtual void updateTopology () = 0; void showTopologyError ( const std::string&, Flags flags=Flags::NoFlags ); @@ -238,6 +245,7 @@ namespace Anabatic { inline bool AutoContact::isInCreationStage () const { return _flags&CntInCreationStage; } inline bool AutoContact::isInvalidated () const { return _flags&CntInvalidated; } inline bool AutoContact::isInvalidatedCache () const { return _flags&CntInvalidatedCache; } + inline bool AutoContact::isInvalidatedWidth () const { return _flags&CntInvalidatedWidth; } inline bool AutoContact::isTurn () const { return _flags&CntTurn; } inline bool AutoContact::isFixed () const { return _flags&CntFixed; } inline bool AutoContact::isUserNativeConstraints () const { return _flags&CntUserNativeConstraints; } diff --git a/anabatic/src/anabatic/AutoContactHTee.h b/anabatic/src/anabatic/AutoContactHTee.h index 590dd179..abc0ea03 100644 --- a/anabatic/src/anabatic/AutoContactHTee.h +++ b/anabatic/src/anabatic/AutoContactHTee.h @@ -41,9 +41,9 @@ namespace Anabatic { virtual ~AutoContactHTee (); virtual void _invalidate ( Flags flags ); public: - inline AutoHorizontal* getHorizontal1 () const; - inline AutoHorizontal* getHorizontal2 () const; - inline AutoVertical* getVertical1 () const; + virtual AutoHorizontal* getHorizontal1 () const; + virtual AutoHorizontal* getHorizontal2 () const; + virtual AutoVertical* getVertical1 () const; virtual AutoSegment* getOpposite ( const AutoSegment* ) const; virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const; virtual AutoSegment* getSegment ( unsigned int ) const; @@ -61,11 +61,6 @@ namespace Anabatic { AutoHorizontal* _horizontal2; AutoVertical* _vertical1; }; - - - inline AutoHorizontal* AutoContactHTee::getHorizontal1 () const { return _horizontal1; }; - inline AutoHorizontal* AutoContactHTee::getHorizontal2 () const { return _horizontal2; }; - inline AutoVertical* AutoContactHTee::getVertical1 () const { return _vertical1; }; } // Anabatic namespace. diff --git a/anabatic/src/anabatic/AutoContactTurn.h b/anabatic/src/anabatic/AutoContactTurn.h index d03aad1d..f95a007d 100644 --- a/anabatic/src/anabatic/AutoContactTurn.h +++ b/anabatic/src/anabatic/AutoContactTurn.h @@ -40,8 +40,8 @@ namespace Anabatic { virtual ~AutoContactTurn (); virtual void _invalidate ( Flags flags ); public: - inline AutoHorizontal* getHorizontal1 () const; - inline AutoVertical* getVertical1 () const; + virtual AutoHorizontal* getHorizontal1 () const; + virtual AutoVertical* getVertical1 () const; virtual AutoSegment* getOpposite ( const AutoSegment* ) const; virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const; virtual AutoSegment* getSegment ( unsigned int ) const; @@ -59,10 +59,6 @@ namespace Anabatic { AutoVertical* _vertical1; }; - - inline AutoHorizontal* AutoContactTurn::getHorizontal1 () const { return _horizontal1; }; - inline AutoVertical* AutoContactTurn::getVertical1 () const { return _vertical1; }; - } // Anabatic namespace. diff --git a/anabatic/src/anabatic/AutoContactVTee.h b/anabatic/src/anabatic/AutoContactVTee.h index 91ce30f8..d7323b24 100644 --- a/anabatic/src/anabatic/AutoContactVTee.h +++ b/anabatic/src/anabatic/AutoContactVTee.h @@ -38,9 +38,9 @@ namespace Anabatic { virtual ~AutoContactVTee (); virtual void _invalidate ( Flags flags ); public: - inline AutoHorizontal* getHorizontal1 () const; - inline AutoVertical* getVertical1 () const; - inline AutoVertical* getVertical2 () const; + virtual AutoHorizontal* getHorizontal1 () const; + virtual AutoVertical* getVertical1 () const; + virtual AutoVertical* getVertical2 () const; virtual AutoSegment* getOpposite ( const AutoSegment* ) const; virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const; virtual AutoSegment* getSegment ( unsigned int ) const; @@ -60,11 +60,6 @@ namespace Anabatic { }; - inline AutoHorizontal* AutoContactVTee::getHorizontal1 () const { return _horizontal1; }; - inline AutoVertical* AutoContactVTee::getVertical1 () const { return _vertical1; }; - inline AutoVertical* AutoContactVTee::getVertical2 () const { return _vertical2; }; - - } // Anabatic namespace. diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index 84b226ce..ba4b07ce 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -60,53 +60,55 @@ namespace Anabatic { // ------------------------------------------------------------------- // Class : "AutoSegment". - enum AutoSegmentFlag { SegNoFlags = 0x0 - , SegHorizontal = (1<< 0) - , SegFixed = (1<< 1) - , SegGlobal = (1<< 2) - , SegWeakGlobal = (1<< 3) - , SegLongLocal = (1<< 4) - , SegCanonical = (1<< 5) - , SegBipoint = (1<< 6) - , SegDogleg = (1<< 7) - , SegStrap = (1<< 8) - , SegSourceTop = (1<< 9) - , SegSourceBottom = (1<<10) - , SegTargetTop = (1<<11) - , SegTargetBottom = (1<<12) - , SegIsReduced = (1<<13) - , SegLayerChange = (1<<14) - , SegSourceTerminal = (1<<15) // Replace Terminal. - , SegTargetTerminal = (1<<16) // Replace Terminal. - , SegStrongTerminal = SegSourceTerminal|SegTargetTerminal - , SegWeakTerminal1 = (1<<17) // Replace TopologicalEnd. - , SegWeakTerminal2 = (1<<18) // Replace TopologicalEnd. - , SegNotSourceAligned = (1<<19) - , SegNotTargetAligned = (1<<20) - , SegUnbound = (1<<21) - , SegHalfSlackened = (1<<22) - , SegSlackened = (1<<23) - , SegAxisSet = (1<<24) - , SegInvalidated = (1<<25) - , SegInvalidatedSource = (1<<26) - , SegInvalidatedTarget = (1<<27) - , SegInvalidatedLayer = (1<<28) - , SegCreated = (1<<29) - , SegUserDefined = (1<<30) - , SegAnalog = (1<<31) - // Masks. - , SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2 - , SegNotAligned = SegNotSourceAligned|SegNotTargetAligned - , SegSpinTop = SegSourceTop |SegTargetTop - , SegSpinBottom = SegSourceBottom |SegTargetBottom - , SegDepthSpin = SegSpinTop |SegSpinBottom - }; class AutoSegment { friend class AutoHorizontal; friend class AutoVertical; + public: + static const uint64_t SegNoFlags = 0L; + static const uint64_t SegHorizontal = (1L<< 0); + static const uint64_t SegFixed = (1L<< 1); + static const uint64_t SegGlobal = (1L<< 2); + static const uint64_t SegWeakGlobal = (1L<< 3); + static const uint64_t SegLongLocal = (1L<< 4); + static const uint64_t SegCanonical = (1L<< 5); + static const uint64_t SegBipoint = (1L<< 6); + static const uint64_t SegDogleg = (1L<< 7); + static const uint64_t SegStrap = (1L<< 8); + static const uint64_t SegSourceTop = (1L<< 9); + static const uint64_t SegSourceBottom = (1L<<10); + static const uint64_t SegTargetTop = (1L<<11); + static const uint64_t SegTargetBottom = (1L<<12); + static const uint64_t SegIsReduced = (1L<<13); + static const uint64_t SegLayerChange = (1L<<14); + static const uint64_t SegSourceTerminal = (1L<<15); // Replace Terminal. + static const uint64_t SegTargetTerminal = (1L<<16); // Replace Terminal. + static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal; + static const uint64_t SegWeakTerminal1 = (1L<<17); // Replace TopologicalEnd. + static const uint64_t SegWeakTerminal2 = (1L<<18); // Replace TopologicalEnd. + static const uint64_t SegNotSourceAligned = (1L<<19); + static const uint64_t SegNotTargetAligned = (1L<<20); + static const uint64_t SegUnbound = (1L<<21); + static const uint64_t SegHalfSlackened = (1L<<22); + static const uint64_t SegSlackened = (1L<<23); + static const uint64_t SegAxisSet = (1L<<24); + static const uint64_t SegInvalidated = (1L<<25); + static const uint64_t SegInvalidatedSource = (1L<<26); + static const uint64_t SegInvalidatedTarget = (1L<<27); + static const uint64_t SegInvalidatedLayer = (1L<<28); + static const uint64_t SegCreated = (1L<<29); + static const uint64_t SegUserDefined = (1L<<30); + static const uint64_t SegAnalog = (1L<<31); + static const uint64_t SegWide = (1L<<32); + // Masks. + static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; + static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; + static const uint64_t SegSpinTop = SegSourceTop |SegTargetTop; + static const uint64_t SegSpinBottom = SegSourceBottom |SegTargetBottom; + static const uint64_t SegDepthSpin = SegSpinTop |SegSpinBottom; + public: class Observable : public StaticObservable<1> { public: @@ -158,6 +160,7 @@ namespace Anabatic { virtual DbU::Unit getX () const; virtual DbU::Unit getY () const; inline DbU::Unit getWidth () const; + inline DbU::Unit getContactWidth () const; inline DbU::Unit getLength () const; inline DbU::Unit getSourcePosition () const; inline DbU::Unit getTargetPosition () const; @@ -204,6 +207,7 @@ namespace Anabatic { bool isReduceCandidate () const; bool isUTurn () const; inline bool isAnalog () const; + inline bool isWide () const; virtual bool _canSlacken () const = 0; bool canReduce () const; bool mustRaise () const; @@ -219,7 +223,7 @@ namespace Anabatic { bool checkDepthSpin () const; // Accessors. inline unsigned long getId () const; - inline uint32_t getFlags () const; + inline uint64_t getFlags () const; virtual Flags getDirection () const = 0; inline GCell* getGCell () const; virtual size_t getGCells ( vector& ) const = 0; @@ -258,9 +262,9 @@ namespace Anabatic { inline AutoSegment* getCanonical ( Interval& i ); float getMaxUnderDensity ( Flags flags ); // Modifiers. - inline void unsetFlags ( uint32_t ); - inline void setFlags ( uint32_t ); - void setFlagsOnAligneds ( uint32_t ); + inline void unsetFlags ( uint64_t ); + inline void setFlags ( uint64_t ); + void setFlagsOnAligneds ( uint64_t ); inline void incReduceds (); inline void decReduceds (); virtual void setDuSource ( DbU::Unit du ) = 0; @@ -345,7 +349,7 @@ namespace Anabatic { // Internal: Attributes. const unsigned long _id; GCell* _gcell; - uint32_t _flags; + uint64_t _flags; unsigned int _depth : 8; unsigned int _optimalMin :16; unsigned int _optimalMax :16; @@ -369,7 +373,7 @@ namespace Anabatic { AutoSegment& operator= ( const AutoSegment& ); protected: void _invalidate (); - inline uint32_t _getFlags () const; + inline uint64_t _getFlags () const; std::string _getStringFlags () const; virtual void _setAxis ( DbU::Unit ) = 0; @@ -390,7 +394,7 @@ namespace Anabatic { // Static Utilities. public: - static inline uint32_t swapSourceTargetFlags ( AutoSegment* ); + static inline uint64_t swapSourceTargetFlags ( AutoSegment* ); static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* ); static AutoSegment* getGlobalThroughDogleg ( AutoSegment* dogleg, AutoContact* from ); static bool isTopologicalBound ( AutoSegment* seed, Flags flags ); @@ -495,11 +499,12 @@ namespace Anabatic { inline bool AutoSegment::isCreated () const { return _flags & SegCreated; } inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; } inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; } - inline void AutoSegment::setFlags ( uint32_t flags ) { _flags |= flags; } - inline void AutoSegment::unsetFlags ( uint32_t flags ) { _flags &= ~flags; } + inline bool AutoSegment::isWide () const { return _flags & SegWide; } + inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; } + inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; } - inline uint32_t AutoSegment::getFlags () const { return _flags; } - inline uint32_t AutoSegment::_getFlags () const { return _flags; } + inline uint64_t AutoSegment::getFlags () const { return _flags; } + inline uint64_t AutoSegment::_getFlags () const { return _flags; } inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; } inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; } inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); } @@ -511,6 +516,11 @@ namespace Anabatic { //inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); } inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); } + + inline DbU::Unit AutoSegment::getContactWidth () const + { return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); } + + inline void AutoSegment::setParent ( AutoSegment* parent ) { if ( parent == this ) { @@ -523,10 +533,10 @@ namespace Anabatic { inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const { return lhs->getId() < rhs->getId(); } - inline uint32_t AutoSegment::swapSourceTargetFlags ( AutoSegment* segment ) + inline uint64_t AutoSegment::swapSourceTargetFlags ( AutoSegment* segment ) { - uint32_t segFlags = segment->getFlags(); - uint32_t swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop + uint64_t segFlags = segment->getFlags(); + uint64_t swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop |SegSourceBottom |SegTargetBottom |SegSourceTerminal |SegTargetTerminal |SegNotSourceAligned |SegNotTargetAligned diff --git a/crlcore/src/ccore/RoutingLayerGauge.cpp b/crlcore/src/ccore/RoutingLayerGauge.cpp index 4adcf253..73192649 100644 --- a/crlcore/src/ccore/RoutingLayerGauge.cpp +++ b/crlcore/src/ccore/RoutingLayerGauge.cpp @@ -210,13 +210,13 @@ namespace CRL { cdebug_log(100,1) << "RoutingLayerGauge::getTrackIndex ( " << position << " )" << endl; long modulo; - long depth; + long index; - divide ( position-start, depth, modulo ); + divide ( position-start, index, modulo ); - cdebug_log(100,0) << "depth := " << depth << endl; + cdebug_log(100,0) << "index := " << index << endl; - if ( depth < 0 ) { + if ( index < 0 ) { cdebug_tabw(100,-1); return 0; @@ -232,13 +232,13 @@ namespace CRL { throw Error ( badExactPosition, getString(this).c_str(), DbU::getValueString(position).c_str() ); if ( mode & Constant::Superior ) { - if ( modulo != 0 ) depth++; + if ( modulo != 0 ) index++; } else if ( mode & Constant::Nearest ) { - if ( modulo > _pitch / 2 ) depth++; + if ( modulo > _pitch / 2 ) index++; } unsigned int tracksNumber = getTrackNumber(start,stop); - if ( (unsigned)depth >= tracksNumber ) { + if ( (unsigned)index >= tracksNumber ) { cdebug_tabw(100,-1); return (tracksNumber > 0) ? tracksNumber-1 : 0; // throw Error ( overflowIndex @@ -251,7 +251,7 @@ namespace CRL { cdebug_tabw(100,-1); - return depth; + return index; } diff --git a/katana/src/DataNegociate.cpp b/katana/src/DataNegociate.cpp index ead77203..4de6d02c 100644 --- a/katana/src/DataNegociate.cpp +++ b/katana/src/DataNegociate.cpp @@ -130,7 +130,7 @@ namespace Katana { } if (RoutingEvent::getStage() == RoutingEvent::Repair) - perpandicular->base()->setFlagsOnAligneds( Anabatic::SegUnbound ); + perpandicular->base()->setFlagsOnAligneds( AutoSegment::SegUnbound ); //cerr << "perpandicular:" << perpandicular << endl; //cerr << " " << interval << endl; diff --git a/katana/src/DataSymmetric.cpp b/katana/src/DataSymmetric.cpp index aaf69f69..c8daa657 100644 --- a/katana/src/DataSymmetric.cpp +++ b/katana/src/DataSymmetric.cpp @@ -77,7 +77,7 @@ namespace { namespace Katana { using namespace std; - using Anabatic::AutoSegmentFlag; + using Anabatic::AutoSegment; DataSymmetric* DataSymmetric::create ( Net* net ) @@ -122,7 +122,7 @@ namespace Katana { bool DataSymmetric::checkPairing () { - const uint32_t mask = ~(AutoSegmentFlag::SegIsReduced); + const uint64_t mask = ~(AutoSegment::SegIsReduced); Message errors ( 0, "[ERROR]" ); // Temporary hardwired: M2 (depth 1) for H pitch, M3 (depth 2) for V pitch. diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index ad0a459c..6b1db674 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -620,11 +620,45 @@ namespace Katana { } - bool Manipulator::insertInTrack ( size_t itrack ) + bool Manipulator::insertInTrack ( size_t icost ) { - Track* track = _fsm.getTrack(itrack); - size_t begin = _fsm.getBegin(itrack); - size_t end = _fsm.getEnd (itrack); + cdebug_log(159,1) << "Manipulator::insertInTrack(size_t)" << endl; + cdebug_log(159,0) << _segment << endl; + + bool success = true; + + for ( size_t itrack=0 ; success and (itrack<_segment->getTrackSpan()) ; ++itrack ) { + success = success and _insertInTrack( icost, itrack ); + } + + if (success) { + cdebug_log(159,0) << "Manipulator::insertInTrack() success" << endl; + + _fsm.setState ( SegmentFsm::OtherRipup ); + _fsm.addAction( _segment + , SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4 + , _fsm.getTrack1(icost)->getAxis() ); + +#if THIS_IS_DISABLED + uint32_t flags = 0; + if (rightIntrication) flags |= RightAxisHint; + if (leftIntrication ) flags |= LeftAxisHint; + if (flags) + Manipulator( _segment, _fsm ).shrinkToTrack( icost, flags, leftAxisHint, rightAxisHint ); +#endif + } else + _fsm.clearActions(); + + cdebug_tabw(159,-1); + return success; + } + + + bool Manipulator::_insertInTrack ( size_t icost, size_t itrack ) + { + Track* track = _fsm.getTrack(icost,itrack); + size_t begin = _fsm.getBegin(icost,itrack); + size_t end = _fsm.getEnd (icost,itrack); Net* ownerNet = _segment->getNet(); Interval toFree (_segment->getCanonicalInterval()); //Net* ripupNet = NULL; @@ -635,10 +669,10 @@ namespace Katana { bool rightIntrication = false; bool success = true; - cdebug_log(159,1) << "Manipulator::insertInTrack(size_t) - " << toFree << endl; + cdebug_log(159,1) << "Manipulator::_insertInTrack(size_t) - " << toFree << endl; cdebug_log(159,0) << _segment << endl; - for ( size_t i = begin ; success && (i < end) ; i++ ) { + for ( size_t i = begin ; success and (i < end) ; i++ ) { TrackElement* segment2 = track->getSegment(i); cdebug_log(159,0) << "* Looking // " << segment2 << endl; @@ -772,42 +806,49 @@ namespace Katana { break; } } - if ( not success ) break; } - if ( success ) { - cdebug_log(159,0) << "Manipulator::insertInTrack() success" << endl; - - _fsm.setState ( SegmentFsm::OtherRipup ); - _fsm.addAction( _segment - , SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4 - , _fsm.getTrack1(itrack)->getAxis() ); - - uint32_t flags = 0; - if ( rightIntrication ) flags |= RightAxisHint; - if ( leftIntrication ) flags |= LeftAxisHint; - if ( flags ) - Manipulator(_segment,_fsm).shrinkToTrack(itrack,flags,leftAxisHint,rightAxisHint); - } else - _fsm.clearActions (); - cdebug_tabw(159,-1); return success; } - bool Manipulator::forceToTrack ( size_t itrack ) + bool Manipulator::forceToTrack ( size_t icost ) { - Track* track = _fsm.getTrack(itrack); - size_t begin = _fsm.getBegin(itrack); - size_t end = _fsm.getEnd (itrack); + cdebug_log(159,1) << "Manipulator::forceToTrack(size_t)" << endl; + cdebug_log(159,0) << _segment << endl; + + bool success = true; + + for ( size_t itrack=0 ; success and (itrack<_segment->getTrackSpan()) ; ++itrack ) { + success = success and _forceToTrack( icost, itrack ); + } + + if (success) { + _fsm.setState ( SegmentFsm::OtherRipup ); + _fsm.addAction( _segment + , SegmentAction::SelfInsert|SegmentAction::MoveToAxis + , _fsm.getTrack(icost)->getAxis() ); + } else + _fsm.clearActions(); + + cdebug_tabw(159,-1); + return success; + } + + + bool Manipulator::_forceToTrack ( size_t icost, size_t itrack ) + { + Track* track = _fsm.getTrack(icost,itrack); + size_t begin = _fsm.getBegin(icost,itrack); + size_t end = _fsm.getEnd (icost,itrack); Net* ownerNet = _segment->getNet(); Interval toFree (_segment->getCanonicalInterval()); //Net* ripupNet = NULL; set canonicals; bool success = true; - cdebug_log(159,1) << "Manipulator::forceToTrack(size_t) - " << toFree << endl; + cdebug_log(159,1) << "Manipulator::_forceToTrack(size_t) - " << toFree << endl; for ( size_t i=begin ; success and (i < end) ; ++i ) { TrackElement* segment2 = track->getSegment(i); @@ -846,11 +887,20 @@ namespace Katana { } } - if (success) { - _fsm.setState ( SegmentFsm::OtherRipup ); - _fsm.addAction( _segment - , SegmentAction::SelfInsert|SegmentAction::MoveToAxis - , _fsm.getTrack(itrack)->getAxis() ); + cdebug_tabw(159,-1); + return success; + } + + + bool Manipulator::shrinkToTrack ( size_t icost, uint32_t flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint ) + { + cdebug_log(159,1) << "Manipulator::shrinkToTrack(size_t)" << endl; + cdebug_log(159,0) << _segment << endl; + + bool success = true; + + for ( size_t itrack=0 ; success and (itrack<_segment->getTrackSpan()) ; ++itrack ) { + success = success and _shrinkToTrack( icost, itrack, flags, leftAxisHint, rightAxisHint ); } cdebug_tabw(159,-1); @@ -858,12 +908,12 @@ namespace Katana { } - bool Manipulator::shrinkToTrack ( size_t i, uint32_t flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint ) + bool Manipulator::_shrinkToTrack ( size_t icost, size_t itrack, uint32_t flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint ) { #if THIS_IS_DISABLED - Track* track = _fsm.getTrack(i); - size_t begin = _fsm.getBegin(i); - size_t end = _fsm.getEnd (i); + Track* track = _fsm.getTrack(icost,itrack); + size_t begin = _fsm.getBegin(icost,itrack); + size_t end = _fsm.getEnd (icost,itrack); Net* ownerNet = _segment->getNet(); set canonicals; bool success = true; diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 88713fce..2c684748 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -186,6 +186,7 @@ namespace Katana { using CRL::Histogram; using CRL::addMeasure; using Anabatic::AutoContact; + using Anabatic::AutoSegment; using Anabatic::AutoSegmentLut; using Anabatic::perpandicularTo; @@ -322,7 +323,7 @@ namespace Katana { cdebug_log(159,0) << "* " << plane << endl; cdebug_log(159,0) << "* " << track << endl; - trackSegment->setAxis( track->getAxis(), Anabatic::SegAxisSet ); + trackSegment->setAxis( track->getAxis(), AutoSegment::SegAxisSet ); trackSegment->invalidate(); if (trackSegment->isFixed()) { diff --git a/katana/src/PreProcess.cpp b/katana/src/PreProcess.cpp index b2891273..03f1972c 100644 --- a/katana/src/PreProcess.cpp +++ b/katana/src/PreProcess.cpp @@ -39,6 +39,7 @@ namespace { using namespace CRL; using namespace Katana; using Anabatic::perpandicularTo; + using Anabatic::AutoSegment; using Anabatic::AutoContactTerminal; @@ -99,15 +100,15 @@ namespace { cdebug_log(159,0) << "Propagate caging: " << segment << endl; - Track* track = segment->getTrack(); - //Flags direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer()); - Flags direction = segment->getDirection(); + Track* track = segment->getTrack(); + //Flags direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer()); + Flags direction = segment->getDirection(); Anabatic::AutoContact* source = segment->base()->getAutoSource(); - RoutingPad* rp = NULL; - Interval uside = source->getGCell()->getSide(direction); - DbU::Unit minConstraint = DbU::Min; - DbU::Unit maxConstraint = DbU::Max; - vector perpandiculars; + RoutingPad* rp = NULL; + Interval uside = source->getGCell()->getSide(direction); + DbU::Unit minConstraint = DbU::Min; + DbU::Unit maxConstraint = DbU::Max; + vector perpandiculars; if ( not track ) { cerr << Bug( "%s is not inserted in a ", getString(segment).c_str() ) << endl; @@ -116,7 +117,7 @@ namespace { // Computing constraints from fixed only TrackElements (caging). TrackElement* parallel; - size_t i = segment->getIndex(); + size_t i = track->find( segment ); while ( i > 0 ) { parallel = track->getSegment( --i ); if (not parallel) continue; @@ -128,7 +129,7 @@ namespace { minConstraint = max( minConstraint, parallel->getTargetU() ); } - i = segment->getIndex(); + i = track->find( segment ); while ( i < track->getSize()-1 ) { parallel = track->getSegment( ++i ); if (not parallel) continue; @@ -308,7 +309,7 @@ namespace { target->setFlags( Anabatic::CntIgnoreAnchor ); AutoSegment* fixedSegment = AutoSegment::create( source, target, Flags::Vertical ); - fixedSegment->setFlags( Anabatic::SegFixed ); + fixedSegment->setFlags( AutoSegment::SegFixed ); Session::getNegociateWindow()->createTrackSegment( fixedSegment, Flags::LoadingStage ); } diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index 1bb6c676..d795ed04 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -58,6 +58,7 @@ namespace Katana { using Hurricane::Net; using Hurricane::Layer; using Anabatic::GCell; + using Anabatic::AutoSegment; // ------------------------------------------------------------------- @@ -95,8 +96,8 @@ namespace Katana { if (lhs._length > rhs._length) return false; if (lhs._length < rhs._length) return true; - if ((lhs._segFlags & Anabatic::SegHorizontal) xor (rhs._segFlags & Anabatic::SegHorizontal)) - return (rhs._segFlags & Anabatic::SegHorizontal); + if ((lhs._segFlags & AutoSegment::SegHorizontal) xor (rhs._segFlags & AutoSegment::SegHorizontal)) + return (rhs._segFlags & AutoSegment::SegHorizontal); if (lhs._axis > rhs._axis) return true; if (lhs._axis < rhs._axis) return false; diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index b0a14db7..4bb3700e 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -546,10 +546,20 @@ namespace Katana { Track* track2 = NULL; if (_event2) { track2 = - (_sameAxis) ? track1 : plane->getTrackByPosition( symData->getSymmetrical( track1->getAxis() ) ); + (_sameAxis) ? track1 : plane->getTrackByPosition + ( segment2->getSymmetricAxis( symData->getSymmetrical( track1->getAxis() ) ) ); + + cdebug_log(155,0) << "refTrack:" << track1 << endl; + cdebug_log(155,0) << "symTrack:" << track2 << endl; + cdebug_log(155,0) << "by symData: " << DbU::getValueString( symData->getSymmetrical(track1->getAxis()) ) << endl; + cdebug_log(155,0) << "plus segment2:" << DbU::getValueString( segment2->getSymmetricAxis(symData->getSymmetrical(track1->getAxis())) ) << endl; } _costs.push_back( new TrackCost(segment1,segment2,track1,track2) ); + + cdebug_log(155,0) << "AxisWeight:" << DbU::getValueString(_costs.back()->getTrack()->getAxis()) + << " sum:" << DbU::getValueString(_costs.back()->getAxisWeight()) + << endl; if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) ) _fullBlocked = false; diff --git a/katana/src/Session.cpp b/katana/src/Session.cpp index fe6df948..1493acf8 100644 --- a/katana/src/Session.cpp +++ b/katana/src/Session.cpp @@ -140,9 +140,7 @@ namespace Katana { for ( size_t i=0 ; i<_removeEvents.size() ; ++i ) { if (not _removeEvents[i]._segment->getTrack()) continue; - - packTracks.insert( _removeEvents[i]._segment->getTrack() ); - _removeEvents[i]._segment->detach(); + _removeEvents[i]._segment->detach( packTracks ); } _removeEvents.clear(); diff --git a/katana/src/SymmetricRoute.cpp b/katana/src/SymmetricRoute.cpp index aa7afd2f..b02ba171 100644 --- a/katana/src/SymmetricRoute.cpp +++ b/katana/src/SymmetricRoute.cpp @@ -49,7 +49,6 @@ namespace { using Anabatic::AutoContact; using Anabatic::AutoContactTerminal; using Anabatic::AutoSegment; - using Anabatic::AutoSegmentFlag; using Katana::TrackElement; using Katana::DataSymmetric; using Katana::KatanaEngine; diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 1e548f1d..237308fb 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -94,7 +94,11 @@ namespace Katana { cdebug_log(155,1) << "Track::_preDestroy() - " << (void*)this << " " << this << endl; for ( size_t i=0 ; i<_segments.size() ; i++ ) - if (_segments[i]) { _segments[i]->detach(); _segments[i]->destroy(); } + if (_segments[i]) { + _segments[i]->detach(); + if (not _segments[i]->getTrackCount()) + _segments[i]->destroy(); + } for ( size_t i=0 ; i<_markers.size() ; i++ ) if (_markers[i]) _markers[i]->destroy(); @@ -105,10 +109,12 @@ namespace Katana { void Track::destroy () { - cdebug_log(155,0) << "Track::destroy() - " << (void*)this << " " << this << endl; + cdebug_log(155,1) << "Track::destroy() - " << (void*)this << " " << this << endl; Track::_preDestroy(); delete this; + + cdebug_tabw(155,-1); } @@ -445,7 +451,7 @@ namespace Katana { { // cdebug_log(9000,0) << "Deter| Track::insert() " << getLayer()->getName() // << " @" << DbU::getValueString(getAxis()) << " " << segment << endl; - cdebug_log(155,0) << "Track::insert() " << getLayer()->getName() + cdebug_log(155,1) << "Track::insert() " << getLayer()->getName() << " @" << DbU::getValueString(getAxis()) << " " << segment << endl; if ( (getLayer()->getMask() != segment->getLayer()->getMask()) @@ -454,11 +460,22 @@ namespace Katana { ,getString(segment).c_str()) << endl; } - _segments.push_back ( segment ); + _segments.push_back( segment ); _segmentsValid = false; - //segment->setAxis ( getAxis() ); + if (segment->isWide()) { + cdebug_log(155,0) << "Segment is wide." << endl; + Track* wtrack = getNextTrack(); + for ( size_t i=1 ; wtrack and (igetTrackSpan()) ; ++i ) { + cdebug_log(155,0) << "Insert in [" << i << "] " << wtrack << endl; + wtrack->_segments.push_back ( segment ); + wtrack->_segmentsValid = false; + wtrack = wtrack->getNextTrack(); + } + } + segment->setTrack ( this ); + cdebug_tabw(155,-1); } @@ -497,12 +514,6 @@ namespace Katana { << _segments[i]->getTrack() << endl; coherency = false; } - if (_segments[i]->getIndex() != i) { - cerr << "[CHECK] incoherency at " << i << " " - << _segments[i] << " has bad index " - << _segments[i]->getIndex() << endl; - coherency = false; - } } if (_segments[i]->getAxis() != getAxis()) { cerr << "[CHECK] incoherency at " << i << " " @@ -642,9 +653,6 @@ namespace Katana { if (not _segmentsValid) { std::sort( _segments.begin(), _segments.end(), SegmentCompare() ); - for ( size_t i=0 ; i < _segments.size() ; i++ ) { - _segments[i]->setIndex( i ); - } _segmentsValid = true; } diff --git a/katana/src/TrackCost.cpp b/katana/src/TrackCost.cpp index 991a00dc..cdad0c39 100644 --- a/katana/src/TrackCost.cpp +++ b/katana/src/TrackCost.cpp @@ -39,7 +39,7 @@ namespace Katana { , Track* symTrack ) : _flags ((symSegment) ? Symmetric : NoFlags) - , _span (1) + , _span (refSegment->getTrackSpan()) , _tracks ( _span * ((symSegment) ? 2 : 1) , std::tuple(NULL,Track::npos,Track::npos) ) , _segment1 (refSegment) @@ -227,25 +227,25 @@ namespace Katana { { string s = "<" + _getTypeName(); - s += " " + getString(getTrack(0)); - s += " " + getString(_dataState); - s += "+" + getString(_ripupCount); - s += ":" + getString((_dataState<<2)+_ripupCount); - s += " " + string ( (isInfinite() )?"I":"-" ); - s += string ( (isBlockage() )?"b":"-" ); - s += string ( (isFixed() )?"f":"-" ); - s += string ( (isHardOverlap() )?"h":"-" ); - s += string ( (isOverlap() )?"o":"-" ); - s += string ( (isOverlapGlobal() )?"g":"-" ); - s += string ( (isGlobalEnclosed())?"e":"-" ); - s += " " + getString(_terminals); - s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta); - s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared); - s += "/" + DbU::getValueString(_axisWeight); - s += "/" + DbU::getValueString(_deltaPerpand); - s += "/f:" + DbU::getValueString(_distanceToFixed); - s += "/" + DbU::getValueString(_longuestOverlap); - s += " " + getString(_dataState); + s += " " + getString(getTrack(0)); + s += " " + getString(_dataState); + s += "+" + getString(_ripupCount); + s += ":" + getString((_dataState<<2)+_ripupCount); + s += " " + string ( (isInfinite() )?"I":"-" ); + s += string ( (isBlockage() )?"b":"-" ); + s += string ( (isFixed() )?"f":"-" ); + s += string ( (isHardOverlap() )?"h":"-" ); + s += string ( (isOverlap() )?"o":"-" ); + s += string ( (isOverlapGlobal() )?"g":"-" ); + s += string ( (isGlobalEnclosed())?"e":"-" ); + s += " " + getString(_terminals); + s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta); + s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared); + s += "/aw:" + DbU::getValueString(_axisWeight); + s += "/dp:" + DbU::getValueString(_deltaPerpand); + s += "/df:" + DbU::getValueString(_distanceToFixed); + s += "/ov:" + DbU::getValueString(_longuestOverlap); + s += " " + getString(_dataState); s += ">"; return s; diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index 7d896f6d..f67f9122 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -145,6 +145,7 @@ namespace Katana { bool TrackElement::isUTurn () const { return false; } bool TrackElement::isUserDefined () const { return false; } bool TrackElement::isAnalog () const { return false; } + bool TrackElement::isWide () const { return false; } // Predicates. bool TrackElement::hasSymmetric () const { return false; } bool TrackElement::canSlacken () const { return false; } @@ -157,6 +158,7 @@ namespace Katana { // Accessors. unsigned long TrackElement::getId () const { return 0; } unsigned long TrackElement::getFreedomDegree () const { return 0; } + uint32_t TrackElement::getTrackCount () const { return 0; } DbU::Unit TrackElement::getPitch () const { return 0; } DbU::Unit TrackElement::getPPitch () const { return 0; } float TrackElement::getMaxUnderDensity ( Flags ) const { return 0.0; }; @@ -172,6 +174,7 @@ namespace Katana { TrackElement* TrackElement::getTargetDogleg () { return NULL; } TrackElement* TrackElement::getSymmetric () { return NULL; } // Mutators. + void TrackElement::addTrackCount ( int32_t ) { } void TrackElement::setTrack ( Track* track ) { _track = track; } void TrackElement::setSymmetric ( TrackElement* ) { } void TrackElement::updateFreedomDegree () { } @@ -179,6 +182,7 @@ namespace Katana { void TrackElement::swapTrack ( TrackElement* ) { } void TrackElement::reschedule ( uint32_t ) { } void TrackElement::detach () { } + void TrackElement::detach ( set& ) { } void TrackElement::revalidate () { } void TrackElement::updatePPitch () { } void TrackElement::setAxis ( DbU::Unit, uint32_t flags ) { } @@ -199,7 +203,6 @@ namespace Katana { TrackElement::TrackElement ( Track* track ) : _flags (0) , _track (track) - , _index ((size_t)-1) , _sourceU (0) , _targetU (0) , _observer(this) @@ -227,14 +230,14 @@ namespace Katana { TrackElement* TrackElement::getNext () const { - size_t dummy = _index; + size_t dummy = _track->find( this ); return _track->getNext( dummy, getNet() ); } TrackElement* TrackElement::getPrevious () const { - size_t dummy = _index; + size_t dummy = _track->find( this ); return _track->getPrevious( dummy, getNet() ); } @@ -243,8 +246,8 @@ namespace Katana { { if (not _track) return Interval(false); - size_t begin = _index; - size_t end = _index; + size_t begin = _track->find( this ); + size_t end = begin; return _track->expandFreeInterval( begin, end, Track::InsideElement, getNet() ); } @@ -276,7 +279,6 @@ namespace Katana { Record* record = new Record( _getString() ); record->add( getSlot( "_flags", _track ) ); record->add( getSlot( "_track", _track ) ); - record->add( getSlot( "_index", _index ) ); record->add( DbU::getValueSlot( "_sourceU", &_sourceU ) ); record->add( DbU::getValueSlot( "_targetU", &_targetU ) ); diff --git a/katana/src/TrackFixedSegment.cpp b/katana/src/TrackFixedSegment.cpp index 8201d250..01985100 100644 --- a/katana/src/TrackFixedSegment.cpp +++ b/katana/src/TrackFixedSegment.cpp @@ -138,6 +138,7 @@ namespace Katana { bool TrackFixedSegment::isFixed () const { return true; } bool TrackFixedSegment::isPriorityLocked () const { return false; } Flags TrackFixedSegment::getDirection () const { return getTrack()->getDirection(); } + DbU::Unit TrackFixedSegment::getWidth () const { return _segment->getWidth(); } const Layer* TrackFixedSegment::getLayer () const { return _segment->getLayer(); } Interval TrackFixedSegment::getFreeInterval () const { return Interval(); } size_t TrackFixedSegment::getTrackSpan () const { return 1; } @@ -161,14 +162,14 @@ namespace Katana { TrackElement* TrackFixedSegment::getNext () const { - size_t dummy = _index; + size_t dummy = _track->find( this ); return _track->getNext( dummy, getNet() ); } TrackElement* TrackFixedSegment::getPrevious () const { - size_t dummy = _index; + size_t dummy = _track->find( this ); return _track->getPrevious( dummy, getNet() ); } @@ -212,7 +213,6 @@ namespace Katana { string s2 = " [" + DbU::getValueString(_sourceU) + ":" + DbU::getValueString(_targetU) + "]" + " " + DbU::getValueString(_targetU-_sourceU) - + " [" + ((_track) ? getString(_index) : "npos") + "] " + "F" + ((isBlockage()) ? "B" : "-"); s1.insert ( s1.size()-1, s2 ); diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index dc54a625..5f359d93 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -26,6 +26,7 @@ #include "anabatic/GCell.h" #include "crlcore/RoutingGauge.h" #include "katana/DataNegociate.h" +#include "katana/RoutingPlane.h" #include "katana/TrackSegmentRegular.h" #include "katana/TrackSegmentWide.h" #include "katana/Track.h" @@ -46,7 +47,7 @@ namespace Katana { using Hurricane::Net; using Hurricane::Name; using Hurricane::RoutingPad; - using Anabatic::SegSlackened; + using Anabatic::AutoSegment; using Anabatic::perpandicularTo; // ------------------------------------------------------------------- @@ -133,20 +134,15 @@ namespace Katana { DbU::Unit defaultWireWidth = Session::getWireWidth( segment->base()->getLayer() ); TrackElement* trackElement = Session::lookup( segment->base() ); if (not trackElement) { - if (segment->base()->getWidth() <= defaultWireWidth) { + if (segment->base()->getWidth() <= defaultWireWidth) trackElement = new TrackSegmentRegular( segment, track ); - trackElement->_postCreate(); - created = true; - - trackElement->invalidate(); + else + trackElement = new TrackSegmentWide ( segment, track ); - cdebug_log(159,0) << "TrackSegment::create(): " << trackElement << endl; - } else { - throw Error( "TrackSegment::create() Non-regular TrackSegment are not supported yet.\n" - " (on: %s)" - , getString(segment).c_str() - ); - } + trackElement->_postCreate(); + trackElement->invalidate(); + created = true; + cdebug_log(159,0) << "TrackSegment::create(): " << trackElement << endl; } return trackElement; @@ -172,6 +168,7 @@ namespace Katana { bool TrackSegment::isUserDefined () const { return _base->isUserDefined(); } bool TrackSegment::isUTurn () const { return _base->isUTurn(); } bool TrackSegment::isAnalog () const { return _base->isAnalog(); } + bool TrackSegment::isWide () const { return _base->isWide(); } bool TrackSegment::isPriorityLocked () const { return _flags & PriorityLocked; } // Predicates. bool TrackSegment::hasSymmetric () const { return _symmetric != NULL; } @@ -179,6 +176,7 @@ namespace Katana { unsigned long TrackSegment::getId () const { return _base->getId(); } Flags TrackSegment::getDirection () const { return _base->getDirection(); } Net* TrackSegment::getNet () const { return _base->getNet(); } + DbU::Unit TrackSegment::getWidth () const { return _base->getWidth(); } const Layer* TrackSegment::getLayer () const { return _base->getLayer(); } DbU::Unit TrackSegment::getPitch () const { return _base->getPitch(); } DbU::Unit TrackSegment::getPPitch () const { return _ppitch; } @@ -206,14 +204,14 @@ namespace Katana { TrackElement* TrackSegment::getNext () const { - size_t dummy = _index; + size_t dummy = _track->find( this ); return _track->getNext( dummy, getNet() ); } TrackElement* TrackSegment::getPrevious () const { - size_t dummy = _index; + size_t dummy = _track->find( this ); return _track->getPrevious( dummy, getNet() ); } @@ -232,8 +230,8 @@ namespace Katana { { if (not _track) return Interval(false); - size_t begin = _index; - size_t end = _index; + size_t begin = _track->find( this ); + size_t end = begin; return _track->expandFreeInterval( begin, end, Track::InsideElement, getNet() ); } @@ -365,7 +363,18 @@ namespace Katana { void TrackSegment::setTrack ( Track* track ) { - if (track) setAxis( track->getAxis(), Anabatic::SegAxisSet ); + if (track) { + DbU::Unit axis = track->getAxis(); + if (getTrackSpan() > 1) { + DbU::Unit pitch = track->getRoutingPlane()->getLayerGauge()->getPitch(); + axis += (pitch * (getTrackSpan() - 1)) / 2; + + cdebug_log(155,0) << "TrackSegment::setTrack(): pitch:" << DbU::getValueString(pitch) + << " trackSpan:" << getTrackSpan() << endl; + } + addTrackCount( getTrackSpan() ); + setAxis( axis, AutoSegment::SegAxisSet ); + } TrackElement::setTrack( track ); } @@ -379,8 +388,23 @@ namespace Katana { cdebug_log(159,0) << "TrackSegment::detach() - " << endl; setTrack( NULL ); - setIndex( (size_t)-1 ); setFlags( TElemLocked ); + addTrackCount( -1 ); + } + + + void TrackSegment::detach ( set& removeds ) + { + cdebug_log(159,0) << "TrackSegment::detach(set&) - " << endl; + + Track* wtrack = getTrack(); + for ( size_t i=0 ; wtrack and (igetNextTrack(); + } + + detach(); } @@ -409,10 +433,10 @@ namespace Katana { cdebug_log(159,0) << "TrackSegment::swapTrack()" << endl; - size_t thisIndex = getIndex (); - Track* thisTrack = getTrack (); - size_t otherIndex = other->getIndex (); - Track* otherTrack = other->getTrack (); + Track* thisTrack = getTrack(); + Track* otherTrack = other->getTrack(); + size_t thisIndex = ( thisTrack) ? thisTrack->find( this) : Track::npos; + size_t otherIndex = (otherTrack) ? otherTrack->find(other) : Track::npos; if (_track and otherTrack and (_track != otherTrack)) { cerr << Error("TrackSegment::swapTrack() - swapping TrackSegments from different tracks.") << endl; @@ -422,12 +446,10 @@ namespace Katana { other->setTrack( NULL ); other->setTrack( thisTrack ); - other->setIndex( thisIndex ); if (thisTrack) thisTrack->setSegment( other, thisIndex ); setTrack( otherTrack ); - setIndex( otherIndex ); - if (_track) _track->setSegment( this, _index ); + if (_track) _track->setSegment( this, otherIndex ); #if defined(CHECK_DATABASE_DISABLED) if (_track) _track->_check(); @@ -964,7 +986,6 @@ namespace Katana { + ":" + DbU::getValueString(_targetU) + "]" + " " + DbU::getValueString(_targetU-_sourceU) + " " + getString(_dogLegLevel) - + " [" + ((_track) ? getString(_index) : "npos") + "] " + ((isRouted() ) ? "R" : "-") + ((isSlackened() ) ? "S" : "-") + ((_track ) ? "T" : "-") diff --git a/katana/src/TrackSegmentRegular.cpp b/katana/src/TrackSegmentRegular.cpp index 0a64bdcf..4292c70f 100644 --- a/katana/src/TrackSegmentRegular.cpp +++ b/katana/src/TrackSegmentRegular.cpp @@ -44,7 +44,7 @@ namespace Katana { using Hurricane::Net; using Hurricane::Name; using Hurricane::RoutingPad; - using Anabatic::SegSlackened; + using Anabatic::AutoSegment; using Anabatic::perpandicularTo; // ------------------------------------------------------------------- diff --git a/katana/src/TrackSegmentWide.cpp b/katana/src/TrackSegmentWide.cpp index 74304d16..fc09fc05 100644 --- a/katana/src/TrackSegmentWide.cpp +++ b/katana/src/TrackSegmentWide.cpp @@ -44,7 +44,7 @@ namespace Katana { using Hurricane::Net; using Hurricane::Name; using Hurricane::RoutingPad; - using Anabatic::SegSlackened; + using Anabatic::AutoSegment; using Anabatic::perpandicularTo; @@ -54,7 +54,8 @@ namespace Katana { TrackSegmentWide::TrackSegmentWide ( AutoSegment* segment, Track* track, size_t trackSpan ) : Super(segment,track) - , _trackSpan(trackSpan) + , _trackSpan (trackSpan) + , _trackCount(0) { cdebug_log(155,0) << "CTOR TrackSegmentWide " << (void*)this << ":" << this << endl; cdebug_log(155,0) << " over " << (void*)segment << ":" << segment << endl; @@ -64,7 +65,10 @@ namespace Katana { if (segment->getWidth() < mWidth) { _trackSpan = 1; } else { - _trackSpan = ((segment->getWidth() - mWidth) / Session::getPitch(segment->getLayer())) + 2; + DbU::Unit pitch = Session::getPitch(segment->getLayer()); + DbU::Unit width = segment->getWidth() - mWidth; + + _trackSpan = (size_t)(width/pitch) + 1 + ((width%pitch) ? 1 : 0); } } } @@ -87,7 +91,18 @@ namespace Katana { } - size_t TrackSegmentWide::getTrackSpan () const { return _trackSpan; } + size_t TrackSegmentWide::getTrackSpan () const { return _trackSpan; } + uint32_t TrackSegmentWide::getTrackCount () const { return _trackCount; } + + + void TrackSegmentWide::addTrackCount ( int32_t count ) + { + if (count > 0) _trackCount += count; + else { + if (-count > (int32_t)_trackCount) _trackCount = 0; + _trackCount -= -count; + } + } void TrackSegmentWide::addOverlapCost ( TrackCost& cost ) const @@ -100,21 +115,29 @@ namespace Katana { cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 ); cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 ); + cost.setDistanceToFixed(); + cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight( track->getAxis() ) ); + cost.incDeltaPerpand( getDataNegociate()->getWiringDelta( track->getAxis() ) ); + + cdebug_log(155,0) << "incAxisWeight:" << DbU::getValueString(track->getAxis()) + << " of " << DbU::getValueString(getDataNegociate()->getRoutingEvent()->getAxisWeight( track->getAxis() )) + << " (sum:" << DbU::getValueString(cost.getAxisWeight()) << ")" + << endl; for ( size_t span=0 ; (span < _trackSpan) and (track != NULL) ; ++span ) { track->addOverlapCost( cost ); // Todo: have to choose here wether we go *next* or *previous* according // to the symmetry kind. track = track->getNextTrack(); - } + cost.selectNextTrack(); + } - cost.setDistanceToFixed(); - cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) ); - cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) ); if (isGlobal()) cost.setForGlobal(); if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) ) cost.setInfinite(); + + cost.select( 0, TrackCost::NoFlags ); } diff --git a/katana/src/Tracks.cpp b/katana/src/Tracks.cpp index 30ed89c0..8773ebb8 100644 --- a/katana/src/Tracks.cpp +++ b/katana/src/Tracks.cpp @@ -77,6 +77,8 @@ namespace Katana { void Tracks_Range::Locator::progress () { + cdebug_log(155,0) << "Tracks_Range::Locator::progress()" << endl;; + if (not _track) return; _track = _track->getNextTrack(); diff --git a/katana/src/katana/Manipulator.h b/katana/src/katana/Manipulator.h index 619d7391..b5a672fe 100644 --- a/katana/src/katana/Manipulator.h +++ b/katana/src/katana/Manipulator.h @@ -75,14 +75,23 @@ namespace Katana { bool makeDogleg ( DbU::Unit ); bool makeDogleg ( Interval ); bool relax ( Interval, uint32_t flags=AllowExpand ); - bool insertInTrack ( size_t ); - bool shrinkToTrack ( size_t - , uint32_t flags=0 - , DbU::Unit leftAxisHint=0 - , DbU::Unit rightAxisHint=0 + bool insertInTrack ( size_t icost ); + bool shrinkToTrack ( size_t icost + , uint32_t flags=0 + , DbU::Unit leftAxisHint=0 + , DbU::Unit rightAxisHint=0 ); - bool forceToTrack ( size_t ); + bool forceToTrack ( size_t icost ); bool forceOverLocals (); + private: + bool _insertInTrack ( size_t icost, size_t itrack ); + bool _shrinkToTrack ( size_t icost + , size_t itrack + , uint32_t flags + , DbU::Unit leftAxisHint + , DbU::Unit rightAxisHint + ); + bool _forceToTrack ( size_t icost, size_t itrack ); private: TrackElement* _segment; DataNegociate* _data; diff --git a/katana/src/katana/SegmentFsm.h b/katana/src/katana/SegmentFsm.h index bcbb69e9..26003950 100644 --- a/katana/src/katana/SegmentFsm.h +++ b/katana/src/katana/SegmentFsm.h @@ -127,15 +127,15 @@ namespace Katana { inline Interval& getOptimal (); inline vector& getCosts (); inline TrackCost* getCost ( size_t ); - inline Track* getTrack ( size_t ); - inline Track* getTrack1 ( size_t ); - inline Track* getTrack2 ( size_t ); - inline size_t getBegin ( size_t ); - inline size_t getBegin1 ( size_t ); - inline size_t getBegin2 ( size_t ); - inline size_t getEnd ( size_t ); - inline size_t getEnd1 ( size_t ); - inline size_t getEnd2 ( size_t ); + inline Track* getTrack ( size_t icost, size_t itrack=0 ); + inline Track* getTrack1 ( size_t icost, size_t itrack=0 ); + inline Track* getTrack2 ( size_t icost, size_t itrack=0 ); + inline size_t getBegin ( size_t icost, size_t itrack=0 ); + inline size_t getBegin1 ( size_t icost, size_t itrack=0 ); + inline size_t getBegin2 ( size_t icost, size_t itrack=0 ); + inline size_t getEnd ( size_t icost, size_t itrack=0 ); + inline size_t getEnd1 ( size_t icost, size_t itrack=0 ); + inline size_t getEnd2 ( size_t icost, size_t itrack=0 ); inline vector& getActions (); inline void setState ( uint32_t ); void setDataState ( uint32_t ); @@ -204,16 +204,16 @@ namespace Katana { inline Interval& SegmentFsm::getConstraint () { return _constraint; } inline Interval& SegmentFsm::getOptimal () { return _optimal; } inline vector& SegmentFsm::getCosts () { return _costs; } - inline TrackCost* SegmentFsm::getCost ( size_t i ) { return _costs[i]; } - inline Track* SegmentFsm::getTrack ( size_t i ) { return (_useEvent2) ? getTrack2(i) : getTrack1(i); } - inline size_t SegmentFsm::getBegin ( size_t i ) { return (_useEvent2) ? getBegin2(i) : getBegin1(i); } - inline size_t SegmentFsm::getEnd ( size_t i ) { return (_useEvent2) ? getEnd2 (i) : getEnd1 (i); } - inline Track* SegmentFsm::getTrack1 ( size_t i ) { return _costs[i]->getTrack(0,TrackCost::NoFlags ); } - inline Track* SegmentFsm::getTrack2 ( size_t i ) { return _costs[i]->getTrack(0,TrackCost::Symmetric); } - inline size_t SegmentFsm::getBegin1 ( size_t i ) { return _costs[i]->getBegin(0,TrackCost::NoFlags ); } - inline size_t SegmentFsm::getBegin2 ( size_t i ) { return _costs[i]->getBegin(0,TrackCost::Symmetric); } - inline size_t SegmentFsm::getEnd1 ( size_t i ) { return _costs[i]->getEnd (0,TrackCost::NoFlags ); } - inline size_t SegmentFsm::getEnd2 ( size_t i ) { return _costs[i]->getEnd (0,TrackCost::Symmetric); } + inline TrackCost* SegmentFsm::getCost ( size_t icost ) { return _costs[icost]; } + inline Track* SegmentFsm::getTrack ( size_t icost, size_t itrack ) { return (_useEvent2) ? getTrack2(icost,itrack) : getTrack1(icost,itrack); } + inline size_t SegmentFsm::getBegin ( size_t icost, size_t itrack ) { return (_useEvent2) ? getBegin2(icost,itrack) : getBegin1(icost,itrack); } + inline size_t SegmentFsm::getEnd ( size_t icost, size_t itrack ) { return (_useEvent2) ? getEnd2 (icost,itrack) : getEnd1 (icost,itrack); } + inline Track* SegmentFsm::getTrack1 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::NoFlags ); } + inline Track* SegmentFsm::getTrack2 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::Symmetric); } + inline size_t SegmentFsm::getBegin1 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::NoFlags ); } + inline size_t SegmentFsm::getBegin2 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::Symmetric); } + inline size_t SegmentFsm::getEnd1 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::NoFlags ); } + inline size_t SegmentFsm::getEnd2 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::Symmetric); } inline vector& SegmentFsm::getActions () { return _actions; } inline void SegmentFsm::setState ( uint32_t state ) { _state = state; } inline void SegmentFsm::clearActions () { _actions.clear(); } diff --git a/katana/src/katana/TrackCost.h b/katana/src/katana/TrackCost.h index 9e70eeb9..95d95336 100644 --- a/katana/src/katana/TrackCost.h +++ b/katana/src/katana/TrackCost.h @@ -142,6 +142,7 @@ namespace Katana { inline void setLonguestOverlap ( DbU::Unit ); inline void mergeRipupCount ( int ); inline void mergeDataState ( uint32_t ); + inline bool selectNextTrack (); inline bool select ( size_t index, uint32_t flags ); void consolidate (); void setDistanceToFixed (); @@ -191,7 +192,6 @@ namespace Katana { inline uint32_t TrackCost::getFlags () const { return _flags; } inline size_t TrackCost::getSpan () const { return _span; } inline Net* TrackCost::getNet () const { return (_selectFlags & Symmetric) ? getNet2() : getNet1(); } - inline Track* TrackCost::getTrack () const { return getTrack(_selectIndex,_selectFlags); } inline Track* TrackCost::getTrack ( size_t i ) const { return getTrack(i,NoFlags); } inline size_t TrackCost::getBegin () const { return getBegin(_selectIndex,_selectFlags); } inline size_t TrackCost::getBegin ( size_t i ) const { return getBegin(i,NoFlags); } @@ -231,6 +231,27 @@ namespace Katana { inline TrackCost::Compare::Compare ( uint32_t flags ) : _flags(flags) { } + inline Track* TrackCost::getTrack () const + { + cdebug_log( 55,0) << "TrackCost::getTrack() _index:" << _selectIndex + << " flags:" << _selectFlags << std::endl; + return getTrack(_selectIndex,_selectFlags); + } + + + inline bool TrackCost::selectNextTrack () + { + if (_selectIndex+1 < _span) { + ++_selectIndex; + cdebug_log( 55,0) << "TrackCost::selectNextTrack() _index:" << _selectIndex + << " flags:" << _selectFlags << std::endl; + return true; + } + cdebug_log( 55,0) << "TrackCost::selectNextTrack() over span:" << _span << std::endl; + return false; + } + + inline bool TrackCost::select ( size_t index, uint32_t flags ) { if ( (index >= _span) or ((flags & Symmetric) and not (_flags & Symmetric)) ) { @@ -241,6 +262,9 @@ namespace Katana { _selectIndex = index; _selectFlags = flags; + + cdebug_log( 55,0) << "TrackCost::select() _index:" << _selectIndex + << " flags:" << _selectFlags << std::endl; return true; } @@ -248,12 +272,22 @@ namespace Katana { inline Track* TrackCost::getTrack ( size_t i, uint32_t flags ) const { if (i >= _span) return NULL; + + cdebug_log( 55,0) << "TrackCost::getTrack() i:" << i + << " flags:" << flags + << " index:" << (i + ((flags & Symmetric) ? _span : 0)) << std::endl; + return std::get<0>( _tracks[i + ((flags & Symmetric) ? _span : 0)] ); } inline void TrackCost::setTrack ( Track* track, size_t begin, size_t end ) { + cdebug_log( 55,0) << "TrackCost::setTrack() sindex:" << _selectIndex + << " sflags:" << _selectFlags + << " index:" << (_selectIndex + ((_selectFlags & Symmetric) ? _span : 0)) + << " " << track << std::endl; + auto& entry = _tracks[_selectIndex + ((_selectFlags & Symmetric) ? _span : 0)]; std::get<0>( entry ) = track; std::get<1>( entry ) = begin; diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index 45b62c3d..35a67b1a 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -19,6 +19,7 @@ #include #include +#include #include "hurricane/Interval.h" #include "hurricane/Observer.h" @@ -65,7 +66,6 @@ namespace Katana { enum TrackElementFlags { TElemCreated = (1 << 0) , TElemBlockage = (1 << 1) , TElemFixed = (1 << 2) - , TElemWide = (1 << 3) , TElemLocked = (1 << 4) , TElemRouted = (1 << 5) , TElemSourceDogleg = (1 << 6) @@ -101,7 +101,7 @@ namespace Katana { virtual bool isFixed () const; virtual bool isHorizontal () const = 0; virtual bool isVertical () const = 0; - inline bool isWide () const; + virtual bool isWide () const; virtual bool isLocal () const; virtual bool isGlobal () const; virtual bool isBipoint () const; @@ -135,14 +135,15 @@ namespace Katana { // Accessors inline Observer* getObserver (); virtual unsigned long getId () const; + virtual uint32_t getTrackCount () const; virtual Flags getDirection () const = 0; virtual Net* getNet () const = 0; + virtual DbU::Unit getWidth () const = 0; virtual const Layer* getLayer () const = 0; virtual DbU::Unit getPitch () const; virtual DbU::Unit getPPitch () const; virtual size_t getTrackSpan () const = 0; inline Track* getTrack () const; - inline size_t getIndex () const; virtual float getPriority () const = 0; virtual unsigned long getFreedomDegree () const; virtual float getMaxUnderDensity ( Flags flags=Flags::NoFlags ) const; @@ -150,6 +151,7 @@ namespace Katana { virtual TrackElement* getNext () const; virtual TrackElement* getPrevious () const; virtual DbU::Unit getAxis () const = 0; + inline DbU::Unit getSymmetricAxis ( DbU::Unit ) const; inline DbU::Unit getSourceU () const; inline DbU::Unit getTargetU () const; inline DbU::Unit getLength () const; @@ -172,7 +174,6 @@ namespace Katana { inline void unsetFlags ( uint32_t ); inline void setRouted (); virtual void setTrack ( Track* ); - inline void setIndex ( size_t ); virtual void setSymmetric ( TrackElement* ); virtual void setPriorityLock ( bool state ) = 0; virtual void forcePriority ( float priority ) = 0; @@ -183,11 +184,13 @@ namespace Katana { virtual void swapTrack ( TrackElement* ); virtual void reschedule ( uint32_t level ); virtual void detach (); + virtual void detach ( std::set& ); virtual void invalidate (); virtual void revalidate (); virtual void updatePPitch (); + virtual void addTrackCount ( int32_t ); virtual void incOverlapCost ( TrackCost& ) const; - virtual void setAxis ( DbU::Unit, uint32_t flags=Anabatic::SegAxisSet ); + virtual void setAxis ( DbU::Unit, uint32_t flags=Anabatic::AutoSegment::SegAxisSet ); virtual TrackElement* makeDogleg (); inline bool makeDogleg ( Anabatic::GCell* ); virtual TrackElement* makeDogleg ( Anabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel ); @@ -211,7 +214,6 @@ namespace Katana { // Attributes. uint32_t _flags; Track* _track; - size_t _index; DbU::Unit _sourceU; DbU::Unit _targetU; Observer _observer; @@ -233,7 +235,6 @@ namespace Katana { inline Observer* TrackElement::getObserver () { return &_observer; } inline void TrackElement::setFlags ( uint32_t flags ) { _flags |= flags; } inline void TrackElement::unsetFlags ( uint32_t flags ) { _flags &= ~flags; } - inline bool TrackElement::isWide () const { return _flags & TElemWide; } inline bool TrackElement::isCreated () const { return _flags & TElemCreated; } inline bool TrackElement::isInvalidated () const { return _flags & TElemInvalidated; } inline bool TrackElement::isBlockage () const { return _flags & TElemBlockage; } @@ -243,17 +244,16 @@ namespace Katana { inline bool TrackElement::hasTargetDogleg () const { return _flags & TElemTargetDogleg; } inline bool TrackElement::canRipple () const { return _flags & TElemRipple; } inline Track* TrackElement::getTrack () const { return _track; } - inline size_t TrackElement::getIndex () const { return _index; } inline DbU::Unit TrackElement::getLength () const { return getTargetU() - getSourceU(); } inline DbU::Unit TrackElement::getSourceU () const { return _sourceU; } inline DbU::Unit TrackElement::getTargetU () const { return _targetU; } inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); } - inline void TrackElement::setIndex ( size_t index ) { _index=index; } + inline DbU::Unit TrackElement::getSymmetricAxis ( DbU::Unit axis ) const { return axis - (getTrackSpan()-1)*getPitch(); } inline void TrackElement::setRouted() { _flags |= TElemRouted; - if (base()) base()->setFlags( Anabatic::SegFixed ); + if (base()) base()->setFlags( Anabatic::AutoSegment::SegFixed ); } inline Box TrackElement::getBoundingBox () const diff --git a/katana/src/katana/TrackFixedSegment.h b/katana/src/katana/TrackFixedSegment.h index 259ae556..e02ce152 100644 --- a/katana/src/katana/TrackFixedSegment.h +++ b/katana/src/katana/TrackFixedSegment.h @@ -49,6 +49,7 @@ namespace Katana { virtual unsigned long getId () const; virtual Flags getDirection () const; virtual Net* getNet () const; + virtual DbU::Unit getWidth () const; virtual const Layer* getLayer () const; virtual size_t getTrackSpan () const; virtual TrackElement* getNext () const; diff --git a/katana/src/katana/TrackSegment.h b/katana/src/katana/TrackSegment.h index c7135093..bcf0886a 100644 --- a/katana/src/katana/TrackSegment.h +++ b/katana/src/katana/TrackSegment.h @@ -77,6 +77,7 @@ namespace Katana { virtual bool isUTurn () const; virtual bool isUserDefined () const; virtual bool isAnalog () const; + virtual bool isWide () const; virtual bool isPriorityLocked () const; // Predicates. virtual bool hasSymmetric () const; @@ -91,6 +92,7 @@ namespace Katana { virtual unsigned long getId () const; virtual Flags getDirection () const; virtual Net* getNet () const; + virtual DbU::Unit getWidth () const; virtual const Layer* getLayer () const; virtual DbU::Unit getPitch () const; virtual DbU::Unit getPPitch () const; @@ -124,6 +126,7 @@ namespace Katana { virtual void swapTrack ( TrackElement* ); virtual void reschedule ( uint32_t level ); virtual void detach (); + virtual void detach ( std::set& ); virtual void invalidate (); virtual void revalidate (); virtual void updatePPitch (); diff --git a/katana/src/katana/TrackSegmentWide.h b/katana/src/katana/TrackSegmentWide.h index 8a31fc67..a561c4ef 100644 --- a/katana/src/katana/TrackSegmentWide.h +++ b/katana/src/katana/TrackSegmentWide.h @@ -53,12 +53,15 @@ namespace Katana { virtual void _postCreate (); virtual void _preDestroy (); virtual size_t getTrackSpan () const; + virtual uint32_t getTrackCount () const; virtual void addOverlapCost ( TrackCost& ) const; + virtual void addTrackCount ( int32_t ); private: TrackSegmentWide ( const TrackSegmentWide& ) = delete; TrackSegmentWide& operator= ( const TrackSegmentWide& ) = delete; private: - size_t _trackSpan; + size_t _trackSpan; + uint32_t _trackCount; };